/// <summary> /// Emit built sections using the R2R PE writer. /// </summary> /// <param name="builder">Section builder to emit</param> /// <param name="machine">Target machine architecture</param> /// <param name="inputReader">Input MSIL reader</param> /// <param name="outputStream">Output stream for the final R2R PE file</param> public static void EmitR2R( this SectionBuilder builder, Machine machine, PEReader inputReader, Action <PEDirectoriesBuilder> directoriesUpdater, Stream outputStream) { R2RPEBuilder r2rBuilder = new R2RPEBuilder( machine: machine, peReader: inputReader, sectionNames: builder.GetSections(), sectionSerializer: builder.SerializeSection, directoriesUpdater: (PEDirectoriesBuilder directoriesBuilder) => { builder.UpdateDirectories(directoriesBuilder); if (directoriesUpdater != null) { directoriesUpdater(directoriesBuilder); } }); BlobBuilder outputPeFile = new BlobBuilder(); r2rBuilder.Serialize(outputPeFile); CorHeaderBuilder corHeader = r2rBuilder.CorHeader; if (corHeader != null) { corHeader.Flags = (r2rBuilder.CorHeader.Flags & ~CorFlags.ILOnly) | CorFlags.ILLibrary; corHeader.MetadataDirectory = r2rBuilder.RelocateDirectoryEntry(corHeader.MetadataDirectory); corHeader.ResourcesDirectory = r2rBuilder.RelocateDirectoryEntry(corHeader.ResourcesDirectory); corHeader.StrongNameSignatureDirectory = r2rBuilder.RelocateDirectoryEntry(corHeader.StrongNameSignatureDirectory); corHeader.CodeManagerTableDirectory = r2rBuilder.RelocateDirectoryEntry(corHeader.CodeManagerTableDirectory); corHeader.VtableFixupsDirectory = r2rBuilder.RelocateDirectoryEntry(corHeader.VtableFixupsDirectory); corHeader.ExportAddressTableJumpsDirectory = r2rBuilder.RelocateDirectoryEntry(corHeader.ExportAddressTableJumpsDirectory); corHeader.ManagedNativeHeaderDirectory = r2rBuilder.RelocateDirectoryEntry(corHeader.ManagedNativeHeaderDirectory); builder.UpdateCorHeader(corHeader); } builder.RelocateOutputFile( outputPeFile, inputReader.PEHeaders.PEHeader.ImageBase, corHeader, r2rBuilder.CorHeaderFileOffset, outputStream); r2rBuilder.RelocateMetadataBlob(outputStream); }
/// <summary> /// Copy all directory entries and the address of entry point, relocating them along the way. /// </summary> protected override PEDirectoriesBuilder GetDirectories() { PEDirectoriesBuilder builder = new PEDirectoriesBuilder(); _sectionBuilder.UpdateDirectories(builder); RuntimeFunctionsTableNode runtimeFunctionsTable = _getRuntimeFunctionsTable(); builder.ExceptionTable = new DirectoryEntry( relativeVirtualAddress: _sectionBuilder.GetSymbolRVA(runtimeFunctionsTable), size: runtimeFunctionsTable.TableSize); return(builder); }