標準ライブラリのみ使用してPEファイルの情報を取得するクラスのコードです。現状ではインポート、エクスポート情報のみ対応しています。おそらくインポート情報を持たないファイルだとエラーが発生します。
#test.py from pefileinfo import * with PEFileInfo(r"C:\Windows\System32\kernel32.dll") as pefile: for import_desc in pefile.get_import_descriptors(): thunks = pefile.get_import_thunks(import_desc) name_orginals = tuple(thunk.name if thunk.name is not None else f"#{thunk.ordinal}" for thunk in thunks) print(f"{import_desc.name}: {', '.join(name_orginals)}") expdir = pefile.get_export_directory() pass
#pefileinfo.py from contextlib import contextmanager import ctypes from dataclasses import dataclass from datetime import datetime from enum import IntEnum from io import BytesIO from typing import ClassVar, Iterator from pefileinfo_nativestructure import * class PEFileError(RuntimeError): pass @dataclass(frozen=True) class ImageDOSHeader: magic: bytes cblp: int cp: int crlc: int cparhdr: int minalloc: int maxalloc: int ss: int sp: int csum: int ip: int cs: int lfarlc: int ovno: int res: tuple[int] oemid: int oeminfo: int res2: tuple[int] lfanew: int def __init__(self, f: BytesIO): t = IMAGE_DOS_HEADER() f.readinto(t) object.__setattr__(self, "magic", t.e_magic) object.__setattr__(self, "cblp", t.e_cblp) object.__setattr__(self, "cp", t.e_cp) object.__setattr__(self, "crlc", t.e_crlc) object.__setattr__(self, "cparhdr", t.e_cparhdr) object.__setattr__(self, "minalloc", t.e_minalloc) object.__setattr__(self, "maxalloc", t.e_maxalloc) object.__setattr__(self, "ss", t.e_ss) object.__setattr__(self, "sp", t.e_sp) object.__setattr__(self, "csum", t.e_csum) object.__setattr__(self, "ip", t.e_ip) object.__setattr__(self, "cs", t.e_cs) object.__setattr__(self, "lfarlc", t.e_lfarlc) object.__setattr__(self, "ovno", t.e_ovno) object.__setattr__(self, "res", tuple(t.e_res)) object.__setattr__(self, "oemid", t.e_oemid) object.__setattr__(self, "oeminfo", t.e_oeminfo) object.__setattr__(self, "res2", tuple(t.e_res2)) object.__setattr__(self, "lfanew", t.e_lfanew) @dataclass(frozen=True) class ImageFileHeaderCharacteristics: value: int @property def stripped_relocations(self) -> bool: return self.value & 0x0001 != 0 @property def is_exe_image(self) -> bool: return self.value & 0x0002 != 0 @property def stripped_linenums(self) -> bool: return self.value & 0x0004 != 0 @property def stripped_localsymbols(self) -> bool: return self.value & 0x0008 != 0 @property def trims_ws_aggresive(self) -> bool: return self.value & 0x0010 != 0 @property def awares_large_address(self) -> bool: return self.value & 0x0020 != 0 @property def is_reversed_bytes_low(self) -> bool: return self.value & 0x0080 != 0 @property def for_32bit_machine(self) -> bool: return self.value & 0x0100 != 0 @property def stripped_debug(self) -> bool: return self.value & 0x0200 != 0 @property def removable_run_from_swap(self) -> bool: return self.value & 0x0400 != 0 @property def net_run_from_swap(self) -> bool: return self.value & 0x0800 != 0 @property def system(self) -> bool: return self.value & 0x1000 != 0 @property def dll(self) -> bool: return self.value & 0x2000 != 0 @property def up_system_only(self) -> bool: return self.value & 0x4000 != 0 @property def reversed_bytes_high(self) -> bool: return self.value & 0x8000 != 0 @dataclass(frozen=True) class ImageFileHeader: machine: int number_of_sections: int timedatestamp: datetime pointer_to_symboltable: int number_of_symbols: int size_of_optionalheader: int characteristics: ImageFileHeaderCharacteristics def __init__(self, f: BytesIO): t = IMAGE_FILE_HEADER() f.readinto(t) object.__setattr__(self, "machine", t.Machine) object.__setattr__(self, "number_of_sections", t.NumberOfSections) object.__setattr__(self, "timedatestamp", datetime.fromtimestamp(t.TimeDataStamp)) object.__setattr__(self, "pointer_to_symboltable", t.PointerToSymbolTable) object.__setattr__(self, "number_of_symbols", t.NumberOfSymbols) object.__setattr__(self, "size_of_optionalheader", t.SizeOfOptionalHeader) object.__setattr__(self, "characteristics", ImageFileHeaderCharacteristics(t.Characteristics)) @dataclass(frozen=True) class ImageDataDirectory: va: int size: int def __init__(self, raw: IMAGE_DATA_DIRECTORY): object.__setattr__(self, "va", raw.VirtualAddress) object.__setattr__(self, "size", raw.Size) class ImageOptionalHeaderSubsystem(IntEnum): UNKNOWN = 0 NATIVE = 1 WINDOWS_GUI = 2 WINDOWS_CUI = 3 OS2_CUI = 5 POSIX_CUI = 7 WINDOWS_CE_GUI = 9 EFI_APPLICATION = 10 EFI_BOOT_SERVICE_DRIVER = 11 EFI_RUNTIME_DRIVER = 12 EFI_ROM = 13 XBOX = 14 WINDOWS_BOOT_APPLICATION = 16 @dataclass(frozen=True) class ImageOptionalHeaderDLLCharacteristics: value: int @property def reserved1(self) -> bool: return self.value & 0x0001 != 0 @property def reserved2(self) -> bool: return self.value & 0x0002 != 0 @property def reserved3(self) -> bool: return self.value & 0x0004 != 0 @property def reserved4(self) -> bool: return self.value & 0x0008 != 0 @property def high_entrophy_va(self) -> bool: return self.value & 0x0020 != 0 @property def dynamic_base(self) -> bool: return self.value & 0x0040 != 0 @property def forces_integrity(self) -> bool: return self.value & 0x0080 != 0 @property def nx_compat(self) -> bool: return self.value & 0x0100 != 0 @property def no_isolation(self) -> bool: return self.value & 0x0200 != 0 @property def no_seh(self) -> bool: return self.value & 0x0400 != 0 @property def no_bind(self) -> bool: return self.value & 0x0800 != 0 @property def appcontainer(self) -> bool: return self.value & 0x1000 != 0 @property def wdm_driver(self) -> bool: return self.value & 0x2000 != 0 @property def guard_cf(self) -> bool: return self.value & 0x4000 != 0 @property def terminal_server_aware(self) -> bool: return self.value & 0x8000 != 0 @dataclass(frozen=True) class ImageOptionalHeader: magic: int major_linkerver: int minor_linkerver: int size_code: int size_initializeddata: int size_uninitializeddata: int address_entrypoint: int basecode: int imagebase: int sectionalignment: int filealignment: int major_osver: int minor_osver: int major_imagever: int minor_imagever: int major_subsystemver: int minor_subsystemver: int win32_vervalue: int size_image: int size_headers: int checksum: int subsystem: ImageOptionalHeaderSubsystem dll_characteristics: ImageOptionalHeaderDLLCharacteristics size_stackreserve: int size_stackcommit: int size_heapreserve: int size_heapcommit: int loaderflags: int number_rvaandsizes: int datadir: tuple[ImageDataDirectory] def __init__(self, f: BytesIO, type: type): if type == IMAGE_OPTIONAL_HEADER32 or type == IMAGE_OPTIONAL_HEADER64: t = type() f.readinto(t) else: raise PEFileError("Invalid type") object.__setattr__(self, "magic", t.Magic) object.__setattr__(self, "major_linkerver", t.MajorLinkerVersion) object.__setattr__(self, "minor_linkerver", t.MinorLinkerVersion) object.__setattr__(self, "size_code", t.SizeOfCode) object.__setattr__(self, "size_initializeddata", t.SizeOfInitializedData) object.__setattr__(self, "size_uninitializeddata", t.SizeOfUninitializedData) object.__setattr__(self, "address_entrypoint", t.AddressOfEntryPoint) object.__setattr__(self, "basecode", t.BaseOfCode) object.__setattr__(self, "imagebase", t.ImageBase) object.__setattr__(self, "sectionalignment", t.SectionAlignment) object.__setattr__(self, "filealignment", t.FileAlignment) object.__setattr__(self, "major_osver", t.MajorOperatingSystemVersion) object.__setattr__(self, "minor_osver", t.MinorOperatingSystemVersion) object.__setattr__(self, "major_imagever", t.MajorImageVersion) object.__setattr__(self, "minor_imagever", t.MinorImageVersion) object.__setattr__(self, "major_subsystemver", t.MajorSubsystemVersion) object.__setattr__(self, "minor_subsystemver", t.MinorSubsystemVersion) object.__setattr__(self, "win32_vervalue", t.Win32VersionValue) object.__setattr__(self, "size_image", t.SizeOfImage) object.__setattr__(self, "size_headers", t.SizeOfHeaders) object.__setattr__(self, "checksum", t.CheckSum) object.__setattr__(self, "subsystem", ImageOptionalHeaderSubsystem(t.Subsystem)) object.__setattr__(self, "dll_characteristics", ImageOptionalHeaderDLLCharacteristics(t.DllCharacteristics)) object.__setattr__(self, "size_stackreserve", t.SizeOfStackReserve) object.__setattr__(self, "size_stackcommit", t.SizeOfStackCommit) object.__setattr__(self, "size_heapreserve", t.SizeOfHeapReserve) object.__setattr__(self, "size_heapcommit", t.SizeOfHeapCommit) object.__setattr__(self, "loaderflags", t.LoaderFlags) object.__setattr__(self, "number_rvaandsizes", t.NumberOfRvaAndSizes) object.__setattr__(self, "datadir", tuple(ImageDataDirectory(dir) for dir in t.DataDirectory)) @property def datadir_export(self) -> ImageDataDirectory: return self.datadir[0] @property def datadir_import(self) -> ImageDataDirectory: return self.datadir[1] @property def datadir_resource(self) -> ImageDataDirectory: return self.datadir[2] @property def datadir_exception(self) -> ImageDataDirectory: return self.datadir[3] @property def datadir_security(self) -> ImageDataDirectory: return self.datadir[4] @property def datadir_basereloc(self) -> ImageDataDirectory: return self.datadir[5] @property def datadir_debug(self) -> ImageDataDirectory: return self.datadir[6] @property def datadir_architecture(self) -> ImageDataDirectory: return self.datadir[7] @property def datadir_globalptr(self) -> ImageDataDirectory: return self.datadir[8] @property def datadir_tls(self) -> ImageDataDirectory: return self.datadir[9] @property def datadir_load_config(self) -> ImageDataDirectory: return self.datadir[10] @property def datadir_bound_import(self) -> ImageDataDirectory: return self.datadir[11] @property def datadir_delay_iat(self) -> ImageDataDirectory: return self.datadir[12] @property def datadir_delay_import(self) -> ImageDataDirectory: return self.datadir[13] @property def datadir_com_desc(self) -> ImageDataDirectory: return self.datadir[14] @dataclass(frozen=True) class ImageSectionHeader: name: str virtual_size: int va: int size_of_rawdata: int pointer_to_rawdata: int pointer_to_relocations: int pointer_to_linenumbers: int number_of_relocations: int number_of_linenumbers: int characteristics: int def __init__(self, f: BytesIO): t = IMAGE_SECTION_HEADER() f.readinto(t) object.__setattr__(self, "name", bytes(t.Name).decode("utf-8").rstrip('\0')) object.__setattr__(self, "virtual_size", t.VirtualSize) object.__setattr__(self, "va", t.VirtualAddress) object.__setattr__(self, "size_of_rawdata", t.SizeOfRawData) object.__setattr__(self, "pointer_to_rawdata", t.PointerToRawData) object.__setattr__(self, "pointer_to_relocations", t.PointerToRelocations) object.__setattr__(self, "pointer_to_linenumbers", t.PointerToLinenumbers) object.__setattr__(self, "number_of_relocations", t.NumberOfRelocations) object.__setattr__(self, "number_of_linenumbers", t.NumberOfLinenumbers) object.__setattr__(self, "characteristics", t.Characteristics) @dataclass(frozen=True) class ImageImportDescriptor: characteristics: int timedatestamp: int forwarder_chain: int name: str name_rva: int firsthunk_rva: int def __init__(self, pefile: "PEFileInfo"): t = IMAGE_IMPORT_DESCRIPTOR() pefile.readinto(t) with pefile.filepointer_saver(): object.__setattr__(self, "characteristics", t.Characteristics) object.__setattr__(self, "timedatestamp", t.TimeDateStamp) object.__setattr__(self, "forwarder_chain", t.ForwarderChain) object.__setattr__(self, "name_rva", t.Name) object.__setattr__(self, "firsthunk_rva", t.FirstThunk) if self.characteristics == 0: return object.__setattr__(self, "name", pefile.read_nullterminated_utf8_rva(self.name_rva)) @dataclass(frozen=True) class ImageThunkData: ordinal: int|None = None data_rva: int|None = None name: str|None = None def __init__(self, pefile: "PEFileInfo", type: type): t = type() pefile.readinto(t) if t.Value == 0: return elif type == IMAGE_THUNK_DATA32: if t.Value & 0x80000000 != 0: object.__setattr__(self, "ordinal", t.Value & 0xffff) else: object.__setattr__(self, "data_rva", t.Value) elif type == IMAGE_THUNK_DATA64: if t.Value & 0x8000000000000000 != 0: object.__setattr__(self, "ordinal", t.Value & 0xffff) else: object.__setattr__(self, "data_rva", t.Value) else: raise PEFileError("Invalid operation.") if self.data_rva is not None: with pefile.filepointer_saver(): # IMAGE_IMPORT_BY_NAME pefile.seek_rva(self.data_rva) object.__setattr__(self, "ordinal", int.from_bytes(pefile.read(2), "little")) object.__setattr__(self, "name", pefile.read_nullterminated_utf8()) @dataclass(frozen=True) class ImageExportDirectory: characteristics: int timedatestamp: datetime majorver: int minorver: int name_rva: int name: str base: int funcs: tuple[int] name_rvas: tuple[int] names: tuple[str] nameordinals: tuple[int] funcs_rva: int names_rva: int nameordinals_rva: int def __init__(self, pefile: "PEFileInfo"): if pefile.optional_header.datadir_export.va == 0: return t = IMAGE_EXPORT_DIRECTORY() pefile.seek_rva(pefile.optional_header.datadir_export.va) pefile.readinto(t) object.__setattr__(self, "characteristics", t.Characteristics) object.__setattr__(self, "timedatestamp", datetime.fromtimestamp(t.TimeDateStamp)) object.__setattr__(self, "majorver", t.MajorVersion) object.__setattr__(self, "minorver", t.MinorVersion) object.__setattr__(self, "name_rva", t.Name) object.__setattr__(self, "name", pefile.read_nullterminated_utf8_rva(self.name_rva)) object.__setattr__(self, "base", t.Base) object.__setattr__(self, "funcs_rva", t.AddressOfFunctions) object.__setattr__(self, "names_rva", t.AddressOfNames) object.__setattr__(self, "nameordinals_rva", t.AddressOfNameOrdinals) # funcs int_size = 4 if pefile.has_nt_headers32 else 8 pefile.seek_rva(self.funcs_rva) object.__setattr__(self, "funcs", tuple(int.from_bytes(pefile.read(int_size), "little") for i in range(t.NumberOfFunctions))) # names RVA pefile.seek_rva(self.names_rva) object.__setattr__(self, "names_rva", tuple(int.from_bytes(pefile.read(4), "little") for i in range(t.NumberOfNames))) #names object.__setattr__(self, "names", tuple(pefile.read_nullterminated_utf8_rva(rva) for rva in self.names_rva)) # name ordinals pefile.seek_rva(self.nameordinals_rva) object.__setattr__(self, "nameordinals", tuple(int.from_bytes(pefile.read(2), "little") for i in range(t.NumberOfNames))) class PEFileInfo: __IMAGE_NT_OPTIONAL_HDR32_MAGIC: ClassVar[int] = 0x10b __IMAGE_NT_OPTIONAL_HDR64_MAGIC: ClassVar[int] = 0x20b __f: BytesIO __dos_hdr: ImageDOSHeader __nt_sign: int __file_hdr: ImageFileHeader __opt_hdr: IMAGE_OPTIONAL_HEADER32|IMAGE_OPTIONAL_HEADER64 __sec_hdrs: tuple[ImageSectionHeader] def __init__(self, path: str): self.__f = f = open(path, "rb") self.__dos_hdr = ImageDOSHeader(f) if self.__dos_hdr.magic != b"MZ": raise PEFileError("Invalid PE file.") # IMAGE_NT_HEADERSの読み込み f.seek(self.__dos_hdr.lfanew, 0) self.__nt_sign = int.from_bytes(f.read(4), "little") if self.__nt_sign != 17744: raise PEFileError("Invalid PE file") self.__file_hdr = ImageFileHeader(f) # 対応機種は無視してオプションヘッダーのサイズとマジックナンバーで判別します。 if self.__file_hdr.size_of_optionalheader == ctypes.sizeof(IMAGE_OPTIONAL_HEADER32): self.__opt_hdr = ImageOptionalHeader(f, IMAGE_OPTIONAL_HEADER32) if self.__opt_hdr.magic != self.__IMAGE_NT_OPTIONAL_HDR32_MAGIC: raise PEFileError("Invalid PE optional header.") elif self.__file_hdr.size_of_optionalheader == ctypes.sizeof(IMAGE_OPTIONAL_HEADER64): self.__opt_hdr = ImageOptionalHeader(f, IMAGE_OPTIONAL_HEADER64) if self.__opt_hdr.magic != self.__IMAGE_NT_OPTIONAL_HDR64_MAGIC: raise PEFileError("Invalid PE optional header.") else: raise PEFileError("Invalid or not-supported PE optional header.") # IMAGE_SECTION_HEADER self.__sec_hdrs = tuple( ImageSectionHeader(f) for i in range(self.__file_hdr.number_of_sections)) def __enter__(self): return self def __exit__(self, *args): self.__f.close() return False def seek(self, offset: int, whence: int) -> int: return self.__f.seek(offset, whence) def seek_rva(self, rva: int) -> int: return self.seek(self.rva_to_offset(rva), 0) def read(self, size: int|None) -> bytes: return self.__f.read(size) def read_rva(self, size: int|None, rva: int) -> bytes: self.__f.seek(self.rva_to_offset(rva), 0) return self.__f.read(size) def readinto(self, buffer) -> int: return self.__f.readinto(buffer) def readinto_rva(self, buffer, rva: int) -> int: self.__f.seek(self.rva_to_offset(rva), 0) return self.__f.readinto(buffer) @contextmanager def filepointer_saver(self): x = self.__f.tell() yield self.__f.seek(x, 0) @property def dos_header(self) -> ImageDOSHeader: return self.__dos_hdr @property def nt_signature(self) -> int: return self.__nt_sign @property def file_header(self) -> ImageFileHeader: return self.__file_hdr @property def optional_header(self) -> ImageOptionalHeader: return self.__opt_hdr @property def has_nt_headers32(self) -> bool: if self.__opt_hdr.magic == self.__IMAGE_NT_OPTIONAL_HDR32_MAGIC: if self.__file_hdr.size_of_optionalheader == ctypes.sizeof(IMAGE_OPTIONAL_HEADER32): return True return False @property def has_nt_headers64(self) -> bool: if self.__opt_hdr.magic == self.__IMAGE_NT_OPTIONAL_HDR64_MAGIC: if self.__file_hdr.size_of_optionalheader == ctypes.sizeof(IMAGE_OPTIONAL_HEADER64): return True return False @property def section_headers(self) -> tuple[ImageSectionHeader]: return self.__sec_hdrs @property def section_names(self) -> tuple[str]: return tuple(hdr.name for hdr in self.__sec_hdrs) def find_section_by_name(self, name) -> ImageSectionHeader: for sec in self.section_headers: if sec.name == name: return sec raise PEFileError("Invalid section index.") def find_section_for_rva(self, rva: int) -> ImageSectionHeader: for sec in self.section_headers: if sec.va <= rva <= sec.va + sec.virtual_size: return sec raise PEFileError("Invalid RVA.") def rva_to_offset(self, rva: int) -> int: sec = self.find_section_for_rva(rva) return rva - sec.va + sec.pointer_to_rawdata def read_nullterminated_utf8(self, expand: int = 256) -> str: s = "" while self.__f: data = self.__f.read(expand) i = data.index(0) if i == -1: s = s + data.decode("utf-8") continue s = s + data[0:i].decode("utf-8") break return s def read_nullterminated_utf8_rva(self, rva: int, expand: int = 256) -> str: offset = self.rva_to_offset(rva) self.__f.seek(offset, 0) return self.read_nullterminated_utf8(expand) def enum_import_descriptors(self) -> Iterator[ImageImportDescriptor]: self.__f.seek(self.rva_to_offset(self.optional_header.datadir_import.va), 0) l = [] while True: desc = ImageImportDescriptor(self) if desc.characteristics == 0: break yield desc def get_import_descriptors(self) -> tuple[ImageImportDescriptor]: return tuple(self.enum_import_descriptors()) def enum_import_thunks(self, desc: ImageImportDescriptor) -> Iterator[ImageThunkData]: self.__f.seek(self.rva_to_offset(desc.firsthunk_rva)) l = [] thunk_type = IMAGE_THUNK_DATA32 if self.has_nt_headers32 else IMAGE_THUNK_DATA64 while True: t = ImageThunkData(self, thunk_type) if t.ordinal is None and t.data_rva is None: break l.append(t) return tuple(l) def enum_original_import_thunks(self, desc: ImageImportDescriptor) -> Iterator[ImageThunkData]: self.__f.seek(self.rva_to_offset(desc.characteristics)) l = [] thunk_type = IMAGE_THUNK_DATA32 if self.has_nt_headers32 else IMAGE_THUNK_DATA64 while True: t = ImageThunkData(self, thunk_type) if t.ordinal is None and t.data_rva is None: break l.append(t) return tuple(l) def get_import_thunks(self, desc: ImageImportDescriptor) -> tuple[ImageThunkData]: return tuple(self.enum_import_thunks(desc)) def get_original_import_thunks(self, desc: ImageImportDescriptor) -> tuple[ImageThunkData]: return tuple(self.enum_original_import_thunks(desc)) def get_export_directory(self) -> ImageExportDirectory|None: expdir = ImageExportDirectory(self) return expdir if hasattr(expdir, "characteristics") else None
#pefileinfo_nativestructure.py import ctypes class IMAGE_DOS_HEADER(ctypes.LittleEndianStructure): _fields_ = ( ("e_magic", ctypes.c_char*2), ("e_cblp", ctypes.c_uint16), ("e_cp", ctypes.c_uint16), ("e_crlc", ctypes.c_uint16), ("e_cparhdr", ctypes.c_uint16), ("e_minalloc", ctypes.c_uint16), ("e_maxalloc", ctypes.c_uint16), ("e_ss", ctypes.c_uint16), ("e_sp", ctypes.c_uint16), ("e_csum", ctypes.c_uint16), ("e_ip", ctypes.c_uint16), ("e_cs", ctypes.c_uint16), ("e_lfarlc", ctypes.c_uint16), ("e_ovno", ctypes.c_uint16), ("e_res", ctypes.c_uint16*4), ("e_oemid", ctypes.c_uint16), ("e_oeminfo", ctypes.c_uint16), ("e_res2", ctypes.c_uint16*10), ("e_lfanew", ctypes.c_uint16), ) class IMAGE_FILE_HEADER(ctypes.LittleEndianStructure): _fields_ = ( ("Machine", ctypes.c_uint16), ("NumberOfSections", ctypes.c_uint16), ("TimeDataStamp", ctypes.c_uint32), ("PointerToSymbolTable", ctypes.c_uint32), ("NumberOfSymbols", ctypes.c_uint32), ("SizeOfOptionalHeader", ctypes.c_uint16), ("Characteristics", ctypes.c_uint16), ) class IMAGE_DATA_DIRECTORY(ctypes.LittleEndianStructure): _fields_ = ( ("VirtualAddress", ctypes.c_uint32), ("Size", ctypes.c_uint32), ) class IMAGE_OPTIONAL_HEADER32(ctypes.LittleEndianStructure): _fields_ = ( ("Magic", ctypes.c_uint16), ("MajorLinkerVersion", ctypes.c_uint8), ("MinorLinkerVersion", ctypes.c_uint8), ("SizeOfCode", ctypes.c_uint32), ("SizeOfInitializedData", ctypes.c_uint32), ("SizeOfUninitializedData", ctypes.c_uint32), ("AddressOfEntryPoint", ctypes.c_uint32), ("BaseOfCode", ctypes.c_uint32), ("BaseOfData", ctypes.c_uint32), ("ImageBase", ctypes.c_uint32), ("SectionAlignment", ctypes.c_uint32), ("FileAlignment", ctypes.c_uint32), ("MajorOperatingSystemVersion", ctypes.c_uint16), ("MinorOperatingSystemVersion", ctypes.c_uint16), ("MajorImageVersion", ctypes.c_uint16), ("MinorImageVersion", ctypes.c_uint16), ("MajorSubsystemVersion", ctypes.c_uint16), ("MinorSubsystemVersion", ctypes.c_uint16), ("Win32VersionValue", ctypes.c_uint32), ("SizeOfImage", ctypes.c_uint32), ("SizeOfHeaders", ctypes.c_uint32), ("CheckSum", ctypes.c_uint32), ("Subsystem", ctypes.c_uint16), ("DllCharacteristics", ctypes.c_uint16), ("SizeOfStackReserve", ctypes.c_uint32), ("SizeOfStackCommit", ctypes.c_uint32), ("SizeOfHeapReserve", ctypes.c_uint32), ("SizeOfHeapCommit", ctypes.c_uint32), ("LoaderFlags", ctypes.c_uint32), ("NumberOfRvaAndSizes", ctypes.c_uint32), ("DataDirectory", IMAGE_DATA_DIRECTORY*16), ) class IMAGE_OPTIONAL_HEADER64(ctypes.LittleEndianStructure): _fields_ = ( ("Magic", ctypes.c_uint16), ("MajorLinkerVersion", ctypes.c_uint8), ("MinorLinkerVersion", ctypes.c_uint8), ("SizeOfCode", ctypes.c_uint32), ("SizeOfInitializedData", ctypes.c_uint32), ("SizeOfUninitializedData", ctypes.c_uint32), ("AddressOfEntryPoint", ctypes.c_uint32), ("BaseOfCode", ctypes.c_uint32), ("ImageBase", ctypes.c_uint64), ("SectionAlignment", ctypes.c_uint32), ("FileAlignment", ctypes.c_uint32), ("MajorOperatingSystemVersion", ctypes.c_uint16), ("MinorOperatingSystemVersion", ctypes.c_uint16), ("MajorImageVersion", ctypes.c_uint16), ("MinorImageVersion", ctypes.c_uint16), ("MajorSubsystemVersion", ctypes.c_uint16), ("MinorSubsystemVersion", ctypes.c_uint16), ("Win32VersionValue", ctypes.c_uint32), ("SizeOfImage", ctypes.c_uint32), ("SizeOfHeaders", ctypes.c_uint32), ("CheckSum", ctypes.c_uint32), ("Subsystem", ctypes.c_uint16), ("DllCharacteristics", ctypes.c_uint16), ("SizeOfStackReserve", ctypes.c_uint64), ("SizeOfStackCommit", ctypes.c_uint64), ("SizeOfHeapReserve", ctypes.c_uint64), ("SizeOfHeapCommit", ctypes.c_uint64), ("LoaderFlags", ctypes.c_uint32), ("NumberOfRvaAndSizes", ctypes.c_uint32), ("DataDirectory", IMAGE_DATA_DIRECTORY*16), ) class IMAGE_SECTION_HEADER(ctypes.LittleEndianStructure): _fields_ = ( ("Name", ctypes.c_uint8 * 8), ("VirtualSize", ctypes.c_uint32), ("VirtualAddress", ctypes.c_uint32), ("SizeOfRawData", ctypes.c_uint32), ("PointerToRawData", ctypes.c_uint32), ("PointerToRelocations", ctypes.c_uint32), ("PointerToLinenumbers", ctypes.c_uint32), ("NumberOfRelocations", ctypes.c_uint16), ("NumberOfLinenumbers", ctypes.c_uint16), ("Characteristics", ctypes.c_uint32), ) class IMAGE_IMPORT_DESCRIPTOR(ctypes.LittleEndianStructure): _fields_ = ( ("Characteristics", ctypes.c_uint32), ("TimeDateStamp", ctypes.c_uint32), ("ForwarderChain", ctypes.c_uint32), ("Name", ctypes.c_uint32), ("FirstThunk", ctypes.c_uint32), ) class IMAGE_THUNK_DATA32(ctypes.LittleEndianStructure): _fields_ = ( ("Value", ctypes.c_uint32), ) class IMAGE_THUNK_DATA64(ctypes.LittleEndianStructure): _fields_ = ( ("Value", ctypes.c_uint64), ) class IMAGE_EXPORT_DIRECTORY(ctypes.LittleEndianStructure): _fields_ = ( ("Characteristics", ctypes.c_uint32), ("TimeDateStamp", ctypes.c_uint32), ("MajorVersion", ctypes.c_uint16), ("MinorVersion", ctypes.c_uint16), ("Name", ctypes.c_uint32), ("Base", ctypes.c_uint32), ("NumberOfFunctions", ctypes.c_uint32), ("NumberOfNames", ctypes.c_uint32), ("AddressOfFunctions", ctypes.c_uint32), ("AddressOfNames", ctypes.c_uint32), ("AddressOfNameOrdinals", ctypes.c_uint32), )