Esempio n. 1
0
        private static void OutputFacadeToFile(string facadePath, HostEnvironment seedHost, Assembly facade, IAssembly contract, string pdbLocation = null)
        {
            // Use the filename (including extension .dll/.winmd) so people can have some control over the output facade file name.
            string facadeFileName   = Path.GetFileName(contract.Location);
            string facadeOutputPath = Path.Combine(facadePath, facadeFileName);

            using (Stream peOutStream = File.Create(facadeOutputPath))
            {
                if (pdbLocation != null)
                {
                    if (File.Exists(pdbLocation))
                    {
                        string pdbOutputPath = Path.Combine(facadePath, contract.Name + ".pdb");
                        using (Stream pdbReadStream = File.OpenRead(pdbLocation))
                            using (PdbReader pdbReader = new PdbReader(pdbReadStream, seedHost))
                                using (PdbWriter pdbWriter = new PdbWriter(pdbOutputPath, pdbReader))
                                {
                                    PeWriter.WritePeToStream(facade, seedHost, peOutStream, pdbReader, pdbReader, pdbWriter);
                                }
                    }
                    else
                    {
                        throw new FacadeGenerationException("Couldn't find the pdb at the given location: " + pdbLocation);
                    }
                }
                else
                {
                    PeWriter.WritePeToStream(facade, seedHost, peOutStream);
                }
            }
        }
Esempio n. 2
0
        static void Main(string[] args)
        {
            using (var host = new HelloHost()) {
                var nameTable    = host.NameTable;
                var coreAssembly = host.LoadAssembly(host.CoreAssemblySymbolicIdentity);

                var aname   = nameTable.GetNameFor("hello");
                var mname   = nameTable.GetNameFor("hello.exe");
                var arefs   = IteratorHelper.GetSingletonEnumerable <IAssemblyReference>(coreAssembly);
                var source  = new HelloSourceDocument(aname);
                var sources = IteratorHelper.GetSingletonEnumerable <HelloSourceDocument>(source);

                var helloAssembly          = new HelloAssembly(aname, host, mname, arefs, sources);
                var sourceLocationProvider = helloAssembly.Compilation.SourceLocationProvider;
                var localScopeProvider     = helloAssembly.Compilation.LocalScopeProvider;

                using (var sourceFile = File.CreateText("hello.cs")) {
                    sourceFile.WriteLine("hello");
                }
                using (var peStream = File.Create("hello.exe")) {
                    using (var pdbWriter = new PdbWriter("hello.pdb", sourceLocationProvider)) {
                        PeWriter.WritePeToStream(helloAssembly, host, peStream, helloAssembly.Compilation.SourceLocationProvider, helloAssembly.Compilation.LocalScopeProvider, pdbWriter);
                    }
                }
            }
        }
Esempio n. 3
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));
    }
Esempio n. 4
0
        private static void TranslateToExe(SpecSharpOptions commandLineOptions)
        //^ requires commandLineOptions.FileNames.Count > 0;
        {
            HostEnvironment hostEnvironment = new HostEnvironment();

            hostEnvironment.Errors         += hostEnvironment.HandleErrors;
            hostEnvironment.displayFileName = true;
            List <IAssemblyReference>      assemblyReferences = GetAssemblyReferences(commandLineOptions, hostEnvironment);
            List <IModuleReference>        moduleReferences   = new List <IModuleReference>();
            List <SpecSharpSourceDocument> programSources     = new List <SpecSharpSourceDocument>(1);
            IName                      name   = hostEnvironment.NameTable.GetNameFor(Path.GetFileNameWithoutExtension(commandLineOptions.FileNames[0]));
            SpecSharpAssembly          assem  = new SpecSharpAssembly(name, Path.GetFullPath(name.Value), hostEnvironment, commandLineOptions, assemblyReferences, moduleReferences, programSources);
            SpecSharpCompilationHelper helper = new SpecSharpCompilationHelper(assem.Compilation);

            foreach (string fileName in commandLineOptions.FileNames)
            {
                name = hostEnvironment.NameTable.GetNameFor(fileName);
                StreamReader instream = File.OpenText(fileName);
                programSources.Add(new SpecSharpSourceDocument(helper, name, Path.GetFullPath(fileName), instream));
            }

            if (assem.Compilation.HasErrors)
            {
                return;
            }
            var sourceLocationProvider = assem.Compilation.SourceLocationProvider;
            var localScopeProvider     = assem.Compilation.LocalScopeProvider;

            using (var pdbWriter = new PdbWriter(Path.ChangeExtension(assem.Location, "pdb"), sourceLocationProvider)) {
                PeWriter.WritePeToStream(assem, hostEnvironment, File.Create(Path.ChangeExtension(assem.Location, "exe")), sourceLocationProvider, localScopeProvider, pdbWriter);
            }
        }
Esempio n. 5
0
    private static void TranslateToExe(SpecSharpOptions commandLineOptions)
      //^ requires commandLineOptions.FileNames.Count > 0;
    {
      HostEnvironment hostEnvironment = new HostEnvironment();
      hostEnvironment.Errors += hostEnvironment.HandleErrors;
      hostEnvironment.displayFileName = true;
      List<IAssemblyReference> assemblyReferences = GetAssemblyReferences(commandLineOptions, hostEnvironment);
      List<IModuleReference> moduleReferences = new List<IModuleReference>();
      List<SpecSharpSourceDocument> programSources = new List<SpecSharpSourceDocument>(1);
      IName name = hostEnvironment.NameTable.GetNameFor(Path.GetFileNameWithoutExtension(commandLineOptions.FileNames[0]));
      SpecSharpAssembly assem = new SpecSharpAssembly(name, Path.GetFullPath(name.Value), hostEnvironment, commandLineOptions, assemblyReferences, moduleReferences, programSources);
      SpecSharpCompilationHelper helper = new SpecSharpCompilationHelper(assem.Compilation);
      foreach (string fileName in commandLineOptions.FileNames) {
        name = hostEnvironment.NameTable.GetNameFor(fileName);
        StreamReader instream = File.OpenText(fileName);
        programSources.Add(new SpecSharpSourceDocument(helper, name, Path.GetFullPath(fileName), instream));
      }

      if (assem.Compilation.HasErrors) return;
      var sourceLocationProvider = assem.Compilation.SourceLocationProvider;
      var localScopeProvider = assem.Compilation.LocalScopeProvider;
      using (var pdbWriter = new PdbWriter(Path.ChangeExtension(assem.Location, "pdb"), sourceLocationProvider)) {
        PeWriter.WritePeToStream(assem, hostEnvironment, File.Create(Path.ChangeExtension(assem.Location, "exe")), sourceLocationProvider, localScopeProvider, pdbWriter);
      }
    }
        static void Main(string[] argv)
        {
            if (argv == null || argv.Length < 1)
            {
                Console.WriteLine("Usage: Main <assemblys> [<outputPath>]");
            }

            using (var host = new PeReader.DefaultHost()) {
                var module = host.LoadUnitFrom(argv[0]) as IModule;
                if (module == null || module == Dummy.Module || module == Dummy.Assembly)
                {
                    throw new Exception(argv[0] + " is not a PE file containing a CLR assembly, or an error occurred when loading it.");
                }

                PdbReader pdbReader = null;
                string    pdbFile   = Path.ChangeExtension(module.Location, "pdb");
                if (File.Exists(pdbFile))
                {
                    using (var pdbStream = File.OpenRead(pdbFile)) {
                        pdbReader = new PdbReader(pdbStream, host);
                    }
                }
                else
                {
                    Console.WriteLine("Could not load the PDB file for '" + module.Name.Value + "' . Proceeding anyway.");
                }

                using (pdbReader) {
                    var copy = new MetadataDeepCopier(host).Copy(module);
                    var shadowFieldsAddedAssembly           = new ShadowFieldRewriter(host).Rewrite(copy);
                    var shadowFieldsAndMethodsAddedAssembly = new ShadowMethodRewriter(host).Rewrite(shadowFieldsAddedAssembly);
                    var rewrittenAssembly = new FinalizeMethodRewriter(host).Rewrite(shadowFieldsAndMethodsAddedAssembly);

                    var main = rewrittenAssembly.EntryPoint.ResolvedMethod;
                    if (main != Dummy.Method)
                    {
                        var body = main.Body as MethodBody;
                        if (body != null)
                        {
                            new AddGCWaitForFinalization(host, body).Rewrite();
                        }
                    }

                    var validator = new MetadataValidator(host);
                    validator.Validate(rewrittenAssembly as IAssembly);

                    string outputPath     = rewrittenAssembly.Location + ".meta";
                    var    outputFileName = Path.GetFileNameWithoutExtension(outputPath);

                    // Need to not pass in a local scope provider until such time as we have one that will use the mutator
                    // to remap things (like the type of a scope constant) from the original assembly to the mutated one.
                    using (var peStream = File.Create(outputPath)) {
                        using (var pdbWriter = new PdbWriter(outputFileName + ".pdb", pdbReader)) {
                            PeWriter.WritePeToStream(rewrittenAssembly, host, peStream, pdbReader, null, pdbWriter);
                        }
                    }
                }
            }
        }
Esempio n. 7
0
        private static void OutputFacadeToFile(string facadePath, HostEnvironment seedHost, Assembly facade, IAssembly contract, string pdbLocation = null)
        {
            bool   needsConversion    = false;
            string pdbOutputPath      = Path.Combine(facadePath, contract.Name + ".pdb");
            string finalPdbOutputPath = pdbOutputPath;

            // Use the filename (including extension .dll/.winmd) so people can have some control over the output facade file name.
            string facadeFileName   = Path.GetFileName(contract.Location);
            string facadeOutputPath = Path.Combine(facadePath, facadeFileName);

            using (Stream peOutStream = File.Create(facadeOutputPath))
            {
                if (pdbLocation != null)
                {
                    if (File.Exists(pdbLocation))
                    {
                        // Convert from portable to windows PDBs if necessary.  If we convert
                        // set the pdbOutput path to a *.windows.pdb file so we can convert it back
                        // to 'finalPdbOutputPath'.
                        if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
                        {
                            needsConversion = ConvertFromPortableIfNecessary(facade.Location, ref pdbLocation);
                        }
                        if (needsConversion)
                        {
                            // We want to keep the same file name for the PDB because it is used as a key when looking it up on a symbol server
                            string pdbOutputPathPdbDir = Path.Combine(Path.GetDirectoryName(pdbOutputPath), "WindowsPdb");
                            Directory.CreateDirectory(pdbOutputPathPdbDir);
                            pdbOutputPath = Path.Combine(pdbOutputPathPdbDir, Path.GetFileName(pdbOutputPath));
                        }

                        // do the main GenFacades logic (which today only works with windows PDBs).
                        using (Stream pdbReadStream = File.OpenRead(pdbLocation))
                            using (PdbReader pdbReader = new PdbReader(pdbReadStream, seedHost))
                                using (PdbWriter pdbWriter = new PdbWriter(pdbOutputPath, pdbReader))
                                {
                                    PeWriter.WritePeToStream(facade, seedHost, peOutStream, pdbReader, pdbReader, pdbWriter);
                                }
                    }
                    else
                    {
                        throw new FacadeGenerationException("Couldn't find the pdb at the given location: " + pdbLocation);
                    }
                }
                else
                {
                    PeWriter.WritePeToStream(facade, seedHost, peOutStream);
                }
            }

            // If we started with Portable PDBs we need to convert the output to portable again.
            // We have to do this after facadeOutputPath is closed for writing.
            if (needsConversion)
            {
                Trace.TraceInformation("Converting PDB generated by GenFacades " + pdbOutputPath + " to portable format " + finalPdbOutputPath);
                ConvertFromWindowsPdb(facadeOutputPath, pdbOutputPath, finalPdbOutputPath);
            }
        }
Esempio n. 8
0
        static int Main(string[] args)
        {
            if (args == null || args.Length < 1)
            {
                Console.WriteLine("Usage: ILMutator <assembly> [<outputPath>]");
                return(1);
            }

            using (var host = new PeReader.DefaultHost()) {
                IModule /*?*/ module = host.LoadUnitFrom(args[0]) as IModule;
                if (module == null || module is Dummy)
                {
                    Console.WriteLine(args[0] + " is not a PE file containing a CLR assembly, or an error occurred when loading it.");
                    return(1);
                }
                module = new MetadataDeepCopier(host).Copy(module);

                PdbReader /*?*/ pdbReader = null;
                string          pdbFile   = Path.ChangeExtension(module.Location, "pdb");
                if (File.Exists(pdbFile))
                {
                    using (var pdbStream = File.OpenRead(pdbFile)) {
                        pdbReader = new PdbReader(pdbStream, host);
                    }
                }
                else
                {
                    Console.WriteLine("Could not load the PDB file for '" + module.Name.Value + "' . Proceeding anyway.");
                }
                using (pdbReader) {
                    var       localScopeProvider = pdbReader == null ? null : new ILGenerator.LocalScopeProvider(pdbReader);
                    ILMutator mutator            = new ILMutator(host, pdbReader);
                    module = mutator.Rewrite(module);

                    string newName;
                    if (args.Length == 2)
                    {
                        newName = args[1];
                    }
                    else
                    {
                        var loc      = module.Location;
                        var path     = Path.GetDirectoryName(loc) ?? "";
                        var fileName = Path.GetFileNameWithoutExtension(loc);
                        var ext      = Path.GetExtension(loc);
                        newName = Path.Combine(path, fileName + "1" + ext);
                    }

                    using (var peStream = File.Create(newName)) {
                        using (var pdbWriter = new PdbWriter(Path.ChangeExtension(newName, ".pdb"), pdbReader)) {
                            PeWriter.WritePeToStream(module, host, peStream, pdbReader, localScopeProvider, pdbWriter);
                        }
                    }
                }
                return(0); // success
            }
        }
