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
}