Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 32 additions & 12 deletions libpeconv/src/exceptions_parser.cpp
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
// Original RtlInsertInvertedFunctionTable implementation: https://github.com/bb107/MemoryModulePP

#include "peconv/exceptions_parser.h"

#include "peconv/pe_hdrs_helper.h"
Expand Down Expand Up @@ -26,6 +28,7 @@ namespace details {
SIZE_T MemoryBlockSize;

} SEARCH_CONTEXT, * PSEARCH_CONTEXT;

typedef struct _NtVersion {
ULONG MajorVersion;
ULONG MinorVersion;
Expand All @@ -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;
Expand Down Expand Up @@ -460,19 +470,29 @@ namespace details {
);
}
ModuleHeaders = reinterpret_cast<PIMAGE_NT_HEADERS>(RtlImageNtHeader(hModule));
if (!hModule || !ModuleHeaders || !hNtdll || !NtdllHeaders)return nullptr;
if (!hModule || !ModuleHeaders || !hNtdll || !NtdllHeaders) return nullptr;

RtlCaptureImageExceptionValues(hModule, &SEHTable, &SEHCount);

entry.EntrySEHandlerTableEncoded = RtlEncodeSystemPointer(reinterpret_cast<PVOID>(SEHTable));
entry.ImageBase = reinterpret_cast<PVOID>(hModule);
entry.ImageSize = ModuleHeaders->OptionalHeader.SizeOfImage;
entry.SEHandlerCount = SEHCount;
if (RtlIsWindowsVersionOrGreater(6, 2, 0)) {
//memory layout is same as x64
auto entry2 = reinterpret_cast<PRTL_INVERTED_FUNCTION_TABLE_ENTRY_WIN8_PLUS_32>(&entry);
entry2->EntrySEHandlerTableEncoded = RtlEncodeSystemPointer(reinterpret_cast<PVOID>(SEHTable));
entry2->ImageBase = reinterpret_cast<PVOID>(hModule);
entry2->ImageSize = ModuleHeaders->OptionalHeader.SizeOfImage;
entry2->SEHandlerCount = SEHCount;
}
else {
entry.EntrySEHandlerTableEncoded = RtlEncodeSystemPointer(reinterpret_cast<PVOID>(SEHTable));
entry.ImageBase = reinterpret_cast<PVOID>(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<decltype(tab)>(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;
}
Expand Down Expand Up @@ -552,9 +572,9 @@ namespace details {
RtlCaptureImageExceptionValues(ImageBase, &ptr, &count);
if (IsWin8OrGreater) {
//memory layout is same as x64
auto entry = reinterpret_cast<PRTL_INVERTED_FUNCTION_TABLE_ENTRY_64>(&InvertedTable->Entries[Index]);
entry->ExceptionDirectory = reinterpret_cast<PIMAGE_RUNTIME_FUNCTION_ENTRY>(RtlEncodeSystemPointer(reinterpret_cast<PVOID>(ptr)));
entry->ExceptionDirectorySize = count;
auto entry = reinterpret_cast<PRTL_INVERTED_FUNCTION_TABLE_ENTRY_WIN8_PLUS_32>(&InvertedTable->Entries[Index]);
entry->EntrySEHandlerTableEncoded = RtlEncodeSystemPointer(reinterpret_cast<PVOID>(ptr));
entry->SEHandlerCount = count;
entry->ImageBase = ImageBase;
entry->ImageSize = SizeOfImage;
}
Expand Down
Loading