Esempio n. 9
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));
 }
Esempio n. 10
0
        private void Add(string name, SymbolInfo symbol)
        {
            int hashVal = (int)PdbWriter.Hash(name, HASH_MODULO);

            if (!m_occupiedHash[hashVal])
            {
                m_occupiedHash[hashVal] = true;
                m_table[hashVal]        = new List <KeyValuePair <string, SymbolInfo> >();
            }
            m_table[hashVal].Add(new KeyValuePair <string, SymbolInfo>(name, symbol));
            m_numGlobals++;
        }
Esempio n. 11
0
        static void Main(string[] args)
        {
            if (args == null || args.Length == 0)
            {
                Console.WriteLine("usage: EdgeProfiler [path]fileName.ext");
                return;
            }
            using (var host = new PeReader.DefaultHost()) {
                IModule /*?*/ module = host.LoadUnitFrom(args[0]) as IModule;
                if (module == null || module is Dummy)
                {
                    Console.WriteLine(args[0] + " is not a PE file containing a CLR module or assembly.");
                    return;
                }

                var coreIdentity = host.CoreAssemblySymbolicIdentity; //force host to let args[0] determine the target platform
                var profiler     = (IAssembly)host.LoadUnitFrom(typeof(Program).Assembly.Location);
                var logger       = (INamespaceTypeDefinition)UnitHelper.FindType(host.NameTable, profiler, "Logger");

                PdbReader /*?*/ pdbReader = null;
                string          pdbFile   = Path.ChangeExtension(module.Location, "pdb");
                if (File.Exists(pdbFile))
                {
                    using (var pdbStream = File.OpenRead(pdbFile)) {
                        pdbReader = new PdbReader(pdbStream, host);
                    }
                }

                using (pdbReader) {
                    var instrumentedModule = Instrumenter.GetInstrumented(host, module, pdbReader, logger);
                    var newRoot            = Path.GetFileNameWithoutExtension(module.Location) + ".instrumented";
                    var newName            = newRoot + Path.GetExtension(module.Location);
                    using (var peStream = File.Create(newName)) {
                        if (pdbReader == null)
                        {
                            PeWriter.WritePeToStream(instrumentedModule, host, peStream);
                        }
                        else
                        {
                            var localScopeProvider = new ILGenerator.LocalScopeProvider(pdbReader);
                            using (var pdbWriter = new PdbWriter(newRoot + ".pdb", pdbReader)) {
                                PeWriter.WritePeToStream(instrumentedModule, host, peStream, pdbReader, localScopeProvider, pdbWriter);
                            }
                        }
                    }
                }
            }
        }
        public void WriteToStream(IModuleInfo moduleInfo, FileStream stream, string filePath)
        {
            var module = (ModuleInfo)moduleInfo;

            if (module.PdbReader == null)
            {
                PeWriter.WritePeToStream(module.Module, _host, stream);
            }
            else
            {
                using (var pdbWriter = new PdbWriter(Path.ChangeExtension(filePath, "pdb"), module.PdbReader)) {
                    PeWriter.WritePeToStream(module.Module, _host, stream, module.PdbReader,
                                             module.PdbReader, pdbWriter);
                }
            }
        }
Esempio n. 13
0
        static void Main(string[] args)
        {
            if (args == null || args.Length != 2)
            {
                Console.WriteLine("usage: asmmeta <input> <output>");
                return;
            }
            HostEnvironment host   = new HostEnvironment();
            IModule /*?*/   module = host.LoadUnitFrom(args[0]) as IModule;

            if (module == null || module == Dummy.Module || module == Dummy.Assembly)
            {
                Console.WriteLine(args[0] + " is not a PE file containing a CLR module or assembly.");
                return;
            }

            string outputFile    = args[1];
            string outputPDBFile = Path.ChangeExtension(args[1], "pdb");

            PdbReader /*?*/ pdbReader = null;
            PdbWriter /*?*/ pdbWriter = null;
            string          pdbFile   = Path.ChangeExtension(module.Location, "pdb");

            if (File.Exists(pdbFile))
            {
                Stream pdbStream = File.OpenRead(pdbFile);
                pdbReader = new PdbReader(pdbStream, host);
                pdbWriter = new PdbWriter(Path.GetFullPath(outputPDBFile), pdbReader);
            }

            MetadataMutator mutator  = new MetadataMutator(host);
            IAssembly /*?*/ assembly = module as IAssembly;

            if (assembly != null)
            {
                var mutable = mutator.GetMutableCopy(assembly);
                mutable.Name = host.NameTable.GetNameFor(Path.GetFileNameWithoutExtension(args[1]));
                module       = mutator.Visit(mutable);
            }
            else
            {
                var mutable = mutator.GetMutableCopy(module);
                mutable.Name = host.NameTable.GetNameFor(Path.GetFileNameWithoutExtension(args[1]));
                module       = mutator.Visit(mutable);
            }
            PeWriter.WritePeToStream(module, host, File.Create(Path.GetFullPath(outputFile)), pdbReader, pdbReader, pdbWriter);
        }
Esempio n. 14
0
        /// <summary>
        /// Write the PDB file. The caller should send the PDB events before and after calling this
        /// method.
        /// </summary>
        protected void WritePdbFile()
        {
            if (!CanWritePdb())
            {
                return;
            }
            if (debugDirectory == null)
            {
                throw new InvalidOperationException("debugDirectory is null but WritePdb is true");
            }

            var pdbState = Module.PdbState;

            if (pdbState == null)
            {
                Error("TheOptions.WritePdb is true but module has no PdbState");
                debugDirectory.DontWriteAnything = true;
                return;
            }

            var symWriter = GetSymbolWriter2();

            if (symWriter == null)
            {
                Error("Could not create a PDB symbol writer. A Windows OS might be required.");
                debugDirectory.DontWriteAnything = true;
                return;
            }

            var pdbWriter = new PdbWriter(symWriter, pdbState, metaData);

            try
            {
                pdbWriter.Logger = TheOptions.Logger;
                pdbWriter.Write();

                debugDirectory.Data          = pdbWriter.GetDebugInfo(out debugDirectory.debugDirData);
                debugDirectory.TimeDateStamp = GetTimeDateStamp();
                pdbWriter.Dispose();
            }
            catch
            {
                pdbWriter.Dispose();
                DeleteFileNoThrow(createdPdbFileName);
                throw;
            }
        }
Esempio n. 15
0
        public void Save(string fileName)
        {
            var pdbName = Path.ChangeExtension(fileName, "pdb");

            using (var peStream = File.Create(fileName))
            {
                if (this.PdbReader == null)
                {
                    PeWriter.WritePeToStream(this.Module, this.Host, peStream);
                }
                else
                {
                    using (var pdbWriter = new PdbWriter(pdbName, this.PdbReader))
                        PeWriter.WritePeToStream(this.Module, this.Host, peStream, this.PdbReader, this.PdbReader, pdbWriter);
                }
            }
        }
Esempio n. 16
0
        private static void RewriteBinary(
            Assembly copy,
            AssemblyReport assemblyReport,
            MetadataReaderHost host,
            string outputPath,
            MethodRemoval methodRemoval,
            StubMethodBodyEmitter stubEmitter)
        {
            /* This is an attempt to decouple the MethodRemoval commandline options
             * from the tree shaker, but it doesn't really seem to be working.
             * Might be better to just pass the method removal directly to
             * the rewriter.
             */

            bool removeMethods  = (methodRemoval == MethodRemoval.Remove);
            bool fullDebugStubs = (methodRemoval == MethodRemoval.Debug);
            bool dryRun         = (methodRemoval == MethodRemoval.None);

            PdbReader /*?*/ pdbReader = null;
            string          pdbFile   = Path.ChangeExtension(copy.Location, "pdb");

            if (File.Exists(pdbFile))
            {
                using (var pdbStream = File.OpenRead(pdbFile)) {
                    pdbReader = new PdbReader(pdbStream, host);
                }
            }
            else
            {
                Console.WriteLine("Could not load the PDB file for '" + copy.Name.Value + "' . Proceeding anyway.");
            }

            using (pdbReader) {
                var localScopeProvider = pdbReader == null ? null : new ILGenerator.LocalScopeProvider(pdbReader);
                var pdbPath            = Path.ChangeExtension(outputPath, ".pdb");
                var outputFileName     = Path.GetFileNameWithoutExtension(outputPath);
                using (var peStream = File.Create(outputPath)) {
                    using (var pdbWriter = new PdbWriter(pdbPath, pdbReader)) {
                        var       rewriter      = new TreeShakingRewriter(host, assemblyReport, dryRun, removeMethods, fullDebugStubs, stubEmitter);
                        IAssembly rewrittenCopy = rewriter.Rewrite(copy);

                        PeWriter.WritePeToStream(rewrittenCopy, host, peStream, pdbReader, localScopeProvider, pdbWriter);
                    }
                }
            }
        }
Esempio n. 17
0
 private static void Compile(string fileName) {
   HostEnvironment hostEnvironment = new HostEnvironment();
   IName name = hostEnvironment.NameTable.GetNameFor(fileName);
   IDictionary<string, string> options = new Dictionary<string, string>();
   List<IAssemblyReference> assemblyReferences = new List<IAssemblyReference>();
   List<IModuleReference> moduleReferences = new List<IModuleReference>();
   assemblyReferences.Add(hostEnvironment.LoadAssembly(hostEnvironment.CoreAssemblySymbolicIdentity));
   assemblyReferences.Add((IAssembly)hostEnvironment.LoadUnitFrom(typeof(Microsoft.SmallBasic.Library.ConsoleWindow).Assembly.Location));
   StreamReader instream = File.OpenText(fileName);
   List<SmallBasicDocument> programSources = new List<SmallBasicDocument>(1);
   SmallBasicAssembly assem = new SmallBasicAssembly(name, Path.GetFullPath(fileName), hostEnvironment, options, assemblyReferences, moduleReferences, programSources);
   SmallBasicCompilationHelper helper = new SmallBasicCompilationHelper(assem.Compilation);
   programSources.Add(new SmallBasicDocument(helper, name, Path.GetFullPath(fileName), instream));
   var exeFile = File.Create(Path.ChangeExtension(fileName, "exe"));
   var sourceLocationProvider = assem.Compilation.SourceLocationProvider;
   //var localScopeProvider = assem.Compilation.LocalScopeProvider;
   using (var pdbWriter = new PdbWriter(Path.ChangeExtension(fileName, "pdb"), sourceLocationProvider)) {
     PeWriter.WritePeToStream(assem, hostEnvironment, exeFile, sourceLocationProvider, null, pdbWriter);
   }
 }
Esempio n. 18
0
        static void Main(string[] args)
        {
            if (args == null || args.Length == 0)
            {
                Console.WriteLine("usage: PeToPe [path]fileName.ext");
                return;
            }

            using (var host = new PeReader.DefaultHost()) {
                var module = host.LoadUnitFrom(args[0]) as IModule;
                if (module == null || module is Dummy)
                {
                    Console.WriteLine(args[0] + " is not a PE file containing a CLR module or assembly.");
                    return;
                }

                PdbReader /*?*/ pdbReader = null;
                string          pdbFile   = module.DebugInformationLocation;
                if (string.IsNullOrEmpty(pdbFile))
                {
                    pdbFile = Path.ChangeExtension(module.Location, "pdb");
                }
                if (File.Exists(pdbFile))
                {
                    Stream pdbStream = File.OpenRead(pdbFile);
                    pdbReader = new PdbReader(pdbStream, host);
                }

                using (pdbReader) {
                    //Make a mutable copy of the module.
                    var copier        = new MetadataDeepCopier(host);
                    var mutableModule = copier.Copy(module);

                    //Traverse the module. In a real application the MetadataVisitor and/or the MetadataTravers will be subclasses
                    //and the traversal will gather information to use during rewriting.
                    var traverser = new MetadataTraverser()
                    {
                        PreorderVisitor = new MetadataVisitor(), TraverseIntoMethodBodies = true
                    };
                    traverser.Traverse(mutableModule);

                    //Rewrite the mutable copy. In a real application the rewriter would be a subclass of MetadataRewriter that actually does something.
                    var rewriter        = new MetadataRewriter(host);
                    var rewrittenModule = rewriter.Rewrite(mutableModule);

                    //Write out rewritten module.
                    using (var peStream = File.Create(rewrittenModule.Location + ".pe")) {
                        if (pdbReader == null)
                        {
                            PeWriter.WritePeToStream(rewrittenModule, host, peStream);
                        }
                        else
                        {
                            //Note that the default copier and rewriter preserves the locations collections, so the original pdbReader is still a valid ISourceLocationProvider.
                            //However, if IL instructions were rewritten, the pdbReader will no longer be an accurate ILocalScopeProvider
                            using (var pdbWriter = new PdbWriter(pdbFile + ".pdb", pdbReader)) {
                                PeWriter.WritePeToStream(rewrittenModule, host, peStream, pdbReader, pdbReader, pdbWriter);
                            }
                        }
                    }
                }
            }
        }
