diff --git a/MemoryModule/Initialize.cpp b/MemoryModule/Initialize.cpp index a4f845d..173f337 100644 --- a/MemoryModule/Initialize.cpp +++ b/MemoryModule/Initialize.cpp @@ -158,22 +158,53 @@ PVOID FindLdrpInvertedFunctionTable64() { #define FindLdrpInvertedFunctionTable FindLdrpInvertedFunctionTable64 #endif -PLIST_ENTRY FindLdrpHashTable() { - PLIST_ENTRY list = nullptr; - PLIST_ENTRY head = &NtCurrentPeb()->Ldr->InInitializationOrderModuleList, entry = head->Flink; - PLDR_DATA_TABLE_ENTRY CurEntry = nullptr; - while (head != entry) { - CurEntry = CONTAINING_RECORD(entry, LDR_DATA_TABLE_ENTRY, LDR_DATA_TABLE_ENTRY::InInitializationOrderLinks); - entry = entry->Flink; - if (CurEntry->HashLinks.Flink == &CurEntry->HashLinks)continue; - list = CurEntry->HashLinks.Flink; - if (list->Flink == &CurEntry->HashLinks) { - list = (decltype(list))((size_t)CurEntry->HashLinks.Flink - LdrHashEntry(CurEntry->BaseDllName) * sizeof(_LIST_ENTRY)); - break; +BOOL IsValidLdrpHashTable(PLIST_ENTRY LdrpHashTable) { + + // + // Additional checks are performed to ensure that the LdrpHashTable is valid. + // + + __try { + + for (ULONG i = 0; i < LDR_HASH_TABLE_ENTRIES; ++i) { + PLIST_ENTRY head = &LdrpHashTable[i], entry = head->Flink; + + while (head != entry) { + PLDR_DATA_TABLE_ENTRY current = CONTAINING_RECORD(entry, LDR_DATA_TABLE_ENTRY, LDR_DATA_TABLE_ENTRY::HashLinks); + + if (LdrHashEntry(current->BaseDllName) != i) { + return FALSE; + } + + entry = entry->Flink; + } } - list = nullptr; + + return TRUE; } - return list; + __except (EXCEPTION_EXECUTE_HANDLER) { + return FALSE; + } + +} + +PLIST_ENTRY FindLdrpHashTable() { + PLIST_ENTRY head = &NtCurrentPeb()->Ldr->InInitializationOrderModuleList, entry = head->Flink; + + while (head != entry) { + PLDR_DATA_TABLE_ENTRY current = CONTAINING_RECORD(entry, LDR_DATA_TABLE_ENTRY, LDR_DATA_TABLE_ENTRY::InInitializationOrderLinks); + PLIST_ENTRY hashEntry = ¤t->HashLinks; + + if (hashEntry->Flink != hashEntry && hashEntry->Flink->Flink == hashEntry) { + PLIST_ENTRY table = &hashEntry->Flink[-(LONG)LdrHashEntry(current->BaseDllName)]; + + return IsValidLdrpHashTable(table) ? table : nullptr; + } + + entry = entry->Flink; + } + + return nullptr; } VOID InitializeWindowsVersion() { diff --git a/MemoryModule/LdrEntry.cpp b/MemoryModule/LdrEntry.cpp index b7ebc89..27b7a93 100644 --- a/MemoryModule/LdrEntry.cpp +++ b/MemoryModule/LdrEntry.cpp @@ -197,6 +197,7 @@ BOOL NTAPI RtlInitializeLdrDataTableEntry( BOOL NTAPI RtlFreeLdrDataTableEntry(_In_ PLDR_DATA_TABLE_ENTRY LdrEntry) { HANDLE heap = NtCurrentPeb()->ProcessHeap; switch (MmpGlobalDataPtr->WindowsVersion) { + case WINDOWS_VERSION::win11: case WINDOWS_VERSION::win10: case WINDOWS_VERSION::win10_1: case WINDOWS_VERSION::win10_2: diff --git a/MemoryModule/MmpGlobalData.h b/MemoryModule/MmpGlobalData.h index b4fa433..e0fc984 100644 --- a/MemoryModule/MmpGlobalData.h +++ b/MemoryModule/MmpGlobalData.h @@ -77,7 +77,7 @@ typedef enum class _WINDOWS_VERSION :BYTE { }WINDOWS_VERSION; #define MEMORY_MODULE_MAJOR_VERSION 1 -#define MEMORY_MODULE_MINOR_VERSION 0 +#define MEMORY_MODULE_MINOR_VERSION 1 typedef struct _MMP_GLOBAL_DATA { diff --git a/test/test.cpp b/test/test.cpp index f44c2dc..68c4bf8 100644 --- a/test/test.cpp +++ b/test/test.cpp @@ -18,6 +18,21 @@ static PVOID ReadDllFile(LPCSTR FileName) { return buffer; } +static void DisplayStatus() { + printf( + "MemoryModulePP [Version %d.%d]\n\n\tMmpFeatures = %08X\n\n\tLdrpModuleBaseAddressIndex = %p\n\tNtdllLdrEntry = %p\n\tRtlRbInsertNodeEx = %p\n\tRtlRbRemoveNode = %p\n\n\tLdrpInvertedFunctionTable = %p\n\n\tLdrpHashTable = %p\n\n", + MmpGlobalDataPtr->MajorVersion, + MmpGlobalDataPtr->MinorVersion, + MmpGlobalDataPtr->MmpFeatures, + MmpGlobalDataPtr->MmpBaseAddressIndex->LdrpModuleBaseAddressIndex, + MmpGlobalDataPtr->MmpBaseAddressIndex->NtdllLdrEntry, + MmpGlobalDataPtr->MmpBaseAddressIndex->_RtlRbInsertNodeEx, + MmpGlobalDataPtr->MmpBaseAddressIndex->_RtlRbRemoveNode, + MmpGlobalDataPtr->MmpInvertedFunctionTable->LdrpInvertedFunctionTable, + MmpGlobalDataPtr->MmpLdrEntry->LdrpHashTable + ); +} + int test() { LPVOID buffer = ReadDllFile("a.dll"); @@ -101,6 +116,8 @@ end: } int main() { + DisplayStatus(); + test(); return 0;