Ejemplo n.º 1
0
        /// <inheritdoc/>
        public void WriteTo(BinaryWriter writer)
        {
            startOffset = writer.BaseStream.Position;

            // DOS header
            writer.Write(dosHeader);

            // PE magic
            writer.Write(0x00004550);

            // Image file header
            writer.Write((ushort)GetMachine());
            writer.Write((ushort)sections.Count);
            writer.Write(options.TimeDateStamp ?? PEHeadersOptions.CreateNewTimeDateStamp());
            writer.Write(options.PointerToSymbolTable ?? 0);
            writer.Write(options.NumberOfSymbols ?? 0);
            writer.Write((ushort)(Use32BitOptionalHeader() ? 0xE0U : 0xF0));
            writer.Write((ushort)GetCharacteristics());

            var sectionSizes = new SectionSizes(fileAlignment, sectionAlignment, length, () => GetSectionSizeInfos());

            // Image optional header
            uint ep = StartupStub == null ? 0 : (uint)StartupStub.EntryPointRVA;

            if (Use32BitOptionalHeader())
            {
                writer.Write((ushort)0x010B);
                writer.Write(options.MajorLinkerVersion ?? PEHeadersOptions.DEFAULT_MAJOR_LINKER_VERSION);
                writer.Write(options.MinorLinkerVersion ?? PEHeadersOptions.DEFAULT_MINOR_LINKER_VERSION);
                writer.Write(sectionSizes.SizeOfCode);
                writer.Write(sectionSizes.SizeOfInitdData);
                writer.Write(sectionSizes.SizeOfUninitdData);
                writer.Write(ep);
                writer.Write(sectionSizes.BaseOfCode);
                writer.Write(sectionSizes.BaseOfData);
                writer.Write((uint)imageBase);
                writer.Write(sectionAlignment);
                writer.Write(fileAlignment);
                writer.Write(options.MajorOperatingSystemVersion ?? 4);
                writer.Write(options.MinorOperatingSystemVersion ?? 0);
                writer.Write(options.MajorImageVersion ?? 0);
                writer.Write(options.MinorImageVersion ?? 0);
                writer.Write(options.MajorSubsystemVersion ?? 4);
                writer.Write(options.MinorSubsystemVersion ?? 0);
                writer.Write(options.Win32VersionValue ?? 0);
                writer.Write(sectionSizes.SizeOfImage);
                writer.Write(sectionSizes.SizeOfHeaders);
                checkSumOffset = writer.BaseStream.Position;
                writer.Write(0);    // CheckSum
                writer.Write((ushort)(options.Subsystem ?? PEHeadersOptions.DEFAULT_SUBSYSTEM));
                writer.Write((ushort)(options.DllCharacteristics ?? PEHeadersOptions.DefaultDllCharacteristics));
                writer.Write((uint)(options.SizeOfStackReserve ?? 0x00100000));
                writer.Write((uint)(options.SizeOfStackCommit ?? 0x00001000));
                writer.Write((uint)(options.SizeOfHeapReserve ?? 0x00100000));
                writer.Write((uint)(options.SizeOfHeapCommit ?? 0x00001000));
                writer.Write(options.LoaderFlags ?? 0x00000000);
                writer.Write(options.NumberOfRvaAndSizes ?? 0x00000010);
            }
            else
            {
                writer.Write((ushort)0x020B);
                writer.Write(options.MajorLinkerVersion ?? PEHeadersOptions.DEFAULT_MAJOR_LINKER_VERSION);
                writer.Write(options.MinorLinkerVersion ?? PEHeadersOptions.DEFAULT_MINOR_LINKER_VERSION);
                writer.Write(sectionSizes.SizeOfCode);
                writer.Write(sectionSizes.SizeOfInitdData);
                writer.Write(sectionSizes.SizeOfUninitdData);
                writer.Write(ep);
                writer.Write(sectionSizes.BaseOfCode);
                writer.Write(imageBase);
                writer.Write(sectionAlignment);
                writer.Write(fileAlignment);
                writer.Write(options.MajorOperatingSystemVersion ?? 4);
                writer.Write(options.MinorOperatingSystemVersion ?? 0);
                writer.Write(options.MajorImageVersion ?? 0);
                writer.Write(options.MinorImageVersion ?? 0);
                writer.Write(options.MajorSubsystemVersion ?? 4);
                writer.Write(options.MinorSubsystemVersion ?? 0);
                writer.Write(options.Win32VersionValue ?? 0);
                writer.Write(sectionSizes.SizeOfImage);
                writer.Write(sectionSizes.SizeOfHeaders);
                checkSumOffset = writer.BaseStream.Position;
                writer.Write(0);    // CheckSum
                writer.Write((ushort)(options.Subsystem ?? PEHeadersOptions.DEFAULT_SUBSYSTEM));
                writer.Write((ushort)(options.DllCharacteristics ?? PEHeadersOptions.DefaultDllCharacteristics));
                writer.Write(options.SizeOfStackReserve ?? 0x0000000000400000);
                writer.Write(options.SizeOfStackCommit ?? 0x0000000000004000);
                writer.Write(options.SizeOfHeapReserve ?? 0x0000000000100000);
                writer.Write(options.SizeOfHeapCommit ?? 0x0000000000002000);
                writer.Write(options.LoaderFlags ?? 0x00000000);
                writer.Write(options.NumberOfRvaAndSizes ?? 0x00000010);
            }

            writer.WriteDataDirectory(null);    // Export table
            writer.WriteDataDirectory(ImportDirectory);
            writer.WriteDataDirectory(Win32Resources);
            writer.WriteDataDirectory(null);    // Exception table
            writer.WriteDataDirectory(null);    // Certificate table
            writer.WriteDataDirectory(RelocDirectory);
            writer.WriteDataDirectory(DebugDirectory, DebugDirectory.HEADER_SIZE);
            writer.WriteDataDirectory(null);    // Architecture-specific data
            writer.WriteDataDirectory(null);    // Global pointer register RVA
            writer.WriteDataDirectory(null);    // Thread local storage
            writer.WriteDataDirectory(null);    // Load configuration table
            writer.WriteDataDirectory(null);    // Bound import table
            writer.WriteDataDirectory(ImportAddressTable);
            writer.WriteDataDirectory(null);    // Delay import descriptor
            writer.WriteDataDirectory(ImageCor20Header);
            writer.WriteDataDirectory(null);    // Reserved

            // Sections
            uint rva = Utils.AlignUp(sectionSizes.SizeOfHeaders, sectionAlignment);

            foreach (var section in sections)
            {
                rva += section.WriteHeaderTo(writer, fileAlignment, sectionAlignment, rva);
            }
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Updates the PE header and COR20 header fields that need updating. All sections are
        /// also updated, and the new ones are added.
        /// </summary>
        private void UpdateHeaderFields(BinaryWriter writer)
        {
            long fileHeaderOffset     = destStreamBaseOffset + (long)peImage.ImageNTHeaders.FileHeader.StartOffset;
            long optionalHeaderOffset = destStreamBaseOffset + (long)peImage.ImageNTHeaders.OptionalHeader.StartOffset;
            long sectionsOffset       = destStreamBaseOffset + (long)peImage.ImageSectionHeaders[0].StartOffset;
            long dataDirOffset        = destStreamBaseOffset + (long)peImage.ImageNTHeaders.OptionalHeader.EndOffset - 16 * 8;
            long cor20Offset          = destStreamBaseOffset + (long)imageCor20Header.FileOffset;

            uint fileAlignment    = peImage.ImageNTHeaders.OptionalHeader.FileAlignment;
            uint sectionAlignment = peImage.ImageNTHeaders.OptionalHeader.SectionAlignment;

            // Update PE file header
            var peOptions = Options.PEHeadersOptions;

            writer.BaseStream.Position = fileHeaderOffset;
            writer.Write((ushort)(peOptions.Machine ?? module.Machine));
            writer.Write((ushort)(origSections.Count + sections.Count));
            WriteUInt32(writer, peOptions.TimeDateStamp);
            WriteUInt32(writer, peOptions.PointerToSymbolTable);
            WriteUInt32(writer, peOptions.NumberOfSymbols);
            writer.BaseStream.Position += 2;    // sizeof(SizeOfOptionalHeader)
            writer.Write((ushort)(peOptions.Characteristics ?? GetCharacteristics()));

            // Update optional header
            var sectionSizes = new SectionSizes(fileAlignment, sectionAlignment, headerSection.GetVirtualSize(), GetSectionSizeInfos);

            writer.BaseStream.Position = optionalHeaderOffset;
            bool is32BitOptionalHeader = peImage.ImageNTHeaders.OptionalHeader is ImageOptionalHeader32;

            if (is32BitOptionalHeader)
            {
                writer.BaseStream.Position += 2;
                WriteByte(writer, peOptions.MajorLinkerVersion);
                WriteByte(writer, peOptions.MinorLinkerVersion);
                writer.Write(sectionSizes.SizeOfCode);
                writer.Write(sectionSizes.SizeOfInitdData);
                writer.Write(sectionSizes.SizeOfUninitdData);
                writer.BaseStream.Position += 4;    // EntryPoint
                writer.Write(sectionSizes.BaseOfCode);
                writer.Write(sectionSizes.BaseOfData);
                WriteUInt32(writer, peOptions.ImageBase);
                writer.BaseStream.Position += 8;    // SectionAlignment, FileAlignment
                WriteUInt16(writer, peOptions.MajorOperatingSystemVersion);
                WriteUInt16(writer, peOptions.MinorOperatingSystemVersion);
                WriteUInt16(writer, peOptions.MajorImageVersion);
                WriteUInt16(writer, peOptions.MinorImageVersion);
                WriteUInt16(writer, peOptions.MajorSubsystemVersion);
                WriteUInt16(writer, peOptions.MinorSubsystemVersion);
                WriteUInt32(writer, peOptions.Win32VersionValue);
                writer.Write(sectionSizes.SizeOfImage);
                writer.Write(sectionSizes.SizeOfHeaders);
                checkSumOffset = writer.BaseStream.Position;
                writer.Write(0);    // CheckSum
                WriteUInt16(writer, peOptions.Subsystem);
                WriteUInt16(writer, peOptions.DllCharacteristics);
                WriteUInt32(writer, peOptions.SizeOfStackReserve);
                WriteUInt32(writer, peOptions.SizeOfStackCommit);
                WriteUInt32(writer, peOptions.SizeOfHeapReserve);
                WriteUInt32(writer, peOptions.SizeOfHeapCommit);
                WriteUInt32(writer, peOptions.LoaderFlags);
                WriteUInt32(writer, peOptions.NumberOfRvaAndSizes);
            }
            else
            {
                writer.BaseStream.Position += 2;
                WriteByte(writer, peOptions.MajorLinkerVersion);
                WriteByte(writer, peOptions.MinorLinkerVersion);
                writer.Write(sectionSizes.SizeOfCode);
                writer.Write(sectionSizes.SizeOfInitdData);
                writer.Write(sectionSizes.SizeOfUninitdData);
                writer.BaseStream.Position += 4;    // EntryPoint
                writer.Write(sectionSizes.BaseOfCode);
                WriteUInt64(writer, peOptions.ImageBase);
                writer.BaseStream.Position += 8;    // SectionAlignment, FileAlignment
                WriteUInt16(writer, peOptions.MajorOperatingSystemVersion);
                WriteUInt16(writer, peOptions.MinorOperatingSystemVersion);
                WriteUInt16(writer, peOptions.MajorImageVersion);
                WriteUInt16(writer, peOptions.MinorImageVersion);
                WriteUInt16(writer, peOptions.MajorSubsystemVersion);
                WriteUInt16(writer, peOptions.MinorSubsystemVersion);
                WriteUInt32(writer, peOptions.Win32VersionValue);
                writer.Write(sectionSizes.SizeOfImage);
                writer.Write(sectionSizes.SizeOfHeaders);
                checkSumOffset = writer.BaseStream.Position;
                writer.Write(0);    // CheckSum
                WriteUInt16(writer, peOptions.Subsystem ?? GetSubsystem());
                WriteUInt16(writer, peOptions.DllCharacteristics ?? module.DllCharacteristics);
                WriteUInt64(writer, peOptions.SizeOfStackReserve);
                WriteUInt64(writer, peOptions.SizeOfStackCommit);
                WriteUInt64(writer, peOptions.SizeOfHeapReserve);
                WriteUInt64(writer, peOptions.SizeOfHeapCommit);
                WriteUInt32(writer, peOptions.LoaderFlags);
                WriteUInt32(writer, peOptions.NumberOfRvaAndSizes);
            }

            // Update Win32 resources data directory, if we wrote a new one
            if (win32Resources != null)
            {
                writer.BaseStream.Position = dataDirOffset + 2 * 8;
                writer.WriteDataDirectory(win32Resources);
            }

            // Clear the security descriptor directory
            writer.BaseStream.Position = dataDirOffset + 4 * 8;
            writer.WriteDataDirectory(null);

            // Write a new debug directory
            writer.BaseStream.Position = dataDirOffset + 6 * 8;
            writer.WriteDataDirectory(debugDirectory, DebugDirectory.HEADER_SIZE);

            // Write a new Metadata data directory
            writer.BaseStream.Position = dataDirOffset + 14 * 8;
            writer.WriteDataDirectory(imageCor20Header);

            // Update old sections, and add new sections
            writer.BaseStream.Position = sectionsOffset;
            foreach (var section in origSections)
            {
                writer.BaseStream.Position += 0x14;
                writer.Write((uint)section.Chunk.FileOffset);   // PointerToRawData
                writer.BaseStream.Position += 0x10;
            }
            foreach (var section in sections)
            {
                section.WriteHeaderTo(writer, fileAlignment, sectionAlignment, (uint)section.RVA);
            }

            // Write the .NET header
            writer.BaseStream.Position = cor20Offset;
            writer.Write(0x48);     // cb
            WriteUInt16(writer, Options.Cor20HeaderOptions.MajorRuntimeVersion);
            WriteUInt16(writer, Options.Cor20HeaderOptions.MinorRuntimeVersion);
            writer.WriteDataDirectory(metaData);
            uint entryPoint;

            writer.Write((uint)GetComImageFlags(GetEntryPoint(out entryPoint)));
            writer.Write(Options.Cor20HeaderOptions.EntryPoint ?? entryPoint);
            writer.WriteDataDirectory(netResources);
            writer.WriteDataDirectory(strongNameSignature);
            WriteDataDirectory(writer, module.MetaData.ImageCor20Header.CodeManagerTable);
            WriteDataDirectory(writer, module.MetaData.ImageCor20Header.VTableFixups);
            WriteDataDirectory(writer, module.MetaData.ImageCor20Header.ExportAddressTableJumps);
            WriteDataDirectory(writer, module.MetaData.ImageCor20Header.ManagedNativeHeader);

            UpdateVTableFixups(writer);
        }