Esempio n. 19
0
		internal void Write(PdbWriter writer)
		{
			writer.Write(this);
		}
Esempio n. 20
0
        static void Main(string[] args)
        {
            if (args == null || args.Length == 0)
            {
                Console.WriteLine("usage: PeToPe [path]fileName.ext [decompile] [noStack]");
                return;
            }
            bool decompile = args.Length >= 2;
            bool noStack   = args.Length >= 3;

            using (var host = new HostEnvironment()) {
                //Read the Metadata Model from the PE file
                var module = host.LoadUnitFrom(args[0]) as IModule;
                if (module == null || module is Dummy)
                {
                    Console.WriteLine(args[0] + " is not a PE file containing a CLR module or assembly.");
                    return;
                }

                //Get a PDB reader if there is a PDB file.
                PdbReader /*?*/ pdbReader = null;
                string          pdbFile   = module.DebugInformationLocation;
                if (string.IsNullOrEmpty(pdbFile) || !File.Exists(pdbFile))
                {
                    pdbFile = Path.ChangeExtension(module.Location, "pdb");
                }
                if (File.Exists(pdbFile))
                {
                    using (var pdbStream = File.OpenRead(pdbFile)) {
                        pdbReader = new PdbReader(pdbStream, host);
                    }
                }
                using (pdbReader) {
                    ISourceLocationProvider sourceLocationProvider = pdbReader;
                    ILocalScopeProvider     localScopeProvider     = pdbReader;
                    if (decompile)
                    {
                        //Construct a Code Model from the Metadata model via decompilation
                        var options = DecompilerOptions.AnonymousDelegates | DecompilerOptions.Iterators | DecompilerOptions.Loops;
                        if (noStack)
                        {
                            options |= DecompilerOptions.Unstack;
                        }
                        module = Decompiler.GetCodeModelFromMetadataModel(host, module, pdbReader, options);
                        if (pdbReader != null)
                        {
                            localScopeProvider = new Decompiler.LocalScopeProvider(pdbReader);
                        }
                    }

                    MetadataRewriter   rewriter;
                    MetadataDeepCopier copier;
                    if (decompile)
                    {
                        copier   = new CodeDeepCopier(host, pdbReader, pdbReader);
                        rewriter = new CodeRewriter(host);
                    }
                    else
                    {
                        copier   = new MetadataDeepCopier(host);
                        rewriter = new MetadataRewriter(host);
                    }

                    var mutableModule = copier.Copy(module);
                    module = rewriter.Rewrite(mutableModule);

                    //var validator = new MetadataValidator(host);
                    //List<Microsoft.Cci.ErrorEventArgs> errorEvents = new List<Microsoft.Cci.ErrorEventArgs>();
                    //host.Errors += (object sender, Microsoft.Cci.ErrorEventArgs e) => errorEvents.Add(e);
                    //var assem = module as IAssembly;
                    //validator.Validate(assem);
                    //if (errorEvents.Count != 0)
                    //{
                    //    foreach (var e in errorEvents)
                    //    {
                    //        foreach (var err in e.Errors)
                    //        {
                    //            Console.WriteLine(err.Message);
                    //        }
                    //    }
                    //}

#if DEBUG
                    var newRoot = Path.GetFileNameWithoutExtension(module.Location) + "1";
                    var newName = newRoot + Path.GetExtension(module.Location);
                    using (Stream peStream = File.Create(newName)) {
                        if (pdbReader == null)
                        {
                            PeWriter.WritePeToStream(module, host, peStream);
                        }
                        else
                        {
                            using (var pdbWriter = new PdbWriter(newRoot + ".pdb", pdbReader, emitTokenSourceInfo: true)) {
                                PeWriter.WritePeToStream(module, host, peStream, sourceLocationProvider, localScopeProvider, pdbWriter);
                            }
                        }
                    }
#else
                    using (Stream peStream = File.Create(module.Location)) {
                        if (pdbReader == null)
                        {
                            PeWriter.WritePeToStream(module, host, peStream);
                        }
                        else
                        {
                            using (var pdbWriter = new PdbWriter(pdbFile, pdbReader, emitTokenSourceInfo: true)) {
                                PeWriter.WritePeToStream(module, host, peStream, sourceLocationProvider, localScopeProvider, pdbWriter);
                            }
                        }
                    }
#endif
                }
            }
        }
Esempio n. 21
0
        /// <summary>
        /// Outputs specified headers, sections, methods or runtime functions for one ReadyToRun image
        /// </summary>
        /// <param name="r2r">The structure containing the info of the ReadyToRun image</param>
        public void Dump(ReadyToRunReader r2r)
        {
            _dumper.Begin();
            bool standardDump = !(_options.EntryPoints || _options.CreatePDB);

            if (_options.Header && standardDump)
            {
                _dumper.WriteDivider("R2R Header");
                _dumper.DumpHeader(true);
            }

            bool haveQuery = false;

            if (_options.Section != null)
            {
                haveQuery = true;
                QuerySection(r2r, _options.Section);
            }

            if (_options.RuntimeFunction != null)
            {
                haveQuery = true;
                QueryRuntimeFunction(r2r, _options.RuntimeFunction);
            }

            if (_options.Query != null)
            {
                haveQuery = true;
                QueryMethod(r2r, "R2R Methods by Query", _options.Query, true);
            }

            if (_options.Keyword != null)
            {
                haveQuery = true;
                QueryMethod(r2r, "R2R Methods by Keyword", _options.Keyword, false);
            }

            if (!haveQuery)
            {
                // Dump all sections and methods if no queries specified
                if (_options.EntryPoints)
                {
                    _dumper.DumpEntryPoints();
                }

                if (_options.CreatePDB)
                {
                    string pdbPath = _options.PdbPath;
                    if (String.IsNullOrEmpty(pdbPath))
                    {
                        pdbPath = Path.GetDirectoryName(r2r.Filename);
                    }
                    var pdbWriter = new PdbWriter(pdbPath, PDBExtraData.None);
                    pdbWriter.WritePDBData(r2r.Filename, ProducePdbWriterMethods(r2r));
                }

                if (!_options.Header && standardDump)
                {
                    _dumper.DumpAllMethods();
                }
            }

            _dumper.End();
        }
		internal void Write(PdbWriter writer)
		{
			foreach (var function in functions)
				function.Write(writer);
		}
