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_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_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.
1145 1146 1147 |
# File 'lib/rex/peparsey/pebase.rb', line 1145 def _config_header @_config_header end |
#_dos_header ⇒ Object
Returns the value of attribute _dos_header.
1145 1146 1147 |
# File 'lib/rex/peparsey/pebase.rb', line 1145 def _dos_header @_dos_header end |
#_exception_header ⇒ Object
Returns the value of attribute _exception_header.
1145 1146 1147 |
# File 'lib/rex/peparsey/pebase.rb', line 1145 def _exception_header @_exception_header end |
#_exports_cache ⇒ Object
Returns the value of attribute _exports_cache.
1151 1152 1153 |
# File 'lib/rex/peparsey/pebase.rb', line 1151 def _exports_cache @_exports_cache end |
#_exports_cached ⇒ Object
Returns the value of attribute _exports_cached.
1151 1152 1153 |
# File 'lib/rex/peparsey/pebase.rb', line 1151 def _exports_cached @_exports_cached end |
#_file_header ⇒ Object
Returns the value of attribute _file_header.
1145 1146 1147 |
# File 'lib/rex/peparsey/pebase.rb', line 1145 def _file_header @_file_header end |
#_imports_cache ⇒ Object
Returns the value of attribute _imports_cache.
1150 1151 1152 |
# File 'lib/rex/peparsey/pebase.rb', line 1150 def _imports_cache @_imports_cache end |
#_imports_cached ⇒ Object
Returns the value of attribute _imports_cached.
1150 1151 1152 |
# File 'lib/rex/peparsey/pebase.rb', line 1150 def _imports_cached @_imports_cached end |
#_isource ⇒ Object
instance stuff
1144 1145 1146 |
# File 'lib/rex/peparsey/pebase.rb', line 1144 def _isource @_isource end |
#_optional_header ⇒ Object
Returns the value of attribute _optional_header.
1145 1146 1147 |
# File 'lib/rex/peparsey/pebase.rb', line 1145 def _optional_header @_optional_header end |
#_relocations_cache ⇒ Object
Returns the value of attribute _relocations_cache.
1152 1153 1154 |
# File 'lib/rex/peparsey/pebase.rb', line 1152 def _relocations_cache @_relocations_cache end |
#_relocations_cached ⇒ Object
Returns the value of attribute _relocations_cached.
1152 1153 1154 |
# File 'lib/rex/peparsey/pebase.rb', line 1152 def _relocations_cached @_relocations_cached end |
#_resources_cache ⇒ Object
Returns the value of attribute _resources_cache.
1153 1154 1155 |
# File 'lib/rex/peparsey/pebase.rb', line 1153 def _resources_cache @_resources_cache end |
#_resources_cached ⇒ Object
Returns the value of attribute _resources_cached.
1153 1154 1155 |
# File 'lib/rex/peparsey/pebase.rb', line 1153 def _resources_cached @_resources_cached end |
#_section_headers ⇒ Object
Returns the value of attribute _section_headers.
1145 1146 1147 |
# File 'lib/rex/peparsey/pebase.rb', line 1145 def _section_headers @_section_headers end |
#_tls_header ⇒ Object
Returns the value of attribute _tls_header.
1145 1146 1147 |
# File 'lib/rex/peparsey/pebase.rb', line 1145 def _tls_header @_tls_header end |
#hdr ⇒ Object
Returns the value of attribute hdr.
1155 1156 1157 |
# File 'lib/rex/peparsey/pebase.rb', line 1155 def hdr @hdr end |
#header_section ⇒ Object
Returns the value of attribute header_section.
1148 1149 1150 |
# File 'lib/rex/peparsey/pebase.rb', line 1148 def header_section @header_section end |
#image_base ⇒ Object
Returns the value of attribute image_base.
1148 1149 1150 |
# File 'lib/rex/peparsey/pebase.rb', line 1148 def image_base @image_base end |
#sections ⇒ Object
Returns the value of attribute sections.
1148 1149 1150 |
# File 'lib/rex/peparsey/pebase.rb', line 1148 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…
1134 1135 1136 1137 1138 |
# File 'lib/rex/peparsey/pebase.rb', line 1134 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
213 214 215 |
# File 'lib/rex/peparsey/pebase.rb', line 213 def self._parse_file_header(rawdata) return FileHeader.new(rawdata) end |
._parse_optional_header(rawdata) ⇒ Object
571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 |
# File 'lib/rex/peparsey/pebase.rb', line 571 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
643 644 645 646 647 648 649 650 651 652 653 654 |
# File 'lib/rex/peparsey/pebase.rb', line 643 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
1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 |
# File 'lib/rex/peparsey/pebase.rb', line 1157 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
1171 1172 1173 |
# File 'lib/rex/peparsey/pebase.rb', line 1171 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
1235 1236 1237 1238 1239 1240 1241 1242 1243 |
# File 'lib/rex/peparsey/pebase.rb', line 1235 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
1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 |
# File 'lib/rex/peparsey/pebase.rb', line 1097 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
1379 1380 1381 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 |
# File 'lib/rex/peparsey/pebase.rb', line 1379 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
1308 1309 1310 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 |
# File 'lib/rex/peparsey/pebase.rb', line 1308 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
1455 1456 1457 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 |
# File 'lib/rex/peparsey/pebase.rb', line 1455 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
1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 |
# File 'lib/rex/peparsey/pebase.rb', line 1517 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 ++
832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 |
# File 'lib/rex/peparsey/pebase.rb', line 832 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
1536 1537 1538 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 |
# File 'lib/rex/peparsey/pebase.rb', line 1536 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
1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 |
# File 'lib/rex/peparsey/pebase.rb', line 1608 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
1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 |
# File 'lib/rex/peparsey/pebase.rb', line 1625 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
963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 |
# File 'lib/rex/peparsey/pebase.rb', line 963 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
1576 1577 1578 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 |
# File 'lib/rex/peparsey/pebase.rb', line 1576 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
1175 1176 1177 |
# File 'lib/rex/peparsey/pebase.rb', line 1175 def close _isource.close end |
#config ⇒ Object
857 858 859 860 |
# File 'lib/rex/peparsey/pebase.rb', line 857 def config _parse_config_header if @config.nil? @config end |
#exception ⇒ Object
1123 1124 1125 1126 |
# File 'lib/rex/peparsey/pebase.rb', line 1123 def exception _load_exception_directory if @exception.nil? @exception end |
#exports ⇒ Object
We lazily parse the exports, and then cache it
1371 1372 1373 1374 1375 1376 1377 |
# File 'lib/rex/peparsey/pebase.rb', line 1371 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
1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 |
# File 'lib/rex/peparsey/pebase.rb', line 1206 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
1220 1221 1222 |
# File 'lib/rex/peparsey/pebase.rb', line 1220 def file_offset_to_vma(foffset) return rva_to_vma(file_offset_to_rva(foffset)) end |
#find_section_by_rva(rva) ⇒ Object
1244 1245 1246 1247 1248 1249 1250 1251 1252 |
# File 'lib/rex/peparsey/pebase.rb', line 1244 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
1257 1258 1259 |
# File 'lib/rex/peparsey/pebase.rb', line 1257 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
1300 1301 1302 1303 1304 1305 1306 |
# File 'lib/rex/peparsey/pebase.rb', line 1300 def imports if !_imports_cached self._imports_cache = _load_imports self._imports_cached = true end return _imports_cache end |
#read_asciiz_rva(rva) ⇒ Object
1283 1284 1285 |
# File 'lib/rex/peparsey/pebase.rb', line 1283 def read_asciiz_rva(rva) return find_section_by_rva(rva).read_asciiz_rva(rva) end |
#read_asciiz_vma(vma) ⇒ Object
1287 1288 1289 |
# File 'lib/rex/peparsey/pebase.rb', line 1287 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…)
1275 1276 1277 |
# File 'lib/rex/peparsey/pebase.rb', line 1275 def read_rva(rva, length) return find_section_by_rva(rva).read_rva(rva, length) end |
#read_vma(vma, length) ⇒ Object
1279 1280 1281 |
# File 'lib/rex/peparsey/pebase.rb', line 1279 def read_vma(vma, length) return read_rva(vma_to_rva(vma), length) end |
#relocations ⇒ Object
Base relocations in the hizzy
1447 1448 1449 1450 1451 1452 1453 |
# File 'lib/rex/peparsey/pebase.rb', line 1447 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
1508 1509 1510 1511 1512 1513 1514 1515 |
# File 'lib/rex/peparsey/pebase.rb', line 1508 def resources if !_resources_cached _load_resources self._resources_cached = true end return self._resources_cache end |
#rva_to_file_offset(rva) ⇒ Object
1193 1194 1195 1196 1197 1198 1199 1200 |
# File 'lib/rex/peparsey/pebase.rb', line 1193 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…
1185 1186 1187 |
# File 'lib/rex/peparsey/pebase.rb', line 1185 def rva_to_vma(rva) return rva + image_base end |
#tls ⇒ Object
988 989 990 991 |
# File 'lib/rex/peparsey/pebase.rb', line 988 def tls _parse_config_header if @tls.nil? @tls end |
#update_checksum ⇒ Object
1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 |
# File 'lib/rex/peparsey/pebase.rb', line 1636 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
1261 1262 1263 |
# File 'lib/rex/peparsey/pebase.rb', line 1261 def valid_rva?(rva) _find_section_by_rva(rva) != nil end |
#valid_vma?(vma) ⇒ Boolean
1264 1265 1266 |
# File 'lib/rex/peparsey/pebase.rb', line 1264 def valid_vma?(vma) _find_section_by_rva(vma_to_rva(vma)) != nil end |
#vma_to_file_offset(vma) ⇒ Object
1202 1203 1204 |
# File 'lib/rex/peparsey/pebase.rb', line 1202 def vma_to_file_offset(vma) return rva_to_file_offset(vma_to_rva(vma)) end |
#vma_to_rva(vma) ⇒ Object
1189 1190 1191 |
# File 'lib/rex/peparsey/pebase.rb', line 1189 def vma_to_rva(vma) return vma - image_base end |