Beispiel #1
0
        public void NewFieldDefinition()
        {
            var module = ModuleDefinition.FromBytes(Properties.Resources.HelloWorld);

            // Create new field.
            var field = new FieldDefinition(
                "MyField",
                FieldAttributes.Public | FieldAttributes.Static,
                FieldSignature.CreateStatic(module.CorLibTypeFactory.Object));

            module.GetOrCreateModuleType().Fields.Add(field);

            // Rebuild.
            var builder = new ManagedPEImageBuilder();
            var result  = builder.CreateImage(module);

            // Assert valid token.
            var newToken = result.TokenMapping[field];

            Assert.NotEqual(0u, newToken.Rid);

            // Assert token resolves to the new field.
            var newModule = ModuleDefinition.FromImage(result.ConstructedImage);
            var newField  = (FieldDefinition)newModule.LookupMember(newToken);

            Assert.Equal(field.Name, newField.Name);
        }
Beispiel #2
0
        public void NewMethodDefinition()
        {
            var module = ModuleDefinition.FromBytes(Properties.Resources.HelloWorld);

            // Create new method.
            var method = new MethodDefinition(
                "MyMethod",
                MethodAttributes.Public | MethodAttributes.Static,
                MethodSignature.CreateStatic(module.CorLibTypeFactory.Void));

            module.GetOrCreateModuleType().Methods.Add(method);

            // Get existing main method.
            var main = module.ManagedEntrypointMethod;

            // Rebuild.
            var builder = new ManagedPEImageBuilder();
            var result  = builder.CreateImage(module);

            // Assert valid tokens for both methods.
            var methodToken     = result.TokenMapping[method];
            var mainMethodToken = result.TokenMapping[main];

            Assert.NotEqual(0u, methodToken.Rid);
            Assert.NotEqual(0u, mainMethodToken.Rid);

            // Assert tokens resolve to the same methods.
            var newModule = ModuleDefinition.FromImage(result.ConstructedImage);
            var newMethod = (MethodDefinition)newModule.LookupMember(methodToken);

            Assert.Equal(method.Name, newMethod.Name);
            var newMain = (MethodDefinition)newModule.LookupMember(mainMethodToken);

            Assert.Equal(main.Name, newMain.Name);
        }
Beispiel #3
0
        public void NewMethodSpecification()
        {
            var module = ModuleDefinition.FromBytes(Properties.Resources.HelloWorld);

            // Import arbitrary generic method.
            var importer  = new ReferenceImporter(module);
            var reference = importer.ImportMethod(typeof(Array).GetMethod("Empty").MakeGenericMethod(typeof(object)));

            // Ensure method reference is added to the module by referencing it in main.
            var instructions = module.ManagedEntrypointMethod.CilMethodBody.Instructions;

            instructions.Insert(0, CilOpCodes.Call, reference);
            instructions.Insert(1, CilOpCodes.Pop);

            // Rebuild.
            var builder = new ManagedPEImageBuilder();
            var result  = builder.CreateImage(module);

            // Assert valid token.
            var newToken = result.TokenMapping[reference];

            Assert.NotEqual(0u, newToken.Rid);

            // Assert token resolves to the same method reference.
            var newModule    = ModuleDefinition.FromImage(result.ConstructedImage);
            var newReference = (MethodSpecification)newModule.LookupMember(newToken);

            Assert.Equal(reference.Name, newReference.Name);
        }
Beispiel #4
0
        public void NewStandaloneSignature()
        {
            var module = ModuleDefinition.FromBytes(Properties.Resources.HelloWorld);

            // Import arbitrary method signature.
            var importer  = new ReferenceImporter(module);
            var signature = new StandAloneSignature(
                importer.ImportMethodSignature(MethodSignature.CreateStatic(module.CorLibTypeFactory.Void)));

            // Ensure reference is added to the module by referencing it in main.
            var instructions = module.ManagedEntrypointMethod.CilMethodBody.Instructions;

            instructions.Insert(0, CilOpCodes.Ldnull);
            instructions.Insert(0, CilOpCodes.Calli, signature);

            // Rebuild.
            var builder = new ManagedPEImageBuilder();
            var result  = builder.CreateImage(module);

            // Assert valid token.
            var newToken = result.TokenMapping[signature];

            Assert.NotEqual(0u, newToken.Rid);

            // Assert token resolves to the same method reference.
            var newModule    = ModuleDefinition.FromImage(result.ConstructedImage);
            var newSignature = (StandAloneSignature)newModule.LookupMember(newToken);

            Assert.Equal(signature.Signature, newSignature.Signature, new SignatureComparer());
        }