Esempio n. 23
0
 public CodeModelRoundTripTests()
 {
     pdbReader = null;
     pdbWriter = null;
     host      = new HostEnvironment();
 }
        internal void Convert(PEReader peReader, MetadataReader pdbReader, PdbWriter <TDocumentWriter> pdbWriter, PdbConversionOptions options)
        {
            if (!SymReaderHelpers.TryReadPdbId(peReader, out var pePdbId, out int peAge))
            {
                throw new InvalidDataException(ConverterResources.SpecifiedPEFileHasNoAssociatedPdb);
            }

            if (!new BlobContentId(pdbReader.DebugMetadataHeader.Id).Equals(pePdbId))
            {
                throw new InvalidDataException(ConverterResources.PdbNotMatchingDebugDirectory);
            }

            string vbDefaultNamespace             = MetadataUtilities.GetVisualBasicDefaultNamespace(pdbReader);
            bool   vbSemantics                    = vbDefaultNamespace != null;
            string vbDefaultNamespaceImportString = string.IsNullOrEmpty(vbDefaultNamespace) ? null : "*" + vbDefaultNamespace;

            var metadataReader = peReader.GetMetadataReader();
            var metadataModel  = new MetadataModel(metadataReader, vbSemantics);

            var documentWriters         = new ArrayBuilder <TDocumentWriter>(pdbReader.Documents.Count);
            var documentNames           = new ArrayBuilder <string>(pdbReader.Documents.Count);
            var symSequencePointBuilder = new SequencePointsBuilder(capacity: 64);
            var declaredExternAliases   = new HashSet <string>();
            var importStringsBuilder    = new List <string>();
            var importGroups            = new List <int>();
            var cdiBuilder          = new BlobBuilder();
            var dynamicLocals       = new List <(string LocalName, byte[] Flags, int Count, int SlotIndex)>();
            var tupleLocals         = new List <(string LocalName, int SlotIndex, int ScopeStart, int ScopeEnd, ImmutableArray <string> Names)>();
            var openScopeEndOffsets = new Stack <int>();

            // state for calculating import string forwarding:
            var lastImportScopeHandle          = default(ImportScopeHandle);
            var vbLastImportScopeNamespace     = default(string);
            var lastImportScopeMethodDefHandle = default(MethodDefinitionHandle);
            var importStringsMap = new Dictionary <ImmutableArray <string>, MethodDefinitionHandle>(SequenceComparer <string> .Instance);

            var aliasedAssemblyRefs = GetAliasedAssemblyRefs(pdbReader);

            foreach (var documentHandle in pdbReader.Documents)
            {
                var document     = pdbReader.GetDocument(documentHandle);
                var languageGuid = pdbReader.GetGuid(document.Language);
                var name         = pdbReader.GetString(document.Name);
                documentNames.Add(name);

                documentWriters.Add(pdbWriter.DefineDocument(
                                        name: name,
                                        language: languageGuid,
                                        type: s_documentTypeText,
                                        vendor: GetLanguageVendorGuid(languageGuid),
                                        algorithmId: pdbReader.GetGuid(document.HashAlgorithm),
                                        checksum: pdbReader.GetBlobBytes(document.Hash)));
            }

            var        localScopeEnumerator = pdbReader.LocalScopes.GetEnumerator();
            LocalScope?currentLocalScope    = NextLocalScope();

            LocalScope?NextLocalScope() =>
            localScopeEnumerator.MoveNext() ? pdbReader.GetLocalScope(localScopeEnumerator.Current) : default(LocalScope?);

            // Handle of the method that is gonna contain list of AssemblyRef aliases.
            // Other methods will forward to it.
            var methodDefHandleWithAssemblyRefAliases = default(MethodDefinitionHandle);

            foreach (var methodDebugInfoHandle in pdbReader.MethodDebugInformation)
            {
                var methodDebugInfo = pdbReader.GetMethodDebugInformation(methodDebugInfoHandle);
                var methodDefHandle = methodDebugInfoHandle.ToDefinitionHandle();
                int methodToken     = MetadataTokens.GetToken(methodDefHandle);
                var methodDef       = metadataReader.GetMethodDefinition(methodDefHandle);
#if DEBUG
                var declaringTypeDef = metadataReader.GetTypeDefinition(methodDef.GetDeclaringType());
                var typeName         = metadataReader.GetString(declaringTypeDef.Name);
                var methodName       = metadataReader.GetString(methodDef.Name);
#endif
                bool methodOpened = false;

                var methodBodyOpt = (methodDef.RelativeVirtualAddress != 0 && (methodDef.ImplAttributes & MethodImplAttributes.CodeTypeMask) == MethodImplAttributes.Managed) ?
                                    peReader.GetMethodBody(methodDef.RelativeVirtualAddress) : null;

                var  vbCurrentMethodNamespace = vbSemantics ? GetMethodNamespace(metadataReader, methodDef) : null;
                var  moveNextHandle           = metadataModel.FindStateMachineMoveNextMethod(methodDefHandle, vbSemantics);
                bool isKickOffMethod          = !moveNextHandle.IsNil;

                var forwardImportScopesToMethodDef = default(MethodDefinitionHandle);
                Debug.Assert(dynamicLocals.Count == 0);
                Debug.Assert(tupleLocals.Count == 0);
                Debug.Assert(openScopeEndOffsets.Count == 0);

                void LazyOpenMethod()
                {
                    if (!methodOpened)
                    {
#if DEBUG
                        Debug.WriteLine($"Open Method '{typeName}::{methodName}' {methodToken:X8}");
#endif
                        pdbWriter.OpenMethod(methodToken);
                        methodOpened = true;
                    }
                }

                void CloseOpenScopes(int currentScopeStartOffset)
                {
                    // close all open scopes that end before this scope starts:
                    while (openScopeEndOffsets.Count > 0 && currentScopeStartOffset >= openScopeEndOffsets.Peek())
                    {
                        int scopeEnd = openScopeEndOffsets.Pop();
                        Debug.WriteLine($"Close Scope [.., {scopeEnd})");

                        // Note that the root scope end is not end-inclusive in VB:
                        pdbWriter.CloseScope(AdjustEndScopeOffset(scopeEnd, isEndInclusive: vbSemantics && openScopeEndOffsets.Count > 0));
                    }
                }

                bool isFirstMethodScope = true;
                while (currentLocalScope.HasValue && currentLocalScope.Value.Method == methodDefHandle)
                {
                    // kickoff methods don't have any scopes emitted to Windows PDBs
                    if (methodBodyOpt == null)
                    {
                        ReportDiagnostic(PdbDiagnosticId.MethodAssociatedWithLocalScopeHasNoBody, MetadataTokens.GetToken(localScopeEnumerator.Current));
                    }
                    else if (!isKickOffMethod)
                    {
                        LazyOpenMethod();

                        var localScope = currentLocalScope.Value;
                        CloseOpenScopes(localScope.StartOffset);

                        Debug.WriteLine($"Open Scope [{localScope.StartOffset}, {localScope.EndOffset})");
                        pdbWriter.OpenScope(localScope.StartOffset);
                        openScopeEndOffsets.Push(localScope.EndOffset);

                        if (isFirstMethodScope)
                        {
                            if (lastImportScopeHandle == localScope.ImportScope && vbLastImportScopeNamespace == vbCurrentMethodNamespace)
                            {
                                // forward to a method that has the same imports:
                                forwardImportScopesToMethodDef = lastImportScopeMethodDefHandle;
                            }
                            else
                            {
                                Debug.Assert(importStringsBuilder.Count == 0);
                                Debug.Assert(declaredExternAliases.Count == 0);
                                Debug.Assert(importGroups.Count == 0);

                                AddImportStrings(importStringsBuilder, importGroups, declaredExternAliases, pdbReader, metadataModel, localScope.ImportScope, aliasedAssemblyRefs, vbDefaultNamespaceImportString, vbCurrentMethodNamespace, vbSemantics);
                                var importStrings = importStringsBuilder.ToImmutableArray();
                                importStringsBuilder.Clear();

                                if (importStringsMap.TryGetValue(importStrings, out forwardImportScopesToMethodDef))
                                {
                                    // forward to a method that has the same imports:
                                    lastImportScopeMethodDefHandle = forwardImportScopesToMethodDef;
                                }
                                else
                                {
                                    // attach import strings to the current method:
                                    WriteImports(pdbWriter, importStrings);
                                    lastImportScopeMethodDefHandle  = methodDefHandle;
                                    importStringsMap[importStrings] = methodDefHandle;
                                }

                                lastImportScopeHandle      = localScope.ImportScope;
                                vbLastImportScopeNamespace = vbCurrentMethodNamespace;
                            }

                            if (vbSemantics && !forwardImportScopesToMethodDef.IsNil)
                            {
                                pdbWriter.UsingNamespace("@" + MetadataTokens.GetToken(forwardImportScopesToMethodDef));
                            }

                            // This is the method that's gonna have AssemblyRef aliases attached:
                            if (methodDefHandleWithAssemblyRefAliases.IsNil)
                            {
                                foreach (var(assemblyRefHandle, alias) in aliasedAssemblyRefs)
                                {
                                    var assemblyRef = metadataReader.GetAssemblyReference(assemblyRefHandle);
                                    pdbWriter.UsingNamespace("Z" + alias + " " + AssemblyDisplayNameBuilder.GetAssemblyDisplayName(metadataReader, assemblyRef));
                                }
                            }
                        }

                        foreach (var localVariableHandle in localScope.GetLocalVariables())
                        {
                            var    variable = pdbReader.GetLocalVariable(localVariableHandle);
                            string name     = pdbReader.GetString(variable.Name);

                            if (name.Length > MaxEntityNameLength)
                            {
                                ReportDiagnostic(PdbDiagnosticId.LocalConstantNameTooLong, MetadataTokens.GetToken(localVariableHandle));
                                continue;
                            }

                            if (methodBodyOpt.LocalSignature.IsNil)
                            {
                                ReportDiagnostic(PdbDiagnosticId.MethodContainingLocalVariablesHasNoLocalSignature, methodToken);
                                continue;
                            }

                            // TODO: translate hoisted variable scopes to dummy VB hoisted state machine locals (https://github.com/dotnet/roslyn/issues/8473)

                            pdbWriter.DefineLocalVariable(variable.Index, name, variable.Attributes, MetadataTokens.GetToken(methodBodyOpt.LocalSignature));

                            var dynamicFlags = MetadataUtilities.ReadDynamicCustomDebugInformation(pdbReader, localVariableHandle);
                            if (TryGetDynamicLocal(name, variable.Index, dynamicFlags, out var dynamicLocal))
                            {
                                dynamicLocals.Add(dynamicLocal);
                            }

                            var tupleElementNames = MetadataUtilities.ReadTupleCustomDebugInformation(pdbReader, localVariableHandle);
                            if (!tupleElementNames.IsDefaultOrEmpty)
                            {
                                tupleLocals.Add((name, SlotIndex: variable.Index, ScopeStart: 0, ScopeEnd: 0, Names: tupleElementNames));
                            }
                        }

                        foreach (var localConstantHandle in localScope.GetLocalConstants())
                        {
                            var    constant = pdbReader.GetLocalConstant(localConstantHandle);
                            string name     = pdbReader.GetString(constant.Name);

                            if (name.Length > MaxEntityNameLength)
                            {
                                ReportDiagnostic(PdbDiagnosticId.LocalConstantNameTooLong, MetadataTokens.GetToken(localConstantHandle));
                                continue;
                            }

                            var(value, signature) = PortableConstantSignature.GetConstantValueAndSignature(pdbReader, localConstantHandle, metadataReader.GetQualifiedTypeName);
                            if (!metadataModel.TryGetStandaloneSignatureHandle(signature, out var constantSignatureHandle))
                            {
                                // Signature will be unspecified. At least we store the name and the value.
                                constantSignatureHandle = default(StandaloneSignatureHandle);
                            }

                            pdbWriter.DefineLocalConstant(name, value, MetadataTokens.GetToken(constantSignatureHandle));

                            var dynamicFlags = MetadataUtilities.ReadDynamicCustomDebugInformation(pdbReader, localConstantHandle);
                            if (TryGetDynamicLocal(name, 0, dynamicFlags, out var dynamicLocal))
                            {
                                dynamicLocals.Add(dynamicLocal);
                            }

                            var tupleElementNames = MetadataUtilities.ReadTupleCustomDebugInformation(pdbReader, localConstantHandle);
                            if (!tupleElementNames.IsDefaultOrEmpty)
                            {
                                // Note that the end offset of tuple locals is always end-exclusive, regardless of whether the PDB uses VB semantics or not.
                                tupleLocals.Add((name, SlotIndex: -1, ScopeStart: localScope.StartOffset, ScopeEnd: localScope.EndOffset, Names: tupleElementNames));
                            }
                        }
                    }

                    currentLocalScope  = NextLocalScope();
                    isFirstMethodScope = false;
                }

                bool hasAnyScopes = !isFirstMethodScope;

                CloseOpenScopes(int.MaxValue);
                if (openScopeEndOffsets.Count > 0)
                {
                    ReportDiagnostic(PdbDiagnosticId.LocalScopeRangesNestingIsInvalid, methodToken);
                    openScopeEndOffsets.Clear();
                }

                if (!methodDebugInfo.SequencePointsBlob.IsNil)
                {
                    LazyOpenMethod();
                    WriteSequencePoints(pdbWriter, documentWriters, symSequencePointBuilder, methodDebugInfo.GetSequencePoints(), methodToken);
                }

                // async method data:
                var asyncData = MetadataUtilities.ReadAsyncMethodData(pdbReader, methodDebugInfoHandle);
                if (!asyncData.IsNone)
                {
                    LazyOpenMethod();
                    pdbWriter.SetAsyncInfo(
                        moveNextMethodToken: methodToken,
                        kickoffMethodToken: MetadataTokens.GetToken(asyncData.KickoffMethod),
                        catchHandlerOffset: asyncData.CatchHandlerOffset,
                        yieldOffsets: asyncData.YieldOffsets.ToArray(),
                        resumeOffsets: asyncData.ResumeOffsets.ToArray());
                }

                // custom debug information:
                var cdiEncoder = new CustomDebugInfoEncoder(cdiBuilder);
                if (isKickOffMethod)
                {
                    cdiEncoder.AddStateMachineTypeName(GetIteratorTypeName(metadataReader, moveNextHandle));
                }
                else
                {
                    if (!vbSemantics && hasAnyScopes)
                    {
                        if (forwardImportScopesToMethodDef.IsNil)
                        {
                            // record the number of import strings in each scope:
                            cdiEncoder.AddUsingGroups(importGroups);

                            if (!methodDefHandleWithAssemblyRefAliases.IsNil)
                            {
                                // forward assembly ref aliases to the first method:
                                cdiEncoder.AddForwardModuleInfo(methodDefHandleWithAssemblyRefAliases);
                            }
                        }
                        else
                        {
                            // forward all imports to another method:
                            cdiEncoder.AddForwardMethodInfo(forwardImportScopesToMethodDef);
                        }
                    }

                    var hoistedLocalScopes = GetStateMachineHoistedLocalScopes(pdbReader, methodDefHandle);
                    if (!hoistedLocalScopes.IsDefault)
                    {
                        cdiEncoder.AddStateMachineHoistedLocalScopes(hoistedLocalScopes);
                    }

                    if (dynamicLocals.Count > 0)
                    {
                        cdiEncoder.AddDynamicLocals(dynamicLocals);
                        dynamicLocals.Clear();
                    }

                    if (tupleLocals.Count > 0)
                    {
                        cdiEncoder.AddTupleElementNames(tupleLocals);
                        tupleLocals.Clear();
                    }
                }

                importGroups.Clear();

                // the following blobs map 1:1
                CopyCustomDebugInfoRecord(ref cdiEncoder, pdbReader, methodDefHandle, PortableCustomDebugInfoKinds.EncLocalSlotMap, CustomDebugInfoKind.EditAndContinueLocalSlotMap);
                CopyCustomDebugInfoRecord(ref cdiEncoder, pdbReader, methodDefHandle, PortableCustomDebugInfoKinds.EncLambdaAndClosureMap, CustomDebugInfoKind.EditAndContinueLambdaMap);

                if (cdiEncoder.RecordCount > 0)
                {
                    LazyOpenMethod();
                    pdbWriter.DefineCustomMetadata(cdiEncoder.ToArray());
                }

                cdiBuilder.Clear();

                if (methodOpened && aliasedAssemblyRefs.Length > 0 && !isKickOffMethod && methodDefHandleWithAssemblyRefAliases.IsNil)
                {
                    methodDefHandleWithAssemblyRefAliases = methodDefHandle;
                }

                if (methodOpened)
                {
                    Debug.WriteLine($"Close Method {methodToken:X8}");
                    pdbWriter.CloseMethod();
                }
            }

            if (!pdbReader.DebugMetadataHeader.EntryPoint.IsNil)
            {
                pdbWriter.SetEntryPoint(MetadataTokens.GetToken(pdbReader.DebugMetadataHeader.EntryPoint));
            }

            var sourceLinkHandle = pdbReader.GetCustomDebugInformation(EntityHandle.ModuleDefinition, PortableCustomDebugInfoKinds.SourceLink);
            if (!sourceLinkHandle.IsNil)
            {
                if ((options & PdbConversionOptions.SuppressSourceLinkConversion) == 0)
                {
                    ConvertSourceServerData(pdbReader.GetStringUTF8(sourceLinkHandle), pdbWriter, documentNames);
                }
                else
                {
                    pdbWriter.SetSourceLinkData(pdbReader.GetBlobBytes(sourceLinkHandle));
                }
            }

            SymReaderHelpers.GetWindowsPdbSignature(pdbReader.DebugMetadataHeader.Id, out var guid, out var stamp, out var age);
            pdbWriter.UpdateSignature(guid, stamp, age);
        }
