protected override void WriteHeaders(FinalProgram<byte> final) { Writer.Write(DosHeader); WritePeHeader(final); WriteOptionalHeader(final); foreach (var section in final.Sections) WriteSectionHeader(section); }
private void WritePeHeader(FinalProgram<byte> final) { Writer.Write(0x00004550); //PE\0\0 switch (Settings.ISA) { case ISA.x86: if(!Settings.Is64Bit) Writer.Write((ushort)0x14c); else Writer.Write((ushort)0x8664); break; case ISA.ARM7: Writer.Write((ushort)0x1c4); break; } Writer.Write((ushort)final.Sections.Count); Writer.Write((uint)DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1)).TotalSeconds); Writer.Write(0); Writer.Write(0); Writer.Write((ushort)0xF0); Writer.Write((ushort)(CoffCharacteristics.Executable | CoffCharacteristics.LargeAddress)); }
private void WriteOptionalHeader(FinalProgram<byte> final) { if (Settings.Is64Bit) Writer.Write((ushort)0x20b); else Writer.Write((ushort)0x10b); // linker version Writer.Write((byte)14); Writer.Write((byte)0); // size of code (uint32) Writer.Write(SumSection(final.Sections, ESectionFlags.Code)); // size of init (uint32) Writer.Write(SumSection(final.Sections, ESectionFlags.InitializedData)); // size of uninit (uint32) Writer.Write(SumSection(final.Sections, ~ESectionFlags.InitializedData)); // relative entry point (uint32) Writer.Write((uint)final.Sections[0].VirtualAddress); // relative base of code (uint32) Writer.Write((uint)final.Sections[0].VirtualAddress); // image base (arch) if (Settings.Is64Bit) Writer.Write(final.VirtualBaseAddress); else Writer.Write((uint)final.VirtualBaseAddress); // section alignment (uint32) virtual chunk size Writer.Write((uint)final.VirtualAlignment); // file alignment (uint32) physical chunk size Writer.Write((uint)final.PhysicalAlignment); // os version (uint32) major / minor Writer.Write(0x00000006); // image version (uint32) major / minor Writer.Write(0x00000000); // subsystem (uint32) major / minor Writer.Write(0x00000006); // win32 version (uint32) Writer.Write(0); // size of image (uint32) ? Writer.Write(SumSection(final.Sections, ESectionFlags.Read, true) + (uint)final.VirtualAlignment); // size of headers (uint32) Writer.Write((uint)final.PhysicalBaseAddress); // checksum (uint32) 0? Writer.Write(0); // subsystem (short) 3 for console Writer.Write((ushort)3); // flags (short) Writer.Write((ushort)0x8160); // stack reserve (arch) ? ArchWrite(0x100000); // stack commit (arch) ? ArchWrite(0x1000); // heap reserve (arch) ? ArchWrite(0x100000); // heap commit (arch) ? ArchWrite(0x1000); // loader flags (uint32) 0 Writer.Write(0); // number of dirs (uint32) Writer.Write(0x10); // n dirs? uint32 rva and uint32 size // Export Directory Writer.Write(new byte[8]); // Import Descriptor Directory Writer.Write((uint)final.ImportDescriptorTableAddress); Writer.Write((uint)final.ImportDescriptorTableSize); // Resource Directory /*Writer.Write((uint)final.ResourcesAddress); Writer.Write((uint)final.ResourcesSize);*/ Writer.Write(new byte[8]); // Exception Directory Writer.Write(new byte[8]); // Certificates directory Writer.Write(new byte[8]); // Base relocation Writer.Write(new byte[8]); // Debug Writer.Write(new byte[8]); // Architecture Writer.Write(new byte[8]); // Global Pointer Writer.Write(new byte[8]); // Thread Local Storage Writer.Write(new byte[8]); // Load Configuration Writer.Write(new byte[8]); // Bound Import Writer.Write(new byte[8]); // Import Address Writer.Write((uint)final.ImportAddressTableAddress); Writer.Write((uint)final.ImportAddressTableSize); // Delay Import Writer.Write(new byte[8]); // COM descriptor Writer.Write(new byte[8]); // Reserved Writer.Write(new byte[8]); }