From 06e93cecf830d40df65608f394e0ec68dcf27470 Mon Sep 17 00:00:00 2001 From: Schamper <1254028+Schamper@users.noreply.github.com> Date: Fri, 11 Jul 2025 15:35:15 +0200 Subject: [PATCH 01/10] Initial commit --- dissect/executable/pe/__init__.py | 5 + dissect/executable/pe/c_pe.py | 2231 ++++++++++++ dissect/executable/pe/c_pe.pyi | 2997 +++++++++++++++++ dissect/executable/pe/directory/__init__.py | 41 + dissect/executable/pe/directory/base.py | 18 + dissect/executable/pe/directory/basereloc.py | 64 + .../executable/pe/directory/bound_import.py | 114 + .../executable/pe/directory/com_descriptor.py | 83 + dissect/executable/pe/directory/debug.py | 244 ++ .../executable/pe/directory/delay_import.py | 176 + dissect/executable/pe/directory/exception.py | 76 + dissect/executable/pe/directory/export.py | 128 + dissect/executable/pe/directory/iat.py | 33 + dissect/executable/pe/directory/imports.py | 151 + .../executable/pe/directory/load_config.py | 56 + dissect/executable/pe/directory/resource.py | 589 ++++ dissect/executable/pe/directory/security.py | 76 + dissect/executable/pe/directory/tls.py | 46 + dissect/executable/pe/locale_id.py | 609 ++++ dissect/executable/pe/pe.py | 448 +++ pyproject.toml | 1 + tests/_data/pe/16/DPMIRES.EXE | Bin 0 -> 5241 bytes tests/_data/pe/32/Dummy.dll | Bin 0 -> 2048 bytes ...indows.SoftwareLogo.Binscope.resources.dll | Bin 0 -> 3584 bytes tests/_data/pe/32/NetDbgTLLoc.dll | Bin 0 -> 20480 bytes tests/_data/pe/32/OLEACCHOOKS.DLL | Bin 0 -> 10240 bytes tests/_data/pe/32/PUNZIP.EXE | Bin 0 -> 143360 bytes tests/_data/pe/32/TpmCertResources.dll | Bin 0 -> 3584 bytes tests/_data/pe/32/UWPEnum.dll | Bin 0 -> 8080 bytes tests/_data/pe/32/aborttest.exe | Bin 0 -> 6144 bytes tests/_data/pe/32/mingwm10.dll | Bin 0 -> 10254 bytes tests/_data/pe/64/comres.dll | Bin 0 -> 10752 bytes tests/_data/pe/64/test.exe | Bin 0 -> 31336 bytes tests/_utils.py | 2 + tests/elf/test_section.py | 6 +- tests/elf/test_segment_table.py | 4 +- tests/pe/__init__.py | 0 tests/pe/directory/__init__.py | 0 tests/pe/directory/test_basereloc.py | 19 + tests/pe/directory/test_bound_import.py | 25 + tests/pe/directory/test_com_descriptor.py | 17 + tests/pe/directory/test_debug.py | 78 + tests/pe/directory/test_delay_import.py | 29 + tests/pe/directory/test_exception.py | 18 + tests/pe/directory/test_export.py | 26 + tests/pe/directory/test_iat.py | 40 + tests/pe/directory/test_import.py | 25 + tests/pe/directory/test_load_config.py | 19 + tests/pe/directory/test_resource.py | 86 + tests/pe/directory/test_security.py | 20 + tests/pe/directory/test_tls.py | 15 + tests/pe/test_pe.py | 56 + 52 files changed, 8669 insertions(+), 2 deletions(-) create mode 100755 dissect/executable/pe/c_pe.py create mode 100644 dissect/executable/pe/c_pe.pyi create mode 100644 dissect/executable/pe/directory/__init__.py create mode 100644 dissect/executable/pe/directory/base.py create mode 100644 dissect/executable/pe/directory/basereloc.py create mode 100644 dissect/executable/pe/directory/bound_import.py create mode 100644 dissect/executable/pe/directory/com_descriptor.py create mode 100644 dissect/executable/pe/directory/debug.py create mode 100644 dissect/executable/pe/directory/delay_import.py create mode 100644 dissect/executable/pe/directory/exception.py create mode 100644 dissect/executable/pe/directory/export.py create mode 100644 dissect/executable/pe/directory/iat.py create mode 100644 dissect/executable/pe/directory/imports.py create mode 100644 dissect/executable/pe/directory/load_config.py create mode 100644 dissect/executable/pe/directory/resource.py create mode 100644 dissect/executable/pe/directory/security.py create mode 100644 dissect/executable/pe/directory/tls.py create mode 100644 dissect/executable/pe/locale_id.py create mode 100644 dissect/executable/pe/pe.py create mode 100644 tests/_data/pe/16/DPMIRES.EXE create mode 100644 tests/_data/pe/32/Dummy.dll create mode 100644 tests/_data/pe/32/Microsoft.Windows.SoftwareLogo.Binscope.resources.dll create mode 100644 tests/_data/pe/32/NetDbgTLLoc.dll create mode 100644 tests/_data/pe/32/OLEACCHOOKS.DLL create mode 100644 tests/_data/pe/32/PUNZIP.EXE create mode 100644 tests/_data/pe/32/TpmCertResources.dll create mode 100644 tests/_data/pe/32/UWPEnum.dll create mode 100644 tests/_data/pe/32/aborttest.exe create mode 100644 tests/_data/pe/32/mingwm10.dll create mode 100644 tests/_data/pe/64/comres.dll create mode 100644 tests/_data/pe/64/test.exe create mode 100644 tests/pe/__init__.py create mode 100644 tests/pe/directory/__init__.py create mode 100644 tests/pe/directory/test_basereloc.py create mode 100644 tests/pe/directory/test_bound_import.py create mode 100644 tests/pe/directory/test_com_descriptor.py create mode 100644 tests/pe/directory/test_debug.py create mode 100644 tests/pe/directory/test_delay_import.py create mode 100644 tests/pe/directory/test_exception.py create mode 100644 tests/pe/directory/test_export.py create mode 100644 tests/pe/directory/test_iat.py create mode 100644 tests/pe/directory/test_import.py create mode 100644 tests/pe/directory/test_load_config.py create mode 100644 tests/pe/directory/test_resource.py create mode 100644 tests/pe/directory/test_security.py create mode 100644 tests/pe/directory/test_tls.py create mode 100644 tests/pe/test_pe.py diff --git a/dissect/executable/pe/__init__.py b/dissect/executable/pe/__init__.py index e69de29..1c31270 100644 --- a/dissect/executable/pe/__init__.py +++ b/dissect/executable/pe/__init__.py @@ -0,0 +1,5 @@ +from dissect.executable.pe.pe import PE + +__all__ = [ + "PE", +] diff --git a/dissect/executable/pe/c_pe.py b/dissect/executable/pe/c_pe.py new file mode 100755 index 0000000..00d1d07 --- /dev/null +++ b/dissect/executable/pe/c_pe.py @@ -0,0 +1,2231 @@ +# References: +# - ntimage.h +# - winnt.h +from __future__ import annotations + +from dissect.cstruct import cstruct + +c_pe_def = """ +typedef BYTE BOOLEAN; + +// +// Image Format +// + +#define IMAGE_DOS_SIGNATURE 0x5A4D // MZ +#define IMAGE_OS2_SIGNATURE 0x454E // NE +#define IMAGE_OS2_SIGNATURE_LE 0x454C // LE +#define IMAGE_VXD_SIGNATURE 0x454C // LE +#define IMAGE_NT_SIGNATURE 0x00004550 // PE00 + +typedef struct _IMAGE_DOS_HEADER { // DOS .EXE header + USHORT e_magic; // Magic number + USHORT e_cblp; // Bytes on last page of file + USHORT e_cp; // Pages in file + USHORT e_crlc; // Relocations + USHORT e_cparhdr; // Size of header in paragraphs + USHORT e_minalloc; // Minimum extra paragraphs needed + USHORT e_maxalloc; // Maximum extra paragraphs needed + USHORT e_ss; // Initial (relative) SS value + USHORT e_sp; // Initial SP value + USHORT e_csum; // Checksum + USHORT e_ip; // Initial IP value + USHORT e_cs; // Initial (relative) CS value + USHORT e_lfarlc; // File address of relocation table + USHORT e_ovno; // Overlay number + USHORT e_res[4]; // Reserved words + USHORT e_oemid; // OEM identifier (for e_oeminfo) + USHORT e_oeminfo; // OEM information; e_oemid specific + USHORT e_res2[10]; // Reserved words + LONG e_lfanew; // File address of new exe header +} IMAGE_DOS_HEADER; + +typedef struct _IMAGE_OS2_HEADER { // OS/2 .EXE header + USHORT ne_magic; // Magic number + CHAR ne_ver; // Version number + CHAR ne_rev; // Revision number + USHORT ne_enttab; // Offset of Entry Table + USHORT ne_cbenttab; // Number of bytes in Entry Table + LONG ne_crc; // Checksum of whole file + USHORT ne_flags; // Flag word + USHORT ne_autodata; // Automatic data segment number + USHORT ne_heap; // Initial heap allocation + USHORT ne_stack; // Initial stack allocation + LONG ne_csip; // Initial CS:IP setting + LONG ne_sssp; // Initial SS:SP setting + USHORT ne_cseg; // Count of file segments + USHORT ne_cmod; // Entries in Module Reference Table + USHORT ne_cbnrestab; // Size of non-resident name table + USHORT ne_segtab; // Offset of Segment Table + USHORT ne_rsrctab; // Offset of Resource Table + USHORT ne_restab; // Offset of resident name table + USHORT ne_modtab; // Offset of Module Reference Table + USHORT ne_imptab; // Offset of Imported Names Table + LONG ne_nrestab; // Offset of Non-resident Names Table + USHORT ne_cmovent; // Count of movable entries + USHORT ne_align; // Segment alignment shift count + USHORT ne_cres; // Count of resource segments + UCHAR ne_exetyp; // Target Operating system + UCHAR ne_flagsothers; // Other .EXE flags + USHORT ne_pretthunks; // offset to return thunks + USHORT ne_psegrefbytes; // offset to segment ref. bytes + USHORT ne_swaparea; // Minimum code swap area size + USHORT ne_expver; // Expected Windows version number +} IMAGE_OS2_HEADER; + +typedef struct _IMAGE_VXD_HEADER { // Windows VXD header + USHORT e32_magic; // Magic number + UCHAR e32_border; // The byte ordering for the VXD + UCHAR e32_worder; // The word ordering for the VXD + ULONG e32_level; // The EXE format level for now = 0 + USHORT e32_cpu; // The CPU type + USHORT e32_os; // The OS type + ULONG e32_ver; // Module version + ULONG e32_mflags; // Module flags + ULONG e32_mpages; // Module # pages + ULONG e32_startobj; // Object # for instruction pointer + ULONG e32_eip; // Extended instruction pointer + ULONG e32_stackobj; // Object # for stack pointer + ULONG e32_esp; // Extended stack pointer + ULONG e32_pagesize; // VXD page size + ULONG e32_lastpagesize; // Last page size in VXD + ULONG e32_fixupsize; // Fixup section size + ULONG e32_fixupsum; // Fixup section checksum + ULONG e32_ldrsize; // Loader section size + ULONG e32_ldrsum; // Loader section checksum + ULONG e32_objtab; // Object table offset + ULONG e32_objcnt; // Number of objects in module + ULONG e32_objmap; // Object page map offset + ULONG e32_itermap; // Object iterated data map offset + ULONG e32_rsrctab; // Offset of Resource Table + ULONG e32_rsrccnt; // Number of resource entries + ULONG e32_restab; // Offset of resident name table + ULONG e32_enttab; // Offset of Entry Table + ULONG e32_dirtab; // Offset of Module Directive Table + ULONG e32_dircnt; // Number of module directives + ULONG e32_fpagetab; // Offset of Fixup Page Table + ULONG e32_frectab; // Offset of Fixup Record Table + ULONG e32_impmod; // Offset of Import Module Name Table + ULONG e32_impmodcnt; // Number of entries in Import Module Name Table + ULONG e32_impproc; // Offset of Import Procedure Name Table + ULONG e32_pagesum; // Offset of Per-Page Checksum Table + ULONG e32_datapage; // Offset of Enumerated Data Pages + ULONG e32_preload; // Number of preload pages + ULONG e32_nrestab; // Offset of Non-resident Names Table + ULONG e32_cbnrestab; // Size of Non-resident Name Table + ULONG e32_nressum; // Non-resident Name Table Checksum + ULONG e32_autodata; // Object # for automatic data object + ULONG e32_debuginfo; // Offset of the debugging information + ULONG e32_debuglen; // The length of the debugging info. in bytes + ULONG e32_instpreload; // Number of instance pages in preload section of VXD file + ULONG e32_instdemand; // Number of instance pages in demand load section of VXD file + ULONG e32_heapsize; // Size of heap - for 16-bit apps + UCHAR e32_res3[12]; // Reserved words + ULONG e32_winresoff; + ULONG e32_winreslen; + USHORT e32_devid; // Device ID for VxD + USHORT e32_ddkver; // DDK version for VxD +} IMAGE_VXD_HEADER; + +// +// File header format. +// + +flag IMAGE_FILE : USHORT { + RELOCS_STRIPPED = 0x0001, // Relocation info stripped from file. + EXECUTABLE_IMAGE = 0x0002, // File is executable (i.e. no unresolved externel references). + LINE_NUMS_STRIPPED = 0x0004, // Line nunbers stripped from file. + LOCAL_SYMS_STRIPPED = 0x0008, // Local symbols stripped from file. + AGGRESSIVE_WS_TRIM = 0x0010, // Agressively trim working set + LARGE_ADDRESS_AWARE = 0x0020, // App can handle >2gb addresses + BYTES_REVERSED_LO = 0x0080, // Bytes of machine word are reversed. + 32BIT_MACHINE = 0x0100, // 32 bit word machine. + DEBUG_STRIPPED = 0x0200, // Debugging info stripped from file in .DBG file + REMOVABLE_RUN_FROM_SWAP = 0x0400, // If Image is on removable media, copy and run from the swap file. + NET_RUN_FROM_SWAP = 0x0800, // If Image is on Net, copy and run from the swap file. + SYSTEM = 0x1000, // System File. + DLL = 0x2000, // File is a DLL. + UP_SYSTEM_ONLY = 0x4000, // File should only be run on a UP machine + BYTES_REVERSED_HI = 0x8000, // Bytes of machine word are reversed. +}; + +enum IMAGE_FILE_MACHINE : USHORT { + UNKNOWN = 0, + TARGET_HOST = 0x0001, // Useful for indicating we want to interact with the host and not a WoW guest. + I386 = 0x014c, // Intel 386. + R3000 = 0x0162, // MIPS little-endian, 0x160 big-endian + R4000 = 0x0166, // MIPS little-endian + R10000 = 0x0168, // MIPS little-endian + WCEMIPSV2 = 0x0169, // MIPS little-endian WCE v2 + ALPHA = 0x0184, // Alpha_AXP + SH3 = 0x01a2, // SH3 little-endian + SH3DSP = 0x01a3, + SH3E = 0x01a4, // SH3E little-endian + SH4 = 0x01a6, // SH4 little-endian + SH5 = 0x01a8, // SH5 + ARM = 0x01c0, // ARM Little-Endian + THUMB = 0x01c2, // ARM Thumb/Thumb-2 Little-Endian + ARMNT = 0x01c4, // ARM Thumb-2 Little-Endian + AM33 = 0x01d3, + POWERPC = 0x01F0, // IBM PowerPC Little-Endian + POWERPCFP = 0x01f1, + IA64 = 0x0200, // Intel 64 + MIPS16 = 0x0266, // MIPS + ALPHA64 = 0x0284, // ALPHA64 + MIPSFPU = 0x0366, // MIPS + MIPSFPU16 = 0x0466, // MIPS + AXP64 = 0x0284, // IMAGE_FILE_MACHINE_ALPHA64 + TRICORE = 0x0520, // Infineon + CEF = 0x0CEF, + EBC = 0x0EBC, // EFI Byte Code + CHPE_X86 = 0x3A64, + RISCV32 = 0x5032, + RISCV64 = 0x5064, + RISCV128 = 0x5128, + AMD64 = 0x8664, // AMD64 (K8) + M32R = 0x9041, // M32R little-endian + ARM64 = 0xAA64, // ARM64 Little-Endian + CEE = 0xC0EE, +}; + +typedef struct _IMAGE_FILE_HEADER { + IMAGE_FILE_MACHINE Machine; + USHORT NumberOfSections; + ULONG TimeDateStamp; + ULONG PointerToSymbolTable; + ULONG NumberOfSymbols; + USHORT SizeOfOptionalHeader; + IMAGE_FILE Characteristics; +} IMAGE_FILE_HEADER; + +// +// Directory format. +// + +typedef struct _IMAGE_DATA_DIRECTORY { + ULONG VirtualAddress; + ULONG Size; +} IMAGE_DATA_DIRECTORY; + +#define IMAGE_NUMBEROF_DIRECTORY_ENTRIES 16 + +// +// Optional header format. +// + +// Subsystem Values + +enum IMAGE_SUBSYSTEM : USHORT { + UNKNOWN = 0, // Unknown subsystem. + NATIVE = 1, // Image doesn't require a subsystem. + WINDOWS_GUI = 2, // Image runs in the Windows GUI subsystem. + WINDOWS_CUI = 3, // Image runs in the Windows character subsystem. + OS2_CUI = 5, // image runs in the OS/2 character subsystem. + POSIX_CUI = 7, // image runs in the Posix character subsystem. + NATIVE_WINDOWS = 8, // image is a native Win9x driver. + WINDOWS_CE_GUI = 9, // Image runs in the Windows CE subsystem. + EFI_APPLICATION = 10, + EFI_BOOT_SERVICE_DRIVER = 11, + EFI_RUNTIME_DRIVER = 12, + EFI_ROM = 13, + XBOX = 14, + WINDOWS_BOOT_APPLICATION = 16, + XBOX_CODE_CATALOG = 17, +}; + +// DllCharacteristics Entries + +enum IMAGE_DLLCHARACTERISTICS : USHORT { + HIGH_ENTROPY_VA = 0x0020, // Image can handle a high entropy 64-bit virtual address space. + DYNAMIC_BASE = 0x0040, // DLL can move. + FORCE_INTEGRITY = 0x0080, // Code Integrity Image + NX_COMPAT = 0x0100, // Image is NX compatible + NO_ISOLATION = 0x0200, // Image understands isolation and doesn't want it + NO_SEH = 0x0400, // Image does not use SEH. No SE handler may reside in this image + NO_BIND = 0x0800, // Do not bind this image. + APPCONTAINER = 0x1000, // Image should execute in an AppContainer + WDM_DRIVER = 0x2000, // Driver uses WDM model + GUARD_CF = 0x4000, // Image supports Control Flow Guard. + TERMINAL_SERVER_AWARE = 0x8000, +}; + +typedef struct _IMAGE_OPTIONAL_HEADER { + // + // Standard fields. + // + + USHORT Magic; + UCHAR MajorLinkerVersion; + UCHAR MinorLinkerVersion; + ULONG SizeOfCode; + ULONG SizeOfInitializedData; + ULONG SizeOfUninitializedData; + ULONG AddressOfEntryPoint; + ULONG BaseOfCode; + ULONG BaseOfData; + + // + // NT additional fields. + // + + ULONG ImageBase; + ULONG SectionAlignment; + ULONG FileAlignment; + USHORT MajorOperatingSystemVersion; + USHORT MinorOperatingSystemVersion; + USHORT MajorImageVersion; + USHORT MinorImageVersion; + USHORT MajorSubsystemVersion; + USHORT MinorSubsystemVersion; + ULONG Win32VersionValue; + ULONG SizeOfImage; + ULONG SizeOfHeaders; + ULONG CheckSum; + IMAGE_SUBSYSTEM Subsystem; + IMAGE_DLLCHARACTERISTICS DllCharacteristics; + ULONG SizeOfStackReserve; + ULONG SizeOfStackCommit; + ULONG SizeOfHeapReserve; + ULONG SizeOfHeapCommit; + ULONG LoaderFlags; + ULONG NumberOfRvaAndSizes; + IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES]; +} IMAGE_OPTIONAL_HEADER32; + +typedef struct _IMAGE_OPTIONAL_HEADER64 { + USHORT Magic; + UCHAR MajorLinkerVersion; + UCHAR MinorLinkerVersion; + ULONG SizeOfCode; + ULONG SizeOfInitializedData; + ULONG SizeOfUninitializedData; + ULONG AddressOfEntryPoint; + ULONG BaseOfCode; + ULONGLONG ImageBase; + ULONG SectionAlignment; + ULONG FileAlignment; + USHORT MajorOperatingSystemVersion; + USHORT MinorOperatingSystemVersion; + USHORT MajorImageVersion; + USHORT MinorImageVersion; + USHORT MajorSubsystemVersion; + USHORT MinorSubsystemVersion; + ULONG Win32VersionValue; + ULONG SizeOfImage; + ULONG SizeOfHeaders; + ULONG CheckSum; + IMAGE_SUBSYSTEM Subsystem; + IMAGE_DLLCHARACTERISTICS DllCharacteristics; + ULONGLONG SizeOfStackReserve; + ULONGLONG SizeOfStackCommit; + ULONGLONG SizeOfHeapReserve; + ULONGLONG SizeOfHeapCommit; + ULONG LoaderFlags; + ULONG NumberOfRvaAndSizes; + IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES]; +} IMAGE_OPTIONAL_HEADER64; + +#define IMAGE_NT_OPTIONAL_HDR32_MAGIC 0x10b +#define IMAGE_NT_OPTIONAL_HDR64_MAGIC 0x20b +#define IMAGE_ROM_OPTIONAL_HDR_MAGIC 0x107 + +typedef struct _IMAGE_NT_HEADERS64 { + ULONG Signature; + IMAGE_FILE_HEADER FileHeader; + IMAGE_OPTIONAL_HEADER64 OptionalHeader; +} IMAGE_NT_HEADERS64; + +typedef struct _IMAGE_NT_HEADERS { + ULONG Signature; + IMAGE_FILE_HEADER FileHeader; + IMAGE_OPTIONAL_HEADER32 OptionalHeader; +} IMAGE_NT_HEADERS32; + +// Directory Entries + +enum IMAGE_DIRECTORY_ENTRY { + EXPORT = 0, // Export Directory + IMPORT = 1, // Import Directory + RESOURCE = 2, // Resource Directory + EXCEPTION = 3, // Exception Directory + SECURITY = 4, // Security Directory + BASERELOC = 5, // Base Relocation Table + DEBUG = 6, // Debug Directory + COPYRIGHT = 7, // (X86 usage) + ARCHITECTURE = 7, // Architecture Specific Data + GLOBALPTR = 8, // RVA of GP + TLS = 9, // TLS Directory + LOAD_CONFIG = 10, // Load Configuration Directory + BOUND_IMPORT = 11, // Bound Import Directory in headers + IAT = 12, // Import Address Table + DELAY_IMPORT = 13, // Delay Load Import Descriptors + COM_DESCRIPTOR = 14, // COM Runtime descriptor +}; + +// +// Section header format. +// + +flag IMAGE_SCN : ULONG { + TYPE_REG = 0x00000000, // Reserved. + TYPE_DSECT = 0x00000001, // Reserved. + TYPE_NOLOAD = 0x00000002, // Reserved. + TYPE_GROUP = 0x00000004, // Reserved. + TYPE_NO_PAD = 0x00000008, // Reserved. + TYPE_COPY = 0x00000010, // Reserved. + + CNT_CODE = 0x00000020, // Section contains code. + CNT_INITIALIZED_DATA = 0x00000040, // Section contains initialized data. + CNT_UNINITIALIZED_DATA = 0x00000080, // Section contains uninitialized data. + + LNK_OTHER = 0x00000100, // Reserved. + LNK_INFO = 0x00000200, // Section contains comments or some other type of information. + TYPE_OVER = 0x00000400, // Reserved. + LNK_REMOVE = 0x00000800, // Section contents will not become part of image. + LNK_COMDAT = 0x00001000, // Section contents comdat. +// // = 0x00002000, // Reserved. + NO_DEFER_SPEC_EXC = 0x00004000, // Reset speculative exceptions handling bits in the TLB entries for this section. + GPREL = 0x00008000, // Section content can be accessed relative to GP + MEM_FARDATA = 0x00008000, +// MEM_SYSHEAP = 0x00010000, // Obsolete + MEM_PURGEABLE = 0x00020000, + MEM_16BIT = 0x00020000, + MEM_LOCKED = 0x00040000, + MEM_PRELOAD = 0x00080000, + + ALIGN_1BYTES = 0x00100000, + ALIGN_2BYTES = 0x00200000, + ALIGN_4BYTES = 0x00300000, + ALIGN_8BYTES = 0x00400000, + ALIGN_16BYTES = 0x00500000, // Default alignment if no others are specified. + ALIGN_32BYTES = 0x00600000, + ALIGN_64BYTES = 0x00700000, + ALIGN_128BYTES = 0x00800000, + ALIGN_256BYTES = 0x00900000, + ALIGN_512BYTES = 0x00A00000, + ALIGN_1024BYTES = 0x00B00000, + ALIGN_2048BYTES = 0x00C00000, + ALIGN_4096BYTES = 0x00D00000, + ALIGN_8192BYTES = 0x00E00000, +// // Unused = 0x00F00000, + ALIGN_MASK = 0x00F00000, + + LNK_NRELOC_OVFL = 0x01000000, // Section contains extended relocations. + MEM_DISCARDABLE = 0x02000000, // Section can be discarded. + MEM_NOT_CACHED = 0x04000000, // Section is not cachable. + MEM_NOT_PAGED = 0x08000000, // Section is not pageable. + MEM_SHARED = 0x10000000, // Section is shareable. + MEM_EXECUTE = 0x20000000, // Section is executable. + MEM_READ = 0x40000000, // Section is readable. + MEM_WRITE = 0x80000000, // Section is writeable. +}; + +#define IMAGE_SIZEOF_SHORT_NAME 8 + +typedef struct _IMAGE_SECTION_HEADER { + CHAR Name[IMAGE_SIZEOF_SHORT_NAME]; + union { + ULONG PhysicalAddress; + ULONG VirtualSize; + } Misc; + ULONG VirtualAddress; + ULONG SizeOfRawData; + ULONG PointerToRawData; + ULONG PointerToRelocations; + ULONG PointerToLinenumbers; + USHORT NumberOfRelocations; + USHORT NumberOfLinenumbers; + IMAGE_SCN Characteristics; +} IMAGE_SECTION_HEADER; + +// +// Symbol format. +// + + + + +// +// Based relocation format. +// + +// +// Based relocation types. +// + +enum IMAGE_REL_BASED { + ABSOLUTE = 0, // The base relocation is skipped. This type can be used to pad a block. + HIGH = 1, // The base relocation adds the high 16 bits of the difference to the 16-bit field at offset. The 16-bit field represents the high value of a 32-bit word. + LOW = 2, // The base relocation adds the low 16 bits of the difference to the 16-bit field at offset. The 16-bit field represents the low half of a 32-bit word. + HIGHLOW = 3, // The base relocation applies all 32 bits of the difference to the 32-bit field at offset. + HIGHADJ = 4, // The base relocation adds the high 16 bits of the difference to the 16-bit field at offset. The 16-bit field represents the high value of a 32-bit word. The low 16 bits of the 32-bit value are stored in the 16-bit word that follows this base relocation. This means that this base relocation occupies two slots. + MIPS_JMPADDR = 5, // The relocation interpretation is dependent on the machine type. When the machine type is MIPS, the base relocation applies to a MIPS jump instruction. + ARM_MOV32 = 5, // This relocation is meaningful only when the machine type is ARM or Thumb. The base relocation applies the 32-bit address of a symbol across a consecutive MOVW/MOVT instruction pair. + RISCV_HIGH20 = 5, // This relocation is only meaningful when the machine type is RISC-V. The base relocation applies to the high 20 bits of a 32-bit absolute address. + MACHINE_SPECIFIC_5 = 5, // The relocation interpretation is dependent on the machine type. + RESERVED = 6, // Reserved, must be zero. + THUMB_MOV32 = 7, // This relocation is meaningful only when the machine type is Thumb. The base relocation applies the 32-bit address of a symbol to a consecutive MOVW/MOVT instruction pair. + RISCV_LOW12I = 7, // This relocation is only meaningful when the machine type is RISC-V. The base relocation applies to the low 12 bits of a 32-bit absolute address formed in RISC-V I-type instruction format. + REL32 = 7, + MACHINE_SPECIFIC_7 = 7, // The relocation interpretation is dependent on the machine type. + RISCV_LOW12S = 8, // This relocation is only meaningful when the machine type is RISC-V. The base relocation applies to the low 12 bits of a 32-bit absolute address formed in RISC-V S-type instruction format. + LOONGARCH32_MARK_LA = 8, // This relocation is only meaningful when the machine type is LoongArch 32-bit. The base relocation applies to a 32-bit absolute address formed in two consecutive instructions. + LOONGARCH64_MARK_LA = 8, // This relocation is only meaningful when the machine type is LoongArch 64-bit. The base relocation applies to a 64-bit absolute address formed in four consecutive instructions. + VXD_RELATIVE = 8, + MACHINE_SPECIFIC_8 = 8, // The relocation interpretation is dependent on the machine type. + MIPS_JMPADDR16 = 9, // The relocation is only meaningful when the machine type is MIPS. The base relocation applies to a MIPS16 jump instruction. + IA64_IMM64 = 9, + MACHINE_SPECIFIC_9 = 9, // The relocation interpretation is dependent on the machine type. + DIR64 = 10, // The base relocation applies the difference to the 64-bit field at offset. +}; + +typedef struct _IMAGE_BASE_RELOCATION { + ULONG VirtualAddress; + ULONG SizeOfBlock; +// USHORT TypeOffset[1]; +} IMAGE_BASE_RELOCATION; + +// +// Archive format. +// + +#define IMAGE_ARCHIVE_START_SIZE 8 +#define IMAGE_ARCHIVE_START b"!\n" +#define IMAGE_ARCHIVE_END b"`\n" +#define IMAGE_ARCHIVE_PAD b"\n" +#define IMAGE_ARCHIVE_LINKER_MEMBER b"/ " +#define IMAGE_ARCHIVE_LONGNAMES_MEMBER b"// " + +typedef struct _IMAGE_ARCHIVE_MEMBER_HEADER { + CHAR Name[16]; // File member name - `/' terminated. + CHAR Date[12]; // File member date - decimal. + CHAR UserID[6]; // File member user id - decimal. + CHAR GroupID[6]; // File member group id - decimal. + CHAR Mode[8]; // File member mode - octal. + CHAR Size[10]; // File member size - decimal. + CHAR EndHeader[2]; // String to end header. +} IMAGE_ARCHIVE_MEMBER_HEADER; + +// +// DLL support. +// + +// +// Export Format +// + +typedef struct _IMAGE_EXPORT_DIRECTORY { + ULONG Characteristics; + ULONG TimeDateStamp; + USHORT MajorVersion; + USHORT MinorVersion; + ULONG Name; + ULONG Base; + ULONG NumberOfFunctions; + ULONG NumberOfNames; + ULONG AddressOfFunctions; // RVA from base of image + ULONG AddressOfNames; // RVA from base of image + ULONG AddressOfNameOrdinals; // RVA from base of image +} IMAGE_EXPORT_DIRECTORY; + +// +// Import Format +// + +typedef struct _IMAGE_IMPORT_BY_NAME { + USHORT Hint; + CHAR Name[]; +} IMAGE_IMPORT_BY_NAME; + +typedef struct _IMAGE_THUNK_DATA64 { + union { + ULONGLONG ForwarderString; // PUCHAR + ULONGLONG Function; // PULONG + ULONGLONG Ordinal; + ULONGLONG AddressOfData; // PIMAGE_IMPORT_BY_NAME + } u1; +} IMAGE_THUNK_DATA64; + +typedef struct _IMAGE_THUNK_DATA32 { + union { + ULONG ForwarderString; // PUCHAR + ULONG Function; // PULONG + ULONG Ordinal; + ULONG AddressOfData; // PIMAGE_IMPORT_BY_NAME + } u1; +} IMAGE_THUNK_DATA32; + +#define IMAGE_ORDINAL_FLAG64 0x8000000000000000 +#define IMAGE_ORDINAL_FLAG32 0x80000000 + +typedef struct _IMAGE_IMPORT_DESCRIPTOR { + union { + ULONG Characteristics; // 0 for terminating null import descriptor + ULONG OriginalFirstThunk; // RVA to original unbound IAT (PIMAGE_THUNK_DATA) + }; + ULONG TimeDateStamp; // 0 if not bound, + // -1 if bound, and real date/time stamp + // in IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT (new BIND) + // O.W. date/time stamp of DLL bound to (Old BIND) + + ULONG ForwarderChain; // -1 if no forwarders + ULONG Name; + ULONG FirstThunk; // RVA to IAT (if bound this IAT has actual addresses) +} IMAGE_IMPORT_DESCRIPTOR; + +// +// Thread Local Storage +// + +typedef struct _IMAGE_TLS_DIRECTORY64 { + ULONGLONG StartAddressOfRawData; + ULONGLONG EndAddressOfRawData; + ULONGLONG AddressOfIndex; // PULONG + ULONGLONG AddressOfCallBacks; // PIMAGE_TLS_CALLBACK *; + ULONG SizeOfZeroFill; + union { + ULONG Characteristics; + struct { + ULONG Reserved0 : 20; + ULONG Alignment : 4; + ULONG Reserved1 : 8; + }; + }; +} IMAGE_TLS_DIRECTORY64; + +typedef struct _IMAGE_TLS_DIRECTORY32 { + ULONG StartAddressOfRawData; + ULONG EndAddressOfRawData; + ULONG AddressOfIndex; // PULONG + ULONG AddressOfCallBacks; // PIMAGE_TLS_CALLBACK * + ULONG SizeOfZeroFill; + union { + ULONG Characteristics; + struct { + ULONG Reserved0 : 20; + ULONG Alignment : 4; + ULONG Reserved1 : 8; + }; + }; +} IMAGE_TLS_DIRECTORY32; + +// +// New format import descriptors pointed to by DataDirectory[ IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT ] +// + +typedef struct _IMAGE_BOUND_IMPORT_DESCRIPTOR { + ULONG TimeDateStamp; + USHORT OffsetModuleName; + USHORT NumberOfModuleForwarderRefs; +// Array of zero or more IMAGE_BOUND_FORWARDER_REF follows +} IMAGE_BOUND_IMPORT_DESCRIPTOR; + +typedef struct _IMAGE_BOUND_FORWARDER_REF { + ULONG TimeDateStamp; + USHORT OffsetModuleName; + USHORT Reserved; +} IMAGE_BOUND_FORWARDER_REF; + +typedef struct _IMAGE_DELAYLOAD_DESCRIPTOR { + union { + ULONG AllAttributes; + struct { + ULONG RvaBased : 1; // Delay load version 2 + ULONG ReservedAttributes : 31; + }; + } Attributes; + + ULONG DllNameRVA; // RVA to the name of the target library (NULL-terminate ASCII string) + ULONG ModuleHandleRVA; // RVA to the HMODULE caching location (PHMODULE) + ULONG ImportAddressTableRVA; // RVA to the start of the IAT (PIMAGE_THUNK_DATA) + ULONG ImportNameTableRVA; // RVA to the start of the name table (PIMAGE_THUNK_DATA::AddressOfData) + ULONG BoundImportAddressTableRVA; // RVA to an optional bound IAT + ULONG UnloadInformationTableRVA; // RVA to an optional unload info table + ULONG TimeDateStamp; // 0 if not bound, + // Otherwise, date/time of the target DLL +} IMAGE_DELAYLOAD_DESCRIPTOR; + +// +// Resource Format. +// + +enum RT { + CURSOR = 1, + BITMAP = 2, + ICON = 3, + MENU = 4, + DIALOG = 5, + STRING = 6, + FONTDIR = 7, + FONT = 8, + ACCELERATOR = 9, + RCDATA = 10, + MESSAGETABLE = 11, + GROUP_CURSOR = 12, + GROUP_ICON = 14, + VERSION = 16, + DLGINCLUDE = 17, + PLUGPLAY = 19, + VXD = 20, + ANICURSOR = 21, + ANIICON = 22, + HTML = 23, + MANIFEST = 24, +}; + +// +// Resource directory consists of two counts, following by a variable length +// array of directory entries. The first count is the number of entries at +// beginning of the array that have actual names associated with each entry. +// The entries are in ascending order, case insensitive strings. The second +// count is the number of entries that immediately follow the named entries. +// This second count identifies the number of entries that have 16-bit integer +// Ids as their name. These entries are also sorted in ascending order. +// +// This structure allows fast lookup by either name or number, but for any +// given resource entry only one form of lookup is supported, not both. +// This is consistant with the syntax of the .RC file and the .RES file. +// + +typedef struct _IMAGE_RESOURCE_DIRECTORY { + ULONG Characteristics; + ULONG TimeDateStamp; + USHORT MajorVersion; + USHORT MinorVersion; + USHORT NumberOfNamedEntries; + USHORT NumberOfIdEntries; + /* IMAGE_RESOURCE_DIRECTORY_ENTRY DirectoryEntries[]; */ +} IMAGE_RESOURCE_DIRECTORY; + +// +// Each directory contains the 32-bit Name of the entry and an offset, +// relative to the beginning of the resource directory of the data associated +// with this directory entry. If the name of the entry is an actual text +// string instead of an integer Id, then the high order bit of the name field +// is set to one and the low order 31-bits are an offset, relative to the +// beginning of the resource directory of the string, which is of type +// IMAGE_RESOURCE_DIRECTORY_STRING. Otherwise the high bit is clear and the +// low-order 16-bits are the integer Id that identify this resource directory +// entry. If the directory entry is yet another resource directory (i.e. a +// subdirectory), then the high order bit of the offset field will be +// set to indicate this. Otherwise the high bit is clear and the offset +// field points to a resource data entry. +// + +typedef struct _IMAGE_RESOURCE_DIRECTORY_ENTRY { + union { + struct { + ULONG NameOffset:31; + ULONG NameIsString:1; + }; + ULONG Name; + USHORT Id; + }; + union { + ULONG OffsetToData; + struct { + ULONG OffsetToDirectory:31; + ULONG DataIsDirectory:1; + }; + }; +} IMAGE_RESOURCE_DIRECTORY_ENTRY; + +// +// For resource directory entries that have actual string names, the Name +// field of the directory entry points to an object of the following type. +// All of these string objects are stored together after the last resource +// directory entry and before the first resource data object. This minimizes +// the impact of these variable length objects on the alignment of the fixed +// size directory entry objects. +// + +typedef struct _IMAGE_RESOURCE_DIRECTORY_STRING { + USHORT Length; + CHAR NameString[Length]; +} IMAGE_RESOURCE_DIRECTORY_STRING; + +typedef struct _IMAGE_RESOURCE_DIR_STRING_U { + USHORT Length; + WCHAR NameString[Length]; +} IMAGE_RESOURCE_DIR_STRING_U; + +// +// Each resource data entry describes a leaf node in the resource directory +// tree. It contains an offset, relative to the beginning of the resource +// directory of the data for the resource, a size field that gives the number +// of bytes of data at that offset, a CodePage that should be used when +// decoding code point values within the resource data. Typically for new +// applications the code page would be the unicode code page. +// + +typedef struct _IMAGE_RESOURCE_DATA_ENTRY { + ULONG OffsetToData; + ULONG Size; + ULONG CodePage; + ULONG Reserved; +} IMAGE_RESOURCE_DATA_ENTRY; + +typedef struct _VS_FIXEDFILEINFO { + DWORD dwSignature; + DWORD dwStrucVersion; + DWORD dwFileVersionMS; + DWORD dwFileVersionLS; + DWORD dwProductVersionMS; + DWORD dwProductVersionLS; + DWORD dwFileFlagsMask; + DWORD dwFileFlags; + DWORD dwFileOS; + DWORD dwFileType; + DWORD dwFileSubtype; + DWORD dwFileDateMS; + DWORD dwFileDateLS; +} VS_FIXEDFILEINFO; + +flag VS_FF { + DEBUG = 0x00000001, // The file contains debugging information or is compiled with debugging features enabled. + PRERELEASE = 0x00000002, // The file is a development version, not a commercially released product. + PATCHED = 0x00000004, // The file has been modified and is not identical to the original shipping file of the same version number. + PRIVATEBUILD = 0x00000008, // The file was not built using standard release procedures. If this flag is set, the StringFileInfo structure should contain a PrivateBuild entry. + INFOINFERRED = 0x00000010, // The file's version structure was created dynamically; therefore, some of the members in this structure may be empty or incorrect. This flag should never be set in a file's VS_VERSIONINFO data. + SPECIALBUILD = 0x00000020, // The file was built by the original company using standard release procedures but is a variation of the normal file of the same version number. If this flag is set, the StringFileInfo structure should contain a SpecialBuild entry. +}; + +enum VOS { + UNKNOWN = 0x00000000, // The operating system for which the file was designed is unknown to the system. + WINDOWS16 = 0x00000001, // The file was designed for 16-bit Windows. + PM16 = 0x00000002, // The file was designed for 16-bit Presentation Manager. + PM32 = 0x00000003, // The file was designed for 32-bit Presentation Manager. + WINDOWS32 = 0x00000004, // The file was designed for 32-bit Windows. + DOS = 0x00010000, // The file was designed for MS-DOS. + OS216 = 0x00020000, // The file was designed for 16-bit OS/2. + OS232 = 0x00030000, // The file was designed for 32-bit OS/2. + NT = 0x00040000, // The file was designed for Windows NT. +}; + +enum VFT { + UNKNOWN = 0x00000000, // The file type is unknown to the system. + APP = 0x00000001, // The file contains an application. + DLL = 0x00000002, // The file contains a DLL. + DRV = 0x00000003, // The file contains a device driver. If dwFileType is VFT_DRV, dwFileSubtype contains a more specific description of the driver. + FONT = 0x00000004, // The file contains a font. If dwFileType is VFT_FONT, dwFileSubtype contains a more specific description of the font file. + VXD = 0x00000005, // The file contains a virtual device. + STATIC_LIBRARY = 0x00000007, // The file contains a static-link library. +}; + +enum VFT2_DRV { + UNKNOWN = 0x00000000, // The driver type is unknown by the system. + PRINTER = 0x00000001, // The file contains a printer driver. + KEYBOARD = 0x00000002, // The file contains a keyboard driver. + LANGUAGE = 0x00000003, // The file contains a language driver. + DISPLAY = 0x00000004, // The file contains a display driver. + MOUSE = 0x00000005, // The file contains a mouse driver. + NETWORK = 0x00000006, // The file contains a network driver. + SYSTEM = 0x00000007, // The file contains a system driver. + INSTALLABLE = 0x00000008, // The file contains an installable driver. + SOUND = 0x00000009, // The file contains a sound driver. + COMM = 0x0000000A, // The file contains a communications driver. + INPUTMETHOD = 0x0000000B, + VERSIONED_PRINTER = 0x0000000C, // The file contains a versioned printer driver. +}; + +enum VFT2_FONT { + UNKNOWN = 0x00000000, // The font type is unknown by the system. + RASTER = 0x00000001, // The file contains a raster font. + VECTOR = 0x00000002, // The file contains a vector font. + TRUETYPE = 0x00000003, // The file contains a TrueType font. +}; + +/* + * Virtual Keys, Standard Set + */ +enum VK { + LBUTTON = 0x01, + RBUTTON = 0x02, + CANCEL = 0x03, + MBUTTON = 0x04, /* NOT contiguous with L & RBUTTON */ + XBUTTON1 = 0x05, /* NOT contiguous with L & RBUTTON */ + XBUTTON2 = 0x06, /* NOT contiguous with L & RBUTTON */ + +/* + * 0x07 : reserved + */ + + BACK = 0x08, + TAB = 0x09, + +/* + * 0x0A - 0x0B : reserved + */ + + CLEAR = 0x0C, + RETURN = 0x0D, + +/* + * 0x0E - 0x0F : unassigned + */ + + SHIFT = 0x10, + CONTROL = 0x11, + MENU = 0x12, + PAUSE = 0x13, + CAPITAL = 0x14, + + KANA = 0x15, + HANGEUL = 0x15, /* old name - should be here for compatibility */ + HANGUL = 0x15, + IME_ON = 0x16, + JUNJA = 0x17, + FINAL = 0x18, + HANJA = 0x19, + KANJI = 0x19, + IME_OFF = 0x1A, + + ESCAPE = 0x1B, + + CONVERT = 0x1C, + NONCONVERT = 0x1D, + ACCEPT = 0x1E, + MODECHANGE = 0x1F, + + SPACE = 0x20, + PRIOR = 0x21, + NEXT = 0x22, + END = 0x23, + HOME = 0x24, + LEFT = 0x25, + UP = 0x26, + RIGHT = 0x27, + DOWN = 0x28, + SELECT = 0x29, + PRINT = 0x2A, + EXECUTE = 0x2B, + SNAPSHOT = 0x2C, + INSERT = 0x2D, + DELETE = 0x2E, + HELP = 0x2F, + +/* + * VK_0 - VK_9 are the same as ASCII '0' - '9' (0x30 - 0x39) + * 0x3A - 0x40 : unassigned + * VK_A - VK_Z are the same as ASCII 'A' - 'Z' (0x41 - 0x5A) + */ + + 0 = 0x30, + 1 = 0x31, + 2 = 0x32, + 3 = 0x33, + 4 = 0x34, + 5 = 0x35, + 6 = 0x36, + 7 = 0x37, + 8 = 0x38, + 9 = 0x39, + A = 0x41, + B = 0x42, + C = 0x43, + D = 0x44, + E = 0x45, + F = 0x46, + G = 0x47, + H = 0x48, + I = 0x49, + J = 0x4A, + K = 0x4B, + L = 0x4C, + M = 0x4D, + N = 0x4E, + O = 0x4F, + P = 0x50, + Q = 0x51, + R = 0x52, + S = 0x53, + T = 0x54, + U = 0x55, + V = 0x56, + W = 0x57, + X = 0x58, + Y = 0x59, + Z = 0x5A, + LWIN = 0x5B, + RWIN = 0x5C, + APPS = 0x5D, + +/* + * 0x5E : reserved + */ + + SLEEP = 0x5F, + + NUMPAD0 = 0x60, + NUMPAD1 = 0x61, + NUMPAD2 = 0x62, + NUMPAD3 = 0x63, + NUMPAD4 = 0x64, + NUMPAD5 = 0x65, + NUMPAD6 = 0x66, + NUMPAD7 = 0x67, + NUMPAD8 = 0x68, + NUMPAD9 = 0x69, + MULTIPLY = 0x6A, + ADD = 0x6B, + SEPARATOR = 0x6C, + SUBTRACT = 0x6D, + DECIMAL = 0x6E, + DIVIDE = 0x6F, + F1 = 0x70, + F2 = 0x71, + F3 = 0x72, + F4 = 0x73, + F5 = 0x74, + F6 = 0x75, + F7 = 0x76, + F8 = 0x77, + F9 = 0x78, + F10 = 0x79, + F11 = 0x7A, + F12 = 0x7B, + F13 = 0x7C, + F14 = 0x7D, + F15 = 0x7E, + F16 = 0x7F, + F17 = 0x80, + F18 = 0x81, + F19 = 0x82, + F20 = 0x83, + F21 = 0x84, + F22 = 0x85, + F23 = 0x86, + F24 = 0x87, + +/* + * 0x88 - 0x8F : UI navigation + */ + + NAVIGATION_VIEW = 0x88, // reserved + NAVIGATION_MENU = 0x89, // reserved + NAVIGATION_UP = 0x8A, // reserved + NAVIGATION_DOWN = 0x8B, // reserved + NAVIGATION_LEFT = 0x8C, // reserved + NAVIGATION_RIGHT = 0x8D, // reserved + NAVIGATION_ACCEPT = 0x8E, // reserved + NAVIGATION_CANCEL = 0x8F, // reserved + + NUMLOCK = 0x90, + SCROLL = 0x91, + +/* + * NEC PC-9800 kbd definitions + */ + OEM_NEC_EQUAL = 0x92, // '=' key on numpad + +/* + * Fujitsu/OASYS kbd definitions + */ + OEM_FJ_JISHO = 0x92, // 'Dictionary' key + OEM_FJ_MASSHOU = 0x93, // 'Unregister word' key + OEM_FJ_TOUROKU = 0x94, // 'Register word' key + OEM_FJ_LOYA = 0x95, // 'Left OYAYUBI' key + OEM_FJ_ROYA = 0x96, // 'Right OYAYUBI' key + +/* + * 0x97 - 0x9F : unassigned + */ + +/* + * VK_L* & VK_R* - left and right Alt, Ctrl and Shift virtual keys. + * Used only as parameters to GetAsyncKeyState() and GetKeyState(). + * No other API or message will distinguish left and right keys in this way. + */ + LSHIFT = 0xA0, + RSHIFT = 0xA1, + LCONTROL = 0xA2, + RCONTROL = 0xA3, + LMENU = 0xA4, + RMENU = 0xA5, + + BROWSER_BACK = 0xA6, + BROWSER_FORWARD = 0xA7, + BROWSER_REFRESH = 0xA8, + BROWSER_STOP = 0xA9, + BROWSER_SEARCH = 0xAA, + BROWSER_FAVORITES = 0xAB, + BROWSER_HOME = 0xAC, + + VOLUME_MUTE = 0xAD, + VOLUME_DOWN = 0xAE, + VOLUME_UP = 0xAF, + MEDIA_NEXT_TRACK = 0xB0, + MEDIA_PREV_TRACK = 0xB1, + MEDIA_STOP = 0xB2, + MEDIA_PLAY_PAUSE = 0xB3, + LAUNCH_MAIL = 0xB4, + LAUNCH_MEDIA_SELECT = 0xB5, + LAUNCH_APP1 = 0xB6, + LAUNCH_APP2 = 0xB7, + +/* + * 0xB8 - 0xB9 : reserved + */ + + OEM_1 = 0xBA, // ';:' for US + OEM_PLUS = 0xBB, // '+' any country + OEM_COMMA = 0xBC, // ',' any country + OEM_MINUS = 0xBD, // '-' any country + OEM_PERIOD = 0xBE, // '.' any country + OEM_2 = 0xBF, // '/?' for US + OEM_3 = 0xC0, // '`~' for US + +/* + * 0xC1 - 0xC2 : reserved + */ + + /* + * 0xC3 - 0xDA : Gamepad input + */ + + GAMEPAD_A = 0xC3, // reserved + GAMEPAD_B = 0xC4, // reserved + GAMEPAD_X = 0xC5, // reserved + GAMEPAD_Y = 0xC6, // reserved + GAMEPAD_RIGHT_SHOULDER = 0xC7, // reserved + GAMEPAD_LEFT_SHOULDER = 0xC8, // reserved + GAMEPAD_LEFT_TRIGGER = 0xC9, // reserved + GAMEPAD_RIGHT_TRIGGER = 0xCA, // reserved + GAMEPAD_DPAD_UP = 0xCB, // reserved + GAMEPAD_DPAD_DOWN = 0xCC, // reserved + GAMEPAD_DPAD_LEFT = 0xCD, // reserved + GAMEPAD_DPAD_RIGHT = 0xCE, // reserved + GAMEPAD_MENU = 0xCF, // reserved + GAMEPAD_VIEW = 0xD0, // reserved + GAMEPAD_LEFT_THUMBSTICK_BUTTON = 0xD1, // reserved + GAMEPAD_RIGHT_THUMBSTICK_BUTTON = 0xD2, // reserved + GAMEPAD_LEFT_THUMBSTICK_UP = 0xD3, // reserved + GAMEPAD_LEFT_THUMBSTICK_DOWN = 0xD4, // reserved + GAMEPAD_LEFT_THUMBSTICK_RIGHT = 0xD5, // reserved + GAMEPAD_LEFT_THUMBSTICK_LEFT = 0xD6, // reserved + GAMEPAD_RIGHT_THUMBSTICK_UP = 0xD7, // reserved + GAMEPAD_RIGHT_THUMBSTICK_DOWN = 0xD8, // reserved + GAMEPAD_RIGHT_THUMBSTICK_RIGHT = 0xD9, // reserved + GAMEPAD_RIGHT_THUMBSTICK_LEFT = 0xDA, // reserved + + OEM_4 = 0xDB, // '[{' for US + OEM_5 = 0xDC, // '|' for US + OEM_6 = 0xDD, // ']}' for US + OEM_7 = 0xDE, // ''"' for US + OEM_8 = 0xDF, + +/* + * 0xE0 : reserved + */ + +/* + * Various extended or enhanced keyboards + */ + OEM_AX = 0xE1, // 'AX' key on Japanese AX kbd + OEM_102 = 0xE2, // "<>" or "|" on RT 102-key kbd. + ICO_HELP = 0xE3, // Help key on ICO + ICO_00 = 0xE4, // 00 key on ICO + + PROCESSKEY = 0xE5, + + ICO_CLEAR = 0xE6, + + PACKET = 0xE7, + +/* + * 0xE8 : unassigned + */ + +/* + * Nokia/Ericsson definitions + */ + OEM_RESET = 0xE9, + OEM_JUMP = 0xEA, + OEM_PA1 = 0xEB, + OEM_PA2 = 0xEC, + OEM_PA3 = 0xED, + OEM_WSCTRL = 0xEE, + OEM_CUSEL = 0xEF, + OEM_ATTN = 0xF0, + OEM_FINISH = 0xF1, + OEM_COPY = 0xF2, + OEM_AUTO = 0xF3, + OEM_ENLW = 0xF4, + OEM_BACKTAB = 0xF5, + + ATTN = 0xF6, + CRSEL = 0xF7, + EXSEL = 0xF8, + EREOF = 0xF9, + PLAY = 0xFA, + ZOOM = 0xFB, + NONAME = 0xFC, + PA1 = 0xFD, + OEM_CLEAR = 0xFE, + +/* + * 0xFF : reserved + */ +}; + +flag ACCEL_F { + VIRTKEY = 0x01, // Assumed to be == TRUE + LASTKEY = 0x80, // Indicates last key in the table + NOINVERT = 0x02, + SHIFT = 0x04, + CONTROL = 0x08, + ALT = 0x10, +}; + +// +// Code Integrity in loadconfig (CI) +// + +typedef struct _IMAGE_LOAD_CONFIG_CODE_INTEGRITY { + USHORT Flags; // Flags to indicate if CI information is available, etc. + USHORT Catalog; // 0xFFFF means not available + ULONG CatalogOffset; + ULONG Reserved; // Additional bitmask to be defined later +} IMAGE_LOAD_CONFIG_CODE_INTEGRITY; + +// +// Dynamic value relocation table in loadconfig +// + +typedef struct _IMAGE_DYNAMIC_RELOCATION_TABLE { + ULONG Version; + ULONG Size; +// IMAGE_DYNAMIC_RELOCATION DynamicRelocations[0]; +} IMAGE_DYNAMIC_RELOCATION_TABLE; + +// +// Dynamic value relocation entries following IMAGE_DYNAMIC_RELOCATION_TABLE +// + +typedef struct _IMAGE_DYNAMIC_RELOCATION32 { + ULONG Symbol; + ULONG BaseRelocSize; +// IMAGE_BASE_RELOCATION BaseRelocations[0]; +} IMAGE_DYNAMIC_RELOCATION32; + +typedef struct _IMAGE_DYNAMIC_RELOCATION64 { + ULONGLONG Symbol; + ULONG BaseRelocSize; +// IMAGE_BASE_RELOCATION BaseRelocations[0]; +} IMAGE_DYNAMIC_RELOCATION64; + +typedef struct _IMAGE_DYNAMIC_RELOCATION32_V2 { + ULONG HeaderSize; + ULONG FixupInfoSize; + ULONG Symbol; + ULONG SymbolGroup; + ULONG Flags; + // ... variable length header fields + // UCHAR FixupInfo[FixupInfoSize]; +} IMAGE_DYNAMIC_RELOCATION32_V2; + +typedef struct _IMAGE_DYNAMIC_RELOCATION64_V2 { + ULONG HeaderSize; + ULONG FixupInfoSize; + ULONGLONG Symbol; + ULONG SymbolGroup; + ULONG Flags; + // ... variable length header fields + // UCHAR FixupInfo[FixupInfoSize] +} IMAGE_DYNAMIC_RELOCATION64_V2; + +// +// Defined symbolic dynamic relocation entries. +// + +#define IMAGE_DYNAMIC_RELOCATION_GUARD_RF_PROLOGUE 0x00000001 +#define IMAGE_DYNAMIC_RELOCATION_GUARD_RF_EPILOGUE 0x00000002 +#define IMAGE_DYNAMIC_RELOCATION_GUARD_IMPORT_CONTROL_TRANSFER 0x00000003 +#define IMAGE_DYNAMIC_RELOCATION_GUARD_INDIR_CONTROL_TRANSFER 0x00000004 +#define IMAGE_DYNAMIC_RELOCATION_GUARD_SWITCHTABLE_BRANCH 0x00000005 +#define IMAGE_DYNAMIC_RELOCATION_ARM64X 0x00000006 +#define IMAGE_DYNAMIC_RELOCATION_FUNCTION_OVERRIDE 0x00000007 +#define IMAGE_DYNAMIC_RELOCATION_ARM64_KERNEL_IMPORT_CALL_TRANSFER 0x00000008 +#define IMAGE_DYNAMIC_RELOCATION_MM_SHARED_USER_DATA_VA 0x7FFE0000 +#define IMAGE_DYNAMIC_RELOCATION_KI_USER_SHARED_DATA64 0xFFFFF78000000000 + +typedef struct _IMAGE_PROLOGUE_DYNAMIC_RELOCATION_HEADER { + UCHAR PrologueByteCount; + // UCHAR PrologueBytes[PrologueByteCount]; +} IMAGE_PROLOGUE_DYNAMIC_RELOCATION_HEADER; + +typedef struct _IMAGE_EPILOGUE_DYNAMIC_RELOCATION_HEADER { + ULONG EpilogueCount; + UCHAR EpilogueByteCount; + UCHAR BranchDescriptorElementSize; + USHORT BranchDescriptorCount; + // UCHAR BranchDescriptors[...]; + // UCHAR BranchDescriptorBitMap[...]; +} IMAGE_EPILOGUE_DYNAMIC_RELOCATION_HEADER; + +typedef struct _IMAGE_IMPORT_CONTROL_TRANSFER_DYNAMIC_RELOCATION { + ULONG PageRelativeOffset : 12; + ULONG IndirectCall : 1; + ULONG IATIndex : 19; +} IMAGE_IMPORT_CONTROL_TRANSFER_DYNAMIC_RELOCATION; + +// +// On ARM64, an optimized imported function uses the following data structure +// insted of a _IMAGE_IMPORT_CONTROL_TRANSFER_DYNAMIC_RELOCATION. +// + +typedef struct _IMAGE_IMPORT_CONTROL_TRANSFER_ARM64_RELOCATION { + ULONG PageRelativeOffset : 10; // Offset to the call instruction shifted right by 2 (4-byte aligned instruction) + ULONG IndirectCall : 1; // 0 if target instruction is a BR, 1 if BLR. + ULONG RegisterIndex : 5; // Register index used for the indirect call/jump. + ULONG ImportType : 1; // 0 if this refers to a static import, 1 for delayload import + ULONG IATIndex : 15; // IAT index of the corresponding import. + // 0x7FFF is a special value indicating no index. +} IMAGE_IMPORT_CONTROL_TRANSFER_ARM64_RELOCATION; + +typedef struct _IMAGE_INDIR_CONTROL_TRANSFER_DYNAMIC_RELOCATION { + USHORT PageRelativeOffset : 12; + USHORT IndirectCall : 1; + USHORT RexWPrefix : 1; + USHORT CfgCheck : 1; + USHORT Reserved : 1; +} IMAGE_INDIR_CONTROL_TRANSFER_DYNAMIC_RELOCATION; + +typedef struct _IMAGE_SWITCHTABLE_BRANCH_DYNAMIC_RELOCATION { + USHORT PageRelativeOffset : 12; + USHORT RegisterNumber : 4; +} IMAGE_SWITCHTABLE_BRANCH_DYNAMIC_RELOCATION; + +typedef struct _IMAGE_FUNCTION_OVERRIDE_HEADER { + ULONG FuncOverrideSize; + // IMAGE_FUNCTION_OVERRIDE_DYNAMIC_RELOCATION FuncOverrideInfo[ANYSIZE_ARRAY]; // FuncOverrideSize bytes in size + // IMAGE_BDD_INFO BDDInfo; // BDD region, size in bytes: DVRTEntrySize - sizeof(IMAGE_FUNCTION_OVERRIDE_HEADER) - FuncOverrideSize +} IMAGE_FUNCTION_OVERRIDE_HEADER; + +typedef struct _IMAGE_FUNCTION_OVERRIDE_DYNAMIC_RELOCATION { + ULONG OriginalRva; // RVA of original function + ULONG BDDOffset; // Offset into the BDD region + ULONG RvaSize; // Size in bytes taken by RVAs. Must be multiple of sizeof(ULONG). + ULONG BaseRelocSize; // Size in bytes taken by BaseRelocs + +// ULONG RVAs[RvaSize / sizeof(ULONG)]; // Array containing overriding func RVAs. + +// IMAGE_BASE_RELOCATION BaseRelocs[ANYSIZE_ARRAY]; // Base relocations (RVA + Size + TO) + // Padded with extra TOs for 4B alignment + // BaseRelocSize size in bytes +} IMAGE_FUNCTION_OVERRIDE_DYNAMIC_RELOCATION; + +typedef struct _IMAGE_BDD_INFO { + ULONG Version; // decides the semantics of serialized BDD + ULONG BDDSize; +// IMAGE_BDD_DYNAMIC_RELOCATION BDDNodes[ANYSIZE_ARRAY]; // BDDSize size in bytes. +} IMAGE_BDD_INFO; + +typedef struct _IMAGE_BDD_DYNAMIC_RELOCATION { + USHORT Left; // Index of FALSE edge in BDD array + USHORT Right; // Index of TRUE edge in BDD array + ULONG Value; // Either FeatureNumber or Index into RVAs array +} IMAGE_BDD_DYNAMIC_RELOCATION; + +// Function override relocation types in DVRT records. + +#define IMAGE_FUNCTION_OVERRIDE_INVALID 0 +#define IMAGE_FUNCTION_OVERRIDE_X64_REL32 1 // 32-bit relative address from byte following reloc +#define IMAGE_FUNCTION_OVERRIDE_ARM64_BRANCH26 2 // 26 bit offset << 2 & sign ext. for B & BL +#define IMAGE_FUNCTION_OVERRIDE_ARM64_THUNK 3 + +// +// Load Configuration Directory Entry +// + +flag IMAGE_GUARD : ULONG { + CF_INSTRUMENTED = 0x00000100, // Module performs control flow integrity checks using system-supplied support + CFW_INSTRUMENTED = 0x00000200, // Module performs control flow and write integrity checks + CF_FUNCTION_TABLE_PRESENT = 0x00000400, // Module contains valid control flow target metadata + SECURITY_COOKIE_UNUSED = 0x00000800, // Module does not make use of the /GS security cookie + PROTECT_DELAYLOAD_IAT = 0x00001000, // Module supports read only delay load IAT + DELAYLOAD_IAT_IN_ITS_OWN_SECTION = 0x00002000, // Delayload import table in its own .didat section (with nothing else in it) that can be freely reprotected + CF_EXPORT_SUPPRESSION_INFO_PRESENT = 0x00004000, // Module contains suppressed export information. This also infers that the address taken + // taken IAT table is also present in the load config. + CF_ENABLE_EXPORT_SUPPRESSION = 0x00008000, // Module enables suppression of exports + CF_LONGJUMP_TABLE_PRESENT = 0x00010000, // Module contains longjmp target information + RF_INSTRUMENTED = 0x00020000, // Module contains return flow instrumentation and metadata + RF_ENABLE = 0x00040000, // Module requests that the OS enable return flow protection + RF_STRICT = 0x00080000, // Module requests that the OS enable return flow protection in strict mode + RETPOLINE_PRESENT = 0x00100000, // Module was built with retpoline support +// DO_NOT_USE = 0x00200000, // Was EHCont flag on VB (20H1) + EH_CONTINUATION_TABLE_PRESENT = 0x00400000, // Module contains EH continuation target information + XFG_ENABLED = 0x00800000, // Module was built with xfg + CASTGUARD_PRESENT = 0x01000000, // Module has CastGuard instrumentation present + MEMCPY_PRESENT = 0x02000000, // Module has Guarded Memcpy instrumentation present +}; + +#define IMAGE_GUARD_CF_FUNCTION_TABLE_SIZE_MASK 0xF0000000 // Stride of Guard CF function table encoded in these bits (additional count of bytes per element) +#define IMAGE_GUARD_CF_FUNCTION_TABLE_SIZE_SHIFT 28 // Shift to right-justify Guard CF function table stride + +typedef struct _IMAGE_LOAD_CONFIG_DIRECTORY32 { + ULONG Size; + ULONG TimeDateStamp; + USHORT MajorVersion; + USHORT MinorVersion; + ULONG GlobalFlagsClear; + ULONG GlobalFlagsSet; + ULONG CriticalSectionDefaultTimeout; + ULONG DeCommitFreeBlockThreshold; + ULONG DeCommitTotalFreeThreshold; + ULONG LockPrefixTable; // VA + ULONG MaximumAllocationSize; + ULONG VirtualMemoryThreshold; + ULONG ProcessHeapFlags; + ULONG ProcessAffinityMask; + USHORT CSDVersion; + USHORT DependentLoadFlags; + ULONG EditList; // VA + ULONG SecurityCookie; // VA + ULONG SEHandlerTable; // VA + ULONG SEHandlerCount; + ULONG GuardCFCheckFunctionPointer; // VA + ULONG GuardCFDispatchFunctionPointer; // VA + ULONG GuardCFFunctionTable; // VA + ULONG GuardCFFunctionCount; + IMAGE_GUARD GuardFlags; + IMAGE_LOAD_CONFIG_CODE_INTEGRITY CodeIntegrity; + ULONG GuardAddressTakenIatEntryTable; // VA + ULONG GuardAddressTakenIatEntryCount; + ULONG GuardLongJumpTargetTable; // VA + ULONG GuardLongJumpTargetCount; + ULONG DynamicValueRelocTable; // VA + ULONG CHPEMetadataPointer; + ULONG GuardRFFailureRoutine; // VA + ULONG GuardRFFailureRoutineFunctionPointer; // VA + ULONG DynamicValueRelocTableOffset; + USHORT DynamicValueRelocTableSection; + USHORT Reserved2; + ULONG GuardRFVerifyStackPointerFunctionPointer; // VA + ULONG HotPatchTableOffset; + ULONG Reserved3; + ULONG EnclaveConfigurationPointer; // VA + ULONG VolatileMetadataPointer; // VA + ULONG GuardEHContinuationTable; // VA + ULONG GuardEHContinuationCount; + ULONG GuardXFGCheckFunctionPointer; // VA + ULONG GuardXFGDispatchFunctionPointer; // VA + ULONG GuardXFGTableDispatchFunctionPointer; // VA + ULONG CastGuardOsDeterminedFailureMode; // VA + ULONG GuardMemcpyFunctionPointer; // VA + ULONG UmaFunctionPointers; // VA +} IMAGE_LOAD_CONFIG_DIRECTORY32; + +typedef struct _IMAGE_LOAD_CONFIG_DIRECTORY64 { + ULONG Size; + ULONG TimeDateStamp; + USHORT MajorVersion; + USHORT MinorVersion; + ULONG GlobalFlagsClear; + ULONG GlobalFlagsSet; + ULONG CriticalSectionDefaultTimeout; + ULONGLONG DeCommitFreeBlockThreshold; + ULONGLONG DeCommitTotalFreeThreshold; + ULONGLONG LockPrefixTable; // VA + ULONGLONG MaximumAllocationSize; + ULONGLONG VirtualMemoryThreshold; + ULONGLONG ProcessAffinityMask; + ULONG ProcessHeapFlags; + USHORT CSDVersion; + USHORT DependentLoadFlags; + ULONGLONG EditList; // VA + ULONGLONG SecurityCookie; // VA + ULONGLONG SEHandlerTable; // VA + ULONGLONG SEHandlerCount; + ULONGLONG GuardCFCheckFunctionPointer; // VA + ULONGLONG GuardCFDispatchFunctionPointer; // VA + ULONGLONG GuardCFFunctionTable; // VA + ULONGLONG GuardCFFunctionCount; + IMAGE_GUARD GuardFlags; + IMAGE_LOAD_CONFIG_CODE_INTEGRITY CodeIntegrity; + ULONGLONG GuardAddressTakenIatEntryTable; // VA + ULONGLONG GuardAddressTakenIatEntryCount; + ULONGLONG GuardLongJumpTargetTable; // VA + ULONGLONG GuardLongJumpTargetCount; + ULONGLONG DynamicValueRelocTable; // VA + ULONGLONG CHPEMetadataPointer; // VA + ULONGLONG GuardRFFailureRoutine; // VA + ULONGLONG GuardRFFailureRoutineFunctionPointer; // VA + ULONG DynamicValueRelocTableOffset; + USHORT DynamicValueRelocTableSection; + USHORT Reserved2; + ULONGLONG GuardRFVerifyStackPointerFunctionPointer; // VA + ULONG HotPatchTableOffset; + ULONG Reserved3; + ULONGLONG EnclaveConfigurationPointer; // VA + ULONGLONG VolatileMetadataPointer; // VA + ULONGLONG GuardEHContinuationTable; // VA + ULONGLONG GuardEHContinuationCount; + ULONGLONG GuardXFGCheckFunctionPointer; // VA + ULONGLONG GuardXFGDispatchFunctionPointer; // VA + ULONGLONG GuardXFGTableDispatchFunctionPointer; // VA + ULONGLONG CastGuardOsDeterminedFailureMode; // VA + ULONGLONG GuardMemcpyFunctionPointer; // VA + ULONGLONG UmaFunctionPointers; // VA +} IMAGE_LOAD_CONFIG_DIRECTORY64; + +typedef struct _IMAGE_CHPE_METADATA_X86 { + ULONG Version; + ULONG CHPECodeAddressRangeOffset; + ULONG CHPECodeAddressRangeCount; + ULONG WowA64ExceptionHandlerFunctionPointer; + ULONG WowA64DispatchCallFunctionPointer; + ULONG WowA64DispatchIndirectCallFunctionPointer; + ULONG WowA64DispatchIndirectCallCfgFunctionPointer; + ULONG WowA64DispatchRetFunctionPointer; + ULONG WowA64DispatchRetLeafFunctionPointer; + ULONG WowA64DispatchJumpFunctionPointer; + ULONG CompilerIATPointer; // Present if Version >= 2 + ULONG WowA64RdtscFunctionPointer; // Present if Version >= 3 +} IMAGE_CHPE_METADATA_X86; + +typedef struct _IMAGE_CHPE_RANGE_ENTRY { + union { + ULONG StartOffset; + struct { + ULONG NativeCode : 1; + ULONG AddressBits : 31; + }; + }; + ULONG Length; +} IMAGE_CHPE_RANGE_ENTRY; + +typedef struct _IMAGE_ARM64EC_METADATA { + ULONG Version; + ULONG CodeMap; + ULONG CodeMapCount; + ULONG CodeRangesToEntryPoints; + ULONG RedirectionMetadata; + ULONG tbd__os_arm64x_dispatch_call_no_redirect; + ULONG tbd__os_arm64x_dispatch_ret; + ULONG tbd__os_arm64x_dispatch_call; + ULONG tbd__os_arm64x_dispatch_icall; + ULONG tbd__os_arm64x_dispatch_icall_cfg; + ULONG AlternateEntryPoint; + ULONG AuxiliaryIAT; + ULONG CodeRangesToEntryPointsCount; + ULONG RedirectionMetadataCount; + ULONG GetX64InformationFunctionPointer; + ULONG SetX64InformationFunctionPointer; + ULONG ExtraRFETable; + ULONG ExtraRFETableSize; + ULONG __os_arm64x_dispatch_fptr; + ULONG AuxiliaryIATCopy; +} IMAGE_ARM64EC_METADATA; + +typedef struct _IMAGE_ARM64EC_METADATA_V2 { + ULONG Version; + ULONG CodeMap; + ULONG CodeMapCount; + ULONG CodeRangesToEntryPoints; + ULONG RedirectionMetadata; + ULONG tbd__os_arm64x_dispatch_call_no_redirect; + ULONG tbd__os_arm64x_dispatch_ret; + ULONG tbd__os_arm64x_dispatch_call; + ULONG tbd__os_arm64x_dispatch_icall; + ULONG tbd__os_arm64x_dispatch_icall_cfg; + ULONG AlternateEntryPoint; + ULONG AuxiliaryIAT; + ULONG CodeRangesToEntryPointsCount; + ULONG RedirectionMetadataCount; + ULONG GetX64InformationFunctionPointer; + ULONG SetX64InformationFunctionPointer; + ULONG ExtraRFETable; + ULONG ExtraRFETableSize; + ULONG __os_arm64x_dispatch_fptr; + ULONG AuxiliaryIATCopy; + + // + // Below are V2-specific + // + ULONG AuxDelayloadIAT; + ULONG AuxDelayloadIATCopy; + ULONG ReservedBitField; // reserved and unused by the linker +} IMAGE_ARM64EC_METADATA_V2; + +typedef struct _IMAGE_ARM64EC_REDIRECTION_ENTRY { + ULONG Source; + ULONG Destination; +} IMAGE_ARM64EC_REDIRECTION_ENTRY; + +typedef struct _IMAGE_ARM64EC_CODE_RANGE_ENTRY_POINT { + ULONG StartRva; + ULONG EndRva; + ULONG EntryPoint; +} IMAGE_ARM64EC_CODE_RANGE_ENTRY_POINT; + +#define IMAGE_DVRT_ARM64X_FIXUP_TYPE_ZEROFILL 0 +#define IMAGE_DVRT_ARM64X_FIXUP_TYPE_VALUE 1 +#define IMAGE_DVRT_ARM64X_FIXUP_TYPE_DELTA 2 + +#define IMAGE_DVRT_ARM64X_FIXUP_SIZE_2BYTES 1 +#define IMAGE_DVRT_ARM64X_FIXUP_SIZE_4BYTES 2 +#define IMAGE_DVRT_ARM64X_FIXUP_SIZE_8BYTES 3 + +typedef struct _IMAGE_DVRT_ARM64X_FIXUP_RECORD { + USHORT Offset : 12; + USHORT Type : 2; + USHORT Size : 2; +} IMAGE_DVRT_ARM64X_FIXUP_RECORD; + +typedef struct _IMAGE_DVRT_ARM64X_DELTA_FIXUP_RECORD { + USHORT Offset : 12; + USHORT Type : 2; + USHORT Sign : 1; + USHORT Scale : 1; +} IMAGE_DVRT_ARM64X_DELTA_FIXUP_RECORD; + +typedef struct _IMAGE_HOT_PATCH_INFO { + ULONG Version; + ULONG Size; + ULONG SequenceNumber; + ULONG BaseImageList; + ULONG BaseImageCount; + ULONG BufferOffset; // Version 2 and later + ULONG ExtraPatchSize; // Version 3 and later + ULONG MinSequenceNumber; // Version 4 and later + ULONG Flags; // Version 4 and later +} IMAGE_HOT_PATCH_INFO; + +typedef struct _IMAGE_HOT_PATCH_BASE { + ULONG SequenceNumber; + ULONG Flags; + ULONG OriginalTimeDateStamp; + ULONG OriginalCheckSum; + ULONG CodeIntegrityInfo; + ULONG CodeIntegritySize; + ULONG PatchTable; + ULONG BufferOffset; // V2 and later +} IMAGE_HOT_PATCH_BASE; + +typedef struct _IMAGE_HOT_PATCH_MACHINE { + struct { + ULONG _x86 : 1; + ULONG Amd64 : 1; + ULONG Arm64 : 1; + ULONG Amd64EC : 1; + }; +} IMAGE_HOT_PATCH_MACHINE; + +typedef struct _IMAGE_HOT_PATCH_HASHES { + UCHAR SHA256[32]; + UCHAR SHA1[20]; +} IMAGE_HOT_PATCH_HASHES; + +#define IMAGE_HOT_PATCH_BASE_OBLIGATORY 0x00000001 +#define IMAGE_HOT_PATCH_BASE_CAN_ROLL_BACK 0x00000002 + +#define IMAGE_HOT_PATCH_BASE_MACHINE_I386 0x00000004 +#define IMAGE_HOT_PATCH_BASE_MACHINE_ARM64 0x00000008 +#define IMAGE_HOT_PATCH_BASE_MACHINE_AMD64 0x00000010 + +#define IMAGE_HOT_PATCH_CHUNK_INVERSE 0x80000000 +#define IMAGE_HOT_PATCH_CHUNK_OBLIGATORY 0x40000000 +#define IMAGE_HOT_PATCH_CHUNK_RESERVED 0x3FF03000 +#define IMAGE_HOT_PATCH_CHUNK_TYPE 0x000FC000 +#define IMAGE_HOT_PATCH_CHUNK_SOURCE_RVA 0x00008000 +#define IMAGE_HOT_PATCH_CHUNK_TARGET_RVA 0x00004000 +#define IMAGE_HOT_PATCH_CHUNK_SIZE 0x00000FFF + +enum IMAGE_HOT_PATCH { + NONE = 0x00000000, + FUNCTION = 0x0001C000, + ABSOLUTE = 0x0002C000, + REL32 = 0x0003C000, + CALL_TARGET = 0x00044000, + INDIRECT = 0x0005C000, + NO_CALL_TARGET = 0x00064000, + DYNAMIC_VALUE = 0x00078000, +}; + +// +// GFIDS table entry flags. +// + +#define IMAGE_GUARD_FLAG_FID_SUPPRESSED 0x01 // The containing GFID entry is suppressed +#define IMAGE_GUARD_FLAG_EXPORT_SUPPRESSED 0x02 // The containing GFID entry is export suppressed +#define IMAGE_GUARD_FLAG_FID_LANGEXCPTHANDLER 0x04 +#define IMAGE_GUARD_FLAG_FID_XFG 0x08 + +// +// WIN CE Exception table format +// + +// +// Function table entry format. Function table is pointed to by the +// IMAGE_DIRECTORY_ENTRY_EXCEPTION directory entry. +// + +typedef struct _IMAGE_CE_RUNTIME_FUNCTION_ENTRY { + ULONG FuncStart; + ULONG PrologLen : 8; + ULONG FuncLen : 22; + ULONG ThirtyTwoBit : 1; + ULONG ExceptionFlag : 1; +} IMAGE_CE_RUNTIME_FUNCTION_ENTRY; + +typedef struct _IMAGE_ARM_RUNTIME_FUNCTION_ENTRY { + ULONG BeginAddress; + union { + ULONG UnwindData; + struct { + ULONG Flag : 2; + ULONG FunctionLength : 11; + ULONG Ret : 2; + ULONG H : 1; + ULONG Reg : 3; + ULONG R : 1; + ULONG L : 1; + ULONG C : 1; + ULONG StackAdjust : 10; + }; + }; +} IMAGE_ARM_RUNTIME_FUNCTION_ENTRY; + +enum ARM64_FNPDATA_FLAGS { + PdataRefToFullXdata = 0, + PdataPackedUnwindFunction = 1, + PdataPackedUnwindFragment = 2, +}; + +enum ARM64_FNPDATA_CR { + PdataCrUnchained = 0, + PdataCrUnchainedSavedLr = 1, + PdataCrChainedWithPac = 2, + PdataCrChained = 3, +}; + +typedef struct _IMAGE_ARM64_RUNTIME_FUNCTION_ENTRY { + ULONG BeginAddress; + union { + ULONG UnwindData; + struct { + ULONG Flag : 2; + ULONG FunctionLength : 11; + ULONG RegF : 3; + ULONG RegI : 4; + ULONG H : 1; + ULONG CR : 2; + ULONG FrameSize : 9; + }; + }; +} IMAGE_ARM64_RUNTIME_FUNCTION_ENTRY; + +typedef union _IMAGE_ARM64_RUNTIME_FUNCTION_ENTRY_XDATA { + ULONG HeaderData; + struct { + ULONG FunctionLength : 18; // in words (2 bytes) + ULONG Version : 2; + ULONG ExceptionDataPresent : 1; + ULONG EpilogInHeader : 1; + ULONG EpilogCount : 5; // number of epilogs or byte index of the first unwind code for the one only epilog + ULONG CodeWords : 5; // number of dwords with unwind codes + }; +} IMAGE_ARM64_RUNTIME_FUNCTION_ENTRY_XDATA; + +typedef union IMAGE_ARM64_RUNTIME_FUNCTION_ENTRY_XDATA_EXTENDED { + ULONG ExtendedHeaderData; + struct { + ULONG ExtendedEpilogCount : 16; + ULONG ExtendedCodeWords : 8; + }; +} IMAGE_ARM64_RUNTIME_FUNCTION_ENTRY_XDATA_EXTENDED; + +typedef union IMAGE_ARM64_RUNTIME_FUNCTION_ENTRY_XDATA_EPILOG_SCOPE { + ULONG EpilogScopeData; + struct { + ULONG EpilogStartOffset : 18; // offset in bytes, divided by 4, of the epilog relative to the start of the function. + ULONG Res0: 4; + ULONG EpilogStartIndex : 10; // byte index of the first unwind code that describes this epilog. + }; +} IMAGE_ARM64_RUNTIME_FUNCTION_ENTRY_XDATA_EPILOG_SCOPE; + +typedef struct _IMAGE_ALPHA64_RUNTIME_FUNCTION_ENTRY { + ULONGLONG BeginAddress; + ULONGLONG EndAddress; + ULONGLONG ExceptionHandler; + ULONGLONG HandlerData; + ULONGLONG PrologEndAddress; +} IMAGE_ALPHA64_RUNTIME_FUNCTION_ENTRY; + +typedef struct _IMAGE_ALPHA_RUNTIME_FUNCTION_ENTRY { + ULONG BeginAddress; + ULONG EndAddress; + ULONG ExceptionHandler; + ULONG HandlerData; + ULONG PrologEndAddress; +} IMAGE_ALPHA_RUNTIME_FUNCTION_ENTRY; + +typedef struct _IMAGE_MIPS_RUNTIME_FUNCTION_ENTRY { + ULONG BeginAddress; + ULONG EndAddress; + ULONG ExceptionHandler; + ULONG HandlerData; + ULONG PrologEndAddress; +} IMAGE_MIPS_RUNTIME_FUNCTION_ENTRY; + +typedef struct _IMAGE_RUNTIME_FUNCTION_ENTRY { + ULONG BeginAddress; + ULONG EndAddress; + union { + ULONG UnwindInfoAddress; + ULONG UnwindData; + }; +} IMAGE_RUNTIME_FUNCTION_ENTRY; + +// +// Sofware enclave information +// + +#define IMAGE_ENCLAVE_LONG_ID_LENGTH ENCLAVE_LONG_ID_LENGTH +#define IMAGE_ENCLAVE_SHORT_ID_LENGTH ENCLAVE_SHORT_ID_LENGTH + +typedef struct _IMAGE_ENCLAVE_CONFIG32 { + ULONG Size; + ULONG MinimumRequiredConfigSize; + ULONG PolicyFlags; + ULONG NumberOfImports; + ULONG ImportList; + ULONG ImportEntrySize; + UCHAR FamilyID[IMAGE_ENCLAVE_SHORT_ID_LENGTH]; + UCHAR ImageID[IMAGE_ENCLAVE_SHORT_ID_LENGTH]; + ULONG ImageVersion; + ULONG SecurityVersion; + ULONG EnclaveSize; + ULONG NumberOfThreads; + ULONG EnclaveFlags; +} IMAGE_ENCLAVE_CONFIG32; + +typedef struct _IMAGE_ENCLAVE_CONFIG64 { + ULONG Size; + ULONG MinimumRequiredConfigSize; + ULONG PolicyFlags; + ULONG NumberOfImports; + ULONG ImportList; + ULONG ImportEntrySize; + UCHAR FamilyID[IMAGE_ENCLAVE_SHORT_ID_LENGTH]; + UCHAR ImageID[IMAGE_ENCLAVE_SHORT_ID_LENGTH]; + ULONG ImageVersion; + ULONG SecurityVersion; + ULONGLONG EnclaveSize; + ULONG NumberOfThreads; + ULONG EnclaveFlags; +} IMAGE_ENCLAVE_CONFIG64; + +#define IMAGE_ENCLAVE_POLICY_DEBUGGABLE 0x00000001 +#define IMAGE_ENCLAVE_POLICY_STRICT_MEMORY 0x00000002 + +#define IMAGE_ENCLAVE_FLAG_PRIMARY_IMAGE 0x00000001 + +typedef struct _IMAGE_ENCLAVE_IMPORT { + ULONG MatchType; + ULONG MinimumSecurityVersion; + UCHAR UniqueOrAuthorID[IMAGE_ENCLAVE_LONG_ID_LENGTH]; + UCHAR FamilyID[IMAGE_ENCLAVE_SHORT_ID_LENGTH]; + UCHAR ImageID[IMAGE_ENCLAVE_SHORT_ID_LENGTH]; + ULONG ImportName; + ULONG Reserved; +} IMAGE_ENCLAVE_IMPORT; + +#define IMAGE_ENCLAVE_IMPORT_MATCH_NONE 0x00000000 +#define IMAGE_ENCLAVE_IMPORT_MATCH_UNIQUE_ID 0x00000001 +#define IMAGE_ENCLAVE_IMPORT_MATCH_AUTHOR_ID 0x00000002 +#define IMAGE_ENCLAVE_IMPORT_MATCH_FAMILY_ID 0x00000003 +#define IMAGE_ENCLAVE_IMPORT_MATCH_IMAGE_ID 0x00000004 + +// +// Security Format +// + +#define WIN_CERT_REVISION_1_0 0x0100 +#define WIN_CERT_REVISION_2_0 0x0200 + +enum WIN_CERT_TYPE : USHORT { + X509 = 0x0001, // bCertificate contains an X.509 Certificate + PKCS_SIGNED_DATA = 0x0002, // bCertificate contains a PKCS SignedData structure + RESERVED_1 = 0x0003, // Reserved + TS_STACK_SIGNED = 0x0004, // Terminal Server Protocol Stack Certificate signing +}; + +typedef struct _WIN_CERTIFICATE { + ULONG dwLength; + USHORT wRevision; + WIN_CERT_TYPE wCertificateType; + CHAR bCertificate[dwLength - 8]; +} WIN_CERTIFICATE; + +// +// Debug Format +// + +enum IMAGE_DEBUG_TYPE : ULONG { + 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. + BBT = 10, + CLSID = 11, // Reserved. + VC_FEATURE = 12, + POGO = 13, + ILTCG = 14, + MPX = 15, + REPRO = 16, // PE determinism or reproducibility. + EMBEDDED_PORTABLE_PDB = 17, // Debugging information is embedded in the PE file at location specified by PointerToRawData. + SPGO = 18, + PDBCHECKSUM = 19, // Stores crypto hash for the content of the symbol file used to build the PE/COFF file. + EX_DLLCHARACTERISTICS = 20, // Extended DLL characteristics bits. + PERFMAP = 21, +}; + +enum IMAGE_DLLCHARACTERISTICS_EX { + CET_COMPAT = 0x01, + CET_COMPAT_STRICT_MODE = 0x02, + CET_SET_CONTEXT_IP_VALIDATION_RELAXED_MODE = 0x04, + CET_DYNAMIC_APIS_ALLOW_IN_PROC = 0x08, + CET_RESERVED_1 = 0x10, + CET_RESERVED_2 = 0x20, + FORWARD_CFI_COMPAT = 0x40, + HOTPATCH_COMPATIBLE = 0x80, +}; + +typedef struct _IMAGE_DEBUG_DIRECTORY { + ULONG Characteristics; + ULONG TimeDateStamp; + USHORT MajorVersion; + USHORT MinorVersion; + IMAGE_DEBUG_TYPE Type; + ULONG SizeOfData; + ULONG AddressOfRawData; + ULONG PointerToRawData; +} IMAGE_DEBUG_DIRECTORY; + +typedef struct _IMAGE_COFF_SYMBOLS_HEADER { + ULONG NumberOfSymbols; + ULONG LvaToFirstSymbol; + ULONG NumberOfLinenumbers; + ULONG LvaToFirstLinenumber; + ULONG RvaToFirstByteOfCode; + ULONG RvaToLastByteOfCode; + ULONG RvaToFirstByteOfData; + ULONG RvaToLastByteOfData; +} IMAGE_COFF_SYMBOLS_HEADER; + +#define CVINFO_PDB70_CVSIGNATURE 0x53445352 // "RSDS" +#define CVINFO_PDB20_CVSIGNATURE 0x3031424e // "NB10" +#define CVINFO_CV50_CVSIGNATURE 0x3131424e // "NB11" +#define CVINFO_CV41_CVSIGNATURE 0x3930424e // "NB09" +#define CVINFO_MTOC_CVSIGNATURE 0x434f544d // "MTOC" + +typedef struct _CV_HEADER { + ULONG Signature; + ULONG Offset; +} CV_HEADER; + +typedef struct _CV_INFO_PDB20 { + CV_HEADER CvHeader; + ULONG Signature; + ULONG Age; + CHAR PdbFileName[]; +} CV_INFO_PDB20; + +typedef struct _CV_INFO_PDB70 { + ULONG CvSignature; + CHAR Signature[16]; + ULONG Age; + CHAR PdbFileName[]; +} CV_INFO_PDB70; + +typedef struct _CV_INFO_MTOC { + ULONG CvSignature; + BYTE Signature[16]; + BYTE PdbFileName[1]; +} CV_INFO_MTOC; + +#define FRAME_FPO 0 +#define FRAME_TRAP 1 +#define FRAME_TSS 2 +#define FRAME_NONFPO 3 + +typedef struct _FPO_DATA { + ULONG ulOffStart; // offset 1st byte of function code + ULONG cbProcSize; // # bytes in function + ULONG cdwLocals; // # bytes in locals/4 + USHORT cdwParams; // # bytes in params/4 + USHORT cbProlog : 8; // # bytes in prolog + USHORT cbRegs : 3; // # regs saved + USHORT fHasSEH : 1; // TRUE if SEH in func + USHORT fUseBP : 1; // TRUE if EBP has been allocated + USHORT reserved : 1; // reserved for future use + USHORT cbFrame : 2; // frame type +} FPO_DATA; + +#define IMAGE_DEBUG_MISC_EXENAME 1 + +typedef struct _IMAGE_DEBUG_MISC { + ULONG DataType; // type of misc data, see defines + ULONG Length; // total length of record, rounded to four + // byte multiple. + BOOLEAN Unicode; // TRUE if data is unicode string + UCHAR Reserved[ 3 ]; +// UCHAR Data[ 1 ]; // Actual data +} IMAGE_DEBUG_MISC; + +#define IMAGE_DEBUG_POGO_SIGNATURE_ZERO 0x00000000 +#define IMAGE_DEBUG_POGO_SIGNATURE_LTCG 0x4C544347 +#define IMAGE_DEBUG_POGO_SIGNATURE_PGU 0x50475500 + +typedef struct _VC_FEATURE { + ULONG PreVC11; + ULONG CCpp; + ULONG Gs; + ULONG Sdl; + ULONG GuardN; +} VC_FEATURE; + +// +// Function table extracted from MIPS/ALPHA/IA64 images. Does not contain +// information needed only for runtime support. Just those fields for +// each entry needed by a debugger. +// + +typedef struct _IMAGE_FUNCTION_ENTRY { + ULONG StartingAddress; + ULONG EndingAddress; + ULONG EndOfPrologue; +} IMAGE_FUNCTION_ENTRY; + +typedef struct _IMAGE_FUNCTION_ENTRY64 { + ULONGLONG StartingAddress; + ULONGLONG EndingAddress; + union { + ULONGLONG EndOfPrologue; + ULONGLONG UnwindInfoAddress; + }; +} IMAGE_FUNCTION_ENTRY64; + +// +// Debugging information can be stripped from an image file and placed +// in a separate .DBG file, whose file name part is the same as the +// image file name part (e.g. symbols for CMD.EXE could be stripped +// and placed in CMD.DBG). This is indicated by the IMAGE_FILE_DEBUG_STRIPPED +// flag in the Characteristics field of the file header. The beginning of +// the .DBG file contains the following structure which captures certain +// information from the image file. This allows a debug to proceed even if +// the original image file is not accessable. This header is followed by +// zero of more IMAGE_SECTION_HEADER structures, followed by zero or more +// IMAGE_DEBUG_DIRECTORY structures. The latter structures and those in +// the image file contain file offsets relative to the beginning of the +// .DBG file. +// +// If symbols have been stripped from an image, the IMAGE_DEBUG_MISC structure +// is left in the image file, but not mapped. This allows a debugger to +// compute the name of the .DBG file, from the name of the image in the +// IMAGE_DEBUG_MISC structure. +// + +typedef struct _IMAGE_SEPARATE_DEBUG_HEADER { + USHORT Signature; + USHORT Flags; + USHORT Machine; + USHORT Characteristics; + ULONG TimeDateStamp; + ULONG CheckSum; + ULONG ImageBase; + ULONG SizeOfImage; + ULONG NumberOfSections; + ULONG ExportedNamesSize; + ULONG DebugDirectorySize; + ULONG SectionAlignment; + ULONG Reserved[2]; +} IMAGE_SEPARATE_DEBUG_HEADER; + +typedef struct _NON_PAGED_DEBUG_INFO { + USHORT Signature; + USHORT Flags; + ULONG Size; + USHORT Machine; + USHORT Characteristics; + ULONG TimeDateStamp; + ULONG CheckSum; + ULONG SizeOfImage; + ULONGLONG ImageBase; + //DebugDirectorySize + //IMAGE_DEBUG_DIRECTORY +} NON_PAGED_DEBUG_INFO; + +#define IMAGE_SEPARATE_DEBUG_SIGNATURE 0x4449 // DI +#define NON_PAGED_DEBUG_SIGNATURE 0x4E49 // NI + +#define IMAGE_SEPARATE_DEBUG_FLAGS_MASK 0x8000 +#define IMAGE_SEPARATE_DEBUG_MISMATCH 0x8000 // when DBG was updated, the + // old checksum didn't match. + +// +// The .arch section is made up of headers, each describing an amask position/value +// pointing to an array of IMAGE_ARCHITECTURE_ENTRY's. Each "array" (both the header +// and entry arrays) are terminiated by a quadword of 0xffffffffL. +// +// NOTE: There may be quadwords of 0 sprinkled around and must be skipped. +// + +typedef struct _ImageArchitectureHeader { + unsigned int AmaskValue: 1; // 1 -> code section depends on mask bit + // 0 -> new instruction depends on mask bit + int _:7; // MBZ + unsigned int AmaskShift: 8; // Amask bit in question for this fixup + int _:16; // MBZ + ULONG FirstEntryRVA; // RVA into .arch section to array of ARCHITECTURE_ENTRY's +} IMAGE_ARCHITECTURE_HEADER; + +typedef struct _ImageArchitectureEntry { + ULONG FixupInstRVA; // RVA of instruction to fixup + ULONG NewInst; // fixup instruction (see alphaops.h) +} IMAGE_ARCHITECTURE_ENTRY; + +// The following structure defines the new import object. Note the values of the first two fields, +// which must be set as stated in order to differentiate old and new import members. +// Following this structure, the linker emits two null-terminated strings used to recreate the +// import at the time of use. The first string is the import's name, the second is the dll's name. + +#define IMPORT_OBJECT_HDR_SIG2 0xffff + +enum IMPORT_OBJECT_TYPE { + IMPORT_OBJECT_CODE = 0, + IMPORT_OBJECT_DATA = 1, + IMPORT_OBJECT_CONST = 2, +}; + +enum IMPORT_OBJECT_NAME_TYPE { + IMPORT_OBJECT_ORDINAL = 0, // Import by ordinal + IMPORT_OBJECT_NAME = 1, // Import name == public symbol name. + IMPORT_OBJECT_NAME_NO_PREFIX = 2, // Import name == public symbol name skipping leading ?, @, or optionally _. + IMPORT_OBJECT_NAME_UNDECORATE = 3, // Import name == public symbol name skipping leading ?, @, or optionally _ + // and truncating at first @. + IMPORT_OBJECT_NAME_EXPORTAS = 4, // Import name == a name is explicitly provided after the DLL name. +}; + +typedef struct IMPORT_OBJECT_HEADER { + USHORT Sig1; // Must be IMAGE_FILE_MACHINE_UNKNOWN + USHORT Sig2; // Must be IMPORT_OBJECT_HDR_SIG2. + USHORT Version; + USHORT Machine; + ULONG TimeDateStamp; // Time/date stamp + ULONG SizeOfData; // particularly useful for incremental links + + union { + USHORT Ordinal; // if grf & IMPORT_OBJECT_ORDINAL + USHORT Hint; + }; + + IMPORT_OBJECT_TYPE Type : 2; // IMPORT_TYPE + IMPORT_OBJECT_NAME_TYPE NameType : 3; // IMPORT_NAME_TYPE + USHORT Reserved : 11; // Reserved. Must be zero. +} IMPORT_OBJECT_HEADER; + +// +// COM Format. +// + +// COM+ Header entry point flags. +enum COMIMAGE_FLAGS : ULONG { + ILONLY = 0x00000001, + 32BITREQUIRED = 0x00000002, + IL_LIBRARY = 0x00000004, + STRONGNAMESIGNED = 0x00000008, + NATIVE_ENTRYPOINT = 0x00000010, + TRACKDEBUGDATA = 0x00010000, + 32BITPREFERRED = 0x00020000 +}; + +// Version flags for image. +#define COR_VERSION_MAJOR_V2 2 +#define COR_VERSION_MAJOR COR_VERSION_MAJOR_V2 +#define COR_VERSION_MINOR 5 +#define COR_DELETED_NAME_LENGTH 8 +#define COR_VTABLEGAP_NAME_LENGTH 8 + +// Maximum size of a NativeType descriptor. +#define NATIVE_TYPE_MAX_CB 1 +#define COR_ILMETHOD_SECT_SMALL_MAX_DATASIZE 0xFF + +// #defines for the MIH FLAGS +#define IMAGE_COR_MIH_METHODRVA 0x01 +#define IMAGE_COR_MIH_EHRVA 0x02 +#define IMAGE_COR_MIH_BASICBLOCK 0x08 + +// V-table constants +#define COR_VTABLE_32BIT 0x01 // V-table slots are 32-bits in size. +#define COR_VTABLE_64BIT 0x02 // V-table slots are 64-bits in size. +#define COR_VTABLE_FROM_UNMANAGED 0x04 // If set, transition from unmanaged. +#define COR_VTABLE_FROM_UNMANAGED_RETAIN_APPDOMAIN 0x08 // If set, transition from unmanaged with keeping the current appdomain. +#define COR_VTABLE_CALL_MOST_DERIVED 0x10 // Call most derived method described by + +// EATJ constants +#define IMAGE_COR_EATJ_THUNK_SIZE 32 // Size of a jump thunk reserved range. + +// Max name lengths +#define MAX_CLASS_NAME 1024 +#define MAX_PACKAGE_NAME 1024 + +// CLR 2.0 header structure. +typedef struct _IMAGE_COR20_HEADER { + // Header versioning + ULONG cb; + USHORT MajorRuntimeVersion; + USHORT MinorRuntimeVersion; + + // Symbol table and startup information + IMAGE_DATA_DIRECTORY MetaData; + ULONG Flags; + + // If COMIMAGE_FLAGS_NATIVE_ENTRYPOINT is not set, EntryPointToken represents a managed entrypoint. + // If COMIMAGE_FLAGS_NATIVE_ENTRYPOINT is set, EntryPointRVA represents an RVA to a native entrypoint. + union { + ULONG EntryPointToken; + ULONG EntryPointRVA; + }; + + // Binding information + IMAGE_DATA_DIRECTORY Resources; + IMAGE_DATA_DIRECTORY StrongNameSignature; + + // Regular fixup and binding information + IMAGE_DATA_DIRECTORY CodeManagerTable; + IMAGE_DATA_DIRECTORY VTableFixups; + IMAGE_DATA_DIRECTORY ExportAddressTableJumps; + + // Precompiled image info (internal use only - set to zero) + IMAGE_DATA_DIRECTORY ManagedNativeHeader; +} IMAGE_COR20_HEADER; + +typedef struct _IMAGE_COR20_METADATA { + ULONG Magic; + USHORT MajorVersion; + USHORT MinorVersion; + ULONG Reserved; + ULONG Length; + CHAR Version[Length]; + USHORT Flags; + USHORT NumberOfStreams; +} IMAGE_COR20_METADATA; + +typedef struct _IMAGE_COR20_STREAM_HEADER { + ULONG Offset; + ULONG Size; + CHAR Name[]; +} IMAGE_COR20_STREAM_HEADER; +""" # noqa: E501 + +c_pe = cstruct().load(c_pe_def) diff --git a/dissect/executable/pe/c_pe.pyi b/dissect/executable/pe/c_pe.pyi new file mode 100644 index 0000000..a1e7fa6 --- /dev/null +++ b/dissect/executable/pe/c_pe.pyi @@ -0,0 +1,2997 @@ +# Generated by cstruct-stubgen +from typing import BinaryIO, Literal, overload + +import dissect.cstruct as __cs__ +from typing_extensions import TypeAlias + +class _c_pe(__cs__.cstruct): + IMAGE_DOS_SIGNATURE: Literal[23117] = ... + IMAGE_OS2_SIGNATURE: Literal[17742] = ... + IMAGE_OS2_SIGNATURE_LE: Literal[17740] = ... + IMAGE_VXD_SIGNATURE: Literal[17740] = ... + IMAGE_NT_SIGNATURE: Literal[17744] = ... + IMAGE_NUMBEROF_DIRECTORY_ENTRIES: Literal[16] = ... + IMAGE_NT_OPTIONAL_HDR32_MAGIC: Literal[267] = ... + IMAGE_NT_OPTIONAL_HDR64_MAGIC: Literal[523] = ... + IMAGE_ROM_OPTIONAL_HDR_MAGIC: Literal[263] = ... + IMAGE_SIZEOF_SHORT_NAME: Literal[8] = ... + IMAGE_ARCHIVE_START_SIZE: Literal[8] = ... + IMAGE_ARCHIVE_START: Literal['b"!'] = ... + IMAGE_ARCHIVE_END: Literal['b"`'] = ... + IMAGE_ARCHIVE_PAD: Literal['b"'] = ... + IMAGE_ARCHIVE_LINKER_MEMBER: Literal[b"/ "] = ... + IMAGE_ARCHIVE_LONGNAMES_MEMBER: Literal[b"// "] = ... + IMAGE_ORDINAL_FLAG64: Literal[9223372036854775808] = ... + IMAGE_ORDINAL_FLAG32: Literal[2147483648] = ... + IMAGE_DYNAMIC_RELOCATION_GUARD_RF_PROLOGUE: Literal[1] = ... + IMAGE_DYNAMIC_RELOCATION_GUARD_RF_EPILOGUE: Literal[2] = ... + IMAGE_DYNAMIC_RELOCATION_GUARD_IMPORT_CONTROL_TRANSFER: Literal[3] = ... + IMAGE_DYNAMIC_RELOCATION_GUARD_INDIR_CONTROL_TRANSFER: Literal[4] = ... + IMAGE_DYNAMIC_RELOCATION_GUARD_SWITCHTABLE_BRANCH: Literal[5] = ... + IMAGE_DYNAMIC_RELOCATION_ARM64X: Literal[6] = ... + IMAGE_DYNAMIC_RELOCATION_FUNCTION_OVERRIDE: Literal[7] = ... + IMAGE_DYNAMIC_RELOCATION_ARM64_KERNEL_IMPORT_CALL_TRANSFER: Literal[8] = ... + IMAGE_DYNAMIC_RELOCATION_MM_SHARED_USER_DATA_VA: Literal[2147352576] = ... + IMAGE_DYNAMIC_RELOCATION_KI_USER_SHARED_DATA64: Literal[18446734727860715520] = ... + IMAGE_FUNCTION_OVERRIDE_INVALID: Literal[0] = ... + IMAGE_FUNCTION_OVERRIDE_X64_REL32: Literal[1] = ... + IMAGE_FUNCTION_OVERRIDE_ARM64_BRANCH26: Literal[2] = ... + IMAGE_FUNCTION_OVERRIDE_ARM64_THUNK: Literal[3] = ... + IMAGE_GUARD_CF_FUNCTION_TABLE_SIZE_MASK: Literal[4026531840] = ... + IMAGE_GUARD_CF_FUNCTION_TABLE_SIZE_SHIFT: Literal[28] = ... + IMAGE_DVRT_ARM64X_FIXUP_TYPE_ZEROFILL: Literal[0] = ... + IMAGE_DVRT_ARM64X_FIXUP_TYPE_VALUE: Literal[1] = ... + IMAGE_DVRT_ARM64X_FIXUP_TYPE_DELTA: Literal[2] = ... + IMAGE_DVRT_ARM64X_FIXUP_SIZE_2BYTES: Literal[1] = ... + IMAGE_DVRT_ARM64X_FIXUP_SIZE_4BYTES: Literal[2] = ... + IMAGE_DVRT_ARM64X_FIXUP_SIZE_8BYTES: Literal[3] = ... + IMAGE_HOT_PATCH_BASE_OBLIGATORY: Literal[1] = ... + IMAGE_HOT_PATCH_BASE_CAN_ROLL_BACK: Literal[2] = ... + IMAGE_HOT_PATCH_BASE_MACHINE_I386: Literal[4] = ... + IMAGE_HOT_PATCH_BASE_MACHINE_ARM64: Literal[8] = ... + IMAGE_HOT_PATCH_BASE_MACHINE_AMD64: Literal[16] = ... + IMAGE_HOT_PATCH_CHUNK_INVERSE: Literal[2147483648] = ... + IMAGE_HOT_PATCH_CHUNK_OBLIGATORY: Literal[1073741824] = ... + IMAGE_HOT_PATCH_CHUNK_RESERVED: Literal[1072705536] = ... + IMAGE_HOT_PATCH_CHUNK_TYPE: Literal[1032192] = ... + IMAGE_HOT_PATCH_CHUNK_SOURCE_RVA: Literal[32768] = ... + IMAGE_HOT_PATCH_CHUNK_TARGET_RVA: Literal[16384] = ... + IMAGE_HOT_PATCH_CHUNK_SIZE: Literal[4095] = ... + IMAGE_GUARD_FLAG_FID_SUPPRESSED: Literal[1] = ... + IMAGE_GUARD_FLAG_EXPORT_SUPPRESSED: Literal[2] = ... + IMAGE_GUARD_FLAG_FID_LANGEXCPTHANDLER: Literal[4] = ... + IMAGE_GUARD_FLAG_FID_XFG: Literal[8] = ... + IMAGE_ENCLAVE_LONG_ID_LENGTH: Literal["ENCLAVE_LONG_ID_LENGTH"] = ... + IMAGE_ENCLAVE_SHORT_ID_LENGTH: Literal["ENCLAVE_SHORT_ID_LENGTH"] = ... + IMAGE_ENCLAVE_POLICY_DEBUGGABLE: Literal[1] = ... + IMAGE_ENCLAVE_POLICY_STRICT_MEMORY: Literal[2] = ... + IMAGE_ENCLAVE_FLAG_PRIMARY_IMAGE: Literal[1] = ... + IMAGE_ENCLAVE_IMPORT_MATCH_NONE: Literal[0] = ... + IMAGE_ENCLAVE_IMPORT_MATCH_UNIQUE_ID: Literal[1] = ... + IMAGE_ENCLAVE_IMPORT_MATCH_AUTHOR_ID: Literal[2] = ... + IMAGE_ENCLAVE_IMPORT_MATCH_FAMILY_ID: Literal[3] = ... + IMAGE_ENCLAVE_IMPORT_MATCH_IMAGE_ID: Literal[4] = ... + WIN_CERT_REVISION_1_0: Literal[256] = ... + WIN_CERT_REVISION_2_0: Literal[512] = ... + CVINFO_PDB70_CVSIGNATURE: Literal[1396986706] = ... + CVINFO_PDB20_CVSIGNATURE: Literal[808534606] = ... + CVINFO_CV50_CVSIGNATURE: Literal[825311822] = ... + CVINFO_CV41_CVSIGNATURE: Literal[959464014] = ... + CVINFO_MTOC_CVSIGNATURE: Literal[1129272397] = ... + FRAME_FPO: Literal[0] = ... + FRAME_TRAP: Literal[1] = ... + FRAME_TSS: Literal[2] = ... + FRAME_NONFPO: Literal[3] = ... + IMAGE_DEBUG_MISC_EXENAME: Literal[1] = ... + IMAGE_DEBUG_POGO_SIGNATURE_ZERO: Literal[0] = ... + IMAGE_DEBUG_POGO_SIGNATURE_LTCG: Literal[1280590663] = ... + IMAGE_DEBUG_POGO_SIGNATURE_PGU: Literal[1346852096] = ... + IMAGE_SEPARATE_DEBUG_SIGNATURE: Literal[17481] = ... + NON_PAGED_DEBUG_SIGNATURE: Literal[20041] = ... + IMAGE_SEPARATE_DEBUG_FLAGS_MASK: Literal[32768] = ... + IMAGE_SEPARATE_DEBUG_MISMATCH: Literal[32768] = ... + IMPORT_OBJECT_HDR_SIG2: Literal[65535] = ... + COR_VERSION_MAJOR_V2: Literal[2] = ... + COR_VERSION_MAJOR: Literal[2] = ... + COR_VERSION_MINOR: Literal[5] = ... + COR_DELETED_NAME_LENGTH: Literal[8] = ... + COR_VTABLEGAP_NAME_LENGTH: Literal[8] = ... + NATIVE_TYPE_MAX_CB: Literal[1] = ... + COR_ILMETHOD_SECT_SMALL_MAX_DATASIZE: Literal[255] = ... + IMAGE_COR_MIH_METHODRVA: Literal[1] = ... + IMAGE_COR_MIH_EHRVA: Literal[2] = ... + IMAGE_COR_MIH_BASICBLOCK: Literal[8] = ... + COR_VTABLE_32BIT: Literal[1] = ... + COR_VTABLE_64BIT: Literal[2] = ... + COR_VTABLE_FROM_UNMANAGED: Literal[4] = ... + COR_VTABLE_FROM_UNMANAGED_RETAIN_APPDOMAIN: Literal[8] = ... + COR_VTABLE_CALL_MOST_DERIVED: Literal[16] = ... + IMAGE_COR_EATJ_THUNK_SIZE: Literal[32] = ... + MAX_CLASS_NAME: Literal[1024] = ... + MAX_PACKAGE_NAME: Literal[1024] = ... + BOOLEAN: TypeAlias = _c_pe.uint8 + class _IMAGE_DOS_HEADER(__cs__.Structure): + e_magic: _c_pe.uint16 + e_cblp: _c_pe.uint16 + e_cp: _c_pe.uint16 + e_crlc: _c_pe.uint16 + e_cparhdr: _c_pe.uint16 + e_minalloc: _c_pe.uint16 + e_maxalloc: _c_pe.uint16 + e_ss: _c_pe.uint16 + e_sp: _c_pe.uint16 + e_csum: _c_pe.uint16 + e_ip: _c_pe.uint16 + e_cs: _c_pe.uint16 + e_lfarlc: _c_pe.uint16 + e_ovno: _c_pe.uint16 + e_res: __cs__.Array[_c_pe.uint16] + e_oemid: _c_pe.uint16 + e_oeminfo: _c_pe.uint16 + e_res2: __cs__.Array[_c_pe.uint16] + e_lfanew: _c_pe.int32 + @overload + def __init__( + self, + e_magic: _c_pe.uint16 | None = ..., + e_cblp: _c_pe.uint16 | None = ..., + e_cp: _c_pe.uint16 | None = ..., + e_crlc: _c_pe.uint16 | None = ..., + e_cparhdr: _c_pe.uint16 | None = ..., + e_minalloc: _c_pe.uint16 | None = ..., + e_maxalloc: _c_pe.uint16 | None = ..., + e_ss: _c_pe.uint16 | None = ..., + e_sp: _c_pe.uint16 | None = ..., + e_csum: _c_pe.uint16 | None = ..., + e_ip: _c_pe.uint16 | None = ..., + e_cs: _c_pe.uint16 | None = ..., + e_lfarlc: _c_pe.uint16 | None = ..., + e_ovno: _c_pe.uint16 | None = ..., + e_res: __cs__.Array[_c_pe.uint16] | None = ..., + e_oemid: _c_pe.uint16 | None = ..., + e_oeminfo: _c_pe.uint16 | None = ..., + e_res2: __cs__.Array[_c_pe.uint16] | None = ..., + e_lfanew: _c_pe.int32 | None = ..., + ): ... + @overload + def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... + + IMAGE_DOS_HEADER: TypeAlias = _IMAGE_DOS_HEADER + class _IMAGE_OS2_HEADER(__cs__.Structure): + ne_magic: _c_pe.uint16 + ne_ver: _c_pe.char + ne_rev: _c_pe.char + ne_enttab: _c_pe.uint16 + ne_cbenttab: _c_pe.uint16 + ne_crc: _c_pe.int32 + ne_flags: _c_pe.uint16 + ne_autodata: _c_pe.uint16 + ne_heap: _c_pe.uint16 + ne_stack: _c_pe.uint16 + ne_csip: _c_pe.int32 + ne_sssp: _c_pe.int32 + ne_cseg: _c_pe.uint16 + ne_cmod: _c_pe.uint16 + ne_cbnrestab: _c_pe.uint16 + ne_segtab: _c_pe.uint16 + ne_rsrctab: _c_pe.uint16 + ne_restab: _c_pe.uint16 + ne_modtab: _c_pe.uint16 + ne_imptab: _c_pe.uint16 + ne_nrestab: _c_pe.int32 + ne_cmovent: _c_pe.uint16 + ne_align: _c_pe.uint16 + ne_cres: _c_pe.uint16 + ne_exetyp: _c_pe.uint8 + ne_flagsothers: _c_pe.uint8 + ne_pretthunks: _c_pe.uint16 + ne_psegrefbytes: _c_pe.uint16 + ne_swaparea: _c_pe.uint16 + ne_expver: _c_pe.uint16 + @overload + def __init__( + self, + ne_magic: _c_pe.uint16 | None = ..., + ne_ver: _c_pe.char | None = ..., + ne_rev: _c_pe.char | None = ..., + ne_enttab: _c_pe.uint16 | None = ..., + ne_cbenttab: _c_pe.uint16 | None = ..., + ne_crc: _c_pe.int32 | None = ..., + ne_flags: _c_pe.uint16 | None = ..., + ne_autodata: _c_pe.uint16 | None = ..., + ne_heap: _c_pe.uint16 | None = ..., + ne_stack: _c_pe.uint16 | None = ..., + ne_csip: _c_pe.int32 | None = ..., + ne_sssp: _c_pe.int32 | None = ..., + ne_cseg: _c_pe.uint16 | None = ..., + ne_cmod: _c_pe.uint16 | None = ..., + ne_cbnrestab: _c_pe.uint16 | None = ..., + ne_segtab: _c_pe.uint16 | None = ..., + ne_rsrctab: _c_pe.uint16 | None = ..., + ne_restab: _c_pe.uint16 | None = ..., + ne_modtab: _c_pe.uint16 | None = ..., + ne_imptab: _c_pe.uint16 | None = ..., + ne_nrestab: _c_pe.int32 | None = ..., + ne_cmovent: _c_pe.uint16 | None = ..., + ne_align: _c_pe.uint16 | None = ..., + ne_cres: _c_pe.uint16 | None = ..., + ne_exetyp: _c_pe.uint8 | None = ..., + ne_flagsothers: _c_pe.uint8 | None = ..., + ne_pretthunks: _c_pe.uint16 | None = ..., + ne_psegrefbytes: _c_pe.uint16 | None = ..., + ne_swaparea: _c_pe.uint16 | None = ..., + ne_expver: _c_pe.uint16 | None = ..., + ): ... + @overload + def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... + + IMAGE_OS2_HEADER: TypeAlias = _IMAGE_OS2_HEADER + class _IMAGE_VXD_HEADER(__cs__.Structure): + e32_magic: _c_pe.uint16 + e32_border: _c_pe.uint8 + e32_worder: _c_pe.uint8 + e32_level: _c_pe.uint32 + e32_cpu: _c_pe.uint16 + e32_os: _c_pe.uint16 + e32_ver: _c_pe.uint32 + e32_mflags: _c_pe.uint32 + e32_mpages: _c_pe.uint32 + e32_startobj: _c_pe.uint32 + e32_eip: _c_pe.uint32 + e32_stackobj: _c_pe.uint32 + e32_esp: _c_pe.uint32 + e32_pagesize: _c_pe.uint32 + e32_lastpagesize: _c_pe.uint32 + e32_fixupsize: _c_pe.uint32 + e32_fixupsum: _c_pe.uint32 + e32_ldrsize: _c_pe.uint32 + e32_ldrsum: _c_pe.uint32 + e32_objtab: _c_pe.uint32 + e32_objcnt: _c_pe.uint32 + e32_objmap: _c_pe.uint32 + e32_itermap: _c_pe.uint32 + e32_rsrctab: _c_pe.uint32 + e32_rsrccnt: _c_pe.uint32 + e32_restab: _c_pe.uint32 + e32_enttab: _c_pe.uint32 + e32_dirtab: _c_pe.uint32 + e32_dircnt: _c_pe.uint32 + e32_fpagetab: _c_pe.uint32 + e32_frectab: _c_pe.uint32 + e32_impmod: _c_pe.uint32 + e32_impmodcnt: _c_pe.uint32 + e32_impproc: _c_pe.uint32 + e32_pagesum: _c_pe.uint32 + e32_datapage: _c_pe.uint32 + e32_preload: _c_pe.uint32 + e32_nrestab: _c_pe.uint32 + e32_cbnrestab: _c_pe.uint32 + e32_nressum: _c_pe.uint32 + e32_autodata: _c_pe.uint32 + e32_debuginfo: _c_pe.uint32 + e32_debuglen: _c_pe.uint32 + e32_instpreload: _c_pe.uint32 + e32_instdemand: _c_pe.uint32 + e32_heapsize: _c_pe.uint32 + e32_res3: __cs__.Array[_c_pe.uint8] + e32_winresoff: _c_pe.uint32 + e32_winreslen: _c_pe.uint32 + e32_devid: _c_pe.uint16 + e32_ddkver: _c_pe.uint16 + @overload + def __init__( + self, + e32_magic: _c_pe.uint16 | None = ..., + e32_border: _c_pe.uint8 | None = ..., + e32_worder: _c_pe.uint8 | None = ..., + e32_level: _c_pe.uint32 | None = ..., + e32_cpu: _c_pe.uint16 | None = ..., + e32_os: _c_pe.uint16 | None = ..., + e32_ver: _c_pe.uint32 | None = ..., + e32_mflags: _c_pe.uint32 | None = ..., + e32_mpages: _c_pe.uint32 | None = ..., + e32_startobj: _c_pe.uint32 | None = ..., + e32_eip: _c_pe.uint32 | None = ..., + e32_stackobj: _c_pe.uint32 | None = ..., + e32_esp: _c_pe.uint32 | None = ..., + e32_pagesize: _c_pe.uint32 | None = ..., + e32_lastpagesize: _c_pe.uint32 | None = ..., + e32_fixupsize: _c_pe.uint32 | None = ..., + e32_fixupsum: _c_pe.uint32 | None = ..., + e32_ldrsize: _c_pe.uint32 | None = ..., + e32_ldrsum: _c_pe.uint32 | None = ..., + e32_objtab: _c_pe.uint32 | None = ..., + e32_objcnt: _c_pe.uint32 | None = ..., + e32_objmap: _c_pe.uint32 | None = ..., + e32_itermap: _c_pe.uint32 | None = ..., + e32_rsrctab: _c_pe.uint32 | None = ..., + e32_rsrccnt: _c_pe.uint32 | None = ..., + e32_restab: _c_pe.uint32 | None = ..., + e32_enttab: _c_pe.uint32 | None = ..., + e32_dirtab: _c_pe.uint32 | None = ..., + e32_dircnt: _c_pe.uint32 | None = ..., + e32_fpagetab: _c_pe.uint32 | None = ..., + e32_frectab: _c_pe.uint32 | None = ..., + e32_impmod: _c_pe.uint32 | None = ..., + e32_impmodcnt: _c_pe.uint32 | None = ..., + e32_impproc: _c_pe.uint32 | None = ..., + e32_pagesum: _c_pe.uint32 | None = ..., + e32_datapage: _c_pe.uint32 | None = ..., + e32_preload: _c_pe.uint32 | None = ..., + e32_nrestab: _c_pe.uint32 | None = ..., + e32_cbnrestab: _c_pe.uint32 | None = ..., + e32_nressum: _c_pe.uint32 | None = ..., + e32_autodata: _c_pe.uint32 | None = ..., + e32_debuginfo: _c_pe.uint32 | None = ..., + e32_debuglen: _c_pe.uint32 | None = ..., + e32_instpreload: _c_pe.uint32 | None = ..., + e32_instdemand: _c_pe.uint32 | None = ..., + e32_heapsize: _c_pe.uint32 | None = ..., + e32_res3: __cs__.Array[_c_pe.uint8] | None = ..., + e32_winresoff: _c_pe.uint32 | None = ..., + e32_winreslen: _c_pe.uint32 | None = ..., + e32_devid: _c_pe.uint16 | None = ..., + e32_ddkver: _c_pe.uint16 | None = ..., + ): ... + @overload + def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... + + IMAGE_VXD_HEADER: TypeAlias = _IMAGE_VXD_HEADER + class IMAGE_FILE(__cs__.Flag): + RELOCS_STRIPPED = ... + EXECUTABLE_IMAGE = ... + LINE_NUMS_STRIPPED = ... + LOCAL_SYMS_STRIPPED = ... + AGGRESSIVE_WS_TRIM = ... + LARGE_ADDRESS_AWARE = ... + BYTES_REVERSED_LO = ... + "32BIT_MACHINE = ..." + DEBUG_STRIPPED = ... + REMOVABLE_RUN_FROM_SWAP = ... + NET_RUN_FROM_SWAP = ... + SYSTEM = ... + DLL = ... + UP_SYSTEM_ONLY = ... + BYTES_REVERSED_HI = ... + + class IMAGE_FILE_MACHINE(__cs__.Enum): + UNKNOWN = ... + TARGET_HOST = ... + I386 = ... + R3000 = ... + R4000 = ... + R10000 = ... + WCEMIPSV2 = ... + ALPHA = ... + SH3 = ... + SH3DSP = ... + SH3E = ... + SH4 = ... + SH5 = ... + ARM = ... + THUMB = ... + ARMNT = ... + AM33 = ... + POWERPC = ... + POWERPCFP = ... + IA64 = ... + MIPS16 = ... + ALPHA64 = ... + MIPSFPU = ... + MIPSFPU16 = ... + AXP64 = ... + TRICORE = ... + CEF = ... + EBC = ... + CHPE_X86 = ... + RISCV32 = ... + RISCV64 = ... + RISCV128 = ... + AMD64 = ... + M32R = ... + ARM64 = ... + CEE = ... + + class _IMAGE_FILE_HEADER(__cs__.Structure): + Machine: _c_pe.IMAGE_FILE_MACHINE + NumberOfSections: _c_pe.uint16 + TimeDateStamp: _c_pe.uint32 + PointerToSymbolTable: _c_pe.uint32 + NumberOfSymbols: _c_pe.uint32 + SizeOfOptionalHeader: _c_pe.uint16 + Characteristics: _c_pe.IMAGE_FILE + @overload + def __init__( + self, + Machine: _c_pe.IMAGE_FILE_MACHINE | None = ..., + NumberOfSections: _c_pe.uint16 | None = ..., + TimeDateStamp: _c_pe.uint32 | None = ..., + PointerToSymbolTable: _c_pe.uint32 | None = ..., + NumberOfSymbols: _c_pe.uint32 | None = ..., + SizeOfOptionalHeader: _c_pe.uint16 | None = ..., + Characteristics: _c_pe.IMAGE_FILE | None = ..., + ): ... + @overload + def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... + + IMAGE_FILE_HEADER: TypeAlias = _IMAGE_FILE_HEADER + class _IMAGE_DATA_DIRECTORY(__cs__.Structure): + VirtualAddress: _c_pe.uint32 + Size: _c_pe.uint32 + @overload + def __init__(self, VirtualAddress: _c_pe.uint32 | None = ..., Size: _c_pe.uint32 | None = ...): ... + @overload + def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... + + IMAGE_DATA_DIRECTORY: TypeAlias = _IMAGE_DATA_DIRECTORY + class IMAGE_SUBSYSTEM(__cs__.Enum): + UNKNOWN = ... + NATIVE = ... + WINDOWS_GUI = ... + WINDOWS_CUI = ... + OS2_CUI = ... + POSIX_CUI = ... + NATIVE_WINDOWS = ... + WINDOWS_CE_GUI = ... + EFI_APPLICATION = ... + EFI_BOOT_SERVICE_DRIVER = ... + EFI_RUNTIME_DRIVER = ... + EFI_ROM = ... + XBOX = ... + WINDOWS_BOOT_APPLICATION = ... + XBOX_CODE_CATALOG = ... + + class IMAGE_DLLCHARACTERISTICS(__cs__.Enum): + HIGH_ENTROPY_VA = ... + DYNAMIC_BASE = ... + FORCE_INTEGRITY = ... + NX_COMPAT = ... + NO_ISOLATION = ... + NO_SEH = ... + NO_BIND = ... + APPCONTAINER = ... + WDM_DRIVER = ... + GUARD_CF = ... + TERMINAL_SERVER_AWARE = ... + + class _IMAGE_OPTIONAL_HEADER(__cs__.Structure): + Magic: _c_pe.uint16 + MajorLinkerVersion: _c_pe.uint8 + MinorLinkerVersion: _c_pe.uint8 + SizeOfCode: _c_pe.uint32 + SizeOfInitializedData: _c_pe.uint32 + SizeOfUninitializedData: _c_pe.uint32 + AddressOfEntryPoint: _c_pe.uint32 + BaseOfCode: _c_pe.uint32 + BaseOfData: _c_pe.uint32 + ImageBase: _c_pe.uint32 + SectionAlignment: _c_pe.uint32 + FileAlignment: _c_pe.uint32 + MajorOperatingSystemVersion: _c_pe.uint16 + MinorOperatingSystemVersion: _c_pe.uint16 + MajorImageVersion: _c_pe.uint16 + MinorImageVersion: _c_pe.uint16 + MajorSubsystemVersion: _c_pe.uint16 + MinorSubsystemVersion: _c_pe.uint16 + Win32VersionValue: _c_pe.uint32 + SizeOfImage: _c_pe.uint32 + SizeOfHeaders: _c_pe.uint32 + CheckSum: _c_pe.uint32 + Subsystem: _c_pe.IMAGE_SUBSYSTEM + DllCharacteristics: _c_pe.IMAGE_DLLCHARACTERISTICS + SizeOfStackReserve: _c_pe.uint32 + SizeOfStackCommit: _c_pe.uint32 + SizeOfHeapReserve: _c_pe.uint32 + SizeOfHeapCommit: _c_pe.uint32 + LoaderFlags: _c_pe.uint32 + NumberOfRvaAndSizes: _c_pe.uint32 + class _IMAGE_DATA_DIRECTORY(__cs__.Structure): + VirtualAddress: _c_pe.uint32 + Size: _c_pe.uint32 + @overload + def __init__(self, VirtualAddress: _c_pe.uint32 | None = ..., Size: _c_pe.uint32 | None = ...): ... + @overload + def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... + + DataDirectory: __cs__.Array[_IMAGE_DATA_DIRECTORY] + @overload + def __init__( + self, + Magic: _c_pe.uint16 | None = ..., + MajorLinkerVersion: _c_pe.uint8 | None = ..., + MinorLinkerVersion: _c_pe.uint8 | None = ..., + SizeOfCode: _c_pe.uint32 | None = ..., + SizeOfInitializedData: _c_pe.uint32 | None = ..., + SizeOfUninitializedData: _c_pe.uint32 | None = ..., + AddressOfEntryPoint: _c_pe.uint32 | None = ..., + BaseOfCode: _c_pe.uint32 | None = ..., + BaseOfData: _c_pe.uint32 | None = ..., + ImageBase: _c_pe.uint32 | None = ..., + SectionAlignment: _c_pe.uint32 | None = ..., + FileAlignment: _c_pe.uint32 | None = ..., + MajorOperatingSystemVersion: _c_pe.uint16 | None = ..., + MinorOperatingSystemVersion: _c_pe.uint16 | None = ..., + MajorImageVersion: _c_pe.uint16 | None = ..., + MinorImageVersion: _c_pe.uint16 | None = ..., + MajorSubsystemVersion: _c_pe.uint16 | None = ..., + MinorSubsystemVersion: _c_pe.uint16 | None = ..., + Win32VersionValue: _c_pe.uint32 | None = ..., + SizeOfImage: _c_pe.uint32 | None = ..., + SizeOfHeaders: _c_pe.uint32 | None = ..., + CheckSum: _c_pe.uint32 | None = ..., + Subsystem: _c_pe.IMAGE_SUBSYSTEM | None = ..., + DllCharacteristics: _c_pe.IMAGE_DLLCHARACTERISTICS | None = ..., + SizeOfStackReserve: _c_pe.uint32 | None = ..., + SizeOfStackCommit: _c_pe.uint32 | None = ..., + SizeOfHeapReserve: _c_pe.uint32 | None = ..., + SizeOfHeapCommit: _c_pe.uint32 | None = ..., + LoaderFlags: _c_pe.uint32 | None = ..., + NumberOfRvaAndSizes: _c_pe.uint32 | None = ..., + DataDirectory: __cs__.Array[_IMAGE_DATA_DIRECTORY] | None = ..., + ): ... + @overload + def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... + + IMAGE_OPTIONAL_HEADER32: TypeAlias = _IMAGE_OPTIONAL_HEADER + class _IMAGE_OPTIONAL_HEADER64(__cs__.Structure): + Magic: _c_pe.uint16 + MajorLinkerVersion: _c_pe.uint8 + MinorLinkerVersion: _c_pe.uint8 + SizeOfCode: _c_pe.uint32 + SizeOfInitializedData: _c_pe.uint32 + SizeOfUninitializedData: _c_pe.uint32 + AddressOfEntryPoint: _c_pe.uint32 + BaseOfCode: _c_pe.uint32 + ImageBase: _c_pe.uint64 + SectionAlignment: _c_pe.uint32 + FileAlignment: _c_pe.uint32 + MajorOperatingSystemVersion: _c_pe.uint16 + MinorOperatingSystemVersion: _c_pe.uint16 + MajorImageVersion: _c_pe.uint16 + MinorImageVersion: _c_pe.uint16 + MajorSubsystemVersion: _c_pe.uint16 + MinorSubsystemVersion: _c_pe.uint16 + Win32VersionValue: _c_pe.uint32 + SizeOfImage: _c_pe.uint32 + SizeOfHeaders: _c_pe.uint32 + CheckSum: _c_pe.uint32 + Subsystem: _c_pe.IMAGE_SUBSYSTEM + DllCharacteristics: _c_pe.IMAGE_DLLCHARACTERISTICS + SizeOfStackReserve: _c_pe.uint64 + SizeOfStackCommit: _c_pe.uint64 + SizeOfHeapReserve: _c_pe.uint64 + SizeOfHeapCommit: _c_pe.uint64 + LoaderFlags: _c_pe.uint32 + NumberOfRvaAndSizes: _c_pe.uint32 + class _IMAGE_DATA_DIRECTORY(__cs__.Structure): + VirtualAddress: _c_pe.uint32 + Size: _c_pe.uint32 + @overload + def __init__(self, VirtualAddress: _c_pe.uint32 | None = ..., Size: _c_pe.uint32 | None = ...): ... + @overload + def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... + + DataDirectory: __cs__.Array[_IMAGE_DATA_DIRECTORY] + @overload + def __init__( + self, + Magic: _c_pe.uint16 | None = ..., + MajorLinkerVersion: _c_pe.uint8 | None = ..., + MinorLinkerVersion: _c_pe.uint8 | None = ..., + SizeOfCode: _c_pe.uint32 | None = ..., + SizeOfInitializedData: _c_pe.uint32 | None = ..., + SizeOfUninitializedData: _c_pe.uint32 | None = ..., + AddressOfEntryPoint: _c_pe.uint32 | None = ..., + BaseOfCode: _c_pe.uint32 | None = ..., + ImageBase: _c_pe.uint64 | None = ..., + SectionAlignment: _c_pe.uint32 | None = ..., + FileAlignment: _c_pe.uint32 | None = ..., + MajorOperatingSystemVersion: _c_pe.uint16 | None = ..., + MinorOperatingSystemVersion: _c_pe.uint16 | None = ..., + MajorImageVersion: _c_pe.uint16 | None = ..., + MinorImageVersion: _c_pe.uint16 | None = ..., + MajorSubsystemVersion: _c_pe.uint16 | None = ..., + MinorSubsystemVersion: _c_pe.uint16 | None = ..., + Win32VersionValue: _c_pe.uint32 | None = ..., + SizeOfImage: _c_pe.uint32 | None = ..., + SizeOfHeaders: _c_pe.uint32 | None = ..., + CheckSum: _c_pe.uint32 | None = ..., + Subsystem: _c_pe.IMAGE_SUBSYSTEM | None = ..., + DllCharacteristics: _c_pe.IMAGE_DLLCHARACTERISTICS | None = ..., + SizeOfStackReserve: _c_pe.uint64 | None = ..., + SizeOfStackCommit: _c_pe.uint64 | None = ..., + SizeOfHeapReserve: _c_pe.uint64 | None = ..., + SizeOfHeapCommit: _c_pe.uint64 | None = ..., + LoaderFlags: _c_pe.uint32 | None = ..., + NumberOfRvaAndSizes: _c_pe.uint32 | None = ..., + DataDirectory: __cs__.Array[_IMAGE_DATA_DIRECTORY] | None = ..., + ): ... + @overload + def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... + + IMAGE_OPTIONAL_HEADER64: TypeAlias = _IMAGE_OPTIONAL_HEADER64 + class _IMAGE_NT_HEADERS64(__cs__.Structure): + Signature: _c_pe.uint32 + FileHeader: _c_pe._IMAGE_FILE_HEADER + OptionalHeader: _c_pe._IMAGE_OPTIONAL_HEADER64 + @overload + def __init__( + self, + Signature: _c_pe.uint32 | None = ..., + FileHeader: _c_pe._IMAGE_FILE_HEADER | None = ..., + OptionalHeader: _c_pe._IMAGE_OPTIONAL_HEADER64 | None = ..., + ): ... + @overload + def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... + + IMAGE_NT_HEADERS64: TypeAlias = _IMAGE_NT_HEADERS64 + class _IMAGE_NT_HEADERS(__cs__.Structure): + Signature: _c_pe.uint32 + FileHeader: _c_pe._IMAGE_FILE_HEADER + OptionalHeader: _c_pe._IMAGE_OPTIONAL_HEADER + @overload + def __init__( + self, + Signature: _c_pe.uint32 | None = ..., + FileHeader: _c_pe._IMAGE_FILE_HEADER | None = ..., + OptionalHeader: _c_pe._IMAGE_OPTIONAL_HEADER | None = ..., + ): ... + @overload + def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... + + IMAGE_NT_HEADERS32: TypeAlias = _IMAGE_NT_HEADERS + class IMAGE_DIRECTORY_ENTRY(__cs__.Enum): + EXPORT = ... + IMPORT = ... + RESOURCE = ... + EXCEPTION = ... + SECURITY = ... + BASERELOC = ... + DEBUG = ... + COPYRIGHT = ... + ARCHITECTURE = ... + GLOBALPTR = ... + TLS = ... + LOAD_CONFIG = ... + BOUND_IMPORT = ... + IAT = ... + DELAY_IMPORT = ... + COM_DESCRIPTOR = ... + + class IMAGE_SCN(__cs__.Flag): + TYPE_REG = ... + TYPE_DSECT = ... + TYPE_NOLOAD = ... + TYPE_GROUP = ... + TYPE_NO_PAD = ... + TYPE_COPY = ... + CNT_CODE = ... + CNT_INITIALIZED_DATA = ... + CNT_UNINITIALIZED_DATA = ... + LNK_OTHER = ... + LNK_INFO = ... + TYPE_OVER = ... + LNK_REMOVE = ... + LNK_COMDAT = ... + NO_DEFER_SPEC_EXC = ... + GPREL = ... + MEM_FARDATA = ... + MEM_PURGEABLE = ... + MEM_16BIT = ... + MEM_LOCKED = ... + MEM_PRELOAD = ... + ALIGN_1BYTES = ... + ALIGN_2BYTES = ... + ALIGN_4BYTES = ... + ALIGN_8BYTES = ... + ALIGN_16BYTES = ... + ALIGN_32BYTES = ... + ALIGN_64BYTES = ... + ALIGN_128BYTES = ... + ALIGN_256BYTES = ... + ALIGN_512BYTES = ... + ALIGN_1024BYTES = ... + ALIGN_2048BYTES = ... + ALIGN_4096BYTES = ... + ALIGN_8192BYTES = ... + ALIGN_MASK = ... + LNK_NRELOC_OVFL = ... + MEM_DISCARDABLE = ... + MEM_NOT_CACHED = ... + MEM_NOT_PAGED = ... + MEM_SHARED = ... + MEM_EXECUTE = ... + MEM_READ = ... + MEM_WRITE = ... + + class _IMAGE_SECTION_HEADER(__cs__.Structure): + Name: __cs__.CharArray + class __anonymous_0__(__cs__.Union): + PhysicalAddress: _c_pe.uint32 + VirtualSize: _c_pe.uint32 + @overload + def __init__(self, PhysicalAddress: _c_pe.uint32 | None = ..., VirtualSize: _c_pe.uint32 | None = ...): ... + @overload + def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... + + Misc: __anonymous_0__ + VirtualAddress: _c_pe.uint32 + SizeOfRawData: _c_pe.uint32 + PointerToRawData: _c_pe.uint32 + PointerToRelocations: _c_pe.uint32 + PointerToLinenumbers: _c_pe.uint32 + NumberOfRelocations: _c_pe.uint16 + NumberOfLinenumbers: _c_pe.uint16 + Characteristics: _c_pe.IMAGE_SCN + @overload + def __init__( + self, + Name: __cs__.CharArray | None = ..., + Misc: __anonymous_0__ | None = ..., + VirtualAddress: _c_pe.uint32 | None = ..., + SizeOfRawData: _c_pe.uint32 | None = ..., + PointerToRawData: _c_pe.uint32 | None = ..., + PointerToRelocations: _c_pe.uint32 | None = ..., + PointerToLinenumbers: _c_pe.uint32 | None = ..., + NumberOfRelocations: _c_pe.uint16 | None = ..., + NumberOfLinenumbers: _c_pe.uint16 | None = ..., + Characteristics: _c_pe.IMAGE_SCN | None = ..., + ): ... + @overload + def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... + + IMAGE_SECTION_HEADER: TypeAlias = _IMAGE_SECTION_HEADER + class IMAGE_REL_BASED(__cs__.Enum): + ABSOLUTE = ... + HIGH = ... + LOW = ... + HIGHLOW = ... + HIGHADJ = ... + MIPS_JMPADDR = ... + ARM_MOV32 = ... + RISCV_HIGH20 = ... + MACHINE_SPECIFIC_5 = ... + RESERVED = ... + THUMB_MOV32 = ... + RISCV_LOW12I = ... + REL32 = ... + MACHINE_SPECIFIC_7 = ... + RISCV_LOW12S = ... + LOONGARCH32_MARK_LA = ... + LOONGARCH64_MARK_LA = ... + VXD_RELATIVE = ... + MACHINE_SPECIFIC_8 = ... + MIPS_JMPADDR16 = ... + IA64_IMM64 = ... + MACHINE_SPECIFIC_9 = ... + DIR64 = ... + + class _IMAGE_BASE_RELOCATION(__cs__.Structure): + VirtualAddress: _c_pe.uint32 + SizeOfBlock: _c_pe.uint32 + @overload + def __init__(self, VirtualAddress: _c_pe.uint32 | None = ..., SizeOfBlock: _c_pe.uint32 | None = ...): ... + @overload + def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... + + IMAGE_BASE_RELOCATION: TypeAlias = _IMAGE_BASE_RELOCATION + class _IMAGE_ARCHIVE_MEMBER_HEADER(__cs__.Structure): + Name: __cs__.CharArray + Date: __cs__.CharArray + UserID: __cs__.CharArray + GroupID: __cs__.CharArray + Mode: __cs__.CharArray + Size: __cs__.CharArray + EndHeader: __cs__.CharArray + @overload + def __init__( + self, + Name: __cs__.CharArray | None = ..., + Date: __cs__.CharArray | None = ..., + UserID: __cs__.CharArray | None = ..., + GroupID: __cs__.CharArray | None = ..., + Mode: __cs__.CharArray | None = ..., + Size: __cs__.CharArray | None = ..., + EndHeader: __cs__.CharArray | None = ..., + ): ... + @overload + def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... + + IMAGE_ARCHIVE_MEMBER_HEADER: TypeAlias = _IMAGE_ARCHIVE_MEMBER_HEADER + class _IMAGE_EXPORT_DIRECTORY(__cs__.Structure): + Characteristics: _c_pe.uint32 + TimeDateStamp: _c_pe.uint32 + MajorVersion: _c_pe.uint16 + MinorVersion: _c_pe.uint16 + Name: _c_pe.uint32 + Base: _c_pe.uint32 + NumberOfFunctions: _c_pe.uint32 + NumberOfNames: _c_pe.uint32 + AddressOfFunctions: _c_pe.uint32 + AddressOfNames: _c_pe.uint32 + AddressOfNameOrdinals: _c_pe.uint32 + @overload + def __init__( + self, + Characteristics: _c_pe.uint32 | None = ..., + TimeDateStamp: _c_pe.uint32 | None = ..., + MajorVersion: _c_pe.uint16 | None = ..., + MinorVersion: _c_pe.uint16 | None = ..., + Name: _c_pe.uint32 | None = ..., + Base: _c_pe.uint32 | None = ..., + NumberOfFunctions: _c_pe.uint32 | None = ..., + NumberOfNames: _c_pe.uint32 | None = ..., + AddressOfFunctions: _c_pe.uint32 | None = ..., + AddressOfNames: _c_pe.uint32 | None = ..., + AddressOfNameOrdinals: _c_pe.uint32 | None = ..., + ): ... + @overload + def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... + + IMAGE_EXPORT_DIRECTORY: TypeAlias = _IMAGE_EXPORT_DIRECTORY + class _IMAGE_IMPORT_BY_NAME(__cs__.Structure): + Hint: _c_pe.uint16 + Name: __cs__.CharArray + @overload + def __init__(self, Hint: _c_pe.uint16 | None = ..., Name: __cs__.CharArray | None = ...): ... + @overload + def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... + + IMAGE_IMPORT_BY_NAME: TypeAlias = _IMAGE_IMPORT_BY_NAME + class _IMAGE_THUNK_DATA64(__cs__.Structure): + class __anonymous_1__(__cs__.Union): + ForwarderString: _c_pe.uint64 + Function: _c_pe.uint64 + Ordinal: _c_pe.uint64 + AddressOfData: _c_pe.uint64 + @overload + def __init__( + self, + ForwarderString: _c_pe.uint64 | None = ..., + Function: _c_pe.uint64 | None = ..., + Ordinal: _c_pe.uint64 | None = ..., + AddressOfData: _c_pe.uint64 | None = ..., + ): ... + @overload + def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... + + u1: __anonymous_1__ + @overload + def __init__(self, u1: __anonymous_1__ | None = ...): ... + @overload + def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... + + IMAGE_THUNK_DATA64: TypeAlias = _IMAGE_THUNK_DATA64 + class _IMAGE_THUNK_DATA32(__cs__.Structure): + class __anonymous_2__(__cs__.Union): + ForwarderString: _c_pe.uint32 + Function: _c_pe.uint32 + Ordinal: _c_pe.uint32 + AddressOfData: _c_pe.uint32 + @overload + def __init__( + self, + ForwarderString: _c_pe.uint32 | None = ..., + Function: _c_pe.uint32 | None = ..., + Ordinal: _c_pe.uint32 | None = ..., + AddressOfData: _c_pe.uint32 | None = ..., + ): ... + @overload + def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... + + u1: __anonymous_2__ + @overload + def __init__(self, u1: __anonymous_2__ | None = ...): ... + @overload + def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... + + IMAGE_THUNK_DATA32: TypeAlias = _IMAGE_THUNK_DATA32 + class _IMAGE_IMPORT_DESCRIPTOR(__cs__.Structure): + Characteristics: _c_pe.uint32 + OriginalFirstThunk: _c_pe.uint32 + TimeDateStamp: _c_pe.uint32 + ForwarderChain: _c_pe.uint32 + Name: _c_pe.uint32 + FirstThunk: _c_pe.uint32 + @overload + def __init__( + self, + Characteristics: _c_pe.uint32 | None = ..., + OriginalFirstThunk: _c_pe.uint32 | None = ..., + TimeDateStamp: _c_pe.uint32 | None = ..., + ForwarderChain: _c_pe.uint32 | None = ..., + Name: _c_pe.uint32 | None = ..., + FirstThunk: _c_pe.uint32 | None = ..., + ): ... + @overload + def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... + + IMAGE_IMPORT_DESCRIPTOR: TypeAlias = _IMAGE_IMPORT_DESCRIPTOR + class _IMAGE_TLS_DIRECTORY64(__cs__.Structure): + StartAddressOfRawData: _c_pe.uint64 + EndAddressOfRawData: _c_pe.uint64 + AddressOfIndex: _c_pe.uint64 + AddressOfCallBacks: _c_pe.uint64 + SizeOfZeroFill: _c_pe.uint32 + Characteristics: _c_pe.uint32 + Reserved0: _c_pe.uint32 + Alignment: _c_pe.uint32 + Reserved1: _c_pe.uint32 + @overload + def __init__( + self, + StartAddressOfRawData: _c_pe.uint64 | None = ..., + EndAddressOfRawData: _c_pe.uint64 | None = ..., + AddressOfIndex: _c_pe.uint64 | None = ..., + AddressOfCallBacks: _c_pe.uint64 | None = ..., + SizeOfZeroFill: _c_pe.uint32 | None = ..., + Characteristics: _c_pe.uint32 | None = ..., + Reserved0: _c_pe.uint32 | None = ..., + Alignment: _c_pe.uint32 | None = ..., + Reserved1: _c_pe.uint32 | None = ..., + ): ... + @overload + def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... + + IMAGE_TLS_DIRECTORY64: TypeAlias = _IMAGE_TLS_DIRECTORY64 + class _IMAGE_TLS_DIRECTORY32(__cs__.Structure): + StartAddressOfRawData: _c_pe.uint32 + EndAddressOfRawData: _c_pe.uint32 + AddressOfIndex: _c_pe.uint32 + AddressOfCallBacks: _c_pe.uint32 + SizeOfZeroFill: _c_pe.uint32 + Characteristics: _c_pe.uint32 + Reserved0: _c_pe.uint32 + Alignment: _c_pe.uint32 + Reserved1: _c_pe.uint32 + @overload + def __init__( + self, + StartAddressOfRawData: _c_pe.uint32 | None = ..., + EndAddressOfRawData: _c_pe.uint32 | None = ..., + AddressOfIndex: _c_pe.uint32 | None = ..., + AddressOfCallBacks: _c_pe.uint32 | None = ..., + SizeOfZeroFill: _c_pe.uint32 | None = ..., + Characteristics: _c_pe.uint32 | None = ..., + Reserved0: _c_pe.uint32 | None = ..., + Alignment: _c_pe.uint32 | None = ..., + Reserved1: _c_pe.uint32 | None = ..., + ): ... + @overload + def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... + + IMAGE_TLS_DIRECTORY32: TypeAlias = _IMAGE_TLS_DIRECTORY32 + class _IMAGE_BOUND_IMPORT_DESCRIPTOR(__cs__.Structure): + TimeDateStamp: _c_pe.uint32 + OffsetModuleName: _c_pe.uint16 + NumberOfModuleForwarderRefs: _c_pe.uint16 + @overload + def __init__( + self, + TimeDateStamp: _c_pe.uint32 | None = ..., + OffsetModuleName: _c_pe.uint16 | None = ..., + NumberOfModuleForwarderRefs: _c_pe.uint16 | None = ..., + ): ... + @overload + def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... + + IMAGE_BOUND_IMPORT_DESCRIPTOR: TypeAlias = _IMAGE_BOUND_IMPORT_DESCRIPTOR + class _IMAGE_BOUND_FORWARDER_REF(__cs__.Structure): + TimeDateStamp: _c_pe.uint32 + OffsetModuleName: _c_pe.uint16 + Reserved: _c_pe.uint16 + @overload + def __init__( + self, + TimeDateStamp: _c_pe.uint32 | None = ..., + OffsetModuleName: _c_pe.uint16 | None = ..., + Reserved: _c_pe.uint16 | None = ..., + ): ... + @overload + def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... + + IMAGE_BOUND_FORWARDER_REF: TypeAlias = _IMAGE_BOUND_FORWARDER_REF + class _IMAGE_DELAYLOAD_DESCRIPTOR(__cs__.Structure): + class __anonymous_9__(__cs__.Union): + AllAttributes: _c_pe.uint32 + RvaBased: _c_pe.uint32 + ReservedAttributes: _c_pe.uint32 + @overload + def __init__( + self, + AllAttributes: _c_pe.uint32 | None = ..., + RvaBased: _c_pe.uint32 | None = ..., + ReservedAttributes: _c_pe.uint32 | None = ..., + ): ... + @overload + def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... + + Attributes: __anonymous_9__ + DllNameRVA: _c_pe.uint32 + ModuleHandleRVA: _c_pe.uint32 + ImportAddressTableRVA: _c_pe.uint32 + ImportNameTableRVA: _c_pe.uint32 + BoundImportAddressTableRVA: _c_pe.uint32 + UnloadInformationTableRVA: _c_pe.uint32 + TimeDateStamp: _c_pe.uint32 + @overload + def __init__( + self, + Attributes: __anonymous_9__ | None = ..., + DllNameRVA: _c_pe.uint32 | None = ..., + ModuleHandleRVA: _c_pe.uint32 | None = ..., + ImportAddressTableRVA: _c_pe.uint32 | None = ..., + ImportNameTableRVA: _c_pe.uint32 | None = ..., + BoundImportAddressTableRVA: _c_pe.uint32 | None = ..., + UnloadInformationTableRVA: _c_pe.uint32 | None = ..., + TimeDateStamp: _c_pe.uint32 | None = ..., + ): ... + @overload + def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... + + IMAGE_DELAYLOAD_DESCRIPTOR: TypeAlias = _IMAGE_DELAYLOAD_DESCRIPTOR + class RT(__cs__.Enum): + CURSOR = ... + BITMAP = ... + ICON = ... + MENU = ... + DIALOG = ... + STRING = ... + FONTDIR = ... + FONT = ... + ACCELERATOR = ... + RCDATA = ... + MESSAGETABLE = ... + GROUP_CURSOR = ... + GROUP_ICON = ... + VERSION = ... + DLGINCLUDE = ... + PLUGPLAY = ... + VXD = ... + ANICURSOR = ... + ANIICON = ... + HTML = ... + MANIFEST = ... + + class _IMAGE_RESOURCE_DIRECTORY(__cs__.Structure): + Characteristics: _c_pe.uint32 + TimeDateStamp: _c_pe.uint32 + MajorVersion: _c_pe.uint16 + MinorVersion: _c_pe.uint16 + NumberOfNamedEntries: _c_pe.uint16 + NumberOfIdEntries: _c_pe.uint16 + @overload + def __init__( + self, + Characteristics: _c_pe.uint32 | None = ..., + TimeDateStamp: _c_pe.uint32 | None = ..., + MajorVersion: _c_pe.uint16 | None = ..., + MinorVersion: _c_pe.uint16 | None = ..., + NumberOfNamedEntries: _c_pe.uint16 | None = ..., + NumberOfIdEntries: _c_pe.uint16 | None = ..., + ): ... + @overload + def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... + + IMAGE_RESOURCE_DIRECTORY: TypeAlias = _IMAGE_RESOURCE_DIRECTORY + class _IMAGE_RESOURCE_DIRECTORY_ENTRY(__cs__.Structure): + NameOffset: _c_pe.uint32 + NameIsString: _c_pe.uint32 + Name: _c_pe.uint32 + Id: _c_pe.uint16 + OffsetToData: _c_pe.uint32 + OffsetToDirectory: _c_pe.uint32 + DataIsDirectory: _c_pe.uint32 + @overload + def __init__( + self, + NameOffset: _c_pe.uint32 | None = ..., + NameIsString: _c_pe.uint32 | None = ..., + Name: _c_pe.uint32 | None = ..., + Id: _c_pe.uint16 | None = ..., + OffsetToData: _c_pe.uint32 | None = ..., + OffsetToDirectory: _c_pe.uint32 | None = ..., + DataIsDirectory: _c_pe.uint32 | None = ..., + ): ... + @overload + def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... + + IMAGE_RESOURCE_DIRECTORY_ENTRY: TypeAlias = _IMAGE_RESOURCE_DIRECTORY_ENTRY + class _IMAGE_RESOURCE_DIRECTORY_STRING(__cs__.Structure): + Length: _c_pe.uint16 + NameString: __cs__.CharArray + @overload + def __init__(self, Length: _c_pe.uint16 | None = ..., NameString: __cs__.CharArray | None = ...): ... + @overload + def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... + + IMAGE_RESOURCE_DIRECTORY_STRING: TypeAlias = _IMAGE_RESOURCE_DIRECTORY_STRING + class _IMAGE_RESOURCE_DIR_STRING_U(__cs__.Structure): + Length: _c_pe.uint16 + NameString: __cs__.WcharArray + @overload + def __init__(self, Length: _c_pe.uint16 | None = ..., NameString: __cs__.WcharArray | None = ...): ... + @overload + def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... + + IMAGE_RESOURCE_DIR_STRING_U: TypeAlias = _IMAGE_RESOURCE_DIR_STRING_U + class _IMAGE_RESOURCE_DATA_ENTRY(__cs__.Structure): + OffsetToData: _c_pe.uint32 + Size: _c_pe.uint32 + CodePage: _c_pe.uint32 + Reserved: _c_pe.uint32 + @overload + def __init__( + self, + OffsetToData: _c_pe.uint32 | None = ..., + Size: _c_pe.uint32 | None = ..., + CodePage: _c_pe.uint32 | None = ..., + Reserved: _c_pe.uint32 | None = ..., + ): ... + @overload + def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... + + IMAGE_RESOURCE_DATA_ENTRY: TypeAlias = _IMAGE_RESOURCE_DATA_ENTRY + class _VS_FIXEDFILEINFO(__cs__.Structure): + dwSignature: _c_pe.uint32 + dwStrucVersion: _c_pe.uint32 + dwFileVersionMS: _c_pe.uint32 + dwFileVersionLS: _c_pe.uint32 + dwProductVersionMS: _c_pe.uint32 + dwProductVersionLS: _c_pe.uint32 + dwFileFlagsMask: _c_pe.uint32 + dwFileFlags: _c_pe.uint32 + dwFileOS: _c_pe.uint32 + dwFileType: _c_pe.uint32 + dwFileSubtype: _c_pe.uint32 + dwFileDateMS: _c_pe.uint32 + dwFileDateLS: _c_pe.uint32 + @overload + def __init__( + self, + dwSignature: _c_pe.uint32 | None = ..., + dwStrucVersion: _c_pe.uint32 | None = ..., + dwFileVersionMS: _c_pe.uint32 | None = ..., + dwFileVersionLS: _c_pe.uint32 | None = ..., + dwProductVersionMS: _c_pe.uint32 | None = ..., + dwProductVersionLS: _c_pe.uint32 | None = ..., + dwFileFlagsMask: _c_pe.uint32 | None = ..., + dwFileFlags: _c_pe.uint32 | None = ..., + dwFileOS: _c_pe.uint32 | None = ..., + dwFileType: _c_pe.uint32 | None = ..., + dwFileSubtype: _c_pe.uint32 | None = ..., + dwFileDateMS: _c_pe.uint32 | None = ..., + dwFileDateLS: _c_pe.uint32 | None = ..., + ): ... + @overload + def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... + + VS_FIXEDFILEINFO: TypeAlias = _VS_FIXEDFILEINFO + class VS_FF(__cs__.Flag): + DEBUG = ... + PRERELEASE = ... + PATCHED = ... + PRIVATEBUILD = ... + INFOINFERRED = ... + SPECIALBUILD = ... + + class VOS(__cs__.Enum): + UNKNOWN = ... + WINDOWS16 = ... + PM16 = ... + PM32 = ... + WINDOWS32 = ... + DOS = ... + OS216 = ... + OS232 = ... + NT = ... + + class VFT(__cs__.Enum): + UNKNOWN = ... + APP = ... + DLL = ... + DRV = ... + FONT = ... + VXD = ... + STATIC_LIBRARY = ... + + class VFT2_DRV(__cs__.Enum): + UNKNOWN = ... + PRINTER = ... + KEYBOARD = ... + LANGUAGE = ... + DISPLAY = ... + MOUSE = ... + NETWORK = ... + SYSTEM = ... + INSTALLABLE = ... + SOUND = ... + COMM = ... + INPUTMETHOD = ... + VERSIONED_PRINTER = ... + + class VFT2_FONT(__cs__.Enum): + UNKNOWN = ... + RASTER = ... + VECTOR = ... + TRUETYPE = ... + + class VK(__cs__.Enum): + LBUTTON = ... + RBUTTON = ... + CANCEL = ... + MBUTTON = ... + XBUTTON1 = ... + XBUTTON2 = ... + BACK = ... + TAB = ... + CLEAR = ... + RETURN = ... + SHIFT = ... + CONTROL = ... + MENU = ... + PAUSE = ... + CAPITAL = ... + KANA = ... + HANGEUL = ... + HANGUL = ... + IME_ON = ... + JUNJA = ... + FINAL = ... + HANJA = ... + KANJI = ... + IME_OFF = ... + ESCAPE = ... + CONVERT = ... + NONCONVERT = ... + ACCEPT = ... + MODECHANGE = ... + SPACE = ... + PRIOR = ... + NEXT = ... + END = ... + HOME = ... + LEFT = ... + UP = ... + RIGHT = ... + DOWN = ... + SELECT = ... + PRINT = ... + EXECUTE = ... + SNAPSHOT = ... + INSERT = ... + DELETE = ... + HELP = ... + "0 = ..." + "1 = ..." + "2 = ..." + "3 = ..." + "4 = ..." + "5 = ..." + "6 = ..." + "7 = ..." + "8 = ..." + "9 = ..." + A = ... + B = ... + C = ... + D = ... + E = ... + F = ... + G = ... + H = ... + I = ... + J = ... + K = ... + L = ... + M = ... + N = ... + O = ... + P = ... + Q = ... + R = ... + S = ... + T = ... + U = ... + V = ... + W = ... + X = ... + Y = ... + Z = ... + LWIN = ... + RWIN = ... + APPS = ... + SLEEP = ... + NUMPAD0 = ... + NUMPAD1 = ... + NUMPAD2 = ... + NUMPAD3 = ... + NUMPAD4 = ... + NUMPAD5 = ... + NUMPAD6 = ... + NUMPAD7 = ... + NUMPAD8 = ... + NUMPAD9 = ... + MULTIPLY = ... + ADD = ... + SEPARATOR = ... + SUBTRACT = ... + DECIMAL = ... + DIVIDE = ... + F1 = ... + F2 = ... + F3 = ... + F4 = ... + F5 = ... + F6 = ... + F7 = ... + F8 = ... + F9 = ... + F10 = ... + F11 = ... + F12 = ... + F13 = ... + F14 = ... + F15 = ... + F16 = ... + F17 = ... + F18 = ... + F19 = ... + F20 = ... + F21 = ... + F22 = ... + F23 = ... + F24 = ... + NAVIGATION_VIEW = ... + NAVIGATION_MENU = ... + NAVIGATION_UP = ... + NAVIGATION_DOWN = ... + NAVIGATION_LEFT = ... + NAVIGATION_RIGHT = ... + NAVIGATION_ACCEPT = ... + NAVIGATION_CANCEL = ... + NUMLOCK = ... + SCROLL = ... + OEM_NEC_EQUAL = ... + OEM_FJ_JISHO = ... + OEM_FJ_MASSHOU = ... + OEM_FJ_TOUROKU = ... + OEM_FJ_LOYA = ... + OEM_FJ_ROYA = ... + LSHIFT = ... + RSHIFT = ... + LCONTROL = ... + RCONTROL = ... + LMENU = ... + RMENU = ... + BROWSER_BACK = ... + BROWSER_FORWARD = ... + BROWSER_REFRESH = ... + BROWSER_STOP = ... + BROWSER_SEARCH = ... + BROWSER_FAVORITES = ... + BROWSER_HOME = ... + VOLUME_MUTE = ... + VOLUME_DOWN = ... + VOLUME_UP = ... + MEDIA_NEXT_TRACK = ... + MEDIA_PREV_TRACK = ... + MEDIA_STOP = ... + MEDIA_PLAY_PAUSE = ... + LAUNCH_MAIL = ... + LAUNCH_MEDIA_SELECT = ... + LAUNCH_APP1 = ... + LAUNCH_APP2 = ... + OEM_1 = ... + OEM_PLUS = ... + OEM_COMMA = ... + OEM_MINUS = ... + OEM_PERIOD = ... + OEM_2 = ... + OEM_3 = ... + GAMEPAD_A = ... + GAMEPAD_B = ... + GAMEPAD_X = ... + GAMEPAD_Y = ... + GAMEPAD_RIGHT_SHOULDER = ... + GAMEPAD_LEFT_SHOULDER = ... + GAMEPAD_LEFT_TRIGGER = ... + GAMEPAD_RIGHT_TRIGGER = ... + GAMEPAD_DPAD_UP = ... + GAMEPAD_DPAD_DOWN = ... + GAMEPAD_DPAD_LEFT = ... + GAMEPAD_DPAD_RIGHT = ... + GAMEPAD_MENU = ... + GAMEPAD_VIEW = ... + GAMEPAD_LEFT_THUMBSTICK_BUTTON = ... + GAMEPAD_RIGHT_THUMBSTICK_BUTTON = ... + GAMEPAD_LEFT_THUMBSTICK_UP = ... + GAMEPAD_LEFT_THUMBSTICK_DOWN = ... + GAMEPAD_LEFT_THUMBSTICK_RIGHT = ... + GAMEPAD_LEFT_THUMBSTICK_LEFT = ... + GAMEPAD_RIGHT_THUMBSTICK_UP = ... + GAMEPAD_RIGHT_THUMBSTICK_DOWN = ... + GAMEPAD_RIGHT_THUMBSTICK_RIGHT = ... + GAMEPAD_RIGHT_THUMBSTICK_LEFT = ... + OEM_4 = ... + OEM_5 = ... + OEM_6 = ... + OEM_7 = ... + OEM_8 = ... + OEM_AX = ... + OEM_102 = ... + ICO_HELP = ... + ICO_00 = ... + PROCESSKEY = ... + ICO_CLEAR = ... + PACKET = ... + OEM_RESET = ... + OEM_JUMP = ... + OEM_PA1 = ... + OEM_PA2 = ... + OEM_PA3 = ... + OEM_WSCTRL = ... + OEM_CUSEL = ... + OEM_ATTN = ... + OEM_FINISH = ... + OEM_COPY = ... + OEM_AUTO = ... + OEM_ENLW = ... + OEM_BACKTAB = ... + ATTN = ... + CRSEL = ... + EXSEL = ... + EREOF = ... + PLAY = ... + ZOOM = ... + NONAME = ... + PA1 = ... + OEM_CLEAR = ... + + class ACCEL_F(__cs__.Flag): + VIRTKEY = ... + LASTKEY = ... + NOINVERT = ... + SHIFT = ... + CONTROL = ... + ALT = ... + + class _IMAGE_LOAD_CONFIG_CODE_INTEGRITY(__cs__.Structure): + Flags: _c_pe.uint16 + Catalog: _c_pe.uint16 + CatalogOffset: _c_pe.uint32 + Reserved: _c_pe.uint32 + @overload + def __init__( + self, + Flags: _c_pe.uint16 | None = ..., + Catalog: _c_pe.uint16 | None = ..., + CatalogOffset: _c_pe.uint32 | None = ..., + Reserved: _c_pe.uint32 | None = ..., + ): ... + @overload + def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... + + IMAGE_LOAD_CONFIG_CODE_INTEGRITY: TypeAlias = _IMAGE_LOAD_CONFIG_CODE_INTEGRITY + class _IMAGE_DYNAMIC_RELOCATION_TABLE(__cs__.Structure): + Version: _c_pe.uint32 + Size: _c_pe.uint32 + @overload + def __init__(self, Version: _c_pe.uint32 | None = ..., Size: _c_pe.uint32 | None = ...): ... + @overload + def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... + + IMAGE_DYNAMIC_RELOCATION_TABLE: TypeAlias = _IMAGE_DYNAMIC_RELOCATION_TABLE + class _IMAGE_DYNAMIC_RELOCATION32(__cs__.Structure): + Symbol: _c_pe.uint32 + BaseRelocSize: _c_pe.uint32 + @overload + def __init__(self, Symbol: _c_pe.uint32 | None = ..., BaseRelocSize: _c_pe.uint32 | None = ...): ... + @overload + def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... + + IMAGE_DYNAMIC_RELOCATION32: TypeAlias = _IMAGE_DYNAMIC_RELOCATION32 + class _IMAGE_DYNAMIC_RELOCATION64(__cs__.Structure): + Symbol: _c_pe.uint64 + BaseRelocSize: _c_pe.uint32 + @overload + def __init__(self, Symbol: _c_pe.uint64 | None = ..., BaseRelocSize: _c_pe.uint32 | None = ...): ... + @overload + def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... + + IMAGE_DYNAMIC_RELOCATION64: TypeAlias = _IMAGE_DYNAMIC_RELOCATION64 + class _IMAGE_DYNAMIC_RELOCATION32_V2(__cs__.Structure): + HeaderSize: _c_pe.uint32 + FixupInfoSize: _c_pe.uint32 + Symbol: _c_pe.uint32 + SymbolGroup: _c_pe.uint32 + Flags: _c_pe.uint32 + @overload + def __init__( + self, + HeaderSize: _c_pe.uint32 | None = ..., + FixupInfoSize: _c_pe.uint32 | None = ..., + Symbol: _c_pe.uint32 | None = ..., + SymbolGroup: _c_pe.uint32 | None = ..., + Flags: _c_pe.uint32 | None = ..., + ): ... + @overload + def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... + + IMAGE_DYNAMIC_RELOCATION32_V2: TypeAlias = _IMAGE_DYNAMIC_RELOCATION32_V2 + class _IMAGE_DYNAMIC_RELOCATION64_V2(__cs__.Structure): + HeaderSize: _c_pe.uint32 + FixupInfoSize: _c_pe.uint32 + Symbol: _c_pe.uint64 + SymbolGroup: _c_pe.uint32 + Flags: _c_pe.uint32 + @overload + def __init__( + self, + HeaderSize: _c_pe.uint32 | None = ..., + FixupInfoSize: _c_pe.uint32 | None = ..., + Symbol: _c_pe.uint64 | None = ..., + SymbolGroup: _c_pe.uint32 | None = ..., + Flags: _c_pe.uint32 | None = ..., + ): ... + @overload + def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... + + IMAGE_DYNAMIC_RELOCATION64_V2: TypeAlias = _IMAGE_DYNAMIC_RELOCATION64_V2 + class _IMAGE_PROLOGUE_DYNAMIC_RELOCATION_HEADER(__cs__.Structure): + PrologueByteCount: _c_pe.uint8 + @overload + def __init__(self, PrologueByteCount: _c_pe.uint8 | None = ...): ... + @overload + def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... + + IMAGE_PROLOGUE_DYNAMIC_RELOCATION_HEADER: TypeAlias = _IMAGE_PROLOGUE_DYNAMIC_RELOCATION_HEADER + class _IMAGE_EPILOGUE_DYNAMIC_RELOCATION_HEADER(__cs__.Structure): + EpilogueCount: _c_pe.uint32 + EpilogueByteCount: _c_pe.uint8 + BranchDescriptorElementSize: _c_pe.uint8 + BranchDescriptorCount: _c_pe.uint16 + @overload + def __init__( + self, + EpilogueCount: _c_pe.uint32 | None = ..., + EpilogueByteCount: _c_pe.uint8 | None = ..., + BranchDescriptorElementSize: _c_pe.uint8 | None = ..., + BranchDescriptorCount: _c_pe.uint16 | None = ..., + ): ... + @overload + def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... + + IMAGE_EPILOGUE_DYNAMIC_RELOCATION_HEADER: TypeAlias = _IMAGE_EPILOGUE_DYNAMIC_RELOCATION_HEADER + class _IMAGE_IMPORT_CONTROL_TRANSFER_DYNAMIC_RELOCATION(__cs__.Structure): + PageRelativeOffset: _c_pe.uint32 + IndirectCall: _c_pe.uint32 + IATIndex: _c_pe.uint32 + @overload + def __init__( + self, + PageRelativeOffset: _c_pe.uint32 | None = ..., + IndirectCall: _c_pe.uint32 | None = ..., + IATIndex: _c_pe.uint32 | None = ..., + ): ... + @overload + def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... + + IMAGE_IMPORT_CONTROL_TRANSFER_DYNAMIC_RELOCATION: TypeAlias = _IMAGE_IMPORT_CONTROL_TRANSFER_DYNAMIC_RELOCATION + class _IMAGE_IMPORT_CONTROL_TRANSFER_ARM64_RELOCATION(__cs__.Structure): + PageRelativeOffset: _c_pe.uint32 + IndirectCall: _c_pe.uint32 + RegisterIndex: _c_pe.uint32 + ImportType: _c_pe.uint32 + IATIndex: _c_pe.uint32 + @overload + def __init__( + self, + PageRelativeOffset: _c_pe.uint32 | None = ..., + IndirectCall: _c_pe.uint32 | None = ..., + RegisterIndex: _c_pe.uint32 | None = ..., + ImportType: _c_pe.uint32 | None = ..., + IATIndex: _c_pe.uint32 | None = ..., + ): ... + @overload + def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... + + IMAGE_IMPORT_CONTROL_TRANSFER_ARM64_RELOCATION: TypeAlias = _IMAGE_IMPORT_CONTROL_TRANSFER_ARM64_RELOCATION + class _IMAGE_INDIR_CONTROL_TRANSFER_DYNAMIC_RELOCATION(__cs__.Structure): + PageRelativeOffset: _c_pe.uint16 + IndirectCall: _c_pe.uint16 + RexWPrefix: _c_pe.uint16 + CfgCheck: _c_pe.uint16 + Reserved: _c_pe.uint16 + @overload + def __init__( + self, + PageRelativeOffset: _c_pe.uint16 | None = ..., + IndirectCall: _c_pe.uint16 | None = ..., + RexWPrefix: _c_pe.uint16 | None = ..., + CfgCheck: _c_pe.uint16 | None = ..., + Reserved: _c_pe.uint16 | None = ..., + ): ... + @overload + def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... + + IMAGE_INDIR_CONTROL_TRANSFER_DYNAMIC_RELOCATION: TypeAlias = _IMAGE_INDIR_CONTROL_TRANSFER_DYNAMIC_RELOCATION + class _IMAGE_SWITCHTABLE_BRANCH_DYNAMIC_RELOCATION(__cs__.Structure): + PageRelativeOffset: _c_pe.uint16 + RegisterNumber: _c_pe.uint16 + @overload + def __init__( + self, PageRelativeOffset: _c_pe.uint16 | None = ..., RegisterNumber: _c_pe.uint16 | None = ... + ): ... + @overload + def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... + + IMAGE_SWITCHTABLE_BRANCH_DYNAMIC_RELOCATION: TypeAlias = _IMAGE_SWITCHTABLE_BRANCH_DYNAMIC_RELOCATION + class _IMAGE_FUNCTION_OVERRIDE_HEADER(__cs__.Structure): + FuncOverrideSize: _c_pe.uint32 + @overload + def __init__(self, FuncOverrideSize: _c_pe.uint32 | None = ...): ... + @overload + def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... + + IMAGE_FUNCTION_OVERRIDE_HEADER: TypeAlias = _IMAGE_FUNCTION_OVERRIDE_HEADER + class _IMAGE_FUNCTION_OVERRIDE_DYNAMIC_RELOCATION(__cs__.Structure): + OriginalRva: _c_pe.uint32 + BDDOffset: _c_pe.uint32 + RvaSize: _c_pe.uint32 + BaseRelocSize: _c_pe.uint32 + @overload + def __init__( + self, + OriginalRva: _c_pe.uint32 | None = ..., + BDDOffset: _c_pe.uint32 | None = ..., + RvaSize: _c_pe.uint32 | None = ..., + BaseRelocSize: _c_pe.uint32 | None = ..., + ): ... + @overload + def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... + + IMAGE_FUNCTION_OVERRIDE_DYNAMIC_RELOCATION: TypeAlias = _IMAGE_FUNCTION_OVERRIDE_DYNAMIC_RELOCATION + class _IMAGE_BDD_INFO(__cs__.Structure): + Version: _c_pe.uint32 + BDDSize: _c_pe.uint32 + @overload + def __init__(self, Version: _c_pe.uint32 | None = ..., BDDSize: _c_pe.uint32 | None = ...): ... + @overload + def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... + + IMAGE_BDD_INFO: TypeAlias = _IMAGE_BDD_INFO + class _IMAGE_BDD_DYNAMIC_RELOCATION(__cs__.Structure): + Left: _c_pe.uint16 + Right: _c_pe.uint16 + Value: _c_pe.uint32 + @overload + def __init__( + self, Left: _c_pe.uint16 | None = ..., Right: _c_pe.uint16 | None = ..., Value: _c_pe.uint32 | None = ... + ): ... + @overload + def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... + + IMAGE_BDD_DYNAMIC_RELOCATION: TypeAlias = _IMAGE_BDD_DYNAMIC_RELOCATION + class IMAGE_GUARD(__cs__.Flag): + CF_INSTRUMENTED = ... + CFW_INSTRUMENTED = ... + CF_FUNCTION_TABLE_PRESENT = ... + SECURITY_COOKIE_UNUSED = ... + PROTECT_DELAYLOAD_IAT = ... + DELAYLOAD_IAT_IN_ITS_OWN_SECTION = ... + CF_EXPORT_SUPPRESSION_INFO_PRESENT = ... + CF_ENABLE_EXPORT_SUPPRESSION = ... + CF_LONGJUMP_TABLE_PRESENT = ... + RF_INSTRUMENTED = ... + RF_ENABLE = ... + RF_STRICT = ... + RETPOLINE_PRESENT = ... + EH_CONTINUATION_TABLE_PRESENT = ... + XFG_ENABLED = ... + CASTGUARD_PRESENT = ... + MEMCPY_PRESENT = ... + + class _IMAGE_LOAD_CONFIG_DIRECTORY32(__cs__.Structure): + Size: _c_pe.uint32 + TimeDateStamp: _c_pe.uint32 + MajorVersion: _c_pe.uint16 + MinorVersion: _c_pe.uint16 + GlobalFlagsClear: _c_pe.uint32 + GlobalFlagsSet: _c_pe.uint32 + CriticalSectionDefaultTimeout: _c_pe.uint32 + DeCommitFreeBlockThreshold: _c_pe.uint32 + DeCommitTotalFreeThreshold: _c_pe.uint32 + LockPrefixTable: _c_pe.uint32 + MaximumAllocationSize: _c_pe.uint32 + VirtualMemoryThreshold: _c_pe.uint32 + ProcessHeapFlags: _c_pe.uint32 + ProcessAffinityMask: _c_pe.uint32 + CSDVersion: _c_pe.uint16 + DependentLoadFlags: _c_pe.uint16 + EditList: _c_pe.uint32 + SecurityCookie: _c_pe.uint32 + SEHandlerTable: _c_pe.uint32 + SEHandlerCount: _c_pe.uint32 + GuardCFCheckFunctionPointer: _c_pe.uint32 + GuardCFDispatchFunctionPointer: _c_pe.uint32 + GuardCFFunctionTable: _c_pe.uint32 + GuardCFFunctionCount: _c_pe.uint32 + GuardFlags: _c_pe.IMAGE_GUARD + CodeIntegrity: _c_pe._IMAGE_LOAD_CONFIG_CODE_INTEGRITY + GuardAddressTakenIatEntryTable: _c_pe.uint32 + GuardAddressTakenIatEntryCount: _c_pe.uint32 + GuardLongJumpTargetTable: _c_pe.uint32 + GuardLongJumpTargetCount: _c_pe.uint32 + DynamicValueRelocTable: _c_pe.uint32 + CHPEMetadataPointer: _c_pe.uint32 + GuardRFFailureRoutine: _c_pe.uint32 + GuardRFFailureRoutineFunctionPointer: _c_pe.uint32 + DynamicValueRelocTableOffset: _c_pe.uint32 + DynamicValueRelocTableSection: _c_pe.uint16 + Reserved2: _c_pe.uint16 + GuardRFVerifyStackPointerFunctionPointer: _c_pe.uint32 + HotPatchTableOffset: _c_pe.uint32 + Reserved3: _c_pe.uint32 + EnclaveConfigurationPointer: _c_pe.uint32 + VolatileMetadataPointer: _c_pe.uint32 + GuardEHContinuationTable: _c_pe.uint32 + GuardEHContinuationCount: _c_pe.uint32 + GuardXFGCheckFunctionPointer: _c_pe.uint32 + GuardXFGDispatchFunctionPointer: _c_pe.uint32 + GuardXFGTableDispatchFunctionPointer: _c_pe.uint32 + CastGuardOsDeterminedFailureMode: _c_pe.uint32 + GuardMemcpyFunctionPointer: _c_pe.uint32 + UmaFunctionPointers: _c_pe.uint32 + @overload + def __init__( + self, + Size: _c_pe.uint32 | None = ..., + TimeDateStamp: _c_pe.uint32 | None = ..., + MajorVersion: _c_pe.uint16 | None = ..., + MinorVersion: _c_pe.uint16 | None = ..., + GlobalFlagsClear: _c_pe.uint32 | None = ..., + GlobalFlagsSet: _c_pe.uint32 | None = ..., + CriticalSectionDefaultTimeout: _c_pe.uint32 | None = ..., + DeCommitFreeBlockThreshold: _c_pe.uint32 | None = ..., + DeCommitTotalFreeThreshold: _c_pe.uint32 | None = ..., + LockPrefixTable: _c_pe.uint32 | None = ..., + MaximumAllocationSize: _c_pe.uint32 | None = ..., + VirtualMemoryThreshold: _c_pe.uint32 | None = ..., + ProcessHeapFlags: _c_pe.uint32 | None = ..., + ProcessAffinityMask: _c_pe.uint32 | None = ..., + CSDVersion: _c_pe.uint16 | None = ..., + DependentLoadFlags: _c_pe.uint16 | None = ..., + EditList: _c_pe.uint32 | None = ..., + SecurityCookie: _c_pe.uint32 | None = ..., + SEHandlerTable: _c_pe.uint32 | None = ..., + SEHandlerCount: _c_pe.uint32 | None = ..., + GuardCFCheckFunctionPointer: _c_pe.uint32 | None = ..., + GuardCFDispatchFunctionPointer: _c_pe.uint32 | None = ..., + GuardCFFunctionTable: _c_pe.uint32 | None = ..., + GuardCFFunctionCount: _c_pe.uint32 | None = ..., + GuardFlags: _c_pe.IMAGE_GUARD | None = ..., + CodeIntegrity: _c_pe._IMAGE_LOAD_CONFIG_CODE_INTEGRITY | None = ..., + GuardAddressTakenIatEntryTable: _c_pe.uint32 | None = ..., + GuardAddressTakenIatEntryCount: _c_pe.uint32 | None = ..., + GuardLongJumpTargetTable: _c_pe.uint32 | None = ..., + GuardLongJumpTargetCount: _c_pe.uint32 | None = ..., + DynamicValueRelocTable: _c_pe.uint32 | None = ..., + CHPEMetadataPointer: _c_pe.uint32 | None = ..., + GuardRFFailureRoutine: _c_pe.uint32 | None = ..., + GuardRFFailureRoutineFunctionPointer: _c_pe.uint32 | None = ..., + DynamicValueRelocTableOffset: _c_pe.uint32 | None = ..., + DynamicValueRelocTableSection: _c_pe.uint16 | None = ..., + Reserved2: _c_pe.uint16 | None = ..., + GuardRFVerifyStackPointerFunctionPointer: _c_pe.uint32 | None = ..., + HotPatchTableOffset: _c_pe.uint32 | None = ..., + Reserved3: _c_pe.uint32 | None = ..., + EnclaveConfigurationPointer: _c_pe.uint32 | None = ..., + VolatileMetadataPointer: _c_pe.uint32 | None = ..., + GuardEHContinuationTable: _c_pe.uint32 | None = ..., + GuardEHContinuationCount: _c_pe.uint32 | None = ..., + GuardXFGCheckFunctionPointer: _c_pe.uint32 | None = ..., + GuardXFGDispatchFunctionPointer: _c_pe.uint32 | None = ..., + GuardXFGTableDispatchFunctionPointer: _c_pe.uint32 | None = ..., + CastGuardOsDeterminedFailureMode: _c_pe.uint32 | None = ..., + GuardMemcpyFunctionPointer: _c_pe.uint32 | None = ..., + UmaFunctionPointers: _c_pe.uint32 | None = ..., + ): ... + @overload + def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... + + IMAGE_LOAD_CONFIG_DIRECTORY32: TypeAlias = _IMAGE_LOAD_CONFIG_DIRECTORY32 + class _IMAGE_LOAD_CONFIG_DIRECTORY64(__cs__.Structure): + Size: _c_pe.uint32 + TimeDateStamp: _c_pe.uint32 + MajorVersion: _c_pe.uint16 + MinorVersion: _c_pe.uint16 + GlobalFlagsClear: _c_pe.uint32 + GlobalFlagsSet: _c_pe.uint32 + CriticalSectionDefaultTimeout: _c_pe.uint32 + DeCommitFreeBlockThreshold: _c_pe.uint64 + DeCommitTotalFreeThreshold: _c_pe.uint64 + LockPrefixTable: _c_pe.uint64 + MaximumAllocationSize: _c_pe.uint64 + VirtualMemoryThreshold: _c_pe.uint64 + ProcessAffinityMask: _c_pe.uint64 + ProcessHeapFlags: _c_pe.uint32 + CSDVersion: _c_pe.uint16 + DependentLoadFlags: _c_pe.uint16 + EditList: _c_pe.uint64 + SecurityCookie: _c_pe.uint64 + SEHandlerTable: _c_pe.uint64 + SEHandlerCount: _c_pe.uint64 + GuardCFCheckFunctionPointer: _c_pe.uint64 + GuardCFDispatchFunctionPointer: _c_pe.uint64 + GuardCFFunctionTable: _c_pe.uint64 + GuardCFFunctionCount: _c_pe.uint64 + GuardFlags: _c_pe.IMAGE_GUARD + CodeIntegrity: _c_pe._IMAGE_LOAD_CONFIG_CODE_INTEGRITY + GuardAddressTakenIatEntryTable: _c_pe.uint64 + GuardAddressTakenIatEntryCount: _c_pe.uint64 + GuardLongJumpTargetTable: _c_pe.uint64 + GuardLongJumpTargetCount: _c_pe.uint64 + DynamicValueRelocTable: _c_pe.uint64 + CHPEMetadataPointer: _c_pe.uint64 + GuardRFFailureRoutine: _c_pe.uint64 + GuardRFFailureRoutineFunctionPointer: _c_pe.uint64 + DynamicValueRelocTableOffset: _c_pe.uint32 + DynamicValueRelocTableSection: _c_pe.uint16 + Reserved2: _c_pe.uint16 + GuardRFVerifyStackPointerFunctionPointer: _c_pe.uint64 + HotPatchTableOffset: _c_pe.uint32 + Reserved3: _c_pe.uint32 + EnclaveConfigurationPointer: _c_pe.uint64 + VolatileMetadataPointer: _c_pe.uint64 + GuardEHContinuationTable: _c_pe.uint64 + GuardEHContinuationCount: _c_pe.uint64 + GuardXFGCheckFunctionPointer: _c_pe.uint64 + GuardXFGDispatchFunctionPointer: _c_pe.uint64 + GuardXFGTableDispatchFunctionPointer: _c_pe.uint64 + CastGuardOsDeterminedFailureMode: _c_pe.uint64 + GuardMemcpyFunctionPointer: _c_pe.uint64 + UmaFunctionPointers: _c_pe.uint64 + @overload + def __init__( + self, + Size: _c_pe.uint32 | None = ..., + TimeDateStamp: _c_pe.uint32 | None = ..., + MajorVersion: _c_pe.uint16 | None = ..., + MinorVersion: _c_pe.uint16 | None = ..., + GlobalFlagsClear: _c_pe.uint32 | None = ..., + GlobalFlagsSet: _c_pe.uint32 | None = ..., + CriticalSectionDefaultTimeout: _c_pe.uint32 | None = ..., + DeCommitFreeBlockThreshold: _c_pe.uint64 | None = ..., + DeCommitTotalFreeThreshold: _c_pe.uint64 | None = ..., + LockPrefixTable: _c_pe.uint64 | None = ..., + MaximumAllocationSize: _c_pe.uint64 | None = ..., + VirtualMemoryThreshold: _c_pe.uint64 | None = ..., + ProcessAffinityMask: _c_pe.uint64 | None = ..., + ProcessHeapFlags: _c_pe.uint32 | None = ..., + CSDVersion: _c_pe.uint16 | None = ..., + DependentLoadFlags: _c_pe.uint16 | None = ..., + EditList: _c_pe.uint64 | None = ..., + SecurityCookie: _c_pe.uint64 | None = ..., + SEHandlerTable: _c_pe.uint64 | None = ..., + SEHandlerCount: _c_pe.uint64 | None = ..., + GuardCFCheckFunctionPointer: _c_pe.uint64 | None = ..., + GuardCFDispatchFunctionPointer: _c_pe.uint64 | None = ..., + GuardCFFunctionTable: _c_pe.uint64 | None = ..., + GuardCFFunctionCount: _c_pe.uint64 | None = ..., + GuardFlags: _c_pe.IMAGE_GUARD | None = ..., + CodeIntegrity: _c_pe._IMAGE_LOAD_CONFIG_CODE_INTEGRITY | None = ..., + GuardAddressTakenIatEntryTable: _c_pe.uint64 | None = ..., + GuardAddressTakenIatEntryCount: _c_pe.uint64 | None = ..., + GuardLongJumpTargetTable: _c_pe.uint64 | None = ..., + GuardLongJumpTargetCount: _c_pe.uint64 | None = ..., + DynamicValueRelocTable: _c_pe.uint64 | None = ..., + CHPEMetadataPointer: _c_pe.uint64 | None = ..., + GuardRFFailureRoutine: _c_pe.uint64 | None = ..., + GuardRFFailureRoutineFunctionPointer: _c_pe.uint64 | None = ..., + DynamicValueRelocTableOffset: _c_pe.uint32 | None = ..., + DynamicValueRelocTableSection: _c_pe.uint16 | None = ..., + Reserved2: _c_pe.uint16 | None = ..., + GuardRFVerifyStackPointerFunctionPointer: _c_pe.uint64 | None = ..., + HotPatchTableOffset: _c_pe.uint32 | None = ..., + Reserved3: _c_pe.uint32 | None = ..., + EnclaveConfigurationPointer: _c_pe.uint64 | None = ..., + VolatileMetadataPointer: _c_pe.uint64 | None = ..., + GuardEHContinuationTable: _c_pe.uint64 | None = ..., + GuardEHContinuationCount: _c_pe.uint64 | None = ..., + GuardXFGCheckFunctionPointer: _c_pe.uint64 | None = ..., + GuardXFGDispatchFunctionPointer: _c_pe.uint64 | None = ..., + GuardXFGTableDispatchFunctionPointer: _c_pe.uint64 | None = ..., + CastGuardOsDeterminedFailureMode: _c_pe.uint64 | None = ..., + GuardMemcpyFunctionPointer: _c_pe.uint64 | None = ..., + UmaFunctionPointers: _c_pe.uint64 | None = ..., + ): ... + @overload + def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... + + IMAGE_LOAD_CONFIG_DIRECTORY64: TypeAlias = _IMAGE_LOAD_CONFIG_DIRECTORY64 + class _IMAGE_CHPE_METADATA_X86(__cs__.Structure): + Version: _c_pe.uint32 + CHPECodeAddressRangeOffset: _c_pe.uint32 + CHPECodeAddressRangeCount: _c_pe.uint32 + WowA64ExceptionHandlerFunctionPointer: _c_pe.uint32 + WowA64DispatchCallFunctionPointer: _c_pe.uint32 + WowA64DispatchIndirectCallFunctionPointer: _c_pe.uint32 + WowA64DispatchIndirectCallCfgFunctionPointer: _c_pe.uint32 + WowA64DispatchRetFunctionPointer: _c_pe.uint32 + WowA64DispatchRetLeafFunctionPointer: _c_pe.uint32 + WowA64DispatchJumpFunctionPointer: _c_pe.uint32 + CompilerIATPointer: _c_pe.uint32 + WowA64RdtscFunctionPointer: _c_pe.uint32 + @overload + def __init__( + self, + Version: _c_pe.uint32 | None = ..., + CHPECodeAddressRangeOffset: _c_pe.uint32 | None = ..., + CHPECodeAddressRangeCount: _c_pe.uint32 | None = ..., + WowA64ExceptionHandlerFunctionPointer: _c_pe.uint32 | None = ..., + WowA64DispatchCallFunctionPointer: _c_pe.uint32 | None = ..., + WowA64DispatchIndirectCallFunctionPointer: _c_pe.uint32 | None = ..., + WowA64DispatchIndirectCallCfgFunctionPointer: _c_pe.uint32 | None = ..., + WowA64DispatchRetFunctionPointer: _c_pe.uint32 | None = ..., + WowA64DispatchRetLeafFunctionPointer: _c_pe.uint32 | None = ..., + WowA64DispatchJumpFunctionPointer: _c_pe.uint32 | None = ..., + CompilerIATPointer: _c_pe.uint32 | None = ..., + WowA64RdtscFunctionPointer: _c_pe.uint32 | None = ..., + ): ... + @overload + def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... + + IMAGE_CHPE_METADATA_X86: TypeAlias = _IMAGE_CHPE_METADATA_X86 + class _IMAGE_CHPE_RANGE_ENTRY(__cs__.Structure): + StartOffset: _c_pe.uint32 + NativeCode: _c_pe.uint32 + AddressBits: _c_pe.uint32 + Length: _c_pe.uint32 + @overload + def __init__( + self, + StartOffset: _c_pe.uint32 | None = ..., + NativeCode: _c_pe.uint32 | None = ..., + AddressBits: _c_pe.uint32 | None = ..., + Length: _c_pe.uint32 | None = ..., + ): ... + @overload + def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... + + IMAGE_CHPE_RANGE_ENTRY: TypeAlias = _IMAGE_CHPE_RANGE_ENTRY + class _IMAGE_ARM64EC_METADATA(__cs__.Structure): + Version: _c_pe.uint32 + CodeMap: _c_pe.uint32 + CodeMapCount: _c_pe.uint32 + CodeRangesToEntryPoints: _c_pe.uint32 + RedirectionMetadata: _c_pe.uint32 + tbd__os_arm64x_dispatch_call_no_redirect: _c_pe.uint32 + tbd__os_arm64x_dispatch_ret: _c_pe.uint32 + tbd__os_arm64x_dispatch_call: _c_pe.uint32 + tbd__os_arm64x_dispatch_icall: _c_pe.uint32 + tbd__os_arm64x_dispatch_icall_cfg: _c_pe.uint32 + AlternateEntryPoint: _c_pe.uint32 + AuxiliaryIAT: _c_pe.uint32 + CodeRangesToEntryPointsCount: _c_pe.uint32 + RedirectionMetadataCount: _c_pe.uint32 + GetX64InformationFunctionPointer: _c_pe.uint32 + SetX64InformationFunctionPointer: _c_pe.uint32 + ExtraRFETable: _c_pe.uint32 + ExtraRFETableSize: _c_pe.uint32 + __os_arm64x_dispatch_fptr: _c_pe.uint32 + AuxiliaryIATCopy: _c_pe.uint32 + @overload + def __init__( + self, + Version: _c_pe.uint32 | None = ..., + CodeMap: _c_pe.uint32 | None = ..., + CodeMapCount: _c_pe.uint32 | None = ..., + CodeRangesToEntryPoints: _c_pe.uint32 | None = ..., + RedirectionMetadata: _c_pe.uint32 | None = ..., + tbd__os_arm64x_dispatch_call_no_redirect: _c_pe.uint32 | None = ..., + tbd__os_arm64x_dispatch_ret: _c_pe.uint32 | None = ..., + tbd__os_arm64x_dispatch_call: _c_pe.uint32 | None = ..., + tbd__os_arm64x_dispatch_icall: _c_pe.uint32 | None = ..., + tbd__os_arm64x_dispatch_icall_cfg: _c_pe.uint32 | None = ..., + AlternateEntryPoint: _c_pe.uint32 | None = ..., + AuxiliaryIAT: _c_pe.uint32 | None = ..., + CodeRangesToEntryPointsCount: _c_pe.uint32 | None = ..., + RedirectionMetadataCount: _c_pe.uint32 | None = ..., + GetX64InformationFunctionPointer: _c_pe.uint32 | None = ..., + SetX64InformationFunctionPointer: _c_pe.uint32 | None = ..., + ExtraRFETable: _c_pe.uint32 | None = ..., + ExtraRFETableSize: _c_pe.uint32 | None = ..., + __os_arm64x_dispatch_fptr: _c_pe.uint32 | None = ..., + AuxiliaryIATCopy: _c_pe.uint32 | None = ..., + ): ... + @overload + def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... + + IMAGE_ARM64EC_METADATA: TypeAlias = _IMAGE_ARM64EC_METADATA + class _IMAGE_ARM64EC_METADATA_V2(__cs__.Structure): + Version: _c_pe.uint32 + CodeMap: _c_pe.uint32 + CodeMapCount: _c_pe.uint32 + CodeRangesToEntryPoints: _c_pe.uint32 + RedirectionMetadata: _c_pe.uint32 + tbd__os_arm64x_dispatch_call_no_redirect: _c_pe.uint32 + tbd__os_arm64x_dispatch_ret: _c_pe.uint32 + tbd__os_arm64x_dispatch_call: _c_pe.uint32 + tbd__os_arm64x_dispatch_icall: _c_pe.uint32 + tbd__os_arm64x_dispatch_icall_cfg: _c_pe.uint32 + AlternateEntryPoint: _c_pe.uint32 + AuxiliaryIAT: _c_pe.uint32 + CodeRangesToEntryPointsCount: _c_pe.uint32 + RedirectionMetadataCount: _c_pe.uint32 + GetX64InformationFunctionPointer: _c_pe.uint32 + SetX64InformationFunctionPointer: _c_pe.uint32 + ExtraRFETable: _c_pe.uint32 + ExtraRFETableSize: _c_pe.uint32 + __os_arm64x_dispatch_fptr: _c_pe.uint32 + AuxiliaryIATCopy: _c_pe.uint32 + AuxDelayloadIAT: _c_pe.uint32 + AuxDelayloadIATCopy: _c_pe.uint32 + ReservedBitField: _c_pe.uint32 + @overload + def __init__( + self, + Version: _c_pe.uint32 | None = ..., + CodeMap: _c_pe.uint32 | None = ..., + CodeMapCount: _c_pe.uint32 | None = ..., + CodeRangesToEntryPoints: _c_pe.uint32 | None = ..., + RedirectionMetadata: _c_pe.uint32 | None = ..., + tbd__os_arm64x_dispatch_call_no_redirect: _c_pe.uint32 | None = ..., + tbd__os_arm64x_dispatch_ret: _c_pe.uint32 | None = ..., + tbd__os_arm64x_dispatch_call: _c_pe.uint32 | None = ..., + tbd__os_arm64x_dispatch_icall: _c_pe.uint32 | None = ..., + tbd__os_arm64x_dispatch_icall_cfg: _c_pe.uint32 | None = ..., + AlternateEntryPoint: _c_pe.uint32 | None = ..., + AuxiliaryIAT: _c_pe.uint32 | None = ..., + CodeRangesToEntryPointsCount: _c_pe.uint32 | None = ..., + RedirectionMetadataCount: _c_pe.uint32 | None = ..., + GetX64InformationFunctionPointer: _c_pe.uint32 | None = ..., + SetX64InformationFunctionPointer: _c_pe.uint32 | None = ..., + ExtraRFETable: _c_pe.uint32 | None = ..., + ExtraRFETableSize: _c_pe.uint32 | None = ..., + __os_arm64x_dispatch_fptr: _c_pe.uint32 | None = ..., + AuxiliaryIATCopy: _c_pe.uint32 | None = ..., + AuxDelayloadIAT: _c_pe.uint32 | None = ..., + AuxDelayloadIATCopy: _c_pe.uint32 | None = ..., + ReservedBitField: _c_pe.uint32 | None = ..., + ): ... + @overload + def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... + + IMAGE_ARM64EC_METADATA_V2: TypeAlias = _IMAGE_ARM64EC_METADATA_V2 + class _IMAGE_ARM64EC_REDIRECTION_ENTRY(__cs__.Structure): + Source: _c_pe.uint32 + Destination: _c_pe.uint32 + @overload + def __init__(self, Source: _c_pe.uint32 | None = ..., Destination: _c_pe.uint32 | None = ...): ... + @overload + def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... + + IMAGE_ARM64EC_REDIRECTION_ENTRY: TypeAlias = _IMAGE_ARM64EC_REDIRECTION_ENTRY + class _IMAGE_ARM64EC_CODE_RANGE_ENTRY_POINT(__cs__.Structure): + StartRva: _c_pe.uint32 + EndRva: _c_pe.uint32 + EntryPoint: _c_pe.uint32 + @overload + def __init__( + self, + StartRva: _c_pe.uint32 | None = ..., + EndRva: _c_pe.uint32 | None = ..., + EntryPoint: _c_pe.uint32 | None = ..., + ): ... + @overload + def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... + + IMAGE_ARM64EC_CODE_RANGE_ENTRY_POINT: TypeAlias = _IMAGE_ARM64EC_CODE_RANGE_ENTRY_POINT + class _IMAGE_DVRT_ARM64X_FIXUP_RECORD(__cs__.Structure): + Offset: _c_pe.uint16 + Type: _c_pe.uint16 + Size: _c_pe.uint16 + @overload + def __init__( + self, Offset: _c_pe.uint16 | None = ..., Type: _c_pe.uint16 | None = ..., Size: _c_pe.uint16 | None = ... + ): ... + @overload + def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... + + IMAGE_DVRT_ARM64X_FIXUP_RECORD: TypeAlias = _IMAGE_DVRT_ARM64X_FIXUP_RECORD + class _IMAGE_DVRT_ARM64X_DELTA_FIXUP_RECORD(__cs__.Structure): + Offset: _c_pe.uint16 + Type: _c_pe.uint16 + Sign: _c_pe.uint16 + Scale: _c_pe.uint16 + @overload + def __init__( + self, + Offset: _c_pe.uint16 | None = ..., + Type: _c_pe.uint16 | None = ..., + Sign: _c_pe.uint16 | None = ..., + Scale: _c_pe.uint16 | None = ..., + ): ... + @overload + def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... + + IMAGE_DVRT_ARM64X_DELTA_FIXUP_RECORD: TypeAlias = _IMAGE_DVRT_ARM64X_DELTA_FIXUP_RECORD + class _IMAGE_HOT_PATCH_INFO(__cs__.Structure): + Version: _c_pe.uint32 + Size: _c_pe.uint32 + SequenceNumber: _c_pe.uint32 + BaseImageList: _c_pe.uint32 + BaseImageCount: _c_pe.uint32 + BufferOffset: _c_pe.uint32 + ExtraPatchSize: _c_pe.uint32 + MinSequenceNumber: _c_pe.uint32 + Flags: _c_pe.uint32 + @overload + def __init__( + self, + Version: _c_pe.uint32 | None = ..., + Size: _c_pe.uint32 | None = ..., + SequenceNumber: _c_pe.uint32 | None = ..., + BaseImageList: _c_pe.uint32 | None = ..., + BaseImageCount: _c_pe.uint32 | None = ..., + BufferOffset: _c_pe.uint32 | None = ..., + ExtraPatchSize: _c_pe.uint32 | None = ..., + MinSequenceNumber: _c_pe.uint32 | None = ..., + Flags: _c_pe.uint32 | None = ..., + ): ... + @overload + def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... + + IMAGE_HOT_PATCH_INFO: TypeAlias = _IMAGE_HOT_PATCH_INFO + class _IMAGE_HOT_PATCH_BASE(__cs__.Structure): + SequenceNumber: _c_pe.uint32 + Flags: _c_pe.uint32 + OriginalTimeDateStamp: _c_pe.uint32 + OriginalCheckSum: _c_pe.uint32 + CodeIntegrityInfo: _c_pe.uint32 + CodeIntegritySize: _c_pe.uint32 + PatchTable: _c_pe.uint32 + BufferOffset: _c_pe.uint32 + @overload + def __init__( + self, + SequenceNumber: _c_pe.uint32 | None = ..., + Flags: _c_pe.uint32 | None = ..., + OriginalTimeDateStamp: _c_pe.uint32 | None = ..., + OriginalCheckSum: _c_pe.uint32 | None = ..., + CodeIntegrityInfo: _c_pe.uint32 | None = ..., + CodeIntegritySize: _c_pe.uint32 | None = ..., + PatchTable: _c_pe.uint32 | None = ..., + BufferOffset: _c_pe.uint32 | None = ..., + ): ... + @overload + def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... + + IMAGE_HOT_PATCH_BASE: TypeAlias = _IMAGE_HOT_PATCH_BASE + class _IMAGE_HOT_PATCH_MACHINE(__cs__.Structure): + _x86: _c_pe.uint32 + Amd64: _c_pe.uint32 + Arm64: _c_pe.uint32 + Amd64EC: _c_pe.uint32 + @overload + def __init__( + self, + _x86: _c_pe.uint32 | None = ..., + Amd64: _c_pe.uint32 | None = ..., + Arm64: _c_pe.uint32 | None = ..., + Amd64EC: _c_pe.uint32 | None = ..., + ): ... + @overload + def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... + + IMAGE_HOT_PATCH_MACHINE: TypeAlias = _IMAGE_HOT_PATCH_MACHINE + class _IMAGE_HOT_PATCH_HASHES(__cs__.Structure): + SHA256: __cs__.Array[_c_pe.uint8] + SHA1: __cs__.Array[_c_pe.uint8] + @overload + def __init__( + self, SHA256: __cs__.Array[_c_pe.uint8] | None = ..., SHA1: __cs__.Array[_c_pe.uint8] | None = ... + ): ... + @overload + def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... + + IMAGE_HOT_PATCH_HASHES: TypeAlias = _IMAGE_HOT_PATCH_HASHES + class IMAGE_HOT_PATCH(__cs__.Enum): + NONE = ... + FUNCTION = ... + ABSOLUTE = ... + REL32 = ... + CALL_TARGET = ... + INDIRECT = ... + NO_CALL_TARGET = ... + DYNAMIC_VALUE = ... + + class _IMAGE_CE_RUNTIME_FUNCTION_ENTRY(__cs__.Structure): + FuncStart: _c_pe.uint32 + PrologLen: _c_pe.uint32 + FuncLen: _c_pe.uint32 + ThirtyTwoBit: _c_pe.uint32 + ExceptionFlag: _c_pe.uint32 + @overload + def __init__( + self, + FuncStart: _c_pe.uint32 | None = ..., + PrologLen: _c_pe.uint32 | None = ..., + FuncLen: _c_pe.uint32 | None = ..., + ThirtyTwoBit: _c_pe.uint32 | None = ..., + ExceptionFlag: _c_pe.uint32 | None = ..., + ): ... + @overload + def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... + + IMAGE_CE_RUNTIME_FUNCTION_ENTRY: TypeAlias = _IMAGE_CE_RUNTIME_FUNCTION_ENTRY + class _IMAGE_ARM_RUNTIME_FUNCTION_ENTRY(__cs__.Structure): + BeginAddress: _c_pe.uint32 + UnwindData: _c_pe.uint32 + Flag: _c_pe.uint32 + FunctionLength: _c_pe.uint32 + Ret: _c_pe.uint32 + H: _c_pe.uint32 + Reg: _c_pe.uint32 + R: _c_pe.uint32 + L: _c_pe.uint32 + C: _c_pe.uint32 + StackAdjust: _c_pe.uint32 + @overload + def __init__( + self, + BeginAddress: _c_pe.uint32 | None = ..., + UnwindData: _c_pe.uint32 | None = ..., + Flag: _c_pe.uint32 | None = ..., + FunctionLength: _c_pe.uint32 | None = ..., + Ret: _c_pe.uint32 | None = ..., + H: _c_pe.uint32 | None = ..., + Reg: _c_pe.uint32 | None = ..., + R: _c_pe.uint32 | None = ..., + L: _c_pe.uint32 | None = ..., + C: _c_pe.uint32 | None = ..., + StackAdjust: _c_pe.uint32 | None = ..., + ): ... + @overload + def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... + + IMAGE_ARM_RUNTIME_FUNCTION_ENTRY: TypeAlias = _IMAGE_ARM_RUNTIME_FUNCTION_ENTRY + class ARM64_FNPDATA_FLAGS(__cs__.Enum): + PdataRefToFullXdata = ... + PdataPackedUnwindFunction = ... + PdataPackedUnwindFragment = ... + + class ARM64_FNPDATA_CR(__cs__.Enum): + PdataCrUnchained = ... + PdataCrUnchainedSavedLr = ... + PdataCrChainedWithPac = ... + PdataCrChained = ... + + class _IMAGE_ARM64_RUNTIME_FUNCTION_ENTRY(__cs__.Structure): + BeginAddress: _c_pe.uint32 + UnwindData: _c_pe.uint32 + Flag: _c_pe.uint32 + FunctionLength: _c_pe.uint32 + RegF: _c_pe.uint32 + RegI: _c_pe.uint32 + H: _c_pe.uint32 + CR: _c_pe.uint32 + FrameSize: _c_pe.uint32 + @overload + def __init__( + self, + BeginAddress: _c_pe.uint32 | None = ..., + UnwindData: _c_pe.uint32 | None = ..., + Flag: _c_pe.uint32 | None = ..., + FunctionLength: _c_pe.uint32 | None = ..., + RegF: _c_pe.uint32 | None = ..., + RegI: _c_pe.uint32 | None = ..., + H: _c_pe.uint32 | None = ..., + CR: _c_pe.uint32 | None = ..., + FrameSize: _c_pe.uint32 | None = ..., + ): ... + @overload + def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... + + IMAGE_ARM64_RUNTIME_FUNCTION_ENTRY: TypeAlias = _IMAGE_ARM64_RUNTIME_FUNCTION_ENTRY + class _IMAGE_ARM64_RUNTIME_FUNCTION_ENTRY_XDATA(__cs__.Union): + HeaderData: _c_pe.uint32 + FunctionLength: _c_pe.uint32 + Version: _c_pe.uint32 + ExceptionDataPresent: _c_pe.uint32 + EpilogInHeader: _c_pe.uint32 + EpilogCount: _c_pe.uint32 + CodeWords: _c_pe.uint32 + @overload + def __init__( + self, + HeaderData: _c_pe.uint32 | None = ..., + FunctionLength: _c_pe.uint32 | None = ..., + Version: _c_pe.uint32 | None = ..., + ExceptionDataPresent: _c_pe.uint32 | None = ..., + EpilogInHeader: _c_pe.uint32 | None = ..., + EpilogCount: _c_pe.uint32 | None = ..., + CodeWords: _c_pe.uint32 | None = ..., + ): ... + @overload + def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... + + IMAGE_ARM64_RUNTIME_FUNCTION_ENTRY_XDATA: TypeAlias = _IMAGE_ARM64_RUNTIME_FUNCTION_ENTRY_XDATA + class IMAGE_ARM64_RUNTIME_FUNCTION_ENTRY_XDATA_EXTENDED(__cs__.Union): + ExtendedHeaderData: _c_pe.uint32 + ExtendedEpilogCount: _c_pe.uint32 + ExtendedCodeWords: _c_pe.uint32 + @overload + def __init__( + self, + ExtendedHeaderData: _c_pe.uint32 | None = ..., + ExtendedEpilogCount: _c_pe.uint32 | None = ..., + ExtendedCodeWords: _c_pe.uint32 | None = ..., + ): ... + @overload + def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... + + class IMAGE_ARM64_RUNTIME_FUNCTION_ENTRY_XDATA_EPILOG_SCOPE(__cs__.Union): + EpilogScopeData: _c_pe.uint32 + EpilogStartOffset: _c_pe.uint32 + Res0: _c_pe.uint32 + EpilogStartIndex: _c_pe.uint32 + @overload + def __init__( + self, + EpilogScopeData: _c_pe.uint32 | None = ..., + EpilogStartOffset: _c_pe.uint32 | None = ..., + Res0: _c_pe.uint32 | None = ..., + EpilogStartIndex: _c_pe.uint32 | None = ..., + ): ... + @overload + def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... + + class _IMAGE_ALPHA64_RUNTIME_FUNCTION_ENTRY(__cs__.Structure): + BeginAddress: _c_pe.uint64 + EndAddress: _c_pe.uint64 + ExceptionHandler: _c_pe.uint64 + HandlerData: _c_pe.uint64 + PrologEndAddress: _c_pe.uint64 + @overload + def __init__( + self, + BeginAddress: _c_pe.uint64 | None = ..., + EndAddress: _c_pe.uint64 | None = ..., + ExceptionHandler: _c_pe.uint64 | None = ..., + HandlerData: _c_pe.uint64 | None = ..., + PrologEndAddress: _c_pe.uint64 | None = ..., + ): ... + @overload + def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... + + IMAGE_ALPHA64_RUNTIME_FUNCTION_ENTRY: TypeAlias = _IMAGE_ALPHA64_RUNTIME_FUNCTION_ENTRY + class _IMAGE_ALPHA_RUNTIME_FUNCTION_ENTRY(__cs__.Structure): + BeginAddress: _c_pe.uint32 + EndAddress: _c_pe.uint32 + ExceptionHandler: _c_pe.uint32 + HandlerData: _c_pe.uint32 + PrologEndAddress: _c_pe.uint32 + @overload + def __init__( + self, + BeginAddress: _c_pe.uint32 | None = ..., + EndAddress: _c_pe.uint32 | None = ..., + ExceptionHandler: _c_pe.uint32 | None = ..., + HandlerData: _c_pe.uint32 | None = ..., + PrologEndAddress: _c_pe.uint32 | None = ..., + ): ... + @overload + def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... + + IMAGE_ALPHA_RUNTIME_FUNCTION_ENTRY: TypeAlias = _IMAGE_ALPHA_RUNTIME_FUNCTION_ENTRY + class _IMAGE_MIPS_RUNTIME_FUNCTION_ENTRY(__cs__.Structure): + BeginAddress: _c_pe.uint32 + EndAddress: _c_pe.uint32 + ExceptionHandler: _c_pe.uint32 + HandlerData: _c_pe.uint32 + PrologEndAddress: _c_pe.uint32 + @overload + def __init__( + self, + BeginAddress: _c_pe.uint32 | None = ..., + EndAddress: _c_pe.uint32 | None = ..., + ExceptionHandler: _c_pe.uint32 | None = ..., + HandlerData: _c_pe.uint32 | None = ..., + PrologEndAddress: _c_pe.uint32 | None = ..., + ): ... + @overload + def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... + + IMAGE_MIPS_RUNTIME_FUNCTION_ENTRY: TypeAlias = _IMAGE_MIPS_RUNTIME_FUNCTION_ENTRY + class _IMAGE_RUNTIME_FUNCTION_ENTRY(__cs__.Structure): + BeginAddress: _c_pe.uint32 + EndAddress: _c_pe.uint32 + UnwindInfoAddress: _c_pe.uint32 + UnwindData: _c_pe.uint32 + @overload + def __init__( + self, + BeginAddress: _c_pe.uint32 | None = ..., + EndAddress: _c_pe.uint32 | None = ..., + UnwindInfoAddress: _c_pe.uint32 | None = ..., + UnwindData: _c_pe.uint32 | None = ..., + ): ... + @overload + def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... + + IMAGE_RUNTIME_FUNCTION_ENTRY: TypeAlias = _IMAGE_RUNTIME_FUNCTION_ENTRY + class _IMAGE_ENCLAVE_CONFIG32(__cs__.Structure): + Size: _c_pe.uint32 + MinimumRequiredConfigSize: _c_pe.uint32 + PolicyFlags: _c_pe.uint32 + NumberOfImports: _c_pe.uint32 + ImportList: _c_pe.uint32 + ImportEntrySize: _c_pe.uint32 + FamilyID: __cs__.Array[_c_pe.uint8] + ImageID: __cs__.Array[_c_pe.uint8] + ImageVersion: _c_pe.uint32 + SecurityVersion: _c_pe.uint32 + EnclaveSize: _c_pe.uint32 + NumberOfThreads: _c_pe.uint32 + EnclaveFlags: _c_pe.uint32 + @overload + def __init__( + self, + Size: _c_pe.uint32 | None = ..., + MinimumRequiredConfigSize: _c_pe.uint32 | None = ..., + PolicyFlags: _c_pe.uint32 | None = ..., + NumberOfImports: _c_pe.uint32 | None = ..., + ImportList: _c_pe.uint32 | None = ..., + ImportEntrySize: _c_pe.uint32 | None = ..., + FamilyID: __cs__.Array[_c_pe.uint8] | None = ..., + ImageID: __cs__.Array[_c_pe.uint8] | None = ..., + ImageVersion: _c_pe.uint32 | None = ..., + SecurityVersion: _c_pe.uint32 | None = ..., + EnclaveSize: _c_pe.uint32 | None = ..., + NumberOfThreads: _c_pe.uint32 | None = ..., + EnclaveFlags: _c_pe.uint32 | None = ..., + ): ... + @overload + def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... + + IMAGE_ENCLAVE_CONFIG32: TypeAlias = _IMAGE_ENCLAVE_CONFIG32 + class _IMAGE_ENCLAVE_CONFIG64(__cs__.Structure): + Size: _c_pe.uint32 + MinimumRequiredConfigSize: _c_pe.uint32 + PolicyFlags: _c_pe.uint32 + NumberOfImports: _c_pe.uint32 + ImportList: _c_pe.uint32 + ImportEntrySize: _c_pe.uint32 + FamilyID: __cs__.Array[_c_pe.uint8] + ImageID: __cs__.Array[_c_pe.uint8] + ImageVersion: _c_pe.uint32 + SecurityVersion: _c_pe.uint32 + EnclaveSize: _c_pe.uint64 + NumberOfThreads: _c_pe.uint32 + EnclaveFlags: _c_pe.uint32 + @overload + def __init__( + self, + Size: _c_pe.uint32 | None = ..., + MinimumRequiredConfigSize: _c_pe.uint32 | None = ..., + PolicyFlags: _c_pe.uint32 | None = ..., + NumberOfImports: _c_pe.uint32 | None = ..., + ImportList: _c_pe.uint32 | None = ..., + ImportEntrySize: _c_pe.uint32 | None = ..., + FamilyID: __cs__.Array[_c_pe.uint8] | None = ..., + ImageID: __cs__.Array[_c_pe.uint8] | None = ..., + ImageVersion: _c_pe.uint32 | None = ..., + SecurityVersion: _c_pe.uint32 | None = ..., + EnclaveSize: _c_pe.uint64 | None = ..., + NumberOfThreads: _c_pe.uint32 | None = ..., + EnclaveFlags: _c_pe.uint32 | None = ..., + ): ... + @overload + def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... + + IMAGE_ENCLAVE_CONFIG64: TypeAlias = _IMAGE_ENCLAVE_CONFIG64 + class _IMAGE_ENCLAVE_IMPORT(__cs__.Structure): + MatchType: _c_pe.uint32 + MinimumSecurityVersion: _c_pe.uint32 + UniqueOrAuthorID: __cs__.Array[_c_pe.uint8] + FamilyID: __cs__.Array[_c_pe.uint8] + ImageID: __cs__.Array[_c_pe.uint8] + ImportName: _c_pe.uint32 + Reserved: _c_pe.uint32 + @overload + def __init__( + self, + MatchType: _c_pe.uint32 | None = ..., + MinimumSecurityVersion: _c_pe.uint32 | None = ..., + UniqueOrAuthorID: __cs__.Array[_c_pe.uint8] | None = ..., + FamilyID: __cs__.Array[_c_pe.uint8] | None = ..., + ImageID: __cs__.Array[_c_pe.uint8] | None = ..., + ImportName: _c_pe.uint32 | None = ..., + Reserved: _c_pe.uint32 | None = ..., + ): ... + @overload + def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... + + IMAGE_ENCLAVE_IMPORT: TypeAlias = _IMAGE_ENCLAVE_IMPORT + class WIN_CERT_TYPE(__cs__.Enum): + X509 = ... + PKCS_SIGNED_DATA = ... + RESERVED_1 = ... + TS_STACK_SIGNED = ... + + class _WIN_CERTIFICATE(__cs__.Structure): + dwLength: _c_pe.uint32 + wRevision: _c_pe.uint16 + wCertificateType: _c_pe.WIN_CERT_TYPE + bCertificate: __cs__.CharArray + @overload + def __init__( + self, + dwLength: _c_pe.uint32 | None = ..., + wRevision: _c_pe.uint16 | None = ..., + wCertificateType: _c_pe.WIN_CERT_TYPE | None = ..., + bCertificate: __cs__.CharArray | None = ..., + ): ... + @overload + def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... + + WIN_CERTIFICATE: TypeAlias = _WIN_CERTIFICATE + class IMAGE_DEBUG_TYPE(__cs__.Enum): + UNKNOWN = ... + COFF = ... + CODEVIEW = ... + FPO = ... + MISC = ... + EXCEPTION = ... + FIXUP = ... + OMAP_TO_SRC = ... + OMAP_FROM_SRC = ... + BORLAND = ... + RESERVED10 = ... + BBT = ... + CLSID = ... + VC_FEATURE = ... + POGO = ... + ILTCG = ... + MPX = ... + REPRO = ... + EMBEDDED_PORTABLE_PDB = ... + SPGO = ... + PDBCHECKSUM = ... + EX_DLLCHARACTERISTICS = ... + PERFMAP = ... + + class IMAGE_DLLCHARACTERISTICS_EX(__cs__.Enum): + CET_COMPAT = ... + CET_COMPAT_STRICT_MODE = ... + CET_SET_CONTEXT_IP_VALIDATION_RELAXED_MODE = ... + CET_DYNAMIC_APIS_ALLOW_IN_PROC = ... + CET_RESERVED_1 = ... + CET_RESERVED_2 = ... + FORWARD_CFI_COMPAT = ... + HOTPATCH_COMPATIBLE = ... + + class _IMAGE_DEBUG_DIRECTORY(__cs__.Structure): + Characteristics: _c_pe.uint32 + TimeDateStamp: _c_pe.uint32 + MajorVersion: _c_pe.uint16 + MinorVersion: _c_pe.uint16 + Type: _c_pe.IMAGE_DEBUG_TYPE + SizeOfData: _c_pe.uint32 + AddressOfRawData: _c_pe.uint32 + PointerToRawData: _c_pe.uint32 + @overload + def __init__( + self, + Characteristics: _c_pe.uint32 | None = ..., + TimeDateStamp: _c_pe.uint32 | None = ..., + MajorVersion: _c_pe.uint16 | None = ..., + MinorVersion: _c_pe.uint16 | None = ..., + Type: _c_pe.IMAGE_DEBUG_TYPE | None = ..., + SizeOfData: _c_pe.uint32 | None = ..., + AddressOfRawData: _c_pe.uint32 | None = ..., + PointerToRawData: _c_pe.uint32 | None = ..., + ): ... + @overload + def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... + + IMAGE_DEBUG_DIRECTORY: TypeAlias = _IMAGE_DEBUG_DIRECTORY + class _IMAGE_COFF_SYMBOLS_HEADER(__cs__.Structure): + NumberOfSymbols: _c_pe.uint32 + LvaToFirstSymbol: _c_pe.uint32 + NumberOfLinenumbers: _c_pe.uint32 + LvaToFirstLinenumber: _c_pe.uint32 + RvaToFirstByteOfCode: _c_pe.uint32 + RvaToLastByteOfCode: _c_pe.uint32 + RvaToFirstByteOfData: _c_pe.uint32 + RvaToLastByteOfData: _c_pe.uint32 + @overload + def __init__( + self, + NumberOfSymbols: _c_pe.uint32 | None = ..., + LvaToFirstSymbol: _c_pe.uint32 | None = ..., + NumberOfLinenumbers: _c_pe.uint32 | None = ..., + LvaToFirstLinenumber: _c_pe.uint32 | None = ..., + RvaToFirstByteOfCode: _c_pe.uint32 | None = ..., + RvaToLastByteOfCode: _c_pe.uint32 | None = ..., + RvaToFirstByteOfData: _c_pe.uint32 | None = ..., + RvaToLastByteOfData: _c_pe.uint32 | None = ..., + ): ... + @overload + def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... + + IMAGE_COFF_SYMBOLS_HEADER: TypeAlias = _IMAGE_COFF_SYMBOLS_HEADER + class _CV_HEADER(__cs__.Structure): + Signature: _c_pe.uint32 + Offset: _c_pe.uint32 + @overload + def __init__(self, Signature: _c_pe.uint32 | None = ..., Offset: _c_pe.uint32 | None = ...): ... + @overload + def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... + + CV_HEADER: TypeAlias = _CV_HEADER + class _CV_INFO_PDB20(__cs__.Structure): + CvHeader: _c_pe._CV_HEADER + Signature: _c_pe.uint32 + Age: _c_pe.uint32 + PdbFileName: __cs__.CharArray + @overload + def __init__( + self, + CvHeader: _c_pe._CV_HEADER | None = ..., + Signature: _c_pe.uint32 | None = ..., + Age: _c_pe.uint32 | None = ..., + PdbFileName: __cs__.CharArray | None = ..., + ): ... + @overload + def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... + + CV_INFO_PDB20: TypeAlias = _CV_INFO_PDB20 + class _CV_INFO_PDB70(__cs__.Structure): + CvSignature: _c_pe.uint32 + Signature: __cs__.CharArray + Age: _c_pe.uint32 + PdbFileName: __cs__.CharArray + @overload + def __init__( + self, + CvSignature: _c_pe.uint32 | None = ..., + Signature: __cs__.CharArray | None = ..., + Age: _c_pe.uint32 | None = ..., + PdbFileName: __cs__.CharArray | None = ..., + ): ... + @overload + def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... + + CV_INFO_PDB70: TypeAlias = _CV_INFO_PDB70 + class _CV_INFO_MTOC(__cs__.Structure): + CvSignature: _c_pe.uint32 + Signature: __cs__.Array[_c_pe.uint8] + PdbFileName: __cs__.Array[_c_pe.uint8] + @overload + def __init__( + self, + CvSignature: _c_pe.uint32 | None = ..., + Signature: __cs__.Array[_c_pe.uint8] | None = ..., + PdbFileName: __cs__.Array[_c_pe.uint8] | None = ..., + ): ... + @overload + def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... + + CV_INFO_MTOC: TypeAlias = _CV_INFO_MTOC + class _FPO_DATA(__cs__.Structure): + ulOffStart: _c_pe.uint32 + cbProcSize: _c_pe.uint32 + cdwLocals: _c_pe.uint32 + cdwParams: _c_pe.uint16 + cbProlog: _c_pe.uint16 + cbRegs: _c_pe.uint16 + fHasSEH: _c_pe.uint16 + fUseBP: _c_pe.uint16 + reserved: _c_pe.uint16 + cbFrame: _c_pe.uint16 + @overload + def __init__( + self, + ulOffStart: _c_pe.uint32 | None = ..., + cbProcSize: _c_pe.uint32 | None = ..., + cdwLocals: _c_pe.uint32 | None = ..., + cdwParams: _c_pe.uint16 | None = ..., + cbProlog: _c_pe.uint16 | None = ..., + cbRegs: _c_pe.uint16 | None = ..., + fHasSEH: _c_pe.uint16 | None = ..., + fUseBP: _c_pe.uint16 | None = ..., + reserved: _c_pe.uint16 | None = ..., + cbFrame: _c_pe.uint16 | None = ..., + ): ... + @overload + def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... + + FPO_DATA: TypeAlias = _FPO_DATA + class _IMAGE_DEBUG_MISC(__cs__.Structure): + DataType: _c_pe.uint32 + Length: _c_pe.uint32 + Unicode: _c_pe.uint8 + Reserved: __cs__.Array[_c_pe.uint8] + @overload + def __init__( + self, + DataType: _c_pe.uint32 | None = ..., + Length: _c_pe.uint32 | None = ..., + Unicode: _c_pe.uint8 | None = ..., + Reserved: __cs__.Array[_c_pe.uint8] | None = ..., + ): ... + @overload + def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... + + IMAGE_DEBUG_MISC: TypeAlias = _IMAGE_DEBUG_MISC + class _VC_FEATURE(__cs__.Structure): + PreVC11: _c_pe.uint32 + CCpp: _c_pe.uint32 + Gs: _c_pe.uint32 + Sdl: _c_pe.uint32 + GuardN: _c_pe.uint32 + @overload + def __init__( + self, + PreVC11: _c_pe.uint32 | None = ..., + CCpp: _c_pe.uint32 | None = ..., + Gs: _c_pe.uint32 | None = ..., + Sdl: _c_pe.uint32 | None = ..., + GuardN: _c_pe.uint32 | None = ..., + ): ... + @overload + def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... + + VC_FEATURE: TypeAlias = _VC_FEATURE + class _IMAGE_FUNCTION_ENTRY(__cs__.Structure): + StartingAddress: _c_pe.uint32 + EndingAddress: _c_pe.uint32 + EndOfPrologue: _c_pe.uint32 + @overload + def __init__( + self, + StartingAddress: _c_pe.uint32 | None = ..., + EndingAddress: _c_pe.uint32 | None = ..., + EndOfPrologue: _c_pe.uint32 | None = ..., + ): ... + @overload + def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... + + IMAGE_FUNCTION_ENTRY: TypeAlias = _IMAGE_FUNCTION_ENTRY + class _IMAGE_FUNCTION_ENTRY64(__cs__.Structure): + StartingAddress: _c_pe.uint64 + EndingAddress: _c_pe.uint64 + EndOfPrologue: _c_pe.uint64 + UnwindInfoAddress: _c_pe.uint64 + @overload + def __init__( + self, + StartingAddress: _c_pe.uint64 | None = ..., + EndingAddress: _c_pe.uint64 | None = ..., + EndOfPrologue: _c_pe.uint64 | None = ..., + UnwindInfoAddress: _c_pe.uint64 | None = ..., + ): ... + @overload + def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... + + IMAGE_FUNCTION_ENTRY64: TypeAlias = _IMAGE_FUNCTION_ENTRY64 + class _IMAGE_SEPARATE_DEBUG_HEADER(__cs__.Structure): + Signature: _c_pe.uint16 + Flags: _c_pe.uint16 + Machine: _c_pe.uint16 + Characteristics: _c_pe.uint16 + TimeDateStamp: _c_pe.uint32 + CheckSum: _c_pe.uint32 + ImageBase: _c_pe.uint32 + SizeOfImage: _c_pe.uint32 + NumberOfSections: _c_pe.uint32 + ExportedNamesSize: _c_pe.uint32 + DebugDirectorySize: _c_pe.uint32 + SectionAlignment: _c_pe.uint32 + Reserved: __cs__.Array[_c_pe.uint32] + @overload + def __init__( + self, + Signature: _c_pe.uint16 | None = ..., + Flags: _c_pe.uint16 | None = ..., + Machine: _c_pe.uint16 | None = ..., + Characteristics: _c_pe.uint16 | None = ..., + TimeDateStamp: _c_pe.uint32 | None = ..., + CheckSum: _c_pe.uint32 | None = ..., + ImageBase: _c_pe.uint32 | None = ..., + SizeOfImage: _c_pe.uint32 | None = ..., + NumberOfSections: _c_pe.uint32 | None = ..., + ExportedNamesSize: _c_pe.uint32 | None = ..., + DebugDirectorySize: _c_pe.uint32 | None = ..., + SectionAlignment: _c_pe.uint32 | None = ..., + Reserved: __cs__.Array[_c_pe.uint32] | None = ..., + ): ... + @overload + def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... + + IMAGE_SEPARATE_DEBUG_HEADER: TypeAlias = _IMAGE_SEPARATE_DEBUG_HEADER + class _NON_PAGED_DEBUG_INFO(__cs__.Structure): + Signature: _c_pe.uint16 + Flags: _c_pe.uint16 + Size: _c_pe.uint32 + Machine: _c_pe.uint16 + Characteristics: _c_pe.uint16 + TimeDateStamp: _c_pe.uint32 + CheckSum: _c_pe.uint32 + SizeOfImage: _c_pe.uint32 + ImageBase: _c_pe.uint64 + @overload + def __init__( + self, + Signature: _c_pe.uint16 | None = ..., + Flags: _c_pe.uint16 | None = ..., + Size: _c_pe.uint32 | None = ..., + Machine: _c_pe.uint16 | None = ..., + Characteristics: _c_pe.uint16 | None = ..., + TimeDateStamp: _c_pe.uint32 | None = ..., + CheckSum: _c_pe.uint32 | None = ..., + SizeOfImage: _c_pe.uint32 | None = ..., + ImageBase: _c_pe.uint64 | None = ..., + ): ... + @overload + def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... + + NON_PAGED_DEBUG_INFO: TypeAlias = _NON_PAGED_DEBUG_INFO + class _ImageArchitectureHeader(__cs__.Structure): + AmaskValue: _c_pe.uint32 + _: _c_pe.int32 + AmaskShift: _c_pe.uint32 + FirstEntryRVA: _c_pe.uint32 + @overload + def __init__( + self, + AmaskValue: _c_pe.uint32 | None = ..., + _: _c_pe.int32 | None = ..., + AmaskShift: _c_pe.uint32 | None = ..., + FirstEntryRVA: _c_pe.uint32 | None = ..., + ): ... + @overload + def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... + + IMAGE_ARCHITECTURE_HEADER: TypeAlias = _ImageArchitectureHeader + class _ImageArchitectureEntry(__cs__.Structure): + FixupInstRVA: _c_pe.uint32 + NewInst: _c_pe.uint32 + @overload + def __init__(self, FixupInstRVA: _c_pe.uint32 | None = ..., NewInst: _c_pe.uint32 | None = ...): ... + @overload + def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... + + IMAGE_ARCHITECTURE_ENTRY: TypeAlias = _ImageArchitectureEntry + class IMPORT_OBJECT_TYPE(__cs__.Enum): + IMPORT_OBJECT_CODE = ... + IMPORT_OBJECT_DATA = ... + IMPORT_OBJECT_CONST = ... + + class IMPORT_OBJECT_NAME_TYPE(__cs__.Enum): + IMPORT_OBJECT_ORDINAL = ... + IMPORT_OBJECT_NAME = ... + IMPORT_OBJECT_NAME_NO_PREFIX = ... + IMPORT_OBJECT_NAME_UNDECORATE = ... + IMPORT_OBJECT_NAME_EXPORTAS = ... + + class IMPORT_OBJECT_HEADER(__cs__.Structure): + Sig1: _c_pe.uint16 + Sig2: _c_pe.uint16 + Version: _c_pe.uint16 + Machine: _c_pe.uint16 + TimeDateStamp: _c_pe.uint32 + SizeOfData: _c_pe.uint32 + Ordinal: _c_pe.uint16 + Hint: _c_pe.uint16 + Type: _c_pe.IMPORT_OBJECT_TYPE + NameType: _c_pe.IMPORT_OBJECT_NAME_TYPE + Reserved: _c_pe.uint16 + @overload + def __init__( + self, + Sig1: _c_pe.uint16 | None = ..., + Sig2: _c_pe.uint16 | None = ..., + Version: _c_pe.uint16 | None = ..., + Machine: _c_pe.uint16 | None = ..., + TimeDateStamp: _c_pe.uint32 | None = ..., + SizeOfData: _c_pe.uint32 | None = ..., + Ordinal: _c_pe.uint16 | None = ..., + Hint: _c_pe.uint16 | None = ..., + Type: _c_pe.IMPORT_OBJECT_TYPE | None = ..., + NameType: _c_pe.IMPORT_OBJECT_NAME_TYPE | None = ..., + Reserved: _c_pe.uint16 | None = ..., + ): ... + @overload + def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... + + class COMIMAGE_FLAGS(__cs__.Enum): + ILONLY = ... + "32BITREQUIRED = ..." + IL_LIBRARY = ... + STRONGNAMESIGNED = ... + NATIVE_ENTRYPOINT = ... + TRACKDEBUGDATA = ... + "32BITPREFERRED = ..." + + class _IMAGE_COR20_HEADER(__cs__.Structure): + cb: _c_pe.uint32 + MajorRuntimeVersion: _c_pe.uint16 + MinorRuntimeVersion: _c_pe.uint16 + MetaData: _c_pe._IMAGE_DATA_DIRECTORY + Flags: _c_pe.uint32 + EntryPointToken: _c_pe.uint32 + EntryPointRVA: _c_pe.uint32 + Resources: _c_pe._IMAGE_DATA_DIRECTORY + StrongNameSignature: _c_pe._IMAGE_DATA_DIRECTORY + CodeManagerTable: _c_pe._IMAGE_DATA_DIRECTORY + VTableFixups: _c_pe._IMAGE_DATA_DIRECTORY + ExportAddressTableJumps: _c_pe._IMAGE_DATA_DIRECTORY + ManagedNativeHeader: _c_pe._IMAGE_DATA_DIRECTORY + @overload + def __init__( + self, + cb: _c_pe.uint32 | None = ..., + MajorRuntimeVersion: _c_pe.uint16 | None = ..., + MinorRuntimeVersion: _c_pe.uint16 | None = ..., + MetaData: _c_pe._IMAGE_DATA_DIRECTORY | None = ..., + Flags: _c_pe.uint32 | None = ..., + EntryPointToken: _c_pe.uint32 | None = ..., + EntryPointRVA: _c_pe.uint32 | None = ..., + Resources: _c_pe._IMAGE_DATA_DIRECTORY | None = ..., + StrongNameSignature: _c_pe._IMAGE_DATA_DIRECTORY | None = ..., + CodeManagerTable: _c_pe._IMAGE_DATA_DIRECTORY | None = ..., + VTableFixups: _c_pe._IMAGE_DATA_DIRECTORY | None = ..., + ExportAddressTableJumps: _c_pe._IMAGE_DATA_DIRECTORY | None = ..., + ManagedNativeHeader: _c_pe._IMAGE_DATA_DIRECTORY | None = ..., + ): ... + @overload + def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... + + IMAGE_COR20_HEADER: TypeAlias = _IMAGE_COR20_HEADER + class _IMAGE_COR20_METADATA(__cs__.Structure): + Magic: _c_pe.uint32 + MajorVersion: _c_pe.uint16 + MinorVersion: _c_pe.uint16 + Reserved: _c_pe.uint32 + Length: _c_pe.uint32 + Version: __cs__.CharArray + Flags: _c_pe.uint16 + NumberOfStreams: _c_pe.uint16 + @overload + def __init__( + self, + Magic: _c_pe.uint32 | None = ..., + MajorVersion: _c_pe.uint16 | None = ..., + MinorVersion: _c_pe.uint16 | None = ..., + Reserved: _c_pe.uint32 | None = ..., + Length: _c_pe.uint32 | None = ..., + Version: __cs__.CharArray | None = ..., + Flags: _c_pe.uint16 | None = ..., + NumberOfStreams: _c_pe.uint16 | None = ..., + ): ... + @overload + def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... + + IMAGE_COR20_METADATA: TypeAlias = _IMAGE_COR20_METADATA + class _IMAGE_COR20_STREAM_HEADER(__cs__.Structure): + Offset: _c_pe.uint32 + Size: _c_pe.uint32 + Name: __cs__.CharArray + @overload + def __init__( + self, + Offset: _c_pe.uint32 | None = ..., + Size: _c_pe.uint32 | None = ..., + Name: __cs__.CharArray | None = ..., + ): ... + @overload + def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... + + IMAGE_COR20_STREAM_HEADER: TypeAlias = _IMAGE_COR20_STREAM_HEADER + +# Technically `c_pe` is an instance of `_c_pe`, but then we can't use it in type hints +c_pe: TypeAlias = _c_pe diff --git a/dissect/executable/pe/directory/__init__.py b/dissect/executable/pe/directory/__init__.py new file mode 100644 index 0000000..907f6fd --- /dev/null +++ b/dissect/executable/pe/directory/__init__.py @@ -0,0 +1,41 @@ +from dissect.executable.pe.directory.base import DataDirectory +from dissect.executable.pe.directory.basereloc import BaseRelocationDirectory +from dissect.executable.pe.directory.bound_import import BoundImportDirectory +from dissect.executable.pe.directory.com_descriptor import ComDescriptorDirectory +from dissect.executable.pe.directory.debug import DebugDirectory +from dissect.executable.pe.directory.delay_import import DelayImportDirectory +from dissect.executable.pe.directory.exception import ExceptionDirectory +from dissect.executable.pe.directory.export import ExportDirectory +from dissect.executable.pe.directory.iat import IatDirectory +from dissect.executable.pe.directory.imports import ImportDirectory, ImportFunction, ImportModule +from dissect.executable.pe.directory.load_config import LoadConfigDirectory +from dissect.executable.pe.directory.resource import ( + ResourceDataEntry, + ResourceDirectory, + ResourceDirectoryEntry, + ResourceEntry, +) +from dissect.executable.pe.directory.security import SecurityDirectory +from dissect.executable.pe.directory.tls import TlsDirectory + +__all__ = [ + "BaseRelocationDirectory", + "BoundImportDirectory", + "ComDescriptorDirectory", + "DataDirectory", + "DebugDirectory", + "DelayImportDirectory", + "ExceptionDirectory", + "ExportDirectory", + "IatDirectory", + "ImportDirectory", + "ImportFunction", + "ImportModule", + "LoadConfigDirectory", + "ResourceDataEntry", + "ResourceDirectory", + "ResourceDirectoryEntry", + "ResourceEntry", + "SecurityDirectory", + "TlsDirectory", +] diff --git a/dissect/executable/pe/directory/base.py b/dissect/executable/pe/directory/base.py new file mode 100644 index 0000000..4778aa7 --- /dev/null +++ b/dissect/executable/pe/directory/base.py @@ -0,0 +1,18 @@ +from __future__ import annotations + +from typing import TYPE_CHECKING + +if TYPE_CHECKING: + from dissect.executable.pe.pe import PE + + +class DataDirectory: + """Base class for PE data directories.""" + + def __init__(self, pe: PE, address: int, size: int): + self.pe = pe + self.address = address + self.size = size + + def __repr__(self) -> str: + return f"<{self.__class__.__name__} address={self.address:#x} size={self.size}>" diff --git a/dissect/executable/pe/directory/basereloc.py b/dissect/executable/pe/directory/basereloc.py new file mode 100644 index 0000000..fcbacc1 --- /dev/null +++ b/dissect/executable/pe/directory/basereloc.py @@ -0,0 +1,64 @@ +from __future__ import annotations + +from dataclasses import dataclass +from functools import cached_property +from typing import TYPE_CHECKING + +from dissect.executable.pe.c_pe import c_pe +from dissect.executable.pe.directory.base import DataDirectory + +if TYPE_CHECKING: + from collections.abc import Iterator + + +class BaseRelocationDirectory(DataDirectory): + """The base relocation directory of a PE file.""" + + def __repr__(self) -> str: + return f"" + + def __len__(self) -> int: + return len(self.entries) + + def __iter__(self) -> Iterator[BaseRelocation]: + return iter(self.entries) + + def __getitem__(self, idx: int) -> BaseRelocation: + return self.entries[idx] + + @cached_property + def entries(self) -> list[BaseRelocation]: + """List of base relocation entries.""" + result = [] + + offset = self.address + while offset < self.address + self.size: + self.pe.vfh.seek(offset) + + block = c_pe._IMAGE_BASE_RELOCATION(self.pe.vfh) + if block.SizeOfBlock == 0: + break + + page_rva = block.VirtualAddress + + num_entries = (block.SizeOfBlock - len(c_pe._IMAGE_BASE_RELOCATION)) // len(c_pe.USHORT) + result.extend( + BaseRelocation(c_pe.IMAGE_REL_BASED(entry >> 12), page_rva + (entry & 0xFFF)) + for entry in c_pe.USHORT[num_entries](self.pe.vfh) + if (entry >> 12) != 0 # Skip IMAGE_REL_BASED_ABSOLUTE (0) + ) + offset += block.SizeOfBlock + offset += -offset & 3 # Align to 4 bytes + + return result + + +@dataclass +class BaseRelocation: + """A single base relocation entry in the base relocation directory.""" + + type: c_pe.IMAGE_REL_BASED + rva: int + + def __repr__(self) -> str: + return f"" diff --git a/dissect/executable/pe/directory/bound_import.py b/dissect/executable/pe/directory/bound_import.py new file mode 100644 index 0000000..ce7f14d --- /dev/null +++ b/dissect/executable/pe/directory/bound_import.py @@ -0,0 +1,114 @@ +from __future__ import annotations + +from functools import cached_property +from typing import TYPE_CHECKING + +from dissect.util.ts import from_unix + +from dissect.executable.pe.c_pe import c_pe +from dissect.executable.pe.directory.base import DataDirectory + +if TYPE_CHECKING: + import datetime + + +class BoundImportDirectory(DataDirectory): + """The bound import directory of a PE file.""" + + def __repr__(self) -> str: + return f"" + + def __len__(self) -> int: + return len(self.modules) + + def __getitem__(self, idx: str | int) -> BoundImportModule: + if isinstance(idx, int): + return self.modules[idx] + if isinstance(idx, str): + if idx not in self._by_name: + raise KeyError(f"Bound import module {idx!r} not found") + return self._by_name[idx] + raise TypeError(f"BoundImportDirectory indices must be str or int, not {type(idx).__name__}") + + def __contains__(self, name: str) -> bool: + if isinstance(name, str): + return name in self._by_name + return False + + @cached_property + def modules(self) -> list[BoundImportModule]: + """List of bound imported modules.""" + result = [] + + self.pe.vfh.seek(self.address) + while self.pe.vfh.tell() < self.address + self.size: + descriptor = c_pe.IMAGE_BOUND_IMPORT_DESCRIPTOR(self.pe.vfh) + if not descriptor: + break + + forwarders = [] + for _ in range(descriptor.NumberOfModuleForwarderRefs): + forwarder = c_pe.IMAGE_BOUND_FORWARDER_REF(self.pe.vfh) + if not forwarder: + break + + forwarders.append(BoundImportForwardReference(self, forwarder)) + + result.append(BoundImportModule(self, descriptor, forwarders)) + + return result + + @cached_property + def _by_name(self) -> dict[str, BoundImportModule]: + """A mapping of module names to their :class:`DelayImportModule`.""" + return {module.name: module for module in self.modules} + + +class BoundImportModule: + """A module bound imported by a PE file, containing its functions.""" + + def __init__( + self, + directory: BoundImportDirectory, + descriptor: c_pe.IMAGE_BOUND_IMPORT_DESCRIPTOR, + forwarders: list[BoundImportForwardReference], + ): + self.directory = directory + self.descriptor = descriptor + self.forwarders = forwarders + + @property + def timestamp(self) -> datetime.datetime | None: + """The timestamp of this bound import module, or ``None`` if the PE file is compiled as reproducible.""" + if self.directory.pe.is_reproducible(): + return None + return from_unix(self.descriptor.TimeDateStamp) + + @property + def name(self) -> str: + self.directory.pe.vfh.seek(self.directory.address + self.descriptor.OffsetModuleName) + return c_pe.CHAR[None](self.directory.pe.vfh).decode() + + +class BoundImportForwardReference: + """A forward reference in a bound import module.""" + + def __init__( + self, + directory: BoundImportDirectory, + descriptor: c_pe.IMAGE_BOUND_FORWARDER_REF, + ): + self.directory = directory + self.descriptor = descriptor + + @property + def timestamp(self) -> datetime.datetime | None: + """The timestamp of this bound import module, or ``None`` if the PE file is compiled as reproducible.""" + if self.directory.pe.is_reproducible(): + return None + return from_unix(self.descriptor.TimeDateStamp) + + @property + def name(self) -> str: + self.directory.pe.vfh.seek(self.directory.address + self.descriptor.OffsetModuleName) + return c_pe.CHAR[None](self.directory.pe.vfh).decode() diff --git a/dissect/executable/pe/directory/com_descriptor.py b/dissect/executable/pe/directory/com_descriptor.py new file mode 100644 index 0000000..21e060a --- /dev/null +++ b/dissect/executable/pe/directory/com_descriptor.py @@ -0,0 +1,83 @@ +from __future__ import annotations + +from functools import cached_property +from typing import BinaryIO + +from dissect.util.stream import RangeStream + +from dissect.executable.pe.c_pe import c_pe +from dissect.executable.pe.directory.base import DataDirectory + + +class ComDescriptorDirectory(DataDirectory): + """The COM descriptor directory of a PE file. + + References: + - https://www.codeproject.com/Articles/12585/The-NET-File-Format + """ + + @cached_property + def descriptor(self) -> c_pe.IMAGE_COR20_HEADER: + """The CLR 2.0 header descriptor.""" + self.pe.vfh.seek(self.address) + return c_pe.IMAGE_COR20_HEADER(self.pe.vfh) + + @cached_property + def metadata(self) -> ComMetadata: + """The COM metadata directory.""" + return ComMetadata(self.pe, self.descriptor.MetaData.VirtualAddress, self.descriptor.MetaData.Size) + + +class ComMetadata(DataDirectory): + """The COM metadata directory of the COM descriptor.""" + + @cached_property + def metadata(self) -> c_pe.IMAGE_COR20_METADATA: + """The CLR 2.0 metadata descriptor.""" + self.pe.vfh.seek(self.address) + return c_pe.IMAGE_COR20_METADATA(self.pe.vfh) + + @property + def version(self) -> str: + """The version as defined in the metadata.""" + return self.metadata.Version.decode().strip("\x00") + + @cached_property + def streams(self) -> list[ComStream]: + """A list of streams defined in the metadata.""" + result = [] + + offset = self.address + len(self.metadata) + for _ in range(self.metadata.NumberOfStreams): + self.pe.vfh.seek(offset) + header = c_pe.IMAGE_COR20_STREAM_HEADER(self.pe.vfh) + + result.append(ComStream(self, header.Offset, header.Size, header.Name.decode())) + + offset += len(header) + offset += -offset & 3 # Align to 4 bytes + + return result + + +class ComStream: + """A stream in the COM metadata.""" + + def __init__(self, metadata: ComMetadata, offset: int, size: int, name: str): + self.metadata = metadata + self.offset = offset + self.size = size + self.name = name + + def __repr__(self) -> str: + return f"" + + @property + def data(self) -> bytes: + """The data of the stream.""" + self.metadata.pe.vfh.seek(self.metadata.address + self.offset) + return self.metadata.pe.vfh.read(self.size) + + def open(self) -> BinaryIO: + """Open the stream for reading.""" + return RangeStream(self.metadata.pe.vfh, self.metadata.address + self.offset, self.size) diff --git a/dissect/executable/pe/directory/debug.py b/dissect/executable/pe/directory/debug.py new file mode 100644 index 0000000..76d0aaf --- /dev/null +++ b/dissect/executable/pe/directory/debug.py @@ -0,0 +1,244 @@ +from __future__ import annotations + +from functools import cached_property +from typing import TYPE_CHECKING, BinaryIO +from uuid import UUID + +from dissect.util.stream import RangeStream +from dissect.util.ts import from_unix + +from dissect.executable.pe.c_pe import c_pe +from dissect.executable.pe.directory.base import DataDirectory + +if TYPE_CHECKING: + import datetime + from collections.abc import Iterator + + from dissect.executable.pe.pe import PE + + +class DebugDirectory(DataDirectory): + """The debug directory of a PE file.""" + + def __repr__(self) -> str: + return f"" + + def __len__(self) -> int: + return len(self.entries) + + def __iter__(self) -> Iterator[DebugEntry]: + return iter(self.entries) + + def __getitem__(self, idx: int) -> DebugEntry: + return self.entries[idx] + + @cached_property + def entries(self) -> list[DebugEntry]: + """List of debug entries in the debug directory.""" + result = [] + + self.pe.vfh.seek(self.address) + for entry in c_pe.IMAGE_DEBUG_DIRECTORY[self.size // len(c_pe.IMAGE_DEBUG_DIRECTORY)](self.pe.vfh): + cls = _DEBUG_TYPE_MAP.get(entry.Type, DebugEntry) + result.append(cls(self.pe, entry)) + + return result + + +class DebugEntry: + """A single debug entry in the debug directory.""" + + def __init__(self, pe: PE, entry: c_pe.IMAGE_DEBUG_DIRECTORY): + self.pe = pe + self.entry = entry + + def __repr__(self) -> str: + return f"" + + @property + def timestamp(self) -> datetime.datetime | None: + """The timestamp of this debug entry, or ``None`` if the PE file is compiled as reproducible.""" + if self.pe.is_reproducible(): + return None + return from_unix(self.entry.TimeDateStamp) + + @property + def type(self) -> c_pe.IMAGE_DEBUG_TYPE: + """The type of the debug entry.""" + return self.entry.Type + + @property + def size(self) -> int: + """The size of the debug entry.""" + return self.entry.SizeOfData + + @property + def data(self) -> bytes: + """The data of the debug entry.""" + with self.open() as fh: + return fh.read() + + def open(self) -> BinaryIO: + """Return a file-like object to read the debug entry data.""" + if not self.entry.AddressOfRawData: + if self.pe.virtual: + raise ValueError("Cannot access raw data of debug entry because it's not mapped into memory") + + fh = self.pe.fh + address = self.entry.PointerToRawData + else: + fh = self.pe.vfh + address = self.entry.AddressOfRawData + + return RangeStream(fh, address, self.size) + + +class CodeViewDebugEntry(DebugEntry): + """A CodeView debug entry.""" + + def __repr__(self) -> str: + return f"" + + @cached_property + def info(self) -> c_pe.CV_INFO_PDB20 | c_pe.CV_INFO_PDB70: + """The CodeView debug information.""" + with self.open() as fh: + cv_signature = c_pe.ULONG(fh) + fh.seek(0) + + if cv_signature == c_pe.CVINFO_PDB70_CVSIGNATURE: + return c_pe.CV_INFO_PDB70(fh) + + if cv_signature == c_pe.CVINFO_PDB20_CVSIGNATURE: + return c_pe.CV_INFO_PDB20(fh) + + if cv_signature == c_pe.CVINFO_MTOC_CVSIGNATURE: + return c_pe.CV_INFO_MTOC(fh) + + raise ValueError("Not a CodeView debug entry") + + @property + def signature(self) -> UUID | int | None: + """The signature of the CodeView debug entry.""" + if isinstance(self.info, c_pe.CV_INFO_PDB20): + return self.info.Signature + + if isinstance(self.info, (c_pe.CV_INFO_PDB70, c_pe.CV_INFO_MTOC)): + return UUID(bytes_le=self.info.Signature) + + return None + + @property + def age(self) -> int | None: + """The age of the CodeView debug entry.""" + return getattr(self.info, "Age", None) + + @property + def pdb(self) -> str | None: + """The PDB filename of the CodeView debug entry.""" + return getattr(self.info, "PdbFileName", b"").decode() or None + + +class VcFeatureDebugEntry(DebugEntry): + """A VC feature debug entry.""" + + def __repr__(self) -> str: + return f"" # noqa: E501 + + @cached_property + def info(self) -> c_pe.VC_FEATURE: + """The VC feature debug information.""" + with self.open() as fh: + return c_pe.VC_FEATURE(fh) + + @property + def pre_vc11(self) -> int: + """Return the count for ``Pre-VC++ 11.00``.""" + return self.info.PreVC11 + + @property + def ccpp(self) -> int: + """Return the count for ``C/C++``.""" + return self.info.CCpp + + @property + def gs(self) -> int: + """Return the count for ``/GS`` (number of guard stack).""" + return self.info.Gs + + @property + def sdl(self) -> int: + """Return the count for ``/sdl`` (Security Development Lifecycle).""" + return self.info.Sdl + + @property + def guards(self) -> int: + """Return the count for ``/guardN``.""" + return self.info.GuardN + + +class PogoDebugEntry(DebugEntry): + """A POGO debug entry.""" + + def __repr__(self) -> str: + return f"" + + def __len__(self) -> int: + return len(self.entries) + + def __iter__(self) -> Iterator[tuple[int, int, str]]: + return iter(self.entries) + + def __getitem__(self, idx: int) -> tuple[int, int, str]: + return self.entries[idx] + + @cached_property + def entries(self) -> list[tuple[int, int, str]]: + """The POGO debug entries.""" + result = [] + + with self.open() as fh: + signature = c_pe.ULONG(fh) + if signature not in ( + c_pe.IMAGE_DEBUG_POGO_SIGNATURE_ZERO, + c_pe.IMAGE_DEBUG_POGO_SIGNATURE_LTCG, + c_pe.IMAGE_DEBUG_POGO_SIGNATURE_PGU, + ): + raise NotImplementedError(f"Unsupported POGO signature: {signature:#x}") + + offset = fh.tell() + while offset < self.size: + fh.seek(offset) + + rva = c_pe.ULONG(fh) + size = c_pe.ULONG(fh) + label = c_pe.CHAR[None](fh).decode() + + result.append((rva, size, label)) + + offset = fh.tell() + offset += -offset & 3 # Align to 4 bytes + + return result + + +class ReproDebugEntry(DebugEntry): + """A Repro debug entry.""" + + def __repr__(self) -> str: + return f"" + + @property + def hash(self) -> bytes: + """The hash of the Repro debug entry.""" + with self.open() as fh: + hash_size = c_pe.ULONG(fh) + return fh.read(hash_size) + + +_DEBUG_TYPE_MAP = { + c_pe.IMAGE_DEBUG_TYPE.CODEVIEW: CodeViewDebugEntry, + c_pe.IMAGE_DEBUG_TYPE.VC_FEATURE: VcFeatureDebugEntry, + c_pe.IMAGE_DEBUG_TYPE.POGO: PogoDebugEntry, + c_pe.IMAGE_DEBUG_TYPE.REPRO: ReproDebugEntry, +} diff --git a/dissect/executable/pe/directory/delay_import.py b/dissect/executable/pe/directory/delay_import.py new file mode 100644 index 0000000..138e5af --- /dev/null +++ b/dissect/executable/pe/directory/delay_import.py @@ -0,0 +1,176 @@ +from __future__ import annotations + +from functools import cached_property +from typing import TYPE_CHECKING + +from dissect.util.ts import from_unix + +from dissect.executable.pe.c_pe import c_pe +from dissect.executable.pe.directory.base import DataDirectory + +if TYPE_CHECKING: + import datetime + from collections.abc import Iterator + + from dissect.executable.pe.pe import PE + + +class DelayImportDirectory(DataDirectory): + """The delay import directory of a PE file.""" + + def __repr__(self) -> str: + return f"" + + def __len__(self) -> int: + return len(self.modules) + + def __getitem__(self, idx: str | int) -> DelayImportModule: + if isinstance(idx, int): + return self.modules[idx] + if isinstance(idx, str): + if idx not in self._by_name: + raise KeyError(f"Delay import module {idx!r} not found") + return self._by_name[idx] + raise TypeError(f"DelayImportDirectory indices must be str or int, not {type(idx).__name__}") + + def __contains__(self, name: str) -> bool: + if isinstance(name, str): + return name in self._by_name + return False + + @cached_property + def modules(self) -> list[DelayImportModule]: + """List of delay imported modules.""" + self.pe.vfh.seek(self.address) + return [ + DelayImportModule(self.pe, descriptor) for descriptor in c_pe.IMAGE_DELAYLOAD_DESCRIPTOR[None](self.pe.vfh) + ] + + @cached_property + def _by_name(self) -> dict[str, DelayImportModule]: + """A mapping of module names to their :class:`DelayImportModule`.""" + return {module.name: module for module in self.modules} + + +class DelayImportModule: + """A module delay imported by a PE file, containing its functions.""" + + def __init__(self, pe: PE, descriptor: c_pe.IMAGE_DELAYLOAD_DESCRIPTOR): + self.pe = pe + self.descriptor = descriptor + + def __repr__(self) -> str: + return f"" + + def __iter__(self) -> Iterator[DelayImportFunction]: + return iter(self.functions) + + def __getitem__(self, idx: str | int) -> DelayImportFunction: + if isinstance(idx, int): + return self._by_ordinal[idx] + if isinstance(idx, str): + if idx not in self._by_name: + raise KeyError(f"Delay import function {idx!r} not found in module {self.name!r}") + return self._by_name[idx] + raise TypeError(f"DelayImportModule indices must be str or int, not {type(idx).__name__}") + + def __contains__(self, idx: str | int) -> bool: + if isinstance(idx, int): + return idx in self._by_ordinal + if isinstance(idx, str): + return idx in self._by_name + return False + + @property + def timestamp(self) -> datetime.datetime | None: + """The timestamp of the target DLL of this delay import module, or ``None`` if the PE file is + compiled as reproducible. + + Will be ``0`` (so epoch) if it's not bound yet. + """ + if self.pe.is_reproducible(): + return None + return from_unix(self.descriptor.TimeDateStamp) + + @cached_property + def name(self) -> str: + """The name of the delay import module.""" + self.pe.vfh.seek(self.descriptor.DllNameRVA) + return c_pe.CHAR[None](self.pe.vfh).decode() + + @cached_property + def functions(self) -> list[DelayImportFunction]: + """List of delay imported functions from this module.""" + ctype = c_pe.IMAGE_THUNK_DATA64 if self.pe.is_64bit() else c_pe.IMAGE_THUNK_DATA32 + + self.pe.vfh.seek(self.descriptor.ImportNameTableRVA) + name_table = ctype[None](self.pe.vfh) + + self.pe.vfh.seek(self.descriptor.ImportAddressTableRVA) + address_table = ctype[None](self.pe.vfh) + + bound_table = [] + if self.descriptor.BoundImportAddressTableRVA: + self.pe.vfh.seek(self.descriptor.BoundImportAddressTableRVA) + bound_table = ctype[None](self.pe.vfh) + # If we are not bound (e.g. PE file on disk instead of in memory), create an empty table + bound_table = bound_table or [None] * len(name_table) + + unload_table = [] + if self.descriptor.UnloadInformationTableRVA: + self.pe.vfh.seek(self.descriptor.UnloadInformationTableRVA) + unload_table = ctype[None](self.pe.vfh) + # If we are not unloading (e.g. PE file on disk instead of in memory), create an empty table + unload_table = unload_table or [None] * len(name_table) + + return [ + DelayImportFunction(self, name_thunk, address_thunk, bound_thunk, unload_thunk) + for name_thunk, address_thunk, bound_thunk, unload_thunk in zip( + name_table, address_table, bound_table, unload_table + ) + ] + + @cached_property + def _by_name(self) -> dict[str, DelayImportFunction]: + """A mapping of imported function names to their :class:`DelayImportFunction`.""" + return {func.name: func for func in self.functions if func.name is not None} + + @cached_property + def _by_ordinal(self) -> dict[int, DelayImportFunction]: + """A mapping of function ordinals to their :class:`DelayImportFunction`.""" + return {func.ordinal: func for func in self.functions} + + +class DelayImportFunction: + """A function delay imported from a module.""" + + def __init__( + self, + module: DelayImportModule, + name_thunk: c_pe.IMAGE_THUNK_DATA32 | c_pe.IMAGE_THUNK_DATA64, + address_thunk: c_pe.IMAGE_THUNK_DATA32 | c_pe.IMAGE_THUNK_DATA64, + bound_thunk: c_pe.IMAGE_THUNK_DATA32 | c_pe.IMAGE_THUNK_DATA64 | None = None, + unload_thunk: c_pe.IMAGE_THUNK_DATA32 | c_pe.IMAGE_THUNK_DATA64 | None = None, + ): + self.module = module + self.name_thunk = name_thunk + self.address_thunk = address_thunk + + if name_thunk.u1.Ordinal & (c_pe.IMAGE_ORDINAL_FLAG64 if module.pe.is_64bit() else c_pe.IMAGE_ORDINAL_FLAG32): + self.ordinal = name_thunk.u1.Ordinal & 0xFFFF + self.name = None + else: + self.module.pe.vfh.seek(name_thunk.u1.AddressOfData & (c_pe.IMAGE_ORDINAL_FLAG32 - 1)) + import_by_name = c_pe.IMAGE_IMPORT_BY_NAME(self.module.pe.vfh) + self.ordinal = import_by_name.Hint + self.name = import_by_name.Name.decode() + + self.address = address_thunk.u1.Function + self.bound_address = bound_thunk.u1.Function if bound_thunk else None + self.unload_address = unload_thunk.u1.Function if unload_thunk else None + + def __repr__(self) -> str: + address = hex(self.address) if self.address is not None else "None" + bound_address = hex(self.bound_address) if self.bound_address is not None else "None" + unload_address = hex(self.unload_address) if self.unload_address is not None else "None" + return f"" # noqa: E501 diff --git a/dissect/executable/pe/directory/exception.py b/dissect/executable/pe/directory/exception.py new file mode 100644 index 0000000..2ab3b4d --- /dev/null +++ b/dissect/executable/pe/directory/exception.py @@ -0,0 +1,76 @@ +from __future__ import annotations + +from functools import cached_property +from typing import TYPE_CHECKING + +from dissect.executable.pe.c_pe import c_pe +from dissect.executable.pe.directory.base import DataDirectory + +if TYPE_CHECKING: + from collections.abc import Iterator + + +class ExceptionDirectory(DataDirectory): + """The exception directory of a PE file. + + Currently only shows the raw exception entries. + """ + + def __repr__(self) -> str: + return f"" + + def __len__(self) -> int: + return len(self.entries) + + def __iter__( + self, + ) -> Iterator[ + c_pe.IMAGE_RUNTIME_FUNCTION_ENTRY + | c_pe.IMAGE_ARM_RUNTIME_FUNCTION_ENTRY + | c_pe.IMAGE_ARM64_RUNTIME_FUNCTION_ENTRY + | c_pe.IMAGE_ALPHA_RUNTIME_FUNCTION_ENTRY + | c_pe.IMAGE_ALPHA64_RUNTIME_FUNCTION_ENTRY + | c_pe.IMAGE_CE_RUNTIME_FUNCTION_ENTRY + ]: + return iter(self.entries) + + def __getitem__( + self, idx: int + ) -> ( + c_pe.IMAGE_RUNTIME_FUNCTION_ENTRY + | c_pe.IMAGE_ARM_RUNTIME_FUNCTION_ENTRY + | c_pe.IMAGE_ARM64_RUNTIME_FUNCTION_ENTRY + | c_pe.IMAGE_ALPHA_RUNTIME_FUNCTION_ENTRY + | c_pe.IMAGE_ALPHA64_RUNTIME_FUNCTION_ENTRY + | c_pe.IMAGE_CE_RUNTIME_FUNCTION_ENTRY + ): + return self.entries[idx] + + @cached_property + def entries( + self, + ) -> list[ + c_pe.IMAGE_RUNTIME_FUNCTION_ENTRY + | c_pe.IMAGE_ARM_RUNTIME_FUNCTION_ENTRY + | c_pe.IMAGE_ARM64_RUNTIME_FUNCTION_ENTRY + | c_pe.IMAGE_ALPHA_RUNTIME_FUNCTION_ENTRY + | c_pe.IMAGE_ALPHA64_RUNTIME_FUNCTION_ENTRY + | c_pe.IMAGE_CE_RUNTIME_FUNCTION_ENTRY + ]: + """List of exception entries.""" + self.pe.vfh.seek(self.address) + + machine = self.pe.file_header.Machine + if machine in (c_pe.IMAGE_FILE_MACHINE.ARM, c_pe.IMAGE_FILE_MACHINE.THUMB, c_pe.IMAGE_FILE_MACHINE.ARMNT): + ctype = c_pe.IMAGE_ARM_RUNTIME_FUNCTION_ENTRY + elif machine == c_pe.IMAGE_FILE_MACHINE.ARM64: + ctype = c_pe.IMAGE_ARM64_RUNTIME_FUNCTION_ENTRY + elif machine == c_pe.IMAGE_FILE_MACHINE.ALPHA: + ctype = c_pe.IMAGE_ALPHA_RUNTIME_FUNCTION_ENTRY + elif machine == c_pe.IMAGE_FILE_MACHINE.ALPHA64: + ctype = c_pe.IMAGE_ALPHA64_RUNTIME_FUNCTION_ENTRY + else: + # May be wrong for esoteric architectures, but this is the default + ctype = c_pe.IMAGE_RUNTIME_FUNCTION_ENTRY + + return ctype[self.size // len(ctype)](self.pe.vfh) diff --git a/dissect/executable/pe/directory/export.py b/dissect/executable/pe/directory/export.py new file mode 100644 index 0000000..3bd4762 --- /dev/null +++ b/dissect/executable/pe/directory/export.py @@ -0,0 +1,128 @@ +from __future__ import annotations + +from dataclasses import dataclass +from functools import cached_property +from typing import TYPE_CHECKING + +from dissect.util.ts import from_unix + +from dissect.executable.pe.c_pe import c_pe +from dissect.executable.pe.directory.base import DataDirectory + +if TYPE_CHECKING: + import datetime + from collections.abc import Iterator + + +class ExportDirectory(DataDirectory): + """The export directory of a PE file.""" + + def __repr__(self) -> str: + return f"" + + def __iter__(self) -> Iterator[ExportFunction]: + return iter(self.functions) + + def __getitem__(self, idx: str | int) -> ExportFunction: + if isinstance(idx, int): + return self._by_ordinal[idx] + if isinstance(idx, str): + if idx not in self._by_name: + raise KeyError(f"Export function {idx!r} not found in directory {self.name!r}") + return self._by_name[idx] + raise TypeError(f"ImportModule indices must be str or int, not {type(idx).__name__}") + + def __contains__(self, idx: str | int) -> bool: + if isinstance(idx, int): + return idx in self._by_ordinal + if isinstance(idx, str): + return idx in self._by_name + return False + + @cached_property + def header(self) -> c_pe.IMAGE_EXPORT_DIRECTORY: + """The export directory header.""" + self.pe.vfh.seek(self.address) + return c_pe.IMAGE_EXPORT_DIRECTORY(self.pe.vfh) + + @property + def timestamp(self) -> datetime.datetime | None: + """The timestamp of the export directory, or ``None`` if the PE file is compiled as reproducible.""" + if self.pe.is_reproducible(): + return None + return from_unix(self.header.TimeDateStamp) + + @cached_property + def name(self) -> str | None: + """The name of the export directory, if available.""" + if self.header.Name: + self.pe.vfh.seek(self.header.Name) + return c_pe.char[None](self.pe.vfh).decode() + return None + + @property + def base(self) -> int: + """The base ordinal of the exported functions.""" + return self.header.Base + + @cached_property + def functions(self) -> list[ExportFunction]: + """List of exported functions.""" + result = [] + + self.pe.vfh.seek(self.header.AddressOfFunctions) + addresses = c_pe.ULONG[self.header.NumberOfFunctions](self.pe.vfh) + + self.pe.vfh.seek(self.header.AddressOfNames) + names = c_pe.ULONG[self.header.NumberOfNames](self.pe.vfh) + + self.pe.vfh.seek(self.header.AddressOfNameOrdinals) + ordinals = c_pe.USHORT[self.header.NumberOfNames](self.pe.vfh) + + for name_ptr, ordinal in zip(names, ordinals): + self.pe.vfh.seek(name_ptr) + name = c_pe.CHAR[None](self.pe.vfh).decode() + + address = addresses[ordinal] + forwarder = None + if self.address <= address < self.address + self.size: + self.pe.vfh.seek(address) + forwarder = c_pe.CHAR[None](self.pe.vfh).decode() + + result.append(ExportFunction(self, ordinal, name, address, forwarder)) + + return result + + @cached_property + def _by_name(self) -> dict[str, ExportFunction]: + """A mapping of exported function names to their :class:`ExportFunction`.""" + return {func.name: func for func in self.functions} + + @cached_property + def _by_ordinal(self) -> dict[int, ExportFunction]: + """A mapping of exported function ordinals to their :class:`ExportFunction`.""" + return {func.ordinal: func for func in self.functions} + + +@dataclass +class ExportFunction: + directory: ExportDirectory + """The export directory this function belongs to.""" + unbiased_ordinal: int + """The unbiased ordinal of the exported function.""" + name: str + """The name of the exported function.""" + address: int + """The address of the exported function.""" + forwarder: str | None = None + """The forwarder of the exported function, if it is a forwarder.""" + + def __repr__(self) -> str: + if self.forwarder: + return f"" + return f"" + + @property + def ordinal(self) -> int: + """The unbiased ordinal with the base ordinal added.""" + return self.unbiased_ordinal + self.directory.base diff --git a/dissect/executable/pe/directory/iat.py b/dissect/executable/pe/directory/iat.py new file mode 100644 index 0000000..5a2bc78 --- /dev/null +++ b/dissect/executable/pe/directory/iat.py @@ -0,0 +1,33 @@ +from __future__ import annotations + +from functools import cached_property +from typing import TYPE_CHECKING + +from dissect.executable.pe.c_pe import c_pe +from dissect.executable.pe.directory.base import DataDirectory + +if TYPE_CHECKING: + from collections.abc import Iterator + + +class IatDirectory(DataDirectory): + """The import address table (IAT) directory of a PE file.""" + + def __repr__(self) -> str: + return f"" + + def __len__(self) -> int: + return len(self.entries) + + def __iter__(self) -> Iterator[int]: + return iter(self.entries) + + def __getitem__(self, idx: int) -> int: + return self.entries[idx] + + @cached_property + def entries(self) -> list[int]: + """List of addresses in the import address table.""" + self.pe.vfh.seek(self.address) + ctype = c_pe.ULONGLONG if self.pe.is_64bit() else c_pe.ULONG + return ctype[self.size // len(ctype)](self.pe.vfh) diff --git a/dissect/executable/pe/directory/imports.py b/dissect/executable/pe/directory/imports.py new file mode 100644 index 0000000..cde895d --- /dev/null +++ b/dissect/executable/pe/directory/imports.py @@ -0,0 +1,151 @@ +# `import` is a reserved keyword in Python, so we can't name this file `import.py` +# Doorn in mijn oog + +from __future__ import annotations + +from functools import cached_property +from typing import TYPE_CHECKING + +from dissect.util.ts import from_unix + +from dissect.executable.pe.c_pe import c_pe +from dissect.executable.pe.directory.base import DataDirectory + +if TYPE_CHECKING: + import datetime + from collections.abc import Iterator + + from dissect.executable.pe.pe import PE + + +class ImportDirectory(DataDirectory): + """The import directory of a PE file.""" + + def __repr__(self) -> str: + return f"" + + def __len__(self) -> int: + return len(self.modules) + + def __getitem__(self, idx: str | int) -> ImportModule: + if isinstance(idx, int): + return self.modules[idx] + if isinstance(idx, str): + if idx not in self._by_name: + raise KeyError(f"Import module {idx!r} not found") + return self._by_name[idx] + raise TypeError(f"ImportDirectory indices must be str or int, not {type(idx).__name__}") + + def __contains__(self, name: str) -> bool: + if isinstance(name, str): + return name in self._by_name + return False + + @cached_property + def modules(self) -> list[ImportModule]: + """List of imported modules.""" + self.pe.vfh.seek(self.address) + return [ImportModule(self.pe, descriptor) for descriptor in c_pe.IMAGE_IMPORT_DESCRIPTOR[None](self.pe.vfh)] + + @cached_property + def _by_name(self) -> dict[str, ImportModule]: + """A mapping of module names to their :class:`ImportModule`.""" + return {module.name: module for module in self.modules} + + +class ImportModule: + """A module imported by a PE file, containing its functions.""" + + def __init__(self, pe: PE, descriptor: c_pe.IMAGE_IMPORT_DESCRIPTOR): + self.pe = pe + self.descriptor = descriptor + + def __repr__(self) -> str: + return f"" + + def __iter__(self) -> Iterator[ImportFunction]: + return iter(self.functions) + + def __getitem__(self, idx: str | int) -> ImportFunction: + if isinstance(idx, int): + return self._by_ordinal[idx] + if isinstance(idx, str): + if idx not in self._by_name: + raise KeyError(f"Import function {idx!r} not found in module {self.name!r}") + return self._by_name[idx] + raise TypeError(f"ImportModule indices must be str or int, not {type(idx).__name__}") + + def __contains__(self, idx: str | int) -> bool: + if isinstance(idx, int): + return idx in self._by_ordinal + if isinstance(idx, str): + return idx in self._by_name + return False + + @property + def timestamp(self) -> datetime.datetime | None: + """The timestamp of this import module, or ``None`` if the PE file is compiled as reproducible.""" + if self.pe.is_reproducible(): + return None + return from_unix(self.descriptor.TimeDateStamp) + + @cached_property + def name(self) -> str: + """The name of the imported module.""" + self.pe.vfh.seek(self.descriptor.Name) + return c_pe.char[None](self.pe.vfh).decode() + + @cached_property + def functions(self) -> list[ImportFunction]: + """List of functions imported from this module.""" + ctype = c_pe.IMAGE_THUNK_DATA64 if self.pe.is_64bit() else c_pe.IMAGE_THUNK_DATA32 + + self.pe.vfh.seek(self.descriptor.OriginalFirstThunk) + lookup_table = ctype[None](self.pe.vfh) + + self.pe.vfh.seek(self.descriptor.FirstThunk) + address_table = ctype[None](self.pe.vfh) + + return [ + ImportFunction(self, lookup_thunk, address_thunk) + for lookup_thunk, address_thunk in zip(lookup_table, address_table) + ] + + @cached_property + def _by_name(self) -> dict[str, ImportFunction]: + """A mapping of imported function names to their :class:`ImportFunction`.""" + return {func.name: func for func in self.functions if func.name is not None} + + @cached_property + def _by_ordinal(self) -> dict[int, ImportFunction]: + """A mapping of imported function ordinals to their :class:`ImportFunction`.""" + return {func.ordinal: func for func in self.functions} + + +class ImportFunction: + """A function imported from a module.""" + + def __init__( + self, + module: ImportModule, + lookup_thunk: c_pe.IMAGE_THUNK_DATA32 | c_pe.IMAGE_THUNK_DATA64, + address_thunk: c_pe.IMAGE_THUNK_DATA32 | c_pe.IMAGE_THUNK_DATA64, + ): + self.module = module + self.lookup_thunk = lookup_thunk + self.address_thunk = address_thunk + + if lookup_thunk.u1.Ordinal & (c_pe.IMAGE_ORDINAL_FLAG64 if module.pe.is_64bit() else c_pe.IMAGE_ORDINAL_FLAG32): + self.ordinal = lookup_thunk.u1.Ordinal & 0xFFFF + self.name = None + else: + self.module.pe.vfh.seek(lookup_thunk.u1.AddressOfData & (c_pe.IMAGE_ORDINAL_FLAG32 - 1)) + import_by_name = c_pe.IMAGE_IMPORT_BY_NAME(self.module.pe.vfh) + self.ordinal = import_by_name.Hint + self.name = import_by_name.Name.decode() + + self.address = address_thunk.u1.Function if lookup_thunk.u1.Function != address_thunk.u1.Function else None + + def __repr__(self) -> str: + address = hex(self.address) if self.address is not None else "None" + return f"" diff --git a/dissect/executable/pe/directory/load_config.py b/dissect/executable/pe/directory/load_config.py new file mode 100644 index 0000000..2e2c8d1 --- /dev/null +++ b/dissect/executable/pe/directory/load_config.py @@ -0,0 +1,56 @@ +from __future__ import annotations + +from functools import cached_property +from typing import TYPE_CHECKING + +from dissect.util.ts import from_unix + +from dissect.executable.pe.c_pe import c_pe +from dissect.executable.pe.directory.base import DataDirectory + +if TYPE_CHECKING: + import datetime + + +class LoadConfigDirectory(DataDirectory): + """The load configuration directory of a PE file.""" + + @cached_property + def config(self) -> c_pe.IMAGE_LOAD_CONFIG_DIRECTORY32 | c_pe.IMAGE_LOAD_CONFIG_DIRECTORY64: + """The load configuration directory header.""" + self.pe.vfh.seek(self.address) + ctype = c_pe.IMAGE_LOAD_CONFIG_DIRECTORY64 if self.pe.is_64bit() else c_pe.IMAGE_LOAD_CONFIG_DIRECTORY32 + return ctype(self.pe.vfh) + + @property + def timestamp(self) -> datetime.datetime | None: + """The timestamp of the load configuration directory, or ``None`` if the PE file is compiled as reproducible.""" + if self.pe.is_reproducible(): + return None + return from_unix(self.config.TimeDateStamp) + + @property + def security_cookie(self) -> int: + """The security cookie address.""" + return self.config.SecurityCookie + + @property + def guard_flags(self) -> c_pe.IMAGE_GUARD: + """The guard flags.""" + return self.config.GuardFlags & ~c_pe.IMAGE_GUARD_CF_FUNCTION_TABLE_SIZE_MASK + + @property + def chpe(self) -> c_pe.IMAGE_ARM64EC_METADATA | c_pe.IMAGE_CHPE_METADATA_X86 | None: + """The CHPE (Compiled Hybrid Portable Executable) metadata.""" + if not self.config.CHPEMetadataPointer: + return None + + rva = self.pe.va_to_rva(self.config.CHPEMetadataPointer) + self.pe.vfh.seek(rva) + if self.pe.machine == c_pe.IMAGE_FILE_MACHINE.ARM64: + version = c_pe.ULONG(self.pe.vfh) + self.pe.vfh.seek(rva) + if version == 2: + return c_pe.IMAGE_ARM64EC_METADATA_V2(self.pe.vfh) + return c_pe.IMAGE_ARM64EC_METADATA(self.pe.vfh) + return c_pe.IMAGE_CHPE_METADATA_X86(self.pe.vfh) diff --git a/dissect/executable/pe/directory/resource.py b/dissect/executable/pe/directory/resource.py new file mode 100644 index 0000000..61d4fef --- /dev/null +++ b/dissect/executable/pe/directory/resource.py @@ -0,0 +1,589 @@ +from __future__ import annotations + +from functools import cached_property +from io import BytesIO +from typing import TYPE_CHECKING, Any, BinaryIO, Union + +from dissect.util.ts import from_unix, wintimestamp + +try: + from typing import TypeAlias # novermin +except ImportError: + # COMPAT: Remove this when we drop Python 3.9 + TypeAlias = Any + + +from dissect.util.stream import RangeStream + +from dissect.executable.pe.c_pe import c_pe +from dissect.executable.pe.directory.base import DataDirectory +from dissect.executable.pe.locale_id import CP_TO_NAME, LCID_TO_TAG, TAG_TO_LCID + +if TYPE_CHECKING: + import datetime + from collections.abc import Iterator + + from dissect.executable.pe.pe import PE + + +class ResourceDirectory(DataDirectory): + """The resource directory of a PE file. + + This class provides a higher-level interface to access resources in a PE file. If you wish to access + the raw resource directory structure, you can traverse it with the ``tree`` attribute. + """ + + def __init__(self, pe: PE, address: int, size: int): + super().__init__(pe, address, size) + self.tree = ResourceDirectoryEntry(self, address) + + def __repr__(self) -> str: + return f"" + + def __len__(self) -> int: + return len(self.resources) + + def __iter__(self) -> Iterator[Resource]: + return iter(self.resources) + + def __getitem__(self, idx: int | str | c_pe.RT) -> list[Resource] | None: + """Get a resource by index or type. + + Args: + idx: The index of the resource to get, which can be an integer, a string (resource type name), + or a member of the ``c_pe.RT`` enum. Integers refer to the index in the resources list, + while strings and enum members refer to the resource type. + """ + if isinstance(idx, int): + return self.resources[idx] + + if isinstance(idx, (str, c_pe.RT)): + return self.get(idx) + + raise TypeError(f"ResourceDirectory indices must be int, str or RT enum members, not {type(idx).__name__}") + + def __contains__(self, idx: str | c_pe.RT) -> bool: + if isinstance(idx, (str, c_pe.RT)): + return self.get(idx) is not None + + return False + + def get(self, type: int | str | c_pe.RT) -> list[Resource] | None: + """Get all resources of a specific type. + + Args: + type: The type of the resource (e.g. ``c_pe.RT.ICON``). + Integers can also be used to refer to resource types by their numeric value, + or strings to refer to resource types by their name. + """ + if isinstance(type, int): + type = c_pe.RT(type) + + if isinstance(type, str) and type in c_pe.RT.__members__: + type = c_pe.RT[type] + + if (root := self.tree.get(type)) is None: + return None + + return [Resource(type, name, entry) for name, entry in root.iterdir()] + + def find(self, type: int | str | c_pe.RT, name: str | int) -> Resource | None: + """Find a specific resource by type and name. + + Args: + type: The type of the resource (e.g. ``c_pe.RT.ICON``). + Integers can also be used to refer to resource types by their numeric value, + or strings to refer to resource types by their name. + name: The name of the resource, which can be a string or an integer ID. + """ + if isinstance(type, int): + type = c_pe.RT(type) + + if isinstance(type, str) and type in c_pe.RT.__members__: + type = c_pe.RT[type] + + if (root := self.tree.get(type)) is None: + return None + + if isinstance(name, str): + name = TAG_TO_LCID.get(name, name) + + if isinstance(name, (int, c_pe.RT)) and (entry := root.get(name)) is not None: + return Resource(type, name, entry) + + raise KeyError(f"Resource with type {type.name!r} and name {name!r} not found") + + @cached_property + def resources(self) -> list[Resource]: + """Return a list of all resources.""" + result = [] + + for type, type_entry in self.tree.iterdir(): + for name, entry in type_entry.iterdir(): + result.append(Resource(c_pe.RT(type) if isinstance(type, int) else type, name, entry)) + + return result + + @property + def cursor(self) -> list[Resource] | None: + """Return a list of hardware-dependent cursor resources, if available.""" + return self.get(c_pe.RT.CURSOR) + + @property + def bitmap(self) -> list[Resource] | None: + """Return a list of bitmap resources, if available.""" + return self.get(c_pe.RT.BITMAP) + + @property + def icon(self) -> list[Resource] | None: + """Return a list of hardware-dependent icon resources, if available.""" + return self.get(c_pe.RT.ICON) + + @property + def menu(self) -> list[Resource] | None: + """Return a list of menu resources, if available.""" + return self.get(c_pe.RT.MENU) + + @property + def dialog(self) -> list[Resource] | None: + """Return a list of dialog box resources, if available.""" + return self.get(c_pe.RT.DIALOG) + + @property + def string(self) -> list[Resource] | None: + """Return a list of string table resources, if available.""" + return self.get(c_pe.RT.STRING) + + def string_table(self, language: str | int | None = None) -> dict[int, str]: + """Return the parsed string table for a specific language. + + Args: + language: The language of the string table to return. + If ``None``, the first available language is used. + """ + result = {} + + if isinstance(language, str): + language = TAG_TO_LCID.get(language, language) + + root = self.tree.get(c_pe.RT.STRING) + + for id, resource in root.iterdir(): + idx = (id - 1) * 16 + entry = next(resource.iterdir())[1] if language is None else resource.get(language) + + with entry.open() as fh: + while fh.tell() != entry.size: + if length := c_pe.USHORT(fh): + result[idx] = fh.read(length * 2).decode("utf-16-le") + idx += 1 + + return result + + @property + def fontdir(self) -> list[Resource] | None: + """Return a list of font directory resources, if available.""" + return self.get(c_pe.RT.FONTDIR) + + @property + def font(self) -> list[Resource] | None: + """Return a list of font resources, if available.""" + return self.get(c_pe.RT.FONT) + + @property + def accelerator(self) -> list[Resource] | None: + """Return a list of accelerator table resources, if available.""" + return self.get(c_pe.RT.ACCELERATOR) + + def accelerator_table(self, language: str | int | None = None) -> dict[int, str]: + """Return the parsed accelerator table for a specific language. + + Args: + language: The language of the version information to return. + If ``None``, the first available language is used. + """ + result = [] + + if isinstance(language, str): + language = TAG_TO_LCID.get(language, language) + + for accelerator in self.accelerator or []: + with accelerator.open(language) as fh: + last_found = False + while not last_found: + try: + key_flags = c_pe.ULONG(fh) + modifiers = c_pe.ACCEL_F(key_flags & 0xFFFF) + key = c_pe.VK(key_flags >> 16) + cmd = c_pe.ULONG(fh) + + if c_pe.ACCEL_F.LASTKEY in modifiers: + last_found = True + modifiers &= ~c_pe.ACCEL_F.LASTKEY + + result.append((key, cmd & 0xFFFF, modifiers)) + except EOFError: # noqa: PERF203 + break + + return result + + @property + def rcdata(self) -> list[Resource] | None: + """Return a list of application-defined (raw data) resources, if available.""" + return self.get(c_pe.RT.RCDATA) + + @property + def message_table(self) -> list[Resource] | None: + """Return a list of message table resources, if available.""" + return self.get(c_pe.RT.MESSAGETABLE) + + @property + def group_cursor(self) -> list[Resource] | None: + """Return a list of hardware-independent group cursor resources, if available.""" + return self.get(c_pe.RT.GROUP_CURSOR) + + @property + def group_icon(self) -> list[Resource] | None: + """Return a list of hardware-independent group icon resources, if available.""" + return self.get(c_pe.RT.GROUP_ICON) + + @property + def version(self) -> list[Resource] | None: + """Return a list of version resources, if available.""" + return self.get(c_pe.RT.VERSION) + + def vs_version_info(self, language: str | int | None = None) -> dict | None: + """Return the parsed version information for a specific language. + + Args: + language: The language of the version information to return. + If ``None``, the first available language is used. + """ + if isinstance(language, str): + language = TAG_TO_LCID.get(language, language) + + if not (version := self.get(c_pe.RT.VERSION)): + return None + + if len(version) != 1: + raise ValueError(f"Expected exactly one version resource, found {len(version)}") + + _Node: TypeAlias = tuple[str, Union[str, bytes, None], list["_Node"]] + + def _parse_lvt(fh: BinaryIO) -> _Node | None: + start = fh.tell() + length = c_pe.USHORT(fh) + if length == 0: + return None + + value_length = c_pe.USHORT(fh) + value_type = c_pe.USHORT(fh) + + key = c_pe.WCHAR[None](fh).rstrip("\x00") + fh.seek(fh.tell() + (-fh.tell() & 3)) # Align to 4 bytes + value = None + if value_length: + value = ( + fh.read(value_length * 2).decode("utf-16-le").rstrip("\x00") + if value_type == 1 + else fh.read(value_length) + ) + fh.seek(fh.tell() + (-fh.tell() & 3)) # Align to 4 bytes + + children = [] + while fh.tell() - start < length: + if (child := _parse_lvt(fh)) is None: + break + children.append(child) + + return key, value, children + + def _build_dict(node: _Node, obj: dict[str, Any]) -> None: + key, value, children = node + + if key == "VS_VERSION_INFO": + # Special case for VS_VERSION_INFO, which is a top-level key + obj[key] = {} + file_info = c_pe.VS_FIXEDFILEINFO(value.ljust(len(c_pe.VS_FIXEDFILEINFO), b"\x00")) + if file_info.dwSignature != 0xFEEF04BD: + raise ValueError("Invalid VS_FIXEDFILEINFO signature") + + if file_info.dwFileVersionMS or file_info.dwFileVersionLS: + obj[key]["FileVersion"] = ( + f"{file_info.dwFileVersionMS >> 16}.{file_info.dwFileVersionMS & 0xFFFF}.{file_info.dwFileVersionLS >> 16}.{file_info.dwFileVersionLS & 0xFFFF}" # noqa: E501 + ) + + if file_info.dwProductVersionMS or file_info.dwProductVersionLS: + obj[key]["ProductVersion"] = ( + f"{file_info.dwProductVersionMS >> 16}.{file_info.dwProductVersionMS & 0xFFFF}.{file_info.dwProductVersionLS >> 16}.{file_info.dwProductVersionLS & 0xFFFF}" # noqa: E501 + ) + + if file_info.dwFileFlags: + obj[key]["FileFlags"] = c_pe.VS_FF(file_info.dwFileFlags & file_info.dwFileFlagsMask).name + + if file_info.dwFileOS: + upper_file_os = file_info.dwFileOS & 0xFFFF0000 + lower_file_os = file_info.dwFileOS & 0x0000FFFF + obj[key]["FileOS"] = "_".join( + c_pe.VOS(x).name for x in filter(None, [upper_file_os, lower_file_os]) + ) + + if file_info.dwFileType: + obj[key]["FileType"] = c_pe.VFT(file_info.dwFileType).name + + if file_info.dwFileSubtype: + if file_info.dwFileType == c_pe.VFT.DRV: + obj[key]["FileSubtype"] = c_pe.VFT2_DRV(file_info.dwFileSubtype).name + elif file_info.dwFileType == c_pe.VFT.FONT: + obj[key]["FileSubtype"] = c_pe.VFT2_FONT(file_info.dwFileSubtype).name + else: + obj[key]["FileSubtype"] = file_info.dwFileSubtype + + if file_info.dwFileDateMS or file_info.dwFileDateLS: + obj[key]["FileDate"] = wintimestamp(file_info.dwFileDateMS << 32 | file_info.dwFileDateLS) + else: + if value is not None: + obj[key] = value + else: + obj[key] = {} + + for child in children: + _build_dict(child, obj[key]) + + result = {} + with version[0].open(language) as fh: + _build_dict(_parse_lvt(fh), result) + + if sfi := result.get("VS_VERSION_INFO", {}).get("StringFileInfo", {}): + keys = list(sfi.keys()) + for key in keys: + lcid = int(key[:4], 16) + codepage = int(key[4:], 16) + sfi[f"{LCID_TO_TAG.get(lcid, str(lcid))}_{CP_TO_NAME.get(codepage, str(codepage))}"] = sfi[key] + del sfi[key] + + if (vfit := result.get("VS_VERSION_INFO", {}).get("VarFileInfo", {})) and "Translation" in vfit: + buf = BytesIO(vfit["Translation"]) + tmp = [] + for _ in range(len(vfit["Translation"]) // 4): + lcid, codepage = c_pe.USHORT[2](buf) + tmp.append(f"{LCID_TO_TAG.get(lcid, str(lcid))}_{CP_TO_NAME.get(codepage, str(codepage))}") + vfit["Translation"] = tmp + + return result + + @property + def dialog_include(self) -> list[Resource] | None: + """Return a list of dialog include resources, if available.""" + return self.get(c_pe.RT.DLGINCLUDE) + + @property + def plug_and_play(self) -> list[Resource] | None: + """Return a list of plug and play resources, if available.""" + return self.get(c_pe.RT.PLUGPLAY) + + @property + def vxd(self) -> list[Resource] | None: + """Return a list of VXD resources, if available.""" + return self.get(c_pe.RT.VXD) + + @property + def animated_cursor(self) -> list[Resource] | None: + """Return a list of animated cursor resources, if available.""" + return self.get(c_pe.RT.ANICURSOR) + + @property + def animated_icon(self) -> list[Resource] | None: + """Return a list of animated icon resources, if available.""" + return self.get(c_pe.RT.ANIICON) + + @property + def html(self) -> list[Resource] | None: + """Return a list of HTML resources, if available.""" + return self.get(c_pe.RT.HTML) + + @property + def manifest(self) -> list[Resource] | None: + """Return a list of side-by-side assembly manifest resources, if available.""" + return self.get(c_pe.RT.MANIFEST) + + +class Resource: + """Higher level representation of a resource in a PE file. + + This class provides a convenient interface to access resource data, abstracting away the details of the + underlying resource directory structure. + + Args: + type: The type of the resource (e.g. ``c_pe.RT.ICON``). + name: The name of the resource, which can be a string or an integer ID. + entry: The resource directory entry that contains the resource data per language. + """ + + def __init__(self, type: c_pe.RT | str, name: str | int, entry: ResourceDirectoryEntry): + self.type = type + self.name = name + self.entry = entry + + def __repr__(self) -> str: + return f"" + + def __iter__(self) -> Iterator[Resource]: + return self.entry.iterdir() + + def __getitem__(self, idx: int | str) -> ResourceDataEntry: + """Get a specific resource data entry by language. + + Args: + idx: The index of the resource data entry, which can be an integer (LCID) or a string (language tag). + """ + if isinstance(idx, str): + idx = TAG_TO_LCID.get(idx, idx) + + if isinstance(idx, int) and (entry := self.entry.get(idx)) is not None: + return entry + + raise KeyError(f"Resource with language {idx!r} not found in {self!r}") + + def __contains__(self, idx: str | c_pe.RT) -> bool: + if isinstance(idx, str): + idx = TAG_TO_LCID.get(idx, idx) + + if isinstance(idx, int): + return self.entry.get(idx) is not None + + return False + + def languages(self) -> list[str]: + """Return a list of languages for this resource.""" + return [LCID_TO_TAG.get(name, str(name)) for name, _ in self.entry.iterdir()] + + def data(self, language: str | int | None = None) -> bytes: + """Get the resource data for a specific language. + + Args: + language: The language of the resource to open. If ``None``, the first available resource is opened. + """ + with self.open(language) as fh: + return fh.read() + + def open(self, language: str | int | None = None) -> RangeStream: + """Open the resource data as a stream. + + Args: + language: The language of the resource to open. If ``None``, the first available resource is opened. + """ + if language is None: + return next(self.entry.iterdir())[1].open() + + if isinstance(language, str): + language = TAG_TO_LCID.get(language, language) + + if isinstance(language, int) and (entry := self.entry.get(language)) is not None: + return entry.open() + + raise KeyError(f"Resource with language {language!r} not found in {self!r}") + + +class ResourceEntry: + """Base class for resource entries in a PE file.""" + + def __init__(self, rsrc: ResourceDirectory, address: int): + self.rsrc = rsrc + self.address = address + + @cached_property + def entry(self) -> c_pe.IMAGE_RESOURCE_DATA_ENTRY: + raise NotImplementedError + + +class ResourceDataEntry(ResourceEntry): + """A resource data entry in a PE file.""" + + def __repr__(self) -> str: + return f"" + + @cached_property + def entry(self) -> c_pe.IMAGE_RESOURCE_DATA_ENTRY: + """The resource data entry structure.""" + self.rsrc.pe.vfh.seek(self.address) + return c_pe.IMAGE_RESOURCE_DATA_ENTRY(self.rsrc.pe.vfh) + + @property + def offset_to_data(self) -> int: + """The offset to the resource data in the file.""" + return self.entry.OffsetToData + + @property + def size(self) -> int: + """The size of the resource data.""" + return self.entry.Size + + @property + def code_page(self) -> int: + """The code page of the resource data.""" + return self.entry.CodePage + + @property + def data(self) -> bytes: + """The raw resource data.""" + self.rsrc.pe.vfh.seek(self.offset_to_data) + return self.rsrc.pe.vfh.read(self.size) + + def open(self) -> RangeStream: + """Open the resource data as a stream.""" + return RangeStream(self.rsrc.pe.vfh, self.offset_to_data, self.size) + + +class ResourceDirectoryEntry(ResourceEntry): + """A resource directory entry in a PE file.""" + + def __repr__(self) -> str: + return f"" # noqa: E501 + + @cached_property + def entry(self) -> c_pe.IMAGE_RESOURCE_DIRECTORY: + """The resource directory entry structure.""" + self.rsrc.pe.vfh.seek(self.address) + return c_pe.IMAGE_RESOURCE_DIRECTORY(self.rsrc.pe.vfh) + + @property + def timestamp(self) -> datetime.datetime | None: + """The timestamp of this resource directory, or ``None`` if the PE file is compiled as reproducible.""" + if self.rsrc.pe.is_reproducible(): + return None + return from_unix(self.entry.TimeDateStamp) + + def get(self, name: int | str | c_pe.RT) -> ResourceDataEntry | ResourceDirectoryEntry | None: + """Get a resource entry by name.""" + for id, entry in self.iterdir(): + if id == name: + return entry + return None + + def listdir(self) -> dict[int | str, ResourceEntry]: + """Return a dictionary of the entries in this resource directory.""" + return dict(self.iterdir()) + + def iterdir(self) -> Iterator[tuple[int | str, ResourceDataEntry | ResourceDirectoryEntry]]: + """Iterate over the entries in this resource directory.""" + vfh = self.rsrc.pe.vfh + offset = self.address + len(c_pe.IMAGE_RESOURCE_DIRECTORY) + for _ in range(self.entry.NumberOfNamedEntries + self.entry.NumberOfIdEntries): + vfh.seek(offset) + entry = c_pe.IMAGE_RESOURCE_DIRECTORY_ENTRY(vfh) + + if entry.NameIsString: + vfh.seek(self.rsrc.address + entry.NameOffset) + name = c_pe.IMAGE_RESOURCE_DIR_STRING_U(vfh).NameString + else: + name = entry.Id + + if entry.DataIsDirectory: + obj = ResourceDirectoryEntry(self.rsrc, self.rsrc.address + entry.OffsetToDirectory) + else: + obj = ResourceDataEntry(self.rsrc, self.rsrc.address + entry.OffsetToData) + + yield name, obj + + offset += len(c_pe.IMAGE_RESOURCE_DIRECTORY_ENTRY) diff --git a/dissect/executable/pe/directory/security.py b/dissect/executable/pe/directory/security.py new file mode 100644 index 0000000..5692bdb --- /dev/null +++ b/dissect/executable/pe/directory/security.py @@ -0,0 +1,76 @@ +from __future__ import annotations + +from functools import cached_property +from typing import TYPE_CHECKING + +from dissect.executable.pe.c_pe import c_pe +from dissect.executable.pe.directory.base import DataDirectory + +if TYPE_CHECKING: + from collections.abc import Iterator + + +class SecurityDirectory(DataDirectory): + """The security directory of a PE file.""" + + def __repr__(self) -> str: + return f"" + + def __len__(self) -> int: + return len(self.entries) + + def __iter__(self) -> Iterator[Certificate]: + return iter(self.entries) + + def __getitem__(self, idx: int) -> Certificate: + return self.entries[idx] + + @cached_property + def entries(self) -> list[Certificate]: + """List of certificates in the security directory.""" + result = [] + + offset = self.address + while offset < self.address + self.size: + # Note: the offset here is a file offset, not an RVA + self.pe.fh.seek(offset) + + certificate = c_pe.WIN_CERTIFICATE(self.pe.fh) + if certificate.dwLength == 0: + break + + result.append(Certificate(certificate)) + offset += certificate.dwLength + offset += -offset & 7 # Align to 8 bytes + + return result + + +class Certificate: + """A single certificate entry in the security directory.""" + + def __init__(self, certificate: c_pe.WIN_CERTIFICATE): + self.certificate = certificate + + def __repr__(self) -> str: + return f"" + + @property + def revision(self) -> int: + """The revision of the certificate.""" + return self.certificate.wRevision + + @property + def type(self) -> c_pe.WIN_CERT_TYPE: + """The type of the certificate.""" + return self.certificate.wCertificateType + + @property + def size(self) -> int: + """The size of the certificate.""" + return self.certificate.dwLength + + @property + def data(self) -> bytes: + """The raw data of the certificate.""" + return self.certificate.bCertificate diff --git a/dissect/executable/pe/directory/tls.py b/dissect/executable/pe/directory/tls.py new file mode 100644 index 0000000..652dff9 --- /dev/null +++ b/dissect/executable/pe/directory/tls.py @@ -0,0 +1,46 @@ +from __future__ import annotations + +from functools import cached_property +from typing import TYPE_CHECKING + +from dissect.executable.pe.c_pe import c_pe +from dissect.executable.pe.directory.base import DataDirectory + +if TYPE_CHECKING: + from collections.abc import Iterator + + +class TlsDirectory(DataDirectory): + """The TLS (Thread Local Storage) directory of a PE file.""" + + def __repr__(self) -> str: + return f"" + + def __len__(self) -> int: + return len(self.callbacks) + + def __iter__(self) -> Iterator[int]: + return iter(self.callbacks) + + def __getitem__(self, idx: int) -> int: + return self.callbacks[idx] + + @cached_property + def header(self) -> c_pe.IMAGE_TLS_DIRECTORY32 | c_pe.IMAGE_TLS_DIRECTORY64: + """The TLS directory header.""" + self.pe.vfh.seek(self.address) + ctype = c_pe.IMAGE_TLS_DIRECTORY64 if self.pe.is_64bit() else c_pe.IMAGE_TLS_DIRECTORY32 + return ctype(self.pe.vfh) + + @cached_property + def callbacks(self) -> list[int]: + """List of callback addresses.""" + if not self.header.AddressOfCallBacks: + return [] + + self.pe.vfh.seek(self.pe.va_to_rva(self.header.AddressOfCallBacks)) + ctype = c_pe.ULONGLONG if self.pe.is_64bit() else c_pe.ULONG + try: + return ctype[None](self.pe.vfh) + except EOFError: + return [] diff --git a/dissect/executable/pe/locale_id.py b/dissect/executable/pe/locale_id.py new file mode 100644 index 0000000..96ffdeb --- /dev/null +++ b/dissect/executable/pe/locale_id.py @@ -0,0 +1,609 @@ +# Various constants and mappings for locale IDs (LCIDs) and code pages (CPs) used in PE files +from __future__ import annotations + +LCID_TO_TAG = { + 0x0000: "neutral", # Neutral locale + 0x0001: "ar", + 0x0002: "bg", + 0x0003: "ca", + 0x0004: "zh-Hans", + 0x0005: "cs", + 0x0006: "da", + 0x0007: "de", + 0x0008: "el", + 0x0009: "en", + 0x000A: "es", + 0x000B: "fi", + 0x000C: "fr", + 0x000D: "he", + 0x000E: "hu", + 0x000F: "is", + 0x0010: "it", + 0x0011: "ja", + 0x0012: "ko", + 0x0013: "nl", + 0x0014: "no", + 0x0015: "pl", + 0x0016: "pt", + 0x0017: "rm", + 0x0018: "ro", + 0x0019: "ru", + 0x001A: "hr", + 0x001B: "sk", + 0x001C: "sq", + 0x001D: "sv", + 0x001E: "th", + 0x001F: "tr", + 0x0020: "ur", + 0x0021: "id", + 0x0022: "uk", + 0x0023: "be", + 0x0024: "sl", + 0x0025: "et", + 0x0026: "lv", + 0x0027: "lt", + 0x0028: "tg", + 0x0029: "fa", + 0x002A: "vi", + 0x002B: "hy", + 0x002C: "az", + 0x002D: "eu", + 0x002E: "hsb", + 0x002F: "mk", + 0x0030: "st", + 0x0031: "ts", + 0x0032: "tn", + 0x0033: "ve", + 0x0034: "xh", + 0x0035: "zu", + 0x0036: "af", + 0x0037: "ka", + 0x0038: "fo", + 0x0039: "hi", + 0x003A: "mt", + 0x003B: "se", + 0x003C: "ga", + 0x003D: "yi", # reserved + 0x003E: "ms", + 0x003F: "kk", + 0x0040: "ky", + 0x0041: "sw", + 0x0042: "tk", + 0x0043: "uz", + 0x0044: "tt", + 0x0045: "bn", + 0x0046: "pa", + 0x0047: "gu", + 0x0048: "or", + 0x0049: "ta", + 0x004A: "te", + 0x004B: "kn", + 0x004C: "ml", + 0x004D: "as", + 0x004E: "mr", + 0x004F: "sa", + 0x0050: "mn", + 0x0051: "bo", + 0x0052: "cy", + 0x0053: "km", + 0x0054: "lo", + 0x0055: "my", + 0x0056: "gl", + 0x0057: "kok", + 0x0058: "mni", # reserved + 0x0059: "sd", + 0x005A: "syr", + 0x005B: "si", + 0x005C: "chr", + 0x005D: "iu", + 0x005E: "am", + 0x005F: "tzm", + 0x0060: "ks", + 0x0061: "ne", + 0x0062: "fy", + 0x0063: "ps", + 0x0064: "fil", + 0x0065: "dv", + 0x0066: "bin", # reserved + 0x0067: "ff", + 0x0068: "ha", + 0x0069: "ibb", # reserved + 0x006A: "yo", + 0x006B: "quz", + 0x006C: "nso", + 0x006D: "ba", + 0x006E: "lb", + 0x006F: "kl", + 0x0070: "ig", + 0x0071: "kr", # reserved + 0x0072: "om", + 0x0073: "ti", + 0x0074: "gn", + 0x0075: "haw", + 0x0076: "la", # reserved + 0x0077: "so", # reserved + 0x0078: "ii", + 0x0079: "pap", # reserved + 0x007A: "arn", + 0x007C: "moh", + 0x007E: "br", + 0x0080: "ug", + 0x0081: "mi", + 0x0082: "oc", + 0x0083: "co", + 0x0084: "gsw", + 0x0085: "sah", + 0x0086: "qut", + 0x0087: "rw", + 0x0088: "wo", + 0x008C: "prs", + 0x0091: "gd", + 0x0092: "ku", + 0x0093: "quc", # reserved + 0x0401: "ar-SA", + 0x0402: "bg-BG", + 0x0403: "ca-ES", + 0x0404: "zh-TW", + 0x0405: "cs-CZ", + 0x0406: "da-DK", + 0x0407: "de-DE", + 0x0408: "el-GR", + 0x0409: "en-US", + 0x040A: "es-ES_tradnl", + 0x040B: "fi-FI", + 0x040C: "fr-FR", + 0x040D: "he-IL", + 0x040E: "hu-HU", + 0x040F: "is-IS", + 0x0410: "it-IT", + 0x0411: "ja-JP", + 0x0412: "ko-KR", + 0x0413: "nl-NL", + 0x0414: "nb-NO", + 0x0415: "pl-PL", + 0x0416: "pt-BR", + 0x0417: "rm-CH", + 0x0418: "ro-RO", + 0x0419: "ru-RU", + 0x041A: "hr-HR", + 0x041B: "sk-SK", + 0x041C: "sq-AL", + 0x041D: "sv-SE", + 0x041E: "th-TH", + 0x041F: "tr-TR", + 0x0420: "ur-PK", + 0x0421: "id-ID", + 0x0422: "uk-UA", + 0x0423: "be-BY", + 0x0424: "sl-SI", + 0x0425: "et-EE", + 0x0426: "lv-LV", + 0x0427: "lt-LT", + 0x0428: "tg-Cyrl-TJ", + 0x0429: "fa-IR", + 0x042A: "vi-VN", + 0x042B: "hy-AM", + 0x042C: "az-Latn-AZ", + 0x042D: "eu-ES", + 0x042E: "hsb-DE", + 0x042F: "mk-MK", + 0x0430: "st-ZA", + 0x0431: "ts-ZA", + 0x0432: "tn-ZA", + 0x0433: "ve-ZA", + 0x0434: "xh-ZA", + 0x0435: "zu-ZA", + 0x0436: "af-ZA", + 0x0437: "ka-GE", + 0x0438: "fo-FO", + 0x0439: "hi-IN", + 0x043A: "mt-MT", + 0x043B: "se-NO", + 0x043D: "yi-001", + 0x043E: "ms-MY", + 0x043F: "kk-KZ", + 0x0440: "ky-KG", + 0x0441: "sw-KE", + 0x0442: "tk-TM", + 0x0443: "uz-Latn-UZ", + 0x0444: "tt-RU", + 0x0445: "bn-IN", + 0x0446: "pa-IN", + 0x0447: "gu-IN", + 0x0448: "or-IN", + 0x0449: "ta-IN", + 0x044A: "te-IN", + 0x044B: "kn-IN", + 0x044C: "ml-IN", + 0x044D: "as-IN", + 0x044E: "mr-IN", + 0x044F: "sa-IN", + 0x0450: "mn-MN", + 0x0451: "bo-CN", + 0x0452: "cy-GB", + 0x0453: "km-KH", + 0x0454: "lo-LA", + 0x0455: "my-MM", + 0x0456: "gl-ES", + 0x0457: "kok-IN", + 0x0458: "mni-IN", # reserved + 0x0459: "sd-Deva-IN", # reserved + 0x045A: "syr-SY", + 0x045B: "si-LK", + 0x045C: "chr-Cher-US", + 0x045D: "iu-Cans-CA", + 0x045E: "am-ET", + 0x045F: "tzm-Arab-MA", + 0x0460: "ks-Arab", + 0x0461: "ne-NP", + 0x0462: "fy-NL", + 0x0463: "ps-AF", + 0x0464: "fil-PH", + 0x0465: "dv-MV", + 0x0466: "bin-NG", # reserved + 0x0467: "ff-NG", # ff-Latn-NG + 0x0468: "ha-Latn-NG", + 0x0469: "ibb-NG", # reserved + 0x046A: "yo-NG", + 0x046B: "quz-BO", + 0x046C: "nso-ZA", + 0x046D: "ba-RU", + 0x046E: "lb-LU", + 0x046F: "kl-GL", + 0x0470: "ig-NG", + 0x0471: "kr-Latn-NG", + 0x0472: "om-ET", + 0x0473: "ti-ET", + 0x0474: "gn-PY", + 0x0475: "haw-US", + 0x0476: "la-VA", + 0x0477: "so-SO", + 0x0478: "ii-CN", + 0x0479: "pap-029", # reserved + 0x047A: "arn-CL", + 0x047C: "moh-CA", + 0x047E: "br-FR", + 0x0480: "ug-CN", + 0x0481: "mi-NZ", + 0x0482: "oc-FR", + 0x0483: "co-FR", + 0x0484: "gsw-FR", + 0x0485: "sah-RU", + 0x0486: "qut-GT", # reserved + 0x0487: "rw-RW", + 0x0488: "wo-SN", + 0x048C: "prs-AF", + 0x048D: "plt-MG", # reserved + 0x048E: "zh-yue-HK", # reserved + 0x048F: "tdd-Tale-CN", # reserved + 0x0490: "khb-Talu-CN", # reserved + 0x0491: "gd-GB", + 0x0492: "ku-Arab-IQ", + 0x0493: "quc-CO", # reserved + 0x0501: "qps-ploc", + 0x05FE: "qps-ploca", + 0x0801: "ar-IQ", + 0x0803: "ca-ES-valencia", + 0x0804: "zh-CN", + 0x0807: "de-CH", + 0x0809: "en-GB", + 0x080A: "es-MX", + 0x080C: "fr-BE", + 0x0810: "it-CH", + 0x0811: "ja-Ploc-JP", # reserved + 0x0813: "nl-BE", + 0x0814: "nn-NO", + 0x0816: "pt-PT", + 0x0818: "ro-MD", + 0x0819: "ru-MD", + 0x081A: "sr-Latn-CS", + 0x081D: "sv-FI", + 0x0820: "ur-IN", + 0x0827: "Invalid", + 0x082C: "az-Cyrl-AZ", # reserved + 0x082E: "dsb-DE", + 0x0832: "tn-BW", + 0x083B: "se-SE", + 0x083C: "ga-IE", + 0x083E: "ms-BN", + 0x083F: "kk-Latn-KZ", # reserved + 0x0843: "uz-Cyrl-UZ", # reserved + 0x0845: "bn-BD", + 0x0846: "pa-Arab-PK", + 0x0849: "ta-LK", + 0x0850: "mn-Mong-CN", # reserved + 0x0851: "bo-BT", # reserved + 0x0859: "sd-Arab-PK", + 0x085D: "iu-Latn-CA", + 0x085F: "tzm-Latn-DZ", + 0x0860: "ks-Deva-IN", + 0x0861: "ne-IN", + 0x0867: "ff-Latn-SN", + 0x086B: "quz-EC", + 0x0873: "ti-ER", + 0x09FF: "qps-plocm", + 0x0C01: "ar-EG", + 0x0C04: "zh-HK", + 0x0C07: "de-AT", + 0x0C09: "en-AU", + 0x0C0A: "es-ES", + 0x0C0C: "fr-CA", + 0x0C1A: "sr-Cyrl-CS", + 0x0C3B: "se-FI", + 0x0C50: "mn-Mong-MN", + 0x0C51: "dz-BT", + 0x0C5F: "tmz-MA", # reserved + 0x0C6B: "quz-PE", + 0x1001: "ar-LY", + 0x1004: "zh-SG", + 0x1007: "de-LU", + 0x1009: "en-CA", + 0x100A: "es-GT", + 0x100C: "fr-CH", + 0x101A: "hr-BA", + 0x103B: "smj-NO", + 0x105F: "tzm-Tfng-MA", + 0x1401: "ar-DZ", + 0x1404: "zh-MO", + 0x1407: "de-LI", + 0x1409: "en-NZ", + 0x140A: "es-CR", + 0x140C: "fr-LU", + 0x141A: "bs-Latn-BA", + 0x143B: "smj-SE", + 0x1801: "ar-MA", + 0x1809: "en-IE", + 0x180A: "es-PA", + 0x180C: "fr-MC", + 0x181A: "sr-Latn-BA", + 0x183B: "sma-NO", + 0x1C01: "ar-TN", + 0x1C09: "en-ZA", + 0x1C0A: "es-DO", + 0x1C0C: "fr-029", + 0x1C1A: "sr-Cyrl-BA", + 0x1C3B: "sma-SE", + 0x2001: "ar-OM", + 0x2009: "en-JM", + 0x200A: "es-VE", + 0x200C: "fr-RE", + 0x201A: "bs-Cyrl-BA", + 0x203B: "sms-FI", + 0x2401: "ar-YE", + 0x2409: "en-029", # reserved + 0x240A: "es-CO", + 0x240C: "fr-CD", + 0x241A: "sr-Latn-RS", + 0x243B: "smn-FI", + 0x2801: "ar-SY", + 0x2809: "en-BZ", + 0x280A: "es-PE", + 0x280C: "fr-SN", + 0x281A: "sr-Cyrl-RS", + 0x2C01: "ar-JO", + 0x2C09: "en-TT", + 0x2C0A: "es-AR", + 0x2C0C: "fr-CM", + 0x2C1A: "sr-Latn-ME", + 0x3001: "ar-LB", + 0x3009: "en-ZW", + 0x300A: "es-EC", + 0x300C: "fr-CI", + 0x301A: "sr-Cyrl-ME", + 0x3401: "ar-KW", + 0x3409: "en-PH", + 0x340A: "es-CL", + 0x340C: "fr-ML", + 0x3801: "ar-AE", + 0x3809: "en-ID", # reserved + 0x380A: "es-UY", + 0x380C: "fr-MA", + 0x3C01: "ar-BH", + 0x3C09: "en-HK", + 0x3C0A: "es-PY", + 0x3C0C: "fr-HT", + 0x4001: "ar-QA", + 0x4009: "en-IN", + 0x400A: "es-BO", + 0x4401: "ar-Ploc-SA", # reserved + 0x4409: "en-MY", + 0x440A: "es-SV", + 0x4801: "ar-145", # reserved + 0x4809: "en-SG", + 0x480A: "es-HN", + 0x4C09: "en-AE", + 0x4C0A: "es-NI", + 0x5009: "en-BH", # reserved + 0x500A: "es-PR", + 0x5409: "en-EG", # reserved + 0x540A: "es-US", + 0x5809: "en-JO", # reserved + 0x580A: "es-419", # reserved + 0x5C09: "en-KW", # reserved + 0x5C0A: "es-CU", + 0x6009: "en-TR", # reserved + 0x6409: "en-YE", # reserved + 0x641A: "bs-Cyrl", + 0x681A: "bs-Latn", + 0x6C1A: "sr-Cyrl", + 0x701A: "sr-Latn", + 0x703B: "smn", + 0x742C: "az-Cyrl", + 0x743B: "sms", + 0x7804: "zh", + 0x7814: "nn", + 0x781A: "bs", + 0x782C: "az-Latn", + 0x783B: "sma", + 0x783F: "kk-Cyrl", # reserved + 0x7843: "uz-Cyrl", + 0x7850: "mn-Cyrl", + 0x785D: "iu-Cans", + 0x785F: "tzm-Tfng", + 0x7C04: "zh-Hant", + 0x7C14: "nb", + 0x7C1A: "sr", + 0x7C28: "tg-Cyrl", + 0x7C2E: "dsb", + 0x7C3B: "smj", + 0x7C3F: "kk-Latn", # reserved + 0x7C43: "uz-Latn", + 0x7C46: "pa-Arab", + 0x7C50: "mn-Mong", + 0x7C59: "sd-Arab", + 0x7C5C: "chr-Cher", + 0x7C5D: "iu-Latn", + 0x7C5F: "tzm-Latn", + 0x7C67: "ff-Latn", + 0x7C68: "ha-Latn", + 0x7C92: "ku-Arab", + 0xE40C: "fr-015", # reserved +} + +TAG_TO_LCID = {v: k for k, v in LCID_TO_TAG.items()} + + +CP_TO_NAME = { + 37: "IBM037", + 437: "IBM437", + 500: "IBM500", + 708: "ASMO-708", + 720: "DOS-720", + 737: "ibm737", + 775: "ibm775", + 850: "ibm850", + 852: "ibm852", + 855: "IBM855", + 857: "ibm857", + 858: "IBM00858", + 860: "IBM860", + 861: "ibm861", + 862: "DOS-862", + 863: "IBM863", + 864: "IBM864", + 865: "IBM865", + 866: "cp866", + 869: "ibm869", + 870: "IBM870", + 874: "windows-874", + 875: "cp875", + 932: "shift_jis", + 936: "gb2312", + 949: "ks_c_5601-1987", + 950: "big5", + 1026: "IBM1026", + 1047: "IBM01047", + 1140: "IBM01140", + 1141: "IBM01141", + 1142: "IBM01142", + 1143: "IBM01143", + 1144: "IBM01144", + 1145: "IBM01145", + 1146: "IBM01146", + 1147: "IBM01147", + 1148: "IBM01148", + 1149: "IBM01149", + 1200: "utf-16", + 1201: "unicodeFFFE", + 1250: "windows-1250", + 1251: "windows-1251", + 1252: "windows-1252", + 1253: "windows-1253", + 1254: "windows-1254", + 1255: "windows-1255", + 1256: "windows-1256", + 1257: "windows-1257", + 1258: "windows-1258", + 1361: "Johab", + 10000: "macintosh", + 10001: "x-mac-japanese", + 10002: "x-mac-chinesetrad", + 10003: "x-mac-korean", + 10004: "x-mac-arabic", + 10005: "x-mac-hebrew", + 10006: "x-mac-greek", + 10007: "x-mac-cyrillic", + 10008: "x-mac-chinesesimp", + 10010: "x-mac-romanian", + 10017: "x-mac-ukrainian", + 10021: "x-mac-thai", + 10029: "x-mac-ce", + 10079: "x-mac-icelandic", + 10081: "x-mac-turkish", + 10082: "x-mac-croatian", + 12000: "utf-32", + 12001: "utf-32BE", + 20000: "x-Chinese_CNS", + 20001: "x-cp20001", + 20002: "x_Chinese-Eten", + 20003: "x-cp20003", + 20004: "x-cp20004", + 20005: "x-cp20005", + 20105: "x-IA5", + 20106: "x-IA5-German", + 20107: "x-IA5-Swedish", + 20108: "x-IA5-Norwegian", + 20127: "us-ascii", + 20261: "x-cp20261", + 20269: "x-cp20269", + 20273: "IBM273", + 20277: "IBM277", + 20278: "IBM278", + 20280: "IBM280", + 20284: "IBM284", + 20285: "IBM285", + 20290: "IBM290", + 20297: "IBM297", + 20420: "IBM420", + 20423: "IBM423", + 20424: "IBM424", + 20833: "x-EBCDIC-KoreanExtended", + 20838: "IBM-Thai", + 20866: "koi8-r", + 20871: "IBM871", + 20880: "IBM880", + 20905: "IBM905", + 20924: "IBM00924", + 20932: "EUC-JP", + 20936: "x-cp20936", + 20949: "x-cp20949", + 21025: "cp1025", + 21866: "koi8-u", + 28591: "iso-8859-1", + 28592: "iso-8859-2", + 28593: "iso-8859-3", + 28594: "iso-8859-4", + 28595: "iso-8859-5", + 28596: "iso-8859-6", + 28597: "iso-8859-7", + 28598: "iso-8859-8", + 28599: "iso-8859-9", + 28603: "iso-8859-13", + 28605: "iso-8859-15", + 29001: "x-Europa", + 38598: "iso-8859-8-i", + 50220: "iso-2022-jp", + 50221: "csISO2022JP", + 50222: "iso-2022-jp", + 50225: "iso-2022-kr", + 50227: "x-cp50227", + 51932: "euc-jp", + 51936: "EUC-CN", + 51949: "euc-kr", + 52936: "hz-gb-2312", + 54936: "GB18030", + 57002: "x-iscii-de", + 57003: "x-iscii-be", + 57004: "x-iscii-ta", + 57005: "x-iscii-te", + 57006: "x-iscii-as", + 57007: "x-iscii-or", + 57008: "x-iscii-ka", + 57009: "x-iscii-ma", + 57010: "x-iscii-gu", + 57011: "x-iscii-pa", + 65000: "utf-7", + 65001: "utf-8", +} + +NAME_TO_CP = {v: k for k, v in CP_TO_NAME.items()} diff --git a/dissect/executable/pe/pe.py b/dissect/executable/pe/pe.py new file mode 100644 index 0000000..d0634af --- /dev/null +++ b/dissect/executable/pe/pe.py @@ -0,0 +1,448 @@ +from __future__ import annotations + +import io +from bisect import bisect_right +from functools import cached_property +from typing import TYPE_CHECKING, BinaryIO + +from dissect.util.stream import AlignedStream, BufferedStream, RangeStream +from dissect.util.ts import from_unix + +from dissect.executable.exception import InvalidSignatureError +from dissect.executable.pe.c_pe import c_pe +from dissect.executable.pe.directory import ( + BaseRelocationDirectory, + BoundImportDirectory, + ComDescriptorDirectory, + DataDirectory, + DebugDirectory, + DelayImportDirectory, + ExceptionDirectory, + ExportDirectory, + IatDirectory, + ImportDirectory, + LoadConfigDirectory, + ResourceDirectory, + SecurityDirectory, + TlsDirectory, +) + +if TYPE_CHECKING: + import datetime + + +class PE: + """PE file parser. + + Args: + fh: A file-like object of an executable. + virtual: Indicate whether to use virtual addressing instead of physical. + Use this when the file has already been mapped into memory. + """ + + def __init__(self, fh: BinaryIO, virtual: bool = False): + self.fh = fh + self.virtual = virtual + + self.fh.seek(0) + + self.mz_header = c_pe.IMAGE_DOS_HEADER(self.fh) + if self.mz_header.e_magic != c_pe.IMAGE_DOS_SIGNATURE: + raise InvalidSignatureError( + f"File is not a valid PE file, wrong MZ signature: {self.mz_header.e_magic.to_bytes(2, 'little')} " + f"(expected {c_pe.IMAGE_DOS_SIGNATURE.to_bytes(2, 'little')})" + ) + + self.os2_header = None + self.file_header = None + self.optional_header = None + self.sections: list[Section] = [] + self.vfh = None + + self.fh.seek(self.mz_header.e_lfanew) + signature = c_pe.ULONG(fh) + if (signature & 0xFFFF) == c_pe.IMAGE_OS2_SIGNATURE: + self.fh.seek(-4, io.SEEK_CUR) + self.os2_header = c_pe.IMAGE_OS2_HEADER(self.fh) + + elif signature == c_pe.IMAGE_NT_SIGNATURE: + # No need to correct the offset + self.file_header = c_pe.IMAGE_FILE_HEADER(self.fh) + + if self.file_header.SizeOfOptionalHeader: + optional_magic = c_pe.USHORT(self.fh) + self.fh.seek(-2, io.SEEK_CUR) + + if optional_magic == c_pe.IMAGE_NT_OPTIONAL_HDR32_MAGIC: + self.optional_header = c_pe.IMAGE_OPTIONAL_HEADER32(self.fh) + elif optional_magic == c_pe.IMAGE_NT_OPTIONAL_HDR64_MAGIC: + self.optional_header = c_pe.IMAGE_OPTIONAL_HEADER64(self.fh) + else: + raise InvalidSignatureError( + f"File is not a valid PE file, wrong NT header magic: {optional_magic:#x} " + f"(expected {c_pe.IMAGE_NT_OPTIONAL_HDR32_MAGIC:#x} or {c_pe.IMAGE_NT_OPTIONAL_HDR64_MAGIC:#x})" + ) + + self.sections = [Section.from_fh(self, self.fh) for _ in range(self.file_header.NumberOfSections)] + + self.vfh = self.open() + else: + raise InvalidSignatureError( + f"File is not a valid PE file, wrong header signature: {signature.to_bytes(4, 'little')} " + f"(expected {c_pe.IMAGE_NT_SIGNATURE.to_bytes(4, 'little')} (NT) " + f"or {c_pe.IMAGE_OS2_SIGNATURE.to_bytes(2, 'little')} (OS/2))" + ) + + self.fh.seek(len(self.mz_header)) + self.dos_stub = self.fh.read(self.mz_header.e_lfanew - len(self.mz_header)) + + @property + def machine(self) -> c_pe.IMAGE_FILE_MACHINE: + """Return the machine type of the PE file.""" + if not self.file_header: + return c_pe.IMAGE_FILE_MACHINE.UNKNOWN + return self.file_header.Machine + + @property + def image_base(self) -> int: + """Return the image base address of the PE file.""" + if not self.optional_header: + return 0 + return self.optional_header.ImageBase + + @property + def timestamp(self) -> datetime.datetime | None: + """The compilation timestamp of the PE file, or ``None`` if the PE file is compiled as reproducible.""" + if not self.file_header or self.is_reproducible(): + return None + return from_unix(self.file_header.TimeDateStamp) + + def is_pe(self) -> bool: + """Return if the file is a valid PE file.""" + return self.is_nt() + + def is_nt(self) -> bool: + """Return if the file is a valid NT executable.""" + return self.file_header is not None + + def is_os2(self) -> bool: + """Return if the file is an OS/2 executable.""" + return self.os2_header is not None + + def is_64bit(self) -> bool: + """Return if the PE file is 64-bit (PE32+).""" + return self.optional_header and self.optional_header.Magic == c_pe.IMAGE_NT_OPTIONAL_HDR64_MAGIC + + def is_reproducible(self) -> bool: + """Return if the PE file is reproducible (i.e. has a REPRO debug entry).""" + return self.debug and any(entry.type == c_pe.IMAGE_DEBUG_TYPE.REPRO for entry in self.debug.entries) + + def pdb_path(self) -> str | None: + """Return the PDB path, if available.""" + for entry in self.debug.entries if self.debug else []: + if entry.type == c_pe.IMAGE_DEBUG_TYPE.CODEVIEW: + return entry.pdb + return None + + def _data_directory(self, index: c_pe.IMAGE_DIRECTORY_ENTRY) -> c_pe.IMAGE_DATA_DIRECTORY | None: + """Return the data directory at the given index.""" + if not self.optional_header or not self.optional_header.DataDirectory: + return None + if index < 0 or index >= len(self.optional_header.DataDirectory): + return None + if not (entry := self.optional_header.DataDirectory[index]): + return None + return entry + + def data_directories(self) -> dict[c_pe.IMAGE_DIRECTORY_ENTRY, DataDirectory]: + """Return all data directories.""" + result = {} + for index in c_pe.IMAGE_DIRECTORY_ENTRY: + if index == c_pe.IMAGE_DIRECTORY_ENTRY.EXPORT: + result[index] = self.exports + elif index == c_pe.IMAGE_DIRECTORY_ENTRY.IMPORT: + result[index] = self.imports + elif index == c_pe.IMAGE_DIRECTORY_ENTRY.RESOURCE: + result[index] = self.resources + elif index == c_pe.IMAGE_DIRECTORY_ENTRY.EXCEPTION: + result[index] = self.exceptions + elif index == c_pe.IMAGE_DIRECTORY_ENTRY.SECURITY and not self.virtual: + result[index] = self.security + elif index == c_pe.IMAGE_DIRECTORY_ENTRY.BASERELOC: + result[index] = self.base_relocations + elif index == c_pe.IMAGE_DIRECTORY_ENTRY.DEBUG: + result[index] = self.debug + elif index == c_pe.IMAGE_DIRECTORY_ENTRY.TLS: + result[index] = self.tls + elif index == c_pe.IMAGE_DIRECTORY_ENTRY.LOAD_CONFIG: + result[index] = self.load_config + elif index == c_pe.IMAGE_DIRECTORY_ENTRY.BOUND_IMPORT: + result[index] = self.bound_import + elif index == c_pe.IMAGE_DIRECTORY_ENTRY.IAT: + result[index] = self.iat + elif index == c_pe.IMAGE_DIRECTORY_ENTRY.DELAY_IMPORT: + result[index] = self.delay_import + elif index == c_pe.IMAGE_DIRECTORY_ENTRY.COM_DESCRIPTOR: + result[index] = self.com_descriptor + else: + if entry := self._data_directory(index): + result[index] = DataDirectory(self, entry.VirtualAddress, entry.Size) + return result + + @cached_property + def exports(self) -> ExportDirectory | None: + """Return the export directory, if available.""" + if not (entry := self._data_directory(c_pe.IMAGE_DIRECTORY_ENTRY.EXPORT)): + return None + return ExportDirectory(self, entry.VirtualAddress, entry.Size) + + @cached_property + def imports(self) -> ImportDirectory | None: + """Return the import directory, if available.""" + if not (entry := self._data_directory(c_pe.IMAGE_DIRECTORY_ENTRY.IMPORT)): + return None + return ImportDirectory(self, entry.VirtualAddress, entry.Size) + + @cached_property + def resources(self) -> ResourceDirectory | None: + """Return the resource directory, if available.""" + if not (entry := self._data_directory(c_pe.IMAGE_DIRECTORY_ENTRY.RESOURCE)): + return None + return ResourceDirectory(self, entry.VirtualAddress, entry.Size) + + @cached_property + def exceptions(self) -> ExceptionDirectory | None: + """Return the exception directory, if available.""" + if not (entry := self._data_directory(c_pe.IMAGE_DIRECTORY_ENTRY.EXCEPTION)): + return None + return ExceptionDirectory(self, entry.VirtualAddress, entry.Size) + + @cached_property + def security(self) -> SecurityDirectory | None: + """Return the security directory, if available.""" + if not (entry := self._data_directory(c_pe.IMAGE_DIRECTORY_ENTRY.SECURITY)) and not self.virtual: + return None + return SecurityDirectory(self, entry.VirtualAddress, entry.Size) + + @cached_property + def base_relocations(self) -> BaseRelocationDirectory | None: + """Return the base relocation directory, if available.""" + if not (entry := self._data_directory(c_pe.IMAGE_DIRECTORY_ENTRY.BASERELOC)): + return None + return BaseRelocationDirectory(self, entry.VirtualAddress, entry.Size) + + @cached_property + def debug(self) -> DebugDirectory | None: + """Return the debug directory, if available.""" + if not (entry := self._data_directory(c_pe.IMAGE_DIRECTORY_ENTRY.DEBUG)): + return None + return DebugDirectory(self, entry.VirtualAddress, entry.Size) + + @cached_property + def global_pointer(self) -> int: + """Return the global pointer address, if available.""" + if not (entry := self._data_directory(c_pe.IMAGE_DIRECTORY_ENTRY.GLOBALPTR)): + return None + return entry.VirtualAddress + + @cached_property + def tls(self) -> TlsDirectory | None: + """Return the TLS (Thread Local Storage) directory, if available.""" + if not (entry := self._data_directory(c_pe.IMAGE_DIRECTORY_ENTRY.TLS)): + return None + return TlsDirectory(self, entry.VirtualAddress, entry.Size) + + @cached_property + def load_config(self) -> LoadConfigDirectory | None: + """Return the load config directory, if available.""" + if not (entry := self._data_directory(c_pe.IMAGE_DIRECTORY_ENTRY.LOAD_CONFIG)): + return None + return LoadConfigDirectory(self, entry.VirtualAddress, entry.Size) + + @cached_property + def bound_import(self) -> BoundImportDirectory | None: + """Return the bound import directory, if available.""" + if not (entry := self._data_directory(c_pe.IMAGE_DIRECTORY_ENTRY.BOUND_IMPORT)): + return None + return BoundImportDirectory(self, entry.VirtualAddress, entry.Size) + + @cached_property + def iat(self) -> IatDirectory | None: + """Return the import address table (IAT) directory, if available.""" + if not (entry := self._data_directory(c_pe.IMAGE_DIRECTORY_ENTRY.IAT)): + return None + return IatDirectory(self, entry.VirtualAddress, entry.Size) + + @cached_property + def delay_import(self) -> DelayImportDirectory | None: + """Return the delay import directory, if available.""" + if not (entry := self._data_directory(c_pe.IMAGE_DIRECTORY_ENTRY.DELAY_IMPORT)): + return None + return DelayImportDirectory(self, entry.VirtualAddress, entry.Size) + + @cached_property + def com_descriptor(self) -> ComDescriptorDirectory | None: + """Return the COM descriptor directory, if available.""" + if not (entry := self._data_directory(c_pe.IMAGE_DIRECTORY_ENTRY.COM_DESCRIPTOR)): + return None + return ComDescriptorDirectory(self, entry.VirtualAddress, entry.Size) + + def va_to_rva(self, va: int) -> int: + """Return the relative virtual address (RVA) of the given virtual address (VA).""" + return va - self.image_base + + def open(self) -> VirtualStream: + """Return a stream of the virtual address space of the PE file.""" + return VirtualStream(self) if not self.virtual else BufferedStream(self.fh) + + +class Section: + """A section in a PE file.""" + + def __init__(self, pe: PE, header: c_pe.IMAGE_SECTION_HEADER): + self.pe = pe + self.header = header + + def __repr__(self) -> str: + return f"
" # noqa: E501 + + @classmethod + def from_fh(cls, pe: PE, fh: BinaryIO) -> None: + """Read a section header from the file-like object. + + Args: + pe: The PE object to which this section belongs. + fh: The file-like object from which to read the section header. + """ + header = c_pe.IMAGE_SECTION_HEADER(fh) + return cls(pe, header) + + def open(self) -> RangeStream: + """Return a stream for the section data.""" + return SectionStream(self) + + @property + def name(self) -> str: + """Return the name of the section.""" + return self.header.Name.decode().strip("\x00") + + @property + def virtual_size(self) -> int: + """Return the virtual size of the section. + + Returns: + The virtual size of the section as an `int`. + """ + return self.header.Misc.VirtualSize + + @property + def virtual_address(self) -> int: + """Return the virtual address of the section. + + Returns: + The virtual address of the section as an `int`. + """ + return self.header.VirtualAddress + + @property + def raw_size(self) -> int: + """Return the raw size of the section. + + Returns: + The raw size of the section as an `int`. + """ + return self.header.SizeOfRawData + + @property + def pointer_to_raw_data(self) -> int: + """Return the pointer to raw data of the section. + + Returns: + The pointer to raw data of the section as an `int`. + """ + return self.header.PointerToRawData + + +class VirtualStream(AlignedStream): + """Read from a PE file as if it's been mapped into the virtual address space.""" + + def __init__(self, pe: PE): + self.pe = pe + self._sections = sorted(pe.sections, key=lambda s: s.virtual_address) + self._lookup = [s.virtual_address for s in self._sections] + super().__init__(pe.optional_header.SizeOfImage, pe.optional_header.SectionAlignment) + + def _read(self, offset: int, length: int) -> bytes: + result = [] + + # Read from the file header + if offset < self.pe.optional_header.SizeOfHeaders: + self.pe.fh.seek(offset) + read_length = min(length, self.pe.optional_header.SizeOfHeaders - offset) + result.append(self.pe.fh.read(read_length)) + + length -= read_length + offset += read_length + + section_idx = bisect_right(self._lookup, offset) + + while length > 0: + # Read from the sections or fill in gaps + current_section = self._sections[section_idx - 1] if section_idx > 0 else None + next_section = self._sections[section_idx] if section_idx < len(self._sections) else None + + if not current_section and not next_section: + # What + result.append(b"\x00" * length) + break + + if not current_section or offset >= current_section.virtual_address + current_section.virtual_size: + # In between sections or after the last section + read_length = min(length, (next_section.virtual_address if next_section else self.size) - offset) + result.append(b"\x00" * read_length) + + length -= read_length + offset += read_length + section_idx += 1 + continue + + if ( + current_section.virtual_address + <= offset + < current_section.virtual_address + current_section.virtual_size + ): + # Within the current section + offset_in_section = offset - current_section.virtual_address + if offset_in_section < current_section.raw_size: + read_length = min(length, current_section.raw_size - offset_in_section) + + self.pe.fh.seek(current_section.pointer_to_raw_data + offset_in_section) + result.append(self.pe.fh.read(read_length)) + + length -= read_length + offset += read_length + # Stay in the same section + continue + + return b"".join(result) + + +class SectionStream(AlignedStream): + """A stream that reads the section data from a PE file.""" + + def __init__(self, section: Section): + self.section = section + super().__init__(section.virtual_size) + + def _read(self, offset: int, length: int) -> bytes: + result = [] + + if raw_remaining := min(length, max(0, self.section.raw_size - offset)): + self.section.pe.fh.seek(self.section.pointer_to_raw_data + offset) + result.append(self.section.pe.fh.read(raw_remaining)) + length -= raw_remaining + + if length: + result.append(b"\x00" * length) + + return b"".join(result) diff --git a/pyproject.toml b/pyproject.toml index 9da98eb..246ef0a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -87,6 +87,7 @@ ignore = ["E203", "B904", "UP024", "ANN002", "ANN003", "ANN204", "ANN401", "SIM1 [tool.ruff.lint.per-file-ignores] "tests/_docs/**" = ["INP001"] +"**/*.pyi" = ["PYI042", "PYI047", "PYI054"] [tool.ruff.lint.isort] known-first-party = ["dissect.executable"] diff --git a/tests/_data/pe/16/DPMIRES.EXE b/tests/_data/pe/16/DPMIRES.EXE new file mode 100644 index 0000000000000000000000000000000000000000..f96bfc058cbc0d920a140e3e20d130cb15a35c17 GIT binary patch literal 5241 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 literal 0 HcmV?d00001 diff --git a/tests/_data/pe/32/Microsoft.Windows.SoftwareLogo.Binscope.resources.dll b/tests/_data/pe/32/Microsoft.Windows.SoftwareLogo.Binscope.resources.dll new file mode 100644 index 0000000000000000000000000000000000000000..1f93017b892a448b2248cc0bd8971fb1624c3406 GIT binary patch literal 3584 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 literal 0 HcmV?d00001 diff --git a/tests/_data/pe/32/OLEACCHOOKS.DLL b/tests/_data/pe/32/OLEACCHOOKS.DLL new file mode 100644 index 0000000000000000000000000000000000000000..15091020d8ad6180c03d17fc96833674a939cb93 GIT binary patch literal 10240 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 literal 0 HcmV?d00001 diff --git a/tests/_data/pe/32/PUNZIP.EXE b/tests/_data/pe/32/PUNZIP.EXE new file mode 100644 index 0000000000000000000000000000000000000000..2010f0d796729d5fc32fd666317a7758e63e37ba GIT binary patch literal 143360 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 NhJV+;0{^Q5{{d||bzuMi literal 0 HcmV?d00001 diff --git a/tests/_data/pe/32/TpmCertResources.dll b/tests/_data/pe/32/TpmCertResources.dll new file mode 100644 index 0000000000000000000000000000000000000000..b1e54a7faec3484f690f0d549d0508a1b6acb47f GIT binary patch literal 3584 zcmeHI&u<%55dJnvp-CGT4(+8>Y$~_3mn9DU5h^5-I&KNXad51FH~<^lb+)zF*6t>x zK|*IO zn>RD>o0;eID=X**(8GE2Ca^{-V?=##{}J8T~qrbl|9+o3v<_g_%htPj;?_%T5Ox*w}w*EM}jFUS$6?_B;n)|804hfB?jFX*`yE= zT{)m=gNU#>bYiu+$!=Kj?C=KR{R<4Qxajfts+f?t7_*wf2V;aG8IJ4Z$*b6OF66S3 z#wJ{6K36C|#{ILTyVwJtla9uKE2Qs{{!SV> z#HGd`uvyzEU#A`Y7V_R6)|DJ;85%_XTnG8f9prNzF6tY~6BZEouud2nFCMv2xelu@K*8z)eu&d&@|YrvbCb^>Wkfx5DAIauNkRR zomG39yMlW~;A6(NZSd8e{oCbUY>aVg>@t(S!kafcLH=L)sIdwq5}V%3K}3EPgKyrd zD0CQcl|_$tad8As@>j$um1RTKoZO|%T;wUM1iMn#QtPgw3kom4zdAUHh*P)p7g{uE zQzG%Jz@W$WTr?v|;e|%mS?p!elw1@U<#B#JzDu1o7T7zjqltu%LxTNxSoK!enMagF zy6zx-q=-}4_0#u(gn0k&qS1;?JGZluMIS49N#zwZn1PDw-LPJ2M9CsrCckF8nFsv; H6oG#L4^wz= literal 0 HcmV?d00001 diff --git a/tests/_data/pe/32/UWPEnum.dll b/tests/_data/pe/32/UWPEnum.dll new file mode 100644 index 0000000000000000000000000000000000000000..edf7d128ade3602d67bd18b503490d7f65c0d3c0 GIT binary patch literal 8080 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 QnEtZn#^R?Ruz%0|4FGf*$^ZZW literal 0 HcmV?d00001 diff --git a/tests/_data/pe/32/aborttest.exe b/tests/_data/pe/32/aborttest.exe new file mode 100644 index 0000000000000000000000000000000000000000..089b4335afb7d872310c36222858169a74fc0d94 GIT binary patch literal 6144 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 Pp?Q&+GrP_ITRrj*V!~zH literal 0 HcmV?d00001 diff --git a/tests/_data/pe/32/mingwm10.dll b/tests/_data/pe/32/mingwm10.dll new file mode 100644 index 0000000000000000000000000000000000000000..6090f6f05e2650eabd8abcc06026cd5775a3c4dc GIT binary patch literal 10254 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 literal 0 HcmV?d00001 diff --git a/tests/_data/pe/64/comres.dll b/tests/_data/pe/64/comres.dll new file mode 100644 index 0000000000000000000000000000000000000000..38c069689dae34f8e41e00ff15a5fa689a069a22 GIT binary patch literal 10752 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 literal 0 HcmV?d00001 diff --git a/tests/_utils.py b/tests/_utils.py index 8d43746..7574f55 100644 --- a/tests/_utils.py +++ b/tests/_utils.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from pathlib import Path diff --git a/tests/elf/test_section.py b/tests/elf/test_section.py index cd0becf..1282267 100644 --- a/tests/elf/test_section.py +++ b/tests/elf/test_section.py @@ -25,7 +25,11 @@ def section_table(entries: int) -> SectionTable: def mock_section_table(section_data: bytes) -> Mock: - shdr = c_elf_64.Shdr(sh_offset=len(c_elf_64.Shdr), sh_size=len(section_data), sh_entsize=len(section_data)) + shdr = c_elf_64.Shdr( + sh_offset=len(c_elf_64.Shdr), + sh_size=len(section_data), + sh_entsize=len(section_data), + ) mocked_table = Mock() mocked_table.fh = BytesIO(shdr.dumps() + section_data) mocked_table.offset = 0 diff --git a/tests/elf/test_segment_table.py b/tests/elf/test_segment_table.py index e666c80..8e8ac0b 100644 --- a/tests/elf/test_segment_table.py +++ b/tests/elf/test_segment_table.py @@ -34,7 +34,9 @@ def create_segment_table(amount: int, random_data: bytes) -> SegmentTable: data_size = len(random_data) segments_data = [] for idx in range(amount): - data = c_elf_64.Phdr(p_offset=len(c_elf_64.Phdr) * amount + idx * data_size, p_filesz=data_size).dumps() + data = c_elf_64.Phdr( + p_offset=len(c_elf_64.Phdr) * amount + idx * data_size, p_filesz=data_size + ).dumps() segments_data.append(data) segments_data.append(random_data * amount) diff --git a/tests/pe/__init__.py b/tests/pe/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/pe/directory/__init__.py b/tests/pe/directory/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/pe/directory/test_basereloc.py b/tests/pe/directory/test_basereloc.py new file mode 100644 index 0000000..b608a06 --- /dev/null +++ b/tests/pe/directory/test_basereloc.py @@ -0,0 +1,19 @@ +from __future__ import annotations + +from dissect.executable.pe.c_pe import c_pe +from dissect.executable.pe.pe import PE +from tests._utils import absolute_path + + +def test_basereloc() -> None: + """Test the base relocations directory.""" + with absolute_path("_data/pe/32/PUNZIP.EXE").open("rb") as fh: + pe = PE(fh) + + assert pe.is_pe() + assert pe.machine.name == "R4000" + assert len(pe.base_relocations) == 5454 + assert list(pe.base_relocations) + + assert pe.base_relocations[0].rva == 0x102C + assert pe.base_relocations[0].type == c_pe.IMAGE_REL_BASED.MIPS_JMPADDR diff --git a/tests/pe/directory/test_bound_import.py b/tests/pe/directory/test_bound_import.py new file mode 100644 index 0000000..d60303e --- /dev/null +++ b/tests/pe/directory/test_bound_import.py @@ -0,0 +1,25 @@ +from __future__ import annotations + +import datetime + +from dissect.executable.pe.pe import PE +from tests._utils import absolute_path + + +def test_bound_import() -> None: + """Test the bound imports directory.""" + with absolute_path("_data/pe/32/NetDbgTLLoc.dll").open("rb") as fh: + pe = PE(fh) + + assert pe.is_pe() + assert pe.machine.name == "I386" + assert len(pe.bound_import) == 2 + assert list(pe.bound_import) + + assert pe.bound_import[0].name == "KERNEL32.dll" + assert len(pe.bound_import[0].forwarders) == 1 + assert pe.bound_import[0].forwarders[0].name == "NTDLL.DLL" + + assert pe.bound_import["MSVCR71.dll"].timestamp == datetime.datetime( + 2003, 2, 21, 12, 42, 20, tzinfo=datetime.timezone.utc + ) diff --git a/tests/pe/directory/test_com_descriptor.py b/tests/pe/directory/test_com_descriptor.py new file mode 100644 index 0000000..aa972a5 --- /dev/null +++ b/tests/pe/directory/test_com_descriptor.py @@ -0,0 +1,17 @@ +from __future__ import annotations + +from dissect.executable.pe.pe import PE +from tests._utils import absolute_path + + +def test_com_descriptor() -> None: + """Test the COM descriptor directory.""" + with absolute_path("_data/pe/32/Microsoft.Windows.SoftwareLogo.Binscope.resources.dll").open("rb") as fh: + pe = PE(fh) + + assert pe.is_pe() + assert pe.machine.name == "I386" + + assert pe.com_descriptor + assert len(pe.com_descriptor.metadata.streams) == 4 + assert [stream.name for stream in pe.com_descriptor.metadata.streams] == ["#~", "#Strings", "#US", "#GUID"] diff --git a/tests/pe/directory/test_debug.py b/tests/pe/directory/test_debug.py new file mode 100644 index 0000000..530b738 --- /dev/null +++ b/tests/pe/directory/test_debug.py @@ -0,0 +1,78 @@ +from __future__ import annotations + +from dissect.executable.pe.pe import PE +from tests._utils import absolute_path + + +def test_debug_codeview() -> None: + """Test the CodeView debug entry.""" + with absolute_path("_data/pe/32/NetDbgTLLoc.dll").open("rb") as fh: + pe = PE(fh) + + assert pe.is_pe() + assert pe.machine.name == "I386" + + assert pe.debug + assert len(pe.debug) == 2 + + assert pe.debug[0].type.name == "CODEVIEW" + assert str(pe.debug[0].signature) == "434b5c0d-1ee4-4bc8-bdf0-2e87ea897763" + assert pe.debug[0].age == 2 + assert pe.debug[0].pdb == "I:\\VS70Builds\\3077\\vsbuilt\\retail\\Bin\\i386\\opt\\natdbgtlloc.pdb" + + assert pe.pdb_path() == "I:\\VS70Builds\\3077\\vsbuilt\\retail\\Bin\\i386\\opt\\natdbgtlloc.pdb" + + +def test_debug_vc_feature() -> None: + """Test the VC feature debug entry.""" + with absolute_path("_data/pe/32/aborttest.exe").open("rb") as fh: + pe = PE(fh) + + assert pe.is_pe() + assert pe.machine.name == "I386" + + assert pe.debug + assert len(pe.debug) == 2 + + assert pe.debug[1].type.name == "VC_FEATURE" + assert pe.debug[1].pre_vc11 == 0 + assert pe.debug[1].ccpp == 23 + assert pe.debug[1].gs == 23 + assert pe.debug[1].sdl == 0 + assert pe.debug[1].guards == 0 + + +def test_debug_pogo() -> None: + """Test the POGO debug entry.""" + with absolute_path("_data/pe/32/Dummy.dll").open("rb") as fh: + pe = PE(fh) + + assert pe.is_pe() + assert pe.machine.name == "I386" + + assert pe.debug + assert len(pe.debug) == 2 + + assert pe.debug[0].type.name == "POGO" + assert len(pe.debug[0]) == 4 + assert list(pe.debug[0]) == [ + (4096, 56, ".rdata"), + (4152, 120, ".rdata$zzzdbg"), + (8192, 96, ".rsrc$01"), + (8288, 928, ".rsrc$02"), + ] + + +def test_debug_repro() -> None: + """Test the REPRO debug entry.""" + with absolute_path("_data/pe/32/Dummy.dll").open("rb") as fh: + pe = PE(fh) + + assert pe.is_pe() + assert pe.machine.name == "I386" + + assert pe.debug + assert len(pe.debug) == 2 + + assert pe.debug[1].type.name == "REPRO" + assert pe.debug[1].hash.hex() == "884f504ffad2de5c25d4bbddff0f8b1fbaa2c8341f2dbdaff5f181ce1300f2e4" diff --git a/tests/pe/directory/test_delay_import.py b/tests/pe/directory/test_delay_import.py new file mode 100644 index 0000000..5a37a1f --- /dev/null +++ b/tests/pe/directory/test_delay_import.py @@ -0,0 +1,29 @@ +from __future__ import annotations + +from dissect.executable.pe.pe import PE +from tests._utils import absolute_path + + +def test_delay_import() -> None: + """Test the delay imports directory.""" + with absolute_path("_data/pe/32/OLEACCHOOKS.DLL").open("rb") as fh: + pe = PE(fh) + + assert pe.is_pe() + assert pe.machine.name == "I386" + assert len(pe.delay_import) == 1 + assert list(pe.delay_import) + + assert pe.delay_import[0].name == "USER32.dll" + assert pe.delay_import["USER32.dll"] == pe.delay_import[0] + assert len(list(pe.delay_import[0])) == 2 + + assert pe.delay_import[0].functions[0].name == "RegisterWindowMessageW" + assert pe.delay_import[0].functions[0].ordinal == 755 + assert pe.delay_import[0].functions[0].address == 0x10001FBC + assert pe.delay_import[0].functions[1].name == "CallNextHookEx" + assert pe.delay_import[0].functions[1].ordinal == 31 + assert pe.delay_import[0].functions[1].address == 0x10001FA1 + + assert pe.delay_import[0]["RegisterWindowMessageW"] == pe.delay_import[0].functions[0] + assert pe.delay_import[0][755] == pe.delay_import[0].functions[0] diff --git a/tests/pe/directory/test_exception.py b/tests/pe/directory/test_exception.py new file mode 100644 index 0000000..1835aac --- /dev/null +++ b/tests/pe/directory/test_exception.py @@ -0,0 +1,18 @@ +from __future__ import annotations + +from dissect.executable.pe.pe import PE +from tests._utils import absolute_path + + +def test_exception() -> None: + """Test the exception directory.""" + with absolute_path("_data/pe/32/PUNZIP.EXE").open("rb") as fh: + pe = PE(fh) + + assert pe.is_pe() + assert pe.machine.name == "R4000" + assert len(pe.exceptions) == 286 + assert list(pe.exceptions) + + assert pe.exceptions[0].BeginAddress == 0x11010 + assert pe.exceptions[0].EndAddress == 0x11068 diff --git a/tests/pe/directory/test_export.py b/tests/pe/directory/test_export.py new file mode 100644 index 0000000..1912c6f --- /dev/null +++ b/tests/pe/directory/test_export.py @@ -0,0 +1,26 @@ +from __future__ import annotations + +from dissect.executable.pe.pe import PE +from tests._utils import absolute_path + + +def test_export() -> None: + """Test the export directory.""" + with absolute_path("_data/pe/32/NetDbgTLLoc.dll").open("rb") as fh: + pe = PE(fh) + + assert pe.is_pe() + assert pe.machine.name == "I386" + assert pe.exports + assert len(list(pe.exports)) == 2 + + assert pe.exports.name == "NatDbgTLLoc.dll" + assert pe.exports[1].ordinal == 1 + assert pe.exports[1].name == "OSDebug4VersionCheck" + assert pe.exports[1].address == 0x10DD + assert pe.exports[2].ordinal == 2 + assert pe.exports[2].name == "TLFunc" + assert pe.exports[2].address == 0x1590 + + assert pe.exports["OSDebug4VersionCheck"].ordinal == 1 + assert pe.exports["TLFunc"].ordinal == 2 diff --git a/tests/pe/directory/test_iat.py b/tests/pe/directory/test_iat.py new file mode 100644 index 0000000..771da74 --- /dev/null +++ b/tests/pe/directory/test_iat.py @@ -0,0 +1,40 @@ +from __future__ import annotations + +from dissect.executable.pe.pe import PE +from tests._utils import absolute_path + + +def test_iat() -> None: + """Test the IAT directory.""" + with absolute_path("_data/pe/32/NetDbgTLLoc.dll").open("rb") as fh: + pe = PE(fh) + + assert pe.is_pe() + assert pe.machine.name == "I386" + assert len(pe.iat) == 24 + assert list(pe.iat) == [ + 0x7C811476, + 0x7C80AA66, + 0x7C80AC28, + 0x7C801D77, + 0x7C809FA1, + 0x7C91188A, + 0x7C809794, + 0x7C80994E, + 0x7C809737, + 0x7C8092AC, + 0x7C80A417, + 0x7C859B5C, + 0x7C8017E5, + 0x0, + 0x7C360951, + 0x7C342151, + 0x7C341CBE, + 0x7C3416E9, + 0x7C38C940, + 0x7C34C45B, + 0x7C34240D, + 0x7C34C095, + 0x7C341D5F, + 0x0, + ] diff --git a/tests/pe/directory/test_import.py b/tests/pe/directory/test_import.py new file mode 100644 index 0000000..7270061 --- /dev/null +++ b/tests/pe/directory/test_import.py @@ -0,0 +1,25 @@ +from __future__ import annotations + +from dissect.executable.pe.pe import PE +from tests._utils import absolute_path + + +def test_import() -> None: + """Test the import directory.""" + with absolute_path("_data/pe/32/OLEACCHOOKS.DLL").open("rb") as fh: + pe = PE(fh) + + assert pe.is_pe() + assert pe.machine.name == "I386" + assert len(pe.imports) == 12 + assert list(pe.imports) + + assert pe.imports[0].name == "msvcrt.dll" + assert pe.imports["msvcrt.dll"] == pe.imports[0] + assert len(list(pe.imports[0])) == 7 + + assert pe.imports[0].functions[0].name == "_vsnwprintf" + assert pe.imports[0].functions[0].ordinal == 1004 + + assert pe.imports[0]["_vsnwprintf"] == pe.imports[0].functions[0] + assert pe.imports[0][1004] == pe.imports[0].functions[0] diff --git a/tests/pe/directory/test_load_config.py b/tests/pe/directory/test_load_config.py new file mode 100644 index 0000000..01fe8af --- /dev/null +++ b/tests/pe/directory/test_load_config.py @@ -0,0 +1,19 @@ +from __future__ import annotations + +from dissect.executable.pe.pe import PE +from tests._utils import absolute_path + + +def test_load_config() -> None: + """Test the load config directory.""" + with absolute_path("_data/pe/64/comres.dll").open("rb") as fh: + pe = PE(fh) + + assert pe.is_pe() + assert pe.machine.name == "ARM64" + assert pe.load_config + + assert pe.load_config.security_cookie == 0x180004000 + assert pe.load_config.guard_flags.name == "CF_INSTRUMENTED" + + assert pe.load_config.chpe.Version == 1 diff --git a/tests/pe/directory/test_resource.py b/tests/pe/directory/test_resource.py new file mode 100644 index 0000000..e1350c4 --- /dev/null +++ b/tests/pe/directory/test_resource.py @@ -0,0 +1,86 @@ +from __future__ import annotations + +import hashlib + +from dissect.executable.pe.c_pe import c_pe +from dissect.executable.pe.pe import PE +from tests._utils import absolute_path + + +def test_resource() -> None: + """Test the resource directory.""" + with absolute_path("_data/pe/64/comres.dll").open("rb") as fh: + pe = PE(fh) + + assert pe.is_pe() + assert pe.machine.name == "ARM64" + assert pe.resources + + # Test the raw tree first + assert list(pe.resources.tree.listdir().keys()) == ["MUI", 16] + assert list(pe.resources.tree.get("MUI").listdir().keys()) == [1] + assert list(pe.resources.tree.get("MUI").get(1).listdir().keys()) == [1033] + assert pe.resources.tree.get("MUI").get(1).get(1033).address == 0x7080 + assert pe.resources.tree.get("MUI").get(1).get(1033).size == 280 + assert ( + hashlib.sha1(pe.resources.tree.get("MUI").get(1).get(1033).data).hexdigest() + == "eeee31518d39d8234ec870d0c3a7eba0eebd728d" + ) + + # Test the higher level API + assert len(list(pe.resources)) == 2 + assert len(pe.resources["MUI"]) == 1 + assert pe.resources["MUI"][0].name == 1 + assert pe.resources["MUI"][0].languages() == ["en-US"] + assert hashlib.sha1(pe.resources["MUI"][0].data()).hexdigest() == "eeee31518d39d8234ec870d0c3a7eba0eebd728d" + + assert pe.resources.vs_version_info() == { + "VS_VERSION_INFO": { + "FileVersion": "2001.12.10941.16384", + "ProductVersion": "10.0.22621.1", + "FileOS": "NT_WINDOWS32", + "FileType": "DLL", + "StringFileInfo": { + "en-US_utf-16": { + "CompanyName": "Microsoft Corporation", + "FileDescription": "COM+ Resources", + "FileVersion": "2001.12.10941.16384 (WinBuild.160101.0800)", + "InternalName": "COMRES.DLL", + "LegalCopyright": "© Microsoft Corporation. All rights reserved.", + "OriginalFilename": "COMRES.DLL", + "ProductName": "Microsoft® Windows® Operating System", + "ProductVersion": "10.0.22621.1", + } + }, + "VarFileInfo": {"Translation": ["en-US_utf-16"]}, + } + } + + +def test_resource_accelerator_table() -> None: + """Test the accelerator resource parsing.""" + with absolute_path("_data/pe/32/PUNZIP.EXE").open("rb") as fh: + pe = PE(fh) + + assert pe.resources.accelerator_table() == [ + (c_pe.VK.A, 40009, c_pe.ACCEL_F.VIRTKEY | c_pe.ACCEL_F.NOINVERT | c_pe.ACCEL_F.CONTROL), + (c_pe.VK.E, 40004, c_pe.ACCEL_F.VIRTKEY | c_pe.ACCEL_F.NOINVERT | c_pe.ACCEL_F.CONTROL), + (c_pe.VK.O, 40001, c_pe.ACCEL_F.VIRTKEY | c_pe.ACCEL_F.NOINVERT | c_pe.ACCEL_F.CONTROL), + (c_pe.VK.T, 40006, c_pe.ACCEL_F.VIRTKEY | c_pe.ACCEL_F.NOINVERT | c_pe.ACCEL_F.CONTROL), + (c_pe.VK.RETURN, 40008, c_pe.ACCEL_F.VIRTKEY | c_pe.ACCEL_F.NOINVERT), + (c_pe.VK.RETURN, 40002, c_pe.ACCEL_F.VIRTKEY | c_pe.ACCEL_F.NOINVERT | c_pe.ACCEL_F.ALT), + ] + + +def test_resource_string_table() -> None: + """Test the string table resource parsing.""" + with absolute_path("_data/pe/32/TpmCertResources.dll").open("rb") as fh: + pe = PE(fh) + + assert pe.resources.string_table() == { + 7673: "https://ekop.intel.com/ekcertservice", + 9298: "http://127.0.0.1:27015/EkCertService", + 33224: "https://ekcert.spserv.microsoft.com/EKCertificate/GetEKCertificate/v1", + 58380: "http://ftpm.amd.com/pki/aia", + 59629: "https://ekcert.spserv.microsoft.com/EKCertificate/GetEKCertificate/v1", + } diff --git a/tests/pe/directory/test_security.py b/tests/pe/directory/test_security.py new file mode 100644 index 0000000..3e9ca61 --- /dev/null +++ b/tests/pe/directory/test_security.py @@ -0,0 +1,20 @@ +from __future__ import annotations + +import hashlib + +from dissect.executable.pe.pe import PE +from tests._utils import absolute_path + + +def test_security() -> None: + """Test the security directory.""" + with absolute_path("_data/pe/32/UWPEnum.dll").open("rb") as fh: + pe = PE(fh) + + assert pe.is_pe() + assert pe.machine.name == "I386" + assert pe.security + + assert pe.security[0].revision == 512 + assert pe.security[0].type.name == "PKCS_SIGNED_DATA" + assert hashlib.sha1(pe.security[0].data).hexdigest() == "933f765d09486cc41091e2bfd305be723e9e4b53" diff --git a/tests/pe/directory/test_tls.py b/tests/pe/directory/test_tls.py new file mode 100644 index 0000000..76c0f9a --- /dev/null +++ b/tests/pe/directory/test_tls.py @@ -0,0 +1,15 @@ +from __future__ import annotations + +from dissect.executable.pe.pe import PE +from tests._utils import absolute_path + + +def test_tls() -> None: + """Test the TLS directory.""" + with absolute_path("_data/pe/32/mingwm10.dll").open("rb") as fh: + pe = PE(fh) + + assert pe.is_pe() + assert pe.machine.name == "I386" + assert len(pe.tls) == 2 + assert list(pe.tls) == [0x6FBC1480, 0x6FBC1430] diff --git a/tests/pe/test_pe.py b/tests/pe/test_pe.py new file mode 100644 index 0000000..6d79979 --- /dev/null +++ b/tests/pe/test_pe.py @@ -0,0 +1,56 @@ +# Most test data is from: +# - https://github.com/cubiclesoft/windows-pe-artifact-library + +from __future__ import annotations + +import datetime +from io import BytesIO + +import pytest + +from dissect.executable.exception import InvalidSignatureError +from dissect.executable.pe.pe import PE +from tests._utils import absolute_path + + +def test_pe_invalid_signature() -> None: + with pytest.raises(InvalidSignatureError): + PE(BytesIO(b"MZ" + b"\x00" * 400)) + + +def test_pe_basic() -> None: + """Test basic properties of a PE file.""" + with absolute_path("_data/pe/64/test.exe").open("rb") as fh: + pe = PE(fh) + + assert pe.is_pe() + assert not pe.is_os2() + assert pe.is_64bit() + assert not pe.is_reproducible() + + assert pe.timestamp == datetime.datetime(2024, 3, 8, 8, 6, 29, tzinfo=datetime.timezone.utc) + + +def test_pe_sections() -> None: + """Test that the PE file has the expected sections.""" + with absolute_path("_data/pe/64/test.exe").open("rb") as fh: + pe = PE(fh) + + assert [section.name for section in pe.sections] == [ + ".dissect", + ".text", + ".rdata", + ".idata", + ".rsrc", + ".reloc", + ".tls", + ] + + +def test_pe_os2() -> None: + """Test an OS/2 executable.""" + with absolute_path("_data/pe/16/DPMIRES.EXE").open("rb") as fh: + pe = PE(fh) + + assert pe.is_os2() + assert not pe.is_pe() From 2007ea620cd4562e5bdbf8e645b4bce00a033a9b Mon Sep 17 00:00:00 2001 From: Erik Schamper <1254028+Schamper@users.noreply.github.com> Date: Thu, 17 Jul 2025 17:49:46 +0200 Subject: [PATCH 02/10] Update exception.py Co-authored-by: Miauwkeru --- dissect/executable/pe/directory/exception.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dissect/executable/pe/directory/exception.py b/dissect/executable/pe/directory/exception.py index 2ab3b4d..1add846 100644 --- a/dissect/executable/pe/directory/exception.py +++ b/dissect/executable/pe/directory/exception.py @@ -60,7 +60,7 @@ def entries( """List of exception entries.""" self.pe.vfh.seek(self.address) - machine = self.pe.file_header.Machine + machine = self.pe.machine if machine in (c_pe.IMAGE_FILE_MACHINE.ARM, c_pe.IMAGE_FILE_MACHINE.THUMB, c_pe.IMAGE_FILE_MACHINE.ARMNT): ctype = c_pe.IMAGE_ARM_RUNTIME_FUNCTION_ENTRY elif machine == c_pe.IMAGE_FILE_MACHINE.ARM64: From 55097634437b4fad661c5248e5dfb40370613e90 Mon Sep 17 00:00:00 2001 From: Schamper <1254028+Schamper@users.noreply.github.com> Date: Fri, 18 Jul 2025 10:59:06 +0200 Subject: [PATCH 03/10] Remove ELF changes --- tests/elf/test_section.py | 6 +----- tests/elf/test_segment_table.py | 4 +--- 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/tests/elf/test_section.py b/tests/elf/test_section.py index 1282267..cd0becf 100644 --- a/tests/elf/test_section.py +++ b/tests/elf/test_section.py @@ -25,11 +25,7 @@ def section_table(entries: int) -> SectionTable: def mock_section_table(section_data: bytes) -> Mock: - shdr = c_elf_64.Shdr( - sh_offset=len(c_elf_64.Shdr), - sh_size=len(section_data), - sh_entsize=len(section_data), - ) + shdr = c_elf_64.Shdr(sh_offset=len(c_elf_64.Shdr), sh_size=len(section_data), sh_entsize=len(section_data)) mocked_table = Mock() mocked_table.fh = BytesIO(shdr.dumps() + section_data) mocked_table.offset = 0 diff --git a/tests/elf/test_segment_table.py b/tests/elf/test_segment_table.py index 8e8ac0b..e666c80 100644 --- a/tests/elf/test_segment_table.py +++ b/tests/elf/test_segment_table.py @@ -34,9 +34,7 @@ def create_segment_table(amount: int, random_data: bytes) -> SegmentTable: data_size = len(random_data) segments_data = [] for idx in range(amount): - data = c_elf_64.Phdr( - p_offset=len(c_elf_64.Phdr) * amount + idx * data_size, p_filesz=data_size - ).dumps() + data = c_elf_64.Phdr(p_offset=len(c_elf_64.Phdr) * amount + idx * data_size, p_filesz=data_size).dumps() segments_data.append(data) segments_data.append(random_data * amount) From 34b753eceaba1e072321f96436b2e962c9d22260 Mon Sep 17 00:00:00 2001 From: Schamper <1254028+Schamper@users.noreply.github.com> Date: Fri, 18 Jul 2025 11:00:14 +0200 Subject: [PATCH 04/10] Fix c_pe bits --- dissect/executable/pe/c_pe.py | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100755 => 100644 dissect/executable/pe/c_pe.py diff --git a/dissect/executable/pe/c_pe.py b/dissect/executable/pe/c_pe.py old mode 100755 new mode 100644 From ace4e57ddcd22b80b572d8a939208188ee0a90d4 Mon Sep 17 00:00:00 2001 From: Erik Schamper <1254028+Schamper@users.noreply.github.com> Date: Tue, 22 Jul 2025 09:32:07 +0200 Subject: [PATCH 05/10] Update pe.py --- dissect/executable/pe/pe.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dissect/executable/pe/pe.py b/dissect/executable/pe/pe.py index d0634af..1defdef 100644 --- a/dissect/executable/pe/pe.py +++ b/dissect/executable/pe/pe.py @@ -135,7 +135,7 @@ def is_64bit(self) -> bool: def is_reproducible(self) -> bool: """Return if the PE file is reproducible (i.e. has a REPRO debug entry).""" - return self.debug and any(entry.type == c_pe.IMAGE_DEBUG_TYPE.REPRO for entry in self.debug.entries) + return self.debug is not None and any(entry.type == c_pe.IMAGE_DEBUG_TYPE.REPRO for entry in self.debug.entries) def pdb_path(self) -> str | None: """Return the PDB path, if available.""" From e14deece5426c9cfd4e189077b5e9deef3a25aa5 Mon Sep 17 00:00:00 2001 From: Erik Schamper <1254028+Schamper@users.noreply.github.com> Date: Tue, 22 Jul 2025 09:32:18 +0200 Subject: [PATCH 06/10] Update pe.py --- dissect/executable/pe/pe.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dissect/executable/pe/pe.py b/dissect/executable/pe/pe.py index 1defdef..469a418 100644 --- a/dissect/executable/pe/pe.py +++ b/dissect/executable/pe/pe.py @@ -131,7 +131,7 @@ def is_os2(self) -> bool: def is_64bit(self) -> bool: """Return if the PE file is 64-bit (PE32+).""" - return self.optional_header and self.optional_header.Magic == c_pe.IMAGE_NT_OPTIONAL_HDR64_MAGIC + return self.optional_header is not None and self.optional_header.Magic == c_pe.IMAGE_NT_OPTIONAL_HDR64_MAGIC def is_reproducible(self) -> bool: """Return if the PE file is reproducible (i.e. has a REPRO debug entry).""" From c1ab55b492e1be2ec9bb278294ec4a2e51732f1f Mon Sep 17 00:00:00 2001 From: Schamper <1254028+Schamper@users.noreply.github.com> Date: Tue, 22 Jul 2025 11:00:01 +0200 Subject: [PATCH 07/10] Add MIPS exception --- dissect/executable/pe/directory/exception.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/dissect/executable/pe/directory/exception.py b/dissect/executable/pe/directory/exception.py index 1add846..6b28b62 100644 --- a/dissect/executable/pe/directory/exception.py +++ b/dissect/executable/pe/directory/exception.py @@ -31,6 +31,7 @@ def __iter__( | c_pe.IMAGE_ALPHA_RUNTIME_FUNCTION_ENTRY | c_pe.IMAGE_ALPHA64_RUNTIME_FUNCTION_ENTRY | c_pe.IMAGE_CE_RUNTIME_FUNCTION_ENTRY + | c_pe.IMAGE_MIPS_RUNTIME_FUNCTION_ENTRY ]: return iter(self.entries) @@ -43,6 +44,7 @@ def __getitem__( | c_pe.IMAGE_ALPHA_RUNTIME_FUNCTION_ENTRY | c_pe.IMAGE_ALPHA64_RUNTIME_FUNCTION_ENTRY | c_pe.IMAGE_CE_RUNTIME_FUNCTION_ENTRY + | c_pe.IMAGE_MIPS_RUNTIME_FUNCTION_ENTRY ): return self.entries[idx] @@ -56,6 +58,7 @@ def entries( | c_pe.IMAGE_ALPHA_RUNTIME_FUNCTION_ENTRY | c_pe.IMAGE_ALPHA64_RUNTIME_FUNCTION_ENTRY | c_pe.IMAGE_CE_RUNTIME_FUNCTION_ENTRY + | c_pe.IMAGE_MIPS_RUNTIME_FUNCTION_ENTRY ]: """List of exception entries.""" self.pe.vfh.seek(self.address) @@ -69,6 +72,16 @@ def entries( ctype = c_pe.IMAGE_ALPHA_RUNTIME_FUNCTION_ENTRY elif machine == c_pe.IMAGE_FILE_MACHINE.ALPHA64: ctype = c_pe.IMAGE_ALPHA64_RUNTIME_FUNCTION_ENTRY + elif machine in ( + c_pe.IMAGE_FILE_MACHINE.R3000, + c_pe.IMAGE_FILE_MACHINE.R4000, + c_pe.IMAGE_FILE_MACHINE.R10000, + c_pe.IMAGE_FILE_MACHINE.WCEMIPSV2, + c_pe.IMAGE_FILE_MACHINE.MIPS16, + c_pe.IMAGE_FILE_MACHINE.MIPSFPU, + c_pe.IMAGE_FILE_MACHINE.MIPSFPU16, + ): + ctype = c_pe.IMAGE_MIPS_RUNTIME_FUNCTION_ENTRY else: # May be wrong for esoteric architectures, but this is the default ctype = c_pe.IMAGE_RUNTIME_FUNCTION_ENTRY From e0895ef7a401fd9f01b4cb380b57ba3e22b70836 Mon Sep 17 00:00:00 2001 From: Schamper <1254028+Schamper@users.noreply.github.com> Date: Thu, 24 Jul 2025 17:17:17 +0200 Subject: [PATCH 08/10] Process review --- dissect/executable/__init__.py | 4 +++- dissect/executable/pe/c_pe.py | 10 +++++++--- dissect/executable/pe/c_pe.pyi | 10 +++++++--- dissect/executable/pe/directory/debug.py | 4 ++-- dissect/executable/pe/directory/load_config.py | 4 +++- tests/pe/directory/test_exception.py | 2 +- 6 files changed, 23 insertions(+), 11 deletions(-) diff --git a/dissect/executable/__init__.py b/dissect/executable/__init__.py index 43d2a88..f9c465a 100644 --- a/dissect/executable/__init__.py +++ b/dissect/executable/__init__.py @@ -1,5 +1,7 @@ -from dissect.executable.elf import ELF +from dissect.executable.elf.elf import ELF +from dissect.executable.pe.pe import PE __all__ = [ "ELF", + "PE", ] diff --git a/dissect/executable/pe/c_pe.py b/dissect/executable/pe/c_pe.py index 00d1d07..70d44ab 100644 --- a/dissect/executable/pe/c_pe.py +++ b/dissect/executable/pe/c_pe.py @@ -235,7 +235,11 @@ // DllCharacteristics Entries -enum IMAGE_DLLCHARACTERISTICS : USHORT { +flag IMAGE_DLLCHARACTERISTICS : USHORT { + PROCESS_INIT = 0x0001, // Reserved. (IMAGE_LIBRARY_PROCESS_INIT) + PROCESS_TERM = 0x0002, // Reserved. (IMAGE_LIBRARY_PROCESS_TERM) + THREAD_INIT = 0x0004, // Reserved. (IMAGE_LIBRARY_THREAD_INIT) + THREAD_TERM = 0x0008, // Reserved. (IMAGE_LIBRARY_THREAD_TERM) HIGH_ENTROPY_VA = 0x0020, // Image can handle a high entropy 64-bit virtual address space. DYNAMIC_BASE = 0x0040, // DLL can move. FORCE_INTEGRITY = 0x0080, // Code Integrity Image @@ -1889,7 +1893,7 @@ PERFMAP = 21, }; -enum IMAGE_DLLCHARACTERISTICS_EX { +flag IMAGE_DLLCHARACTERISTICS_EX { CET_COMPAT = 0x01, CET_COMPAT_STRICT_MODE = 0x02, CET_SET_CONTEXT_IP_VALIDATION_RELAXED_MODE = 0x04, @@ -2139,7 +2143,7 @@ // // COM+ Header entry point flags. -enum COMIMAGE_FLAGS : ULONG { +flag COMIMAGE_FLAGS : ULONG { ILONLY = 0x00000001, 32BITREQUIRED = 0x00000002, IL_LIBRARY = 0x00000004, diff --git a/dissect/executable/pe/c_pe.pyi b/dissect/executable/pe/c_pe.pyi index a1e7fa6..c99b355 100644 --- a/dissect/executable/pe/c_pe.pyi +++ b/dissect/executable/pe/c_pe.pyi @@ -441,7 +441,11 @@ class _c_pe(__cs__.cstruct): WINDOWS_BOOT_APPLICATION = ... XBOX_CODE_CATALOG = ... - class IMAGE_DLLCHARACTERISTICS(__cs__.Enum): + class IMAGE_DLLCHARACTERISTICS(__cs__.Flag): + PROCESS_INIT = ... + PROCESS_TERM = ... + THREAD_INIT = ... + THREAD_TERM = ... HIGH_ENTROPY_VA = ... DYNAMIC_BASE = ... FORCE_INTEGRITY = ... @@ -2563,7 +2567,7 @@ class _c_pe(__cs__.cstruct): EX_DLLCHARACTERISTICS = ... PERFMAP = ... - class IMAGE_DLLCHARACTERISTICS_EX(__cs__.Enum): + class IMAGE_DLLCHARACTERISTICS_EX(__cs__.Flag): CET_COMPAT = ... CET_COMPAT_STRICT_MODE = ... CET_SET_CONTEXT_IP_VALIDATION_RELAXED_MODE = ... @@ -2908,7 +2912,7 @@ class _c_pe(__cs__.cstruct): @overload def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... - class COMIMAGE_FLAGS(__cs__.Enum): + class COMIMAGE_FLAGS(__cs__.Flag): ILONLY = ... "32BITREQUIRED = ..." IL_LIBRARY = ... diff --git a/dissect/executable/pe/directory/debug.py b/dissect/executable/pe/directory/debug.py index 76d0aaf..415c3f4 100644 --- a/dissect/executable/pe/directory/debug.py +++ b/dissect/executable/pe/directory/debug.py @@ -134,9 +134,9 @@ def age(self) -> int | None: return getattr(self.info, "Age", None) @property - def pdb(self) -> str | None: + def pdb(self) -> str: """The PDB filename of the CodeView debug entry.""" - return getattr(self.info, "PdbFileName", b"").decode() or None + return self.info.PdbFileName.decode() class VcFeatureDebugEntry(DebugEntry): diff --git a/dissect/executable/pe/directory/load_config.py b/dissect/executable/pe/directory/load_config.py index 2e2c8d1..861d3ac 100644 --- a/dissect/executable/pe/directory/load_config.py +++ b/dissect/executable/pe/directory/load_config.py @@ -40,7 +40,9 @@ def guard_flags(self) -> c_pe.IMAGE_GUARD: return self.config.GuardFlags & ~c_pe.IMAGE_GUARD_CF_FUNCTION_TABLE_SIZE_MASK @property - def chpe(self) -> c_pe.IMAGE_ARM64EC_METADATA | c_pe.IMAGE_CHPE_METADATA_X86 | None: + def chpe( + self, + ) -> c_pe.IMAGE_ARM64EC_METADATA | c_pe.IMAGE_ARM64EC_METADATA_V2 | c_pe.IMAGE_CHPE_METADATA_X86 | None: """The CHPE (Compiled Hybrid Portable Executable) metadata.""" if not self.config.CHPEMetadataPointer: return None diff --git a/tests/pe/directory/test_exception.py b/tests/pe/directory/test_exception.py index 1835aac..0e64720 100644 --- a/tests/pe/directory/test_exception.py +++ b/tests/pe/directory/test_exception.py @@ -11,7 +11,7 @@ def test_exception() -> None: assert pe.is_pe() assert pe.machine.name == "R4000" - assert len(pe.exceptions) == 286 + assert len(pe.exceptions) == 172 assert list(pe.exceptions) assert pe.exceptions[0].BeginAddress == 0x11010 From 2d7c6456d5e3b3bf406a65f968d8cceb541e945b Mon Sep 17 00:00:00 2001 From: Schamper <1254028+Schamper@users.noreply.github.com> Date: Wed, 30 Jul 2025 13:55:32 +0200 Subject: [PATCH 09/10] Process review comments --- dissect/executable/pe/directory/debug.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/dissect/executable/pe/directory/debug.py b/dissect/executable/pe/directory/debug.py index 415c3f4..da172a3 100644 --- a/dissect/executable/pe/directory/debug.py +++ b/dissect/executable/pe/directory/debug.py @@ -100,18 +100,18 @@ def __repr__(self) -> str: return f"" @cached_property - def info(self) -> c_pe.CV_INFO_PDB20 | c_pe.CV_INFO_PDB70: + def info(self) -> c_pe.CV_INFO_PDB20 | c_pe.CV_INFO_PDB70 | c_pe.CV_INFO_MTOC: """The CodeView debug information.""" with self.open() as fh: cv_signature = c_pe.ULONG(fh) fh.seek(0) - if cv_signature == c_pe.CVINFO_PDB70_CVSIGNATURE: - return c_pe.CV_INFO_PDB70(fh) - if cv_signature == c_pe.CVINFO_PDB20_CVSIGNATURE: return c_pe.CV_INFO_PDB20(fh) + if cv_signature == c_pe.CVINFO_PDB70_CVSIGNATURE: + return c_pe.CV_INFO_PDB70(fh) + if cv_signature == c_pe.CVINFO_MTOC_CVSIGNATURE: return c_pe.CV_INFO_MTOC(fh) @@ -236,7 +236,7 @@ def hash(self) -> bytes: return fh.read(hash_size) -_DEBUG_TYPE_MAP = { +_DEBUG_TYPE_MAP: dict[c_pe.IMAGE_DEBUG_TYPE, type[DebugEntry]] = { c_pe.IMAGE_DEBUG_TYPE.CODEVIEW: CodeViewDebugEntry, c_pe.IMAGE_DEBUG_TYPE.VC_FEATURE: VcFeatureDebugEntry, c_pe.IMAGE_DEBUG_TYPE.POGO: PogoDebugEntry, From b5e33d54a4a21f427fb313b0981356f2ba9e19b3 Mon Sep 17 00:00:00 2001 From: Schamper <1254028+Schamper@users.noreply.github.com> Date: Wed, 30 Jul 2025 13:55:42 +0200 Subject: [PATCH 10/10] Add pointer types --- dissect/executable/pe/c_pe.py | 185 ++++++++++++++++----------------- dissect/executable/pe/c_pe.pyi | 111 ++++++++++++++++++++ pyproject.toml | 4 +- 3 files changed, 205 insertions(+), 95 deletions(-) diff --git a/dissect/executable/pe/c_pe.py b/dissect/executable/pe/c_pe.py index 70d44ab..777a500 100644 --- a/dissect/executable/pe/c_pe.py +++ b/dissect/executable/pe/c_pe.py @@ -38,7 +38,7 @@ USHORT e_oeminfo; // OEM information; e_oemid specific USHORT e_res2[10]; // Reserved words LONG e_lfanew; // File address of new exe header -} IMAGE_DOS_HEADER; +} IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER; typedef struct _IMAGE_OS2_HEADER { // OS/2 .EXE header USHORT ne_magic; // Magic number @@ -71,7 +71,7 @@ USHORT ne_psegrefbytes; // offset to segment ref. bytes USHORT ne_swaparea; // Minimum code swap area size USHORT ne_expver; // Expected Windows version number -} IMAGE_OS2_HEADER; +} IMAGE_OS2_HEADER, *PIMAGE_OS2_HEADER; typedef struct _IMAGE_VXD_HEADER { // Windows VXD header USHORT e32_magic; // Magic number @@ -125,7 +125,7 @@ ULONG e32_winreslen; USHORT e32_devid; // Device ID for VxD USHORT e32_ddkver; // DDK version for VxD -} IMAGE_VXD_HEADER; +} IMAGE_VXD_HEADER, *PIMAGE_VXD_HEADER; // // File header format. @@ -196,7 +196,7 @@ ULONG NumberOfSymbols; USHORT SizeOfOptionalHeader; IMAGE_FILE Characteristics; -} IMAGE_FILE_HEADER; +} IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER; // // Directory format. @@ -205,7 +205,7 @@ typedef struct _IMAGE_DATA_DIRECTORY { ULONG VirtualAddress; ULONG Size; -} IMAGE_DATA_DIRECTORY; +} IMAGE_DATA_DIRECTORY, *PIMAGE_DATA_DIRECTORY; #define IMAGE_NUMBEROF_DIRECTORY_ENTRIES 16 @@ -294,7 +294,7 @@ ULONG LoaderFlags; ULONG NumberOfRvaAndSizes; IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES]; -} IMAGE_OPTIONAL_HEADER32; +} IMAGE_OPTIONAL_HEADER32, *PIMAGE_OPTIONAL_HEADER32; typedef struct _IMAGE_OPTIONAL_HEADER64 { USHORT Magic; @@ -327,7 +327,7 @@ ULONG LoaderFlags; ULONG NumberOfRvaAndSizes; IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES]; -} IMAGE_OPTIONAL_HEADER64; +} IMAGE_OPTIONAL_HEADER64, *PIMAGE_OPTIONAL_HEADER64; #define IMAGE_NT_OPTIONAL_HDR32_MAGIC 0x10b #define IMAGE_NT_OPTIONAL_HDR64_MAGIC 0x20b @@ -337,13 +337,13 @@ ULONG Signature; IMAGE_FILE_HEADER FileHeader; IMAGE_OPTIONAL_HEADER64 OptionalHeader; -} IMAGE_NT_HEADERS64; +} IMAGE_NT_HEADERS64, *PIMAGE_NT_HEADERS64; typedef struct _IMAGE_NT_HEADERS { ULONG Signature; IMAGE_FILE_HEADER FileHeader; IMAGE_OPTIONAL_HEADER32 OptionalHeader; -} IMAGE_NT_HEADERS32; +} IMAGE_NT_HEADERS32, *PIMAGE_NT_HEADERS32; // Directory Entries @@ -440,14 +440,13 @@ USHORT NumberOfRelocations; USHORT NumberOfLinenumbers; IMAGE_SCN Characteristics; -} IMAGE_SECTION_HEADER; +} IMAGE_SECTION_HEADER, *PIMAGE_SECTION_HEADER; // // Symbol format. // - - +/* TODO */ // // Based relocation format. @@ -487,7 +486,7 @@ ULONG VirtualAddress; ULONG SizeOfBlock; // USHORT TypeOffset[1]; -} IMAGE_BASE_RELOCATION; +} IMAGE_BASE_RELOCATION, *PIMAGE_BASE_RELOCATION; // // Archive format. @@ -508,7 +507,7 @@ CHAR Mode[8]; // File member mode - octal. CHAR Size[10]; // File member size - decimal. CHAR EndHeader[2]; // String to end header. -} IMAGE_ARCHIVE_MEMBER_HEADER; +} IMAGE_ARCHIVE_MEMBER_HEADER, *PIMAGE_ARCHIVE_MEMBER_HEADER; // // DLL support. @@ -530,7 +529,7 @@ ULONG AddressOfFunctions; // RVA from base of image ULONG AddressOfNames; // RVA from base of image ULONG AddressOfNameOrdinals; // RVA from base of image -} IMAGE_EXPORT_DIRECTORY; +} IMAGE_EXPORT_DIRECTORY, *PIMAGE_EXPORT_DIRECTORY; // // Import Format @@ -539,7 +538,7 @@ typedef struct _IMAGE_IMPORT_BY_NAME { USHORT Hint; CHAR Name[]; -} IMAGE_IMPORT_BY_NAME; +} IMAGE_IMPORT_BY_NAME, *PIMAGE_IMPORT_BY_NAME; typedef struct _IMAGE_THUNK_DATA64 { union { @@ -548,7 +547,7 @@ ULONGLONG Ordinal; ULONGLONG AddressOfData; // PIMAGE_IMPORT_BY_NAME } u1; -} IMAGE_THUNK_DATA64; +} IMAGE_THUNK_DATA64, *PIMAGE_THUNK_DATA64; typedef struct _IMAGE_THUNK_DATA32 { union { @@ -557,7 +556,7 @@ ULONG Ordinal; ULONG AddressOfData; // PIMAGE_IMPORT_BY_NAME } u1; -} IMAGE_THUNK_DATA32; +} IMAGE_THUNK_DATA32, *PIMAGE_THUNK_DATA32; #define IMAGE_ORDINAL_FLAG64 0x8000000000000000 #define IMAGE_ORDINAL_FLAG32 0x80000000 @@ -575,7 +574,7 @@ ULONG ForwarderChain; // -1 if no forwarders ULONG Name; ULONG FirstThunk; // RVA to IAT (if bound this IAT has actual addresses) -} IMAGE_IMPORT_DESCRIPTOR; +} IMAGE_IMPORT_DESCRIPTOR, *PIMAGE_IMPORT_DESCRIPTOR; // // Thread Local Storage @@ -595,7 +594,7 @@ ULONG Reserved1 : 8; }; }; -} IMAGE_TLS_DIRECTORY64; +} IMAGE_TLS_DIRECTORY64, *PIMAGE_TLS_DIRECTORY64; typedef struct _IMAGE_TLS_DIRECTORY32 { ULONG StartAddressOfRawData; @@ -611,7 +610,7 @@ ULONG Reserved1 : 8; }; }; -} IMAGE_TLS_DIRECTORY32; +} IMAGE_TLS_DIRECTORY32, *PIMAGE_TLS_DIRECTORY32; // // New format import descriptors pointed to by DataDirectory[ IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT ] @@ -622,13 +621,13 @@ USHORT OffsetModuleName; USHORT NumberOfModuleForwarderRefs; // Array of zero or more IMAGE_BOUND_FORWARDER_REF follows -} IMAGE_BOUND_IMPORT_DESCRIPTOR; +} IMAGE_BOUND_IMPORT_DESCRIPTOR, *PIMAGE_BOUND_IMPORT_DESCRIPTOR; typedef struct _IMAGE_BOUND_FORWARDER_REF { ULONG TimeDateStamp; USHORT OffsetModuleName; USHORT Reserved; -} IMAGE_BOUND_FORWARDER_REF; +} IMAGE_BOUND_FORWARDER_REF, *PIMAGE_BOUND_FORWARDER_REF; typedef struct _IMAGE_DELAYLOAD_DESCRIPTOR { union { @@ -647,7 +646,7 @@ ULONG UnloadInformationTableRVA; // RVA to an optional unload info table ULONG TimeDateStamp; // 0 if not bound, // Otherwise, date/time of the target DLL -} IMAGE_DELAYLOAD_DESCRIPTOR; +} IMAGE_DELAYLOAD_DESCRIPTOR, *PIMAGE_DELAYLOAD_DESCRIPTOR; // // Resource Format. @@ -699,7 +698,7 @@ USHORT NumberOfNamedEntries; USHORT NumberOfIdEntries; /* IMAGE_RESOURCE_DIRECTORY_ENTRY DirectoryEntries[]; */ -} IMAGE_RESOURCE_DIRECTORY; +} IMAGE_RESOURCE_DIRECTORY, *PIMAGE_RESOURCE_DIRECTORY; // // Each directory contains the 32-bit Name of the entry and an offset, @@ -732,7 +731,7 @@ ULONG DataIsDirectory:1; }; }; -} IMAGE_RESOURCE_DIRECTORY_ENTRY; +} IMAGE_RESOURCE_DIRECTORY_ENTRY, *PIMAGE_RESOURCE_DIRECTORY_ENTRY; // // For resource directory entries that have actual string names, the Name @@ -746,12 +745,12 @@ typedef struct _IMAGE_RESOURCE_DIRECTORY_STRING { USHORT Length; CHAR NameString[Length]; -} IMAGE_RESOURCE_DIRECTORY_STRING; +} IMAGE_RESOURCE_DIRECTORY_STRING, *PIMAGE_RESOURCE_DIRECTORY_STRING; typedef struct _IMAGE_RESOURCE_DIR_STRING_U { USHORT Length; WCHAR NameString[Length]; -} IMAGE_RESOURCE_DIR_STRING_U; +} IMAGE_RESOURCE_DIR_STRING_U, *PIMAGE_RESOURCE_DIR_STRING_U; // // Each resource data entry describes a leaf node in the resource directory @@ -767,7 +766,7 @@ ULONG Size; ULONG CodePage; ULONG Reserved; -} IMAGE_RESOURCE_DATA_ENTRY; +} IMAGE_RESOURCE_DATA_ENTRY, *PIMAGE_RESOURCE_DATA_ENTRY; typedef struct _VS_FIXEDFILEINFO { DWORD dwSignature; @@ -783,7 +782,7 @@ DWORD dwFileSubtype; DWORD dwFileDateMS; DWORD dwFileDateLS; -} VS_FIXEDFILEINFO; +} VS_FIXEDFILEINFO, *PVS_FIXEDFILEINFO; flag VS_FF { DEBUG = 0x00000001, // The file contains debugging information or is compiled with debugging features enabled. @@ -1190,7 +1189,7 @@ USHORT Catalog; // 0xFFFF means not available ULONG CatalogOffset; ULONG Reserved; // Additional bitmask to be defined later -} IMAGE_LOAD_CONFIG_CODE_INTEGRITY; +} IMAGE_LOAD_CONFIG_CODE_INTEGRITY, *PIMAGE_LOAD_CONFIG_CODE_INTEGRITY; // // Dynamic value relocation table in loadconfig @@ -1200,7 +1199,7 @@ ULONG Version; ULONG Size; // IMAGE_DYNAMIC_RELOCATION DynamicRelocations[0]; -} IMAGE_DYNAMIC_RELOCATION_TABLE; +} IMAGE_DYNAMIC_RELOCATION_TABLE, *PIMAGE_DYNAMIC_RELOCATION_TABLE; // // Dynamic value relocation entries following IMAGE_DYNAMIC_RELOCATION_TABLE @@ -1210,13 +1209,13 @@ ULONG Symbol; ULONG BaseRelocSize; // IMAGE_BASE_RELOCATION BaseRelocations[0]; -} IMAGE_DYNAMIC_RELOCATION32; +} IMAGE_DYNAMIC_RELOCATION32, *PIMAGE_DYNAMIC_RELOCATION32; typedef struct _IMAGE_DYNAMIC_RELOCATION64 { ULONGLONG Symbol; ULONG BaseRelocSize; // IMAGE_BASE_RELOCATION BaseRelocations[0]; -} IMAGE_DYNAMIC_RELOCATION64; +} IMAGE_DYNAMIC_RELOCATION64, *PIMAGE_DYNAMIC_RELOCATION64; typedef struct _IMAGE_DYNAMIC_RELOCATION32_V2 { ULONG HeaderSize; @@ -1226,7 +1225,7 @@ ULONG Flags; // ... variable length header fields // UCHAR FixupInfo[FixupInfoSize]; -} IMAGE_DYNAMIC_RELOCATION32_V2; +} IMAGE_DYNAMIC_RELOCATION32_V2, *PIMAGE_DYNAMIC_RELOCATION32_V2; typedef struct _IMAGE_DYNAMIC_RELOCATION64_V2 { ULONG HeaderSize; @@ -1236,7 +1235,7 @@ ULONG Flags; // ... variable length header fields // UCHAR FixupInfo[FixupInfoSize] -} IMAGE_DYNAMIC_RELOCATION64_V2; +} IMAGE_DYNAMIC_RELOCATION64_V2, *PIMAGE_DYNAMIC_RELOCATION64_V2; // // Defined symbolic dynamic relocation entries. @@ -1256,7 +1255,7 @@ typedef struct _IMAGE_PROLOGUE_DYNAMIC_RELOCATION_HEADER { UCHAR PrologueByteCount; // UCHAR PrologueBytes[PrologueByteCount]; -} IMAGE_PROLOGUE_DYNAMIC_RELOCATION_HEADER; +} IMAGE_PROLOGUE_DYNAMIC_RELOCATION_HEADER, *PIMAGE_PROLOGUE_DYNAMIC_RELOCATION_HEADER; typedef struct _IMAGE_EPILOGUE_DYNAMIC_RELOCATION_HEADER { ULONG EpilogueCount; @@ -1265,13 +1264,13 @@ USHORT BranchDescriptorCount; // UCHAR BranchDescriptors[...]; // UCHAR BranchDescriptorBitMap[...]; -} IMAGE_EPILOGUE_DYNAMIC_RELOCATION_HEADER; +} IMAGE_EPILOGUE_DYNAMIC_RELOCATION_HEADER, *PIMAGE_EPILOGUE_DYNAMIC_RELOCATION_HEADER; typedef struct _IMAGE_IMPORT_CONTROL_TRANSFER_DYNAMIC_RELOCATION { ULONG PageRelativeOffset : 12; ULONG IndirectCall : 1; ULONG IATIndex : 19; -} IMAGE_IMPORT_CONTROL_TRANSFER_DYNAMIC_RELOCATION; +} IMAGE_IMPORT_CONTROL_TRANSFER_DYNAMIC_RELOCATION, *PIMAGE_IMPORT_CONTROL_TRANSFER_DYNAMIC_RELOCATION; // // On ARM64, an optimized imported function uses the following data structure @@ -1285,7 +1284,7 @@ ULONG ImportType : 1; // 0 if this refers to a static import, 1 for delayload import ULONG IATIndex : 15; // IAT index of the corresponding import. // 0x7FFF is a special value indicating no index. -} IMAGE_IMPORT_CONTROL_TRANSFER_ARM64_RELOCATION; +} IMAGE_IMPORT_CONTROL_TRANSFER_ARM64_RELOCATION, *PIMAGE_IMPORT_CONTROL_TRANSFER_ARM64_RELOCATION; typedef struct _IMAGE_INDIR_CONTROL_TRANSFER_DYNAMIC_RELOCATION { USHORT PageRelativeOffset : 12; @@ -1293,18 +1292,18 @@ USHORT RexWPrefix : 1; USHORT CfgCheck : 1; USHORT Reserved : 1; -} IMAGE_INDIR_CONTROL_TRANSFER_DYNAMIC_RELOCATION; +} IMAGE_INDIR_CONTROL_TRANSFER_DYNAMIC_RELOCATION, *PIMAGE_INDIR_CONTROL_TRANSFER_DYNAMIC_RELOCATION; typedef struct _IMAGE_SWITCHTABLE_BRANCH_DYNAMIC_RELOCATION { USHORT PageRelativeOffset : 12; USHORT RegisterNumber : 4; -} IMAGE_SWITCHTABLE_BRANCH_DYNAMIC_RELOCATION; +} IMAGE_SWITCHTABLE_BRANCH_DYNAMIC_RELOCATION, *PIMAGE_SWITCHTABLE_BRANCH_DYNAMIC_RELOCATION; typedef struct _IMAGE_FUNCTION_OVERRIDE_HEADER { ULONG FuncOverrideSize; // IMAGE_FUNCTION_OVERRIDE_DYNAMIC_RELOCATION FuncOverrideInfo[ANYSIZE_ARRAY]; // FuncOverrideSize bytes in size // IMAGE_BDD_INFO BDDInfo; // BDD region, size in bytes: DVRTEntrySize - sizeof(IMAGE_FUNCTION_OVERRIDE_HEADER) - FuncOverrideSize -} IMAGE_FUNCTION_OVERRIDE_HEADER; +} IMAGE_FUNCTION_OVERRIDE_HEADER, *PIMAGE_FUNCTION_OVERRIDE_HEADER; typedef struct _IMAGE_FUNCTION_OVERRIDE_DYNAMIC_RELOCATION { ULONG OriginalRva; // RVA of original function @@ -1317,19 +1316,19 @@ // IMAGE_BASE_RELOCATION BaseRelocs[ANYSIZE_ARRAY]; // Base relocations (RVA + Size + TO) // Padded with extra TOs for 4B alignment // BaseRelocSize size in bytes -} IMAGE_FUNCTION_OVERRIDE_DYNAMIC_RELOCATION; +} IMAGE_FUNCTION_OVERRIDE_DYNAMIC_RELOCATION, *PIMAGE_FUNCTION_OVERRIDE_DYNAMIC_RELOCATION; typedef struct _IMAGE_BDD_INFO { ULONG Version; // decides the semantics of serialized BDD ULONG BDDSize; // IMAGE_BDD_DYNAMIC_RELOCATION BDDNodes[ANYSIZE_ARRAY]; // BDDSize size in bytes. -} IMAGE_BDD_INFO; +} IMAGE_BDD_INFO, *PIMAGE_BDD_INFO; typedef struct _IMAGE_BDD_DYNAMIC_RELOCATION { USHORT Left; // Index of FALSE edge in BDD array USHORT Right; // Index of TRUE edge in BDD array ULONG Value; // Either FeatureNumber or Index into RVAs array -} IMAGE_BDD_DYNAMIC_RELOCATION; +} IMAGE_BDD_DYNAMIC_RELOCATION, *PIMAGE_BDD_DYNAMIC_RELOCATION; // Function override relocation types in DVRT records. @@ -1418,7 +1417,7 @@ ULONG CastGuardOsDeterminedFailureMode; // VA ULONG GuardMemcpyFunctionPointer; // VA ULONG UmaFunctionPointers; // VA -} IMAGE_LOAD_CONFIG_DIRECTORY32; +} IMAGE_LOAD_CONFIG_DIRECTORY32, *PIMAGE_LOAD_CONFIG_DIRECTORY32; typedef struct _IMAGE_LOAD_CONFIG_DIRECTORY64 { ULONG Size; @@ -1471,7 +1470,7 @@ ULONGLONG CastGuardOsDeterminedFailureMode; // VA ULONGLONG GuardMemcpyFunctionPointer; // VA ULONGLONG UmaFunctionPointers; // VA -} IMAGE_LOAD_CONFIG_DIRECTORY64; +} IMAGE_LOAD_CONFIG_DIRECTORY64, *PIMAGE_LOAD_CONFIG_DIRECTORY64; typedef struct _IMAGE_CHPE_METADATA_X86 { ULONG Version; @@ -1486,7 +1485,7 @@ ULONG WowA64DispatchJumpFunctionPointer; ULONG CompilerIATPointer; // Present if Version >= 2 ULONG WowA64RdtscFunctionPointer; // Present if Version >= 3 -} IMAGE_CHPE_METADATA_X86; +} IMAGE_CHPE_METADATA_X86, *PIMAGE_CHPE_METADATA_X86; typedef struct _IMAGE_CHPE_RANGE_ENTRY { union { @@ -1497,7 +1496,7 @@ }; }; ULONG Length; -} IMAGE_CHPE_RANGE_ENTRY; +} IMAGE_CHPE_RANGE_ENTRY, *PIMAGE_CHPE_RANGE_ENTRY; typedef struct _IMAGE_ARM64EC_METADATA { ULONG Version; @@ -1520,7 +1519,7 @@ ULONG ExtraRFETableSize; ULONG __os_arm64x_dispatch_fptr; ULONG AuxiliaryIATCopy; -} IMAGE_ARM64EC_METADATA; +} IMAGE_ARM64EC_METADATA, *PIMAGE_ARM64EC_METADATA; typedef struct _IMAGE_ARM64EC_METADATA_V2 { ULONG Version; @@ -1550,18 +1549,18 @@ ULONG AuxDelayloadIAT; ULONG AuxDelayloadIATCopy; ULONG ReservedBitField; // reserved and unused by the linker -} IMAGE_ARM64EC_METADATA_V2; +} IMAGE_ARM64EC_METADATA_V2, *PIMAGE_ARM64EC_METADATA_V2; typedef struct _IMAGE_ARM64EC_REDIRECTION_ENTRY { ULONG Source; ULONG Destination; -} IMAGE_ARM64EC_REDIRECTION_ENTRY; +} IMAGE_ARM64EC_REDIRECTION_ENTRY, *PIMAGE_ARM64EC_REDIRECTION_ENTRY; typedef struct _IMAGE_ARM64EC_CODE_RANGE_ENTRY_POINT { ULONG StartRva; ULONG EndRva; ULONG EntryPoint; -} IMAGE_ARM64EC_CODE_RANGE_ENTRY_POINT; +} IMAGE_ARM64EC_CODE_RANGE_ENTRY_POINT, *PIMAGE_ARM64EC_CODE_RANGE_ENTRY_POINT; #define IMAGE_DVRT_ARM64X_FIXUP_TYPE_ZEROFILL 0 #define IMAGE_DVRT_ARM64X_FIXUP_TYPE_VALUE 1 @@ -1575,14 +1574,14 @@ USHORT Offset : 12; USHORT Type : 2; USHORT Size : 2; -} IMAGE_DVRT_ARM64X_FIXUP_RECORD; +} IMAGE_DVRT_ARM64X_FIXUP_RECORD, *PIMAGE_DVRT_ARM64X_FIXUP_RECORD; typedef struct _IMAGE_DVRT_ARM64X_DELTA_FIXUP_RECORD { USHORT Offset : 12; USHORT Type : 2; USHORT Sign : 1; USHORT Scale : 1; -} IMAGE_DVRT_ARM64X_DELTA_FIXUP_RECORD; +} IMAGE_DVRT_ARM64X_DELTA_FIXUP_RECORD, *PIMAGE_DVRT_ARM64X_DELTA_FIXUP_RECORD; typedef struct _IMAGE_HOT_PATCH_INFO { ULONG Version; @@ -1594,7 +1593,7 @@ ULONG ExtraPatchSize; // Version 3 and later ULONG MinSequenceNumber; // Version 4 and later ULONG Flags; // Version 4 and later -} IMAGE_HOT_PATCH_INFO; +} IMAGE_HOT_PATCH_INFO, *PIMAGE_HOT_PATCH_INFO; typedef struct _IMAGE_HOT_PATCH_BASE { ULONG SequenceNumber; @@ -1605,7 +1604,7 @@ ULONG CodeIntegritySize; ULONG PatchTable; ULONG BufferOffset; // V2 and later -} IMAGE_HOT_PATCH_BASE; +} IMAGE_HOT_PATCH_BASE, *PIMAGE_HOT_PATCH_BASE; typedef struct _IMAGE_HOT_PATCH_MACHINE { struct { @@ -1614,12 +1613,12 @@ ULONG Arm64 : 1; ULONG Amd64EC : 1; }; -} IMAGE_HOT_PATCH_MACHINE; +} IMAGE_HOT_PATCH_MACHINE, *PIMAGE_HOT_PATCH_MACHINE; typedef struct _IMAGE_HOT_PATCH_HASHES { UCHAR SHA256[32]; UCHAR SHA1[20]; -} IMAGE_HOT_PATCH_HASHES; +} IMAGE_HOT_PATCH_HASHES, *PIMAGE_HOT_PATCH_HASHES; #define IMAGE_HOT_PATCH_BASE_OBLIGATORY 0x00000001 #define IMAGE_HOT_PATCH_BASE_CAN_ROLL_BACK 0x00000002 @@ -1671,7 +1670,7 @@ ULONG FuncLen : 22; ULONG ThirtyTwoBit : 1; ULONG ExceptionFlag : 1; -} IMAGE_CE_RUNTIME_FUNCTION_ENTRY; +} IMAGE_CE_RUNTIME_FUNCTION_ENTRY, *PIMAGE_CE_RUNTIME_FUNCTION_ENTRY; typedef struct _IMAGE_ARM_RUNTIME_FUNCTION_ENTRY { ULONG BeginAddress; @@ -1689,7 +1688,7 @@ ULONG StackAdjust : 10; }; }; -} IMAGE_ARM_RUNTIME_FUNCTION_ENTRY; +} IMAGE_ARM_RUNTIME_FUNCTION_ENTRY, *PIMAGE_ARM_RUNTIME_FUNCTION_ENTRY; enum ARM64_FNPDATA_FLAGS { PdataRefToFullXdata = 0, @@ -1718,7 +1717,7 @@ ULONG FrameSize : 9; }; }; -} IMAGE_ARM64_RUNTIME_FUNCTION_ENTRY; +} IMAGE_ARM64_RUNTIME_FUNCTION_ENTRY, *PIMAGE_ARM64_RUNTIME_FUNCTION_ENTRY; typedef union _IMAGE_ARM64_RUNTIME_FUNCTION_ENTRY_XDATA { ULONG HeaderData; @@ -1730,7 +1729,7 @@ ULONG EpilogCount : 5; // number of epilogs or byte index of the first unwind code for the one only epilog ULONG CodeWords : 5; // number of dwords with unwind codes }; -} IMAGE_ARM64_RUNTIME_FUNCTION_ENTRY_XDATA; +} IMAGE_ARM64_RUNTIME_FUNCTION_ENTRY_XDATA, *PIMAGE_ARM64_RUNTIME_FUNCTION_ENTRY_XDATA; typedef union IMAGE_ARM64_RUNTIME_FUNCTION_ENTRY_XDATA_EXTENDED { ULONG ExtendedHeaderData; @@ -1738,7 +1737,7 @@ ULONG ExtendedEpilogCount : 16; ULONG ExtendedCodeWords : 8; }; -} IMAGE_ARM64_RUNTIME_FUNCTION_ENTRY_XDATA_EXTENDED; +} IMAGE_ARM64_RUNTIME_FUNCTION_ENTRY_XDATA_EXTENDED, *PIMAGE_ARM64_RUNTIME_FUNCTION_ENTRY_XDATA_EXTENDED; typedef union IMAGE_ARM64_RUNTIME_FUNCTION_ENTRY_XDATA_EPILOG_SCOPE { ULONG EpilogScopeData; @@ -1747,7 +1746,7 @@ ULONG Res0: 4; ULONG EpilogStartIndex : 10; // byte index of the first unwind code that describes this epilog. }; -} IMAGE_ARM64_RUNTIME_FUNCTION_ENTRY_XDATA_EPILOG_SCOPE; +} IMAGE_ARM64_RUNTIME_FUNCTION_ENTRY_XDATA_EPILOG_SCOPE, *PIMAGE_ARM64_RUNTIME_FUNCTION_ENTRY_XDATA_EPILOG_SCOPE; typedef struct _IMAGE_ALPHA64_RUNTIME_FUNCTION_ENTRY { ULONGLONG BeginAddress; @@ -1755,7 +1754,7 @@ ULONGLONG ExceptionHandler; ULONGLONG HandlerData; ULONGLONG PrologEndAddress; -} IMAGE_ALPHA64_RUNTIME_FUNCTION_ENTRY; +} IMAGE_ALPHA64_RUNTIME_FUNCTION_ENTRY, *PIMAGE_ALPHA64_RUNTIME_FUNCTION_ENTRY; typedef struct _IMAGE_ALPHA_RUNTIME_FUNCTION_ENTRY { ULONG BeginAddress; @@ -1763,7 +1762,7 @@ ULONG ExceptionHandler; ULONG HandlerData; ULONG PrologEndAddress; -} IMAGE_ALPHA_RUNTIME_FUNCTION_ENTRY; +} IMAGE_ALPHA_RUNTIME_FUNCTION_ENTRY, *PIMAGE_ALPHA_RUNTIME_FUNCTION_ENTRY; typedef struct _IMAGE_MIPS_RUNTIME_FUNCTION_ENTRY { ULONG BeginAddress; @@ -1771,7 +1770,7 @@ ULONG ExceptionHandler; ULONG HandlerData; ULONG PrologEndAddress; -} IMAGE_MIPS_RUNTIME_FUNCTION_ENTRY; +} IMAGE_MIPS_RUNTIME_FUNCTION_ENTRY, *PIMAGE_MIPS_RUNTIME_FUNCTION_ENTRY; typedef struct _IMAGE_RUNTIME_FUNCTION_ENTRY { ULONG BeginAddress; @@ -1780,7 +1779,7 @@ ULONG UnwindInfoAddress; ULONG UnwindData; }; -} IMAGE_RUNTIME_FUNCTION_ENTRY; +} IMAGE_RUNTIME_FUNCTION_ENTRY, *PIMAGE_RUNTIME_FUNCTION_ENTRY; // // Sofware enclave information @@ -1803,7 +1802,7 @@ ULONG EnclaveSize; ULONG NumberOfThreads; ULONG EnclaveFlags; -} IMAGE_ENCLAVE_CONFIG32; +} IMAGE_ENCLAVE_CONFIG32, *PIMAGE_ENCLAVE_CONFIG32; typedef struct _IMAGE_ENCLAVE_CONFIG64 { ULONG Size; @@ -1819,7 +1818,7 @@ ULONGLONG EnclaveSize; ULONG NumberOfThreads; ULONG EnclaveFlags; -} IMAGE_ENCLAVE_CONFIG64; +} IMAGE_ENCLAVE_CONFIG64, *PIMAGE_ENCLAVE_CONFIG64; #define IMAGE_ENCLAVE_POLICY_DEBUGGABLE 0x00000001 #define IMAGE_ENCLAVE_POLICY_STRICT_MEMORY 0x00000002 @@ -1834,7 +1833,7 @@ UCHAR ImageID[IMAGE_ENCLAVE_SHORT_ID_LENGTH]; ULONG ImportName; ULONG Reserved; -} IMAGE_ENCLAVE_IMPORT; +} IMAGE_ENCLAVE_IMPORT, *PIMAGE_ENCLAVE_IMPORT; #define IMAGE_ENCLAVE_IMPORT_MATCH_NONE 0x00000000 #define IMAGE_ENCLAVE_IMPORT_MATCH_UNIQUE_ID 0x00000001 @@ -1861,7 +1860,7 @@ USHORT wRevision; WIN_CERT_TYPE wCertificateType; CHAR bCertificate[dwLength - 8]; -} WIN_CERTIFICATE; +} WIN_CERTIFICATE, *PWIN_CERTIFICATE; // // Debug Format @@ -1913,7 +1912,7 @@ ULONG SizeOfData; ULONG AddressOfRawData; ULONG PointerToRawData; -} IMAGE_DEBUG_DIRECTORY; +} IMAGE_DEBUG_DIRECTORY, *PIMAGE_DEBUG_DIRECTORY; typedef struct _IMAGE_COFF_SYMBOLS_HEADER { ULONG NumberOfSymbols; @@ -1924,7 +1923,7 @@ ULONG RvaToLastByteOfCode; ULONG RvaToFirstByteOfData; ULONG RvaToLastByteOfData; -} IMAGE_COFF_SYMBOLS_HEADER; +} IMAGE_COFF_SYMBOLS_HEADER, *PIMAGE_COFF_SYMBOLS_HEADER; #define CVINFO_PDB70_CVSIGNATURE 0x53445352 // "RSDS" #define CVINFO_PDB20_CVSIGNATURE 0x3031424e // "NB10" @@ -1935,27 +1934,27 @@ typedef struct _CV_HEADER { ULONG Signature; ULONG Offset; -} CV_HEADER; +} CV_HEADER, *PCV_HEADER; typedef struct _CV_INFO_PDB20 { CV_HEADER CvHeader; ULONG Signature; ULONG Age; CHAR PdbFileName[]; -} CV_INFO_PDB20; +} CV_INFO_PDB20, *PCV_INFO_PDB20; typedef struct _CV_INFO_PDB70 { ULONG CvSignature; CHAR Signature[16]; ULONG Age; CHAR PdbFileName[]; -} CV_INFO_PDB70; +} CV_INFO_PDB70, *PCV_INFO_PDB70; typedef struct _CV_INFO_MTOC { ULONG CvSignature; BYTE Signature[16]; BYTE PdbFileName[1]; -} CV_INFO_MTOC; +} CV_INFO_MTOC, *PCV_INFO_MTOC; #define FRAME_FPO 0 #define FRAME_TRAP 1 @@ -1973,7 +1972,7 @@ USHORT fUseBP : 1; // TRUE if EBP has been allocated USHORT reserved : 1; // reserved for future use USHORT cbFrame : 2; // frame type -} FPO_DATA; +} FPO_DATA, *PFPO_DATA; #define IMAGE_DEBUG_MISC_EXENAME 1 @@ -1984,7 +1983,7 @@ BOOLEAN Unicode; // TRUE if data is unicode string UCHAR Reserved[ 3 ]; // UCHAR Data[ 1 ]; // Actual data -} IMAGE_DEBUG_MISC; +} IMAGE_DEBUG_MISC, *PIMAGE_DEBUG_MISC; #define IMAGE_DEBUG_POGO_SIGNATURE_ZERO 0x00000000 #define IMAGE_DEBUG_POGO_SIGNATURE_LTCG 0x4C544347 @@ -1996,7 +1995,7 @@ ULONG Gs; ULONG Sdl; ULONG GuardN; -} VC_FEATURE; +} VC_FEATURE, *PVC_FEATURE; // // Function table extracted from MIPS/ALPHA/IA64 images. Does not contain @@ -2008,7 +2007,7 @@ ULONG StartingAddress; ULONG EndingAddress; ULONG EndOfPrologue; -} IMAGE_FUNCTION_ENTRY; +} IMAGE_FUNCTION_ENTRY, *PIMAGE_FUNCTION_ENTRY; typedef struct _IMAGE_FUNCTION_ENTRY64 { ULONGLONG StartingAddress; @@ -2017,7 +2016,7 @@ ULONGLONG EndOfPrologue; ULONGLONG UnwindInfoAddress; }; -} IMAGE_FUNCTION_ENTRY64; +} IMAGE_FUNCTION_ENTRY64, *PIMAGE_FUNCTION_ENTRY64; // // Debugging information can be stripped from an image file and placed @@ -2053,7 +2052,7 @@ ULONG DebugDirectorySize; ULONG SectionAlignment; ULONG Reserved[2]; -} IMAGE_SEPARATE_DEBUG_HEADER; +} IMAGE_SEPARATE_DEBUG_HEADER, *PIMAGE_SEPARATE_DEBUG_HEADER; typedef struct _NON_PAGED_DEBUG_INFO { USHORT Signature; @@ -2067,7 +2066,7 @@ ULONGLONG ImageBase; //DebugDirectorySize //IMAGE_DEBUG_DIRECTORY -} NON_PAGED_DEBUG_INFO; +} NON_PAGED_DEBUG_INFO, *PNON_PAGED_DEBUG_INFO; #define IMAGE_SEPARATE_DEBUG_SIGNATURE 0x4449 // DI #define NON_PAGED_DEBUG_SIGNATURE 0x4E49 // NI @@ -2091,12 +2090,12 @@ unsigned int AmaskShift: 8; // Amask bit in question for this fixup int _:16; // MBZ ULONG FirstEntryRVA; // RVA into .arch section to array of ARCHITECTURE_ENTRY's -} IMAGE_ARCHITECTURE_HEADER; +} IMAGE_ARCHITECTURE_HEADER, *PIMAGE_ARCHITECTURE_HEADER; typedef struct _ImageArchitectureEntry { ULONG FixupInstRVA; // RVA of instruction to fixup ULONG NewInst; // fixup instruction (see alphaops.h) -} IMAGE_ARCHITECTURE_ENTRY; +} IMAGE_ARCHITECTURE_ENTRY, *PIMAGE_ARCHITECTURE_ENTRY; // The following structure defines the new import object. Note the values of the first two fields, // which must be set as stated in order to differentiate old and new import members. @@ -2136,7 +2135,7 @@ IMPORT_OBJECT_TYPE Type : 2; // IMPORT_TYPE IMPORT_OBJECT_NAME_TYPE NameType : 3; // IMPORT_NAME_TYPE USHORT Reserved : 11; // Reserved. Must be zero. -} IMPORT_OBJECT_HEADER; +} IMPORT_OBJECT_HEADER, *PIMPORT_OBJECT_HEADER; // // COM Format. @@ -2212,7 +2211,7 @@ // Precompiled image info (internal use only - set to zero) IMAGE_DATA_DIRECTORY ManagedNativeHeader; -} IMAGE_COR20_HEADER; +} IMAGE_COR20_HEADER, *PIMAGE_COR20_HEADER; typedef struct _IMAGE_COR20_METADATA { ULONG Magic; @@ -2223,13 +2222,13 @@ CHAR Version[Length]; USHORT Flags; USHORT NumberOfStreams; -} IMAGE_COR20_METADATA; +} IMAGE_COR20_METADATA, *PIMAGE_COR20_METADATA; typedef struct _IMAGE_COR20_STREAM_HEADER { ULONG Offset; ULONG Size; CHAR Name[]; -} IMAGE_COR20_STREAM_HEADER; +} IMAGE_COR20_STREAM_HEADER, *PIMAGE_COR20_STREAM_HEADER; """ # noqa: E501 c_pe = cstruct().load(c_pe_def) diff --git a/dissect/executable/pe/c_pe.pyi b/dissect/executable/pe/c_pe.pyi index c99b355..1efb7de 100644 --- a/dissect/executable/pe/c_pe.pyi +++ b/dissect/executable/pe/c_pe.pyi @@ -157,6 +157,7 @@ class _c_pe(__cs__.cstruct): def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... IMAGE_DOS_HEADER: TypeAlias = _IMAGE_DOS_HEADER + PIMAGE_DOS_HEADER: TypeAlias = __cs__.Pointer[_c_pe._IMAGE_DOS_HEADER] class _IMAGE_OS2_HEADER(__cs__.Structure): ne_magic: _c_pe.uint16 ne_ver: _c_pe.char @@ -226,6 +227,7 @@ class _c_pe(__cs__.cstruct): def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... IMAGE_OS2_HEADER: TypeAlias = _IMAGE_OS2_HEADER + PIMAGE_OS2_HEADER: TypeAlias = __cs__.Pointer[_c_pe._IMAGE_OS2_HEADER] class _IMAGE_VXD_HEADER(__cs__.Structure): e32_magic: _c_pe.uint16 e32_border: _c_pe.uint8 @@ -337,6 +339,7 @@ class _c_pe(__cs__.cstruct): def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... IMAGE_VXD_HEADER: TypeAlias = _IMAGE_VXD_HEADER + PIMAGE_VXD_HEADER: TypeAlias = __cs__.Pointer[_c_pe._IMAGE_VXD_HEADER] class IMAGE_FILE(__cs__.Flag): RELOCS_STRIPPED = ... EXECUTABLE_IMAGE = ... @@ -415,6 +418,7 @@ class _c_pe(__cs__.cstruct): def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... IMAGE_FILE_HEADER: TypeAlias = _IMAGE_FILE_HEADER + PIMAGE_FILE_HEADER: TypeAlias = __cs__.Pointer[_c_pe._IMAGE_FILE_HEADER] class _IMAGE_DATA_DIRECTORY(__cs__.Structure): VirtualAddress: _c_pe.uint32 Size: _c_pe.uint32 @@ -424,6 +428,7 @@ class _c_pe(__cs__.cstruct): def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... IMAGE_DATA_DIRECTORY: TypeAlias = _IMAGE_DATA_DIRECTORY + PIMAGE_DATA_DIRECTORY: TypeAlias = __cs__.Pointer[_c_pe._IMAGE_DATA_DIRECTORY] class IMAGE_SUBSYSTEM(__cs__.Enum): UNKNOWN = ... NATIVE = ... @@ -537,6 +542,7 @@ class _c_pe(__cs__.cstruct): def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... IMAGE_OPTIONAL_HEADER32: TypeAlias = _IMAGE_OPTIONAL_HEADER + PIMAGE_OPTIONAL_HEADER32: TypeAlias = __cs__.Pointer[_c_pe._IMAGE_OPTIONAL_HEADER] class _IMAGE_OPTIONAL_HEADER64(__cs__.Structure): Magic: _c_pe.uint16 MajorLinkerVersion: _c_pe.uint8 @@ -614,6 +620,7 @@ class _c_pe(__cs__.cstruct): def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... IMAGE_OPTIONAL_HEADER64: TypeAlias = _IMAGE_OPTIONAL_HEADER64 + PIMAGE_OPTIONAL_HEADER64: TypeAlias = __cs__.Pointer[_c_pe._IMAGE_OPTIONAL_HEADER64] class _IMAGE_NT_HEADERS64(__cs__.Structure): Signature: _c_pe.uint32 FileHeader: _c_pe._IMAGE_FILE_HEADER @@ -629,6 +636,7 @@ class _c_pe(__cs__.cstruct): def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... IMAGE_NT_HEADERS64: TypeAlias = _IMAGE_NT_HEADERS64 + PIMAGE_NT_HEADERS64: TypeAlias = __cs__.Pointer[_c_pe._IMAGE_NT_HEADERS64] class _IMAGE_NT_HEADERS(__cs__.Structure): Signature: _c_pe.uint32 FileHeader: _c_pe._IMAGE_FILE_HEADER @@ -644,6 +652,7 @@ class _c_pe(__cs__.cstruct): def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... IMAGE_NT_HEADERS32: TypeAlias = _IMAGE_NT_HEADERS + PIMAGE_NT_HEADERS32: TypeAlias = __cs__.Pointer[_c_pe._IMAGE_NT_HEADERS] class IMAGE_DIRECTORY_ENTRY(__cs__.Enum): EXPORT = ... IMPORT = ... @@ -745,6 +754,7 @@ class _c_pe(__cs__.cstruct): def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... IMAGE_SECTION_HEADER: TypeAlias = _IMAGE_SECTION_HEADER + PIMAGE_SECTION_HEADER: TypeAlias = __cs__.Pointer[_c_pe._IMAGE_SECTION_HEADER] class IMAGE_REL_BASED(__cs__.Enum): ABSOLUTE = ... HIGH = ... @@ -779,6 +789,7 @@ class _c_pe(__cs__.cstruct): def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... IMAGE_BASE_RELOCATION: TypeAlias = _IMAGE_BASE_RELOCATION + PIMAGE_BASE_RELOCATION: TypeAlias = __cs__.Pointer[_c_pe._IMAGE_BASE_RELOCATION] class _IMAGE_ARCHIVE_MEMBER_HEADER(__cs__.Structure): Name: __cs__.CharArray Date: __cs__.CharArray @@ -802,6 +813,7 @@ class _c_pe(__cs__.cstruct): def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... IMAGE_ARCHIVE_MEMBER_HEADER: TypeAlias = _IMAGE_ARCHIVE_MEMBER_HEADER + PIMAGE_ARCHIVE_MEMBER_HEADER: TypeAlias = __cs__.Pointer[_c_pe._IMAGE_ARCHIVE_MEMBER_HEADER] class _IMAGE_EXPORT_DIRECTORY(__cs__.Structure): Characteristics: _c_pe.uint32 TimeDateStamp: _c_pe.uint32 @@ -833,6 +845,7 @@ class _c_pe(__cs__.cstruct): def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... IMAGE_EXPORT_DIRECTORY: TypeAlias = _IMAGE_EXPORT_DIRECTORY + PIMAGE_EXPORT_DIRECTORY: TypeAlias = __cs__.Pointer[_c_pe._IMAGE_EXPORT_DIRECTORY] class _IMAGE_IMPORT_BY_NAME(__cs__.Structure): Hint: _c_pe.uint16 Name: __cs__.CharArray @@ -842,6 +855,7 @@ class _c_pe(__cs__.cstruct): def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... IMAGE_IMPORT_BY_NAME: TypeAlias = _IMAGE_IMPORT_BY_NAME + PIMAGE_IMPORT_BY_NAME: TypeAlias = __cs__.Pointer[_c_pe._IMAGE_IMPORT_BY_NAME] class _IMAGE_THUNK_DATA64(__cs__.Structure): class __anonymous_1__(__cs__.Union): ForwarderString: _c_pe.uint64 @@ -866,6 +880,7 @@ class _c_pe(__cs__.cstruct): def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... IMAGE_THUNK_DATA64: TypeAlias = _IMAGE_THUNK_DATA64 + PIMAGE_THUNK_DATA64: TypeAlias = __cs__.Pointer[_c_pe._IMAGE_THUNK_DATA64] class _IMAGE_THUNK_DATA32(__cs__.Structure): class __anonymous_2__(__cs__.Union): ForwarderString: _c_pe.uint32 @@ -890,6 +905,7 @@ class _c_pe(__cs__.cstruct): def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... IMAGE_THUNK_DATA32: TypeAlias = _IMAGE_THUNK_DATA32 + PIMAGE_THUNK_DATA32: TypeAlias = __cs__.Pointer[_c_pe._IMAGE_THUNK_DATA32] class _IMAGE_IMPORT_DESCRIPTOR(__cs__.Structure): Characteristics: _c_pe.uint32 OriginalFirstThunk: _c_pe.uint32 @@ -911,6 +927,7 @@ class _c_pe(__cs__.cstruct): def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... IMAGE_IMPORT_DESCRIPTOR: TypeAlias = _IMAGE_IMPORT_DESCRIPTOR + PIMAGE_IMPORT_DESCRIPTOR: TypeAlias = __cs__.Pointer[_c_pe._IMAGE_IMPORT_DESCRIPTOR] class _IMAGE_TLS_DIRECTORY64(__cs__.Structure): StartAddressOfRawData: _c_pe.uint64 EndAddressOfRawData: _c_pe.uint64 @@ -938,6 +955,7 @@ class _c_pe(__cs__.cstruct): def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... IMAGE_TLS_DIRECTORY64: TypeAlias = _IMAGE_TLS_DIRECTORY64 + PIMAGE_TLS_DIRECTORY64: TypeAlias = __cs__.Pointer[_c_pe._IMAGE_TLS_DIRECTORY64] class _IMAGE_TLS_DIRECTORY32(__cs__.Structure): StartAddressOfRawData: _c_pe.uint32 EndAddressOfRawData: _c_pe.uint32 @@ -965,6 +983,7 @@ class _c_pe(__cs__.cstruct): def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... IMAGE_TLS_DIRECTORY32: TypeAlias = _IMAGE_TLS_DIRECTORY32 + PIMAGE_TLS_DIRECTORY32: TypeAlias = __cs__.Pointer[_c_pe._IMAGE_TLS_DIRECTORY32] class _IMAGE_BOUND_IMPORT_DESCRIPTOR(__cs__.Structure): TimeDateStamp: _c_pe.uint32 OffsetModuleName: _c_pe.uint16 @@ -980,6 +999,7 @@ class _c_pe(__cs__.cstruct): def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... IMAGE_BOUND_IMPORT_DESCRIPTOR: TypeAlias = _IMAGE_BOUND_IMPORT_DESCRIPTOR + PIMAGE_BOUND_IMPORT_DESCRIPTOR: TypeAlias = __cs__.Pointer[_c_pe._IMAGE_BOUND_IMPORT_DESCRIPTOR] class _IMAGE_BOUND_FORWARDER_REF(__cs__.Structure): TimeDateStamp: _c_pe.uint32 OffsetModuleName: _c_pe.uint16 @@ -995,6 +1015,7 @@ class _c_pe(__cs__.cstruct): def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... IMAGE_BOUND_FORWARDER_REF: TypeAlias = _IMAGE_BOUND_FORWARDER_REF + PIMAGE_BOUND_FORWARDER_REF: TypeAlias = __cs__.Pointer[_c_pe._IMAGE_BOUND_FORWARDER_REF] class _IMAGE_DELAYLOAD_DESCRIPTOR(__cs__.Structure): class __anonymous_9__(__cs__.Union): AllAttributes: _c_pe.uint32 @@ -1034,6 +1055,7 @@ class _c_pe(__cs__.cstruct): def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... IMAGE_DELAYLOAD_DESCRIPTOR: TypeAlias = _IMAGE_DELAYLOAD_DESCRIPTOR + PIMAGE_DELAYLOAD_DESCRIPTOR: TypeAlias = __cs__.Pointer[_c_pe._IMAGE_DELAYLOAD_DESCRIPTOR] class RT(__cs__.Enum): CURSOR = ... BITMAP = ... @@ -1078,6 +1100,7 @@ class _c_pe(__cs__.cstruct): def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... IMAGE_RESOURCE_DIRECTORY: TypeAlias = _IMAGE_RESOURCE_DIRECTORY + PIMAGE_RESOURCE_DIRECTORY: TypeAlias = __cs__.Pointer[_c_pe._IMAGE_RESOURCE_DIRECTORY] class _IMAGE_RESOURCE_DIRECTORY_ENTRY(__cs__.Structure): NameOffset: _c_pe.uint32 NameIsString: _c_pe.uint32 @@ -1101,6 +1124,7 @@ class _c_pe(__cs__.cstruct): def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... IMAGE_RESOURCE_DIRECTORY_ENTRY: TypeAlias = _IMAGE_RESOURCE_DIRECTORY_ENTRY + PIMAGE_RESOURCE_DIRECTORY_ENTRY: TypeAlias = __cs__.Pointer[_c_pe._IMAGE_RESOURCE_DIRECTORY_ENTRY] class _IMAGE_RESOURCE_DIRECTORY_STRING(__cs__.Structure): Length: _c_pe.uint16 NameString: __cs__.CharArray @@ -1110,6 +1134,7 @@ class _c_pe(__cs__.cstruct): def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... IMAGE_RESOURCE_DIRECTORY_STRING: TypeAlias = _IMAGE_RESOURCE_DIRECTORY_STRING + PIMAGE_RESOURCE_DIRECTORY_STRING: TypeAlias = __cs__.Pointer[_c_pe._IMAGE_RESOURCE_DIRECTORY_STRING] class _IMAGE_RESOURCE_DIR_STRING_U(__cs__.Structure): Length: _c_pe.uint16 NameString: __cs__.WcharArray @@ -1119,6 +1144,7 @@ class _c_pe(__cs__.cstruct): def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... IMAGE_RESOURCE_DIR_STRING_U: TypeAlias = _IMAGE_RESOURCE_DIR_STRING_U + PIMAGE_RESOURCE_DIR_STRING_U: TypeAlias = __cs__.Pointer[_c_pe._IMAGE_RESOURCE_DIR_STRING_U] class _IMAGE_RESOURCE_DATA_ENTRY(__cs__.Structure): OffsetToData: _c_pe.uint32 Size: _c_pe.uint32 @@ -1136,6 +1162,7 @@ class _c_pe(__cs__.cstruct): def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... IMAGE_RESOURCE_DATA_ENTRY: TypeAlias = _IMAGE_RESOURCE_DATA_ENTRY + PIMAGE_RESOURCE_DATA_ENTRY: TypeAlias = __cs__.Pointer[_c_pe._IMAGE_RESOURCE_DATA_ENTRY] class _VS_FIXEDFILEINFO(__cs__.Structure): dwSignature: _c_pe.uint32 dwStrucVersion: _c_pe.uint32 @@ -1171,6 +1198,7 @@ class _c_pe(__cs__.cstruct): def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... VS_FIXEDFILEINFO: TypeAlias = _VS_FIXEDFILEINFO + PVS_FIXEDFILEINFO: TypeAlias = __cs__.Pointer[_c_pe._VS_FIXEDFILEINFO] class VS_FF(__cs__.Flag): DEBUG = ... PRERELEASE = ... @@ -1477,6 +1505,7 @@ class _c_pe(__cs__.cstruct): def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... IMAGE_LOAD_CONFIG_CODE_INTEGRITY: TypeAlias = _IMAGE_LOAD_CONFIG_CODE_INTEGRITY + PIMAGE_LOAD_CONFIG_CODE_INTEGRITY: TypeAlias = __cs__.Pointer[_c_pe._IMAGE_LOAD_CONFIG_CODE_INTEGRITY] class _IMAGE_DYNAMIC_RELOCATION_TABLE(__cs__.Structure): Version: _c_pe.uint32 Size: _c_pe.uint32 @@ -1486,6 +1515,7 @@ class _c_pe(__cs__.cstruct): def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... IMAGE_DYNAMIC_RELOCATION_TABLE: TypeAlias = _IMAGE_DYNAMIC_RELOCATION_TABLE + PIMAGE_DYNAMIC_RELOCATION_TABLE: TypeAlias = __cs__.Pointer[_c_pe._IMAGE_DYNAMIC_RELOCATION_TABLE] class _IMAGE_DYNAMIC_RELOCATION32(__cs__.Structure): Symbol: _c_pe.uint32 BaseRelocSize: _c_pe.uint32 @@ -1495,6 +1525,7 @@ class _c_pe(__cs__.cstruct): def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... IMAGE_DYNAMIC_RELOCATION32: TypeAlias = _IMAGE_DYNAMIC_RELOCATION32 + PIMAGE_DYNAMIC_RELOCATION32: TypeAlias = __cs__.Pointer[_c_pe._IMAGE_DYNAMIC_RELOCATION32] class _IMAGE_DYNAMIC_RELOCATION64(__cs__.Structure): Symbol: _c_pe.uint64 BaseRelocSize: _c_pe.uint32 @@ -1504,6 +1535,7 @@ class _c_pe(__cs__.cstruct): def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... IMAGE_DYNAMIC_RELOCATION64: TypeAlias = _IMAGE_DYNAMIC_RELOCATION64 + PIMAGE_DYNAMIC_RELOCATION64: TypeAlias = __cs__.Pointer[_c_pe._IMAGE_DYNAMIC_RELOCATION64] class _IMAGE_DYNAMIC_RELOCATION32_V2(__cs__.Structure): HeaderSize: _c_pe.uint32 FixupInfoSize: _c_pe.uint32 @@ -1523,6 +1555,7 @@ class _c_pe(__cs__.cstruct): def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... IMAGE_DYNAMIC_RELOCATION32_V2: TypeAlias = _IMAGE_DYNAMIC_RELOCATION32_V2 + PIMAGE_DYNAMIC_RELOCATION32_V2: TypeAlias = __cs__.Pointer[_c_pe._IMAGE_DYNAMIC_RELOCATION32_V2] class _IMAGE_DYNAMIC_RELOCATION64_V2(__cs__.Structure): HeaderSize: _c_pe.uint32 FixupInfoSize: _c_pe.uint32 @@ -1542,6 +1575,7 @@ class _c_pe(__cs__.cstruct): def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... IMAGE_DYNAMIC_RELOCATION64_V2: TypeAlias = _IMAGE_DYNAMIC_RELOCATION64_V2 + PIMAGE_DYNAMIC_RELOCATION64_V2: TypeAlias = __cs__.Pointer[_c_pe._IMAGE_DYNAMIC_RELOCATION64_V2] class _IMAGE_PROLOGUE_DYNAMIC_RELOCATION_HEADER(__cs__.Structure): PrologueByteCount: _c_pe.uint8 @overload @@ -1550,6 +1584,9 @@ class _c_pe(__cs__.cstruct): def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... IMAGE_PROLOGUE_DYNAMIC_RELOCATION_HEADER: TypeAlias = _IMAGE_PROLOGUE_DYNAMIC_RELOCATION_HEADER + PIMAGE_PROLOGUE_DYNAMIC_RELOCATION_HEADER: TypeAlias = __cs__.Pointer[ + _c_pe._IMAGE_PROLOGUE_DYNAMIC_RELOCATION_HEADER + ] class _IMAGE_EPILOGUE_DYNAMIC_RELOCATION_HEADER(__cs__.Structure): EpilogueCount: _c_pe.uint32 EpilogueByteCount: _c_pe.uint8 @@ -1567,6 +1604,9 @@ class _c_pe(__cs__.cstruct): def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... IMAGE_EPILOGUE_DYNAMIC_RELOCATION_HEADER: TypeAlias = _IMAGE_EPILOGUE_DYNAMIC_RELOCATION_HEADER + PIMAGE_EPILOGUE_DYNAMIC_RELOCATION_HEADER: TypeAlias = __cs__.Pointer[ + _c_pe._IMAGE_EPILOGUE_DYNAMIC_RELOCATION_HEADER + ] class _IMAGE_IMPORT_CONTROL_TRANSFER_DYNAMIC_RELOCATION(__cs__.Structure): PageRelativeOffset: _c_pe.uint32 IndirectCall: _c_pe.uint32 @@ -1582,6 +1622,9 @@ class _c_pe(__cs__.cstruct): def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... IMAGE_IMPORT_CONTROL_TRANSFER_DYNAMIC_RELOCATION: TypeAlias = _IMAGE_IMPORT_CONTROL_TRANSFER_DYNAMIC_RELOCATION + PIMAGE_IMPORT_CONTROL_TRANSFER_DYNAMIC_RELOCATION: TypeAlias = __cs__.Pointer[ + _c_pe._IMAGE_IMPORT_CONTROL_TRANSFER_DYNAMIC_RELOCATION + ] class _IMAGE_IMPORT_CONTROL_TRANSFER_ARM64_RELOCATION(__cs__.Structure): PageRelativeOffset: _c_pe.uint32 IndirectCall: _c_pe.uint32 @@ -1601,6 +1644,9 @@ class _c_pe(__cs__.cstruct): def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... IMAGE_IMPORT_CONTROL_TRANSFER_ARM64_RELOCATION: TypeAlias = _IMAGE_IMPORT_CONTROL_TRANSFER_ARM64_RELOCATION + PIMAGE_IMPORT_CONTROL_TRANSFER_ARM64_RELOCATION: TypeAlias = __cs__.Pointer[ + _c_pe._IMAGE_IMPORT_CONTROL_TRANSFER_ARM64_RELOCATION + ] class _IMAGE_INDIR_CONTROL_TRANSFER_DYNAMIC_RELOCATION(__cs__.Structure): PageRelativeOffset: _c_pe.uint16 IndirectCall: _c_pe.uint16 @@ -1620,6 +1666,9 @@ class _c_pe(__cs__.cstruct): def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... IMAGE_INDIR_CONTROL_TRANSFER_DYNAMIC_RELOCATION: TypeAlias = _IMAGE_INDIR_CONTROL_TRANSFER_DYNAMIC_RELOCATION + PIMAGE_INDIR_CONTROL_TRANSFER_DYNAMIC_RELOCATION: TypeAlias = __cs__.Pointer[ + _c_pe._IMAGE_INDIR_CONTROL_TRANSFER_DYNAMIC_RELOCATION + ] class _IMAGE_SWITCHTABLE_BRANCH_DYNAMIC_RELOCATION(__cs__.Structure): PageRelativeOffset: _c_pe.uint16 RegisterNumber: _c_pe.uint16 @@ -1631,6 +1680,9 @@ class _c_pe(__cs__.cstruct): def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... IMAGE_SWITCHTABLE_BRANCH_DYNAMIC_RELOCATION: TypeAlias = _IMAGE_SWITCHTABLE_BRANCH_DYNAMIC_RELOCATION + PIMAGE_SWITCHTABLE_BRANCH_DYNAMIC_RELOCATION: TypeAlias = __cs__.Pointer[ + _c_pe._IMAGE_SWITCHTABLE_BRANCH_DYNAMIC_RELOCATION + ] class _IMAGE_FUNCTION_OVERRIDE_HEADER(__cs__.Structure): FuncOverrideSize: _c_pe.uint32 @overload @@ -1639,6 +1691,7 @@ class _c_pe(__cs__.cstruct): def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... IMAGE_FUNCTION_OVERRIDE_HEADER: TypeAlias = _IMAGE_FUNCTION_OVERRIDE_HEADER + PIMAGE_FUNCTION_OVERRIDE_HEADER: TypeAlias = __cs__.Pointer[_c_pe._IMAGE_FUNCTION_OVERRIDE_HEADER] class _IMAGE_FUNCTION_OVERRIDE_DYNAMIC_RELOCATION(__cs__.Structure): OriginalRva: _c_pe.uint32 BDDOffset: _c_pe.uint32 @@ -1656,6 +1709,9 @@ class _c_pe(__cs__.cstruct): def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... IMAGE_FUNCTION_OVERRIDE_DYNAMIC_RELOCATION: TypeAlias = _IMAGE_FUNCTION_OVERRIDE_DYNAMIC_RELOCATION + PIMAGE_FUNCTION_OVERRIDE_DYNAMIC_RELOCATION: TypeAlias = __cs__.Pointer[ + _c_pe._IMAGE_FUNCTION_OVERRIDE_DYNAMIC_RELOCATION + ] class _IMAGE_BDD_INFO(__cs__.Structure): Version: _c_pe.uint32 BDDSize: _c_pe.uint32 @@ -1665,6 +1721,7 @@ class _c_pe(__cs__.cstruct): def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... IMAGE_BDD_INFO: TypeAlias = _IMAGE_BDD_INFO + PIMAGE_BDD_INFO: TypeAlias = __cs__.Pointer[_c_pe._IMAGE_BDD_INFO] class _IMAGE_BDD_DYNAMIC_RELOCATION(__cs__.Structure): Left: _c_pe.uint16 Right: _c_pe.uint16 @@ -1677,6 +1734,7 @@ class _c_pe(__cs__.cstruct): def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... IMAGE_BDD_DYNAMIC_RELOCATION: TypeAlias = _IMAGE_BDD_DYNAMIC_RELOCATION + PIMAGE_BDD_DYNAMIC_RELOCATION: TypeAlias = __cs__.Pointer[_c_pe._IMAGE_BDD_DYNAMIC_RELOCATION] class IMAGE_GUARD(__cs__.Flag): CF_INSTRUMENTED = ... CFW_INSTRUMENTED = ... @@ -1805,6 +1863,7 @@ class _c_pe(__cs__.cstruct): def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... IMAGE_LOAD_CONFIG_DIRECTORY32: TypeAlias = _IMAGE_LOAD_CONFIG_DIRECTORY32 + PIMAGE_LOAD_CONFIG_DIRECTORY32: TypeAlias = __cs__.Pointer[_c_pe._IMAGE_LOAD_CONFIG_DIRECTORY32] class _IMAGE_LOAD_CONFIG_DIRECTORY64(__cs__.Structure): Size: _c_pe.uint32 TimeDateStamp: _c_pe.uint32 @@ -1914,6 +1973,7 @@ class _c_pe(__cs__.cstruct): def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... IMAGE_LOAD_CONFIG_DIRECTORY64: TypeAlias = _IMAGE_LOAD_CONFIG_DIRECTORY64 + PIMAGE_LOAD_CONFIG_DIRECTORY64: TypeAlias = __cs__.Pointer[_c_pe._IMAGE_LOAD_CONFIG_DIRECTORY64] class _IMAGE_CHPE_METADATA_X86(__cs__.Structure): Version: _c_pe.uint32 CHPECodeAddressRangeOffset: _c_pe.uint32 @@ -1947,6 +2007,7 @@ class _c_pe(__cs__.cstruct): def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... IMAGE_CHPE_METADATA_X86: TypeAlias = _IMAGE_CHPE_METADATA_X86 + PIMAGE_CHPE_METADATA_X86: TypeAlias = __cs__.Pointer[_c_pe._IMAGE_CHPE_METADATA_X86] class _IMAGE_CHPE_RANGE_ENTRY(__cs__.Structure): StartOffset: _c_pe.uint32 NativeCode: _c_pe.uint32 @@ -1964,6 +2025,7 @@ class _c_pe(__cs__.cstruct): def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... IMAGE_CHPE_RANGE_ENTRY: TypeAlias = _IMAGE_CHPE_RANGE_ENTRY + PIMAGE_CHPE_RANGE_ENTRY: TypeAlias = __cs__.Pointer[_c_pe._IMAGE_CHPE_RANGE_ENTRY] class _IMAGE_ARM64EC_METADATA(__cs__.Structure): Version: _c_pe.uint32 CodeMap: _c_pe.uint32 @@ -2013,6 +2075,7 @@ class _c_pe(__cs__.cstruct): def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... IMAGE_ARM64EC_METADATA: TypeAlias = _IMAGE_ARM64EC_METADATA + PIMAGE_ARM64EC_METADATA: TypeAlias = __cs__.Pointer[_c_pe._IMAGE_ARM64EC_METADATA] class _IMAGE_ARM64EC_METADATA_V2(__cs__.Structure): Version: _c_pe.uint32 CodeMap: _c_pe.uint32 @@ -2068,6 +2131,7 @@ class _c_pe(__cs__.cstruct): def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... IMAGE_ARM64EC_METADATA_V2: TypeAlias = _IMAGE_ARM64EC_METADATA_V2 + PIMAGE_ARM64EC_METADATA_V2: TypeAlias = __cs__.Pointer[_c_pe._IMAGE_ARM64EC_METADATA_V2] class _IMAGE_ARM64EC_REDIRECTION_ENTRY(__cs__.Structure): Source: _c_pe.uint32 Destination: _c_pe.uint32 @@ -2077,6 +2141,7 @@ class _c_pe(__cs__.cstruct): def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... IMAGE_ARM64EC_REDIRECTION_ENTRY: TypeAlias = _IMAGE_ARM64EC_REDIRECTION_ENTRY + PIMAGE_ARM64EC_REDIRECTION_ENTRY: TypeAlias = __cs__.Pointer[_c_pe._IMAGE_ARM64EC_REDIRECTION_ENTRY] class _IMAGE_ARM64EC_CODE_RANGE_ENTRY_POINT(__cs__.Structure): StartRva: _c_pe.uint32 EndRva: _c_pe.uint32 @@ -2092,6 +2157,7 @@ class _c_pe(__cs__.cstruct): def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... IMAGE_ARM64EC_CODE_RANGE_ENTRY_POINT: TypeAlias = _IMAGE_ARM64EC_CODE_RANGE_ENTRY_POINT + PIMAGE_ARM64EC_CODE_RANGE_ENTRY_POINT: TypeAlias = __cs__.Pointer[_c_pe._IMAGE_ARM64EC_CODE_RANGE_ENTRY_POINT] class _IMAGE_DVRT_ARM64X_FIXUP_RECORD(__cs__.Structure): Offset: _c_pe.uint16 Type: _c_pe.uint16 @@ -2104,6 +2170,7 @@ class _c_pe(__cs__.cstruct): def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... IMAGE_DVRT_ARM64X_FIXUP_RECORD: TypeAlias = _IMAGE_DVRT_ARM64X_FIXUP_RECORD + PIMAGE_DVRT_ARM64X_FIXUP_RECORD: TypeAlias = __cs__.Pointer[_c_pe._IMAGE_DVRT_ARM64X_FIXUP_RECORD] class _IMAGE_DVRT_ARM64X_DELTA_FIXUP_RECORD(__cs__.Structure): Offset: _c_pe.uint16 Type: _c_pe.uint16 @@ -2121,6 +2188,7 @@ class _c_pe(__cs__.cstruct): def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... IMAGE_DVRT_ARM64X_DELTA_FIXUP_RECORD: TypeAlias = _IMAGE_DVRT_ARM64X_DELTA_FIXUP_RECORD + PIMAGE_DVRT_ARM64X_DELTA_FIXUP_RECORD: TypeAlias = __cs__.Pointer[_c_pe._IMAGE_DVRT_ARM64X_DELTA_FIXUP_RECORD] class _IMAGE_HOT_PATCH_INFO(__cs__.Structure): Version: _c_pe.uint32 Size: _c_pe.uint32 @@ -2148,6 +2216,7 @@ class _c_pe(__cs__.cstruct): def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... IMAGE_HOT_PATCH_INFO: TypeAlias = _IMAGE_HOT_PATCH_INFO + PIMAGE_HOT_PATCH_INFO: TypeAlias = __cs__.Pointer[_c_pe._IMAGE_HOT_PATCH_INFO] class _IMAGE_HOT_PATCH_BASE(__cs__.Structure): SequenceNumber: _c_pe.uint32 Flags: _c_pe.uint32 @@ -2173,6 +2242,7 @@ class _c_pe(__cs__.cstruct): def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... IMAGE_HOT_PATCH_BASE: TypeAlias = _IMAGE_HOT_PATCH_BASE + PIMAGE_HOT_PATCH_BASE: TypeAlias = __cs__.Pointer[_c_pe._IMAGE_HOT_PATCH_BASE] class _IMAGE_HOT_PATCH_MACHINE(__cs__.Structure): _x86: _c_pe.uint32 Amd64: _c_pe.uint32 @@ -2190,6 +2260,7 @@ class _c_pe(__cs__.cstruct): def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... IMAGE_HOT_PATCH_MACHINE: TypeAlias = _IMAGE_HOT_PATCH_MACHINE + PIMAGE_HOT_PATCH_MACHINE: TypeAlias = __cs__.Pointer[_c_pe._IMAGE_HOT_PATCH_MACHINE] class _IMAGE_HOT_PATCH_HASHES(__cs__.Structure): SHA256: __cs__.Array[_c_pe.uint8] SHA1: __cs__.Array[_c_pe.uint8] @@ -2201,6 +2272,7 @@ class _c_pe(__cs__.cstruct): def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... IMAGE_HOT_PATCH_HASHES: TypeAlias = _IMAGE_HOT_PATCH_HASHES + PIMAGE_HOT_PATCH_HASHES: TypeAlias = __cs__.Pointer[_c_pe._IMAGE_HOT_PATCH_HASHES] class IMAGE_HOT_PATCH(__cs__.Enum): NONE = ... FUNCTION = ... @@ -2230,6 +2302,7 @@ class _c_pe(__cs__.cstruct): def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... IMAGE_CE_RUNTIME_FUNCTION_ENTRY: TypeAlias = _IMAGE_CE_RUNTIME_FUNCTION_ENTRY + PIMAGE_CE_RUNTIME_FUNCTION_ENTRY: TypeAlias = __cs__.Pointer[_c_pe._IMAGE_CE_RUNTIME_FUNCTION_ENTRY] class _IMAGE_ARM_RUNTIME_FUNCTION_ENTRY(__cs__.Structure): BeginAddress: _c_pe.uint32 UnwindData: _c_pe.uint32 @@ -2261,6 +2334,7 @@ class _c_pe(__cs__.cstruct): def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... IMAGE_ARM_RUNTIME_FUNCTION_ENTRY: TypeAlias = _IMAGE_ARM_RUNTIME_FUNCTION_ENTRY + PIMAGE_ARM_RUNTIME_FUNCTION_ENTRY: TypeAlias = __cs__.Pointer[_c_pe._IMAGE_ARM_RUNTIME_FUNCTION_ENTRY] class ARM64_FNPDATA_FLAGS(__cs__.Enum): PdataRefToFullXdata = ... PdataPackedUnwindFunction = ... @@ -2299,6 +2373,7 @@ class _c_pe(__cs__.cstruct): def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... IMAGE_ARM64_RUNTIME_FUNCTION_ENTRY: TypeAlias = _IMAGE_ARM64_RUNTIME_FUNCTION_ENTRY + PIMAGE_ARM64_RUNTIME_FUNCTION_ENTRY: TypeAlias = __cs__.Pointer[_c_pe._IMAGE_ARM64_RUNTIME_FUNCTION_ENTRY] class _IMAGE_ARM64_RUNTIME_FUNCTION_ENTRY_XDATA(__cs__.Union): HeaderData: _c_pe.uint32 FunctionLength: _c_pe.uint32 @@ -2322,6 +2397,9 @@ class _c_pe(__cs__.cstruct): def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... IMAGE_ARM64_RUNTIME_FUNCTION_ENTRY_XDATA: TypeAlias = _IMAGE_ARM64_RUNTIME_FUNCTION_ENTRY_XDATA + PIMAGE_ARM64_RUNTIME_FUNCTION_ENTRY_XDATA: TypeAlias = __cs__.Pointer[ + _c_pe._IMAGE_ARM64_RUNTIME_FUNCTION_ENTRY_XDATA + ] class IMAGE_ARM64_RUNTIME_FUNCTION_ENTRY_XDATA_EXTENDED(__cs__.Union): ExtendedHeaderData: _c_pe.uint32 ExtendedEpilogCount: _c_pe.uint32 @@ -2336,6 +2414,9 @@ class _c_pe(__cs__.cstruct): @overload def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... + PIMAGE_ARM64_RUNTIME_FUNCTION_ENTRY_XDATA_EXTENDED: TypeAlias = __cs__.Pointer[ + _c_pe.IMAGE_ARM64_RUNTIME_FUNCTION_ENTRY_XDATA_EXTENDED + ] class IMAGE_ARM64_RUNTIME_FUNCTION_ENTRY_XDATA_EPILOG_SCOPE(__cs__.Union): EpilogScopeData: _c_pe.uint32 EpilogStartOffset: _c_pe.uint32 @@ -2352,6 +2433,9 @@ class _c_pe(__cs__.cstruct): @overload def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... + PIMAGE_ARM64_RUNTIME_FUNCTION_ENTRY_XDATA_EPILOG_SCOPE: TypeAlias = __cs__.Pointer[ + _c_pe.IMAGE_ARM64_RUNTIME_FUNCTION_ENTRY_XDATA_EPILOG_SCOPE + ] class _IMAGE_ALPHA64_RUNTIME_FUNCTION_ENTRY(__cs__.Structure): BeginAddress: _c_pe.uint64 EndAddress: _c_pe.uint64 @@ -2371,6 +2455,7 @@ class _c_pe(__cs__.cstruct): def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... IMAGE_ALPHA64_RUNTIME_FUNCTION_ENTRY: TypeAlias = _IMAGE_ALPHA64_RUNTIME_FUNCTION_ENTRY + PIMAGE_ALPHA64_RUNTIME_FUNCTION_ENTRY: TypeAlias = __cs__.Pointer[_c_pe._IMAGE_ALPHA64_RUNTIME_FUNCTION_ENTRY] class _IMAGE_ALPHA_RUNTIME_FUNCTION_ENTRY(__cs__.Structure): BeginAddress: _c_pe.uint32 EndAddress: _c_pe.uint32 @@ -2390,6 +2475,7 @@ class _c_pe(__cs__.cstruct): def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... IMAGE_ALPHA_RUNTIME_FUNCTION_ENTRY: TypeAlias = _IMAGE_ALPHA_RUNTIME_FUNCTION_ENTRY + PIMAGE_ALPHA_RUNTIME_FUNCTION_ENTRY: TypeAlias = __cs__.Pointer[_c_pe._IMAGE_ALPHA_RUNTIME_FUNCTION_ENTRY] class _IMAGE_MIPS_RUNTIME_FUNCTION_ENTRY(__cs__.Structure): BeginAddress: _c_pe.uint32 EndAddress: _c_pe.uint32 @@ -2409,6 +2495,7 @@ class _c_pe(__cs__.cstruct): def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... IMAGE_MIPS_RUNTIME_FUNCTION_ENTRY: TypeAlias = _IMAGE_MIPS_RUNTIME_FUNCTION_ENTRY + PIMAGE_MIPS_RUNTIME_FUNCTION_ENTRY: TypeAlias = __cs__.Pointer[_c_pe._IMAGE_MIPS_RUNTIME_FUNCTION_ENTRY] class _IMAGE_RUNTIME_FUNCTION_ENTRY(__cs__.Structure): BeginAddress: _c_pe.uint32 EndAddress: _c_pe.uint32 @@ -2426,6 +2513,7 @@ class _c_pe(__cs__.cstruct): def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... IMAGE_RUNTIME_FUNCTION_ENTRY: TypeAlias = _IMAGE_RUNTIME_FUNCTION_ENTRY + PIMAGE_RUNTIME_FUNCTION_ENTRY: TypeAlias = __cs__.Pointer[_c_pe._IMAGE_RUNTIME_FUNCTION_ENTRY] class _IMAGE_ENCLAVE_CONFIG32(__cs__.Structure): Size: _c_pe.uint32 MinimumRequiredConfigSize: _c_pe.uint32 @@ -2461,6 +2549,7 @@ class _c_pe(__cs__.cstruct): def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... IMAGE_ENCLAVE_CONFIG32: TypeAlias = _IMAGE_ENCLAVE_CONFIG32 + PIMAGE_ENCLAVE_CONFIG32: TypeAlias = __cs__.Pointer[_c_pe._IMAGE_ENCLAVE_CONFIG32] class _IMAGE_ENCLAVE_CONFIG64(__cs__.Structure): Size: _c_pe.uint32 MinimumRequiredConfigSize: _c_pe.uint32 @@ -2496,6 +2585,7 @@ class _c_pe(__cs__.cstruct): def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... IMAGE_ENCLAVE_CONFIG64: TypeAlias = _IMAGE_ENCLAVE_CONFIG64 + PIMAGE_ENCLAVE_CONFIG64: TypeAlias = __cs__.Pointer[_c_pe._IMAGE_ENCLAVE_CONFIG64] class _IMAGE_ENCLAVE_IMPORT(__cs__.Structure): MatchType: _c_pe.uint32 MinimumSecurityVersion: _c_pe.uint32 @@ -2519,6 +2609,7 @@ class _c_pe(__cs__.cstruct): def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... IMAGE_ENCLAVE_IMPORT: TypeAlias = _IMAGE_ENCLAVE_IMPORT + PIMAGE_ENCLAVE_IMPORT: TypeAlias = __cs__.Pointer[_c_pe._IMAGE_ENCLAVE_IMPORT] class WIN_CERT_TYPE(__cs__.Enum): X509 = ... PKCS_SIGNED_DATA = ... @@ -2542,6 +2633,7 @@ class _c_pe(__cs__.cstruct): def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... WIN_CERTIFICATE: TypeAlias = _WIN_CERTIFICATE + PWIN_CERTIFICATE: TypeAlias = __cs__.Pointer[_c_pe._WIN_CERTIFICATE] class IMAGE_DEBUG_TYPE(__cs__.Enum): UNKNOWN = ... COFF = ... @@ -2602,6 +2694,7 @@ class _c_pe(__cs__.cstruct): def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... IMAGE_DEBUG_DIRECTORY: TypeAlias = _IMAGE_DEBUG_DIRECTORY + PIMAGE_DEBUG_DIRECTORY: TypeAlias = __cs__.Pointer[_c_pe._IMAGE_DEBUG_DIRECTORY] class _IMAGE_COFF_SYMBOLS_HEADER(__cs__.Structure): NumberOfSymbols: _c_pe.uint32 LvaToFirstSymbol: _c_pe.uint32 @@ -2627,6 +2720,7 @@ class _c_pe(__cs__.cstruct): def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... IMAGE_COFF_SYMBOLS_HEADER: TypeAlias = _IMAGE_COFF_SYMBOLS_HEADER + PIMAGE_COFF_SYMBOLS_HEADER: TypeAlias = __cs__.Pointer[_c_pe._IMAGE_COFF_SYMBOLS_HEADER] class _CV_HEADER(__cs__.Structure): Signature: _c_pe.uint32 Offset: _c_pe.uint32 @@ -2636,6 +2730,7 @@ class _c_pe(__cs__.cstruct): def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... CV_HEADER: TypeAlias = _CV_HEADER + PCV_HEADER: TypeAlias = __cs__.Pointer[_c_pe._CV_HEADER] class _CV_INFO_PDB20(__cs__.Structure): CvHeader: _c_pe._CV_HEADER Signature: _c_pe.uint32 @@ -2653,6 +2748,7 @@ class _c_pe(__cs__.cstruct): def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... CV_INFO_PDB20: TypeAlias = _CV_INFO_PDB20 + PCV_INFO_PDB20: TypeAlias = __cs__.Pointer[_c_pe._CV_INFO_PDB20] class _CV_INFO_PDB70(__cs__.Structure): CvSignature: _c_pe.uint32 Signature: __cs__.CharArray @@ -2670,6 +2766,7 @@ class _c_pe(__cs__.cstruct): def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... CV_INFO_PDB70: TypeAlias = _CV_INFO_PDB70 + PCV_INFO_PDB70: TypeAlias = __cs__.Pointer[_c_pe._CV_INFO_PDB70] class _CV_INFO_MTOC(__cs__.Structure): CvSignature: _c_pe.uint32 Signature: __cs__.Array[_c_pe.uint8] @@ -2685,6 +2782,7 @@ class _c_pe(__cs__.cstruct): def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... CV_INFO_MTOC: TypeAlias = _CV_INFO_MTOC + PCV_INFO_MTOC: TypeAlias = __cs__.Pointer[_c_pe._CV_INFO_MTOC] class _FPO_DATA(__cs__.Structure): ulOffStart: _c_pe.uint32 cbProcSize: _c_pe.uint32 @@ -2714,6 +2812,7 @@ class _c_pe(__cs__.cstruct): def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... FPO_DATA: TypeAlias = _FPO_DATA + PFPO_DATA: TypeAlias = __cs__.Pointer[_c_pe._FPO_DATA] class _IMAGE_DEBUG_MISC(__cs__.Structure): DataType: _c_pe.uint32 Length: _c_pe.uint32 @@ -2731,6 +2830,7 @@ class _c_pe(__cs__.cstruct): def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... IMAGE_DEBUG_MISC: TypeAlias = _IMAGE_DEBUG_MISC + PIMAGE_DEBUG_MISC: TypeAlias = __cs__.Pointer[_c_pe._IMAGE_DEBUG_MISC] class _VC_FEATURE(__cs__.Structure): PreVC11: _c_pe.uint32 CCpp: _c_pe.uint32 @@ -2750,6 +2850,7 @@ class _c_pe(__cs__.cstruct): def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... VC_FEATURE: TypeAlias = _VC_FEATURE + PVC_FEATURE: TypeAlias = __cs__.Pointer[_c_pe._VC_FEATURE] class _IMAGE_FUNCTION_ENTRY(__cs__.Structure): StartingAddress: _c_pe.uint32 EndingAddress: _c_pe.uint32 @@ -2765,6 +2866,7 @@ class _c_pe(__cs__.cstruct): def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... IMAGE_FUNCTION_ENTRY: TypeAlias = _IMAGE_FUNCTION_ENTRY + PIMAGE_FUNCTION_ENTRY: TypeAlias = __cs__.Pointer[_c_pe._IMAGE_FUNCTION_ENTRY] class _IMAGE_FUNCTION_ENTRY64(__cs__.Structure): StartingAddress: _c_pe.uint64 EndingAddress: _c_pe.uint64 @@ -2782,6 +2884,7 @@ class _c_pe(__cs__.cstruct): def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... IMAGE_FUNCTION_ENTRY64: TypeAlias = _IMAGE_FUNCTION_ENTRY64 + PIMAGE_FUNCTION_ENTRY64: TypeAlias = __cs__.Pointer[_c_pe._IMAGE_FUNCTION_ENTRY64] class _IMAGE_SEPARATE_DEBUG_HEADER(__cs__.Structure): Signature: _c_pe.uint16 Flags: _c_pe.uint16 @@ -2817,6 +2920,7 @@ class _c_pe(__cs__.cstruct): def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... IMAGE_SEPARATE_DEBUG_HEADER: TypeAlias = _IMAGE_SEPARATE_DEBUG_HEADER + PIMAGE_SEPARATE_DEBUG_HEADER: TypeAlias = __cs__.Pointer[_c_pe._IMAGE_SEPARATE_DEBUG_HEADER] class _NON_PAGED_DEBUG_INFO(__cs__.Structure): Signature: _c_pe.uint16 Flags: _c_pe.uint16 @@ -2844,6 +2948,7 @@ class _c_pe(__cs__.cstruct): def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... NON_PAGED_DEBUG_INFO: TypeAlias = _NON_PAGED_DEBUG_INFO + PNON_PAGED_DEBUG_INFO: TypeAlias = __cs__.Pointer[_c_pe._NON_PAGED_DEBUG_INFO] class _ImageArchitectureHeader(__cs__.Structure): AmaskValue: _c_pe.uint32 _: _c_pe.int32 @@ -2861,6 +2966,7 @@ class _c_pe(__cs__.cstruct): def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... IMAGE_ARCHITECTURE_HEADER: TypeAlias = _ImageArchitectureHeader + PIMAGE_ARCHITECTURE_HEADER: TypeAlias = __cs__.Pointer[_c_pe._ImageArchitectureHeader] class _ImageArchitectureEntry(__cs__.Structure): FixupInstRVA: _c_pe.uint32 NewInst: _c_pe.uint32 @@ -2870,6 +2976,7 @@ class _c_pe(__cs__.cstruct): def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... IMAGE_ARCHITECTURE_ENTRY: TypeAlias = _ImageArchitectureEntry + PIMAGE_ARCHITECTURE_ENTRY: TypeAlias = __cs__.Pointer[_c_pe._ImageArchitectureEntry] class IMPORT_OBJECT_TYPE(__cs__.Enum): IMPORT_OBJECT_CODE = ... IMPORT_OBJECT_DATA = ... @@ -2912,6 +3019,7 @@ class _c_pe(__cs__.cstruct): @overload def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... + PIMPORT_OBJECT_HEADER: TypeAlias = __cs__.Pointer[_c_pe.IMPORT_OBJECT_HEADER] class COMIMAGE_FLAGS(__cs__.Flag): ILONLY = ... "32BITREQUIRED = ..." @@ -2956,6 +3064,7 @@ class _c_pe(__cs__.cstruct): def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... IMAGE_COR20_HEADER: TypeAlias = _IMAGE_COR20_HEADER + PIMAGE_COR20_HEADER: TypeAlias = __cs__.Pointer[_c_pe._IMAGE_COR20_HEADER] class _IMAGE_COR20_METADATA(__cs__.Structure): Magic: _c_pe.uint32 MajorVersion: _c_pe.uint16 @@ -2981,6 +3090,7 @@ class _c_pe(__cs__.cstruct): def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... IMAGE_COR20_METADATA: TypeAlias = _IMAGE_COR20_METADATA + PIMAGE_COR20_METADATA: TypeAlias = __cs__.Pointer[_c_pe._IMAGE_COR20_METADATA] class _IMAGE_COR20_STREAM_HEADER(__cs__.Structure): Offset: _c_pe.uint32 Size: _c_pe.uint32 @@ -2996,6 +3106,7 @@ class _c_pe(__cs__.cstruct): def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ... IMAGE_COR20_STREAM_HEADER: TypeAlias = _IMAGE_COR20_STREAM_HEADER + PIMAGE_COR20_STREAM_HEADER: TypeAlias = __cs__.Pointer[_c_pe._IMAGE_COR20_STREAM_HEADER] # Technically `c_pe` is an instance of `_c_pe`, but then we can't use it in type hints c_pe: TypeAlias = _c_pe diff --git a/pyproject.toml b/pyproject.toml index 246ef0a..fd1bb2a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -25,7 +25,7 @@ classifiers = [ "Topic :: Utilities", ] dependencies = [ - "dissect.cstruct>=4,<5", + "dissect.cstruct>=4.6.dev,<5", # TODO: remove on release "dissect.util>=3,<4", ] dynamic = ["version"] @@ -37,7 +37,7 @@ repository = "https://github.com/fox-it/dissect.executable" [project.optional-dependencies] dev = [ - "dissect.cstruct>=4.0.dev,<5.0.dev", + "dissect.cstruct>=4.6.dev,<5.0.dev", "dissect.util>=3.0.dev,<4.0.dev", ]