Esempio n. 25
0
        public bool TrimBinaries(string sourceDir, string outputDir)
        {
            bool fSuccess = true;

            foreach (TrimAssembly trimAssembly in _includeSet.GetAllAssemblies())
            {
                _currentTrimAssembly = trimAssembly;

                try
                {
                    string sourceFile = Path.Combine(sourceDir, trimAssembly.Name + ".dll");
                    string outputFile = Path.Combine(outputDir, trimAssembly.Name + ".dll");

                    Console.WriteLine("loading assembly '" + sourceFile + "'");
                    IModule module = host.LoadUnitFrom(sourceFile) as IModule;

                    if (module == null || module == Dummy.Module || module == Dummy.Assembly)
                    {
                        throw new Exception(sourceFile + " is not a PE file containing a CLR module or assembly, or an error occurred when loading it.");
                    }

                    // Working around bug
                    DummyTraverser dummyTraverser = new DummyTraverser();

                    PdbReader pdbReader     = null;
                    PdbWriter pdbWriter     = null;
                    string    pdbSourceFile = Path.ChangeExtension(sourceFile, "pdb");
                    string    pdbOutputFile = Path.ChangeExtension(outputFile, "pdb");
                    if (File.Exists(pdbSourceFile))
                    {
                        Stream pdbStream = File.OpenRead(pdbSourceFile);
                        pdbReader = new PdbReader(pdbStream, host);
                        pdbWriter = new PdbWriter(Path.GetFullPath(pdbOutputFile), pdbReader);
                    }

                    IAssembly /*?*/ assembly = module as IAssembly;
                    if (assembly != null)
                    {
                        dummyTraverser.Visit(assembly);
                        module = this.Rewrite(assembly);
                    }
                    else
                    {
                        dummyTraverser.Visit(module);
                        module = this.Rewrite(module);
                    }
                    PeWriter.WritePeToStream(module, host, File.Create(outputFile), pdbReader, pdbReader, pdbWriter);
                }
                catch (Exception e)
                {
                    Console.WriteLine(trimAssembly.Key + ": " + e.Message);
                    throw;
                }
            }

            if (!fSuccess)
            {
                Console.Error.WriteLine(String.Format("At least one of the assemblies could not be processed!"));
            }

            return(fSuccess);
        }
Esempio n. 26
0
        static void Main(string[] args)
        {
            if (args == null || args.Length == 0)
            {
                Console.WriteLine("usage: PeToPe [path]fileName.ext [noStack]");
                return;
            }
            bool noStack = args.Length == 2;

            using (var host = new PeReader.DefaultHost()) {
                //Read the Metadata Model from the PE file
                var module = host.LoadUnitFrom(args[0]) as IModule;
                if (module == null || module == Dummy.Module || module == Dummy.Assembly)
                {
                    Console.WriteLine(args[0] + " is not a PE file containing a CLR module or assembly.");
                    return;
                }

                //Get a PDB reader if there is a PDB file.
                PdbReader /*?*/ pdbReader = null;
                string          pdbFile   = Path.ChangeExtension(module.Location, "pdb");
                if (File.Exists(pdbFile))
                {
                    Stream pdbStream = File.OpenRead(pdbFile);
                    pdbReader = new PdbReader(pdbStream, host);
                }
                using (pdbReader) {
                    //Construct a Code Model from the Metadata model via decompilation
                    var options = DecompilerOptions.None;
                    if (noStack)
                    {
                        options |= DecompilerOptions.Unstack;
                    }
                    var decompiledModule = Decompiler.GetCodeModelFromMetadataModel(host, module, pdbReader, options);
                    ISourceLocationProvider sourceLocationProvider = pdbReader; //The decompiler preserves the Locations from the IOperation values, so the PdbReader still works.
                    //Recompiling the CodeModel to IL might change the IL offsets, so a new provider is needed.
                    ILocalScopeProvider localScopeProvider = new Decompiler.LocalScopeProvider(pdbReader);

                    //Get a mutable copy of the Code Model. The ISourceLocationProvider is needed to provide copied source method bodies with the
                    //ability to find out where to mark sequence points when compiling themselves back into IL.
                    //(ISourceMethodBody does not know about the Source Model, so this information must be provided explicitly.)
                    var copier        = new CodeDeepCopier(host, sourceLocationProvider);
                    var mutableModule = copier.Copy(decompiledModule);

                    //Traverse the mutable copy. In a real application the traversal will collect information to be used during rewriting.
                    var traverser = new CodeTraverser()
                    {
                        PreorderVisitor = new CodeVisitor()
                    };
                    traverser.Traverse(mutableModule);

                    //Rewrite the mutable Code Model. In a real application CodeRewriter would be a subclass that actually does something.
                    //(This is why decompiled source method bodies must recompile themselves, rather than just use the IL from which they were decompiled.)
                    var rewriter        = new CodeRewriter(host);
                    var rewrittenModule = rewriter.Rewrite(mutableModule);

                    //Write out the Code Model by traversing it as the Metadata Model that it also is.
                    using (var peStream = File.Create(rewrittenModule.Location + ".pe")) {
                        if (pdbReader == null)
                        {
                            PeWriter.WritePeToStream(rewrittenModule, host, peStream);
                        }
                        else
                        {
                            using (var pdbWriter = new PdbWriter(rewrittenModule.Location + ".pdb", pdbReader)) {
                                PeWriter.WritePeToStream(rewrittenModule, host, peStream, sourceLocationProvider, localScopeProvider, pdbWriter);
                            }
                        }
                    }
                }
            }
        }
Esempio n. 27
0
        public bool WriteSliceToFile(ISlice <MethodReferenceAdaptor, FieldReferenceAdaptor, TypeReferenceAdaptor, IAssemblyReference> slice, string directory, out string dll)
        {
#if TRACE_PERFORMANCE
            var stopWatch = new Stopwatch();
            stopWatch.Start();
#endif

            var newAssembly = Prune.PruneAssembly(host, slice);

#if TRACE_PERFORMANCE
            Console.WriteLine("Time to prune the assembly: {0}", stopWatch.Elapsed);
#endif

            var errors = ValidateAssembly(host, newAssembly);
            if (/*errors != null && */ 0 < errors.Count)
            {
#if !DEBUG_SLICE
                dll = null;
                return(false);
#endif
            }

            //Get a PDB reader if there is a PDB file.
            PdbReader /*?*/ pdbReader = null;
            string          pdbFile   = slice.ContainingAssembly.ResolvedAssembly.DebugInformationLocation;
            if (string.IsNullOrEmpty(pdbFile) || !File.Exists(pdbFile))
            {
                pdbFile = Path.ChangeExtension(slice.ContainingAssembly.ResolvedAssembly.Location, "pdb");
            }
            if (File.Exists(pdbFile))
            {
                using (var pdbStream = File.OpenRead(pdbFile)) {
                    pdbReader = new PdbReader(pdbStream, host);
                }
            }
            using (pdbReader) {
                ISourceLocationProvider sourceLocationProvider = pdbReader;
                ILocalScopeProvider     localScopeProvider     = pdbReader;

                Contract.Assume(sourceLocationProvider != null, "why??");
                if (!MakeSureSliceHasAtLeastMethodSourceLocation(slice, sourceLocationProvider))
                {
                    dll = null;
                    return(false);
                }

                dll = Path.Combine(directory, slice.Name + ".dll");

#if TRACE_PERFORMANCE
                stopWatch.Reset();
#endif

                using (var peStream = File.Create(dll)) {
                    if (pdbReader == null)
                    {
                        PeWriter.WritePeToStream(newAssembly, host, peStream);
                    }
                    else
                    {
                        using (var pdbWriter = new PdbWriter(dll.Replace(".dll", ".pdb"), pdbReader, emitTokenSourceInfo: true)) {
                            PeWriter.WritePeToStream(newAssembly, host, peStream, sourceLocationProvider, localScopeProvider, pdbWriter);
                        }
                    }
                }

#if TRACE_PERFORMANCE
                Console.WriteLine("Time spent to write on the disk: {0}", stopWatch.Elapsed);
#endif
            }

#if !DEBUG_SLICE
            if (errors != null && 0 < errors.Count)
            {
                using (var tw = new StreamWriter(File.Create(Path.Combine(directory, slice.Name + ".errors.txt"))))
                {
                    // something is performed asynchronously and may not be terminated here, that is wrong!
                    lock (errors)
                    {
                        foreach (var err in errors)
                        {
                            tw.WriteLine(err.Location);
                            foreach (var e in err.Errors)
                            {
                                tw.WriteLine("{0} {1} {2}", e.IsWarning ? "WARNING" : "ERROR ", e.Code, e.Message);
                            }
                            tw.WriteLine();
                        }
                    }
                }

                return(false);
            }
#endif

            // Can this be checked before writing it out?
            if (newAssembly.AssemblyReferences.Any(ar => ar.AssemblyIdentity.Equals(slice.ContainingAssembly.AssemblyIdentity)))
            {
            }

            return(true);
        }
Esempio n. 28
0
        static int Main(string[] args)
        {
            if (args == null || args.Length == 0)
            {
                Console.WriteLine("usage: HelloContracts [path]fileName.Contracts.dll [-libpaths ...]* [-p [-i] | -inject]");
                return(1);
            }
            #region Parse options
            var options = new Options();
            options.Parse(args);
            if (options.HelpRequested)
            {
                options.PrintOptions("");
                return(1);
            }
            if (options.HasErrors)
            {
                options.PrintErrorsAndExit(Console.Out);
            }
            #endregion

            var fileName = String.IsNullOrEmpty(options.assembly) ? options.GeneralArguments[0] : options.assembly;

            if (options.printContracts)
            {
                #region Collect and write contracts
                using (var host = new CodeContractAwareHostEnvironment(options.libpaths)) {
                    IModule module = host.LoadUnitFrom(fileName) as IModule;
                    if (module == null || module is Dummy)
                    {
                        Console.WriteLine("'{0}' is not a PE file containing a CLR module or assembly.", fileName);
                        Environment.Exit(1);
                    }
                    var t = new Traverser(host, options.inherited);
                    t.Traverse(module);
                }
                #endregion
                return(0);
            }
            else
            {
                using (var host = new CodeContractAwareHostEnvironment(options.libpaths, true, true)) {
                    // Read the Metadata Model from the PE file
                    var module = host.LoadUnitFrom(fileName) as IModule;
                    if (module == null || module is Dummy)
                    {
                        Console.WriteLine(fileName + " is not a PE file containing a CLR module or assembly.");
                        return(1);
                    }

                    // Get a PDB reader if there is a PDB file.
                    PdbReader /*?*/ pdbReader = null;
                    string          pdbFile   = Path.ChangeExtension(module.Location, "pdb");
                    if (File.Exists(pdbFile))
                    {
                        using (var pdbStream = File.OpenRead(pdbFile)) {
                            pdbReader = new PdbReader(pdbStream, host);
                        }
                    }

                    using (pdbReader) {
                        ISourceLocationProvider sourceLocationProvider = pdbReader;

                        // Construct a Code Model from the Metadata model via decompilation
                        var mutableModule = Decompiler.GetCodeModelFromMetadataModel(host, module, pdbReader, DecompilerOptions.AnonymousDelegates | DecompilerOptions.Loops);
                        ILocalScopeProvider localScopeProvider = new Decompiler.LocalScopeProvider(pdbReader);

                        // Extract contracts (side effect: removes them from the method bodies)
                        var contractProvider = Microsoft.Cci.MutableContracts.ContractHelper.ExtractContracts(host, mutableModule, pdbReader, localScopeProvider);

                        // Inject non-null postconditions
                        if (options.inject)
                        {
                            new NonNullInjector(host, contractProvider).Traverse(mutableModule);
                        }

                        // Put the contracts back in as method calls at the beginning of each method
                        Microsoft.Cci.MutableContracts.ContractHelper.InjectContractCalls(host, mutableModule, contractProvider, sourceLocationProvider);

                        // Write out the resulting module. Each method's corresponding IL is produced
                        // lazily using CodeModelToILConverter via the delegate that the mutator stored in the method bodies.
                        using (var peStream = File.Create(mutableModule.Location + ".pe")) {
                            if (pdbReader == null)
                            {
                                PeWriter.WritePeToStream(mutableModule, host, peStream);
                            }
                            else
                            {
                                using (var pdbWriter = new PdbWriter(mutableModule.Location + ".pdb", sourceLocationProvider)) {
                                    PeWriter.WritePeToStream(mutableModule, host, peStream, sourceLocationProvider, localScopeProvider, pdbWriter);
                                }
                            }
                        }
                    }
                }
                return(0);
            }
        }
