Ejemplo n.º 1
0
        void Write(AssemblyDefinition assemblyToPatch, NPath assemblyToPatchPath, PatchOptions patchOptions = default)
        {
            // atomic write of file with backup
            // TODO: skip backup if existing file already patched. want the .orig to only be the unpatched file.

            // write to tmp and release the lock
            var tmpPath = assemblyToPatchPath.ChangeExtension(".tmp");

            tmpPath.DeleteIfExists();
            assemblyToPatch.Write(tmpPath); // $$$ , new WriterParameters { WriteSymbols = true }); see https://github.com/jbevain/cecil/issues/421
            assemblyToPatch.Dispose();

            // TODO: peverify obviously won't work with memory written streams. also needs all the dependencies.
            // solution is to create a temp folder, write the patched dll there as well as any of its direct dependencies, and run peverify

            if ((patchOptions & PatchOptions.SkipPeVerify) == 0)
            {
                PeVerify.Verify(tmpPath);
            }

            // move the actual file to backup, and move the tmp to actual
            var backupPath = ElevatedWeaver.GetPatchBackupPathFor(assemblyToPatchPath);

            File.Replace(tmpPath, assemblyToPatchPath, backupPath);
        }
Ejemplo n.º 2
0
    void RoundTripCodeCopier(string assemblyName, string pdbName, bool allowCheckerFail)
    {
        PeVerifyResult expectedResult = PeVerify.VerifyAssembly(assemblyName);
        IAssembly      assembly       = LoadAssembly(assemblyName);

        if (pdbName != null)
        {
            using (var f = File.OpenRead(pdbName)) {
                using (var pdbReader = new PdbReader(f, host)) {
                    var            codeAssembly = Decompiler.GetCodeModelFromMetadataModel(this.host, assembly, pdbReader);
                    CodeDeepCopier copier       = new CodeDeepCopier(host);
                    codeAssembly = copier.Copy(codeAssembly);
                    Checker checker = new Checker(this.host);
                    checker.Traverse(codeAssembly);
                    Debug.Assert(checker.Errors.Count == 0);
                    AssertWriteToPeFile(expectedResult, codeAssembly, pdbReader);
                }
            }
        }
        else
        {
            var            codeAssembly = Decompiler.GetCodeModelFromMetadataModel(this.host, assembly, null);
            CodeDeepCopier copier       = new CodeDeepCopier(host);
            codeAssembly = copier.Copy(codeAssembly);
            Checker checker = new Checker(this.host);
            checker.Traverse(codeAssembly);
            Debug.Assert(allowCheckerFail || checker.Errors.Count == 0);
            AssertWriteToPeFile(expectedResult, codeAssembly, null);
        }
    }
Ejemplo n.º 3
0
        public void ValidDll_VerifiesClean()
        {
            var dllPath = typeof(TestAttribute).Assembly.Location; // pick nunit, why not

            File.Exists(dllPath).ShouldBeTrue();
            Should.NotThrow(() => PeVerify.Verify(dllPath));
        }
Ejemplo n.º 4
0
        public void MissingDll_Throws()
        {
            var badPath = GetType().Assembly.Location + ".xyzzy";

            File.Exists(badPath).ShouldBeFalse();
            Should.Throw <PeVerifyException>(() => PeVerify.Verify(badPath));
        }
Ejemplo n.º 5
0
    void AssertWriteToPeFile(PeVerifyResult expectedResult, IAssembly assembly, string pdbPath)
    {
        var validator = new MetadataValidator(this.host);
        List <Microsoft.Cci.ErrorEventArgs> errorEvents = new List <Microsoft.Cci.ErrorEventArgs>();

        this.host.Errors += (object sender, Microsoft.Cci.ErrorEventArgs e) => errorEvents.Add(e);
        validator.Validate(assembly);
        Debug.Assert(errorEvents.Count == 0);
        using (var rewrittenFile = File.Create(assembly.Location)) {
            if (pdbPath != null)
            {
                using (var f = File.OpenRead(pdbPath)) {
                    using (var pdbReader = new PdbReader(f, host)) {
                        using (var pdbWriter = new PdbWriter(Path.GetFullPath(assembly.Location + ".pdb"), pdbReader)) {
                            PeWriter.WritePeToStream(assembly, host, rewrittenFile, pdbReader, pdbReader, pdbWriter);
                        }
                    }
                }
            }
            else
            {
                using (var pdbWriter = new PdbWriter(Path.GetFullPath(assembly.Location + ".pdb"), null)) {
                    PeWriter.WritePeToStream(assembly, host, rewrittenFile, null, null, pdbWriter);
                }
            }
        }

        Assert.True(File.Exists(assembly.Location));
        PeVerify.Assert(expectedResult, PeVerify.VerifyAssembly(assembly.Location, true));
    }
