Class: Rex::PeParsey::PeBase
- Inherits:
-
Object
- Object
- Rex::PeParsey::PeBase
- Defined in:
- lib/rex/peparsey/pebase.rb
Direct Known Subclasses
Defined Under Namespace
Classes: ConfigHeader, DosHeader, ExportDirectory, ExportEntry, FileHeader, GenericHeader, GenericStruct, HeaderAccessor, ImportDescriptor, ImportEntry, OptionalHeader, OptionalHeader32, OptionalHeader64, RelocationDirectory, RelocationEntry, ResourceDirectory, ResourceEntry, RuntimeFunctionEntry, SectionHeader, TLSHeader, UnwindCode, UnwindInfo
Constant Summary collapse
- IMAGE_DOS_SIGNATURE =
#define IMAGE_DOS_SIGNATURE 0x5A4D // MZ
0x5a4d- IMAGE_DOS_HEADER_SIZE =
64- IMAGE_DOS_HEADER =
Struct
typedef struct _IMAGE_DOS_HEADER { // DOS .EXE header WORD e_magic; // Magic number WORD e_cblp; // Bytes on last page of file WORD e_cp; // Pages in file WORD e_crlc; // Relocations WORD e_cparhdr; // Size of header in paragraphs WORD e_minalloc; // Minimum extra paragraphs needed WORD e_maxalloc; // Maximum extra paragraphs needed WORD e_ss; // Initial (relative) SS value WORD e_sp; // Initial SP value WORD e_csum; // Checksum WORD e_ip; // Initial IP value WORD e_cs; // Initial (relative) CS value WORD e_lfarlc; // File address of relocation table WORD e_ovno; // Overlay number WORD e_res[4]; // Reserved words WORD e_oemid; // OEM identifier (for e_oeminfo) WORD e_oeminfo; // OEM information; e_oemid specific WORD e_res2[10]; // Reserved words LONG e_lfanew; // File address of new exe header } IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER; Rex::Struct2::CStructTemplate.new( [ 'uint16v', 'e_magic', IMAGE_DOS_SIGNATURE ], [ 'uint16v', 'e_cblp', 0 ], [ 'uint16v', 'e_cp', 0 ], [ 'uint16v', 'e_crlc', 0 ], [ 'uint16v', 'e_cparhdr', 0 ], [ 'uint16v', 'e_minalloc', 0 ], [ 'uint16v', 'e_maxalloc', 0 ], [ 'uint16v', 'e_ss', 0 ], [ 'uint16v', 'e_sp', 0 ], [ 'uint16v', 'e_csum', 0 ], [ 'uint16v', 'e_ip', 0 ], [ 'uint16v', 'e_cs', 0 ], [ 'uint16v', 'e_lfarlc', 0 ], [ 'uint16v', 'e_ovno', 0 ], [ 'template', 'e_res', Rex::Struct2::CStructTemplate.new( [ 'uint16v', 'e_res_0', 0 ], [ 'uint16v', 'e_res_1', 0 ], [ 'uint16v', 'e_res_2', 0 ], [ 'uint16v', 'e_res_3', 0 ] )], [ 'uint16v', 'e_oemid', 0 ], [ 'uint16v', 'e_oeminfo', 0 ], [ 'template', 'e_res2', Rex::Struct2::CStructTemplate.new( [ 'uint16v', 'e_res2_0', 0 ], [ 'uint16v', 'e_res2_1', 0 ], [ 'uint16v', 'e_res2_2', 0 ], [ 'uint16v', 'e_res2_3', 0 ], [ 'uint16v', 'e_res2_4', 0 ], [ 'uint16v', 'e_res2_5', 0 ], [ 'uint16v', 'e_res2_6', 0 ], [ 'uint16v', 'e_res2_7', 0 ], [ 'uint16v', 'e_res2_8', 0 ], [ 'uint16v', 'e_res2_9', 0 ] )], [ 'uint32v', 'e_lfanew', 0 ] )
- IMAGE_NT_SIGNATURE =
#define IMAGE_NT_SIGNATURE 0x00004550 // PE00
0x00004550- IMAGE_FILE_MACHINE_I386 =
#define IMAGE_FILE_MACHINE_I386 0x014c // Intel 386.
0x014c- IMAGE_FILE_MACHINE_IA64 =
#define IMAGE_FILE_MACHINE_IA64 0x0200 // Intel 64
0x0200- IMAGE_FILE_MACHINE_ALPHA64 =
#define IMAGE_FILE_MACHINE_ALPHA64 0x0284 // ALPHA64
0x0284- IMAGE_FILE_MACHINE_AMD64 =
#define IMAGE_FILE_MACHINE_AMD64 0x8664 // AMD64 (K8)
0x8664- IMAGE_FILE_MACHINE_ARM64 =
#define IMAGE_FILE_MACHINE_ARM64 0xaa64 // ARM64
0xaa64- IMAGE_FILE_HEADER_SIZE =
#define IMAGE_SIZEOF_FILE_HEADER 20
20+4
- IMAGE_FILE_HEADER =
C struct defining the PE file header
typedef struct _IMAGE_FILE_HEADER { WORD Machine; WORD NumberOfSections; DWORD TimeDateStamp; DWORD PointerToSymbolTable; DWORD NumberOfSymbols; WORD SizeOfOptionalHeader; WORD Characteristics; } IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER; Rex::Struct2::CStructTemplate.new( # not really in the header, but easier for us this way [ 'uint32v', 'NtSignature', 0 ], [ 'uint16v', 'Machine', 0 ], [ 'uint16v', 'NumberOfSections', 0 ], [ 'uint32v', 'TimeDateStamp', 0 ], [ 'uint32v', 'PointerToSymbolTable', 0 ], [ 'uint32v', 'NumberOfSymbols', 0 ], [ 'uint16v', 'SizeOfOptionalHeader', 0 ], [ 'uint16v', 'Characteristics', 0 ] )
- SUPPORTED_MACHINES =
[ IMAGE_FILE_MACHINE_I386, IMAGE_FILE_MACHINE_IA64, IMAGE_FILE_MACHINE_ALPHA64, IMAGE_FILE_MACHINE_AMD64, IMAGE_FILE_MACHINE_ARM64 ]
- IMAGE_ORDINAL_FLAG32 =
0x80000000- IMAGE_IMPORT_DESCRIPTOR_SIZE =
20- IMAGE_IMPORT_DESCRIPTOR =
Struct
typedef struct _IMAGE_IMPORT_DESCRIPTOR { union { DWORD Characteristics; // 0 for terminating null import descriptor DWORD OriginalFirstThunk; // RVA to original unbound IAT (PIMAGE_THUNK_DATA) }; DWORD 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) DWORD ForwarderChain; // -1 if no forwarders DWORD Name; DWORD FirstThunk; // RVA to IAT (if bound this IAT has actual addresses) } IMAGE_IMPORT_DESCRIPTOR; Rex::Struct2::CStructTemplate.new( [ 'uint32v', 'OriginalFirstThunk', 0 ], [ 'uint32v', 'TimeDateStamp', 0 ], [ 'uint32v', 'ForwarderChain', 0 ], [ 'uint32v', 'Name', 0 ], [ 'uint32v', 'FirstThunk', 0 ] )
- IMAGE_EXPORT_DESCRIPTOR_SIZE =
sizeof(struct _IMAGE_EXPORT_DESCRIPTOR)
40- IMAGE_EXPORT_DESCRIPTOR =
Struct defining the export table
typedef struct _IMAGE_EXPORT_DIRECTORY { DWORD Characteristics; DWORD TimeDateStamp; WORD MajorVersion; WORD MinorVersion; DWORD Name; DWORD Base; DWORD NumberOfFunctions; DWORD NumberOfNames; DWORD AddressOfFunctions; // RVA from base of image DWORD AddressOfNames; // RVA from base of image DWORD AddressOfNameOrdinals; // RVA from base of image } IMAGE_EXPORT_DIRECTORY, *PIMAGE_EXPORT_DIRECTORY; Rex::Struct2::CStructTemplate.new( [ 'uint32v', 'Characteristics', 0 ], [ 'uint32v', 'TimeDateStamp', 0 ], [ 'uint16v', 'MajorVersion', 0 ], [ 'uint16v', 'MinorVersion', 0 ], [ 'uint32v', 'Name', 0 ], [ 'uint32v', 'Base', 0 ], [ 'uint32v', 'NumberOfFunctions', 0 ], [ 'uint32v', 'NumberOfNames', 0 ], [ 'uint32v', 'AddressOfFunctions', 0 ], [ 'uint32v', 'AddressOfNames', 0 ], [ 'uint32v', 'AddressOfNameOrdinals', 0 ] )
- IMAGE_NUMBEROF_DIRECTORY_ENTRIES =
16- IMAGE_DATA_DIRECTORY_SIZE =
8- IMAGE_DIRECTORY_ENTRY_EXPORT =
0- IMAGE_DIRECTORY_ENTRY_IMPORT =
1- IMAGE_DIRECTORY_ENTRY_RESOURCE =
2- IMAGE_DIRECTORY_ENTRY_EXCEPTION =
3- IMAGE_DIRECTORY_ENTRY_SECURITY =
4- IMAGE_DIRECTORY_ENTRY_BASERELOC =
5- IMAGE_DIRECTORY_ENTRY_DEBUG =
6- IMAGE_DIRECTORY_ENTRY_COPYRIGHT =
7- IMAGE_DIRECTORY_ENTRY_ARCHITECTURE =
7- IMAGE_DIRECTORY_ENTRY_GLOBALPTR =
8- IMAGE_DIRECTORY_ENTRY_TLS =
9- IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG =
10- IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT =
11- IMAGE_DIRECTORY_ENTRY_IAT =
12- IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT =
13- IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR =
14- IMAGE_DATA_DIRECTORY =
Struct
typedef struct _IMAGE_DATA_DIRECTORY { DWORD VirtualAddress; DWORD Size; } IMAGE_DATA_DIRECTORY, *PIMAGE_DATA_DIRECTORY; Rex::Struct2::CStructTemplate.new( [ 'uint32v', 'VirtualAddress', 0 ], [ 'uint32v', 'Size', 0 ] )
- IMAGE_NT_OPTIONAL_HDR32_MAGIC =
Struct
typedef struct _IMAGE_OPTIONAL_HEADER { // // Standard fields. // WORD Magic; BYTE MajorLinkerVersion; BYTE MinorLinkerVersion; DWORD SizeOfCode; DWORD SizeOfInitializedData; DWORD SizeOfUninitializedData; DWORD AddressOfEntryPoint; DWORD BaseOfCode; DWORD BaseOfData; // // NT additional fields. // DWORD ImageBase; DWORD SectionAlignment; DWORD FileAlignment; WORD MajorOperatingSystemVersion; WORD MinorOperatingSystemVersion; WORD MajorImageVersion; WORD MinorImageVersion; WORD MajorSubsystemVersion; WORD MinorSubsystemVersion; DWORD Win32VersionValue; DWORD SizeOfImage; DWORD SizeOfHeaders; DWORD CheckSum; WORD Subsystem; WORD DllCharacteristics; DWORD SizeOfStackReserve; DWORD SizeOfStackCommit; DWORD SizeOfHeapReserve; DWORD SizeOfHeapCommit; DWORD LoaderFlags; DWORD NumberOfRvaAndSizes; IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES]; } IMAGE_OPTIONAL_HEADER32, *PIMAGE_OPTIONAL_HEADER32; #define IMAGE_NT_OPTIONAL_HDR32_MAGIC 0x10b #define IMAGE_SIZEOF_NT_OPTIONAL32_HEADER 224 0x10b- IMAGE_SIZEOF_NT_OPTIONAL32_HEADER =
224- IMAGE_OPTIONAL_HEADER32 =
Rex::Struct2::CStructTemplate.new( [ 'uint16v', 'Magic', 0 ], [ 'uint8', 'MajorLinkerVersion', 0 ], [ 'uint8', 'MinorLinkerVersion', 0 ], [ 'uint32v', 'SizeOfCode', 0 ], [ 'uint32v', 'SizeOfInitializeData', 0 ], [ 'uint32v', 'SizeOfUninitializeData', 0 ], [ 'uint32v', 'AddressOfEntryPoint', 0 ], [ 'uint32v', 'BaseOfCode', 0 ], [ 'uint32v', 'BaseOfData', 0 ], [ 'uint32v', 'ImageBase', 0 ], [ 'uint32v', 'SectionAlignment', 0 ], [ 'uint32v', 'FileAlignment', 0 ], [ 'uint16v', 'MajorOperatingSystemVersion', 0 ], [ 'uint16v', 'MinorOperatingSystemVersion', 0 ], [ 'uint16v', 'MajorImageVersion', 0 ], [ 'uint16v', 'MinorImageVersion', 0 ], [ 'uint16v', 'MajorSubsystemVersion', 0 ], [ 'uint16v', 'MinorSubsystemVersion', 0 ], [ 'uint32v', 'Win32VersionValue', 0 ], [ 'uint32v', 'SizeOfImage', 0 ], [ 'uint32v', 'SizeOfHeaders', 0 ], [ 'uint32v', 'CheckSum', 0 ], [ 'uint16v', 'Subsystem', 0 ], [ 'uint16v', 'DllCharacteristics', 0 ], [ 'uint32v', 'SizeOfStackReserve', 0 ], [ 'uint32v', 'SizeOfStackCommit', 0 ], [ 'uint32v', 'SizeOfHeapReserve', 0 ], [ 'uint32v', 'SizeOfHeapCommit', 0 ], [ 'uint32v', 'LoaderFlags', 0 ], [ 'uint32v', 'NumberOfRvaAndSizes', 0 ], [ 'template', 'DataDirectory', Rex::Struct2::CStructTemplate.new( [ 'template', 'DataDirectoryEntry_0', IMAGE_DATA_DIRECTORY ], [ 'template', 'DataDirectoryEntry_1', IMAGE_DATA_DIRECTORY ], [ 'template', 'DataDirectoryEntry_2', IMAGE_DATA_DIRECTORY ], [ 'template', 'DataDirectoryEntry_3', IMAGE_DATA_DIRECTORY ], [ 'template', 'DataDirectoryEntry_4', IMAGE_DATA_DIRECTORY ], [ 'template', 'DataDirectoryEntry_5', IMAGE_DATA_DIRECTORY ], [ 'template', 'DataDirectoryEntry_6', IMAGE_DATA_DIRECTORY ], [ 'template', 'DataDirectoryEntry_7', IMAGE_DATA_DIRECTORY ], [ 'template', 'DataDirectoryEntry_8', IMAGE_DATA_DIRECTORY ], [ 'template', 'DataDirectoryEntry_9', IMAGE_DATA_DIRECTORY ], [ 'template', 'DataDirectoryEntry_10', IMAGE_DATA_DIRECTORY ], [ 'template', 'DataDirectoryEntry_11', IMAGE_DATA_DIRECTORY ], [ 'template', 'DataDirectoryEntry_12', IMAGE_DATA_DIRECTORY ], [ 'template', 'DataDirectoryEntry_13', IMAGE_DATA_DIRECTORY ], [ 'template', 'DataDirectoryEntry_14', IMAGE_DATA_DIRECTORY ], [ 'template', 'DataDirectoryEntry_15', IMAGE_DATA_DIRECTORY ] )] )
- IMAGE_NT_OPTIONAL_HDR64_MAGIC =
#define IMAGE_SIZEOF_NT_OPTIONAL64_HEADER 240
0x20b- IMAGE_SIZEOF_NT_OPTIONAL64_HEADER =
#define IMAGE_NT_OPTIONAL_HDR64_MAGIC 0x20b
240- IMAGE_OPTIONAL_HEADER64 =
Struct
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; USHORT Subsystem; USHORT DllCharacteristics; ULONGLONG SizeOfStackReserve; ULONGLONG SizeOfStackCommit; ULONGLONG SizeOfHeapReserve; ULONGLONG SizeOfHeapCommit; ULONG LoaderFlags; ULONG NumberOfRvaAndSizes; IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES]; } IMAGE_OPTIONAL_HEADER64, *PIMAGE_OPTIONAL_HEADER64; Rex::Struct2::CStructTemplate.new( [ 'uint16v', 'Magic', 0 ], [ 'uint8', 'MajorLinkerVersion', 0 ], [ 'uint8', 'MinorLinkerVersion', 0 ], [ 'uint32v', 'SizeOfCode', 0 ], [ 'uint32v', 'SizeOfInitializeData', 0 ], [ 'uint32v', 'SizeOfUninitializeData', 0 ], [ 'uint32v', 'AddressOfEntryPoint', 0 ], [ 'uint32v', 'BaseOfCode', 0 ], [ 'uint64v', 'ImageBase', 0 ], [ 'uint32v', 'SectionAlignment', 0 ], [ 'uint32v', 'FileAlignment', 0 ], [ 'uint16v', 'MajorOperatingSystemVersion', 0 ], [ 'uint16v', 'MinorOperatingSystemVersion', 0 ], [ 'uint16v', 'MajorImageVersion', 0 ], [ 'uint16v', 'MinorImageVersion', 0 ], [ 'uint16v', 'MajorSubsystemVersion', 0 ], [ 'uint16v', 'MinorSubsystemVersion', 0 ], [ 'uint32v', 'Win32VersionValue', 0 ], [ 'uint32v', 'SizeOfImage', 0 ], [ 'uint32v', 'SizeOfHeaders', 0 ], [ 'uint32v', 'CheckSum', 0 ], [ 'uint16v', 'Subsystem', 0 ], [ 'uint16v', 'DllCharacteristics', 0 ], [ 'uint64v', 'SizeOfStackReserve', 0 ], [ 'uint64v', 'SizeOfStackCommit', 0 ], [ 'uint64v', 'SizeOfHeapReserve', 0 ], [ 'uint64v', 'SizeOfHeapCommit', 0 ], [ 'uint32v', 'LoaderFlags', 0 ], [ 'uint32v', 'NumberOfRvaAndSizes', 0 ], [ 'template', 'DataDirectory', Rex::Struct2::CStructTemplate.new( [ 'template', 'DataDirectoryEntry_0', IMAGE_DATA_DIRECTORY ], [ 'template', 'DataDirectoryEntry_1', IMAGE_DATA_DIRECTORY ], [ 'template', 'DataDirectoryEntry_2', IMAGE_DATA_DIRECTORY ], [ 'template', 'DataDirectoryEntry_3', IMAGE_DATA_DIRECTORY ], [ 'template', 'DataDirectoryEntry_4', IMAGE_DATA_DIRECTORY ], [ 'template', 'DataDirectoryEntry_5', IMAGE_DATA_DIRECTORY ], [ 'template', 'DataDirectoryEntry_6', IMAGE_DATA_DIRECTORY ], [ 'template', 'DataDirectoryEntry_7', IMAGE_DATA_DIRECTORY ], [ 'template', 'DataDirectoryEntry_8', IMAGE_DATA_DIRECTORY ], [ 'template', 'DataDirectoryEntry_9', IMAGE_DATA_DIRECTORY ], [ 'template', 'DataDirectoryEntry_10', IMAGE_DATA_DIRECTORY ], [ 'template', 'DataDirectoryEntry_11', IMAGE_DATA_DIRECTORY ], [ 'template', 'DataDirectoryEntry_12', IMAGE_DATA_DIRECTORY ], [ 'template', 'DataDirectoryEntry_13', IMAGE_DATA_DIRECTORY ], [ 'template', 'DataDirectoryEntry_14', IMAGE_DATA_DIRECTORY ], [ 'template', 'DataDirectoryEntry_15', IMAGE_DATA_DIRECTORY ] )] )
- IMAGE_SIZEOF_SECTION_HEADER =
#define IMAGE_SIZEOF_SECTION_HEADER 40
40- IMAGE_SECTION_HEADER =
Struct
typedef struct _IMAGE_SECTION_HEADER { BYTE Name[IMAGE_SIZEOF_SHORT_NAME]; union { DWORD PhysicalAddress; DWORD VirtualSize; } Misc; DWORD VirtualAddress; DWORD SizeOfRawData; DWORD PointerToRawData; DWORD PointerToRelocations; DWORD PointerToLinenumbers; WORD NumberOfRelocations; WORD NumberOfLinenumbers; DWORD Characteristics; } IMAGE_SECTION_HEADER, *PIMAGE_SECTION_HEADER; Rex::Struct2::CStructTemplate.new( [ 'string', 'Name', 8, '' ], [ 'uint32v', 'Misc', 0 ], [ 'uint32v', 'VirtualAddress', 0 ], [ 'uint32v', 'SizeOfRawData', 0 ], [ 'uint32v', 'PointerToRawData', 0 ], [ 'uint32v', 'PointerToRelocations', 0 ], [ 'uint32v', 'NumberOfRelocations', 0 ], [ 'uint32v', 'NumberOfLineNumbers', 0 ], [ 'uint32v', 'Characteristics', 0 ] )
- IMAGE_SIZEOF_BASE_RELOCATION =
#define IMAGE_SIZEOF_BASE_RELOCATION 8
8- IMAGE_BASE_RELOCATION =
Struct
typedef struct _IMAGE_BASE_RELOCATION { DWORD VirtualAddress; DWORD SizeOfBlock; // WORD TypeOffset[1]; } IMAGE_BASE_RELOCATION; typedef IMAGE_BASE_RELOCATION UNALIGNED * PIMAGE_BASE_RELOCATION; Rex::Struct2::CStructTemplate.new( [ 'uint32v', 'VirtualAddress', 0 ], [ 'uint32v', 'SizeOfBlock', 0 ] )
- IMAGE_BASE_RELOCATION_TYPE_OFFSET =
Rex::Struct2::CStructTemplate.new( [ 'uint16v', 'TypeOffset', 0 ] )
- IMAGE_LOAD_CONFIG_DIRECTORY32 =
Struct
typedef struct { DWORD Size; DWORD TimeDateStamp; WORD MajorVersion; WORD MinorVersion; DWORD GlobalFlagsClear; DWORD GlobalFlagsSet; DWORD CriticalSectionDefaultTimeout; DWORD DeCommitFreeBlockThreshold; DWORD DeCommitTotalFreeThreshold; DWORD LockPrefixTable; // VA DWORD MaximumAllocationSize; DWORD VirtualMemoryThreshold; DWORD ProcessHeapFlags; DWORD ProcessAffinityMask; WORD CSDVersion; WORD Reserved1; DWORD EditList; // VA DWORD SecurityCookie; // VA DWORD SEHandlerTable; // VA DWORD SEHandlerCount; } IMAGE_LOAD_CONFIG_DIRECTORY32, *PIMAGE_LOAD_CONFIG_DIRECTORY32; Rex::Struct2::CStructTemplate.new( [ 'uint32v', 'Size', 0 ], [ 'uint32v', 'TimeDateStamp', 0 ], [ 'uint16v', 'MajorVersion', 0 ], [ 'uint16v', 'MinorVersion', 0 ], [ 'uint32v', 'GlobalFlagsClear', 0 ], [ 'uint32v', 'GlobalFlagsSet', 0 ], [ 'uint32v', 'CriticalSectionDefaultTimeout', 0 ], [ 'uint32v', 'DeCommitFreeBlockThreshold', 0 ], [ 'uint32v', 'DeCommitTotalFreeThreshold', 0 ], [ 'uint32v', 'LockPrefixTable', 0 ], [ 'uint32v', 'MaximumAllocationSize', 0 ], [ 'uint32v', 'VirtualMemoryThreshold', 0 ], [ 'uint32v', 'ProcessHeapFlags', 0 ], [ 'uint32v', 'ProcessAffinityMask', 0 ], [ 'uint16v', 'CSDVersion', 0 ], [ 'uint16v', 'Reserved1', 0 ], [ 'uint32v', 'EditList', 0 ], [ 'uint32v', 'SecurityCookie', 0 ], [ 'uint32v', 'SEHandlerTable', 0 ], [ 'uint32v', 'SEHandlerCount', 0 ] )
- IMAGE_LOAD_CONFIG_DIRECTORY64 =
Struct
typedef struct { 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 Reserved1; ULONGLONG EditList; // VA ULONGLONG SecurityCookie; // VA ULONGLONG SEHandlerTable; // VA ULONGLONG SEHandlerCount; } IMAGE_LOAD_CONFIG_DIRECTORY64, *PIMAGE_LOAD_CONFIG_DIRECTORY64; Rex::Struct2::CStructTemplate.new( [ 'uint32v', 'Size', 0 ], [ 'uint32v', 'TimeDateStamp', 0 ], [ 'uint16v', 'MajorVersion', 0 ], [ 'uint16v', 'MinorVersion', 0 ], [ 'uint32v', 'GlobalFlagsClear', 0 ], [ 'uint32v', 'GlobalFlagsSet', 0 ], [ 'uint32v', 'CriticalSectionDefaultTimeout', 0 ], [ 'uint64v', 'DeCommitFreeBlockThreshold', 0 ], [ 'uint64v', 'DeCommitTotalFreeThreshold', 0 ], [ 'uint64v', 'LockPrefixTable', 0 ], [ 'uint64v', 'MaximumAllocationSize', 0 ], [ 'uint64v', 'VirtualMemoryThreshold', 0 ], [ 'uint64v', 'ProcessAffinityMask', 0 ], [ 'uint32v', 'ProcessHeapFlags', 0 ], [ 'uint16v', 'CSDVersion', 0 ], [ 'uint16v', 'Reserved1', 0 ], [ 'uint64v', 'EditList', 0 ], [ 'uint64v', 'SecurityCookie', 0 ], [ 'uint64v', 'SEHandlerTable', 0 ], [ 'uint64v', 'SEHandlerCount', 0 ] )
- IMAGE_LOAD_TLS_DIRECTORY32 =
Struct
typedef struct { DWORD Size; DWORD TimeDateStamp; WORD MajorVersion; WORD MinorVersion; DWORD GlobalFlagsClear; DWORD GlobalFlagsSet; DWORD CriticalSectionDefaultTimeout; DWORD DeCommitFreeBlockThreshold; DWORD DeCommitTotalFreeThreshold; DWORD LockPrefixTable; // VA DWORD MaximumAllocationSize; DWORD VirtualMemoryThreshold; DWORD ProcessHeapFlags; DWORD ProcessAffinityMask; WORD CSDVersion; WORD Reserved1; DWORD EditList; // VA DWORD SecurityCookie; // VA DWORD SEHandlerTable; // VA DWORD SEHandlerCount; } IMAGE_LOAD_CONFIG_DIRECTORY32, *PIMAGE_LOAD_CONFIG_DIRECTORY32; Rex::Struct2::CStructTemplate.new( [ 'uint32v', 'Size', 0 ], [ 'uint32v', 'TimeDateStamp', 0 ], [ 'uint16v', 'MajorVersion', 0 ], [ 'uint16v', 'MinorVersion', 0 ], [ 'uint32v', 'GlobalFlagsClear', 0 ], [ 'uint32v', 'GlobalFlagsSet', 0 ], [ 'uint32v', 'CriticalSectionDefaultTimeout', 0 ], [ 'uint32v', 'DeCommitFreeBlockThreshold', 0 ], [ 'uint32v', 'DeCommitTotalFreeThreshold', 0 ], [ 'uint32v', 'LockPrefixTable', 0 ], [ 'uint32v', 'MaximumAllocationSize', 0 ], [ 'uint32v', 'VirtualMemoryThreshold', 0 ], [ 'uint32v', 'ProcessHeapFlags', 0 ], [ 'uint32v', 'ProcessAffinityMask', 0 ], [ 'uint16v', 'CSDVersion', 0 ], [ 'uint16v', 'Reserved1', 0 ], [ 'uint32v', 'EditList', 0 ], [ 'uint32v', 'SecurityCookie', 0 ], [ 'uint32v', 'SEHandlerTable', 0 ], [ 'uint32v', 'SEHandlerCount', 0 ] )
- IMAGE_LOAD_TLS_DIRECTORY64 =
Struct
typedef struct { 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 Reserved1; ULONGLONG EditList; // VA ULONGLONG SecurityCookie; // VA ULONGLONG SEHandlerTable; // VA ULONGLONG SEHandlerCount; } IMAGE_LOAD_CONFIG_DIRECTORY64, *PIMAGE_LOAD_CONFIG_DIRECTORY64; Rex::Struct2::CStructTemplate.new( [ 'uint32v', 'Size', 0 ], [ 'uint32v', 'TimeDateStamp', 0 ], [ 'uint16v', 'MajorVersion', 0 ], [ 'uint16v', 'MinorVersion', 0 ], [ 'uint32v', 'GlobalFlagsClear', 0 ], [ 'uint32v', 'GlobalFlagsSet', 0 ], [ 'uint32v', 'CriticalSectionDefaultTimeout', 0 ], [ 'uint64v', 'DeCommitFreeBlockThreshold', 0 ], [ 'uint64v', 'DeCommitTotalFreeThreshold', 0 ], [ 'uint64v', 'LockPrefixTable', 0 ], [ 'uint64v', 'MaximumAllocationSize', 0 ], [ 'uint64v', 'VirtualMemoryThreshold', 0 ], [ 'uint64v', 'ProcessAffinityMask', 0 ], [ 'uint32v', 'ProcessHeapFlags', 0 ], [ 'uint16v', 'CSDVersion', 0 ], [ 'uint16v', 'Reserved1', 0 ], [ 'uint64v', 'EditList', 0 ], [ 'uint64v', 'SecurityCookie', 0 ], [ 'uint64v', 'SEHandlerTable', 0 ], [ 'uint64v', 'SEHandlerCount', 0 ] )
- IMAGE_RUNTIME_FUNCTION_ENTRY_SZ =
Exception directory
12- IMAGE_RUNTIME_FUNCTION_ENTRY =
Struct
typedef struct _IMAGE_RUNTIME_FUNCTION_ENTRY { DWORD BeginAddress; DWORD EndAddress; DWORD UnwindInfoAddress; } _IMAGE_RUNTIME_FUNCTION_ENTRY, *_PIMAGE_RUNTIME_FUNCTION_ENTRY; Rex::Struct2::CStructTemplate.new( [ 'uint32v', 'BeginAddress', 0 ], [ 'uint32v', 'EndAddress', 0 ], [ 'uint32v', 'UnwindInfoAddress', 0 ] )
- UNWIND_INFO_HEADER_SZ =
4- UNWIND_INFO_HEADER =
Rex::Struct2::CStructTemplate.new( [ 'uint8', 'VersionFlags', 0 ], [ 'uint8', 'SizeOfProlog', 0 ], [ 'uint8', 'CountOfCodes', 0 ], [ 'uint8', 'FrameRegisterAndOffset', 0 ] )
- UWOP_PUSH_NONVOL =
1 node
0- UWOP_ALLOC_LARGE =
2 or 3 nodes
1- UWOP_ALLOC_SMALL =
1 node
2- UWOP_SET_FPREG =
1 node
3- UWOP_SAVE_NONVOL =
2 nodes
4- UWOP_SAVE_NONVOL_FAR =
3 nodes
5- UWOP_SAVE_XMM128 =
2 nodes
8- UWOP_SAVE_XMM128_FAR =
3 nodes
9- UWOP_PUSH_MACHFRAME =
1 node
10- UNW_FLAG_EHANDLER =
1- UNW_FLAG_UHANDLER =
2- UNW_FLAG_CHAININFO =
4
Instance Attribute Summary collapse
-
#_config_header ⇒ Object
Returns the value of attribute _config_header.
-
#_dos_header ⇒ Object
Returns the value of attribute _dos_header.
-
#_exception_header ⇒ Object
Returns the value of attribute _exception_header.
-
#_exports_cache ⇒ Object
Returns the value of attribute _exports_cache.
-
#_exports_cached ⇒ Object
Returns the value of attribute _exports_cached.
-
#_file_header ⇒ Object
Returns the value of attribute _file_header.
-
#_imports_cache ⇒ Object
Returns the value of attribute _imports_cache.
-
#_imports_cached ⇒ Object
Returns the value of attribute _imports_cached.
-
#_isource ⇒ Object
instance stuff.
-
#_optional_header ⇒ Object
Returns the value of attribute _optional_header.
-
#_relocations_cache ⇒ Object
Returns the value of attribute _relocations_cache.
-
#_relocations_cached ⇒ Object
Returns the value of attribute _relocations_cached.
-
#_resources_cache ⇒ Object
Returns the value of attribute _resources_cache.
-
#_resources_cached ⇒ Object
Returns the value of attribute _resources_cached.
-
#_section_headers ⇒ Object
Returns the value of attribute _section_headers.
-
#_tls_header ⇒ Object
Returns the value of attribute _tls_header.
-
#hdr ⇒ Object
Returns the value of attribute hdr.
-
#header_section ⇒ Object
Returns the value of attribute header_section.
-
#image_base ⇒ Object
Returns the value of attribute image_base.
-
#sections ⇒ Object
Returns the value of attribute sections.
Class Method Summary collapse
-
._align_offset(offset, alignment) ⇒ Object
Just a stupid routine to round an offset up to it’s alignment.
- ._parse_dos_header(rawdata) ⇒ Object
- ._parse_file_header(rawdata) ⇒ Object
- ._parse_optional_header(rawdata) ⇒ Object
- ._parse_section_headers(rawdata) ⇒ Object
- .new_from_file(filename, disk_backed = false) ⇒ Object
- .new_from_string(data) ⇒ Object
Instance Method Summary collapse
-
#_find_section_by_rva(rva) ⇒ Object
Find a section by an RVA.
- #_load_exception_directory ⇒ Object
- #_load_exports ⇒ Object
- #_load_imports ⇒ Object
- #_load_relocations ⇒ Object
- #_load_resources ⇒ Object
-
#_parse_config_header ⇒ Object
– doesn’t seem to be used – not compatible with 64-bit def self._parse_config_header(rawdata) header = IMAGE_LOAD_CONFIG_DIRECTORY32.make_struct header.from_s(rawdata) ConfigHeader.new(header) end ++.
- #_parse_resource_directory(data, rname = 0, rvalue = 0x80000000, path = '0', pname = nil) ⇒ Object
- #_parse_resource_entry(data, rname, rvalue, path, pname) ⇒ Object
- #_parse_resource_name(data, rname) ⇒ Object
- #_parse_tls_header ⇒ Object
- #_resource_lookup(i) ⇒ Object
- #close ⇒ Object
- #config ⇒ Object
- #exception ⇒ Object
-
#exports ⇒ Object
We lazily parse the exports, and then cache it.
- #file_offset_to_rva(foffset) ⇒ Object
- #file_offset_to_vma(foffset) ⇒ Object
- #find_section_by_rva(rva) ⇒ Object
-
#find_section_by_vma(vma) ⇒ Object
Find a section by a VMA.
-
#imports ⇒ Object
We lazily parse the imports, and then cache it.
- #read_asciiz_rva(rva) ⇒ Object
- #read_asciiz_vma(vma) ⇒ Object
-
#read_rva(rva, length) ⇒ Object
Some convenient methods to read a vma/rva without having the section…
- #read_vma(vma, length) ⇒ Object
-
#relocations ⇒ Object
Base relocations in the hizzy.
-
#resources ⇒ Object
We lazily parse the resources, and then cache them.
- #rva_to_file_offset(rva) ⇒ Object
-
#rva_to_vma(rva) ⇒ Object
Random rva, vma, file offset, section offset, etc conversion routines…
- #tls ⇒ Object
- #update_checksum ⇒ Object
- #valid_rva?(rva) ⇒ Boolean
- #valid_vma?(vma) ⇒ Boolean
- #vma_to_file_offset(vma) ⇒ Object
- #vma_to_rva(vma) ⇒ Object
Instance Attribute Details
#_config_header ⇒ Object
Returns the value of attribute _config_header.
1148 1149 1150 |
# File 'lib/rex/peparsey/pebase.rb', line 1148 def _config_header @_config_header end |
#_dos_header ⇒ Object
Returns the value of attribute _dos_header.
1148 1149 1150 |
# File 'lib/rex/peparsey/pebase.rb', line 1148 def _dos_header @_dos_header end |
#_exception_header ⇒ Object
Returns the value of attribute _exception_header.
1148 1149 1150 |
# File 'lib/rex/peparsey/pebase.rb', line 1148 def _exception_header @_exception_header end |
#_exports_cache ⇒ Object
Returns the value of attribute _exports_cache.
1154 1155 1156 |
# File 'lib/rex/peparsey/pebase.rb', line 1154 def _exports_cache @_exports_cache end |
#_exports_cached ⇒ Object
Returns the value of attribute _exports_cached.
1154 1155 1156 |
# File 'lib/rex/peparsey/pebase.rb', line 1154 def _exports_cached @_exports_cached end |
#_file_header ⇒ Object
Returns the value of attribute _file_header.
1148 1149 1150 |
# File 'lib/rex/peparsey/pebase.rb', line 1148 def _file_header @_file_header end |
#_imports_cache ⇒ Object
Returns the value of attribute _imports_cache.
1153 1154 1155 |
# File 'lib/rex/peparsey/pebase.rb', line 1153 def _imports_cache @_imports_cache end |
#_imports_cached ⇒ Object
Returns the value of attribute _imports_cached.
1153 1154 1155 |
# File 'lib/rex/peparsey/pebase.rb', line 1153 def _imports_cached @_imports_cached end |
#_isource ⇒ Object
instance stuff
1147 1148 1149 |
# File 'lib/rex/peparsey/pebase.rb', line 1147 def _isource @_isource end |
#_optional_header ⇒ Object
Returns the value of attribute _optional_header.
1148 1149 1150 |
# File 'lib/rex/peparsey/pebase.rb', line 1148 def _optional_header @_optional_header end |
#_relocations_cache ⇒ Object
Returns the value of attribute _relocations_cache.
1155 1156 1157 |
# File 'lib/rex/peparsey/pebase.rb', line 1155 def _relocations_cache @_relocations_cache end |
#_relocations_cached ⇒ Object
Returns the value of attribute _relocations_cached.
1155 1156 1157 |
# File 'lib/rex/peparsey/pebase.rb', line 1155 def _relocations_cached @_relocations_cached end |
#_resources_cache ⇒ Object
Returns the value of attribute _resources_cache.
1156 1157 1158 |
# File 'lib/rex/peparsey/pebase.rb', line 1156 def _resources_cache @_resources_cache end |
#_resources_cached ⇒ Object
Returns the value of attribute _resources_cached.
1156 1157 1158 |
# File 'lib/rex/peparsey/pebase.rb', line 1156 def _resources_cached @_resources_cached end |
#_section_headers ⇒ Object
Returns the value of attribute _section_headers.
1148 1149 1150 |
# File 'lib/rex/peparsey/pebase.rb', line 1148 def _section_headers @_section_headers end |
#_tls_header ⇒ Object
Returns the value of attribute _tls_header.
1148 1149 1150 |
# File 'lib/rex/peparsey/pebase.rb', line 1148 def _tls_header @_tls_header end |
#hdr ⇒ Object
Returns the value of attribute hdr.
1158 1159 1160 |
# File 'lib/rex/peparsey/pebase.rb', line 1158 def hdr @hdr end |
#header_section ⇒ Object
Returns the value of attribute header_section.
1151 1152 1153 |
# File 'lib/rex/peparsey/pebase.rb', line 1151 def header_section @header_section end |
#image_base ⇒ Object
Returns the value of attribute image_base.
1151 1152 1153 |
# File 'lib/rex/peparsey/pebase.rb', line 1151 def image_base @image_base end |
#sections ⇒ Object
Returns the value of attribute sections.
1151 1152 1153 |
# File 'lib/rex/peparsey/pebase.rb', line 1151 def sections @sections end |
Class Method Details
._align_offset(offset, alignment) ⇒ Object
Just a stupid routine to round an offset up to it’s alignment.
For example, you’re going to want this for FileAlignment and SectionAlignment, etc…
1137 1138 1139 1140 1141 |
# File 'lib/rex/peparsey/pebase.rb', line 1137 def self._align_offset(offset, alignment) offset += alignment - 1 offset -= offset % alignment return offset end |
._parse_dos_header(rawdata) ⇒ Object
135 136 137 |
# File 'lib/rex/peparsey/pebase.rb', line 135 def self._parse_dos_header(rawdata) return DosHeader.new(rawdata) end |
._parse_file_header(rawdata) ⇒ Object
216 217 218 |
# File 'lib/rex/peparsey/pebase.rb', line 216 def self._parse_file_header(rawdata) return FileHeader.new(rawdata) end |
._parse_optional_header(rawdata) ⇒ Object
574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 |
# File 'lib/rex/peparsey/pebase.rb', line 574 def self._parse_optional_header(rawdata) case rawdata.length # no optional header when 0 return nil # good, good when IMAGE_SIZEOF_NT_OPTIONAL32_HEADER return OptionalHeader32.new(rawdata) when IMAGE_SIZEOF_NT_OPTIONAL64_HEADER return OptionalHeader64.new(rawdata) # bad, bad else raise OptionalHeaderError, "I don't know this header size, #{rawdata.length}", caller end end |
._parse_section_headers(rawdata) ⇒ Object
646 647 648 649 650 651 652 653 654 655 656 657 |
# File 'lib/rex/peparsey/pebase.rb', line 646 def self._parse_section_headers(rawdata) section_headers = [ ] size = IMAGE_SIZEOF_SECTION_HEADER numsections = rawdata.length / size numsections.times do |i| data = rawdata[i * size, size] section_headers << SectionHeader.new(data) end return section_headers end |
.new_from_file(filename, disk_backed = false) ⇒ Object
1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 |
# File 'lib/rex/peparsey/pebase.rb', line 1160 def self.new_from_file(filename, disk_backed = false) file = ::File.new(filename) file.binmode # windows... :\ if disk_backed return self.new(ImageSource::Disk.new(file)) else obj = new_from_string(file.read) file.close return obj end end |
.new_from_string(data) ⇒ Object
1174 1175 1176 |
# File 'lib/rex/peparsey/pebase.rb', line 1174 def self.new_from_string(data) return self.new(ImageSource::Memory.new(data)) end |
Instance Method Details
#_find_section_by_rva(rva) ⇒ Object
Find a section by an RVA
1238 1239 1240 1241 1242 1243 1244 1245 1246 |
# File 'lib/rex/peparsey/pebase.rb', line 1238 def _find_section_by_rva(rva) all_sections.each do |section| if section.contains_rva?(rva) return section end end return nil end |
#_load_exception_directory ⇒ Object
1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 |
# File 'lib/rex/peparsey/pebase.rb', line 1100 def _load_exception_directory @exception = [] exception_entry = _optional_header['DataDirectory'][IMAGE_DIRECTORY_ENTRY_EXCEPTION] rva = exception_entry.v['VirtualAddress'] size = exception_entry.v['Size'] return if (rva == 0) data = _isource.read(rva_to_file_offset(rva), size) case hdr.file.Machine when IMAGE_FILE_MACHINE_AMD64 count = data.length / IMAGE_RUNTIME_FUNCTION_ENTRY_SZ count.times { |current| @exception << RuntimeFunctionEntry.new(self, data.slice!(0, IMAGE_RUNTIME_FUNCTION_ENTRY_SZ)) } else end return @exception end |
#_load_exports ⇒ Object
1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 |
# File 'lib/rex/peparsey/pebase.rb', line 1382 def _load_exports # # Get the data directory entry, size, etc # exports_entry = _optional_header['DataDirectory'][0] rva = exports_entry.v['VirtualAddress'] size = exports_entry.v['Size'] return nil if size == 0 # # Ok, so we have the data directory, now lets parse it # directory = IMAGE_EXPORT_DESCRIPTOR.make_struct directory.from_s(_isource.read(rva_to_file_offset(rva), IMAGE_EXPORT_DESCRIPTOR_SIZE)) # # We can have nameless exports, so we need to do the whole # NumberOfFunctions NumberOfNames foo # num_functions = directory.v['NumberOfFunctions'] num_names = directory.v['NumberOfNames'] dllname_rva = directory.v['Name'] dllname = _isource.read_asciiz(rva_to_file_offset(dllname_rva)) # FIXME Base, etc fun_off = rva_to_file_offset(directory.v['AddressOfFunctions']) name_off = rva_to_file_offset(directory.v['AddressOfNames']) ord_off = rva_to_file_offset(directory.v['AddressOfNameOrdinals']) base = directory.v['Base'] # Allocate the list of names names = Array.new(num_functions) # # Iterate the names and name/ordinal list, getting the names # and storing them in the name list... # num_names.times do |i| name_rva = _isource.read(name_off + (i * 4), 4).unpack('V')[0] ordinal = _isource.read(ord_off + (i * 2), 2).unpack('v')[0] name = _isource.read_asciiz(rva_to_file_offset(name_rva)) # store the exported name in the name list names[ordinal] = name end exports = ExportDirectory.new(dllname, [ ], base) # # Now just iterate the functions (rvas) list.. # num_functions.times do |i| rva = _isource.read(fun_off + (i * 4), 4).unpack('V')[0] # ExportEntry.new(name, ordinal, rva) exports.entries << ExportEntry.new(names[i], i + base, rva) end return exports end |
#_load_imports ⇒ Object
1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 |
# File 'lib/rex/peparsey/pebase.rb', line 1311 def _load_imports # # Get the data directory entry, size, etc # imports_entry = _optional_header['DataDirectory'][1] rva = imports_entry.v['VirtualAddress'] size = imports_entry.v['Size'] return nil if size == 0 # # Ok, so we have the data directory, now lets parse it # imports = [ ] descriptors_data = _isource.read(rva_to_file_offset(rva), size) while descriptors_data.length >= IMAGE_IMPORT_DESCRIPTOR_SIZE descriptor = IMAGE_IMPORT_DESCRIPTOR.make_struct descriptor.from_s(descriptors_data) descriptors_data = descriptor.leftover othunk = descriptor.v['OriginalFirstThunk'] fthunk = descriptor.v['FirstThunk'] break if fthunk == 0 dllname = _isource.read_asciiz(rva_to_file_offset(descriptor.v['Name'])) import = ImportDescriptor.new(dllname, [ ]) # we prefer the Characteristics/OriginalFirstThunk... thunk_off = rva_to_file_offset(othunk == 0 ? fthunk : othunk) while (orgrva = _isource.read(thunk_off, 4).unpack('V')[0]) != 0 hint = nil name = nil if (orgrva & IMAGE_ORDINAL_FLAG32) != 0 hint = orgrva & 0xffff else foff = rva_to_file_offset(orgrva) hint = _isource.read(foff, 2).unpack('v')[0] name = _isource.read_asciiz(foff + 2) end import.entries << ImportEntry.new(name, hint) thunk_off += 4 end imports << import end return imports end |
#_load_relocations ⇒ Object
1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 |
# File 'lib/rex/peparsey/pebase.rb', line 1458 def _load_relocations # # Get the data directory entry, size, etc # exports_entry = _optional_header['DataDirectory'][5] rva = exports_entry.v['VirtualAddress'] size = exports_entry.v['Size'] return nil if size == 0 # # Ok, so we have the data directory, now lets parse it # dirdata = _isource.read(rva_to_file_offset(rva), size) relocdirs = [ ] while dirdata.length >= IMAGE_SIZEOF_BASE_RELOCATION header = IMAGE_BASE_RELOCATION.make_struct header.from_s(dirdata) dirdata = header.leftover numrelocs = (header.v['SizeOfBlock'] - IMAGE_SIZEOF_BASE_RELOCATION) / 2 relocbase = header.v['VirtualAddress'] relocdir = RelocationDirectory.new(relocbase, [ ]) numrelocs.times do reloc = IMAGE_BASE_RELOCATION_TYPE_OFFSET.make_struct reloc.from_s(dirdata) dirdata = reloc.leftover typeoffset = reloc.v['TypeOffset'] relocrva = relocbase + (typeoffset & 0xfff) reloctype = (typeoffset >> 12) & 0xf relocdir.entries << RelocationEntry.new(relocrva, reloctype) end relocdirs << relocdir end return relocdirs end |
#_load_resources ⇒ Object
1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 |
# File 'lib/rex/peparsey/pebase.rb', line 1520 def _load_resources # # Get the data directory entry, size, etc # rsrc_entry = _optional_header['DataDirectory'][IMAGE_DIRECTORY_ENTRY_RESOURCE] rva = rsrc_entry.v['VirtualAddress'] size = rsrc_entry.v['Size'] return nil if size == 0 # # Ok, so we have the data directory, now lets parse it # data = _isource.read(rva_to_file_offset(rva), size) self._resources_cache = {} _parse_resource_directory(data) end |
#_parse_config_header ⇒ Object
– doesn’t seem to be used – not compatible with 64-bit def self._parse_config_header(rawdata) header = IMAGE_LOAD_CONFIG_DIRECTORY32.make_struct header.from_s(rawdata) ConfigHeader.new(header) end ++
835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 |
# File 'lib/rex/peparsey/pebase.rb', line 835 def _parse_config_header # # Get the data directory entry, size, etc # exports_entry = _optional_header['DataDirectory'][IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG] rva = exports_entry.v['VirtualAddress'] size = exports_entry.v['Size'] return nil if size == 0 # # Ok, so we have the data directory, now lets parse it # dirdata = _isource.read(rva_to_file_offset(rva), size) klass = (ptr_64?) ? IMAGE_LOAD_CONFIG_DIRECTORY64 : IMAGE_LOAD_CONFIG_DIRECTORY32 header = klass.make_struct header.from_s(dirdata) @config = ConfigHeader.new(header) end |
#_parse_resource_directory(data, rname = 0, rvalue = 0x80000000, path = '0', pname = nil) ⇒ Object
1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 |
# File 'lib/rex/peparsey/pebase.rb', line 1539 def _parse_resource_directory(data, rname=0, rvalue=0x80000000, path='0', pname=nil) pname = _parse_resource_name(data, rname) if (path.scan('/').length == 1) if (pname !~ /^\d+/) path = "/" + pname else path = "/" + _resource_lookup( (rname & ~0x80000000).to_s) end end rvalue &= ~0x80000000 vals = data[rvalue, 16].unpack('VVvvvv') chars = vals[0] tdate = vals[1] vers = "#{vals[2]}#{vals[3]}" count = vals[4] + vals[5] 0.upto(count-1) do |i| ename, evalue = data[rvalue + 16 + ( i * 8), 8].unpack('VV') epath = path + '/' + i.to_s if (ename & 0x80000000 != 0) pname = _parse_resource_name(data, ename) end if (evalue & 0x80000000 != 0) # This is a subdirectory _parse_resource_directory(data, ename, evalue, epath, pname) else # This is an entry _parse_resource_entry(data, ename, evalue, epath, pname) end end end |
#_parse_resource_entry(data, rname, rvalue, path, pname) ⇒ Object
1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 |
# File 'lib/rex/peparsey/pebase.rb', line 1611 def _parse_resource_entry(data, rname, rvalue, path, pname) rva, size, code = data[rvalue, 12].unpack('VVV') lang = _parse_resource_name(data, rname) ent = ResourceEntry.new( self, path, lang, code, rva, size, pname ) self._resources_cache[path] = ent end |
#_parse_resource_name(data, rname) ⇒ Object
1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 |
# File 'lib/rex/peparsey/pebase.rb', line 1628 def _parse_resource_name(data, rname) if (rname & 0x80000000 != 0) rname &= ~0x80000000 unistr = data[rname+2, 2 * data[rname,2].unpack('v')[0] ] unistr, trash = unistr.split(/\x00\x00/n, 2) return unistr ? unistr.gsub(/\x00/n, '') : nil end rname.to_s end |
#_parse_tls_header ⇒ Object
966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 |
# File 'lib/rex/peparsey/pebase.rb', line 966 def _parse_tls_header # # Get the data directory entry, size, etc # exports_entry = _optional_header['DataDirectory'][IMAGE_DIRECTORY_ENTRY_TLS] rva = exports_entry.v['VirtualAddress'] size = exports_entry.v['Size'] return nil if size == 0 # # Ok, so we have the data directory, now lets parse it # dirdata = _isource.read(rva_to_file_offset(rva), size) klass = (ptr_64?) ? IMAGE_LOAD_TLS_DIRECTORY64 : IMAGE_LOAD_TLS_DIRECTORY32 header = klass.make_struct header.from_s(dirdata) @tls = TLSHeader.new(header) end |
#_resource_lookup(i) ⇒ Object
1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 |
# File 'lib/rex/peparsey/pebase.rb', line 1579 def _resource_lookup(i) tbl = { '1' => 'RT_CURSOR', '2' => 'RT_BITMAP', '3' => 'RT_ICON', '4' => 'RT_MENU', '5' => 'RT_DIALOG', '6' => 'RT_STRING', '7' => 'RT_FONTDIR', '8' => 'RT_FONT', '9' => 'RT_ACCELERATORS', '10' => 'RT_RCDATA', '11' => 'RT_MESSAGETABLE', '12' => 'RT_GROUP_CURSOR', '14' => 'RT_GROUP_ICON', '16' => 'RT_VERSION', '17' => 'RT_DLGINCLUDE', '19' => 'RT_PLUGPLAY', '20' => 'RT_VXD', '21' => 'RT_ANICURSOR', '22' => 'RT_ANIICON', '23' => 'RT_HTML', '24' => 'RT_MANIFEST', '32767' => 'RT_ERROR', '8192' => 'RT_NEWRESOURCE', '8194' => 'RT_NEWBITMAP', '8196' => 'RT_NEWMENU', '8197' => 'RT_NEWDIALOG' } tbl[i] || i end |
#close ⇒ Object
1178 1179 1180 |
# File 'lib/rex/peparsey/pebase.rb', line 1178 def close _isource.close end |
#config ⇒ Object
860 861 862 863 |
# File 'lib/rex/peparsey/pebase.rb', line 860 def config _parse_config_header if @config.nil? @config end |
#exception ⇒ Object
1126 1127 1128 1129 |
# File 'lib/rex/peparsey/pebase.rb', line 1126 def exception _load_exception_directory if @exception.nil? @exception end |
#exports ⇒ Object
We lazily parse the exports, and then cache it
1374 1375 1376 1377 1378 1379 1380 |
# File 'lib/rex/peparsey/pebase.rb', line 1374 def exports if !_exports_cached self._exports_cache = _load_exports self._exports_cached = true end return _exports_cache end |
#file_offset_to_rva(foffset) ⇒ Object
1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 |
# File 'lib/rex/peparsey/pebase.rb', line 1209 def file_offset_to_rva(foffset) if foffset < 0 raise PeParseyError, "Offset should not be less than 0. The value is: #{foffset}", caller end all_sections.each do |section| if section.contains_file_offset?(foffset) return section.file_offset_to_rva(foffset) end end raise PeParseyError, "No section contains file offset #{foffset}", caller end |
#file_offset_to_vma(foffset) ⇒ Object
1223 1224 1225 |
# File 'lib/rex/peparsey/pebase.rb', line 1223 def file_offset_to_vma(foffset) return rva_to_vma(file_offset_to_rva(foffset)) end |
#find_section_by_rva(rva) ⇒ Object
1247 1248 1249 1250 1251 1252 1253 1254 1255 |
# File 'lib/rex/peparsey/pebase.rb', line 1247 def find_section_by_rva(rva) section = _find_section_by_rva(rva) if !section raise PeParseyError, "Cannot find rva! #{rva}", caller end return section end |
#find_section_by_vma(vma) ⇒ Object
Find a section by a VMA
1260 1261 1262 |
# File 'lib/rex/peparsey/pebase.rb', line 1260 def find_section_by_vma(vma) return find_section_by_rva(vma_to_rva(vma)) end |
#imports ⇒ Object
We lazily parse the imports, and then cache it
1303 1304 1305 1306 1307 1308 1309 |
# File 'lib/rex/peparsey/pebase.rb', line 1303 def imports if !_imports_cached self._imports_cache = _load_imports self._imports_cached = true end return _imports_cache end |
#read_asciiz_rva(rva) ⇒ Object
1286 1287 1288 |
# File 'lib/rex/peparsey/pebase.rb', line 1286 def read_asciiz_rva(rva) return find_section_by_rva(rva).read_asciiz_rva(rva) end |
#read_asciiz_vma(vma) ⇒ Object
1290 1291 1292 |
# File 'lib/rex/peparsey/pebase.rb', line 1290 def read_asciiz_vma(vma) return read_asciiz_rva(vma_to_rva(vma)) end |
#read_rva(rva, length) ⇒ Object
Some convenient methods to read a vma/rva without having the section… (inefficent though I suppose…)
1278 1279 1280 |
# File 'lib/rex/peparsey/pebase.rb', line 1278 def read_rva(rva, length) return find_section_by_rva(rva).read_rva(rva, length) end |
#read_vma(vma, length) ⇒ Object
1282 1283 1284 |
# File 'lib/rex/peparsey/pebase.rb', line 1282 def read_vma(vma, length) return read_rva(vma_to_rva(vma), length) end |
#relocations ⇒ Object
Base relocations in the hizzy
1450 1451 1452 1453 1454 1455 1456 |
# File 'lib/rex/peparsey/pebase.rb', line 1450 def relocations if !_relocations_cached self._relocations_cache = _load_relocations self._relocations_cached = true end return _relocations_cache end |
#resources ⇒ Object
We lazily parse the resources, and then cache them
1511 1512 1513 1514 1515 1516 1517 1518 |
# File 'lib/rex/peparsey/pebase.rb', line 1511 def resources if !_resources_cached _load_resources self._resources_cached = true end return self._resources_cache end |
#rva_to_file_offset(rva) ⇒ Object
1196 1197 1198 1199 1200 1201 1202 1203 |
# File 'lib/rex/peparsey/pebase.rb', line 1196 def rva_to_file_offset(rva) all_sections.each do |section| if section.contains_rva?(rva) return section.rva_to_file_offset(rva) end end raise PeParseyError, "No section contains RVA", caller end |
#rva_to_vma(rva) ⇒ Object
Random rva, vma, file offset, section offset, etc conversion routines…
1188 1189 1190 |
# File 'lib/rex/peparsey/pebase.rb', line 1188 def rva_to_vma(rva) return rva + image_base end |
#tls ⇒ Object
991 992 993 994 |
# File 'lib/rex/peparsey/pebase.rb', line 991 def tls _parse_config_header if @tls.nil? @tls end |
#update_checksum ⇒ Object
1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 |
# File 'lib/rex/peparsey/pebase.rb', line 1639 def update_checksum off = _dos_header.e_lfanew + IMAGE_FILE_HEADER_SIZE + 0x40 _isource.rawdata[off, 4] = [0].pack('V') rem = _isource.size % 4 sum_me = '' sum_me << _isource.rawdata sum_me << "\x00" * (4 - rem) if rem > 0 cksum = 0 sum_me.unpack('V*').each { |el| cksum = (cksum & 0xffffffff) + (cksum >> 32) + el if cksum > 2**32 cksum = (cksum & 0xffffffff) + (cksum >> 32) end } cksum = (cksum & 0xffff) + (cksum >> 16) cksum += (cksum >> 16) cksum &= 0xffff cksum += _isource.size _isource.rawdata[off, 4] = [cksum].pack('V') end |
#valid_rva?(rva) ⇒ Boolean
1264 1265 1266 |
# File 'lib/rex/peparsey/pebase.rb', line 1264 def valid_rva?(rva) _find_section_by_rva(rva) != nil end |
#valid_vma?(vma) ⇒ Boolean
1267 1268 1269 |
# File 'lib/rex/peparsey/pebase.rb', line 1267 def valid_vma?(vma) _find_section_by_rva(vma_to_rva(vma)) != nil end |
#vma_to_file_offset(vma) ⇒ Object
1205 1206 1207 |
# File 'lib/rex/peparsey/pebase.rb', line 1205 def vma_to_file_offset(vma) return rva_to_file_offset(vma_to_rva(vma)) end |
#vma_to_rva(vma) ⇒ Object
1192 1193 1194 |
# File 'lib/rex/peparsey/pebase.rb', line 1192 def vma_to_rva(vma) return vma - image_base end |