Esempio n. 29
0
        /// <summary>
        /// Outputs specified headers, sections, methods or runtime functions for one ReadyToRun image
        /// </summary>
        /// <param name="r2r">The structure containing the info of the ReadyToRun image</param>
        public void Dump(ReadyToRunReader r2r)
        {
            _dumper.Begin();
            bool standardDump = !(_options.EntryPoints || _options.CreatePDB || _options.CreatePerfmap);

            if (_options.Header && standardDump)
            {
                _dumper.WriteDivider("R2R Header");
                _dumper.DumpHeader(true);
            }

            bool haveQuery = false;
            if (_options.Section != null)
            {
                haveQuery = true;
                QuerySection(r2r, _options.Section);
            }

            if (_options.RuntimeFunction != null)
            {
                haveQuery = true;
                QueryRuntimeFunction(r2r, _options.RuntimeFunction);
            }

            if (_options.Query != null)
            {
                haveQuery = true;
                QueryMethod(r2r, "R2R Methods by Query", _options.Query, true);
            }

            if (_options.Keyword != null)
            {
                haveQuery = true;
                QueryMethod(r2r, "R2R Methods by Keyword", _options.Keyword, false);
            }

            if (!haveQuery)
            {
                // Dump all sections and methods if no queries specified
                if (_options.EntryPoints)
                {
                    _dumper.DumpEntryPoints();
                }

                if (_options.CreatePDB)
                {
                    string pdbPath = _options.PdbPath;
                    if (String.IsNullOrEmpty(pdbPath))
                    {
                        pdbPath = Path.GetDirectoryName(r2r.Filename);
                    }
                    var pdbWriter = new PdbWriter(pdbPath, PDBExtraData.None);
                    pdbWriter.WritePDBData(r2r.Filename, ProduceDebugInfoMethods(r2r));
                }

                if (_options.CreatePerfmap)
                {
                    string perfmapPath = _options.PerfmapPath;
                    if (string.IsNullOrEmpty(perfmapPath))
                    {
                        perfmapPath = Path.ChangeExtension(r2r.Filename, ".r2rmap");
                    }
                    // TODO: can't seem to find any place that surfaces the ABI. This is for debugging purposes, so may not be as relevant to be correct.
                    TargetDetails details = new TargetDetails(r2r.TargetArchitecture, r2r.TargetOperatingSystem, TargetAbi.CoreRT);
                    PerfMapWriter.Write(perfmapPath, _options.PerfmapFormatVersion, ProduceDebugInfoMethods(r2r), ProduceDebugInfoAssemblies(r2r), details);
                }

                if (standardDump)
                {
                    _dumper.DumpAllMethods();
                    _dumper.DumpFixupStats();
                }
            }

            _dumper.End();
        }
Esempio n. 30
0
        /// <summary>
        /// Outputs specified headers, sections, methods or runtime functions for one ReadyToRun image
        /// </summary>
        /// <param name="r2r">The structure containing the info of the ReadyToRun image</param>
        public void Dump(ReadyToRunReader r2r)
        {
            _dumper.Begin();
            bool standardDump = !(_options.EntryPoints || _options.CreatePDB || _options.CreatePerfmap);

            if (_options.Header && standardDump)
            {
                _dumper.WriteDivider("R2R Header");
                _dumper.DumpHeader(true);
            }

            bool haveQuery = false;

            if (_options.Section != null)
            {
                haveQuery = true;
                QuerySection(r2r, _options.Section);
            }

            if (_options.RuntimeFunction != null)
            {
                haveQuery = true;
                QueryRuntimeFunction(r2r, _options.RuntimeFunction);
            }

            if (_options.Query != null)
            {
                haveQuery = true;
                QueryMethod(r2r, "R2R Methods by Query", _options.Query, true);
            }

            if (_options.Keyword != null)
            {
                haveQuery = true;
                QueryMethod(r2r, "R2R Methods by Keyword", _options.Keyword, false);
            }

            if (!haveQuery)
            {
                // Dump all sections and methods if no queries specified
                if (_options.EntryPoints)
                {
                    _dumper.DumpEntryPoints();
                }

                TargetArchitecture architecture = r2r.Machine switch
                {
                    Machine.I386 => TargetArchitecture.X86,
                    Machine.Amd64 => TargetArchitecture.X64,
                    Machine.ArmThumb2 => TargetArchitecture.ARM,
                    Machine.Arm64 => TargetArchitecture.ARM64,
                    _ => throw new NotImplementedException(r2r.Machine.ToString()),
                };
                TargetOS os = r2r.OperatingSystem switch
                {
                    OperatingSystem.Windows => TargetOS.Windows,
                    OperatingSystem.Linux => TargetOS.Linux,
                    OperatingSystem.Apple => TargetOS.OSX,
                    OperatingSystem.FreeBSD => TargetOS.FreeBSD,
                    OperatingSystem.NetBSD => TargetOS.FreeBSD,
                    _ => throw new NotImplementedException(r2r.OperatingSystem.ToString()),
                };
                TargetDetails details = new TargetDetails(architecture, os, TargetAbi.CoreRT);

                if (_options.CreatePDB)
                {
                    string pdbPath = _options.PdbPath;
                    if (String.IsNullOrEmpty(pdbPath))
                    {
                        pdbPath = Path.GetDirectoryName(r2r.Filename);
                    }
                    var pdbWriter = new PdbWriter(pdbPath, PDBExtraData.None, details);
                    pdbWriter.WritePDBData(r2r.Filename, ProduceDebugInfoMethods(r2r));
                }

                if (_options.CreatePerfmap)
                {
                    string perfmapPath = _options.PerfmapPath;
                    if (string.IsNullOrEmpty(perfmapPath))
                    {
                        perfmapPath = Path.ChangeExtension(r2r.Filename, ".r2rmap");
                    }
                    PerfMapWriter.Write(perfmapPath, _options.PerfmapFormatVersion, ProduceDebugInfoMethods(r2r), ProduceDebugInfoAssemblies(r2r), details);
                }

                if (standardDump)
                {
                    _dumper.DumpAllMethods();
                    _dumper.DumpFixupStats();
                }
            }

            _dumper.End();
        }
        public static MemoryStream RewriteProgramIL(CeleriacArgs celeriacArgs, TypeManager typeManager)
        {
            if (String.IsNullOrWhiteSpace(celeriacArgs.AssemblyPath))
            {
                throw new FileNotFoundException("Path to program to be profiled not provided");
            }

            Stream resultStream;
            var    host = typeManager.Host;

            IModule /*?*/ module = host.LoadUnitFrom(celeriacArgs.AssemblyPath) as IModule;

            if (module == null || module == Dummy.Module || module == Dummy.Assembly)
            {
                throw new FileNotFoundException("Given path is not a PE file containing a CLR"
                                                + " assembly, or an error occurred when loading it.", celeriacArgs.AssemblyPath);
            }

            if (module.GetAllTypes().Any(
                    type => type.Name.ToString().Equals(ILRewriter.ArgumentStoringClassName)))
            {
                throw new InvalidOperationException("Program has already been instrumented.");
            }

            string   pdbFile = Path.ChangeExtension(module.Location, "pdb");
            Assembly mutable = null;

            using (var pdbReader = LoadPdbReaderAndFile(celeriacArgs, typeManager, module, pdbFile))
            {
                AssemblySummary comparabilityManager = GenerateComparability(celeriacArgs, typeManager,
                                                                             host, module, pdbReader, ref mutable);

                if (celeriacArgs.GenerateComparability && celeriacArgs.ComparabilityFile == null)
                {
                    return(null);
                }

                ILRewriter mutator = new ILRewriter(host, pdbReader, celeriacArgs, typeManager, comparabilityManager);

                module = mutator.Visit(mutable, Path.Combine(FindVisitorDir(), VisitorDll));

                if (celeriacArgs.EmitNullaryInfo || celeriacArgs.GenerateComparability)
                {
                    return(null);
                }

                // Remove the old PDB file
                try
                {
                    File.Delete(pdbFile);
                }
                catch (UnauthorizedAccessException)
                {
                    // If they are running the debugger we might not be able to delete the file
                    // Save the pdb elsewhere in this case.
                    pdbFile = module.Location + ".pdb";
                }

                if (celeriacArgs.SaveProgram != null)
                {
                    resultStream = new FileStream(celeriacArgs.SaveProgram, FileMode.Create);
                }
                else
                {
                    resultStream = new MemoryStream();
                }


#if __MonoCS__
                // Reading / Writing DEBUG information on Mono is not supported by CCI
                PdbWriter pdbWriter = null;
#else
                var pdbWriter = new PdbWriter(pdbFile, pdbReader);
#endif

                // Need to not pass in a local scope provider until such time as we have one
                // that will use the mutator to remap things (like the type of a scope
                // constant) from the original assembly to the mutated one.
                using (pdbWriter)
                {
                    PeWriter.WritePeToStream(module, host, resultStream, pdbReader, null, pdbWriter);
                }
            }

            if (celeriacArgs.SaveProgram != null)
            {
                // We aren't going to run the program, so no need to return anything,
                // but close the file stream.
                resultStream.Close();
                return(null);
            }
            else
            {
                return((MemoryStream)resultStream); // success
            }
        }
		/// <summary>
		/// Write the pdb to a file.
		/// </summary>
		/// <param name="fileName">The file name to write the pdb into.</param>
		/// <param name="metadataProvider">The metadata provider for the managed metadata.</param>
		public void Write(string fileName, IMetadataProvider metadataProvider)
		{
			if (fileName == null)
				throw new ArgumentNullException("fileName");
			if (metadataProvider == null)
				throw new ArgumentNullException("metadataProvider");

			using (var writer = new PdbWriter(fileName, metadataProvider))
				Write(writer);

			WriteHeader(fileName);
		}
