예제 #1
0
        /// <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);
        }
예제 #2
0
        /// <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);
        }