pe.odin 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221
  1. package debug_pe
  2. PE_SIGNATURE_OFFSET_INDEX_POS :: 0x3c
  3. PE_SIGNATURE :: u32le(0x0000_4550) // "PE\x00\x00"
  4. PE_SIGNATURE_STRING :: "PE\x00\x00"
  5. OPTIONAL_HEADER_MAGIC :: enum u16le {
  6. PE32 = 0x010b,
  7. PE32_PLUS = 0x020b,
  8. }
  9. Optional_Header_Base :: struct #packed {
  10. magic: OPTIONAL_HEADER_MAGIC,
  11. major_linker_version: u8,
  12. minor_linker_version: u8,
  13. size_of_code: u32le,
  14. size_of_initialized_data: u32le,
  15. size_of_uninitialized_data: u32le,
  16. address_of_entry_point: u32le,
  17. base_of_code: u32le,
  18. }
  19. File_Header :: struct #packed {
  20. machine: IMAGE_FILE_MACHINE,
  21. number_of_sections: u16le,
  22. time_date_stamp: u32le,
  23. pointer_to_symbol_table: u32le,
  24. number_of_symbols: u32le,
  25. size_of_optional_header: u16le,
  26. characteristics: IMAGE_FILE_CHARACTERISTICS,
  27. }
  28. Data_Directory :: struct #packed {
  29. virtual_address: u32le,
  30. size: u32le,
  31. }
  32. Optional_Header32 :: struct #packed {
  33. using base: Optional_Header_Base,
  34. base_of_data: u32le,
  35. image_base: u32le,
  36. section_alignment: u32le,
  37. file_alignment: u32le,
  38. major_operating_system_version: u16le,
  39. minor_operating_system_version: u16le,
  40. major_image_version: u16le,
  41. minor_image_version: u16le,
  42. major_subsystem_version: u16le,
  43. minor_subsystem_version: u16le,
  44. win32_version_value: u32le,
  45. size_of_image: u32le,
  46. size_of_headers: u32le,
  47. check_sum: u32le,
  48. subsystem: IMAGE_SUBSYSTEM,
  49. dll_characteristics: IMAGE_DLLCHARACTERISTICS,
  50. size_of_stack_reserve: u32le,
  51. size_of_stack_commit: u32le,
  52. size_of_heap_reserve: u32le,
  53. size_of_heap_commit: u32le,
  54. loader_flags: u32le,
  55. number_of_rva_and_sizes: u32le,
  56. data_directory: [16]Data_Directory,
  57. }
  58. Optional_Header64 :: struct #packed {
  59. using base: Optional_Header_Base,
  60. image_base: u64le,
  61. section_alignment: u32le,
  62. file_alignment: u32le,
  63. major_operating_system_version: u16le,
  64. minor_operating_system_version: u16le,
  65. major_image_version: u16le,
  66. minor_image_version: u16le,
  67. major_subsystem_version: u16le,
  68. minor_subsystem_version: u16le,
  69. win32_version_value: u32le,
  70. size_of_image: u32le,
  71. size_of_headers: u32le,
  72. check_sum: u32le,
  73. subsystem: IMAGE_SUBSYSTEM,
  74. dll_characteristics: IMAGE_DLLCHARACTERISTICS,
  75. size_of_stack_reserve: u64le,
  76. size_of_stack_commit: u64le,
  77. size_of_heap_reserve: u64le,
  78. size_of_heap_commit: u64le,
  79. loader_flags: u32le,
  80. number_of_rva_and_sizes: u32le,
  81. data_directory: [16]Data_Directory,
  82. }
  83. // .debug section
  84. Debug_Directory_Entry :: struct {
  85. characteristics: u32le,
  86. time_date_stamp: u32le,
  87. major_version: u16le,
  88. minor_version: u16le,
  89. type: IMAGE_DEBUG_TYPE,
  90. size_of_data: u32le,
  91. address_of_raw_data: u32le,
  92. pointer_to_raw_data: u32le,
  93. }
  94. IMAGE_FILE_MACHINE :: enum u16le {
  95. UNKNOWN = 0x0,
  96. AM33 = 0x1d3,
  97. AMD64 = 0x8664,
  98. ARM = 0x1c0,
  99. ARMNT = 0x1c4,
  100. ARM64 = 0xaa64,
  101. EBC = 0xebc,
  102. I386 = 0x14c,
  103. IA64 = 0x200,
  104. LOONGARCH32 = 0x6232,
  105. LOONGARCH64 = 0x6264,
  106. M32R = 0x9041,
  107. MIPS16 = 0x266,
  108. MIPSFPU = 0x366,
  109. MIPSFPU16 = 0x466,
  110. POWERPC = 0x1f0,
  111. POWERPCFP = 0x1f1,
  112. R4000 = 0x166,
  113. SH3 = 0x1a2,
  114. SH3DSP = 0x1a3,
  115. SH4 = 0x1a6,
  116. SH5 = 0x1a8,
  117. THUMB = 0x1c2,
  118. WCEMIPSV2 = 0x169,
  119. }
  120. // IMAGE_DIRECTORY_ENTRY constants
  121. IMAGE_DIRECTORY_ENTRY :: enum u8 {
  122. EXPORT = 0,
  123. IMPORT = 1,
  124. RESOURCE = 2,
  125. EXCEPTION = 3,
  126. SECURITY = 4,
  127. BASERELOC = 5,
  128. DEBUG = 6,
  129. ARCHITECTURE = 7, // reserved
  130. GLOBALPTR = 8,
  131. TLS = 9,
  132. LOAD_CONFIG = 10,
  133. BOUND_IMPORT = 11,
  134. IAT = 12,
  135. DELAY_IMPORT = 13,
  136. COM_DESCRIPTOR = 14, // DLR Runtime headers
  137. _RESERVED = 15,
  138. }
  139. #assert(len(IMAGE_DIRECTORY_ENTRY) == 16)
  140. IMAGE_FILE_CHARACTERISTICS :: distinct bit_set[IMAGE_FILE_CHARACTERISTIC; u16le]
  141. IMAGE_FILE_CHARACTERISTIC :: enum u16le {
  142. RELOCS_STRIPPED = 0,
  143. EXECUTABLE_IMAGE = 1,
  144. LINE_NUMS_STRIPPED = 2,
  145. LOCAL_SYMS_STRIPPED = 3,
  146. AGGRESIVE_WS_TRIM = 4,
  147. LARGE_ADDRESS_AWARE = 5,
  148. BYTES_REVERSED_LO = 7,
  149. MACHINE_32BIT = 8, // IMAGE_FILE_32BIT_MACHINE originally
  150. DEBUG_STRIPPED = 9,
  151. REMOVABLE_RUN_FROM_SWAP = 10,
  152. NET_RUN_FROM_SWAP = 11,
  153. SYSTEM = 12,
  154. DLL = 13,
  155. UP_SYSTEM_ONLY = 14,
  156. BYTES_REVERSED_HI = 15,
  157. }
  158. IMAGE_SUBSYSTEM :: enum u16le {
  159. UNKNOWN = 0,
  160. NATIVE = 1,
  161. WINDOWS_GUI = 2,
  162. WINDOWS_CUI = 3,
  163. OS2_CUI = 5,
  164. POSIX_CUI = 7,
  165. NATIVE_WINDOWS = 8,
  166. WINDOWS_CE_GUI = 9,
  167. EFI_APPLICATION = 10,
  168. EFI_BOOT_SERVICE_DRIVER = 11,
  169. EFI_RUNTIME_DRIVER = 12,
  170. EFI_ROM = 13,
  171. XBOX = 14,
  172. WINDOWS_BOOT_APPLICATION = 16,
  173. }
  174. IMAGE_DLLCHARACTERISTICS :: distinct bit_set[IMAGE_DLLCHARACTERISTIC; u16le]
  175. IMAGE_DLLCHARACTERISTIC :: enum u16le {
  176. HIGH_ENTROPY_VA = 5,
  177. DYNAMIC_BASE = 6,
  178. FORCE_INTEGRITY = 7,
  179. NX_COMPAT = 8,
  180. NO_ISOLATION = 9,
  181. NO_SEH = 10,
  182. NO_BIND = 11,
  183. APPCONTAINER = 12,
  184. WDM_DRIVER = 13,
  185. GUARD_CF = 14,
  186. TERMINAL_SERVER_AWARE = 15,
  187. }
  188. IMAGE_DEBUG_TYPE :: enum u32le {
  189. UNKNOWN = 0, // An unknown value that is ignored by all tools.
  190. 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.
  191. CODEVIEW = 2, // The Visual C++ debug information.
  192. 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.
  193. MISC = 4, // The location of DBG file.
  194. EXCEPTION = 5, // A copy of .pdata section.
  195. FIXUP = 6, // Reserved.
  196. OMAP_TO_SRC = 7, // The mapping from an RVA in image to an RVA in source image.
  197. OMAP_FROM_SRC = 8, // The mapping from an RVA in source image to an RVA in image.
  198. BORLAND = 9, // Reserved for Borland.
  199. RESERVED10 = 10, // Reserved.
  200. CLSID = 11, // Reserved.
  201. REPRO = 16, // PE determinism or reproducibility.
  202. EX_DLLCHARACTERISTICS = 20, // Extended DLL characteristics bits.
  203. }