|
@@ -0,0 +1,221 @@
|
|
|
+package debug_pe
|
|
|
+
|
|
|
+PE_SIGNATURE_OFFSET_INDEX_POS :: 0x3c
|
|
|
+PE_SIGNATURE :: u32le(0x0000_4550) // "PE\x00\x00"
|
|
|
+PE_SIGNATURE_STRING :: "PE\x00\x00"
|
|
|
+
|
|
|
+OPTIONAL_HEADER_MAGIC :: enum u16le {
|
|
|
+ PE32 = 0x010b,
|
|
|
+ PE32_PLUS = 0x020b,
|
|
|
+}
|
|
|
+
|
|
|
+Optional_Header_Base :: struct #packed {
|
|
|
+ magic: OPTIONAL_HEADER_MAGIC,
|
|
|
+ major_linker_version: u8,
|
|
|
+ minor_linker_version: u8,
|
|
|
+ size_of_code: u32le,
|
|
|
+ size_of_initialized_data: u32le,
|
|
|
+ size_of_uninitialized_data: u32le,
|
|
|
+ address_of_entry_point: u32le,
|
|
|
+ base_of_code: u32le,
|
|
|
+}
|
|
|
+
|
|
|
+File_Header :: struct #packed {
|
|
|
+ machine: IMAGE_FILE_MACHINE,
|
|
|
+ number_of_sections: u16le,
|
|
|
+ time_date_stamp: u32le,
|
|
|
+ pointer_to_symbol_table: u32le,
|
|
|
+ number_of_symbols: u32le,
|
|
|
+ size_of_optional_header: u16le,
|
|
|
+ characteristics: IMAGE_FILE_CHARACTERISTICS,
|
|
|
+}
|
|
|
+
|
|
|
+Data_Directory :: struct #packed {
|
|
|
+ virtual_address: u32le,
|
|
|
+ size: u32le,
|
|
|
+}
|
|
|
+
|
|
|
+Optional_Header32 :: struct #packed {
|
|
|
+ using base: Optional_Header_Base,
|
|
|
+ base_of_data: u32le,
|
|
|
+ image_base: u32le,
|
|
|
+ section_alignment: u32le,
|
|
|
+ file_alignment: u32le,
|
|
|
+ major_operating_system_version: u16le,
|
|
|
+ minor_operating_system_version: u16le,
|
|
|
+ major_image_version: u16le,
|
|
|
+ minor_image_version: u16le,
|
|
|
+ major_subsystem_version: u16le,
|
|
|
+ minor_subsystem_version: u16le,
|
|
|
+ win32_version_value: u32le,
|
|
|
+ size_of_image: u32le,
|
|
|
+ size_of_headers: u32le,
|
|
|
+ check_sum: u32le,
|
|
|
+ subsystem: IMAGE_SUBSYSTEM,
|
|
|
+ dll_characteristics: IMAGE_DLLCHARACTERISTICS,
|
|
|
+ size_of_stack_reserve: u32le,
|
|
|
+ size_of_stack_commit: u32le,
|
|
|
+ size_of_heap_reserve: u32le,
|
|
|
+ size_of_heap_commit: u32le,
|
|
|
+ loader_flags: u32le,
|
|
|
+ number_of_rva_and_sizes: u32le,
|
|
|
+ data_directory: [16]Data_Directory,
|
|
|
+}
|
|
|
+
|
|
|
+Optional_Header64 :: struct #packed {
|
|
|
+ using base: Optional_Header_Base,
|
|
|
+ image_base: u64le,
|
|
|
+ section_alignment: u32le,
|
|
|
+ file_alignment: u32le,
|
|
|
+ major_operating_system_version: u16le,
|
|
|
+ minor_operating_system_version: u16le,
|
|
|
+ major_image_version: u16le,
|
|
|
+ minor_image_version: u16le,
|
|
|
+ major_subsystem_version: u16le,
|
|
|
+ minor_subsystem_version: u16le,
|
|
|
+ win32_version_value: u32le,
|
|
|
+ size_of_image: u32le,
|
|
|
+ size_of_headers: u32le,
|
|
|
+ check_sum: u32le,
|
|
|
+ subsystem: IMAGE_SUBSYSTEM,
|
|
|
+ dll_characteristics: IMAGE_DLLCHARACTERISTICS,
|
|
|
+ size_of_stack_reserve: u64le,
|
|
|
+ size_of_stack_commit: u64le,
|
|
|
+ size_of_heap_reserve: u64le,
|
|
|
+ size_of_heap_commit: u64le,
|
|
|
+ loader_flags: u32le,
|
|
|
+ number_of_rva_and_sizes: u32le,
|
|
|
+ data_directory: [16]Data_Directory,
|
|
|
+}
|
|
|
+
|
|
|
+// .debug section
|
|
|
+Debug_Directory_Entry :: struct {
|
|
|
+ characteristics: u32le,
|
|
|
+ time_date_stamp: u32le,
|
|
|
+ major_version: u16le,
|
|
|
+ minor_version: u16le,
|
|
|
+ type: IMAGE_DEBUG_TYPE,
|
|
|
+ size_of_data: u32le,
|
|
|
+ address_of_raw_data: u32le,
|
|
|
+ pointer_to_raw_data: u32le,
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+IMAGE_FILE_MACHINE :: enum u16le {
|
|
|
+ UNKNOWN = 0x0,
|
|
|
+ AM33 = 0x1d3,
|
|
|
+ AMD64 = 0x8664,
|
|
|
+ ARM = 0x1c0,
|
|
|
+ ARMNT = 0x1c4,
|
|
|
+ ARM64 = 0xaa64,
|
|
|
+ EBC = 0xebc,
|
|
|
+ I386 = 0x14c,
|
|
|
+ IA64 = 0x200,
|
|
|
+ LOONGARCH32 = 0x6232,
|
|
|
+ LOONGARCH64 = 0x6264,
|
|
|
+ M32R = 0x9041,
|
|
|
+ MIPS16 = 0x266,
|
|
|
+ MIPSFPU = 0x366,
|
|
|
+ MIPSFPU16 = 0x466,
|
|
|
+ POWERPC = 0x1f0,
|
|
|
+ POWERPCFP = 0x1f1,
|
|
|
+ R4000 = 0x166,
|
|
|
+ SH3 = 0x1a2,
|
|
|
+ SH3DSP = 0x1a3,
|
|
|
+ SH4 = 0x1a6,
|
|
|
+ SH5 = 0x1a8,
|
|
|
+ THUMB = 0x1c2,
|
|
|
+ WCEMIPSV2 = 0x169,
|
|
|
+}
|
|
|
+
|
|
|
+// IMAGE_DIRECTORY_ENTRY constants
|
|
|
+IMAGE_DIRECTORY_ENTRY :: enum u8 {
|
|
|
+ EXPORT = 0,
|
|
|
+ IMPORT = 1,
|
|
|
+ RESOURCE = 2,
|
|
|
+ EXCEPTION = 3,
|
|
|
+ SECURITY = 4,
|
|
|
+ BASERELOC = 5,
|
|
|
+ DEBUG = 6,
|
|
|
+ ARCHITECTURE = 7, // reserved
|
|
|
+ GLOBALPTR = 8,
|
|
|
+ TLS = 9,
|
|
|
+ LOAD_CONFIG = 10,
|
|
|
+ BOUND_IMPORT = 11,
|
|
|
+ IAT = 12,
|
|
|
+ DELAY_IMPORT = 13,
|
|
|
+ COM_DESCRIPTOR = 14, // DLR Runtime headers
|
|
|
+ _RESERVED = 15,
|
|
|
+}
|
|
|
+#assert(len(IMAGE_DIRECTORY_ENTRY) == 16)
|
|
|
+
|
|
|
+
|
|
|
+IMAGE_FILE_CHARACTERISTICS :: distinct bit_set[IMAGE_FILE_CHARACTERISTIC; u16le]
|
|
|
+IMAGE_FILE_CHARACTERISTIC :: enum u16le {
|
|
|
+ RELOCS_STRIPPED = 0,
|
|
|
+ EXECUTABLE_IMAGE = 1,
|
|
|
+ LINE_NUMS_STRIPPED = 2,
|
|
|
+ LOCAL_SYMS_STRIPPED = 3,
|
|
|
+ AGGRESIVE_WS_TRIM = 4,
|
|
|
+ LARGE_ADDRESS_AWARE = 5,
|
|
|
+
|
|
|
+ BYTES_REVERSED_LO = 7,
|
|
|
+ MACHINE_32BIT = 8, // IMAGE_FILE_32BIT_MACHINE originally
|
|
|
+ DEBUG_STRIPPED = 9,
|
|
|
+ REMOVABLE_RUN_FROM_SWAP = 10,
|
|
|
+ NET_RUN_FROM_SWAP = 11,
|
|
|
+ SYSTEM = 12,
|
|
|
+ DLL = 13,
|
|
|
+ UP_SYSTEM_ONLY = 14,
|
|
|
+ BYTES_REVERSED_HI = 15,
|
|
|
+}
|
|
|
+
|
|
|
+IMAGE_SUBSYSTEM :: enum u16le {
|
|
|
+ UNKNOWN = 0,
|
|
|
+ NATIVE = 1,
|
|
|
+ WINDOWS_GUI = 2,
|
|
|
+ WINDOWS_CUI = 3,
|
|
|
+ OS2_CUI = 5,
|
|
|
+ POSIX_CUI = 7,
|
|
|
+ NATIVE_WINDOWS = 8,
|
|
|
+ WINDOWS_CE_GUI = 9,
|
|
|
+ EFI_APPLICATION = 10,
|
|
|
+ EFI_BOOT_SERVICE_DRIVER = 11,
|
|
|
+ EFI_RUNTIME_DRIVER = 12,
|
|
|
+ EFI_ROM = 13,
|
|
|
+ XBOX = 14,
|
|
|
+ WINDOWS_BOOT_APPLICATION = 16,
|
|
|
+}
|
|
|
+
|
|
|
+IMAGE_DLLCHARACTERISTICS :: distinct bit_set[IMAGE_DLLCHARACTERISTIC; u16le]
|
|
|
+IMAGE_DLLCHARACTERISTIC :: enum u16le {
|
|
|
+ HIGH_ENTROPY_VA = 5,
|
|
|
+ DYNAMIC_BASE = 6,
|
|
|
+ FORCE_INTEGRITY = 7,
|
|
|
+ NX_COMPAT = 8,
|
|
|
+ NO_ISOLATION = 9,
|
|
|
+ NO_SEH = 10,
|
|
|
+ NO_BIND = 11,
|
|
|
+ APPCONTAINER = 12,
|
|
|
+ WDM_DRIVER = 13,
|
|
|
+ GUARD_CF = 14,
|
|
|
+ TERMINAL_SERVER_AWARE = 15,
|
|
|
+}
|
|
|
+
|
|
|
+IMAGE_DEBUG_TYPE :: enum u32le {
|
|
|
+ UNKNOWN = 0, // An unknown value that is ignored by all tools.
|
|
|
+ COFF = 1, // The COFF debug information (line numbers, symbol table, and string table). This type of debug information is also pointed to by fields in the file headers.
|
|
|
+ CODEVIEW = 2, // The Visual C++ debug information.
|
|
|
+ FPO = 3, // The frame pointer omission (FPO) information. This information tells the debugger how to interpret nonstandard stack frames, which use the EBP register for a purpose other than as a frame pointer.
|
|
|
+ MISC = 4, // The location of DBG file.
|
|
|
+ EXCEPTION = 5, // A copy of .pdata section.
|
|
|
+ FIXUP = 6, // Reserved.
|
|
|
+ OMAP_TO_SRC = 7, // The mapping from an RVA in image to an RVA in source image.
|
|
|
+ OMAP_FROM_SRC = 8, // The mapping from an RVA in source image to an RVA in image.
|
|
|
+ BORLAND = 9, // Reserved for Borland.
|
|
|
+ RESERVED10 = 10, // Reserved.
|
|
|
+ CLSID = 11, // Reserved.
|
|
|
+ REPRO = 16, // PE determinism or reproducibility.
|
|
|
+ EX_DLLCHARACTERISTICS = 20, // Extended DLL characteristics bits.
|
|
|
+}
|
|
|
+
|