Ejemplo n.º 6
0
        public void InvalidDll_Throws()
        {
            var path = BaseDir.Combine("test.txt").WriteAllText("this is definitely not a valid dll");

            File.Exists(path).ShouldBeTrue();
            Should.Throw <PeVerifyException>(() => PeVerify.Verify(path));
        }
        protected NPath Compile(string testAssemblyName, string sourceCode, params string[] dependentAssemblyNames)
        {
            // prefix the assembly name because they are globally unique and don't want to ever collide
            var testAssemblyPath = BaseDir
                                   .Combine($"{TestContext.CurrentContext.GetFixtureName()}_{testAssemblyName}")
                                   .ChangeExtension(".dll");

            // set up to compile

            var compiler     = new Microsoft.CSharp.CSharpCodeProvider();
            var compilerArgs = new CompilerParameters
            {
                OutputAssembly          = testAssemblyPath,
                IncludeDebugInformation = true,
                CompilerOptions         = "/o- /debug+ /warn:0"
            };

            compilerArgs.ReferencedAssemblies.Add(typeof(int).Assembly.Location); // mscorlib

            // TODO: use typecache
            var assemblies = AppDomain.CurrentDomain
                             .GetAssemblies()
                             .Where(a => !a.IsDynamic)
                             .ToDictionary(a => a.GetName().Name, a => a.Location.ToNPath(), StringComparer.OrdinalIgnoreCase);

            foreach (var dependentAssemblyName in dependentAssemblyNames)
            {
                // we may have already copied it in
                var path = BaseDir.Combine(dependentAssemblyName).ChangeExtension(".dll");

                // if not,
                if (!path.Exists() && assemblies.TryGetValue(dependentAssemblyName, out path))
                {
                    path.Copy(BaseDir.Combine(path.FileName));
                }

                compilerArgs.ReferencedAssemblies.Add(path);
            }

            // compile and handle errors

            var compilerResult = compiler.CompileAssemblyFromSource(compilerArgs, sourceCode);

            if (compilerResult.Errors.Count > 0)
            {
                var errorText = compilerResult.Errors
                                .OfType <CompilerError>()
                                .Select(e => $"({e.Line},{e.Column}): error {e.ErrorNumber}: {e.ErrorText}")
                                .Prepend("Compiler errors:")
                                .StringJoin("\n");
                throw new Exception(errorText);
            }

            testAssemblyPath.ShouldBe(new NPath(compilerResult.PathToAssembly));

            PeVerify.Verify(testAssemblyPath); // sanity check on what the compiler generated

            return(testAssemblyPath);
        }
Ejemplo n.º 8
0
 void AssertWriteToPeFile(PeVerifyResult expectedResult, IAssembly assembly, PdbReader pdbReader)
 {
     using (var rewrittenFile = File.Create(assembly.Location)) {
         using (var pdbWriter = new PdbWriter(Path.GetFullPath(assembly.Location + ".pdb"), pdbReader)) {
             PeWriter.WritePeToStream(assembly, host, rewrittenFile, pdbReader, pdbReader, pdbWriter);
         }
     }
     Assert.True(File.Exists(assembly.Location));
     PeVerify.Assert(expectedResult, PeVerify.VerifyAssembly(assembly.Location, true));
 }
Ejemplo n.º 9
0
    void AssertWriteToPeFile(PeVerifyResult expectedResult, IAssembly assembly)
    {
        using (FileStream rewrittenFile = File.Create(assembly.Location)) {
            using (this.pdbReader) {
                PeWriter.WritePeToStream(assembly, this.host, rewrittenFile, this.pdbReader, this.pdbReader, this.pdbWriter);
            }
        }

        Assert.True(File.Exists(assembly.Location));
        PeVerify.Assert(expectedResult, PeVerify.VerifyAssembly(assembly.Location));
    }
Ejemplo n.º 10
0
    void RoundTripMutableCopyMarkedNodes(string assemblyName, string pdbName)
    {
        PeVerifyResult expectedResult = PeVerify.VerifyAssembly(assemblyName);
        IAssembly      assembly       = LoadAssembly(assemblyName);

        using (var f = File.OpenRead(pdbName)) {
            using (var pdbReader = new PdbReader(f, host)) {
                var adder        = new CopyMarkedNodes(host);
                var codeAssembly = adder.Rewrite(assembly);
                AssertWriteToPeFile(expectedResult, codeAssembly, pdbReader);
            }
        }
    }
Ejemplo n.º 11
0
    void RoundTripMutableCopyAndAddGenericParameter2(string assemblyName)
    {
        PeVerifyResult expectedResult = PeVerify.VerifyAssembly(assemblyName);
        IAssembly      assembly       = LoadAssembly(assemblyName);
        var            copier1        = new MetadataDeepCopier(host);
        var            codeAssembly   = copier1.Copy(assembly);

        for (int i = 0; i < 30; i++)
        {
            AddGenericParameters adder = new AddGenericParameters(host, codeAssembly.AllTypes, i);
            codeAssembly = (Assembly)adder.Rewrite(codeAssembly);
        }
        AssertWriteToPeFile(expectedResult, codeAssembly, null);
    }
