Skip to content

Commit e90f742

Browse files
NotCapengeRNotCapengeR
andauthored
Function table fix (#64)
* [FIX] Fixed RTL_INVERTED_FUNCTION_TABLE_ENTRY memory layout on 32-bits Windows 7 and below * [TYPO] Comment typo * Space --------- Co-authored-by: NotCapengeR <[email protected]>
1 parent d8b02e0 commit e90f742

File tree

1 file changed

+32
-12
lines changed

1 file changed

+32
-12
lines changed

libpeconv/src/exceptions_parser.cpp

Lines changed: 32 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
// Original RtlInsertInvertedFunctionTable implementation: https://github.com/bb107/MemoryModulePP
2+
13
#include "peconv/exceptions_parser.h"
24

35
#include "peconv/pe_hdrs_helper.h"
@@ -26,6 +28,7 @@ namespace details {
2628
SIZE_T MemoryBlockSize;
2729

2830
} SEARCH_CONTEXT, * PSEARCH_CONTEXT;
31+
2932
typedef struct _NtVersion {
3033
ULONG MajorVersion;
3134
ULONG MinorVersion;
@@ -46,14 +49,21 @@ namespace details {
4649
RTL_INVERTED_FUNCTION_TABLE_ENTRY_64 Entries[0x200];
4750
} RTL_INVERTED_FUNCTION_TABLE_64, * PRTL_INVERTED_FUNCTION_TABLE_64;
4851

49-
// The correct data structure should be this.
50-
//
51-
typedef struct _RTL_INVERTED_FUNCTION_TABLE_ENTRY_WIN7_32 {
52+
/* The correct data structure for Win8+ 32 should be this.*/
53+
typedef struct _RTL_INVERTED_FUNCTION_TABLE_ENTRY_WIN8_PLUS_32 {
5254
PVOID EntrySEHandlerTableEncoded;
55+
PVOID ImageBase;
56+
ULONG ImageSize;
57+
ULONG SEHandlerCount;
58+
} RTL_INVERTED_FUNCTION_TABLE_ENTRY_WIN8_PLUS_32, * PRTL_INVERTED_FUNCTION_TABLE_ENTRY_WIN8_PLUS_32;
59+
60+
typedef struct _RTL_INVERTED_FUNCTION_TABLE_ENTRY_WIN7_32 {
5361
PVOID ImageBase;
5462
ULONG ImageSize;
5563
ULONG SEHandlerCount;
64+
PVOID EntrySEHandlerTableEncoded;
5665
} RTL_INVERTED_FUNCTION_TABLE_ENTRY_WIN7_32, * PRTL_INVERTED_FUNCTION_TABLE_ENTRY_WIN7_32;
66+
5767
typedef struct _RTL_INVERTED_FUNCTION_TABLE_WIN7_32 {
5868
ULONG Count;
5969
ULONG MaxCount;
@@ -460,19 +470,29 @@ namespace details {
460470
);
461471
}
462472
ModuleHeaders = reinterpret_cast<PIMAGE_NT_HEADERS>(RtlImageNtHeader(hModule));
463-
if (!hModule || !ModuleHeaders || !hNtdll || !NtdllHeaders)return nullptr;
473+
if (!hModule || !ModuleHeaders || !hNtdll || !NtdllHeaders) return nullptr;
464474

465475
RtlCaptureImageExceptionValues(hModule, &SEHTable, &SEHCount);
466476

467-
entry.EntrySEHandlerTableEncoded = RtlEncodeSystemPointer(reinterpret_cast<PVOID>(SEHTable));
468-
entry.ImageBase = reinterpret_cast<PVOID>(hModule);
469-
entry.ImageSize = ModuleHeaders->OptionalHeader.SizeOfImage;
470-
entry.SEHandlerCount = SEHCount;
477+
if (RtlIsWindowsVersionOrGreater(6, 2, 0)) {
478+
//memory layout is same as x64
479+
auto entry2 = reinterpret_cast<PRTL_INVERTED_FUNCTION_TABLE_ENTRY_WIN8_PLUS_32>(&entry);
480+
entry2->EntrySEHandlerTableEncoded = RtlEncodeSystemPointer(reinterpret_cast<PVOID>(SEHTable));
481+
entry2->ImageBase = reinterpret_cast<PVOID>(hModule);
482+
entry2->ImageSize = ModuleHeaders->OptionalHeader.SizeOfImage;
483+
entry2->SEHandlerCount = SEHCount;
484+
}
485+
else {
486+
entry.EntrySEHandlerTableEncoded = RtlEncodeSystemPointer(reinterpret_cast<PVOID>(SEHTable));
487+
entry.ImageBase = reinterpret_cast<PVOID>(hModule);
488+
entry.ImageSize = ModuleHeaders->OptionalHeader.SizeOfImage;
489+
entry.SEHandlerCount = SEHCount;
490+
}
471491

472492
while (NT_SUCCESS(RtlFindMemoryBlockFromModuleSection(hNtdll, lpSectionName, &SearchContext))) {
473493
PRTL_INVERTED_FUNCTION_TABLE_WIN7_32 tab = reinterpret_cast<decltype(tab)>(SearchContext.Result - Offset);
474494

475-
//Note: Same memory layout for RTL_INVERTED_FUNCTION_TABLE_ENTRY in Windows 10 x86 and x64.
495+
//Note: Same memory layout for RTL_INVERTED_FUNCTION_TABLE_ENTRY in Windows 8 x86 and x64.
476496
if (RtlIsWindowsVersionOrGreater(6, 2, 0) && tab->MaxCount == 0x200 && !tab->NextEntrySEHandlerTableEncoded) return tab;
477497
else if (tab->MaxCount == 0x200 && !tab->Overflow) return tab;
478498
}
@@ -552,9 +572,9 @@ namespace details {
552572
RtlCaptureImageExceptionValues(ImageBase, &ptr, &count);
553573
if (IsWin8OrGreater) {
554574
//memory layout is same as x64
555-
auto entry = reinterpret_cast<PRTL_INVERTED_FUNCTION_TABLE_ENTRY_64>(&InvertedTable->Entries[Index]);
556-
entry->ExceptionDirectory = reinterpret_cast<PIMAGE_RUNTIME_FUNCTION_ENTRY>(RtlEncodeSystemPointer(reinterpret_cast<PVOID>(ptr)));
557-
entry->ExceptionDirectorySize = count;
575+
auto entry = reinterpret_cast<PRTL_INVERTED_FUNCTION_TABLE_ENTRY_WIN8_PLUS_32>(&InvertedTable->Entries[Index]);
576+
entry->EntrySEHandlerTableEncoded = RtlEncodeSystemPointer(reinterpret_cast<PVOID>(ptr));
577+
entry->SEHandlerCount = count;
558578
entry->ImageBase = ImageBase;
559579
entry->ImageSize = SizeOfImage;
560580
}

0 commit comments

Comments
 (0)