Esempio n. 33
0
        internal int Run()
        {
            SecurityKeepOptions securityKeepOptions = options.onlySecurityTransparent ? SecurityKeepOptions.OnlyNonCritical : SecurityKeepOptions.All;

            if (options.doBreak)
            {
                System.Diagnostics.Debugger.Launch();
            }

            string assemblyName = null;

            if (options.GeneralArguments.Count == 1)
            {
                assemblyName = options.GeneralArguments[0];
            }
            if (assemblyName == null)
            {
                errorLogger("Must specify an input file.");
                return(1);
            }

            using (var host = new AsmMetaHostEnvironment(options.libPaths.ToArray(), options.searchGAC))
            {
                foreach (var p in options.resolvedPaths)
                {
                    host.AddResolvedPath(p);
                }

                IAssembly /*?*/ assembly = host.LoadUnitFrom(assemblyName) as IAssembly;
                if (assembly == null || assembly is Dummy)
                {
                    errorLogger(assemblyName + " is not a PE file containing a CLR assembly, or an error occurred when loading it.");
                    return(1);
                }

                var rewrittenAttribute = CreateTypeReference(host, assembly, "System.Diagnostics.Contracts.RuntimeContractsAttribute");
                if (AttributeHelper.Contains(assembly.Attributes, rewrittenAttribute))
                {
                    errorLogger(assemblyName + " is already rewritten, cannot generate a reference assembly from it.");
                    return(1);
                }

                if (options.backwardCompatibility)
                { // redundant because RemoveMethodBodies.ctor also does this when the flag is set
                    options.whatToEmit     = KeepOptions.ExtVis;
                    options.emitAttributes = false;
                }

                PdbReader /*?*/ pdbReader = null;
                if (options.includeSourceTextInContract)
                { // No point getting the PDB file unless we want to use it for source text
                    string pdbFile = Path.ChangeExtension(assembly.Location, "pdb");
                    if (File.Exists(pdbFile))
                    {
                        using (var pdbStream = File.OpenRead(pdbFile))
                        {
                            pdbReader = new PdbReader(pdbStream, host);
                        }
                    }
                    else
                    {
                        errorLogger("Could not load the PDB file for the assembly '" + assembly.Name.Value + "' . Source text will not be preserved in the reference assembly. Proceeding anyway.");
                    }
                }
                using (pdbReader)
                {
                    // We might be working on the assembly that defines the contract class and/or the type System.Void.
                    // (Or any other platform type!)
                    // But the host.PlatformType object has not been duplicated, so its properties will continue to be references to the immutable ones.
                    // This is OK, except if the assembly is being renamed.
                    this.compilerGeneratedAttributeType = host.PlatformType.SystemRuntimeCompilerServicesCompilerGeneratedAttribute;
                    this.contractClassType   = host.PlatformType.SystemDiagnosticsContractsContract;
                    this.systemAttributeType = host.PlatformType.SystemAttribute;
                    this.systemBooleanType   = host.PlatformType.SystemBoolean;
                    this.systemStringType    = host.PlatformType.SystemString;
                    this.systemObjectType    = host.PlatformType.SystemObject;
                    this.systemVoidType      = host.PlatformType.SystemVoid;
                    //new FindPlatformTypes(this).Traverse(assembly); //update the above fields if any of those types are defined in mutable

                    Assembly mutable = new MetadataDeepCopier(host).Copy(assembly);

                    #region Rename the assembly in a separate pass because things done in later passes depend on interned keys that are computed based (in part) on the assembly identity

                    if (options.rename)
                    {
                        if (options.output != null)
                        {
                            mutable.Name = host.NameTable.GetNameFor(Path.GetFileNameWithoutExtension(options.output));
                        }
                        else
                        {
                            mutable.Name = host.NameTable.GetNameFor(assembly.Name.Value + ".Contracts");
                        }
                        mutable.ModuleName = mutable.Name;
                        mutable.Kind       = ModuleKind.DynamicallyLinkedLibrary;
                        mutable            = (Assembly)RenameAssembly.ReparentAssemblyIdentity(host, assembly.AssemblyIdentity, mutable.AssemblyIdentity, mutable);
                    }

                    #endregion Rename the assembly in a separate pass because things done in later passes depend on interned keys that are computed based (in part) on the assembly identity
                    if (!options.renameOnly)
                    {
                        if (options.contracts)
                        {
                            if (options.rename)
                            {
                                // We might be working on the assembly that defines the contract class and/or the type System.Void.
                                // (Or any other platform type!)
                                // But the host.PlatformType object has not been duplicated, so its properties will continue to be references to the immutable ones.
                                // This is OK, except if the assembly is being renamed.

                                var systemNamespace = GetFirstMatchingNamespace(host, mutable.UnitNamespaceRoot, "System");
                                if (systemNamespace != null)
                                {
                                    var typeDefinition = GetFirstMatchingTypeDefinition(host, systemNamespace, "Attribute");
                                    if (typeDefinition != null)
                                    {
                                        this.systemAttributeType = typeDefinition;
                                    }
                                    typeDefinition = GetFirstMatchingTypeDefinition(host, systemNamespace, "Boolean");
                                    if (typeDefinition != null)
                                    {
                                        this.systemBooleanType = typeDefinition;
                                    }
                                    typeDefinition = GetFirstMatchingTypeDefinition(host, systemNamespace, "Object");
                                    if (typeDefinition != null)
                                    {
                                        this.systemObjectType = typeDefinition;
                                    }
                                    typeDefinition = GetFirstMatchingTypeDefinition(host, systemNamespace, "String");
                                    if (typeDefinition != null)
                                    {
                                        this.systemStringType = typeDefinition;
                                    }
                                    typeDefinition = GetFirstMatchingTypeDefinition(host, systemNamespace, "Void");
                                    if (typeDefinition != null)
                                    {
                                        this.systemVoidType = typeDefinition;
                                    }

                                    var systemRuntimeNamespace = GetFirstMatchingNamespace(host, systemNamespace, "Runtime");
                                    if (systemRuntimeNamespace != null)
                                    {
                                        var systemRuntimeCompilerServicesNamespace = GetFirstMatchingNamespace(host, systemRuntimeNamespace, "CompilerServices");
                                        if (systemRuntimeCompilerServicesNamespace != null)
                                        {
                                            typeDefinition = GetFirstMatchingTypeDefinition(host, systemRuntimeCompilerServicesNamespace, "CompilerGeneratedAttribute");
                                            if (typeDefinition != null)
                                            {
                                                this.compilerGeneratedAttributeType = typeDefinition;
                                            }
                                        }
                                    }

                                    var systemDiagnosticsNamespace = GetFirstMatchingNamespace(host, systemNamespace, "Diagnostics");
                                    if (systemDiagnosticsNamespace != null)
                                    {
                                        var systemDiagnosticsContractsNamespace = GetFirstMatchingNamespace(host, systemDiagnosticsNamespace, "Contracts");
                                        if (systemDiagnosticsContractsNamespace != null)
                                        {
                                            typeDefinition = GetFirstMatchingTypeDefinition(host, systemDiagnosticsContractsNamespace, "Contract");
                                            if (typeDefinition != null)
                                            {
                                                this.contractClassType = typeDefinition;
                                            }
                                        }
                                    }
                                }
                            }

                            mutable = AsmMetaRewriter.RewriteModule(host,
                                                                    pdbReader,
                                                                    mutable,
                                                                    contractClassType,
                                                                    compilerGeneratedAttributeType,
                                                                    systemAttributeType,
                                                                    systemBooleanType,
                                                                    systemObjectType,
                                                                    systemStringType,
                                                                    systemVoidType
                                                                    ) as Assembly;
                        }
                        #region Delete things that are not to be kept
                        if (options.backwardCompatibility || options.whatToEmit != KeepOptions.All || !options.emitAttributes || (options.attrs != null && 0 < options.attrs.Count))
                        {
                            DeleteThings thinner = new DeleteThings(host, options.whatToEmit, securityKeepOptions, options.emitAttributes, options.attrs.ToArray(), options.backwardCompatibility);
                            if (securityKeepOptions == SecurityKeepOptions.OnlyNonCritical && host.platformType.SystemSecuritySecurityCriticalAttribute.ResolvedType is Dummy)
                            {
                                errorLogger("You asked to remove security critical methods, but the version of mscorlib doesn't support the SecurityCriticalAttribute.");
                                return(1);
                            }
                            thinner.RewriteChildren(mutable);
                            #region Fix up dangling references to things that were deleted
                            FixUpReferences patcher = new FixUpReferences(host, thinner.WhackedMethods, thinner.WhackedTypes);
                            patcher.RewriteChildren(mutable);
                            #endregion Fix up dangling references to things that were deleted
                        }
                        #endregion Delete things that are not to be kept
                        #region Output is always a dll, so mark the assembly as that
                        mutable.EntryPoint = Dummy.MethodReference;
                        mutable.Kind       = ModuleKind.DynamicallyLinkedLibrary;
                        #endregion Output is always a dll, so mark the assembly as that
                    }

                    assembly = mutable;

                    string outputPath;
                    if (options.output != null) // user specified, they'd better make sure it doesn't conflict with anything
                    {
                        outputPath = options.output;
                    }
                    else if (options.rename) // A.dll ==> A.Contracts.dll (Always! Even if the input is an exe!)
                    {
                        outputPath = assembly.Name.Value + ".dll";
                    }
                    else // A.dll ==> A.dll.meta
                    {
                        outputPath = assembly.Name.Value + Path.GetExtension(assemblyName) + ".meta";
                    }
                    // NB: Do *not* pass a pdbWriter to WritePeToStream. No need to create a PDB file and if
                    // it is provided, then it might find things (like constants in a scope) that don't get
                    // visited and so don't have any type references modified as they should be.
                    using (var outputFile = File.Create(outputPath))
                    {
                        if (pdbReader != null && options.writePDB)
                        {
                            using (var pdbWriter = new PdbWriter(Path.ChangeExtension(outputPath, "pdb"), pdbReader))
                            {
                                // Need to not pass in a local scope provider until such time as we have one that will use the mutator
                                // to remap things (like the type of a scope constant) from the original assembly to the mutated one.
                                PeWriter.WritePeToStream(assembly, host, outputFile, pdbReader, null /*pdbReader*/, pdbWriter);
                            }
                        }
                        else
                        {
                            PeWriter.WritePeToStream(assembly, host, outputFile);
                        }
                    }
                }
            }
            return(0); // success
        }
Esempio n. 34
0
        public static void RunBclRewriter(string[] args)
        {
            #region Parse the command-line arguments.
            if (!Parser.ParseArgumentsWithUsage(args, typeof(Program)))
            {
                throw new UsageException();
            }
            #endregion

            #region Figure out paths
            s_assemblyName = Path.GetFullPath(s_assemblyName); // this has to be specified

            string outputBaseName = null;
            if (!String.IsNullOrEmpty(s_output))
            {
                s_output       = Path.GetFullPath(s_output);
                outputBaseName = Path.GetFileNameWithoutExtension(s_output);
            }
            else
            {
                s_output       = Path.Combine(Directory.GetCurrentDirectory(), Path.GetFileNameWithoutExtension(s_assemblyName) + ".small" + Path.GetExtension(s_assemblyName));
                outputBaseName = s_assemblyName;
            }

            string pdbSourceFile = Path.ChangeExtension(s_assemblyName, "pdb");
            string outputPdb     = Path.ChangeExtension(s_output, "pdb");
            string outputFolder  = Path.GetDirectoryName(s_output);

            // if the user wants to do an in-place rewrite, we copy the file to a temp file
            if (s_output == s_assemblyName)
            {
                String tempPath    = s_assemblyName + TempExtension;
                String tempPdbPath = pdbSourceFile + TempExtension;

                File.Copy(s_assemblyName, tempPath, true);
                s_assemblyName = tempPath;

                if (File.Exists(pdbSourceFile))
                {
                    File.Copy(pdbSourceFile, tempPdbPath, true);
                    pdbSourceFile = tempPdbPath;
                }
            }

            if (!Directory.Exists(outputFolder))
            {
                Directory.CreateDirectory(outputFolder);
            }

            #endregion

            #region Load input files
            HostEnvironment host = new HostEnvironment(new NameTable(), s_assemblyDependencyPaths, s_referencedAssemblies);

            IAssembly /*?*/ assembly = host.LoadUnitFrom(s_assemblyName) as IAssembly;
            // TODO: Handle multimodule assemblies
            if (assembly == null || assembly == Dummy.Assembly)
            {
                throw new UsageException(args[0] + " is not a PE file containing a CLR assembly, or an error occurred when loading it.");
            }

            if (!File.Exists(s_includeListFile))
            {
                throw new UsageException(String.Format("ERROR: Can't find code model file '{0}'", s_includeListFile));
            }

            ThinModel model = new ThinModel(new ThinnerOptions(host, new AssemblyIdentity[] { assembly.AssemblyIdentity }));
            model.LoadModel(s_includeListFile, new ModelReaderOptions(s_platform, s_architecture, s_flavor, s_treatFxInternalAsPublic, s_defines));
            #endregion

            #region Calculate api closure.
            ConsoleTimer.StartTimer("Calculating api closure");
            model.LoadMetadataFrom(assembly);

            ThinModel apiClosure = model.CalculateApiClosure();
            if (s_keepTempFiles)
            {
                apiClosure.SaveModel(Path.ChangeExtension(s_output, ".apiClosure.xml"));
            }
            ConsoleTimer.EndTimer("Calculating api closure");
            #endregion

            #region Calculate impl closure.
            ConsoleTimer.StartTimer("Calculating implementation closure");
            apiClosure.LoadMetadataFrom(assembly);

            ThinModel implClosure = apiClosure.CalculateImplementationClosure(true, FieldOptions.KeepAll);

            if (s_keepTempFiles)
            {
                implClosure.SaveModel(Path.ChangeExtension(s_output, ".implClosure.xml"));
            }
            ConsoleTimer.EndTimer("Calculating implementation closure");
            #endregion

            #region Trim.
            ConsoleTimer.StartTimer("Trimming assembly");
            IncludeSet includeSet = new IncludeSet();
            includeSet.LoadFrom(implClosure);

            var      copier         = new MetadataDeepCopier(host);
            Assembly copiedAssembly = copier.Copy(assembly);

            Trimmer trimmer = new Trimmer(includeSet, true, false, true, host, s_removeSerializable);
            trimmer.RewriteChildren(copiedAssembly);
            Assembly mutableAssembly = copiedAssembly;
            assembly = mutableAssembly;

            ConsoleTimer.EndTimer("Trimming assembly");
            #endregion

            #region Update assembly name.
            ConsoleTimer.StartTimer("Updating assembly name");

            // If the output assembly name is different, update the internal assembly name to match.
            AssemblyIdentity originalAssemblyIdentity = mutableAssembly.AssemblyIdentity;
            if (!outputBaseName.Equals(originalAssemblyIdentity.Name.ToString(), StringComparison.OrdinalIgnoreCase))
            {
                mutableAssembly.Name       = host.NameTable.GetNameFor(outputBaseName);
                mutableAssembly.ModuleName = mutableAssembly.Name;
            }

            // If we changed the assembly identity, update references to it.
            if (!mutableAssembly.AssemblyIdentity.Equals(originalAssemblyIdentity))
            {
                trimmer.UpdateAssemblyReferences(originalAssemblyIdentity, mutableAssembly.AssemblyIdentity);
            }

            ConsoleTimer.EndTimer("Updating assembly name");
            #endregion

            #region Write out the assembly
            ConsoleTimer.StartTimer("Writing assembly");
            PdbReader pdbReader = null;
            PdbWriter pdbWriter = null;
            if (File.Exists(pdbSourceFile))
            {
                Stream pdbStream = File.OpenRead(pdbSourceFile);
                pdbReader = new PdbReader(pdbStream, host);
                pdbWriter = new PdbWriter(outputPdb, pdbReader);
                Console.WriteLine("Writing pdb: {0}", outputPdb);
            }

            Console.WriteLine("Writing assembly: {0}", s_output);
            FileStream file = File.Create(s_output);

            try
            {
                PeWriter.WritePeToStream(assembly, host, file, pdbReader, pdbReader, pdbWriter);
            }
            finally
            {
                if (file != null)
                {
                    file.Dispose();
                }

                if (pdbWriter != null)
                {
                    pdbWriter.Dispose();
                }
            }

            ConsoleTimer.EndTimer("Writing assembly");
            #endregion
        }
