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 =
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;
64
- IMAGE_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 =
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;
#define IMAGE_NT_SIGNATURE 0x00004550 // PE00 #define IMAGE_FILE_MACHINE_I386 0x014c // Intel 386. #define IMAGE_FILE_MACHINE_IA64 0x0200 // Intel 64 #define IMAGE_FILE_MACHINE_ALPHA64 0x0284 // ALPHA64 #define IMAGE_FILE_MACHINE_AMD64 0x8664 // AMD64 (K8) #define IMAGE_SIZEOF_FILE_HEADER 20
0x00004550
- IMAGE_FILE_MACHINE_I386 =
0x014c
- IMAGE_FILE_MACHINE_IA64 =
0x0200
- IMAGE_FILE_MACHINE_ALPHA64 =
0x0284
- IMAGE_FILE_MACHINE_AMD64 =
0x8664
- IMAGE_FILE_HEADER_SIZE =
because we include the signature
20+4
- IMAGE_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_ORDINAL_FLAG32 =
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;
0x80000000
- IMAGE_IMPORT_DESCRIPTOR_SIZE =
20
- 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 =
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;
40
- IMAGE_EXPORT_DESCRIPTOR =
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 =
typedef struct _IMAGE_DATA_DIRECTORY
DWORD VirtualAddress; DWORD Size;
IMAGE_DATA_DIRECTORY, *PIMAGE_DATA_DIRECTORY;
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 =
Rex::Struct2::CStructTemplate.new( [ 'uint32v', 'VirtualAddress', 0 ], [ 'uint32v', 'Size', 0 ] )
- IMAGE_NT_OPTIONAL_HDR32_MAGIC =
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 =
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_OPTIONAL_HEADER64, *PIMAGE_OPTIONAL_HEADER64;
#define IMAGE_NT_OPTIONAL_HDR64_MAGIC 0x20b #define IMAGE_SIZEOF_NT_OPTIONAL64_HEADER 240
0x20b
- IMAGE_SIZEOF_NT_OPTIONAL64_HEADER =
240
- IMAGE_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 =
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;
#define IMAGE_SIZEOF_SECTION_HEADER 40
40
- IMAGE_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 =
typedef struct _IMAGE_BASE_RELOCATION {
DWORD VirtualAddress; DWORD SizeOfBlock;
// WORD TypeOffset; } IMAGE_BASE_RELOCATION; typedef IMAGE_BASE_RELOCATION UNALIGNED * PIMAGE_BASE_RELOCATION;
#define IMAGE_SIZEOF_BASE_RELOCATION 8
8
- IMAGE_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 =
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 =
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 =
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 =
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 =
typedef struct _IMAGE_RUNTIME_FUNCTION_ENTRY
DWORD BeginAddress; DWORD EndAddress; DWORD UnwindInfoAddress;
_IMAGE_RUNTIME_FUNCTION_ENTRY, *_PIMAGE_RUNTIME_FUNCTION_ENTRY;
12
- IMAGE_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.
1163 1164 1165 |
# File 'lib/rex/peparsey/pebase.rb', line 1163 def _config_header @_config_header end |
#_dos_header ⇒ Object
Returns the value of attribute _dos_header.
1163 1164 1165 |
# File 'lib/rex/peparsey/pebase.rb', line 1163 def _dos_header @_dos_header end |
#_exception_header ⇒ Object
Returns the value of attribute _exception_header.
1163 1164 1165 |
# File 'lib/rex/peparsey/pebase.rb', line 1163 def _exception_header @_exception_header end |
#_exports_cache ⇒ Object
Returns the value of attribute _exports_cache.
1169 1170 1171 |
# File 'lib/rex/peparsey/pebase.rb', line 1169 def _exports_cache @_exports_cache end |
#_exports_cached ⇒ Object
Returns the value of attribute _exports_cached.
1169 1170 1171 |
# File 'lib/rex/peparsey/pebase.rb', line 1169 def _exports_cached @_exports_cached end |
#_file_header ⇒ Object
Returns the value of attribute _file_header.
1163 1164 1165 |
# File 'lib/rex/peparsey/pebase.rb', line 1163 def _file_header @_file_header end |
#_imports_cache ⇒ Object
Returns the value of attribute _imports_cache.
1168 1169 1170 |
# File 'lib/rex/peparsey/pebase.rb', line 1168 def _imports_cache @_imports_cache end |
#_imports_cached ⇒ Object
Returns the value of attribute _imports_cached.
1168 1169 1170 |
# File 'lib/rex/peparsey/pebase.rb', line 1168 def _imports_cached @_imports_cached end |
#_isource ⇒ Object
instance stuff
1162 1163 1164 |
# File 'lib/rex/peparsey/pebase.rb', line 1162 def _isource @_isource end |
#_optional_header ⇒ Object
Returns the value of attribute _optional_header.
1163 1164 1165 |
# File 'lib/rex/peparsey/pebase.rb', line 1163 def _optional_header @_optional_header end |
#_relocations_cache ⇒ Object
Returns the value of attribute _relocations_cache.
1170 1171 1172 |
# File 'lib/rex/peparsey/pebase.rb', line 1170 def _relocations_cache @_relocations_cache end |
#_relocations_cached ⇒ Object
Returns the value of attribute _relocations_cached.
1170 1171 1172 |
# File 'lib/rex/peparsey/pebase.rb', line 1170 def _relocations_cached @_relocations_cached end |
#_resources_cache ⇒ Object
Returns the value of attribute _resources_cache.
1171 1172 1173 |
# File 'lib/rex/peparsey/pebase.rb', line 1171 def _resources_cache @_resources_cache end |
#_resources_cached ⇒ Object
Returns the value of attribute _resources_cached.
1171 1172 1173 |
# File 'lib/rex/peparsey/pebase.rb', line 1171 def _resources_cached @_resources_cached end |
#_section_headers ⇒ Object
Returns the value of attribute _section_headers.
1163 1164 1165 |
# File 'lib/rex/peparsey/pebase.rb', line 1163 def _section_headers @_section_headers end |
#_tls_header ⇒ Object
Returns the value of attribute _tls_header.
1163 1164 1165 |
# File 'lib/rex/peparsey/pebase.rb', line 1163 def _tls_header @_tls_header end |
#hdr ⇒ Object
Returns the value of attribute hdr.
1173 1174 1175 |
# File 'lib/rex/peparsey/pebase.rb', line 1173 def hdr @hdr end |
#header_section ⇒ Object
Returns the value of attribute header_section.
1166 1167 1168 |
# File 'lib/rex/peparsey/pebase.rb', line 1166 def header_section @header_section end |
#image_base ⇒ Object
Returns the value of attribute image_base.
1166 1167 1168 |
# File 'lib/rex/peparsey/pebase.rb', line 1166 def image_base @image_base end |
#sections ⇒ Object
Returns the value of attribute sections.
1166 1167 1168 |
# File 'lib/rex/peparsey/pebase.rb', line 1166 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…
1152 1153 1154 1155 1156 |
# File 'lib/rex/peparsey/pebase.rb', line 1152 def self._align_offset(offset, alignment) offset += alignment - 1 offset -= offset % alignment return offset end |
._parse_dos_header(rawdata) ⇒ Object
140 141 142 |
# File 'lib/rex/peparsey/pebase.rb', line 140 def self._parse_dos_header(rawdata) return DosHeader.new(rawdata) end |
._parse_file_header(rawdata) ⇒ Object
220 221 222 |
# File 'lib/rex/peparsey/pebase.rb', line 220 def self._parse_file_header(rawdata) return FileHeader.new(rawdata) end |
._parse_optional_header(rawdata) ⇒ Object
583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 |
# File 'lib/rex/peparsey/pebase.rb', line 583 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
658 659 660 661 662 663 664 665 666 667 668 669 |
# File 'lib/rex/peparsey/pebase.rb', line 658 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
1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 |
# File 'lib/rex/peparsey/pebase.rb', line 1175 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
1189 1190 1191 |
# File 'lib/rex/peparsey/pebase.rb', line 1189 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
1253 1254 1255 1256 1257 1258 1259 1260 1261 |
# File 'lib/rex/peparsey/pebase.rb', line 1253 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
1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 |
# File 'lib/rex/peparsey/pebase.rb', line 1115 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
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 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 |
# File 'lib/rex/peparsey/pebase.rb', line 1397 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
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 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 |
# File 'lib/rex/peparsey/pebase.rb', line 1326 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
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 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 |
# File 'lib/rex/peparsey/pebase.rb', line 1473 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
1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 |
# File 'lib/rex/peparsey/pebase.rb', line 1535 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
847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 |
# File 'lib/rex/peparsey/pebase.rb', line 847 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
1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 |
# File 'lib/rex/peparsey/pebase.rb', line 1554 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
1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 |
# File 'lib/rex/peparsey/pebase.rb', line 1626 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
1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 |
# File 'lib/rex/peparsey/pebase.rb', line 1643 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/, 2) return unistr ? unistr.gsub(/\x00/, '') : nil end rname.to_s end |
#_parse_tls_header ⇒ Object
980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 |
# File 'lib/rex/peparsey/pebase.rb', line 980 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
1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 |
# File 'lib/rex/peparsey/pebase.rb', line 1594 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
1193 1194 1195 |
# File 'lib/rex/peparsey/pebase.rb', line 1193 def close _isource.close end |
#config ⇒ Object
872 873 874 875 |
# File 'lib/rex/peparsey/pebase.rb', line 872 def config _parse_config_header if @config.nil? @config end |
#exception ⇒ Object
1141 1142 1143 1144 |
# File 'lib/rex/peparsey/pebase.rb', line 1141 def exception _load_exception_directory if @exception.nil? @exception end |
#exports ⇒ Object
We lazily parse the exports, and then cache it
1389 1390 1391 1392 1393 1394 1395 |
# File 'lib/rex/peparsey/pebase.rb', line 1389 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
1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 |
# File 'lib/rex/peparsey/pebase.rb', line 1224 def file_offset_to_rva(foffset) if foffset < 0 raise WtfError, "lame", caller end all_sections.each do |section| if section.contains_file_offset?(foffset) return section.file_offset_to_rva(foffset) end end raise WtfError, "wtf! #{foffset}", caller end |
#file_offset_to_vma(foffset) ⇒ Object
1238 1239 1240 |
# File 'lib/rex/peparsey/pebase.rb', line 1238 def file_offset_to_vma(foffset) return rva_to_vma(file_offset_to_rva(foffset)) end |
#find_section_by_rva(rva) ⇒ Object
1262 1263 1264 1265 1266 1267 1268 1269 1270 |
# File 'lib/rex/peparsey/pebase.rb', line 1262 def find_section_by_rva(rva) section = _find_section_by_rva(rva) if !section raise WtfError, "Cannot find rva! #{rva}", caller end return section end |
#find_section_by_vma(vma) ⇒ Object
Find a section by a VMA
1275 1276 1277 |
# File 'lib/rex/peparsey/pebase.rb', line 1275 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
1318 1319 1320 1321 1322 1323 1324 |
# File 'lib/rex/peparsey/pebase.rb', line 1318 def imports if !_imports_cached self._imports_cache = _load_imports self._imports_cached = true end return _imports_cache end |
#read_asciiz_rva(rva) ⇒ Object
1301 1302 1303 |
# File 'lib/rex/peparsey/pebase.rb', line 1301 def read_asciiz_rva(rva) return find_section_by_rva(rva).read_asciiz_rva(rva) end |
#read_asciiz_vma(vma) ⇒ Object
1305 1306 1307 |
# File 'lib/rex/peparsey/pebase.rb', line 1305 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…)
1293 1294 1295 |
# File 'lib/rex/peparsey/pebase.rb', line 1293 def read_rva(rva, length) return find_section_by_rva(rva).read_rva(rva, length) end |
#read_vma(vma, length) ⇒ Object
1297 1298 1299 |
# File 'lib/rex/peparsey/pebase.rb', line 1297 def read_vma(vma, length) return read_rva(vma_to_rva(vma), length) end |
#relocations ⇒ Object
Base relocations in the hizzy
1465 1466 1467 1468 1469 1470 1471 |
# File 'lib/rex/peparsey/pebase.rb', line 1465 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
1526 1527 1528 1529 1530 1531 1532 1533 |
# File 'lib/rex/peparsey/pebase.rb', line 1526 def resources if !_resources_cached _load_resources self._resources_cached = true end return self._resources_cache end |
#rva_to_file_offset(rva) ⇒ Object
1211 1212 1213 1214 1215 1216 1217 1218 |
# File 'lib/rex/peparsey/pebase.rb', line 1211 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 WtfError, "wtf!", caller end |
#rva_to_vma(rva) ⇒ Object
Random rva, vma, file offset, section offset, etc conversion routines…
1203 1204 1205 |
# File 'lib/rex/peparsey/pebase.rb', line 1203 def rva_to_vma(rva) return rva + image_base end |
#tls ⇒ Object
1005 1006 1007 1008 |
# File 'lib/rex/peparsey/pebase.rb', line 1005 def tls _parse_config_header if @tls.nil? @tls end |
#update_checksum ⇒ Object
1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 |
# File 'lib/rex/peparsey/pebase.rb', line 1654 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
1279 1280 1281 |
# File 'lib/rex/peparsey/pebase.rb', line 1279 def valid_rva?(rva) _find_section_by_rva(rva) != nil end |
#valid_vma?(vma) ⇒ Boolean
1282 1283 1284 |
# File 'lib/rex/peparsey/pebase.rb', line 1282 def valid_vma?(vma) _find_section_by_rva(vma_to_rva(vma)) != nil end |
#vma_to_file_offset(vma) ⇒ Object
1220 1221 1222 |
# File 'lib/rex/peparsey/pebase.rb', line 1220 def vma_to_file_offset(vma) return rva_to_file_offset(vma_to_rva(vma)) end |
#vma_to_rva(vma) ⇒ Object
1207 1208 1209 |
# File 'lib/rex/peparsey/pebase.rb', line 1207 def vma_to_rva(vma) return vma - image_base end |