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)); }
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); } }
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); } } }
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); } } } }
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); } } } } }
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); } }
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 } }
public override string Run(string tempFolder) { var assembly = Generate(); var fileName = assembly.Kind == ModuleKind.DynamicallyLinkedLibrary ? DllName : ExeName; var resultPath = Path.Combine(tempFolder, fileName); using (var fs = File.Create(resultPath)) PeWriter.WritePeToStream(assembly, Host, fs); return(resultPath); }
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)); }
void AssertWriteToPeFile(PeVerifyResult expectedResult, IAssembly assembly) { using (FileStream rewrittenFile = File.Create(assembly.Location)) { using (this.pdbReader) { PeWriter.WritePeToStream(assembly, this.host, rewrittenFile, this.pdbReader, this.pdbReader, this.pdbWriter); } } Assert.True(File.Exists(assembly.Location)); PeVerify.Assert(expectedResult, PeVerify.VerifyAssembly(assembly.Location)); }
internal static void EmitCorLibWithAssemblyReferences( Compilation comp, string pdbPath, Func <CommonPEModuleBuilder, EmitOptions, CommonPEModuleBuilder> getModuleBuilder, out ImmutableArray <byte> peBytes, out ImmutableArray <byte> pdbBytes) { var diagnostics = DiagnosticBag.GetInstance(); var emitOptions = EmitOptions.Default.WithRuntimeMetadataVersion("0.0.0.0").WithDebugInformationFormat(DebugInformationFormat.PortablePdb); var moduleBuilder = comp.CheckOptionsAndCreateModuleBuilder( diagnostics, null, emitOptions, null, null, null, null, default(CancellationToken)); // Wrap the module builder in a module builder that // reports the "System.Object" type as having no base type. moduleBuilder = getModuleBuilder(moduleBuilder, emitOptions); bool result = comp.Compile( moduleBuilder, emittingPdb: pdbPath != null, diagnostics: diagnostics, filterOpt: null, cancellationToken: default(CancellationToken)); using (var peStream = new MemoryStream()) { using (var pdbStream = new MemoryStream()) { PeWriter.WritePeToStream( new EmitContext(moduleBuilder, null, diagnostics, metadataOnly: false, includePrivateMembers: true), comp.MessageProvider, () => peStream, () => pdbStream, null, null, metadataOnly: true, isDeterministic: false, emitTestCoverageData: false, privateKeyOpt: null, cancellationToken: default(CancellationToken)); peBytes = peStream.ToImmutable(); pdbBytes = pdbStream.ToImmutable(); } } diagnostics.Verify(); diagnostics.Free(); }
private static int RunTest(HostEnvironment hostEnvironment, string suiteName, string test, StringBuilder actualOutput, List <string> compilerParameters, List <string> testCaseParameters) { hostEnvironment.hasError = false; IName name = hostEnvironment.NameTable.GetNameFor(suiteName); SpecSharpOptions options = new SpecSharpOptions(); //TODO: extract from params List <IAssemblyReference> assemblyReferences = new List <IAssemblyReference>(); List <IModuleReference> moduleReferences = new List <IModuleReference>(); assemblyReferences.Add(hostEnvironment.LoadAssembly(hostEnvironment.CoreAssemblySymbolicIdentity)); IUnit unit; SpecSharpAssembly /*?*/ assem = null; SpecSharpCompilationHelper helper; if (hostEnvironment.previousDocument != null && compilerParameters.Contains("/incremental")) { unit = hostEnvironment.GetIncrementalUnit(test); helper = (SpecSharpCompilationHelper)hostEnvironment.previousDocument.SpecSharpCompilationPart.Helper; } else { List <SpecSharpSourceDocument> programSources = new List <SpecSharpSourceDocument>(1); assem = new SpecSharpAssembly(name, "", hostEnvironment, options, assemblyReferences, moduleReferences, programSources); helper = new SpecSharpCompilationHelper(assem.Compilation); programSources.Add(hostEnvironment.previousDocument = new SpecSharpSourceDocument(helper, name, "", test)); unit = assem; } if (assem != null && assem.Compilation.HasErrors) { return(0); } if (assem != null && assem.EntryPoint.ResolvedMethod != Dummy.Method) { var memStream = new MemoryStream(); PeWriter.WritePeToStream(assem, hostEnvironment, memStream); if (hostEnvironment.hasError) { return(0); } var runtimeAssembly = System.Reflection.Assembly.Load(memStream.ToArray()); var result = runtimeAssembly.EntryPoint.Invoke(null, null); if (result is int) { return((int)result); } return(0); } BaseCodeTraverser traverser = new BaseCodeTraverser(); unit.Dispatch(traverser); return(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); } } }
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); }
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); } } } }
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); } } }
public void Save(CciAssembly assembly, string path) { Contract.Requires(assembly != null); Contract.Requires(!string.IsNullOrEmpty(path)); var sourceLocationProvider = GetPdbReader(assembly.Module); lock (turnstile) { ContractHelper.InjectContractCalls(host, assembly.Module, assembly.ContractProvider, sourceLocationProvider); } using (var peStream = File.Create(path)) { lock (turnstile) { PeWriter.WritePeToStream(assembly.Module, host, peStream); } } }
public static void Main(string[] args) { if (args.Length != 2) { Console.WriteLine("Usage: PInvokeCompiler Input.dll Output.dll"); return; } var inputFile = args[0]; var outputFile = args[1]; using (var host = new PeReader.DefaultHost()) { var unit = host.LoadUnitFrom(inputFile); var assembly = unit as IAssembly; if (assembly == null) { Console.WriteLine("Error: Input file not loadable as assembly"); return; } Assembly mutable = new MetadataDeepCopier(host).Copy(assembly); var interopHelperReference = new InteropHelperReferences(host, mutable); var pinvokeMethodMetadataTraverser = new PInvokeMethodMetadataTraverser(interopHelperReference.PInvokeHelpers); pinvokeMethodMetadataTraverser.TraverseChildren(mutable); var methodTransformationMetadataRewriter = new MethodTransformationMetadataRewriter(interopHelperReference.LoadLibrary, interopHelperReference.GetProcAddress, interopHelperReference.IsLibraryInitialized, host, pinvokeMethodMetadataTraverser); methodTransformationMetadataRewriter.RewriteChildren(mutable); var pinvokeMethodMetadataRewriter = new PInvokeMethodMetadataRewriter(interopHelperReference, host, methodTransformationMetadataRewriter); pinvokeMethodMetadataRewriter.RewriteChildren(mutable); using (var stream = File.Create(outputFile)) { PeWriter.WritePeToStream(mutable, host, stream); } } }
public MemoryStream WriteToStream(IModuleInfo moduleInfo) { var module = (ModuleInfo)moduleInfo; _log.Info("CommonCompilerInfra.WriteToFile:" + module.Name); MemoryStream stream = new MemoryStream(); if (module.PdbReader == null) { PeWriter.WritePeToStream(module.Module, _host, stream); } else { throw new NotImplementedException(); // using (var pdbWriter = new PdbWriter(Path.ChangeExtension(filePath, "pdb"), module.PdbReader)) // { // PeWriter.WritePeToStream(module.Module, _host, stream, module.SourceLocationProvider, // module.LocalScopeProvider, pdbWriter); // } } stream.Position = 0; return(stream); }
static void Main(string[] args) { var nameTable = new NameTable(); using (var host = new PeReader.DefaultHost(nameTable)) { var coreAssembly = host.LoadAssembly(host.CoreAssemblySymbolicIdentity); var assembly = new Assembly() { Name = nameTable.GetNameFor("hello"), ModuleName = nameTable.GetNameFor("hello.exe"), PlatformType = host.PlatformType, Kind = ModuleKind.ConsoleApplication, RequiresStartupStub = host.PointerSize == 4, TargetRuntimeVersion = coreAssembly.TargetRuntimeVersion, }; assembly.AssemblyReferences.Add(coreAssembly); var rootUnitNamespace = new RootUnitNamespace(); assembly.UnitNamespaceRoot = rootUnitNamespace; rootUnitNamespace.Unit = assembly; var moduleClass = new NamespaceTypeDefinition() { ContainingUnitNamespace = rootUnitNamespace, InternFactory = host.InternFactory, IsClass = true, Name = nameTable.GetNameFor("<Module>"), }; assembly.AllTypes.Add(moduleClass); var testClass = new NamespaceTypeDefinition() { ContainingUnitNamespace = rootUnitNamespace, InternFactory = host.InternFactory, IsClass = true, IsPublic = true, Methods = new List <IMethodDefinition>(1), Name = nameTable.GetNameFor("Test"), }; rootUnitNamespace.Members.Add(testClass); assembly.AllTypes.Add(testClass); testClass.BaseClasses = new List <ITypeReference>() { host.PlatformType.SystemObject }; var mainMethod = new MethodDefinition() { ContainingTypeDefinition = testClass, InternFactory = host.InternFactory, IsCil = true, IsStatic = true, Name = nameTable.GetNameFor("Main"), Type = host.PlatformType.SystemVoid, Visibility = TypeMemberVisibility.Public, }; assembly.EntryPoint = mainMethod; testClass.Methods.Add(mainMethod); var ilGenerator = new ILGenerator(host, mainMethod); var systemConsole = UnitHelper.FindType(nameTable, coreAssembly, "System.Console"); var writeLine = TypeHelper.GetMethod(systemConsole, nameTable.GetNameFor("WriteLine"), host.PlatformType.SystemString); ilGenerator.Emit(OperationCode.Ldstr, "hello"); ilGenerator.Emit(OperationCode.Call, writeLine); ilGenerator.Emit(OperationCode.Ret); var body = new ILGeneratorMethodBody(ilGenerator, true, 1, mainMethod, Enumerable <ILocalDefinition> .Empty, Enumerable <ITypeDefinition> .Empty); mainMethod.Body = body; using (var peStream = File.Create("hello.exe")) { PeWriter.WritePeToStream(assembly, host, peStream); } } }
public void Compile(string fileName) { string appName = Path.GetFileNameWithoutExtension(fileName); string exeName = appName + ".exe"; string src = ""; using (TextReader file = new StreamReader(fileName)) { src = file.ReadToEnd(); } var nameTable = new NameTable(); using (var host = new PeReader.DefaultHost(nameTable)) { // Load Mirage types IModule module = host.LoadUnitFrom("Mirage.dll") as IModule; if (module == null || module is Dummy) { return; } var machineType = module.GetAllTypes().First(x => x.Name.Value == "Machine"); var inputType = module.GetAllTypes().First(x => x.Name.Value == "ConsoleInput"); var outputType = module.GetAllTypes().First(x => x.Name.Value == "ConsoleOutput"); // Create assembly var coreAssembly = host.LoadAssembly(host.CoreAssemblySymbolicIdentity); var assembly = new Assembly() { Name = nameTable.GetNameFor(appName), ModuleName = nameTable.GetNameFor(exeName), PlatformType = host.PlatformType, Kind = ModuleKind.ConsoleApplication, RequiresStartupStub = host.PointerSize == 4, TargetRuntimeVersion = coreAssembly.TargetRuntimeVersion, }; assembly.AssemblyReferences.Add(coreAssembly); // Create namespace var rootUnitNamespace = new RootUnitNamespace(); assembly.UnitNamespaceRoot = rootUnitNamespace; rootUnitNamespace.Unit = assembly; // Create module class var moduleClass = new NamespaceTypeDefinition() { ContainingUnitNamespace = rootUnitNamespace, InternFactory = host.InternFactory, IsClass = true, Name = nameTable.GetNameFor("<Module>"), }; assembly.AllTypes.Add(moduleClass); // Create program class var programClass = new NamespaceTypeDefinition() { ContainingUnitNamespace = rootUnitNamespace, InternFactory = host.InternFactory, IsClass = true, IsPublic = true, Methods = new List <IMethodDefinition>(1), Name = nameTable.GetNameFor("Program"), }; programClass.BaseClasses = new List <ITypeReference>() { host.PlatformType.SystemObject }; rootUnitNamespace.Members.Add(programClass); // Add types to the assembly assembly.AllTypes.Add(machineType); foreach (var t in machineType.NestedTypes) { assembly.AllTypes.Add(t); } assembly.AllTypes.Add(inputType); assembly.AllTypes.Add(outputType); assembly.AllTypes.Add(programClass); // Create main method var mainMethod = new MethodDefinition() { ContainingTypeDefinition = programClass, InternFactory = host.InternFactory, IsCil = true, IsStatic = true, Name = nameTable.GetNameFor("Main"), Type = host.PlatformType.SystemVoid, Visibility = TypeMemberVisibility.Public, }; assembly.EntryPoint = mainMethod; programClass.Methods.Add(mainMethod); // Create constructors and methods IMethodReference machineConstructor = new Microsoft.Cci.MethodReference( host, machineType, CallingConvention.HasThis, host.PlatformType.SystemVoid, host.NameTable.Ctor, 0 ); IMethodReference inputConstructor = new Microsoft.Cci.MethodReference( host, inputType, CallingConvention.HasThis, host.PlatformType.SystemVoid, host.NameTable.Ctor, 0 ); var inputCast = TypeHelper.GetMethod(inputType, nameTable.GetNameFor("op_Implicit"), inputType); IMethodReference outputConstructor = new Microsoft.Cci.MethodReference( host, outputType, CallingConvention.HasThis, host.PlatformType.SystemVoid, host.NameTable.Ctor, 0 ); var outputCast = TypeHelper.GetMethod(outputType, nameTable.GetNameFor("op_Implicit"), outputType); var opIncPointers = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("IncPointers")); var opDecPointers = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("DecPointers")); var opIncHiPointer = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("IncHiPointer")); var opDecHiPointer = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("DecHiPointer")); var opReflectHiPointer = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("ReflectHiPointer")); var opLoadHiPointer = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("LoadHiPointer")); var opDragLoPointer = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("DragLoPointer")); var opXchPointers = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("XchPointers")); var opClear = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("Clear")); var opAdd = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("Add")); var opDec = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("Dec")); var opNot = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("Not")); var opAnd = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("And")); var opOr = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("Or")); var opXor = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("Xor")); var opSal = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("Sal")); var opSar = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("Sar")); var opLoadData = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("LoadData"), host.PlatformType.SystemString); var opInput = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("Input"), inputCast.Type); var opOutput = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("Output"), outputCast.Type); var opJz = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("Jz")); // Create program code var labels = new Stack <ILGeneratorLabel>(100); var ilGenerator = new ILGenerator(host, mainMethod); ilGenerator.Emit(OperationCode.Newobj, machineConstructor); ilGenerator.Emit(OperationCode.Stloc_0); ilGenerator.Emit(OperationCode.Newobj, inputConstructor); ilGenerator.Emit(OperationCode.Stloc_1); ilGenerator.Emit(OperationCode.Newobj, outputConstructor); ilGenerator.Emit(OperationCode.Stloc_2); int pc = 0; while (pc < src.Length) { char opcode = src[pc++]; switch (opcode) { case '>': ilGenerator.Emit(OperationCode.Ldloc_0); ilGenerator.Emit(OperationCode.Callvirt, opIncPointers); break; case '<': ilGenerator.Emit(OperationCode.Ldloc_0); ilGenerator.Emit(OperationCode.Callvirt, opDecPointers); break; case ']': ilGenerator.Emit(OperationCode.Ldloc_0); ilGenerator.Emit(OperationCode.Callvirt, opIncHiPointer); break; case '[': ilGenerator.Emit(OperationCode.Ldloc_0); ilGenerator.Emit(OperationCode.Callvirt, opDecHiPointer); break; case '#': ilGenerator.Emit(OperationCode.Ldloc_0); ilGenerator.Emit(OperationCode.Callvirt, opReflectHiPointer); break; case '$': ilGenerator.Emit(OperationCode.Ldloc_0); ilGenerator.Emit(OperationCode.Callvirt, opLoadHiPointer); break; case '=': ilGenerator.Emit(OperationCode.Ldloc_0); ilGenerator.Emit(OperationCode.Callvirt, opDragLoPointer); break; case '%': ilGenerator.Emit(OperationCode.Ldloc_0); ilGenerator.Emit(OperationCode.Callvirt, opXchPointers); break; case '_': ilGenerator.Emit(OperationCode.Ldloc_0); ilGenerator.Emit(OperationCode.Callvirt, opClear); break; case '+': ilGenerator.Emit(OperationCode.Ldloc_0); ilGenerator.Emit(OperationCode.Callvirt, opAdd); break; case '-': ilGenerator.Emit(OperationCode.Ldloc_0); ilGenerator.Emit(OperationCode.Callvirt, opDec); break; case '~': ilGenerator.Emit(OperationCode.Ldloc_0); ilGenerator.Emit(OperationCode.Callvirt, opNot); break; case '&': ilGenerator.Emit(OperationCode.Ldloc_0); ilGenerator.Emit(OperationCode.Callvirt, opAnd); break; case '|': ilGenerator.Emit(OperationCode.Ldloc_0); ilGenerator.Emit(OperationCode.Callvirt, opOr); break; case '^': ilGenerator.Emit(OperationCode.Ldloc_0); ilGenerator.Emit(OperationCode.Callvirt, opXor); break; case '*': ilGenerator.Emit(OperationCode.Ldloc_0); ilGenerator.Emit(OperationCode.Callvirt, opSal); break; case '/': ilGenerator.Emit(OperationCode.Ldloc_0); ilGenerator.Emit(OperationCode.Callvirt, opSar); break; case '(': int dataStart = pc; int dataEnd = dataStart; while (src[pc++] != ')') { dataEnd = pc; } ilGenerator.Emit(OperationCode.Ldloc_0); ilGenerator.Emit(OperationCode.Ldstr, src.Substring(dataStart, dataEnd - dataStart)); ilGenerator.Emit(OperationCode.Callvirt, opLoadData); break; case '?': ilGenerator.Emit(OperationCode.Ldloc_0); ilGenerator.Emit(OperationCode.Ldloc_1); ilGenerator.Emit(OperationCode.Call, inputCast); ilGenerator.Emit(OperationCode.Callvirt, opInput); break; case '!': ilGenerator.Emit(OperationCode.Ldloc_0); ilGenerator.Emit(OperationCode.Ldloc_2); ilGenerator.Emit(OperationCode.Call, outputCast); ilGenerator.Emit(OperationCode.Callvirt, opOutput); break; case '{': var cycleStart = new ILGeneratorLabel(); var cycleEnd = new ILGeneratorLabel(); labels.Push(cycleStart); labels.Push(cycleEnd); ilGenerator.Emit(OperationCode.Br, cycleEnd); ilGenerator.MarkLabel(cycleStart); break; case '}': ilGenerator.MarkLabel(labels.Pop()); ilGenerator.Emit(OperationCode.Ldloc_0); ilGenerator.Emit(OperationCode.Callvirt, opJz); ilGenerator.Emit(OperationCode.Ldc_I4_0); ilGenerator.Emit(OperationCode.Ceq); ilGenerator.Emit(OperationCode.Stloc_3); ilGenerator.Emit(OperationCode.Ldloc_3); ilGenerator.Emit(OperationCode.Brtrue, labels.Pop()); break; default: break; } } ilGenerator.Emit(OperationCode.Ret); mainMethod.Body = new ILGeneratorMethodBody( ilGenerator, true, 8, mainMethod, new List <ILocalDefinition>() { new LocalDefinition() { Type = machineType }, new LocalDefinition() { Type = inputType }, new LocalDefinition() { Type = outputType }, new LocalDefinition() { Type = host.PlatformType.SystemInt32 }, }, Enumerable <ITypeDefinition> .Empty ); using (var peStream = File.Create(exeName)) { PeWriter.WritePeToStream(assembly, host, peStream); } } }
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 }
static void Main(string[] args) { var nameTable = new NameTable(); using (var host = new PeReader.DefaultHost(nameTable)) { var coreAssembly = host.LoadAssembly(host.CoreAssemblySymbolicIdentity); var assembly = new Assembly() { Name = nameTable.GetNameFor("hello"), ModuleName = nameTable.GetNameFor("hello.exe"), Kind = ModuleKind.ConsoleApplication, PlatformType = host.PlatformType, RequiresStartupStub = host.PointerSize == 4, TargetRuntimeVersion = coreAssembly.TargetRuntimeVersion, }; assembly.AssemblyReferences.Add(coreAssembly); var rootUnitNamespace = new RootUnitNamespace(); assembly.UnitNamespaceRoot = rootUnitNamespace; rootUnitNamespace.Unit = assembly; var moduleClass = new NamespaceTypeDefinition() { ContainingUnitNamespace = rootUnitNamespace, InternFactory = host.InternFactory, IsClass = true, Name = nameTable.GetNameFor("<Module>"), }; assembly.AllTypes.Add(moduleClass); var testClass = new NamespaceTypeDefinition() { BaseClasses = new List <ITypeReference>(1) { host.PlatformType.SystemObject }, ContainingUnitNamespace = rootUnitNamespace, InternFactory = host.InternFactory, IsClass = true, IsPublic = true, Methods = new List <IMethodDefinition>(1), Name = nameTable.GetNameFor("Test"), }; rootUnitNamespace.Members.Add(testClass); assembly.AllTypes.Add(testClass); var mainMethod = new MethodDefinition() { ContainingTypeDefinition = testClass, InternFactory = host.InternFactory, IsCil = true, IsStatic = true, Name = nameTable.GetNameFor("Main"), Type = host.PlatformType.SystemVoid, Visibility = TypeMemberVisibility.Public, }; assembly.EntryPoint = mainMethod; testClass.Methods.Add(mainMethod); var body = new SourceMethodBody(host) { MethodDefinition = mainMethod, LocalsAreZeroed = true }; mainMethod.Body = body; var block = new BlockStatement(); body.Block = block; var systemConsole = UnitHelper.FindType(nameTable, coreAssembly, "System.Console"); var writeLine = TypeHelper.GetMethod(systemConsole, nameTable.GetNameFor("WriteLine"), host.PlatformType.SystemString); var call = new MethodCall() { IsStaticCall = true, MethodToCall = writeLine, Type = host.PlatformType.SystemVoid }; call.Arguments.Add(new CompileTimeConstant() { Type = host.PlatformType.SystemString, Value = "hello" }); block.Statements.Add(new ExpressionStatement() { Expression = call }); block.Statements.Add(new ReturnStatement()); using (var peStream = File.Create("hello.exe")) { PeWriter.WritePeToStream(assembly, host, peStream); } } }
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); }
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 }
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); } } } } } }
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); } }
public void Save(bool autoHandleDependencies = false) { lock (this) { if (_manifest != null) { _pendingChanges = _manifest.Modified || _pendingChanges; } // Logger.Message("Saving Binary '{0}' : Pending Changes: {1} ", _filename, _pendingChanges); if (_pendingChanges) { // saves any changes made to the binary. // work on a back up of the file var tmpFilename = _filename.CreateWritableWorkingCopy(); try { // remove any digital signatures from the binary before doing anything if (!IsManaged) { StripSignatures(tmpFilename); // this is irrelevant if the binary is managed--we'll be writing out a new one. } // rewrite any native resources that we want to change. if (IsManaged && ILOnly) { // we can only edit the file if it's IL only, mixed mode assemblies can only be strong named, signed and native-resource-edited. // set the strong name key data MutableAssembly.PublicKey = StrongNameKey.ToList(); // change any assembly attributes we need to change if (MutableAssembly != null) { if (StrongNameKeyCertificate != null) { foreach (var ar in MutableAssembly.AssemblyReferences) { if (!ar.PublicKeyToken.Any()) { var dep = FindAssembly(ar.Name.Value, ar.Version.ToString()); if (dep == null) { // can't strong name a file that doesn't have its deps all strong named. throw new ClrPlusException("dependent assembly '{0}-{1}' not available for strong naming".format(ar.Name.Value, ar.Version.ToString())); } lock (dep) { // this should wait until the dependency is finished saving, right? } if (dep.MutableAssembly.PublicKey.IsNullOrEmpty()) { if (autoHandleDependencies) { Console.WriteLine( "Warning: Non-strong-named dependent reference found: '{0}-{1}' updating with same strong-name-key.", ar.Name, ar.Version); dep.StrongNameKeyCertificate = StrongNameKeyCertificate; dep.SigningCertificate = SigningCertificate; dep.AssemblyCopyright = AssemblyCopyright; dep.AssemblyCompany = AssemblyCompany; dep.AssemblyProduct = AssemblyProduct; dep.Save(); } else { throw new ClrPlusException("dependent assembly '{0}-{1}' not strong named".format(ar.Name.Value, ar.Version.ToString())); } } (ar as Microsoft.Cci.MutableCodeModel.AssemblyReference).PublicKeyToken = dep.MutableAssembly.PublicKeyToken.ToList(); (ar as Microsoft.Cci.MutableCodeModel.AssemblyReference).PublicKey = dep.MutableAssembly.PublicKey; } } } // we should see if we can get assembly attributes, since sometimes they can be set, but not the native ones. try { foreach (var a in MutableAssembly.AssemblyAttributes) { var attributeArgument = (a.Arguments.FirstOrDefault() as MetadataConstant); if (attributeArgument != null) { var attributeName = a.Type.ToString(); switch (attributeName) { case "System.Reflection.AssemblyTitleAttribute": attributeArgument.Value = string.IsNullOrEmpty(AssemblyTitle) ? string.Empty : AssemblyTitle; break; case "System.Reflection.AssemblyDescriptionAttribute": attributeArgument.Value = string.IsNullOrEmpty(AssemblyDescription) ? string.Empty : AssemblyDescription; break; case "System.Reflection.AssemblyCompanyAttribute": attributeArgument.Value = string.IsNullOrEmpty(AssemblyCompany) ? string.Empty : AssemblyCompany; break; case "System.Reflection.AssemblyProductAttribute": attributeArgument.Value = string.IsNullOrEmpty(AssemblyProduct) ? string.Empty : AssemblyProduct; break; case "System.Reflection.AssemblyVersionAttribute": attributeArgument.Value = string.IsNullOrEmpty(AssemblyVersion) ? string.Empty : AssemblyVersion; break; case "System.Reflection.AssemblyFileVersionAttribute": attributeArgument.Value = string.IsNullOrEmpty(AssemblyFileVersion) ? string.Empty : AssemblyFileVersion; break; case "System.Reflection.AssemblyCopyrightAttribute": attributeArgument.Value = string.IsNullOrEmpty(AssemblyCopyright) ? string.Empty : AssemblyCopyright; break; case "System.Reflection.AssemblyTrademarkAttribute": attributeArgument.Value = string.IsNullOrEmpty(AssemblyTrademark) ? string.Empty : AssemblyTrademark; break; case "BugTrackerAttribute": attributeArgument.Value = string.IsNullOrEmpty(BugTracker) ? string.Empty : BugTracker; break; } } } } catch { // hmm. carry on. } } // save it to disk using (var peStream = File.Create(tmpFilename)) { PeWriter.WritePeToStream(MutableAssembly, _host, peStream); } } // update native metadata try { var ri = new ResourceInfo(); ri.Load(tmpFilename); if (_manifest != null && _manifest.Modified) { // GS01: We only support one manifest right now. // so we're gonna remove the extra ones. // figure out the bigger case later. var manifestKeys = ri.Resources.Keys.Where(each => each.ResourceType == ResourceTypes.RT_MANIFEST).ToArray(); foreach (var k in manifestKeys) { ri.Resources.Remove(k); } var manifestResource = new ManifestResource(); manifestResource.ManifestText = _manifest.ToString(); ri.Resources.Add(new ResourceId(ResourceTypes.RT_MANIFEST), new List <Resource> { manifestResource }); manifestResource.SaveTo(tmpFilename); } VersionResource versionResource; StringTable versionStringTable; var versionKey = ri.Resources.Keys.Where(each => each.ResourceType == ResourceTypes.RT_VERSION).FirstOrDefault(); if (versionKey != null) { versionResource = ri.Resources[versionKey].First() as VersionResource; versionStringTable = (versionResource["StringFileInfo"] as StringFileInfo).Strings.Values.First(); } else { versionResource = new VersionResource(); ri.Resources.Add(new ResourceId(ResourceTypes.RT_VERSION), new List <Resource> { versionResource }); var sfi = new StringFileInfo(); versionResource["StringFileInfo"] = sfi; sfi.Strings["040904b0"] = (versionStringTable = new StringTable("040904b0")); var vfi = new VarFileInfo(); versionResource["VarFileInfo"] = vfi; var translation = new VarTable("Translation"); vfi.Vars["Translation"] = translation; translation[0x0409] = 0x04b0; } versionResource.FileVersion = FileVersion; versionResource.ProductVersion = ProductVersion; versionStringTable["ProductName"] = ProductName; versionStringTable["CompanyName"] = CompanyName; versionStringTable["FileDescription"] = FileDescription; versionStringTable["Comments"] = _comments; versionStringTable["Assembly Version"] = _assemblyVersion; versionStringTable["FileVersion"] = _fileVersion; versionStringTable["ProductVersion"] = _productVersion; versionStringTable["InternalName"] = _internalName; versionStringTable["OriginalFilename"] = _originalFilename; versionStringTable["LegalCopyright"] = _legalCopyright; versionStringTable["LegalTrademarks"] = _legalTrademarks; versionStringTable["BugTracker"] = _bugTracker; versionResource.SaveTo(tmpFilename); } catch (Exception e) { Console.WriteLine("{0} -- {1}", e.Message, e.StackTrace); } // strong name the binary if (IsManaged && StrongNameKeyCertificate != null && (StrongNameKeyCertificate.Certificate.PrivateKey is RSACryptoServiceProvider)) { ApplyStrongName(tmpFilename, StrongNameKeyCertificate); } // sign the binary if (_signingCertificate != null) { SignFile(tmpFilename, SigningCertificate.Certificate); } _filename.TryHardToDelete(); File.Move(tmpFilename, _filename); } catch (Exception e) { #if TODO Logger.Error(e); #endif // get rid of whatever we tried tmpFilename.TryHardToDelete(); // as you were... throw; } } _pendingChanges = false; if (_manifest != null) { _manifest.Modified = false; } } }
internal static void Amend(params string[] targets) { // Ensure that at least one target assembly was specified if (targets == null || targets.Length == 0) { throw new ArgumentException("At least one target assembly must be specified."); } // Ensure that the target assemblies exist for (int i = 0; i < targets.Length; i++) { var path = targets[i] = Path.GetFullPath(targets[i]); if (!File.Exists(path)) { throw new ArgumentException("The specified target assembly, " + path + ", does not exist."); } } // Determine the set of target directories and backup locations var directories = targets .Select(path => Path.GetDirectoryName(path).ToLower()) .Distinct() .Select(directory => new { SourcePath = directory, BackupPath = Directory.CreateDirectory(Path.Combine(directory, "Backup")).FullName }); // Determine the set of dlls, pdbs, and backup files var assemblies = targets .Select(dllPath => new { DllPath = dllPath, DllBackupPath = Path.Combine(Path.Combine(Path.GetDirectoryName(dllPath), "Backup"), Path.GetFileName(dllPath)), PdbPath = Path.Combine(Path.GetDirectoryName(dllPath), Path.GetFileNameWithoutExtension(dllPath) + ".pdb"), PdbBackupPath = Path.Combine(Path.Combine(Path.GetDirectoryName(dllPath), "Backup"), Path.GetFileNameWithoutExtension(dllPath) + ".pdb") }); // Backup the directories containing the targeted dll and pdb files foreach (var directory in directories) { foreach (var file in Directory.GetFiles(directory.SourcePath)) { if (file.ToLower().EndsWith("exe") || file.ToLower().EndsWith("dll") || file.ToLower().EndsWith("pdb")) { File.Copy(file, Path.Combine(directory.BackupPath, Path.GetFileName(file)), true); } } } // Register an assembly resolver to look in backup folders when resolving assemblies AppDomain.CurrentDomain.AssemblyResolve += (s, e) => { try { return(System.Reflection.Assembly.Load(e.Name)); } catch { foreach (var directory in directories) { var dependency = Path.Combine(directory.BackupPath, e.Name.Substring(0, e.Name.IndexOf(',')) + ".dll"); if (File.Exists(dependency)) { return(System.Reflection.Assembly.LoadFrom(dependency)); } } return(null); } }; // Get the set of amendments to apply from all of the specified assemblies var amendments = AmendmentAttribute.GetAmendments(assemblies.Select(a => System.Reflection.Assembly.LoadFrom(a.DllBackupPath)).ToArray()).ToList(); // Exit immediately if there are no amendments in the target assemblies if (amendments.Count == 0) { return; } // Process each target assembly individually foreach (var assembly in assemblies) { var assemblyAmendments = amendments.Where(a => a.Type.Assembly.Location == assembly.DllBackupPath).ToArray(); if (assemblyAmendments.Length == 0) { continue; } Console.Write("Amending " + Path.GetFileName(assembly.DllPath)); var start = DateTime.Now; using (var host = new PeReader.DefaultHost()) { // Load the target assembly IModule module = host.LoadUnitFrom(assembly.DllBackupPath) as IModule; if (module == null || module == Dummy.Module || module == Dummy.Assembly) { throw new ArgumentException(assembly.DllBackupPath + " is not a PE file containing a CLR assembly, or an error occurred when loading it."); } // Copy the assembly to enable it to be mutated module = new MetadataDeepCopier(host).Copy(module); // Load the debug file if it exists PdbReader pdbReader = null; if (File.Exists(assembly.PdbBackupPath)) { using (var pdbStream = File.OpenRead(assembly.PdbBackupPath)) { pdbReader = new PdbReader(pdbStream, host); } } // Amend and persist the target assembly using (pdbReader) { // Create and execute a new assembly amender AssemblyAmender amender = new AssemblyAmender(host, pdbReader, assemblyAmendments); amender.TargetRuntimeVersion = module.TargetRuntimeVersion; module = amender.Visit(module); // Save the amended assembly back to the original directory using (var pdbWriter = pdbReader != null ? new PdbWriter(assembly.PdbPath, pdbReader) : null) { using (var dllStream = File.Create(assembly.DllPath)) { PeWriter.WritePeToStream(module, host, dllStream, pdbReader, null, pdbWriter); } } } } Console.WriteLine(" (" + DateTime.Now.Subtract(start).TotalSeconds.ToString("0.000") + " seconds)"); } }