From bb60dc63892340f28924acc48827927b8094f0ac Mon Sep 17 00:00:00 2001 From: NotCapengeR Date: Tue, 4 Mar 2025 02:01:36 +0500 Subject: [PATCH 1/3] [FIX] Fixed RTL_INVERTED_FUNCTION_TABLE_ENTRY memory layout on 32-bits Windows 7 and below --- libpeconv/src/exceptions_parser.cpp | 40 +++++++++++++++++++++-------- 1 file changed, 30 insertions(+), 10 deletions(-) diff --git a/libpeconv/src/exceptions_parser.cpp b/libpeconv/src/exceptions_parser.cpp index 483ae9241..6f9516279 100644 --- a/libpeconv/src/exceptions_parser.cpp +++ b/libpeconv/src/exceptions_parser.cpp @@ -1,3 +1,5 @@ +// Original RtlInsertInvertedFunctionTable implementation: https://github.com/bb107/MemoryModulePP + #include "peconv/exceptions_parser.h" #include "peconv/pe_hdrs_helper.h" @@ -26,6 +28,7 @@ namespace details { SIZE_T MemoryBlockSize; } SEARCH_CONTEXT, * PSEARCH_CONTEXT; + typedef struct _NtVersion { ULONG MajorVersion; ULONG MinorVersion; @@ -46,14 +49,21 @@ namespace details { RTL_INVERTED_FUNCTION_TABLE_ENTRY_64 Entries[0x200]; } RTL_INVERTED_FUNCTION_TABLE_64, * PRTL_INVERTED_FUNCTION_TABLE_64; - // The correct data structure should be this. - // - typedef struct _RTL_INVERTED_FUNCTION_TABLE_ENTRY_WIN7_32 { + /* The correct data structure for Win8+ 32 should be this.*/ + typedef struct _RTL_INVERTED_FUNCTION_TABLE_ENTRY_WIN8_PLUS_32 { PVOID EntrySEHandlerTableEncoded; + PVOID ImageBase; + ULONG ImageSize; + ULONG SEHandlerCount; + } RTL_INVERTED_FUNCTION_TABLE_ENTRY_WIN8_PLUS_32, * PRTL_INVERTED_FUNCTION_TABLE_ENTRY_WIN8_PLUS_32; + + typedef struct _RTL_INVERTED_FUNCTION_TABLE_ENTRY_WIN7_32 { PVOID ImageBase; ULONG ImageSize; ULONG SEHandlerCount; + PVOID EntrySEHandlerTableEncoded; } RTL_INVERTED_FUNCTION_TABLE_ENTRY_WIN7_32, * PRTL_INVERTED_FUNCTION_TABLE_ENTRY_WIN7_32; + typedef struct _RTL_INVERTED_FUNCTION_TABLE_WIN7_32 { ULONG Count; ULONG MaxCount; @@ -464,10 +474,20 @@ namespace details { RtlCaptureImageExceptionValues(hModule, &SEHTable, &SEHCount); - entry.EntrySEHandlerTableEncoded = RtlEncodeSystemPointer(reinterpret_cast(SEHTable)); - entry.ImageBase = reinterpret_cast(hModule); - entry.ImageSize = ModuleHeaders->OptionalHeader.SizeOfImage; - entry.SEHandlerCount = SEHCount; + if (RtlIsWindowsVersionOrGreater(6, 2, 0)) { + //memory layout is same as x64 + auto entry2 = reinterpret_cast(&entry); + entry2->EntrySEHandlerTableEncoded = RtlEncodeSystemPointer(reinterpret_cast(SEHTable)); + entry2->ImageBase = reinterpret_cast(hModule); + entry2->ImageSize = ModuleHeaders->OptionalHeader.SizeOfImage; + entry2->SEHandlerCount = SEHCount; + } + else { + entry.EntrySEHandlerTableEncoded = RtlEncodeSystemPointer(reinterpret_cast(SEHTable)); + entry.ImageBase = reinterpret_cast(hModule); + entry.ImageSize = ModuleHeaders->OptionalHeader.SizeOfImage; + entry.SEHandlerCount = SEHCount; + } while (NT_SUCCESS(RtlFindMemoryBlockFromModuleSection(hNtdll, lpSectionName, &SearchContext))) { PRTL_INVERTED_FUNCTION_TABLE_WIN7_32 tab = reinterpret_cast(SearchContext.Result - Offset); @@ -552,9 +572,9 @@ namespace details { RtlCaptureImageExceptionValues(ImageBase, &ptr, &count); if (IsWin8OrGreater) { //memory layout is same as x64 - auto entry = reinterpret_cast(&InvertedTable->Entries[Index]); - entry->ExceptionDirectory = reinterpret_cast(RtlEncodeSystemPointer(reinterpret_cast(ptr))); - entry->ExceptionDirectorySize = count; + auto entry = reinterpret_cast(&InvertedTable->Entries[Index]); + entry->EntrySEHandlerTableEncoded = RtlEncodeSystemPointer(reinterpret_cast(ptr)); + entry->SEHandlerCount = count; entry->ImageBase = ImageBase; entry->ImageSize = SizeOfImage; } From f3bde03f65627ddbe0ce4a67b1eb40c70569d02c Mon Sep 17 00:00:00 2001 From: NotCapengeR Date: Tue, 4 Mar 2025 02:10:03 +0500 Subject: [PATCH 2/3] [TYPO] Comment typo --- libpeconv/src/exceptions_parser.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libpeconv/src/exceptions_parser.cpp b/libpeconv/src/exceptions_parser.cpp index 6f9516279..bd3acc8dd 100644 --- a/libpeconv/src/exceptions_parser.cpp +++ b/libpeconv/src/exceptions_parser.cpp @@ -492,7 +492,7 @@ namespace details { while (NT_SUCCESS(RtlFindMemoryBlockFromModuleSection(hNtdll, lpSectionName, &SearchContext))) { PRTL_INVERTED_FUNCTION_TABLE_WIN7_32 tab = reinterpret_cast(SearchContext.Result - Offset); - //Note: Same memory layout for RTL_INVERTED_FUNCTION_TABLE_ENTRY in Windows 10 x86 and x64. + //Note: Same memory layout for RTL_INVERTED_FUNCTION_TABLE_ENTRY in Windows 8 x86 and x64. if (RtlIsWindowsVersionOrGreater(6, 2, 0) && tab->MaxCount == 0x200 && !tab->NextEntrySEHandlerTableEncoded) return tab; else if (tab->MaxCount == 0x200 && !tab->Overflow) return tab; } From deda0840d34ceb33ea8333b9d38ee358c85cdcd9 Mon Sep 17 00:00:00 2001 From: NotCapengeR Date: Tue, 4 Mar 2025 02:10:52 +0500 Subject: [PATCH 3/3] Space --- libpeconv/src/exceptions_parser.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libpeconv/src/exceptions_parser.cpp b/libpeconv/src/exceptions_parser.cpp index bd3acc8dd..9e23288e0 100644 --- a/libpeconv/src/exceptions_parser.cpp +++ b/libpeconv/src/exceptions_parser.cpp @@ -470,7 +470,7 @@ namespace details { ); } ModuleHeaders = reinterpret_cast(RtlImageNtHeader(hModule)); - if (!hModule || !ModuleHeaders || !hNtdll || !NtdllHeaders)return nullptr; + if (!hModule || !ModuleHeaders || !hNtdll || !NtdllHeaders) return nullptr; RtlCaptureImageExceptionValues(hModule, &SEHTable, &SEHCount);