void WriteOptionalHeaders() { WriteUInt16((ushort)(!pe64 ? 0x10b : 0x20b)); // Magic WriteUInt16(module.linker_version); WriteUInt32(text.SizeOfRawData); // CodeSize WriteUInt32((reloc != null ? reloc.SizeOfRawData : 0) + (rsrc != null ? rsrc.SizeOfRawData : 0)); // InitializedDataSize WriteUInt32(0); // UninitializedDataSize var startub_stub = text_map.GetRange(TextSegment.StartupStub); WriteUInt32(startub_stub.Length > 0 ? startub_stub.Start : 0); // EntryPointRVA WriteUInt32(text_rva); // BaseOfCode if (!pe64) { WriteUInt32(0); // BaseOfData WriteUInt32((uint)image_base); // ImageBase } else { WriteUInt64(image_base); // ImageBase } WriteUInt32(section_alignment); // SectionAlignment WriteUInt32(file_alignment); // FileAlignment WriteUInt16(4); // OSMajor WriteUInt16(0); // OSMinor WriteUInt16(0); // UserMajor WriteUInt16(0); // UserMinor WriteUInt16(4); // SubSysMajor WriteUInt16(0); // SubSysMinor WriteUInt32(0); // Reserved var last_section = LastSection(); WriteUInt32(last_section.VirtualAddress + Align(last_section.VirtualSize, section_alignment)); // ImageSize WriteUInt32(text.PointerToRawData); // HeaderSize WriteUInt32(0); // Checksum WriteUInt16(GetSubSystem()); // SubSystem WriteUInt16((ushort)module.Characteristics); // DLLFlags const ulong stack_reserve = 0x100000; const ulong stack_commit = 0x1000; const ulong heap_reserve = 0x100000; const ulong heap_commit = 0x1000; if (!pe64) { WriteUInt32((uint)stack_reserve); WriteUInt32((uint)stack_commit); WriteUInt32((uint)heap_reserve); WriteUInt32((uint)heap_commit); } else { WriteUInt64(stack_reserve); WriteUInt64(stack_commit); WriteUInt64(heap_reserve); WriteUInt64(heap_commit); } WriteUInt32(0); // LoaderFlags WriteUInt32(16); // NumberOfDataDir WriteZeroDataDirectory(); // ExportTable WriteDataDirectory(text_map.GetDataDirectory(TextSegment.ImportDirectory)); // ImportTable if (rsrc != null) // ResourceTable { WriteUInt32(rsrc.VirtualAddress); WriteUInt32(rsrc.VirtualSize); } else { WriteZeroDataDirectory(); } WriteZeroDataDirectory(); // ExceptionTable WriteZeroDataDirectory(); // CertificateTable WriteUInt32(reloc != null ? reloc.VirtualAddress : 0); // BaseRelocationTable WriteUInt32(reloc != null ? reloc.VirtualSize : 0); if (text_map.GetLength(TextSegment.DebugDirectory) > 0) { WriteUInt32(text_map.GetRVA(TextSegment.DebugDirectory)); WriteUInt32((uint)(debug_header.Entries.Length * ImageDebugDirectory.Size)); } else { WriteZeroDataDirectory(); } WriteZeroDataDirectory(); // Copyright WriteZeroDataDirectory(); // GlobalPtr WriteZeroDataDirectory(); // TLSTable WriteZeroDataDirectory(); // LoadConfigTable WriteZeroDataDirectory(); // BoundImport WriteDataDirectory(text_map.GetDataDirectory(TextSegment.ImportAddressTable)); // IAT WriteZeroDataDirectory(); // DelayImportDesc WriteDataDirectory(text_map.GetDataDirectory(TextSegment.CLIHeader)); // CLIHeader WriteZeroDataDirectory(); // Reserved }
private void WriteOptionalHeaders() { base.WriteUInt16((ushort)((!pe64) ? 267 : 523)); base.WriteUInt16(module.linker_version); base.WriteUInt32(text.SizeOfRawData); base.WriteUInt32(((reloc != null) ? reloc.SizeOfRawData : 0) + ((rsrc != null) ? rsrc.SizeOfRawData : 0)); base.WriteUInt32(0u); Range range = text_map.GetRange(TextSegment.StartupStub); base.WriteUInt32((range.Length != 0) ? range.Start : 0); base.WriteUInt32(8192u); if (!pe64) { base.WriteUInt32(0u); base.WriteUInt32(4194304u); } else { base.WriteUInt64(4194304uL); } base.WriteUInt32(8192u); base.WriteUInt32(512u); base.WriteUInt16(4); base.WriteUInt16(0); base.WriteUInt16(0); base.WriteUInt16(0); base.WriteUInt16(4); base.WriteUInt16(0); base.WriteUInt32(0u); Section section = LastSection(); base.WriteUInt32(section.VirtualAddress + Align(section.VirtualSize, 8192u)); base.WriteUInt32(text.PointerToRawData); base.WriteUInt32(0u); base.WriteUInt16(GetSubSystem()); base.WriteUInt16((ushort)module.Characteristics); if (!pe64) { base.WriteUInt32(1048576u); base.WriteUInt32(4096u); base.WriteUInt32(1048576u); base.WriteUInt32(4096u); } else { base.WriteUInt64(1048576uL); base.WriteUInt64(4096uL); base.WriteUInt64(1048576uL); base.WriteUInt64(4096uL); } base.WriteUInt32(0u); base.WriteUInt32(16u); WriteZeroDataDirectory(); base.WriteDataDirectory(text_map.GetDataDirectory(TextSegment.ImportDirectory)); if (rsrc != null) { base.WriteUInt32(rsrc.VirtualAddress); base.WriteUInt32(rsrc.VirtualSize); } else { WriteZeroDataDirectory(); } WriteZeroDataDirectory(); WriteZeroDataDirectory(); base.WriteUInt32((reloc != null) ? reloc.VirtualAddress : 0); base.WriteUInt32((reloc != null) ? reloc.VirtualSize : 0); if (text_map.GetLength(TextSegment.DebugDirectory) > 0) { base.WriteUInt32(text_map.GetRVA(TextSegment.DebugDirectory)); base.WriteUInt32((uint)(debug_header.Entries.Length * 28)); } else { WriteZeroDataDirectory(); } WriteZeroDataDirectory(); WriteZeroDataDirectory(); WriteZeroDataDirectory(); WriteZeroDataDirectory(); WriteZeroDataDirectory(); base.WriteDataDirectory(text_map.GetDataDirectory(TextSegment.ImportAddressTable)); WriteZeroDataDirectory(); base.WriteDataDirectory(text_map.GetDataDirectory(TextSegment.CLIHeader)); WriteZeroDataDirectory(); }