Beispiel #5
0
        public void NewTypeReference()
        {
            var module = ModuleDefinition.FromBytes(Properties.Resources.HelloWorld);

            // Import arbitrary type as reference.
            var importer  = new ReferenceImporter(module);
            var reference = importer.ImportType(typeof(MemoryStream));

            // Ensure type ref is added to the module by adding a dummy field referencing it.
            module.GetOrCreateModuleType().Fields.Add(new FieldDefinition(
                                                          "MyField",
                                                          FieldAttributes.Public | FieldAttributes.Static,
                                                          FieldSignature.CreateStatic(reference.ToTypeSignature())));

            // Rebuild.
            var builder = new ManagedPEImageBuilder();
            var result  = builder.CreateImage(module);

            // Assert valid token.
            var newToken = result.TokenMapping[reference];

            Assert.NotEqual(0u, newToken.Rid);

            // Assert token resolves to the same type reference.
            var newModule    = ModuleDefinition.FromImage(result.ConstructedImage);
            var newReference = (TypeReference)newModule.LookupMember(newToken);

            Assert.Equal(reference.Namespace, newReference.Namespace);
            Assert.Equal(reference.Name, newReference.Name);
        }
Beispiel #6
0
        public void NewTypeDefinition()
        {
            var module = ModuleDefinition.FromBytes(Properties.Resources.HelloWorld);

            // Create new type.
            var type = new TypeDefinition("Namespace", "Name", TypeAttributes.Interface);;

            module.TopLevelTypes.Add(type);

            // Rebuild.
            var builder = new ManagedPEImageBuilder();
            var result  = builder.CreateImage(module);

            // Assert valid token.
            var newToken = result.TokenMapping[type];

            Assert.NotEqual(0u, newToken.Rid);

            // Assert token resolves to the new type.
            var newModule = ModuleDefinition.FromImage(result.ConstructedImage);
            var newType   = (TypeDefinition)newModule.LookupMember(newToken);

            Assert.Equal(type.Namespace, newType.Namespace);
            Assert.Equal(type.Name, newType.Name);
        }
Beispiel #7
0
        public void ComputeMaxStackOnBuildOverride(bool computeMaxStack, bool?computeMaxStackOverride, int expectedMaxStack)
        {
            const int maxStack = 100;

            var module = new ModuleDefinition("SomeModule", KnownCorLibs.SystemPrivateCoreLib_v4_0_0_0);
            var main   = new MethodDefinition(
                "Main",
                MethodAttributes.Public | MethodAttributes.Static,
                MethodSignature.CreateStatic(module.CorLibTypeFactory.Void));

            main.CilMethodBody = new CilMethodBody(main)
            {
                ComputeMaxStackOnBuild = computeMaxStack,
                MaxStack       = maxStack,
                Instructions   = { new CilInstruction(CilOpCodes.Ret) },
                LocalVariables = { new CilLocalVariable(module.CorLibTypeFactory.Int32) } // Force fat method body.
            };

            module.GetOrCreateModuleType().Methods.Add(main);
            module.ManagedEntrypoint = main;

            var builder = new ManagedPEImageBuilder(new DotNetDirectoryFactory
            {
                MethodBodySerializer = new CilMethodBodySerializer
                {
                    ComputeMaxStackOnBuildOverride = computeMaxStackOverride
                }
            });

            var newImage  = builder.CreateImage(module);
            var newModule = ModuleDefinition.FromImage(newImage);

            Assert.Equal(expectedMaxStack, newModule.ManagedEntrypointMethod.CilMethodBody.MaxStack);
        }
Beispiel #8
0
        private static FieldDefinition RebuildAndLookup(FieldDefinition field)
        {
            var builder   = new ManagedPEImageBuilder();
            var newImage  = builder.CreateImage(field.Module).ConstructedImage;
            var newModule = ModuleDefinition.FromImage(newImage);

            return(LookupFieldInModule(newModule, field.Name));
        }
Beispiel #9
0
        private static MethodDefinition RebuildAndLookup(MethodDefinition method)
        {
            var builder   = new ManagedPEImageBuilder();
            var newImage  = builder.CreateImage(method.Module).ConstructedImage;
            var newModule = ModuleDefinition.FromImage(newImage);

            return(LookupMethodInModule(newModule, method.Name));
        }