Esempio n. 35
0
        static void Main(string[] args)
        {
            String inputFile;
            String targetFile;
            String targetNamespace;
            String targetClass;
            String targetMethod;
            int    depth;
            int    dimension;
            int    numberValidPaths;
            int    duplicateBasicBlockWeight;
            int    duplicateBasicBlockCorrectionValue;
            int    stateChangeWeight;
            int    stateChangeCorrectionValue;
            int    insertOpaquePredicateWeight;
            int    seed;

            // Add debugging code into the obfuscated method (dump obfuscation graphs and so on)
            bool graphTransformerDebug = false;

            // Should the obfuscated code contain information to trace the control flow?
            bool basicBlockTrace = false;

            // When debugging is active, should the whole obfuscation graph be dumped or only the vpaths in it?
            bool graphOnlyDumpVPaths = true;

            // The number of random interfaces that are added to the program
            int numberRandomInterfaces = 100;

            if (args.Length != 14)
            {
                System.Console.WriteLine("Needed parameters: <inputBinary> <outputBinary> <namespace> <class> <method> <depth> <dimension> <numberValidPaths> <duplicateBasicBlockWeight> <duplicateBasicBlockCorrectionValue> <stateChangeWeight> <stateChangeCorrectionValue> <insertOpaquePredicateWeight> <seed>");
                return;
            }
            else
            {
                inputFile                          = args[0];
                targetFile                         = args[1];
                targetNamespace                    = args[2];
                targetClass                        = args[3];
                targetMethod                       = args[4];
                depth                              = Convert.ToInt32(args[5]);
                dimension                          = Convert.ToInt32(args[6]);
                numberValidPaths                   = Convert.ToInt32(args[7]);
                duplicateBasicBlockWeight          = Convert.ToInt32(args[8]);
                duplicateBasicBlockCorrectionValue = Convert.ToInt32(args[9]);
                stateChangeWeight                  = Convert.ToInt32(args[10]);
                stateChangeCorrectionValue         = Convert.ToInt32(args[11]);
                insertOpaquePredicateWeight        = Convert.ToInt32(args[12]);
                seed = Convert.ToInt32(args[13]);
            }

            String logDir = Path.GetDirectoryName(targetFile);

            Log.Log logger = new Log.Log(logDir, "probfuscation_logfile.txt");

            System.Console.WriteLine("Obfuscating: " + inputFile);
            logger.writeLine("Obfuscating: " + inputFile);
            System.Console.WriteLine("Output file: " + targetFile);
            logger.writeLine("Output file: " + targetFile);
            System.Console.WriteLine("Target namespace: " + targetNamespace);
            logger.writeLine("Target namespace: " + targetNamespace);
            System.Console.WriteLine("Target class: " + targetClass);
            logger.writeLine("Target class: " + targetClass);
            System.Console.WriteLine("Target method: " + targetMethod);
            logger.writeLine("Target method: " + targetMethod);
            System.Console.WriteLine("Depth: " + depth);
            logger.writeLine("Depth: " + depth);
            System.Console.WriteLine("Dimension: " + dimension);
            logger.writeLine("Dimension: " + dimension);
            System.Console.WriteLine("Number of vpaths: " + numberValidPaths);
            logger.writeLine("Number of vpaths: " + numberValidPaths);
            System.Console.WriteLine("Basic Block duplication weight: " + duplicateBasicBlockWeight);
            logger.writeLine("Basic Block duplication weight: " + duplicateBasicBlockWeight);
            System.Console.WriteLine("Basic Block duplication correction value: " + duplicateBasicBlockCorrectionValue);
            logger.writeLine("Basic Block duplication correction value: " + duplicateBasicBlockCorrectionValue);
            System.Console.WriteLine("State change weight: " + stateChangeWeight);
            logger.writeLine("State change weight: " + stateChangeWeight);
            System.Console.WriteLine("State change correction value: " + stateChangeCorrectionValue);
            logger.writeLine("State change correction value: " + stateChangeCorrectionValue);
            System.Console.WriteLine("Opaque predicate weight: " + insertOpaquePredicateWeight);
            logger.writeLine("Opaque predicate weight: " + insertOpaquePredicateWeight);
            System.Console.WriteLine("Seed: " + seed);
            logger.writeLine("Seed: " + seed);

            // Seed PRNG for interfaces
            PRNGRandomInterfaces = new Random(seed);

            using (var host = new PeReader.DefaultHost()) {
                IModule /*?*/ module = host.LoadUnitFrom(inputFile) as IModule;

                if (module == null || module == Dummy.Module || module == Dummy.Assembly)
                {
                    Console.WriteLine(inputFile + " is not a PE file containing a CLR module or assembly.");
                    return;
                }

                module = new MetadataDeepCopier(host).Copy(module);

                if (module as Assembly == null)
                {
                    logger.writeLine("File does not have CIL assembly");
                    return;
                }

                // create analyzer object object
                CfgBuilder analyze = new Cfg.CfgBuilder(module, host, logger);

                PdbReader /*?*/ pdbReader = null;
                string          pdbFile   = Path.ChangeExtension(module.Location, "pdb");
                if (File.Exists(pdbFile))
                {
                    using (var pdbStream = File.OpenRead(pdbFile)) {
                        pdbReader = new PdbReader(pdbStream, host);
                    }
                }
                else
                {
                    logger.writeLine("Could not load the PDB file for '" + module.Name.Value + "' . Proceeding anyway.");
                }

                using (pdbReader) {
                    Microsoft.Cci.ILGenerator.LocalScopeProvider localScopeProvider = null;
                    if (pdbReader != null)
                    {
                        localScopeProvider = new ILGenerator.LocalScopeProvider(pdbReader);
                    }

                    // search the namespace the interface should be added to
                    IUnitNamespace foundNamespace = null;
                    foreach (var tempMember in module.UnitNamespaceRoot.Members)
                    {
                        if ((tempMember as IUnitNamespace) == null)
                        {
                            continue;
                        }

                        IUnitNamespace tempNamespace = (tempMember as IUnitNamespace);

                        if (tempNamespace.ToString() == targetNamespace)
                        {
                            foundNamespace = tempNamespace;
                            break;
                        }
                    }
                    if (foundNamespace == null)
                    {
                        throw new ArgumentException("Not able to find target namespace.");
                    }

                    // add created interface (and implemented methods) to all classes
                    bool classFound = false;
                    foreach (var tempClass in module.GetAllTypes())
                    {
                        if ((tempClass as NamespaceTypeDefinition) == null ||
                            tempClass.IsAbstract)
                        {
                            continue;
                        }

                        NamespaceTypeDefinition foundClass = (tempClass as NamespaceTypeDefinition);

                        if (foundClass.ContainingUnitNamespace.ToString() == "")
                        {
                            continue;
                        }
                        if (foundClass.ToString() != targetNamespace + "." + targetClass)
                        {
                            continue;
                        }
                        classFound = true;

                        Random           prng             = new Random();
                        GraphTransformer graphTransformer = new GraphTransformer(module, host, logger, prng, foundNamespace, foundClass, depth, dimension, graphTransformerDebug);

                        graphTransformer.duplicateBasicBlockWeight          = duplicateBasicBlockWeight;
                        graphTransformer.duplicateBasicBlockCorrectionValue = duplicateBasicBlockCorrectionValue;
                        graphTransformer.stateChangeWeight           = stateChangeWeight;
                        graphTransformer.stateChangeCorrectionValue  = stateChangeCorrectionValue;
                        graphTransformer.insertOpaquePredicateWeight = insertOpaquePredicateWeight;
                        graphTransformer.trace = basicBlockTrace;
                        graphTransformer.graphOnlyDumpVPaths   = graphOnlyDumpVPaths;
                        graphTransformer.debuggingDumpLocation = logDir;

                        // Add 100 random interfaces to the namespace
                        Helper testHelper = new Helper(module, host, logger);
                        List <NamespaceTypeDefinition> randomInterfaces = new List <NamespaceTypeDefinition>();
                        for (int i = 0; i < numberRandomInterfaces; i++)
                        {
                            String randName = randomString(20);
                            NamespaceTypeDefinition temp = testHelper.createNewInterface(randName, foundNamespace);
                            randomInterfaces.Add(temp);
                        }

                        InterfaceTransformer interfaceTransformer = new InterfaceTransformer(module, host, logger);
                        foreach (var classToAdd in module.GetAllTypes())
                        {
                            if ((classToAdd as NamespaceTypeDefinition) == null ||
                                classToAdd.IsAbstract ||
                                classToAdd.IsInterface ||
                                classToAdd.IsEnum ||
                                classToAdd.IsDelegate ||
                                classToAdd.IsGeneric ||
                                classToAdd.IsStruct)
                            {
                                continue;
                            }

                            if (((NamespaceTypeDefinition)classToAdd).ContainingUnitNamespace.ToString() == "")
                            {
                                continue;
                            }

                            /*
                             * // Use this code if you want to add standard interfaces to the target class
                             * interfaceTransformer.addStdInterfacesGivenByFile(@"e:\code\dotnet_standard_interfaces.txt");
                             *
                             * // add std interfaces to class
                             * if (foundClass != (classToAdd as NamespaceTypeDefinition)) {
                             *  foreach (ITypeDefinition temp in interfaceTransformer.getInterfacesList()) {
                             *      interfaceTransformer.addInterface((classToAdd as NamespaceTypeDefinition), temp);
                             *  }
                             * }
                             */

                            // Add random interfaces to the classes
                            List <NamespaceTypeDefinition> alreadyAdded = new List <NamespaceTypeDefinition>();
                            int max = PRNGRandomInterfaces.Next(numberRandomInterfaces);
                            NamespaceTypeDefinition interfaceClass = (classToAdd as NamespaceTypeDefinition);
                            logger.writeLine("Adding " + max + " random interfaces to class \"" + interfaceClass.ToString() + "\"");
                            for (int i = 0; i < max; i++)
                            {
                                NamespaceTypeDefinition randInterface = randomInterfaces.ElementAt(PRNGRandomInterfaces.Next(randomInterfaces.Count));
                                if (alreadyAdded.Contains(randInterface))
                                {
                                    continue;
                                }
                                alreadyAdded.Add(randInterface);
                                logger.writeLine("Adding interface: \"" + randInterface.ToString() + "\"");

                                // add nodes interface to class
                                if (interfaceClass.Interfaces != null)
                                {
                                    interfaceClass.Interfaces.Add(randInterface);
                                }
                                else
                                {
                                    interfaceClass.Interfaces = new List <ITypeReference>();
                                    interfaceClass.Interfaces.Add(randInterface);
                                }
                            }
                            logger.writeLine("");

                            // Add special interface for the obfuscation scheme to the class
                            // (makes sure that all needed attributes and methods are implemented)
                            graphTransformer.addNodeInterfaceToTargetClass((classToAdd as NamespaceTypeDefinition));
                        }

                        // Prepare obfuscation graph
                        graphTransformer.generateGraph(numberValidPaths);
                        graphTransformer.createGraphMethods();

                        // Search method to obfuscate
                        MethodDefinition methodToObfu = null;
                        foreach (MethodDefinition tempMethod in foundClass.Methods)
                        {
                            if (tempMethod.Name.ToString() == targetMethod)
                            {
                                methodToObfu = tempMethod;
                                break;
                            }
                        }
                        if (methodToObfu == null)
                        {
                            throw new ArgumentException("Not able to find target method.");
                        }

                        // Obfuscate target method
                        MethodCfg cfg = analyze.buildCfgForMethod(methodToObfu);
                        logger.dumpMethodCfg(cfg, "before");
                        graphTransformer.addObfuscationToMethod(cfg);
                        analyze.createMethodFromCfg(cfg);
                        logger.dumpMethodCfg(cfg, "after");

                        break;
                    }
                    if (!classFound)
                    {
                        throw new ArgumentException("Not able to find target class.");
                    }


                    /*
                     * This code can be used if not only one specific method should be obfuscated,
                     * but the whole class.
                     * List<ClassCfg> classCfgList = new List<ClassCfg>();
                     * foreach (var tempClass in module.GetAllTypes()) {
                     *  if ((tempClass as NamespaceTypeDefinition) == null
                     || tempClass.IsAbstract) {
                     ||     continue;
                     || }
                     ||
                     || // create basic blocks
                     || NamespaceTypeDefinition foundClass = (tempClass as NamespaceTypeDefinition);
                     ||
                     || logger.writeLine("Create CFG for class \"" + foundClass.Name.ToString() + "\"");
                     || ClassCfg temp = analyze.buildCfgForClass(foundClass);
                     || classCfgList.Add(temp);
                     || logger.writeLine("\n---------------------------------\n");
                     ||}
                     ||
                     ||// transform each function
                     ||NopTransformer transformator = new NopTransformer(module, host, logger);
                     ||foreach (ClassCfg tempClassCfg in classCfgList) {
                     || foreach (MethodCfg tempMethodCfg in tempClassCfg.methodCfgs) {
                     ||     logger.writeLine("Transform method CFG of \"" + tempMethodCfg.method.ToString() + "\"");
                     ||     transformator.addNopsToCfg(tempMethodCfg);
                     ||     logger.writeLine("\n---------------------------------\n");
                     || }
                     ||}
                     ||
                     ||foreach (ClassCfg tempClassCfg in classCfgList) {
                     || logger.writeLine("Create class from CFG for \"" + tempClassCfg.classObj.Name.ToString() + "\"");
                     || analyze.createClassFromCfg(tempClassCfg);
                     || logger.writeLine("\n---------------------------------\n");
                     ||}
                     */

                    using (var peStream = File.Create(targetFile)) {
                        using (var pdbWriter = new PdbWriter(Path.ChangeExtension(targetFile, ".pdb"), pdbReader)) {
                            PeWriter.WritePeToStream(module, host, peStream, pdbReader, localScopeProvider, pdbWriter);
                        }
                    }
                }
            }
        }