Ejemplo n.º 12
0
    void RoundTripNoCopyTestDecompilation(string assemblyName, string pdbName)
    {
        PeVerifyResult expectedResult = PeVerify.VerifyAssembly(assemblyName);
        IAssembly      assembly       = LoadAssembly(assemblyName);

        using (var f = File.OpenRead(pdbName)) {
            using (var pdbReader = new PdbReader(f, host)) {
                var     codeAssembly = Decompiler.GetCodeModelFromMetadataModel(this.host, assembly, pdbReader);
                Checker checker      = new Checker(this.host);
                checker.Traverse(codeAssembly);
                Debug.Assert(checker.Errors.Count == 0);
                AssertWriteToPeFile(expectedResult, codeAssembly, pdbReader);
            }
        }
    }
Ejemplo n.º 13
0
    void RoundTripMutableCopyAndAddGenericParameter(string assemblyName, string pdbName)
    {
        PeVerifyResult expectedResult = PeVerify.VerifyAssembly(assemblyName);
        IAssembly      assembly       = LoadAssembly(assemblyName);

        using (var f = File.OpenRead(pdbName)) {
            using (var pdbReader = new PdbReader(f, host)) {
                var codeAssembly = Decompiler.GetCodeModelFromMetadataModel(this.host, assembly, pdbReader);
                codeAssembly = new CodeDeepCopier(host).Copy(codeAssembly);
                AddGenericParameters adder = new AddGenericParameters(host, codeAssembly.AllTypes, 0);
                codeAssembly = (Assembly)adder.Rewrite(codeAssembly);
                Checker checker = new Checker(this.host);
                checker.Traverse(codeAssembly);
                Debug.Assert(checker.Errors.Count == 0);
                AssertWriteToPeFile(expectedResult, codeAssembly, pdbReader);
            }
        }
    }
Ejemplo n.º 14
0
        public void Run(CodeGenerator codeGenerator)
        {
            try
            {
                var path           = codeGenerator.Run(tempFolder);
                var peVerifyResult = PeVerify.VerifyAssembly(path);
                if (peVerifyResult.Errors.Any())
                {
                    throw new VerificationException(string.Join(Environment.NewLine, peVerifyResult.Errors.ToArray()));
                }

                verifier(path);
                Console.WriteLine("Successful");
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
                Console.WriteLine("Failed");
            }
        }
Ejemplo n.º 15
0
    void RoundTripCopyAndExecute(string assemblyName, string pdbName, bool verificationMayFail)
    {
        PeVerifyResult expectedResult = !verificationMayFail
      ? PeVerify.VerifyAssembly(assemblyName)
      : PeVerify.RunPeVerifyOnAssembly(assemblyName);

        string    expectedOutput = Execute(assemblyName);
        IAssembly assembly       = LoadAssembly(assemblyName);

        using (var f = File.OpenRead(pdbName)) {
            using (var pdbReader = new PdbReader(f, host)) {
                var codeAssembly = Decompiler.GetCodeModelFromMetadataModel(this.host, assembly, pdbReader);
                var copier       = new CodeDeepCopier(host);
                codeAssembly = copier.Copy(codeAssembly);
                Checker checker = new Checker(this.host);
                checker.Traverse(codeAssembly);
                Debug.Assert(checker.Errors.Count == 0);
                AssertWriteToPeFile(expectedResult, codeAssembly, pdbReader);
                AssertExecute(expectedOutput, assemblyName);
            }
        }
    }
Ejemplo n.º 16
0
    void RoundTripWithILMutator(string assemblyName, string pdbPath, bool verificationMayFail)
    {
        PeVerifyResult expectedResult = PeVerify.VerifyAssembly(assemblyName, verificationMayFail);

        RoundTripWithMutator(expectedResult, LoadAssembly(assemblyName), new MetadataRewriter(host), pdbPath);
    }
Ejemplo n.º 17
0
    void RoundTripWithILMutator(string assemblyName, string pdbName)
    {
        PeVerifyResult expectedResult = PeVerify.VerifyAssembly(assemblyName);

        RoundTripWithMutator(expectedResult, LoadAssembly(assemblyName), new MetadataRewriter(host));
    }
Ejemplo n.º 18
0
    void RoundTripWithCodeMutator(string assemblyName, string pdbName)
    {
        PeVerifyResult expectedResult = PeVerify.VerifyAssembly(assemblyName);

        RoundTripWithCodeMutator(expectedResult, assemblyName, pdbName);
    }