Beispiel #10
0
        private DevirtualisationContext CreateDevirtualisationContext(DevirtualisationOptions options)
        {
            string workingDirectory = Path.GetDirectoryName(options.InputFile);

            // Open target PE.
            Logger.Log(Tag, $"Opening target file {options.InputFile}...");
            var peFile = PEFile.FromFile(options.InputFile);

            // Create #Koi stream aware metadata reader.
            var streamReader = options.OverrideKoiStreamData
                ? new DefaultMetadataStreamReader()
                : (IMetadataStreamReader) new KoiVmAwareStreamReader(options.KoiStreamName, Logger);

            var peImage = PEImage.FromFile(peFile, new PEReaderParameters
            {
                MetadataStreamReader = streamReader
            });

            var metadata = peImage.DotNetDirectory?.Metadata;

            if (metadata is null)
            {
                throw new BadImageFormatException("Assembly does not contain a valid .NET header.");
            }

            // If custom koi stream data was provided, inject it.
            KoiStream koiStream;

            if (!options.OverrideKoiStreamData)
            {
                koiStream = metadata.GetStream <KoiStream>() ?? throw new DevirtualisationException(
                                      "Koi stream was not found in the target PE. This could be because the input file is " +
                                      "not protected with KoiVM, or the metadata stream uses a name that is different " +
                                      "from the one specified in the input parameters.");
            }
            else
            {
                string path = Path.IsPathRooted(options.KoiStreamDataFile)
                    ? options.KoiStreamDataFile
                    : Path.Combine(workingDirectory, options.KoiStreamDataFile);

                Logger.Log(Tag, $"Opening external Koi stream data file {path}...");
                var contents = File.ReadAllBytes(path);

                // Replace original koi stream if it existed.
                koiStream = new KoiStream(options.KoiStreamName, new DataSegment(contents), Logger);
            }

            // Ignore invalid / encrypted method bodies when specified.
            var moduleReadParameters = new ModuleReaderParameters(workingDirectory,
                                                                  options.IgnoreInvalidMD ? (IErrorListener)ThrowErrorListener.Instance : EmptyErrorListener.Instance);

            var module        = ModuleDefinition.FromImage(peImage, moduleReadParameters);
            var runtimeModule = ResolveRuntimeModule(options, module);

            koiStream.ResolutionContext = module;
            return(new DevirtualisationContext(options, module, runtimeModule, koiStream, Logger));
        }
        protected static ModuleDefinition RebuildAndReloadModule(ModuleDefinition module, MetadataBuilderFlags builderFlags)
        {
            var builder = new ManagedPEImageBuilder
            {
                DotNetDirectoryFactory = new DotNetDirectoryFactory(builderFlags)
            };

            var newImage = builder.CreateImage(module).ConstructedImage;

            return(ModuleDefinition.FromImage(newImage));
        }
        public void AssignTokenToNewUnusedTypeReferenceShouldPreserveAfterBuild()
        {
            var module    = ModuleDefinition.FromBytes(Properties.Resources.HelloWorld);
            var reference = new TypeReference(module, module, "SomeNamespace", "SomeType");

            module.TokenAllocator.AssignNextAvailableToken(reference);

            var image     = module.ToPEImage(new ManagedPEImageBuilder(MetadataBuilderFlags.PreserveTypeReferenceIndices));
            var newModule = ModuleDefinition.FromImage(image);

            var newReference = (TypeReference)newModule.LookupMember(reference.MetadataToken);

            Assert.Equal(reference.Namespace, newReference.Namespace);
            Assert.Equal(reference.Name, newReference.Name);
        }
Beispiel #13
0
        protected static ModuleDefinition RebuildAndReloadModule(ModuleDefinition module, MetadataBuilderFlags builderFlags)
        {
            var builder = new ManagedPEImageBuilder
            {
                DotNetDirectoryFactory = new DotNetDirectoryFactory(builderFlags)
            };

            var result = builder.CreateImage(module);

            if (result.DiagnosticBag.HasErrors)
            {
                throw new AggregateException(result.DiagnosticBag.Exceptions);
            }

            var newImage = result.ConstructedImage;

            return(ModuleDefinition.FromImage(newImage));
        }