From 0c4f334418a95d8bd2cb243dd359f944834842fd Mon Sep 17 00:00:00 2001 From: Boring Date: Fri, 30 Sep 2022 22:47:48 +0800 Subject: [PATCH 1/8] update --- MemoryModule/Initialize.cpp | 61 ++++++++++++++++++++++++++++++- test/test.cpp | 72 ++++++++++++++++++++++++++++++++++++- 2 files changed, 131 insertions(+), 2 deletions(-) diff --git a/MemoryModule/Initialize.cpp b/MemoryModule/Initialize.cpp index 032dc377..d0132115 100644 --- a/MemoryModule/Initialize.cpp +++ b/MemoryModule/Initialize.cpp @@ -1,5 +1,64 @@ #include "stdafx.h" +#include -VOID Initialize() { +BOOLEAN MmpBuildSectionName(_Out_ PUNICODE_STRING SectionName) { + WCHAR buffer[128]; + wsprintfW(buffer, L"\\Sessions\\%d\\BaseNamedObjects\\MMPP%d", NtCurrentPeb()->SessionId, (unsigned int)NtCurrentProcessId()); + return RtlCreateUnicodeString(SectionName, buffer); +} + +VOID InitializeLockHeld() { + NTSTATUS status; + HANDLE hSection; + OBJECT_ATTRIBUTES oa; + LARGE_INTEGER li; + UNICODE_STRING us{}; + + li.QuadPart = 0x1000; + + do { + + if (!MmpBuildSectionName(&us))break; + + InitializeObjectAttributes(&oa, &us, 0, nullptr, nullptr); + + status = NtCreateSection( + &hSection, + SECTION_ALL_ACCESS, + &oa, + &li, + PAGE_READWRITE, + SEC_COMMIT | SEC_BASED, + nullptr + ); + if (!NT_SUCCESS(status)) { + if (status != STATUS_OBJECT_NAME_COLLISION) break; + + status = NtOpenSection( + &hSection, + SECTION_ALL_ACCESS, + &oa + ); + if (!NT_SUCCESS(status))break; + } + + PVOID BaseAddress = 0; + SIZE_T ViewSize = 0; + status = NtMapViewOfSection( + hSection, + NtCurrentProcess(), + &BaseAddress, + 0, + 0, + nullptr, + &ViewSize, + ViewUnmap, + 0, + PAGE_READWRITE + ); + + } while (false); + + RtlFreeUnicodeString(&us); } diff --git a/test/test.cpp b/test/test.cpp index 29a047a1..4e376c4d 100644 --- a/test/test.cpp +++ b/test/test.cpp @@ -132,7 +132,77 @@ int test_user32() { return 0; } +void test() { + + NTSTATUS status; + HANDLE hSection; + OBJECT_ATTRIBUTES oa; + LARGE_INTEGER li; + UNICODE_STRING us; + SECTION_BASIC_INFORMATION sbi; + PVOID BaseAddress = 0; + SIZE_T ViewSize = 0; + + li.QuadPart = 0x1000; + + RtlInitUnicodeString(&us, L"\\Sessions\\2\\BaseNamedObjects\\SectionTest"); + + InitializeObjectAttributes(&oa, &us, 0, nullptr, nullptr); + + status = NtCreateSection( + &hSection, + SECTION_ALL_ACCESS, + &oa, + &li, + PAGE_READWRITE, + SEC_COMMIT | SEC_BASED, + nullptr + ); + + if (NT_SUCCESS(status)) { + + status = NtQuerySection( + hSection, + SECTION_INFORMATION_CLASS::SectionBasicInformation, + &sbi, + sizeof(sbi), + nullptr + ); + + status = NtMapViewOfSection( + hSection, + NtCurrentProcess(), + &BaseAddress, + 0, + 0, + nullptr, + &ViewSize, + ViewUnmap, + 0, + PAGE_READWRITE + ); + if (NT_SUCCESS(status)) { + + status = NtQuerySection( + hSection, + SECTION_INFORMATION_CLASS::SectionBasicInformation, + &sbi, + sizeof(sbi), + nullptr + ); + + status = NtUnmapViewOfSection( + NtCurrentProcess(), + BaseAddress + ); + } + + NtClose(hSection); + } + +} + int main() { - test_a_dll(); + test(); return 0; } From d6f0715c499c71e59d03ebdb144151fc8285aec2 Mon Sep 17 00:00:00 2001 From: Boring <1079299053@qq.com> Date: Sat, 1 Oct 2022 12:51:58 +0800 Subject: [PATCH 2/8] update --- MemoryModule/BaseAddressIndex.cpp | 32 +-- MemoryModule/BaseAddressIndex.h | 2 - MemoryModule/Initialize.cpp | 241 +++++++++++++++++++++- MemoryModule/InvertedFunctionTable.cpp | 163 +-------------- MemoryModule/InvertedFunctionTable.h | 9 - MemoryModule/LdrEntry.cpp | 22 +- MemoryModule/LdrEntry.h | 2 - MemoryModule/Loader.cpp | 18 +- MemoryModule/Loader.h | 7 +- MemoryModule/MemoryModule.vcxproj | 166 +++++++++++++++ MemoryModule/MemoryModule.vcxproj.filters | 6 + MemoryModule/MemoryModulePP.def | 13 ++ MemoryModule/MmpGlobalData.h | 29 +++ MemoryModule/MmpTls.cpp | 104 ++++------ MemoryModule/MmpTls.h | 2 + MemoryModule/Utils.cpp | 28 +++ MemoryModule/Utils.h | 2 + MemoryModule/stdafx.h | 3 + MemoryModulePP.sln | 12 +- test/test.cpp | 72 +------ 20 files changed, 550 insertions(+), 383 deletions(-) create mode 100644 MemoryModule/MemoryModulePP.def create mode 100644 MemoryModule/MmpGlobalData.h diff --git a/MemoryModule/BaseAddressIndex.cpp b/MemoryModule/BaseAddressIndex.cpp index f261ae7d..4fc1db5d 100644 --- a/MemoryModule/BaseAddressIndex.cpp +++ b/MemoryModule/BaseAddressIndex.cpp @@ -1,35 +1,7 @@ #include "stdafx.h" -PRTL_RB_TREE NTAPI RtlFindLdrpModuleBaseAddressIndex() { - static PRTL_RB_TREE LdrpModuleBaseAddressIndex = nullptr; - if (LdrpModuleBaseAddressIndex)return LdrpModuleBaseAddressIndex; - - PLDR_DATA_TABLE_ENTRY_WIN10 nt10 = decltype(nt10)(RtlFindNtdllLdrEntry()); - PRTL_BALANCED_NODE node = nullptr; - if (!nt10 || !RtlIsWindowsVersionOrGreater(6, 2, 0))return nullptr; - node = &nt10->BaseAddressIndexNode; - while (node->ParentValue & (~7)) node = decltype(node)(node->ParentValue & (~7)); - - if (!node->Red) { - BYTE count = 0; - PRTL_RB_TREE tmp = nullptr; - SEARCH_CONTEXT SearchContext{}; - SearchContext.MemoryBuffer = &node; - SearchContext.BufferLength = sizeof(size_t); - while (NT_SUCCESS(RtlFindMemoryBlockFromModuleSection((HMODULE)nt10->DllBase, ".data", &SearchContext))) { - if (count++)return nullptr; - tmp = (decltype(tmp))SearchContext.MemoryBlockInSection; - } - if (count && tmp && tmp->Root && tmp->Min) { - LdrpModuleBaseAddressIndex = tmp; - } - } - - return LdrpModuleBaseAddressIndex; -} - NTSTATUS NTAPI RtlInsertModuleBaseAddressIndexNode(IN PLDR_DATA_TABLE_ENTRY DataTableEntry, IN PVOID BaseAddress) { - static auto LdrpModuleBaseAddressIndex = RtlFindLdrpModuleBaseAddressIndex(); + auto LdrpModuleBaseAddressIndex = MmpGlobalDataPtr->LdrpModuleBaseAddressIndex; if (!LdrpModuleBaseAddressIndex)return STATUS_UNSUCCESSFUL; PLDR_DATA_TABLE_ENTRY_WIN8 LdrNode = decltype(LdrNode)((size_t)LdrpModuleBaseAddressIndex - offsetof(LDR_DATA_TABLE_ENTRY_WIN8, BaseAddressIndexNode)); @@ -61,7 +33,7 @@ NTSTATUS NTAPI RtlInsertModuleBaseAddressIndexNode(IN PLDR_DATA_TABLE_ENTRY Data } NTSTATUS NTAPI RtlRemoveModuleBaseAddressIndexNode(IN PLDR_DATA_TABLE_ENTRY DataTableEntry) { - static auto tree{ RtlFindLdrpModuleBaseAddressIndex() }; + static auto tree{ MmpGlobalDataPtr->LdrpModuleBaseAddressIndex }; if (!tree->Root)return STATUS_UNSUCCESSFUL; RtlRbRemoveNode(tree, &PLDR_DATA_TABLE_ENTRY_WIN8(DataTableEntry)->BaseAddressIndexNode); return STATUS_SUCCESS; diff --git a/MemoryModule/BaseAddressIndex.h b/MemoryModule/BaseAddressIndex.h index 3cb80642..c19ff532 100644 --- a/MemoryModule/BaseAddressIndex.h +++ b/MemoryModule/BaseAddressIndex.h @@ -1,7 +1,5 @@ #pragma once -PRTL_RB_TREE NTAPI RtlFindLdrpModuleBaseAddressIndex(); - NTSTATUS NTAPI RtlInsertModuleBaseAddressIndexNode(IN PLDR_DATA_TABLE_ENTRY DataTableEntry, IN PVOID BaseAddress); NTSTATUS NTAPI RtlRemoveModuleBaseAddressIndexNode(IN PLDR_DATA_TABLE_ENTRY DataTableEntry); diff --git a/MemoryModule/Initialize.cpp b/MemoryModule/Initialize.cpp index d0132115..bb5bc25f 100644 --- a/MemoryModule/Initialize.cpp +++ b/MemoryModule/Initialize.cpp @@ -1,6 +1,14 @@ #include "stdafx.h" #include +PMMP_GLOBAL_DATA MmpGlobalDataPtr; + +#ifdef _WIN64 +#define FindLdrpInvertedFunctionTable FindLdrpInvertedFunctionTable64 +#else +#define FindLdrpInvertedFunctionTable FindLdrpInvertedFunctionTable32 +#endif + BOOLEAN MmpBuildSectionName(_Out_ PUNICODE_STRING SectionName) { WCHAR buffer[128]; @@ -8,9 +16,176 @@ BOOLEAN MmpBuildSectionName(_Out_ PUNICODE_STRING SectionName) { return RtlCreateUnicodeString(SectionName, buffer); } -VOID InitializeLockHeld() { - NTSTATUS status; - HANDLE hSection; +PRTL_RB_TREE FindLdrpModuleBaseAddressIndex() { + PRTL_RB_TREE LdrpModuleBaseAddressIndex = nullptr; + PLDR_DATA_TABLE_ENTRY_WIN10 nt10 = decltype(nt10)(MmpGlobalDataPtr->LdrpNtdllBase); + PRTL_BALANCED_NODE node = nullptr; + if (!nt10 || !RtlIsWindowsVersionOrGreater(6, 2, 0))return nullptr; + node = &nt10->BaseAddressIndexNode; + while (node->ParentValue & (~7)) node = decltype(node)(node->ParentValue & (~7)); + + if (!node->Red) { + BYTE count = 0; + PRTL_RB_TREE tmp = nullptr; + SEARCH_CONTEXT SearchContext{}; + SearchContext.MemoryBuffer = &node; + SearchContext.BufferLength = sizeof(size_t); + while (NT_SUCCESS(RtlFindMemoryBlockFromModuleSection((HMODULE)nt10->DllBase, ".data", &SearchContext))) { + if (count++)return nullptr; + tmp = (decltype(tmp))SearchContext.MemoryBlockInSection; + } + if (count && tmp && tmp->Root && tmp->Min) { + LdrpModuleBaseAddressIndex = tmp; + } + } + + return LdrpModuleBaseAddressIndex; +} + +static __forceinline bool IsModuleUnloaded(PLDR_DATA_TABLE_ENTRY entry) { + if (RtlIsWindowsVersionOrGreater(6, 2, 0)) { + return PLDR_DATA_TABLE_ENTRY_WIN8(entry)->DdagNode->State == LdrModulesUnloaded; + } + else { + return entry->DllBase == nullptr; + } +} + +PVOID FindLdrpInvertedFunctionTable32() { + // _RTL_INVERTED_FUNCTION_TABLE x86 + // Count +0x0 ???????? + // MaxCount +0x4 0x00000200 + // Overflow +0x8 0x00000000(Win7) ????????(Win10) + // NextEntrySEHandlerTableEncoded +0xc 0x00000000(Win10) ++++++++(Win7) + // _RTL_INVERTED_FUNCTION_TABLE_ENTRY[0] +0x10 ntdll.dll(win10) or The smallest base module + // ImageBase +0x10 ++++++++ + // ImageSize +0x14 ++++++++ + // SEHandlerCount +0x18 ++++++++ + // NextEntrySEHandlerTableEncoded +0x1c ++++++++(Win10) ????????(Win7) + // _RTL_INVERTED_FUNCTION_TABLE_ENTRY[1] ... ... + // ...... + HMODULE hModule = nullptr, hNtdll = GetModuleHandleW(L"ntdll.dll"); + PIMAGE_NT_HEADERS NtdllHeaders = RtlImageNtHeader(hNtdll), ModuleHeaders = nullptr; + _RTL_INVERTED_FUNCTION_TABLE_ENTRY_WIN7_32 entry{}; + LPCSTR lpSectionName = ".data"; + SEARCH_CONTEXT SearchContext{ SearchContext.MemoryBuffer = &entry,SearchContext.BufferLength = sizeof(entry) }; + PLIST_ENTRY ListHead = &NtCurrentPeb()->Ldr->InMemoryOrderModuleList, + ListEntry = ListHead->Flink; + PLDR_DATA_TABLE_ENTRY CurEntry = nullptr; + DWORD SEHTable, SEHCount; + BYTE Offset = 0x20; //sizeof(_RTL_INVERTED_FUNCTION_TABLE_ENTRY)*2 + + if (RtlIsWindowsVersionOrGreater(6, 3, 0)) lpSectionName = ".mrdata"; + else if (!RtlIsWindowsVersionOrGreater(6, 2, 0)) Offset = 0xC; + + while (ListEntry != ListHead) { + CurEntry = CONTAINING_RECORD(ListEntry, LDR_DATA_TABLE_ENTRY, InMemoryOrderLinks); + ListEntry = ListEntry->Flink; + if (IsModuleUnloaded(CurEntry))continue; //skip unloaded module + if (IsValidMemoryModuleHandle((HMEMORYMODULE)CurEntry->DllBase))continue; //skip our memory module. + if (CurEntry->DllBase == hNtdll && Offset == 0x20)continue; //Win10 skip first entry, if the base of ntdll is smallest. + hModule = (HMODULE)(hModule ? min(hModule, CurEntry->DllBase) : CurEntry->DllBase); + } + ModuleHeaders = RtlImageNtHeader(hModule); + if (!hModule || !ModuleHeaders || !hNtdll || !NtdllHeaders)return nullptr; + + RtlCaptureImageExceptionValues(hModule, &SEHTable, &SEHCount); + entry = { RtlEncodeSystemPointer((PVOID)SEHTable),(DWORD)hModule,ModuleHeaders->OptionalHeader.SizeOfImage,(PVOID)SEHCount }; + + while (NT_SUCCESS(RtlFindMemoryBlockFromModuleSection(hNtdll, lpSectionName, &SearchContext))) { + PRTL_INVERTED_FUNCTION_TABLE_WIN7_32 tab = decltype(tab)(SearchContext.OutBufferPtr - Offset); + + //Note: Same memory layout for RTL_INVERTED_FUNCTION_TABLE_ENTRY in Windows 10 x86 and x64. + if (RtlIsWindowsVersionOrGreater(6, 2, 0) && tab->MaxCount == 0x200 && !tab->NextEntrySEHandlerTableEncoded) return tab; + else if (tab->MaxCount == 0x200 && !tab->Overflow) return tab; + } + + return nullptr; +} + +PVOID FindLdrpInvertedFunctionTable64() { + // _RTL_INVERTED_FUNCTION_TABLE x64 + // Count +0x0 ???????? + // MaxCount +0x4 0x00000200 + // Epoch +0x8 ???????? + // OverFlow +0xc 0x00000000 + // _RTL_INVERTED_FUNCTION_TABLE_ENTRY[0] +0x10 ntdll.dll(win10) or The smallest base module + // ExceptionDirectory +0x10 ++++++++ + // ImageBase +0x18 ++++++++ + // ImageSize +0x20 ++++++++ + // ExceptionDirectorySize +0x24 ++++++++ + // _RTL_INVERTED_FUNCTION_TABLE_ENTRY[1] ... ... + // ...... + HMODULE hModule = nullptr, hNtdll = GetModuleHandleW(L"ntdll.dll"); + PIMAGE_NT_HEADERS NtdllHeaders = RtlImageNtHeader(hNtdll), ModuleHeaders = nullptr; + _RTL_INVERTED_FUNCTION_TABLE_ENTRY_64 entry{}; + LPCSTR lpSectionName = ".data"; + PIMAGE_DATA_DIRECTORY dir = nullptr; + SEARCH_CONTEXT SearchContext{ SearchContext.MemoryBuffer = &entry,SearchContext.BufferLength = sizeof(entry) }; + + //Windows 8 + if (RtlVerifyVersion(6, 2, 0, RTL_VERIFY_FLAGS_MAJOR_VERSION | RTL_VERIFY_FLAGS_MINOR_VERSION)) { + hModule = hNtdll; + ModuleHeaders = NtdllHeaders; + //lpSectionName = ".data"; + } + //Windows 8.1 ~ Windows 10 + else if (RtlIsWindowsVersionOrGreater(6, 3, 0)) { + hModule = hNtdll; + ModuleHeaders = NtdllHeaders; + lpSectionName = ".mrdata"; + } + else { + PLIST_ENTRY ListHead = &NtCurrentPeb()->Ldr->InLoadOrderModuleList, + ListEntry = ListHead->Flink; + PLDR_DATA_TABLE_ENTRY CurEntry = nullptr; + while (ListEntry != ListHead) { + CurEntry = CONTAINING_RECORD(ListEntry, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks); + ListEntry = ListEntry->Flink; + //Make sure the smallest base address is not our memory module + if (IsValidMemoryModuleHandle((HMEMORYMODULE)CurEntry->DllBase))continue; + hModule = (HMODULE)(hModule ? min(hModule, CurEntry->DllBase) : CurEntry->DllBase); + } + ModuleHeaders = RtlImageNtHeader(hModule); + } + + if (!hModule || !ModuleHeaders || !hNtdll || !NtdllHeaders)return nullptr; + dir = &ModuleHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXCEPTION]; + entry = { + dir->Size ? decltype(entry.ExceptionDirectory)((size_t)hModule + dir->VirtualAddress) : nullptr , + (PVOID)hModule, ModuleHeaders->OptionalHeader.SizeOfImage,dir->Size + }; + + while (NT_SUCCESS(RtlFindMemoryBlockFromModuleSection(hNtdll, lpSectionName, &SearchContext))) { + PRTL_INVERTED_FUNCTION_TABLE_64 tab = decltype(tab)(SearchContext.OutBufferPtr - 0x10); + if (RtlIsWindowsVersionOrGreater(6, 2, 0) && tab->MaxCount == 0x200 && !tab->Overflow) return tab; + else if (tab->MaxCount == 0x200 && !tab->Epoch) return tab; + } + + return nullptr; +} + +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; + } + list = nullptr; + } + return list; +} + +NTSTATUS InitializeLockHeld() { + NTSTATUS status = STATUS_UNSUCCESSFUL; + HANDLE hSection = nullptr; OBJECT_ATTRIBUTES oa; LARGE_INTEGER li; UNICODE_STRING us{}; @@ -35,12 +210,26 @@ VOID InitializeLockHeld() { if (!NT_SUCCESS(status)) { if (status != STATUS_OBJECT_NAME_COLLISION) break; + HANDLE hSection2; status = NtOpenSection( - &hSection, + &hSection2, SECTION_ALL_ACCESS, &oa ); if (!NT_SUCCESS(status))break; + + SECTION_BASIC_INFORMATION sbi{}; + status = NtQuerySection( + hSection2, + SECTION_INFORMATION_CLASS::SectionBasicInformation, + &sbi, + sizeof(sbi), + nullptr + ); + + NtClose(hSection2); + MmpGlobalDataPtr = (PMMP_GLOBAL_DATA)sbi.BaseAddress; + break; } PVOID BaseAddress = 0; @@ -57,8 +246,52 @@ VOID InitializeLockHeld() { 0, PAGE_READWRITE ); + if (!NT_SUCCESS(status))break; + + MmpGlobalDataPtr = (PMMP_GLOBAL_DATA)BaseAddress; + + MmpGlobalDataPtr->MajorVersion = 1; + MmpGlobalDataPtr->MinorVersion = 0; + + MmpGlobalDataPtr->LdrpNtdllBase = RtlFindNtdllLdrEntry(); + MmpGlobalDataPtr->LdrpHashTable = FindLdrpHashTable(); + + MmpGlobalDataPtr->LdrpModuleBaseAddressIndex = FindLdrpModuleBaseAddressIndex(); + + MmpGlobalDataPtr->LdrpInvertedFunctionTable = FindLdrpInvertedFunctionTable(); + + MmpGlobalDataPtr->MmpFeatures = MEMORY_FEATURE_SUPPORT_VERSION | MEMORY_FEATURE_LDRP_HEAP | MEMORY_FEATURE_LDRP_HANDLE_TLS_DATA | MEMORY_FEATURE_LDRP_RELEASE_TLS_ENTRY; + if (MmpGlobalDataPtr->LdrpModuleBaseAddressIndex)MmpGlobalDataPtr->MmpFeatures |= MEMORY_FEATURE_MODULE_BASEADDRESS_INDEX; + if (MmpGlobalDataPtr->LdrpHashTable)MmpGlobalDataPtr->MmpFeatures |= MEMORY_FEATURE_LDRP_HASH_TABLE; + if (MmpGlobalDataPtr->LdrpInvertedFunctionTable)MmpGlobalDataPtr->MmpFeatures |= MEMORY_FEATURE_INVERTED_FUNCTION_TABLE; + + MmpTlsInitialize(); } while (false); + if (!NT_SUCCESS(status) && hSection)NtClose(hSection); RtlFreeUnicodeString(&us); + return status; +} + +NTSTATUS NTAPI Initialize() { + NTSTATUS status; + + RtlAcquirePebLock(); + status = InitializeLockHeld(); + RtlReleasePebLock(); + + return status; +} + +#ifdef _USRDLL +BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) { + if (ul_reason_for_call == DLL_PROCESS_ATTACH) { + return NT_SUCCESS(Initialize()); + } + + return TRUE; } +#else +const NTSTATUS Initializer = Initialize(); +#endif diff --git a/MemoryModule/InvertedFunctionTable.cpp b/MemoryModule/InvertedFunctionTable.cpp index 0e535105..20a59b59 100644 --- a/MemoryModule/InvertedFunctionTable.cpp +++ b/MemoryModule/InvertedFunctionTable.cpp @@ -1,16 +1,5 @@ #include "stdafx.h" -int NTAPI RtlCaptureImageExceptionValues(PVOID BaseAddress, PDWORD SEHandlerTable, PDWORD SEHandlerCount); - -static __forceinline bool NTAPI RtlIsModuleUnloaded(PLDR_DATA_TABLE_ENTRY entry) { - if (RtlIsWindowsVersionOrGreater(6, 2, 0)) { - return PLDR_DATA_TABLE_ENTRY_WIN8(entry)->DdagNode->State == LdrModulesUnloaded; - } - else { - return entry->DllBase == nullptr; - } -} - static VOID NTAPI RtlpInsertInvertedFunctionTable(IN PRTL_INVERTED_FUNCTION_TABLE InvertedTable, IN PVOID ImageBase, IN ULONG SizeOfImage) { #ifdef _WIN64 ULONG CurrentSize; @@ -147,152 +136,6 @@ static VOID NTAPI RtlpRemoveInvertedFunctionTable(IN PRTL_INVERTED_FUNCTION_TABL return; } -int NTAPI RtlCaptureImageExceptionValues(PVOID BaseAddress, PDWORD SEHandlerTable, PDWORD SEHandlerCount) { - PIMAGE_LOAD_CONFIG_DIRECTORY pLoadConfigDirectory; - PIMAGE_COR20_HEADER pCor20; - ULONG Size; - - //check if no seh - if (RtlImageNtHeader(BaseAddress)->OptionalHeader.DllCharacteristics & IMAGE_DLLCHARACTERISTICS_NO_SEH) { - *SEHandlerTable = *SEHandlerCount = -1; - return 0; - } - - //get seh table and count - pLoadConfigDirectory = (decltype(pLoadConfigDirectory))RtlImageDirectoryEntryToData(BaseAddress, TRUE, IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG, &Size); - if (pLoadConfigDirectory) { - if (Size == 0x40 && pLoadConfigDirectory->Size >= 0x48u) { - if (pLoadConfigDirectory->SEHandlerTable && pLoadConfigDirectory->SEHandlerCount) { - *SEHandlerTable = pLoadConfigDirectory->SEHandlerTable; - return *SEHandlerCount = pLoadConfigDirectory->SEHandlerCount; - } - } - } - - //is .net core ? - pCor20 = (decltype(pCor20))RtlImageDirectoryEntryToData(BaseAddress, TRUE, IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR, &Size); - *SEHandlerTable = *SEHandlerCount = ((pCor20 && pCor20->Flags & 1) ? -1 : 0); - return 0; -} - -PVOID FindLdrpInvertedFunctionTable32() { - // _RTL_INVERTED_FUNCTION_TABLE x86 - // Count +0x0 ???????? - // MaxCount +0x4 0x00000200 - // Overflow +0x8 0x00000000(Win7) ????????(Win10) - // NextEntrySEHandlerTableEncoded +0xc 0x00000000(Win10) ++++++++(Win7) - // _RTL_INVERTED_FUNCTION_TABLE_ENTRY[0] +0x10 ntdll.dll(win10) or The smallest base module - // ImageBase +0x10 ++++++++ - // ImageSize +0x14 ++++++++ - // SEHandlerCount +0x18 ++++++++ - // NextEntrySEHandlerTableEncoded +0x1c ++++++++(Win10) ????????(Win7) - // _RTL_INVERTED_FUNCTION_TABLE_ENTRY[1] ... ... - // ...... - HMODULE hModule = nullptr, hNtdll = GetModuleHandleW(L"ntdll.dll"); - PIMAGE_NT_HEADERS NtdllHeaders = RtlImageNtHeader(hNtdll), ModuleHeaders = nullptr; - _RTL_INVERTED_FUNCTION_TABLE_ENTRY_WIN7_32 entry{}; - LPCSTR lpSectionName = ".data"; - SEARCH_CONTEXT SearchContext{ SearchContext.MemoryBuffer = &entry,SearchContext.BufferLength = sizeof(entry) }; - PLIST_ENTRY ListHead = &NtCurrentPeb()->Ldr->InMemoryOrderModuleList, - ListEntry = ListHead->Flink; - PLDR_DATA_TABLE_ENTRY CurEntry = nullptr; - DWORD SEHTable, SEHCount; - BYTE Offset = 0x20; //sizeof(_RTL_INVERTED_FUNCTION_TABLE_ENTRY)*2 - - if (RtlIsWindowsVersionOrGreater(6, 3, 0)) lpSectionName = ".mrdata"; - else if (!RtlIsWindowsVersionOrGreater(6, 2, 0)) Offset = 0xC; - - while (ListEntry != ListHead) { - CurEntry = CONTAINING_RECORD(ListEntry, LDR_DATA_TABLE_ENTRY, InMemoryOrderLinks); - ListEntry = ListEntry->Flink; - if (RtlIsModuleUnloaded(CurEntry))continue; //skip unloaded module - if (IsValidMemoryModuleHandle((HMEMORYMODULE)CurEntry->DllBase))continue; //skip our memory module. - if (CurEntry->DllBase == hNtdll && Offset == 0x20)continue; //Win10 skip first entry, if the base of ntdll is smallest. - hModule = (HMODULE)(hModule ? min(hModule, CurEntry->DllBase) : CurEntry->DllBase); - } - ModuleHeaders = RtlImageNtHeader(hModule); - if (!hModule || !ModuleHeaders || !hNtdll || !NtdllHeaders)return nullptr; - - RtlCaptureImageExceptionValues(hModule, &SEHTable, &SEHCount); - entry = { RtlEncodeSystemPointer((PVOID)SEHTable),(DWORD)hModule,ModuleHeaders->OptionalHeader.SizeOfImage,(PVOID)SEHCount }; - - while (NT_SUCCESS(RtlFindMemoryBlockFromModuleSection(hNtdll, lpSectionName, &SearchContext))) { - PRTL_INVERTED_FUNCTION_TABLE_WIN7_32 tab = decltype(tab)(SearchContext.OutBufferPtr - Offset); - - //Note: Same memory layout for RTL_INVERTED_FUNCTION_TABLE_ENTRY in Windows 10 x86 and x64. - if (RtlIsWindowsVersionOrGreater(6, 2, 0) && tab->MaxCount == 0x200 && !tab->NextEntrySEHandlerTableEncoded) return tab; - else if (tab->MaxCount == 0x200 && !tab->Overflow) return tab; - } - - return nullptr; -} -PVOID FindLdrpInvertedFunctionTable64() { - // _RTL_INVERTED_FUNCTION_TABLE x64 - // Count +0x0 ???????? - // MaxCount +0x4 0x00000200 - // Epoch +0x8 ???????? - // OverFlow +0xc 0x00000000 - // _RTL_INVERTED_FUNCTION_TABLE_ENTRY[0] +0x10 ntdll.dll(win10) or The smallest base module - // ExceptionDirectory +0x10 ++++++++ - // ImageBase +0x18 ++++++++ - // ImageSize +0x20 ++++++++ - // ExceptionDirectorySize +0x24 ++++++++ - // _RTL_INVERTED_FUNCTION_TABLE_ENTRY[1] ... ... - // ...... - HMODULE hModule = nullptr, hNtdll = GetModuleHandleW(L"ntdll.dll"); - PIMAGE_NT_HEADERS NtdllHeaders = RtlImageNtHeader(hNtdll), ModuleHeaders = nullptr; - _RTL_INVERTED_FUNCTION_TABLE_ENTRY_64 entry{}; - LPCSTR lpSectionName = ".data"; - PIMAGE_DATA_DIRECTORY dir = nullptr; - SEARCH_CONTEXT SearchContext{ SearchContext.MemoryBuffer = &entry,SearchContext.BufferLength = sizeof(entry) }; - - //Windows 8 - if (RtlVerifyVersion(6, 2, 0, RTL_VERIFY_FLAGS_MAJOR_VERSION | RTL_VERIFY_FLAGS_MINOR_VERSION)) { - hModule = hNtdll; - ModuleHeaders = NtdllHeaders; - //lpSectionName = ".data"; - } - //Windows 8.1 ~ Windows 10 - else if (RtlIsWindowsVersionOrGreater(6, 3, 0)) { - hModule = hNtdll; - ModuleHeaders = NtdllHeaders; - lpSectionName = ".mrdata"; - } - else { - PLIST_ENTRY ListHead = &NtCurrentPeb()->Ldr->InLoadOrderModuleList, - ListEntry = ListHead->Flink; - PLDR_DATA_TABLE_ENTRY CurEntry = nullptr; - while (ListEntry != ListHead) { - CurEntry = CONTAINING_RECORD(ListEntry, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks); - ListEntry = ListEntry->Flink; - //Make sure the smallest base address is not our memory module - if (IsValidMemoryModuleHandle((HMEMORYMODULE)CurEntry->DllBase))continue; - hModule = (HMODULE)(hModule ? min(hModule, CurEntry->DllBase) : CurEntry->DllBase); - } - ModuleHeaders = RtlImageNtHeader(hModule); - } - - if (!hModule || !ModuleHeaders || !hNtdll || !NtdllHeaders)return nullptr; - dir = &ModuleHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXCEPTION]; - entry = { - dir->Size ? decltype(entry.ExceptionDirectory)((size_t)hModule + dir->VirtualAddress) : nullptr , - (PVOID)hModule, ModuleHeaders->OptionalHeader.SizeOfImage,dir->Size - }; - - while (NT_SUCCESS(RtlFindMemoryBlockFromModuleSection(hNtdll, lpSectionName, &SearchContext))) { - PRTL_INVERTED_FUNCTION_TABLE_64 tab = decltype(tab)(SearchContext.OutBufferPtr - 0x10); - if (RtlIsWindowsVersionOrGreater(6, 2, 0) && tab->MaxCount == 0x200 && !tab->Overflow) return tab; - else if (tab->MaxCount == 0x200 && !tab->Epoch) return tab; - } - - return nullptr; -} - - -PVOID NTAPI RtlFindLdrpInvertedFunctionTable() { - static PVOID LdrpInvertedFunctionTable = FindLdrpInvertedFunctionTable(); - return LdrpInvertedFunctionTable; -} static NTSTATUS NTAPI RtlProtectMrdata(IN SIZE_T Protect) { static PVOID MrdataBase = nullptr; static SIZE_T size = 0; @@ -303,7 +146,7 @@ static NTSTATUS NTAPI RtlProtectMrdata(IN SIZE_T Protect) { if (!MrdataBase) { MEMORY_BASIC_INFORMATION mbi{}; - status = NtQueryVirtualMemory(GetCurrentProcess(), RtlFindLdrpInvertedFunctionTable(), MemoryBasicInformation, &mbi, sizeof(mbi), nullptr); + status = NtQueryVirtualMemory(GetCurrentProcess(), MmpGlobalDataPtr->LdrpInvertedFunctionTable, MemoryBasicInformation, &mbi, sizeof(mbi), nullptr); if (!NT_SUCCESS(status))return status; MrdataBase = mbi.BaseAddress; size = mbi.RegionSize; @@ -315,7 +158,7 @@ static NTSTATUS NTAPI RtlProtectMrdata(IN SIZE_T Protect) { } NTSTATUS NTAPI RtlInsertInvertedFunctionTable(IN PVOID BaseAddress, IN size_t ImageSize) { - static auto table = PRTL_INVERTED_FUNCTION_TABLE(RtlFindLdrpInvertedFunctionTable()); + auto table = PRTL_INVERTED_FUNCTION_TABLE(MmpGlobalDataPtr->LdrpInvertedFunctionTable); if (!table)return STATUS_NOT_SUPPORTED; bool need_virtual_protect = RtlIsWindowsVersionOrGreater(6, 3, 0); NTSTATUS status; @@ -334,7 +177,7 @@ NTSTATUS NTAPI RtlInsertInvertedFunctionTable(IN PVOID BaseAddress, IN size_t Im } NTSTATUS NTAPI RtlRemoveInvertedFunctionTable(IN PVOID ImageBase) { - static auto table = PRTL_INVERTED_FUNCTION_TABLE(RtlFindLdrpInvertedFunctionTable()); + auto table = PRTL_INVERTED_FUNCTION_TABLE(MmpGlobalDataPtr->LdrpInvertedFunctionTable); bool need_virtual_protect = RtlIsWindowsVersionOrGreater(6, 3, 0); NTSTATUS status; diff --git a/MemoryModule/InvertedFunctionTable.h b/MemoryModule/InvertedFunctionTable.h index 1b43fbf5..979a3e6a 100644 --- a/MemoryModule/InvertedFunctionTable.h +++ b/MemoryModule/InvertedFunctionTable.h @@ -52,14 +52,5 @@ typedef RTL_INVERTED_FUNCTION_TABLE_WIN7_32 _RTL_INVERTED_FUNCTION_TABLE, RTL_IN typedef _RTL_INVERTED_FUNCTION_TABLE_ENTRY_WIN7_32 _RTL_INVERTED_FUNCTION_TABLE_ENTRY, RTL_INVERTED_FUNCTION_TABLE_ENTRY, * PRTL_INVERTED_FUNCTION_TABLE_ENTRY; #endif -PVOID NTAPI RtlFindLdrpInvertedFunctionTable(); - NTSTATUS NTAPI RtlInsertInvertedFunctionTable(IN PVOID BaseAddress, IN size_t ImageSize); NTSTATUS NTAPI RtlRemoveInvertedFunctionTable(IN PVOID ImageBase); - - -#ifdef _WIN64 -#define FindLdrpInvertedFunctionTable FindLdrpInvertedFunctionTable64 -#else -#define FindLdrpInvertedFunctionTable FindLdrpInvertedFunctionTable32 -#endif diff --git a/MemoryModule/LdrEntry.cpp b/MemoryModule/LdrEntry.cpp index 30e02fd0..6d62fbd9 100644 --- a/MemoryModule/LdrEntry.cpp +++ b/MemoryModule/LdrEntry.cpp @@ -254,7 +254,7 @@ NTSTATUS NTAPI RtlGetReferenceCount(IN PMEMORYMODULE pModule, OUT PULONG Count) VOID NTAPI RtlInsertMemoryTableEntry(IN PLDR_DATA_TABLE_ENTRY LdrEntry) { PPEB_LDR_DATA PebData = NtCurrentPeb()->Ldr; - PLIST_ENTRY LdrpHashTable = RtlFindLdrpHashTable(); + PLIST_ENTRY LdrpHashTable = MmpGlobalDataPtr->LdrpHashTable; ULONG i; /* Insert into hash table */ @@ -319,26 +319,6 @@ ULONG NTAPI LdrHashEntry(IN UNICODE_STRING& str, IN bool _xor) { return result; } -PLIST_ENTRY NTAPI RtlFindLdrpHashTable() { - static PLIST_ENTRY list = nullptr; - if (list) return list; - - 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; - } - list = nullptr; - } - return list; -} - size_t NTAPI LdrpDataTableEntrySize() { static size_t size = 0; if (size)return size; diff --git a/MemoryModule/LdrEntry.h b/MemoryModule/LdrEntry.h index 56a6b198..8a416944 100644 --- a/MemoryModule/LdrEntry.h +++ b/MemoryModule/LdrEntry.h @@ -334,8 +334,6 @@ typedef struct _LDR_DATA_TABLE_ENTRY_WIN10_2 { ULONG NTAPI LdrHashEntry(IN UNICODE_STRING& str, IN bool _xor = true); -PLIST_ENTRY NTAPI RtlFindLdrpHashTable(); - #define RtlInitializeListEntry(entry) ((entry)->Blink = (entry)->Flink = (entry)) #define RtlInitializeSingleEntry(entry) ((entry->Next = (entry))) diff --git a/MemoryModule/Loader.cpp b/MemoryModule/Loader.cpp index 9a4f64dc..5dbf8360 100644 --- a/MemoryModule/Loader.cpp +++ b/MemoryModule/Loader.cpp @@ -285,24 +285,10 @@ VOID NTAPI LdrUnloadDllMemoryAndExitThread(IN HMEMORYMODULE BaseAddress, IN DWOR RtlExitUserThread(dwExitCode); } -NTSTATUS NTAPI LdrQuerySystemMemoryModuleFeatures(OUT PDWORD pFeatures) { - static DWORD features = 0; +NTSTATUS NTAPI LdrQuerySystemMemoryModuleFeatures(_Out_ PDWORD pFeatures) { NTSTATUS status = STATUS_SUCCESS; - PVOID pfn = nullptr; - bool value = false; __try { - if (features) { - *pFeatures = features; - return status; - } - - if (RtlFindLdrpModuleBaseAddressIndex())features |= MEMORY_FEATURE_MODULE_BASEADDRESS_INDEX; - if (RtlFindLdrpHashTable())features |= MEMORY_FEATURE_LDRP_HASH_TABLE; - if (RtlFindLdrpInvertedFunctionTable())features |= MEMORY_FEATURE_INVERTED_FUNCTION_TABLE; - features |= MEMORY_FEATURE_LDRP_HEAP | MEMORY_FEATURE_LDRP_HANDLE_TLS_DATA | MEMORY_FEATURE_LDRP_RELEASE_TLS_ENTRY; - - if (features)features |= MEMORY_FEATURE_SUPPORT_VERSION; - *pFeatures = features; + *pFeatures = MmpGlobalDataPtr->MmpFeatures; } __except (EXCEPTION_EXECUTE_HANDLER) { status = GetExceptionCode(); diff --git a/MemoryModule/Loader.h b/MemoryModule/Loader.h index b171318d..9217b124 100644 --- a/MemoryModule/Loader.h +++ b/MemoryModule/Loader.h @@ -17,7 +17,7 @@ NTSTATUS NTAPI LdrLoadDllMemory( #define MEMORY_FEATURE_ALL 0x0000007f //Get the implementation of the currently running operating system. -NTSTATUS NTAPI LdrQuerySystemMemoryModuleFeatures(OUT PDWORD pFeatures); +NTSTATUS NTAPI LdrQuerySystemMemoryModuleFeatures(_Out_ PDWORD pFeatures); /* @@ -78,6 +78,7 @@ NTSTATUS NTAPI LdrLoadDllMemoryExA( //Unload modules previously loaded from memory NTSTATUS NTAPI LdrUnloadDllMemory(IN HMEMORYMODULE BaseAddress); +#ifndef _USRDLL #ifdef _WIN64 #pragma comment(linker,"/export:LdrUnloadDllMemoryAndExitThread") #pragma comment(linker,"/export:FreeLibraryMemoryAndExitThread=LdrUnloadDllMemoryAndExitThread") @@ -85,8 +86,8 @@ NTSTATUS NTAPI LdrUnloadDllMemory(IN HMEMORYMODULE BaseAddress); #pragma comment(linker,"/export:LdrUnloadDllMemoryAndExitThread=_LdrUnloadDllMemoryAndExitThread@8") #pragma comment(linker,"/export:FreeLibraryMemoryAndExitThread=_LdrUnloadDllMemoryAndExitThread@8") #endif -//FreeLibraryMemoryAndExitThread = GetProcAddress(GetModuleHandleW(nullptr), "FreeLibraryMemoryAndExitThread"); -//FreeLibraryMemoryAndExitThread(hModule, 0); +#endif + extern "C" { __declspec(noreturn) VOID NTAPI LdrUnloadDllMemoryAndExitThread(IN HMEMORYMODULE BaseAddress, IN DWORD dwExitCode); } diff --git a/MemoryModule/MemoryModule.vcxproj b/MemoryModule/MemoryModule.vcxproj index 8df50e56..526246d8 100644 --- a/MemoryModule/MemoryModule.vcxproj +++ b/MemoryModule/MemoryModule.vcxproj @@ -1,10 +1,26 @@ + + DebugDll + Win32 + + + DebugDll + x64 + Debug Win32 + + ReleaseDll + Win32 + + + ReleaseDll + x64 + Release Win32 @@ -77,6 +93,7 @@ + @@ -87,6 +104,7 @@ + 16.0 @@ -103,6 +121,12 @@ v142 Unicode + + DynamicLibrary + true + v142 + Unicode + StaticLibrary false @@ -110,6 +134,13 @@ true Unicode + + DynamicLibrary + false + v142 + true + Unicode + StaticLibrary true @@ -117,6 +148,13 @@ Unicode false + + DynamicLibrary + true + v142 + Unicode + false + StaticLibrary false @@ -124,6 +162,13 @@ true Unicode + + DynamicLibrary + false + v142 + true + Unicode + @@ -133,32 +178,65 @@ + + + + + + + + + + + + true $(VC_IncludePath);$(WindowsSDK_IncludePath);$(SolutionDir); + $(SolutionDir)$(Configuration)\ + + + true + $(VC_IncludePath);$(WindowsSDK_IncludePath);$(SolutionDir); + $(SolutionDir)Debug\ true $(VC_IncludePath);$(WindowsSDK_IncludePath);$(SolutionDir); + + true + $(VC_IncludePath);$(WindowsSDK_IncludePath);$(SolutionDir); + $(SolutionDir)$(Platform)\Debug\ + false $(VC_IncludePath);$(WindowsSDK_IncludePath);$(SolutionDir); + + false + $(VC_IncludePath);$(WindowsSDK_IncludePath);$(SolutionDir); + $(SolutionDir)Release\ + false $(VC_IncludePath);$(WindowsSDK_IncludePath);$(SolutionDir); + + false + $(VC_IncludePath);$(WindowsSDK_IncludePath);$(SolutionDir); + $(SolutionDir)$(Platform)\Release\ + NotUsing @@ -174,6 +252,26 @@ Windows true + MemoryModulePP.def + + + + + NotUsing + Level3 + true + WIN32;_DEBUG;_USRDLL;%(PreprocessorDefinitions) + true + + + + + MultiThreadedDebug + + + Windows + true + MemoryModulePP.def @@ -191,6 +289,26 @@ Windows true + MemoryModulePP.def + + + + + NotUsing + Level3 + true + _DEBUG;_USRDLL;%(PreprocessorDefinitions) + true + + + + + MultiThreadedDebug + + + Windows + true + MemoryModulePP.def @@ -212,6 +330,30 @@ true true true + MemoryModulePP.def + + + + + NotUsing + Level3 + true + true + true + WIN32;NDEBUG;_USRDLL;%(PreprocessorDefinitions) + true + + + + + MultiThreaded + + + Windows + true + true + true + MemoryModulePP.def @@ -233,6 +375,30 @@ true true true + MemoryModulePP.def + + + + + NotUsing + Level3 + true + true + true + NDEBUG;_USRDLL;%(PreprocessorDefinitions) + true + + + + + MultiThreaded + + + Windows + true + true + true + MemoryModulePP.def diff --git a/MemoryModule/MemoryModule.vcxproj.filters b/MemoryModule/MemoryModule.vcxproj.filters index e32c49b5..2aa9155c 100644 --- a/MemoryModule/MemoryModule.vcxproj.filters +++ b/MemoryModule/MemoryModule.vcxproj.filters @@ -221,10 +221,16 @@ Header Files\3rdparty\phnt + + Header Files + Resource Files + + Resource Files + \ No newline at end of file diff --git a/MemoryModule/MemoryModulePP.def b/MemoryModule/MemoryModulePP.def new file mode 100644 index 00000000..90108a6f --- /dev/null +++ b/MemoryModule/MemoryModulePP.def @@ -0,0 +1,13 @@ +LIBRARY +EXPORTS +LoadLibraryMemory +LoadLibraryMemoryExA +LoadLibraryMemoryExW +FreeLibraryMemory + +LdrLoadDllMemory +LdrLoadDllMemoryExA +LdrLoadDllMemoryExW +LdrUnloadDllMemory +LdrUnloadDllMemoryAndExitThread +LdrQuerySystemMemoryModuleFeatures \ No newline at end of file diff --git a/MemoryModule/MmpGlobalData.h b/MemoryModule/MmpGlobalData.h new file mode 100644 index 00000000..3470c183 --- /dev/null +++ b/MemoryModule/MmpGlobalData.h @@ -0,0 +1,29 @@ +#pragma once + +typedef struct _MMP_GLOBAL_DATA { + + WORD MajorVersion; + WORD MinorVersion; + + DWORD MmpFeatures; + + //BaseAddressIndex.cpp + PRTL_RB_TREE LdrpModuleBaseAddressIndex; + + //InvertedFunctionTable.cpp + PVOID LdrpInvertedFunctionTable; + + //LdrEntry.cpp + PLDR_DATA_TABLE_ENTRY LdrpNtdllBase; + PLIST_ENTRY LdrpHashTable; + + //MmpTls.cpp + LIST_ENTRY MmpTlsList; + RTL_BITMAP MmpTlsBitmap; + SRWLOCK MmpTlsListLock; + CRITICAL_SECTION MmpTlspLock; + LIST_ENTRY MmpThreadLocalStoragePointer; + DWORD MmpActiveThreadCount; +}MMP_GLOBAL_DATA, * PMMP_GLOBAL_DATA; + +extern PMMP_GLOBAL_DATA MmpGlobalDataPtr; \ No newline at end of file diff --git a/MemoryModule/MmpTls.cpp b/MemoryModule/MmpTls.cpp index 0d45cfd5..aa3e65bc 100644 --- a/MemoryModule/MmpTls.cpp +++ b/MemoryModule/MmpTls.cpp @@ -42,11 +42,6 @@ typedef struct _TLS_ENTRY { PLDR_DATA_TABLE_ENTRY ModuleEntry; } TLS_ENTRY, * PTLS_ENTRY; -LIST_ENTRY MmpTlsList; -RTL_BITMAP MmpTlsBitmap; -SRWLOCK MmpTlsListLock; - - typedef struct _MMP_TLSP_RECORD { LIST_ENTRY InMmpThreadLocalStoragePointer; @@ -60,11 +55,6 @@ typedef struct _MMP_TLSP_RECORD { PVOID* TlspMmpBlock; }MMP_TLSP_RECORD, * PMMP_TLSP_RECORD; -CRITICAL_SECTION MmpTlspLock; -LIST_ENTRY MmpThreadLocalStoragePointer; -DWORD MmpActiveThreadCount; - - decltype(&NtCreateThread) OriginNtCreateThread = NtCreateThread; decltype(&NtCreateThreadEx) OriginNtCreateThreadEx = NtCreateThreadEx; decltype(&NtSetInformationProcess) OriginNtSetInformationProcess = NtSetInformationProcess; @@ -169,7 +159,7 @@ DWORD NTAPI MmpUserThreadStart(LPVOID lpThreadParameter) { // // Allocate and replace ThreadLocalStoragePointer for new thread // - EnterCriticalSection(&MmpTlspLock); + EnterCriticalSection(&MmpGlobalDataPtr->MmpTlspLock); record = PMMP_TLSP_RECORD(RtlAllocateHeap(RtlProcessHeap(), 0, sizeof(MMP_TLSP_RECORD))); if (record) { @@ -187,7 +177,7 @@ DWORD NTAPI MmpUserThreadStart(LPVOID lpThreadParameter) { NtCurrentTeb()->ThreadLocalStoragePointer = record->TlspMmpBlock; - InsertTailList(&MmpThreadLocalStoragePointer, &record->InMmpThreadLocalStoragePointer); + InsertTailList(&MmpGlobalDataPtr->MmpThreadLocalStoragePointer, &record->InMmpThreadLocalStoragePointer); success = true; } else { @@ -195,17 +185,17 @@ DWORD NTAPI MmpUserThreadStart(LPVOID lpThreadParameter) { } } - LeaveCriticalSection(&MmpTlspLock); + LeaveCriticalSection(&MmpGlobalDataPtr->MmpTlspLock); // // Handle MemoryModule Tls data // if (success) { - RtlAcquireSRWLockShared(&MmpTlsListLock); + RtlAcquireSRWLockShared(&MmpGlobalDataPtr->MmpTlsListLock); auto ThreadLocalStoragePointer = (PVOID*)NtCurrentTeb()->ThreadLocalStoragePointer; - PLIST_ENTRY entry = MmpTlsList.Flink; - while (entry != &MmpTlsList) { + PLIST_ENTRY entry = MmpGlobalDataPtr->MmpTlsList.Flink; + while (entry != &MmpGlobalDataPtr->MmpTlsList) { PTLS_ENTRY tls = CONTAINING_RECORD(entry, TLS_ENTRY, TlsEntryLinks); auto len = tls->TlsDirectory.EndAddressOfRawData - tls->TlsDirectory.StartAddressOfRawData; @@ -227,16 +217,16 @@ DWORD NTAPI MmpUserThreadStart(LPVOID lpThreadParameter) { entry = entry->Flink; } - RtlReleaseSRWLockShared(&MmpTlsListLock); + RtlReleaseSRWLockShared(&MmpGlobalDataPtr->MmpTlsListLock); } if (!success) { return ERROR_NOT_ENOUGH_MEMORY; } - EnterCriticalSection(&MmpTlspLock); - ++MmpActiveThreadCount; - LeaveCriticalSection(&MmpTlspLock); + EnterCriticalSection(&MmpGlobalDataPtr->MmpTlspLock); + ++MmpGlobalDataPtr->MmpActiveThreadCount; + LeaveCriticalSection(&MmpGlobalDataPtr->MmpTlspLock); __skip_tls: return Context.ThreadStartRoutine(Context.ThreadParameter); @@ -337,10 +327,10 @@ VOID NTAPI HookLdrShutdownThread(VOID) { // // Find our tlsp record // - EnterCriticalSection(&MmpTlspLock); + EnterCriticalSection(&MmpGlobalDataPtr->MmpTlspLock); - entry = MmpThreadLocalStoragePointer.Flink; - while (entry != &MmpThreadLocalStoragePointer) { + entry = MmpGlobalDataPtr->MmpThreadLocalStoragePointer.Flink; + while (entry != &MmpGlobalDataPtr->MmpThreadLocalStoragePointer) { auto p = CONTAINING_RECORD(entry, MMP_TLSP_RECORD, InMmpThreadLocalStoragePointer); if (p->UniqueThread == NtCurrentThreadId()) { @@ -359,19 +349,19 @@ VOID NTAPI HookLdrShutdownThread(VOID) { entry = entry->Flink; } - --MmpActiveThreadCount; + --MmpGlobalDataPtr->MmpActiveThreadCount; - LeaveCriticalSection(&MmpTlspLock); + LeaveCriticalSection(&MmpGlobalDataPtr->MmpTlspLock); // // Free MemoryModule Tls data // - RtlAcquireSRWLockExclusive(&MmpTlsListLock); + RtlAcquireSRWLockExclusive(&MmpGlobalDataPtr->MmpTlsListLock); if (record) { auto TlspMmpBlock = (PVOID*)record->TlspMmpBlock; - entry = MmpTlsList.Flink; - while (entry != &MmpTlsList) { + entry = MmpGlobalDataPtr->MmpTlsList.Flink; + while (entry != &MmpGlobalDataPtr->MmpTlsList) { auto p = CONTAINING_RECORD(entry, TLS_ENTRY, TlsEntryLinks); RtlFreeHeap(RtlProcessHeap(), 0, TlspMmpBlock[p->TlsDirectory.Characteristics]); @@ -382,12 +372,12 @@ VOID NTAPI HookLdrShutdownThread(VOID) { RtlFreeHeap(RtlProcessHeap(), 0, TlspMmpBlock); } else { - if (MmpTlsList.Flink != &MmpTlsList) { + if (MmpGlobalDataPtr->MmpTlsList.Flink != &MmpGlobalDataPtr->MmpTlsList) { assert(false); } } - RtlReleaseSRWLockExclusive(&MmpTlsListLock); + RtlReleaseSRWLockExclusive(&MmpGlobalDataPtr->MmpTlsListLock); // // Call the original function @@ -443,7 +433,7 @@ BOOL NTAPI PreHookNtSetInformationProcess() { ); if (NT_SUCCESS(status)) { - EnterCriticalSection(&MmpTlspLock); + EnterCriticalSection(&MmpGlobalDataPtr->MmpTlspLock); for (DWORD i = 0; i < CurrentThreadCount; ++i) { auto const& LdrTls = ProcessTlsInformation->ThreadData[i]; auto const& MmpTls = tmpTlsInformation->ThreadData[i]; @@ -453,9 +443,9 @@ BOOL NTAPI PreHookNtSetInformationProcess() { record->TlspLdrBlock = LdrTls.TlsVector; record->TlspMmpBlock = MmpTls.TlsVector; record->UniqueThread = LdrTls.ThreadId; - InsertTailList(&MmpThreadLocalStoragePointer, &record->InMmpThreadLocalStoragePointer); + InsertTailList(&MmpGlobalDataPtr->MmpThreadLocalStoragePointer, &record->InMmpThreadLocalStoragePointer); } - LeaveCriticalSection(&MmpTlspLock); + LeaveCriticalSection(&MmpGlobalDataPtr->MmpTlspLock); } } @@ -557,14 +547,14 @@ NTSTATUS NTAPI HookNtSetInformationProcess( // // Modify our mapping // - EnterCriticalSection(&MmpTlspLock); + EnterCriticalSection(&MmpGlobalDataPtr->MmpTlspLock); for (auto i = 0; i < Tls->ThreadDataCount; ++i) { bool found = false; - PLIST_ENTRY entry = MmpThreadLocalStoragePointer.Flink; + PLIST_ENTRY entry = MmpGlobalDataPtr->MmpThreadLocalStoragePointer.Flink; // Find thread-spec tlsp - while (entry != &MmpThreadLocalStoragePointer) { + while (entry != &MmpGlobalDataPtr->MmpThreadLocalStoragePointer) { PMMP_TLSP_RECORD j = CONTAINING_RECORD(entry, MMP_TLSP_RECORD, InMmpThreadLocalStoragePointer); @@ -608,7 +598,7 @@ NTSTATUS NTAPI HookNtSetInformationProcess( ProcessTlsInformation->ThreadData[i].ThreadId = Tls->ThreadData[i].ThreadId; } } - LeaveCriticalSection(&MmpTlspLock); + LeaveCriticalSection(&MmpGlobalDataPtr->MmpTlspLock); } while (false); @@ -620,7 +610,7 @@ NTSTATUS NTAPI MmpAcquireTlsIndex(_Out_ PULONG TlsIndex) { *TlsIndex = -1; - ULONG Index = RtlFindClearBitsAndSet(&MmpTlsBitmap, 1, 0); + ULONG Index = RtlFindClearBitsAndSet(&MmpGlobalDataPtr->MmpTlsBitmap, 1, 0); if (Index != -1) { *TlsIndex = Index; return STATUS_SUCCESS; @@ -681,9 +671,9 @@ NTSTATUS NTAPI MmpAllocateTlsEntry( Entry->TlsDirectory.Characteristics = *PULONG(Entry->TlsDirectory.AddressOfIndex) = TlsIndex; - RtlAcquireSRWLockExclusive(&MmpTlsListLock); - InsertTailList(&MmpTlsList, &Entry->TlsEntryLinks); - RtlReleaseSRWLockExclusive(&MmpTlsListLock); + RtlAcquireSRWLockExclusive(&MmpGlobalDataPtr->MmpTlsListLock); + InsertTailList(&MmpGlobalDataPtr->MmpTlsList, &Entry->TlsEntryLinks); + RtlReleaseSRWLockExclusive(&MmpGlobalDataPtr->MmpTlsListLock); *lpTlsEntry = Entry; *lpTlsIndex = TlsIndex; @@ -692,20 +682,20 @@ NTSTATUS NTAPI MmpAllocateTlsEntry( NTSTATUS NTAPI MmpReleaseTlsEntry(_In_ PLDR_DATA_TABLE_ENTRY lpModuleEntry) { - RtlAcquireSRWLockExclusive(&MmpTlsListLock); + RtlAcquireSRWLockExclusive(&MmpGlobalDataPtr->MmpTlsListLock); - for (auto entry = MmpTlsList.Flink; entry != &MmpTlsList; entry = entry->Flink) { + for (auto entry = MmpGlobalDataPtr->MmpTlsList.Flink; entry != &MmpGlobalDataPtr->MmpTlsList; entry = entry->Flink) { auto p = CONTAINING_RECORD(entry, TLS_ENTRY, TlsEntryLinks); if (p->ModuleEntry == lpModuleEntry) { RemoveEntryList(&p->TlsEntryLinks); - RtlClearBit(&MmpTlsBitmap, p->TlsDirectory.Characteristics); + RtlClearBit(&MmpGlobalDataPtr->MmpTlsBitmap, p->TlsDirectory.Characteristics); RtlFreeHeap(RtlProcessHeap(), 0, p); break; } } - RtlReleaseSRWLockExclusive(&MmpTlsListLock); + RtlReleaseSRWLockExclusive(&MmpGlobalDataPtr->MmpTlsListLock); return STATUS_SUCCESS; } @@ -738,7 +728,7 @@ NTSTATUS NTAPI MmpHandleTlsData(_In_ PLDR_DATA_TABLE_ENTRY lpModuleEntry) { return STATUS_INSUFFICIENT_RESOURCES; } - auto ThreadCount = MmpActiveThreadCount; + auto ThreadCount = MmpGlobalDataPtr->MmpActiveThreadCount; auto success = true; auto Length = sizeof(PROCESS_TLS_INFORMATION) + (ThreadCount - 1) * sizeof(THREAD_TLS_INFORMATION); auto ProcessTlsInformation = PPROCESS_TLS_INFORMATION(RtlAllocateHeap(RtlProcessHeap(), HEAP_ZERO_MEMORY, Length)); @@ -795,8 +785,7 @@ NTSTATUS NTAPI MmpHandleTlsData(_In_ PLDR_DATA_TABLE_ENTRY lpModuleEntry) { return status; } - -BOOL NTAPI MmpInitialize() { +BOOL NTAPI MmpTlsInitialize() { auto tls = CONTAINING_RECORD(NtCurrentTeb()->ThreadLocalStoragePointer, TLS_VECTOR, TLS_VECTOR::ModuleTlsData); if (tls && tls->Length > MMP_START_TLS_INDEX) { @@ -807,27 +796,26 @@ BOOL NTAPI MmpInitialize() { // // Capture thread count // - MmpActiveThreadCount = MmpGetThreadCount(); + MmpGlobalDataPtr->MmpActiveThreadCount = MmpGetThreadCount(); // // Initialize tlsp // - InitializeCriticalSection(&MmpTlspLock); - InitializeListHead(&MmpThreadLocalStoragePointer); + InitializeCriticalSection(&MmpGlobalDataPtr->MmpTlspLock); + InitializeListHead(&MmpGlobalDataPtr->MmpThreadLocalStoragePointer); // // Initialize tls list // - InitializeListHead(&MmpTlsList); - RtlInitializeSRWLock(&MmpTlsListLock); + InitializeListHead(&MmpGlobalDataPtr->MmpTlsList); + RtlInitializeSRWLock(&MmpGlobalDataPtr->MmpTlsListLock); PULONG buffer = PULONG(RtlAllocateHeap(RtlProcessHeap(), HEAP_ZERO_MEMORY, MMP_TLSP_INDEX_BUFFER_SIZE)); - if (!buffer) { - RtlRaiseStatus(STATUS_NO_MEMORY); - } + if (!buffer) RtlRaiseStatus(STATUS_NO_MEMORY); + RtlFillMemory(buffer, MMP_START_TLS_INDEX / 8, -1); - RtlInitializeBitMap(&MmpTlsBitmap, buffer, MMP_MAXIMUM_TLS_INDEX); + RtlInitializeBitMap(&MmpGlobalDataPtr->MmpTlsBitmap, buffer, MMP_MAXIMUM_TLS_INDEX); if (NtCurrentTeb()->ThreadLocalStoragePointer) { if (!PreHookNtSetInformationProcess()) { @@ -848,5 +836,3 @@ BOOL NTAPI MmpInitialize() { return TRUE; } - -static const BOOL MmpStaticInitializer = MmpInitialize(); diff --git a/MemoryModule/MmpTls.h b/MemoryModule/MmpTls.h index f6c49502..ebcc64a4 100644 --- a/MemoryModule/MmpTls.h +++ b/MemoryModule/MmpTls.h @@ -1,5 +1,7 @@ #pragma once +BOOL NTAPI MmpTlsInitialize(); + NTSTATUS NTAPI MmpReleaseTlsEntry(PLDR_DATA_TABLE_ENTRY lpModuleEntry); NTSTATUS NTAPI MmpHandleTlsData(PLDR_DATA_TABLE_ENTRY lpModuleEntry); diff --git a/MemoryModule/Utils.cpp b/MemoryModule/Utils.cpp index 155b6bae..3fe4e270 100644 --- a/MemoryModule/Utils.cpp +++ b/MemoryModule/Utils.cpp @@ -408,3 +408,31 @@ WINDOWS_VERSION NTAPI NtWindowsVersion() { } return version = invalid; } + +int NTAPI RtlCaptureImageExceptionValues(PVOID BaseAddress, PDWORD SEHandlerTable, PDWORD SEHandlerCount) { + PIMAGE_LOAD_CONFIG_DIRECTORY pLoadConfigDirectory; + PIMAGE_COR20_HEADER pCor20; + ULONG Size; + + //check if no seh + if (RtlImageNtHeader(BaseAddress)->OptionalHeader.DllCharacteristics & IMAGE_DLLCHARACTERISTICS_NO_SEH) { + *SEHandlerTable = *SEHandlerCount = -1; + return 0; + } + + //get seh table and count + pLoadConfigDirectory = (decltype(pLoadConfigDirectory))RtlImageDirectoryEntryToData(BaseAddress, TRUE, IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG, &Size); + if (pLoadConfigDirectory) { + if (Size == 0x40 && pLoadConfigDirectory->Size >= 0x48u) { + if (pLoadConfigDirectory->SEHandlerTable && pLoadConfigDirectory->SEHandlerCount) { + *SEHandlerTable = pLoadConfigDirectory->SEHandlerTable; + return *SEHandlerCount = pLoadConfigDirectory->SEHandlerCount; + } + } + } + + //is .net core ? + pCor20 = (decltype(pCor20))RtlImageDirectoryEntryToData(BaseAddress, TRUE, IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR, &Size); + *SEHandlerTable = *SEHandlerCount = ((pCor20 && pCor20->Flags & 1) ? -1 : 0); + return 0; +} diff --git a/MemoryModule/Utils.h b/MemoryModule/Utils.h index d5183e4e..afe375de 100644 --- a/MemoryModule/Utils.h +++ b/MemoryModule/Utils.h @@ -86,3 +86,5 @@ typedef enum _WINDOWS_VERSION { }WINDOWS_VERSION; WINDOWS_VERSION NTAPI NtWindowsVersion(); + +int NTAPI RtlCaptureImageExceptionValues(PVOID BaseAddress, PDWORD SEHandlerTable, PDWORD SEHandlerCount); diff --git a/MemoryModule/stdafx.h b/MemoryModule/stdafx.h index 226baf32..0affb02e 100644 --- a/MemoryModule/stdafx.h +++ b/MemoryModule/stdafx.h @@ -34,3 +34,6 @@ //utils #include "Utils.h" + +//global data +#include "MmpGlobalData.h" \ No newline at end of file diff --git a/MemoryModulePP.sln b/MemoryModulePP.sln index 0b985a5c..77f852f9 100644 --- a/MemoryModulePP.sln +++ b/MemoryModulePP.sln @@ -19,12 +19,12 @@ Global GlobalSection(ProjectConfigurationPlatforms) = postSolution {5B1F46DB-036E-4A50-AF5F-F5D6584D42C6}.Debug|x64.ActiveCfg = Debug|x64 {5B1F46DB-036E-4A50-AF5F-F5D6584D42C6}.Debug|x64.Build.0 = Debug|x64 - {5B1F46DB-036E-4A50-AF5F-F5D6584D42C6}.Debug|x86.ActiveCfg = Debug|Win32 - {5B1F46DB-036E-4A50-AF5F-F5D6584D42C6}.Debug|x86.Build.0 = Debug|Win32 - {5B1F46DB-036E-4A50-AF5F-F5D6584D42C6}.Release|x64.ActiveCfg = Release|x64 - {5B1F46DB-036E-4A50-AF5F-F5D6584D42C6}.Release|x64.Build.0 = Release|x64 - {5B1F46DB-036E-4A50-AF5F-F5D6584D42C6}.Release|x86.ActiveCfg = Release|Win32 - {5B1F46DB-036E-4A50-AF5F-F5D6584D42C6}.Release|x86.Build.0 = Release|Win32 + {5B1F46DB-036E-4A50-AF5F-F5D6584D42C6}.Debug|x86.ActiveCfg = DebugDll|Win32 + {5B1F46DB-036E-4A50-AF5F-F5D6584D42C6}.Debug|x86.Build.0 = DebugDll|Win32 + {5B1F46DB-036E-4A50-AF5F-F5D6584D42C6}.Release|x64.ActiveCfg = ReleaseDll|x64 + {5B1F46DB-036E-4A50-AF5F-F5D6584D42C6}.Release|x64.Build.0 = ReleaseDll|x64 + {5B1F46DB-036E-4A50-AF5F-F5D6584D42C6}.Release|x86.ActiveCfg = ReleaseDll|Win32 + {5B1F46DB-036E-4A50-AF5F-F5D6584D42C6}.Release|x86.Build.0 = ReleaseDll|Win32 {5B3131BA-178A-4A28-BD54-315A45C97ED1}.Debug|x64.ActiveCfg = Debug|x64 {5B3131BA-178A-4A28-BD54-315A45C97ED1}.Debug|x64.Build.0 = Debug|x64 {5B3131BA-178A-4A28-BD54-315A45C97ED1}.Debug|x64.Deploy.0 = Debug|x64 diff --git a/test/test.cpp b/test/test.cpp index 4e376c4d..29a047a1 100644 --- a/test/test.cpp +++ b/test/test.cpp @@ -132,77 +132,7 @@ int test_user32() { return 0; } -void test() { - - NTSTATUS status; - HANDLE hSection; - OBJECT_ATTRIBUTES oa; - LARGE_INTEGER li; - UNICODE_STRING us; - SECTION_BASIC_INFORMATION sbi; - PVOID BaseAddress = 0; - SIZE_T ViewSize = 0; - - li.QuadPart = 0x1000; - - RtlInitUnicodeString(&us, L"\\Sessions\\2\\BaseNamedObjects\\SectionTest"); - - InitializeObjectAttributes(&oa, &us, 0, nullptr, nullptr); - - status = NtCreateSection( - &hSection, - SECTION_ALL_ACCESS, - &oa, - &li, - PAGE_READWRITE, - SEC_COMMIT | SEC_BASED, - nullptr - ); - - if (NT_SUCCESS(status)) { - - status = NtQuerySection( - hSection, - SECTION_INFORMATION_CLASS::SectionBasicInformation, - &sbi, - sizeof(sbi), - nullptr - ); - - status = NtMapViewOfSection( - hSection, - NtCurrentProcess(), - &BaseAddress, - 0, - 0, - nullptr, - &ViewSize, - ViewUnmap, - 0, - PAGE_READWRITE - ); - if (NT_SUCCESS(status)) { - - status = NtQuerySection( - hSection, - SECTION_INFORMATION_CLASS::SectionBasicInformation, - &sbi, - sizeof(sbi), - nullptr - ); - - status = NtUnmapViewOfSection( - NtCurrentProcess(), - BaseAddress - ); - } - - NtClose(hSection); - } - -} - int main() { - test(); + test_a_dll(); return 0; } From ad7986eb6c4ec409bb80c183f23d2a712b780070 Mon Sep 17 00:00:00 2001 From: Boring <1079299053@qq.com> Date: Sat, 1 Oct 2022 16:28:02 +0800 Subject: [PATCH 3/8] update --- MemoryModule/BaseAddressIndex.cpp | 4 +- MemoryModule/Initialize.cpp | 20 +++--- MemoryModule/InvertedFunctionTable.cpp | 6 +- MemoryModule/LdrEntry.cpp | 4 +- MemoryModule/LdrEntry.h | 6 -- MemoryModule/MemoryModule.cpp | 42 ++++++------- MemoryModule/MmpDotNet.cpp | 46 ++++++-------- MemoryModule/MmpGlobalData.h | 58 ++++++++++++++---- MemoryModule/MmpTls.cpp | 84 +++++++++++++------------- 9 files changed, 142 insertions(+), 128 deletions(-) diff --git a/MemoryModule/BaseAddressIndex.cpp b/MemoryModule/BaseAddressIndex.cpp index 4fc1db5d..eacbf897 100644 --- a/MemoryModule/BaseAddressIndex.cpp +++ b/MemoryModule/BaseAddressIndex.cpp @@ -1,7 +1,7 @@ #include "stdafx.h" NTSTATUS NTAPI RtlInsertModuleBaseAddressIndexNode(IN PLDR_DATA_TABLE_ENTRY DataTableEntry, IN PVOID BaseAddress) { - auto LdrpModuleBaseAddressIndex = MmpGlobalDataPtr->LdrpModuleBaseAddressIndex; + auto LdrpModuleBaseAddressIndex = MmpGlobalDataPtr->MmpBaseAddressIndex.LdrpModuleBaseAddressIndex; if (!LdrpModuleBaseAddressIndex)return STATUS_UNSUCCESSFUL; PLDR_DATA_TABLE_ENTRY_WIN8 LdrNode = decltype(LdrNode)((size_t)LdrpModuleBaseAddressIndex - offsetof(LDR_DATA_TABLE_ENTRY_WIN8, BaseAddressIndexNode)); @@ -33,7 +33,7 @@ NTSTATUS NTAPI RtlInsertModuleBaseAddressIndexNode(IN PLDR_DATA_TABLE_ENTRY Data } NTSTATUS NTAPI RtlRemoveModuleBaseAddressIndexNode(IN PLDR_DATA_TABLE_ENTRY DataTableEntry) { - static auto tree{ MmpGlobalDataPtr->LdrpModuleBaseAddressIndex }; + static auto tree{ MmpGlobalDataPtr->MmpBaseAddressIndex.LdrpModuleBaseAddressIndex }; if (!tree->Root)return STATUS_UNSUCCESSFUL; RtlRbRemoveNode(tree, &PLDR_DATA_TABLE_ENTRY_WIN8(DataTableEntry)->BaseAddressIndexNode); return STATUS_SUCCESS; diff --git a/MemoryModule/Initialize.cpp b/MemoryModule/Initialize.cpp index bb5bc25f..dde66846 100644 --- a/MemoryModule/Initialize.cpp +++ b/MemoryModule/Initialize.cpp @@ -18,7 +18,7 @@ BOOLEAN MmpBuildSectionName(_Out_ PUNICODE_STRING SectionName) { PRTL_RB_TREE FindLdrpModuleBaseAddressIndex() { PRTL_RB_TREE LdrpModuleBaseAddressIndex = nullptr; - PLDR_DATA_TABLE_ENTRY_WIN10 nt10 = decltype(nt10)(MmpGlobalDataPtr->LdrpNtdllBase); + PLDR_DATA_TABLE_ENTRY_WIN10 nt10 = decltype(nt10)(MmpGlobalDataPtr->MmpBaseAddressIndex.NtdllLdrEntry); PRTL_BALANCED_NODE node = nullptr; if (!nt10 || !RtlIsWindowsVersionOrGreater(6, 2, 0))return nullptr; node = &nt10->BaseAddressIndexNode; @@ -253,20 +253,24 @@ NTSTATUS InitializeLockHeld() { MmpGlobalDataPtr->MajorVersion = 1; MmpGlobalDataPtr->MinorVersion = 0; - MmpGlobalDataPtr->LdrpNtdllBase = RtlFindNtdllLdrEntry(); - MmpGlobalDataPtr->LdrpHashTable = FindLdrpHashTable(); + GetSystemInfo(&MmpGlobalDataPtr->SystemInfo); - MmpGlobalDataPtr->LdrpModuleBaseAddressIndex = FindLdrpModuleBaseAddressIndex(); + MmpGlobalDataPtr->MmpBaseAddressIndex.NtdllLdrEntry = RtlFindLdrTableEntryByBaseName(L"ntdll.dll"); + MmpGlobalDataPtr->MmpBaseAddressIndex.LdrpModuleBaseAddressIndex = FindLdrpModuleBaseAddressIndex(); - MmpGlobalDataPtr->LdrpInvertedFunctionTable = FindLdrpInvertedFunctionTable(); + MmpGlobalDataPtr->MmpLdrEntry.LdrpHashTable = FindLdrpHashTable(); + + MmpGlobalDataPtr->MmpInvertedFunctionTable.LdrpInvertedFunctionTable = FindLdrpInvertedFunctionTable(); MmpGlobalDataPtr->MmpFeatures = MEMORY_FEATURE_SUPPORT_VERSION | MEMORY_FEATURE_LDRP_HEAP | MEMORY_FEATURE_LDRP_HANDLE_TLS_DATA | MEMORY_FEATURE_LDRP_RELEASE_TLS_ENTRY; - if (MmpGlobalDataPtr->LdrpModuleBaseAddressIndex)MmpGlobalDataPtr->MmpFeatures |= MEMORY_FEATURE_MODULE_BASEADDRESS_INDEX; - if (MmpGlobalDataPtr->LdrpHashTable)MmpGlobalDataPtr->MmpFeatures |= MEMORY_FEATURE_LDRP_HASH_TABLE; - if (MmpGlobalDataPtr->LdrpInvertedFunctionTable)MmpGlobalDataPtr->MmpFeatures |= MEMORY_FEATURE_INVERTED_FUNCTION_TABLE; + if (MmpGlobalDataPtr->MmpBaseAddressIndex.LdrpModuleBaseAddressIndex)MmpGlobalDataPtr->MmpFeatures |= MEMORY_FEATURE_MODULE_BASEADDRESS_INDEX; + if (MmpGlobalDataPtr->MmpLdrEntry.LdrpHashTable)MmpGlobalDataPtr->MmpFeatures |= MEMORY_FEATURE_LDRP_HASH_TABLE; + if (MmpGlobalDataPtr->MmpInvertedFunctionTable.LdrpInvertedFunctionTable)MmpGlobalDataPtr->MmpFeatures |= MEMORY_FEATURE_INVERTED_FUNCTION_TABLE; MmpTlsInitialize(); + MmpGlobalDataPtr->MmpDotNet.Initialized = MmpGlobalDataPtr->MmpDotNet.PreHooked = FALSE; + } while (false); if (!NT_SUCCESS(status) && hSection)NtClose(hSection); diff --git a/MemoryModule/InvertedFunctionTable.cpp b/MemoryModule/InvertedFunctionTable.cpp index 20a59b59..c5f90a9d 100644 --- a/MemoryModule/InvertedFunctionTable.cpp +++ b/MemoryModule/InvertedFunctionTable.cpp @@ -146,7 +146,7 @@ static NTSTATUS NTAPI RtlProtectMrdata(IN SIZE_T Protect) { if (!MrdataBase) { MEMORY_BASIC_INFORMATION mbi{}; - status = NtQueryVirtualMemory(GetCurrentProcess(), MmpGlobalDataPtr->LdrpInvertedFunctionTable, MemoryBasicInformation, &mbi, sizeof(mbi), nullptr); + status = NtQueryVirtualMemory(GetCurrentProcess(), MmpGlobalDataPtr->MmpInvertedFunctionTable.LdrpInvertedFunctionTable, MemoryBasicInformation, &mbi, sizeof(mbi), nullptr); if (!NT_SUCCESS(status))return status; MrdataBase = mbi.BaseAddress; size = mbi.RegionSize; @@ -158,7 +158,7 @@ static NTSTATUS NTAPI RtlProtectMrdata(IN SIZE_T Protect) { } NTSTATUS NTAPI RtlInsertInvertedFunctionTable(IN PVOID BaseAddress, IN size_t ImageSize) { - auto table = PRTL_INVERTED_FUNCTION_TABLE(MmpGlobalDataPtr->LdrpInvertedFunctionTable); + auto table = PRTL_INVERTED_FUNCTION_TABLE(MmpGlobalDataPtr->MmpInvertedFunctionTable.LdrpInvertedFunctionTable); if (!table)return STATUS_NOT_SUPPORTED; bool need_virtual_protect = RtlIsWindowsVersionOrGreater(6, 3, 0); NTSTATUS status; @@ -177,7 +177,7 @@ NTSTATUS NTAPI RtlInsertInvertedFunctionTable(IN PVOID BaseAddress, IN size_t Im } NTSTATUS NTAPI RtlRemoveInvertedFunctionTable(IN PVOID ImageBase) { - auto table = PRTL_INVERTED_FUNCTION_TABLE(MmpGlobalDataPtr->LdrpInvertedFunctionTable); + auto table = PRTL_INVERTED_FUNCTION_TABLE(MmpGlobalDataPtr->MmpInvertedFunctionTable.LdrpInvertedFunctionTable); bool need_virtual_protect = RtlIsWindowsVersionOrGreater(6, 3, 0); NTSTATUS status; diff --git a/MemoryModule/LdrEntry.cpp b/MemoryModule/LdrEntry.cpp index 6d62fbd9..867cd22c 100644 --- a/MemoryModule/LdrEntry.cpp +++ b/MemoryModule/LdrEntry.cpp @@ -1,8 +1,6 @@ #include "stdafx.h" #include -PLDR_DATA_TABLE_ENTRY const LdrpNtdllBase = RtlFindLdrTableEntryByBaseName(L"ntdll.dll"); - static NTSTATUS NTAPI RtlFreeDependencies(IN PLDR_DATA_TABLE_ENTRY_WIN10 LdrEntry) { _LDR_DDAG_NODE* DependentDdgeNode = nullptr; PLDR_DATA_TABLE_ENTRY_WIN10 ModuleEntry = nullptr; @@ -254,7 +252,7 @@ NTSTATUS NTAPI RtlGetReferenceCount(IN PMEMORYMODULE pModule, OUT PULONG Count) VOID NTAPI RtlInsertMemoryTableEntry(IN PLDR_DATA_TABLE_ENTRY LdrEntry) { PPEB_LDR_DATA PebData = NtCurrentPeb()->Ldr; - PLIST_ENTRY LdrpHashTable = MmpGlobalDataPtr->LdrpHashTable; + PLIST_ENTRY LdrpHashTable = MmpGlobalDataPtr->MmpLdrEntry.LdrpHashTable; ULONG i; /* Insert into hash table */ diff --git a/MemoryModule/LdrEntry.h b/MemoryModule/LdrEntry.h index 8a416944..fb6ec014 100644 --- a/MemoryModule/LdrEntry.h +++ b/MemoryModule/LdrEntry.h @@ -19,12 +19,6 @@ PLDR_DATA_TABLE_ENTRY NTAPI RtlFindLdrTableEntryByHandle(PVOID BaseAddress); PLDR_DATA_TABLE_ENTRY NTAPI RtlFindLdrTableEntryByBaseName(PCWSTR BaseName); -extern PLDR_DATA_TABLE_ENTRY const LdrpNtdllBase; - -#define RtlFindNtdllLdrEntry() (LdrpNtdllBase) - - - // // Loader Data Table Entry Flags // diff --git a/MemoryModule/MemoryModule.cpp b/MemoryModule/MemoryModule.cpp index 509294a1..6c1731fe 100644 --- a/MemoryModule/MemoryModule.cpp +++ b/MemoryModule/MemoryModule.cpp @@ -8,6 +8,23 @@ #define GET_HEADER_DICTIONARY(headers, idx) &headers->OptionalHeader.DataDirectory[idx] +#define AlignValueUp(value, alignment) ((size_t(value) + size_t(alignment) + 1) & ~(size_t(alignment) - 1)) + +#define OffsetPointer(data, offset) LPVOID(LPBYTE(data) + ptrdiff_t(offset)) + +// Protection flags for memory pages (Executable, Readable, Writeable) +static const int ProtectionFlags[2][2][2] = { + { + // not executable + {PAGE_NOACCESS, PAGE_WRITECOPY}, + {PAGE_READONLY, PAGE_READWRITE}, + }, { + // executable + {PAGE_EXECUTE, PAGE_EXECUTE_WRITECOPY}, + {PAGE_EXECUTE_READ, PAGE_EXECUTE_READWRITE}, + }, +}; + int MmpSizeOfImageHeadersUnsafe(PVOID BaseAddress) { PIMAGE_DOS_HEADER dh = (PIMAGE_DOS_HEADER)BaseAddress; PIMAGE_NT_HEADERS nh = (PIMAGE_NT_HEADERS)((LPBYTE)BaseAddress + dh->e_lfanew); @@ -38,29 +55,6 @@ bool WINAPI IsValidMemoryModuleHandle(HMEMORYMODULE hModule) { return MapMemoryModuleHandle(hModule) != nullptr; } -#define AlignValueUp(value, alignment) ((size_t(value) + size_t(alignment) + 1) & ~(size_t(alignment) - 1)) - -#define OffsetPointer(data, offset) LPVOID(LPBYTE(data) + ptrdiff_t(offset)) - - -// Protection flags for memory pages (Executable, Readable, Writeable) -static int ProtectionFlags[2][2][2] = { - { - // not executable - {PAGE_NOACCESS, PAGE_WRITECOPY}, - {PAGE_READONLY, PAGE_READWRITE}, - }, { - // executable - {PAGE_EXECUTE, PAGE_EXECUTE_WRITECOPY}, - {PAGE_EXECUTE_READ, PAGE_EXECUTE_READWRITE}, - }, -}; - -static SYSTEM_INFO sysInfo = []()->SYSTEM_INFO { - SYSTEM_INFO tmp; - GetNativeSystemInfo(&tmp); - return tmp; -}(); NTSTATUS MemoryResolveImportTable( _In_ LPBYTE base, @@ -271,7 +265,7 @@ NTSTATUS MemoryLoadLibrary( // // Allocate memory for image headers // - size_t alignedHeadersSize = (DWORD)AlignValueUp(old_header->OptionalHeader.SizeOfHeaders + sizeof(MEMORYMODULE), sysInfo.dwPageSize); + size_t alignedHeadersSize = (DWORD)AlignValueUp(old_header->OptionalHeader.SizeOfHeaders + sizeof(MEMORYMODULE), MmpGlobalDataPtr->SystemInfo.dwPageSize); if (!VirtualAlloc(base, alignedHeadersSize, MEM_COMMIT, PAGE_READWRITE)) { VirtualFree(base, 0, MEM_RELEASE); status = STATUS_NO_MEMORY; diff --git a/MemoryModule/MmpDotNet.cpp b/MemoryModule/MmpDotNet.cpp index 7d6c5178..26389ad2 100644 --- a/MemoryModule/MmpDotNet.cpp +++ b/MemoryModule/MmpDotNet.cpp @@ -28,14 +28,6 @@ static decltype(&CloseHandle)OriginCloseHandle = CloseHandle; static GetFileVersion_T OriginGetFileVersion1 = nullptr; static GetFileVersion_T OriginGetFileVersion2 = nullptr; -FILETIME AssemblyTimes; - -CRITICAL_SECTION MmpFakeHandleListLock; -LIST_ENTRY MmpFakeHandleListHead; - -static BOOLEAN g_PreHooked = FALSE; -static BOOLEAN g_Initialized = FALSE; - BOOL MmpIsMemoryModuleFileName( _In_ LPCWSTR lpFileName, _Out_opt_ PLDR_DATA_TABLE_ENTRY *LdrEntry) { @@ -87,17 +79,17 @@ VOID MmpInsertHandleEntry( entry->value = value; entry->bImageMapping = bImageMapping; - EnterCriticalSection(&MmpFakeHandleListLock); - InsertTailList(&MmpFakeHandleListHead, &entry->InMmpFakeHandleList); - LeaveCriticalSection(&MmpFakeHandleListLock); + EnterCriticalSection(&MmpGlobalDataPtr->MmpDotNet.MmpFakeHandleListLock); + InsertTailList(&MmpGlobalDataPtr->MmpDotNet.MmpFakeHandleListHead, &entry->InMmpFakeHandleList); + LeaveCriticalSection(&MmpGlobalDataPtr->MmpDotNet.MmpFakeHandleListLock); } PMMP_FAKE_HANDLE_LIST_ENTRY MmpFindHandleEntry(HANDLE hObject) { PMMP_FAKE_HANDLE_LIST_ENTRY result = nullptr; - EnterCriticalSection(&MmpFakeHandleListLock); + EnterCriticalSection(&MmpGlobalDataPtr->MmpDotNet.MmpFakeHandleListLock); - for (auto entry = MmpFakeHandleListHead.Flink; entry != &MmpFakeHandleListHead; entry = entry->Flink) { + for (auto entry = MmpGlobalDataPtr->MmpDotNet.MmpFakeHandleListHead.Flink; entry != &MmpGlobalDataPtr->MmpDotNet.MmpFakeHandleListHead; entry = entry->Flink) { auto CurEntry = CONTAINING_RECORD(entry, MMP_FAKE_HANDLE_LIST_ENTRY, MMP_FAKE_HANDLE_LIST_ENTRY::InMmpFakeHandleList); if (CurEntry->hObject == hObject) { @@ -107,15 +99,15 @@ PMMP_FAKE_HANDLE_LIST_ENTRY MmpFindHandleEntry(HANDLE hObject) { } - LeaveCriticalSection(&MmpFakeHandleListLock); + LeaveCriticalSection(&MmpGlobalDataPtr->MmpDotNet.MmpFakeHandleListLock); return result; } VOID MmpFreeHandleEntry(PMMP_FAKE_HANDLE_LIST_ENTRY lpHandleEntry) { - EnterCriticalSection(&MmpFakeHandleListLock); + EnterCriticalSection(&MmpGlobalDataPtr->MmpDotNet.MmpFakeHandleListLock); RemoveEntryList(&lpHandleEntry->InMmpFakeHandleList); RtlFreeHeap(RtlProcessHeap(), 0, lpHandleEntry); - LeaveCriticalSection(&MmpFakeHandleListLock); + LeaveCriticalSection(&MmpGlobalDataPtr->MmpDotNet.MmpFakeHandleListLock); } HANDLE WINAPI HookCreateFileW( @@ -156,7 +148,7 @@ BOOL WINAPI HookGetFileInformationByHandle( auto entry = (PLDR_DATA_TABLE_ENTRY)iter->value; auto module = MapMemoryModuleHandle((HMEMORYMODULE)entry->DllBase); - lpFileInformation->ftCreationTime = lpFileInformation->ftLastAccessTime = lpFileInformation->ftLastWriteTime = AssemblyTimes; + lpFileInformation->ftCreationTime = lpFileInformation->ftLastAccessTime = lpFileInformation->ftLastWriteTime = MmpGlobalDataPtr->MmpDotNet.AssemblyTimes; lpFileInformation->nFileSizeLow = module->dwImageFileSize; return TRUE; @@ -185,7 +177,7 @@ BOOL WINAPI HookGetFileAttributesExW( LPWIN32_FILE_ATTRIBUTE_DATA data = (LPWIN32_FILE_ATTRIBUTE_DATA)lpFileInformation; auto module = MapMemoryModuleHandle((HMEMORYMODULE)entry->DllBase); - data->ftCreationTime = data->ftLastAccessTime = data->ftLastWriteTime = AssemblyTimes; + data->ftCreationTime = data->ftLastAccessTime = data->ftLastWriteTime = MmpGlobalDataPtr->MmpDotNet.AssemblyTimes; data->nFileSizeLow = module->dwImageFileSize; return TRUE; } @@ -394,16 +386,16 @@ BOOL WINAPI MmpPreInitializeHooksForDotNet() { EnterCriticalSection(NtCurrentPeb()->FastPebLock); - if (!g_PreHooked) { + if (!MmpGlobalDataPtr->MmpDotNet.PreHooked) { HMODULE hModule = LoadLibraryW(L"mscoree.dll"); if (hModule) { OriginGetFileVersion2 = (GetFileVersion_T)GetProcAddress(hModule, "GetFileVersion"); if (OriginGetFileVersion2) { - GetSystemTimeAsFileTime(&AssemblyTimes); + GetSystemTimeAsFileTime(&MmpGlobalDataPtr->MmpDotNet.AssemblyTimes); - InitializeCriticalSection(&MmpFakeHandleListLock); - InitializeListHead(&MmpFakeHandleListHead); + InitializeCriticalSection(&MmpGlobalDataPtr->MmpDotNet.MmpFakeHandleListLock); + InitializeListHead(&MmpGlobalDataPtr->MmpDotNet.MmpFakeHandleListHead); DetourTransactionBegin(); DetourUpdateThread(NtCurrentThread()); @@ -422,14 +414,14 @@ BOOL WINAPI MmpPreInitializeHooksForDotNet() { DetourTransactionCommit(); - g_PreHooked = TRUE; + MmpGlobalDataPtr->MmpDotNet.PreHooked = TRUE; } } } LeaveCriticalSection(NtCurrentPeb()->FastPebLock); - return g_PreHooked; + return MmpGlobalDataPtr->MmpDotNet.PreHooked; } BOOL WINAPI MmpInitializeHooksForDotNet() { @@ -440,17 +432,17 @@ BOOL WINAPI MmpInitializeHooksForDotNet() { EnterCriticalSection(NtCurrentPeb()->FastPebLock); - if (!g_PreHooked) { + if (!MmpGlobalDataPtr->MmpDotNet.PreHooked) { LeaveCriticalSection(NtCurrentPeb()->FastPebLock); return FALSE; } - if (!g_Initialized) { + if (!MmpGlobalDataPtr->MmpDotNet.Initialized) { DetourTransactionBegin(); DetourUpdateThread(NtCurrentThread()); DetourAttach((PVOID*)&OriginGetFileVersion1, HookGetFileVersion); DetourTransactionCommit(); - g_Initialized = TRUE; + MmpGlobalDataPtr->MmpDotNet.Initialized = TRUE; } LeaveCriticalSection(NtCurrentPeb()->FastPebLock); diff --git a/MemoryModule/MmpGlobalData.h b/MemoryModule/MmpGlobalData.h index 3470c183..56d2d914 100644 --- a/MemoryModule/MmpGlobalData.h +++ b/MemoryModule/MmpGlobalData.h @@ -1,29 +1,61 @@ #pragma once -typedef struct _MMP_GLOBAL_DATA { - - WORD MajorVersion; - WORD MinorVersion; - - DWORD MmpFeatures; - - //BaseAddressIndex.cpp +//BaseAddressIndex.cpp +typedef struct _MMP_BASE_ADDRESS_INDEX_DATA { PRTL_RB_TREE LdrpModuleBaseAddressIndex; + PLDR_DATA_TABLE_ENTRY NtdllLdrEntry; +}MMP_BASE_ADDRESS_INDEX_DATA, * PMMP_BASE_ADDRESS_INDEX_DATA; - //InvertedFunctionTable.cpp +//InvertedFunctionTable.cpp +typedef struct _MMP_INVERTED_FUNCTION_TABLE_DATA { PVOID LdrpInvertedFunctionTable; +}MMP_INVERTED_FUNCTION_TABLE_DATA, * PMMP_INVERTED_FUNCTION_TABLE_DATA; - //LdrEntry.cpp - PLDR_DATA_TABLE_ENTRY LdrpNtdllBase; +//LdrEntry.cpp +typedef struct _MMP_LDR_ENTRY_DATA { PLIST_ENTRY LdrpHashTable; +}MMP_LDR_ENTRY_DATA, * PMMP_LDR_ENTRY_DATA; - //MmpTls.cpp +//MmpTls.cpp +typedef struct _MMP_TLS_DATA { LIST_ENTRY MmpTlsList; RTL_BITMAP MmpTlsBitmap; SRWLOCK MmpTlsListLock; CRITICAL_SECTION MmpTlspLock; LIST_ENTRY MmpThreadLocalStoragePointer; DWORD MmpActiveThreadCount; +}MMP_TLS_DATA, * PMMP_TLS_DATA; + +//MmpDotNet.cpp +typedef struct _MMP_DOT_NET_DATA { + FILETIME AssemblyTimes; + + CRITICAL_SECTION MmpFakeHandleListLock; + LIST_ENTRY MmpFakeHandleListHead; + + BOOLEAN PreHooked; + BOOLEAN Initialized; +}MMP_DOT_NET_DATA, * PMMP_DOT_NET_DATA; + +typedef struct _MMP_GLOBAL_DATA { + + WORD MajorVersion; + WORD MinorVersion; + + DWORD MmpFeatures; + + SYSTEM_INFO SystemInfo; + + MMP_BASE_ADDRESS_INDEX_DATA MmpBaseAddressIndex; + + MMP_INVERTED_FUNCTION_TABLE_DATA MmpInvertedFunctionTable; + + MMP_LDR_ENTRY_DATA MmpLdrEntry; + + MMP_TLS_DATA MmpTls; + + MMP_DOT_NET_DATA MmpDotNet; + }MMP_GLOBAL_DATA, * PMMP_GLOBAL_DATA; -extern PMMP_GLOBAL_DATA MmpGlobalDataPtr; \ No newline at end of file +extern PMMP_GLOBAL_DATA MmpGlobalDataPtr; diff --git a/MemoryModule/MmpTls.cpp b/MemoryModule/MmpTls.cpp index aa3e65bc..de7cb0e4 100644 --- a/MemoryModule/MmpTls.cpp +++ b/MemoryModule/MmpTls.cpp @@ -159,7 +159,7 @@ DWORD NTAPI MmpUserThreadStart(LPVOID lpThreadParameter) { // // Allocate and replace ThreadLocalStoragePointer for new thread // - EnterCriticalSection(&MmpGlobalDataPtr->MmpTlspLock); + EnterCriticalSection(&MmpGlobalDataPtr->MmpTls.MmpTlspLock); record = PMMP_TLSP_RECORD(RtlAllocateHeap(RtlProcessHeap(), 0, sizeof(MMP_TLSP_RECORD))); if (record) { @@ -177,7 +177,7 @@ DWORD NTAPI MmpUserThreadStart(LPVOID lpThreadParameter) { NtCurrentTeb()->ThreadLocalStoragePointer = record->TlspMmpBlock; - InsertTailList(&MmpGlobalDataPtr->MmpThreadLocalStoragePointer, &record->InMmpThreadLocalStoragePointer); + InsertTailList(&MmpGlobalDataPtr->MmpTls.MmpThreadLocalStoragePointer, &record->InMmpThreadLocalStoragePointer); success = true; } else { @@ -185,17 +185,17 @@ DWORD NTAPI MmpUserThreadStart(LPVOID lpThreadParameter) { } } - LeaveCriticalSection(&MmpGlobalDataPtr->MmpTlspLock); + LeaveCriticalSection(&MmpGlobalDataPtr->MmpTls.MmpTlspLock); // // Handle MemoryModule Tls data // if (success) { - RtlAcquireSRWLockShared(&MmpGlobalDataPtr->MmpTlsListLock); + RtlAcquireSRWLockShared(&MmpGlobalDataPtr->MmpTls.MmpTlsListLock); auto ThreadLocalStoragePointer = (PVOID*)NtCurrentTeb()->ThreadLocalStoragePointer; - PLIST_ENTRY entry = MmpGlobalDataPtr->MmpTlsList.Flink; - while (entry != &MmpGlobalDataPtr->MmpTlsList) { + PLIST_ENTRY entry = MmpGlobalDataPtr->MmpTls.MmpTlsList.Flink; + while (entry != &MmpGlobalDataPtr->MmpTls.MmpTlsList) { PTLS_ENTRY tls = CONTAINING_RECORD(entry, TLS_ENTRY, TlsEntryLinks); auto len = tls->TlsDirectory.EndAddressOfRawData - tls->TlsDirectory.StartAddressOfRawData; @@ -217,16 +217,16 @@ DWORD NTAPI MmpUserThreadStart(LPVOID lpThreadParameter) { entry = entry->Flink; } - RtlReleaseSRWLockShared(&MmpGlobalDataPtr->MmpTlsListLock); + RtlReleaseSRWLockShared(&MmpGlobalDataPtr->MmpTls.MmpTlsListLock); } if (!success) { return ERROR_NOT_ENOUGH_MEMORY; } - EnterCriticalSection(&MmpGlobalDataPtr->MmpTlspLock); - ++MmpGlobalDataPtr->MmpActiveThreadCount; - LeaveCriticalSection(&MmpGlobalDataPtr->MmpTlspLock); + EnterCriticalSection(&MmpGlobalDataPtr->MmpTls.MmpTlspLock); + ++MmpGlobalDataPtr->MmpTls.MmpActiveThreadCount; + LeaveCriticalSection(&MmpGlobalDataPtr->MmpTls.MmpTlspLock); __skip_tls: return Context.ThreadStartRoutine(Context.ThreadParameter); @@ -327,10 +327,10 @@ VOID NTAPI HookLdrShutdownThread(VOID) { // // Find our tlsp record // - EnterCriticalSection(&MmpGlobalDataPtr->MmpTlspLock); + EnterCriticalSection(&MmpGlobalDataPtr->MmpTls.MmpTlspLock); - entry = MmpGlobalDataPtr->MmpThreadLocalStoragePointer.Flink; - while (entry != &MmpGlobalDataPtr->MmpThreadLocalStoragePointer) { + entry = MmpGlobalDataPtr->MmpTls.MmpThreadLocalStoragePointer.Flink; + while (entry != &MmpGlobalDataPtr->MmpTls.MmpThreadLocalStoragePointer) { auto p = CONTAINING_RECORD(entry, MMP_TLSP_RECORD, InMmpThreadLocalStoragePointer); if (p->UniqueThread == NtCurrentThreadId()) { @@ -349,19 +349,19 @@ VOID NTAPI HookLdrShutdownThread(VOID) { entry = entry->Flink; } - --MmpGlobalDataPtr->MmpActiveThreadCount; + --MmpGlobalDataPtr->MmpTls.MmpActiveThreadCount; - LeaveCriticalSection(&MmpGlobalDataPtr->MmpTlspLock); + LeaveCriticalSection(&MmpGlobalDataPtr->MmpTls.MmpTlspLock); // // Free MemoryModule Tls data // - RtlAcquireSRWLockExclusive(&MmpGlobalDataPtr->MmpTlsListLock); + RtlAcquireSRWLockExclusive(&MmpGlobalDataPtr->MmpTls.MmpTlsListLock); if (record) { auto TlspMmpBlock = (PVOID*)record->TlspMmpBlock; - entry = MmpGlobalDataPtr->MmpTlsList.Flink; - while (entry != &MmpGlobalDataPtr->MmpTlsList) { + entry = MmpGlobalDataPtr->MmpTls.MmpTlsList.Flink; + while (entry != &MmpGlobalDataPtr->MmpTls.MmpTlsList) { auto p = CONTAINING_RECORD(entry, TLS_ENTRY, TlsEntryLinks); RtlFreeHeap(RtlProcessHeap(), 0, TlspMmpBlock[p->TlsDirectory.Characteristics]); @@ -372,12 +372,12 @@ VOID NTAPI HookLdrShutdownThread(VOID) { RtlFreeHeap(RtlProcessHeap(), 0, TlspMmpBlock); } else { - if (MmpGlobalDataPtr->MmpTlsList.Flink != &MmpGlobalDataPtr->MmpTlsList) { + if (MmpGlobalDataPtr->MmpTls.MmpTlsList.Flink != &MmpGlobalDataPtr->MmpTls.MmpTlsList) { assert(false); } } - RtlReleaseSRWLockExclusive(&MmpGlobalDataPtr->MmpTlsListLock); + RtlReleaseSRWLockExclusive(&MmpGlobalDataPtr->MmpTls.MmpTlsListLock); // // Call the original function @@ -433,7 +433,7 @@ BOOL NTAPI PreHookNtSetInformationProcess() { ); if (NT_SUCCESS(status)) { - EnterCriticalSection(&MmpGlobalDataPtr->MmpTlspLock); + EnterCriticalSection(&MmpGlobalDataPtr->MmpTls.MmpTlspLock); for (DWORD i = 0; i < CurrentThreadCount; ++i) { auto const& LdrTls = ProcessTlsInformation->ThreadData[i]; auto const& MmpTls = tmpTlsInformation->ThreadData[i]; @@ -443,9 +443,9 @@ BOOL NTAPI PreHookNtSetInformationProcess() { record->TlspLdrBlock = LdrTls.TlsVector; record->TlspMmpBlock = MmpTls.TlsVector; record->UniqueThread = LdrTls.ThreadId; - InsertTailList(&MmpGlobalDataPtr->MmpThreadLocalStoragePointer, &record->InMmpThreadLocalStoragePointer); + InsertTailList(&MmpGlobalDataPtr->MmpTls.MmpThreadLocalStoragePointer, &record->InMmpThreadLocalStoragePointer); } - LeaveCriticalSection(&MmpGlobalDataPtr->MmpTlspLock); + LeaveCriticalSection(&MmpGlobalDataPtr->MmpTls.MmpTlspLock); } } @@ -547,14 +547,14 @@ NTSTATUS NTAPI HookNtSetInformationProcess( // // Modify our mapping // - EnterCriticalSection(&MmpGlobalDataPtr->MmpTlspLock); + EnterCriticalSection(&MmpGlobalDataPtr->MmpTls.MmpTlspLock); for (auto i = 0; i < Tls->ThreadDataCount; ++i) { bool found = false; - PLIST_ENTRY entry = MmpGlobalDataPtr->MmpThreadLocalStoragePointer.Flink; + PLIST_ENTRY entry = MmpGlobalDataPtr->MmpTls.MmpThreadLocalStoragePointer.Flink; // Find thread-spec tlsp - while (entry != &MmpGlobalDataPtr->MmpThreadLocalStoragePointer) { + while (entry != &MmpGlobalDataPtr->MmpTls.MmpThreadLocalStoragePointer) { PMMP_TLSP_RECORD j = CONTAINING_RECORD(entry, MMP_TLSP_RECORD, InMmpThreadLocalStoragePointer); @@ -598,7 +598,7 @@ NTSTATUS NTAPI HookNtSetInformationProcess( ProcessTlsInformation->ThreadData[i].ThreadId = Tls->ThreadData[i].ThreadId; } } - LeaveCriticalSection(&MmpGlobalDataPtr->MmpTlspLock); + LeaveCriticalSection(&MmpGlobalDataPtr->MmpTls.MmpTlspLock); } while (false); @@ -610,7 +610,7 @@ NTSTATUS NTAPI MmpAcquireTlsIndex(_Out_ PULONG TlsIndex) { *TlsIndex = -1; - ULONG Index = RtlFindClearBitsAndSet(&MmpGlobalDataPtr->MmpTlsBitmap, 1, 0); + ULONG Index = RtlFindClearBitsAndSet(&MmpGlobalDataPtr->MmpTls.MmpTlsBitmap, 1, 0); if (Index != -1) { *TlsIndex = Index; return STATUS_SUCCESS; @@ -671,9 +671,9 @@ NTSTATUS NTAPI MmpAllocateTlsEntry( Entry->TlsDirectory.Characteristics = *PULONG(Entry->TlsDirectory.AddressOfIndex) = TlsIndex; - RtlAcquireSRWLockExclusive(&MmpGlobalDataPtr->MmpTlsListLock); - InsertTailList(&MmpGlobalDataPtr->MmpTlsList, &Entry->TlsEntryLinks); - RtlReleaseSRWLockExclusive(&MmpGlobalDataPtr->MmpTlsListLock); + RtlAcquireSRWLockExclusive(&MmpGlobalDataPtr->MmpTls.MmpTlsListLock); + InsertTailList(&MmpGlobalDataPtr->MmpTls.MmpTlsList, &Entry->TlsEntryLinks); + RtlReleaseSRWLockExclusive(&MmpGlobalDataPtr->MmpTls.MmpTlsListLock); *lpTlsEntry = Entry; *lpTlsIndex = TlsIndex; @@ -682,20 +682,20 @@ NTSTATUS NTAPI MmpAllocateTlsEntry( NTSTATUS NTAPI MmpReleaseTlsEntry(_In_ PLDR_DATA_TABLE_ENTRY lpModuleEntry) { - RtlAcquireSRWLockExclusive(&MmpGlobalDataPtr->MmpTlsListLock); + RtlAcquireSRWLockExclusive(&MmpGlobalDataPtr->MmpTls.MmpTlsListLock); - for (auto entry = MmpGlobalDataPtr->MmpTlsList.Flink; entry != &MmpGlobalDataPtr->MmpTlsList; entry = entry->Flink) { + for (auto entry = MmpGlobalDataPtr->MmpTls.MmpTlsList.Flink; entry != &MmpGlobalDataPtr->MmpTls.MmpTlsList; entry = entry->Flink) { auto p = CONTAINING_RECORD(entry, TLS_ENTRY, TlsEntryLinks); if (p->ModuleEntry == lpModuleEntry) { RemoveEntryList(&p->TlsEntryLinks); - RtlClearBit(&MmpGlobalDataPtr->MmpTlsBitmap, p->TlsDirectory.Characteristics); + RtlClearBit(&MmpGlobalDataPtr->MmpTls.MmpTlsBitmap, p->TlsDirectory.Characteristics); RtlFreeHeap(RtlProcessHeap(), 0, p); break; } } - RtlReleaseSRWLockExclusive(&MmpGlobalDataPtr->MmpTlsListLock); + RtlReleaseSRWLockExclusive(&MmpGlobalDataPtr->MmpTls.MmpTlsListLock); return STATUS_SUCCESS; } @@ -728,7 +728,7 @@ NTSTATUS NTAPI MmpHandleTlsData(_In_ PLDR_DATA_TABLE_ENTRY lpModuleEntry) { return STATUS_INSUFFICIENT_RESOURCES; } - auto ThreadCount = MmpGlobalDataPtr->MmpActiveThreadCount; + auto ThreadCount = MmpGlobalDataPtr->MmpTls.MmpActiveThreadCount; auto success = true; auto Length = sizeof(PROCESS_TLS_INFORMATION) + (ThreadCount - 1) * sizeof(THREAD_TLS_INFORMATION); auto ProcessTlsInformation = PPROCESS_TLS_INFORMATION(RtlAllocateHeap(RtlProcessHeap(), HEAP_ZERO_MEMORY, Length)); @@ -796,26 +796,26 @@ BOOL NTAPI MmpTlsInitialize() { // // Capture thread count // - MmpGlobalDataPtr->MmpActiveThreadCount = MmpGetThreadCount(); + MmpGlobalDataPtr->MmpTls.MmpActiveThreadCount = MmpGetThreadCount(); // // Initialize tlsp // - InitializeCriticalSection(&MmpGlobalDataPtr->MmpTlspLock); - InitializeListHead(&MmpGlobalDataPtr->MmpThreadLocalStoragePointer); + InitializeCriticalSection(&MmpGlobalDataPtr->MmpTls.MmpTlspLock); + InitializeListHead(&MmpGlobalDataPtr->MmpTls.MmpThreadLocalStoragePointer); // // Initialize tls list // - InitializeListHead(&MmpGlobalDataPtr->MmpTlsList); - RtlInitializeSRWLock(&MmpGlobalDataPtr->MmpTlsListLock); + InitializeListHead(&MmpGlobalDataPtr->MmpTls.MmpTlsList); + RtlInitializeSRWLock(&MmpGlobalDataPtr->MmpTls.MmpTlsListLock); PULONG buffer = PULONG(RtlAllocateHeap(RtlProcessHeap(), HEAP_ZERO_MEMORY, MMP_TLSP_INDEX_BUFFER_SIZE)); if (!buffer) RtlRaiseStatus(STATUS_NO_MEMORY); RtlFillMemory(buffer, MMP_START_TLS_INDEX / 8, -1); - RtlInitializeBitMap(&MmpGlobalDataPtr->MmpTlsBitmap, buffer, MMP_MAXIMUM_TLS_INDEX); + RtlInitializeBitMap(&MmpGlobalDataPtr->MmpTls.MmpTlsBitmap, buffer, MMP_MAXIMUM_TLS_INDEX); if (NtCurrentTeb()->ThreadLocalStoragePointer) { if (!PreHookNtSetInformationProcess()) { From 53885cd5e7c30eb1fca4531a15d33f1c494df6f1 Mon Sep 17 00:00:00 2001 From: Boring <1079299053@qq.com> Date: Sat, 1 Oct 2022 17:28:23 +0800 Subject: [PATCH 4/8] fix release errors --- MemoryModule/MmpDotNet.cpp | 83 ++++++++++++++++-------------------- MemoryModule/MmpDotNet.h | 8 ++++ MemoryModule/MmpGlobalData.h | 22 ++++++++++ MemoryModule/MmpTls.cpp | 29 +++++++------ MemoryModulePP.sln | 4 +- test/test.vcxproj | 10 ++++- 6 files changed, 92 insertions(+), 64 deletions(-) diff --git a/MemoryModule/MmpDotNet.cpp b/MemoryModule/MmpDotNet.cpp index 26389ad2..242b8bda 100644 --- a/MemoryModule/MmpDotNet.cpp +++ b/MemoryModule/MmpDotNet.cpp @@ -1,13 +1,6 @@ #include "stdafx.h" #include <3rdparty/Detours/detours.h> -typedef HRESULT (WINAPI* GetFileVersion_T)( - LPCWSTR szFilename, - LPWSTR szBuffer, - DWORD cchBuffer, - DWORD* dwLength -); - typedef struct _MMP_FAKE_HANDLE_LIST_ENTRY { LIST_ENTRY InMmpFakeHandleList; HANDLE hObject; @@ -15,19 +8,6 @@ typedef struct _MMP_FAKE_HANDLE_LIST_ENTRY { BOOL bImageMapping; }MMP_FAKE_HANDLE_LIST_ENTRY, * PMMP_FAKE_HANDLE_LIST_ENTRY; -static decltype(&CreateFileW) OriginCreateFileW = CreateFileW; -static decltype(&GetFileInformationByHandle) OriginGetFileInformationByHandle = GetFileInformationByHandle; -static decltype(&GetFileAttributesExW) OriginGetFileAttributesExW = GetFileAttributesExW; -static decltype(&GetFileSize) OriginGetFileSize = GetFileSize; -static decltype(&GetFileSizeEx) OriginGetFileSizeEx = GetFileSizeEx; -static decltype(&CreateFileMappingW) OriginCreateFileMappingW = CreateFileMappingW; -static decltype(&MapViewOfFileEx) OriginMapViewOfFileEx = MapViewOfFileEx; -static decltype(&MapViewOfFile) OriginMapViewOfFile = MapViewOfFile; -static decltype(&UnmapViewOfFile)OriginUnmapViewOfFile = UnmapViewOfFile; -static decltype(&CloseHandle)OriginCloseHandle = CloseHandle; -static GetFileVersion_T OriginGetFileVersion1 = nullptr; -static GetFileVersion_T OriginGetFileVersion2 = nullptr; - BOOL MmpIsMemoryModuleFileName( _In_ LPCWSTR lpFileName, _Out_opt_ PLDR_DATA_TABLE_ENTRY *LdrEntry) { @@ -127,7 +107,7 @@ HANDLE WINAPI HookCreateFileW( return hEvent; } - return OriginCreateFileW( + return MmpGlobalDataPtr->MmpDotNet.Hooks.OriginCreateFileW( lpFileName, dwDesiredAccess, dwShareMode, @@ -154,7 +134,7 @@ BOOL WINAPI HookGetFileInformationByHandle( return TRUE; } else { - return OriginGetFileInformationByHandle( + return MmpGlobalDataPtr->MmpDotNet.Hooks.OriginGetFileInformationByHandle( hFile, lpFileInformation ); @@ -186,7 +166,7 @@ BOOL WINAPI HookGetFileAttributesExW( } } - return OriginGetFileAttributesExW( + return MmpGlobalDataPtr->MmpDotNet.Hooks.OriginGetFileAttributesExW( lpFileName, fInfoLevelId, lpFileInformation @@ -207,7 +187,7 @@ DWORD WINAPI HookGetFileSize( return module->dwImageFileSize; } else { - return OriginGetFileSize( + return MmpGlobalDataPtr->MmpDotNet.Hooks.OriginGetFileSize( hFile, lpFileSizeHigh ); @@ -228,7 +208,7 @@ BOOL WINAPI HookGetFileSizeEx( return TRUE; } else { - return OriginGetFileSizeEx( + return MmpGlobalDataPtr->MmpDotNet.Hooks.OriginGetFileSizeEx( hFile, lpFileSize ); @@ -252,7 +232,7 @@ HANDLE WINAPI HookCreateFileMappingW( return hEvent; } - return OriginCreateFileMappingW( + return MmpGlobalDataPtr->MmpDotNet.Hooks.OriginCreateFileMappingW( hFile, lpFileMappingAttributes, flProtect, @@ -288,7 +268,7 @@ LPVOID WINAPI HookMapViewOfFileEx( return hModule; } - return OriginMapViewOfFileEx( + return MmpGlobalDataPtr->MmpDotNet.Hooks.OriginMapViewOfFileEx( hFileMappingObject, dwDesiredAccess, dwFileOffsetHigh, @@ -324,14 +304,14 @@ BOOL WINAPI HookUnmapViewOfFile(_In_ LPCVOID lpBaseAddress) { return TRUE; } - return OriginUnmapViewOfFile(lpBaseAddress); + return MmpGlobalDataPtr->MmpDotNet.Hooks.OriginUnmapViewOfFile(lpBaseAddress); } BOOL WINAPI HookCloseHandle(_In_ _Post_ptr_invalid_ HANDLE hObject) { auto iter = MmpFindHandleEntry(hObject); if (iter)MmpFreeHandleEntry(iter); - return OriginCloseHandle(hObject); + return MmpGlobalDataPtr->MmpDotNet.Hooks.OriginCloseHandle(hObject); } HRESULT WINAPI HookGetFileVersion( @@ -374,7 +354,7 @@ HRESULT WINAPI HookGetFileVersion( } - return OriginGetFileVersion1( + return MmpGlobalDataPtr->MmpDotNet.Hooks.OriginGetFileVersion1( szFilename, szBuffer, cchBuffer, @@ -389,28 +369,39 @@ BOOL WINAPI MmpPreInitializeHooksForDotNet() { if (!MmpGlobalDataPtr->MmpDotNet.PreHooked) { HMODULE hModule = LoadLibraryW(L"mscoree.dll"); if (hModule) { - OriginGetFileVersion2 = (GetFileVersion_T)GetProcAddress(hModule, "GetFileVersion"); - if (OriginGetFileVersion2) { + MmpGlobalDataPtr->MmpDotNet.Hooks.OriginGetFileVersion2 = (GetFileVersion_T)GetProcAddress(hModule, "GetFileVersion"); + if (MmpGlobalDataPtr->MmpDotNet.Hooks.OriginGetFileVersion2) { GetSystemTimeAsFileTime(&MmpGlobalDataPtr->MmpDotNet.AssemblyTimes); InitializeCriticalSection(&MmpGlobalDataPtr->MmpDotNet.MmpFakeHandleListLock); InitializeListHead(&MmpGlobalDataPtr->MmpDotNet.MmpFakeHandleListHead); + MmpGlobalDataPtr->MmpDotNet.Hooks.OriginCreateFileW = CreateFileW; + MmpGlobalDataPtr->MmpDotNet.Hooks.OriginGetFileInformationByHandle = GetFileInformationByHandle; + MmpGlobalDataPtr->MmpDotNet.Hooks.OriginGetFileAttributesExW = GetFileAttributesExW; + MmpGlobalDataPtr->MmpDotNet.Hooks.OriginGetFileSize = GetFileSize; + MmpGlobalDataPtr->MmpDotNet.Hooks.OriginGetFileSizeEx = GetFileSizeEx; + MmpGlobalDataPtr->MmpDotNet.Hooks.OriginCreateFileMappingW = CreateFileMappingW; + MmpGlobalDataPtr->MmpDotNet.Hooks.OriginMapViewOfFileEx = MapViewOfFileEx; + MmpGlobalDataPtr->MmpDotNet.Hooks.OriginMapViewOfFile = MapViewOfFile; + MmpGlobalDataPtr->MmpDotNet.Hooks.OriginUnmapViewOfFile = UnmapViewOfFile; + MmpGlobalDataPtr->MmpDotNet.Hooks.OriginCloseHandle = CloseHandle; + DetourTransactionBegin(); DetourUpdateThread(NtCurrentThread()); - DetourAttach((PVOID*)&OriginCreateFileW, HookCreateFileW); - DetourAttach((PVOID*)&OriginGetFileInformationByHandle, HookGetFileInformationByHandle); - DetourAttach((PVOID*)&OriginGetFileAttributesExW, HookGetFileAttributesExW); - DetourAttach((PVOID*)&OriginGetFileSize, HookGetFileSize); - DetourAttach((PVOID*)&OriginGetFileSizeEx, HookGetFileSizeEx); - DetourAttach((PVOID*)&OriginCreateFileMappingW, HookCreateFileMappingW); - DetourAttach((PVOID*)&OriginMapViewOfFileEx, HookMapViewOfFileEx); - DetourAttach((PVOID*)&OriginMapViewOfFile, HookMapViewOfFile); - DetourAttach((PVOID*)&OriginUnmapViewOfFile, HookUnmapViewOfFile); - DetourAttach((PVOID*)&OriginCloseHandle, HookCloseHandle); - DetourAttach((PVOID*)&OriginGetFileVersion2, HookGetFileVersion); + DetourAttach((PVOID*)&MmpGlobalDataPtr->MmpDotNet.Hooks.OriginCreateFileW, HookCreateFileW); + DetourAttach((PVOID*)&MmpGlobalDataPtr->MmpDotNet.Hooks.OriginGetFileInformationByHandle, HookGetFileInformationByHandle); + DetourAttach((PVOID*)&MmpGlobalDataPtr->MmpDotNet.Hooks.OriginGetFileAttributesExW, HookGetFileAttributesExW); + DetourAttach((PVOID*)&MmpGlobalDataPtr->MmpDotNet.Hooks.OriginGetFileSize, HookGetFileSize); + DetourAttach((PVOID*)&MmpGlobalDataPtr->MmpDotNet.Hooks.OriginGetFileSizeEx, HookGetFileSizeEx); + DetourAttach((PVOID*)&MmpGlobalDataPtr->MmpDotNet.Hooks.OriginCreateFileMappingW, HookCreateFileMappingW); + DetourAttach((PVOID*)&MmpGlobalDataPtr->MmpDotNet.Hooks.OriginMapViewOfFileEx, HookMapViewOfFileEx); + DetourAttach((PVOID*)&MmpGlobalDataPtr->MmpDotNet.Hooks.OriginMapViewOfFile, HookMapViewOfFile); + DetourAttach((PVOID*)&MmpGlobalDataPtr->MmpDotNet.Hooks.OriginUnmapViewOfFile, HookUnmapViewOfFile); + DetourAttach((PVOID*)&MmpGlobalDataPtr->MmpDotNet.Hooks.OriginCloseHandle, HookCloseHandle); + DetourAttach((PVOID*)&MmpGlobalDataPtr->MmpDotNet.Hooks.OriginGetFileVersion2, HookGetFileVersion); DetourTransactionCommit(); @@ -427,8 +418,8 @@ BOOL WINAPI MmpPreInitializeHooksForDotNet() { BOOL WINAPI MmpInitializeHooksForDotNet() { HMODULE hModule = GetModuleHandleW(L"mscoreei.dll"); if (hModule) { - OriginGetFileVersion1 = (GetFileVersion_T)GetProcAddress(hModule, "GetFileVersion"); - if (OriginGetFileVersion1) { + MmpGlobalDataPtr->MmpDotNet.Hooks.OriginGetFileVersion1 = (GetFileVersion_T)GetProcAddress(hModule, "GetFileVersion"); + if (MmpGlobalDataPtr->MmpDotNet.Hooks.OriginGetFileVersion1) { EnterCriticalSection(NtCurrentPeb()->FastPebLock); @@ -440,7 +431,7 @@ BOOL WINAPI MmpInitializeHooksForDotNet() { if (!MmpGlobalDataPtr->MmpDotNet.Initialized) { DetourTransactionBegin(); DetourUpdateThread(NtCurrentThread()); - DetourAttach((PVOID*)&OriginGetFileVersion1, HookGetFileVersion); + DetourAttach((PVOID*)&MmpGlobalDataPtr->MmpDotNet.Hooks.OriginGetFileVersion1, HookGetFileVersion); DetourTransactionCommit(); MmpGlobalDataPtr->MmpDotNet.Initialized = TRUE; } diff --git a/MemoryModule/MmpDotNet.h b/MemoryModule/MmpDotNet.h index cecd4d7e..14253e58 100644 --- a/MemoryModule/MmpDotNet.h +++ b/MemoryModule/MmpDotNet.h @@ -1,3 +1,11 @@ #pragma once + +typedef HRESULT(WINAPI* GetFileVersion_T)( + LPCWSTR szFilename, + LPWSTR szBuffer, + DWORD cchBuffer, + DWORD* dwLength + ); + BOOL WINAPI MmpPreInitializeHooksForDotNet(); BOOL WINAPI MmpInitializeHooksForDotNet(); \ No newline at end of file diff --git a/MemoryModule/MmpGlobalData.h b/MemoryModule/MmpGlobalData.h index 56d2d914..d672a7f7 100644 --- a/MemoryModule/MmpGlobalData.h +++ b/MemoryModule/MmpGlobalData.h @@ -24,6 +24,13 @@ typedef struct _MMP_TLS_DATA { CRITICAL_SECTION MmpTlspLock; LIST_ENTRY MmpThreadLocalStoragePointer; DWORD MmpActiveThreadCount; + + struct { + decltype(&NtCreateThread) OriginNtCreateThread; + decltype(&NtCreateThreadEx) OriginNtCreateThreadEx; + decltype(&NtSetInformationProcess) OriginNtSetInformationProcess; + decltype(&LdrShutdownThread) OriginLdrShutdownThread; + }Hooks; }MMP_TLS_DATA, * PMMP_TLS_DATA; //MmpDotNet.cpp @@ -35,6 +42,21 @@ typedef struct _MMP_DOT_NET_DATA { BOOLEAN PreHooked; BOOLEAN Initialized; + + struct { + decltype(&CreateFileW) OriginCreateFileW; + decltype(&GetFileInformationByHandle) OriginGetFileInformationByHandle; + decltype(&GetFileAttributesExW) OriginGetFileAttributesExW; + decltype(&GetFileSize) OriginGetFileSize; + decltype(&GetFileSizeEx) OriginGetFileSizeEx; + decltype(&CreateFileMappingW) OriginCreateFileMappingW; + decltype(&MapViewOfFileEx) OriginMapViewOfFileEx; + decltype(&MapViewOfFile) OriginMapViewOfFile; + decltype(&UnmapViewOfFile)OriginUnmapViewOfFile; + decltype(&CloseHandle)OriginCloseHandle; + GetFileVersion_T OriginGetFileVersion1; + GetFileVersion_T OriginGetFileVersion2; + }Hooks; }MMP_DOT_NET_DATA, * PMMP_DOT_NET_DATA; typedef struct _MMP_GLOBAL_DATA { diff --git a/MemoryModule/MmpTls.cpp b/MemoryModule/MmpTls.cpp index de7cb0e4..78876354 100644 --- a/MemoryModule/MmpTls.cpp +++ b/MemoryModule/MmpTls.cpp @@ -55,11 +55,6 @@ typedef struct _MMP_TLSP_RECORD { PVOID* TlspMmpBlock; }MMP_TLSP_RECORD, * PMMP_TLSP_RECORD; -decltype(&NtCreateThread) OriginNtCreateThread = NtCreateThread; -decltype(&NtCreateThreadEx) OriginNtCreateThreadEx = NtCreateThreadEx; -decltype(&NtSetInformationProcess) OriginNtSetInformationProcess = NtSetInformationProcess; -decltype(&LdrShutdownThread) OriginLdrShutdownThread = LdrShutdownThread; - typedef struct _THREAD_CONTEXT { PTHREAD_START_ROUTINE ThreadStartRoutine; LPVOID ThreadParameter; @@ -262,7 +257,7 @@ NTSTATUS NTAPI HookNtCreateThread( Context.Rdx = ULONG64(_Context); #endif - status = OriginNtCreateThread( + status = MmpGlobalDataPtr->MmpTls.Hooks.OriginNtCreateThread( ThreadHandle, DesiredAccess, ObjectAttributes, @@ -299,7 +294,7 @@ NTSTATUS NTAPI HookNtCreateThreadEx( Context->ThreadStartRoutine = PTHREAD_START_ROUTINE(StartRoutine); Context->ThreadParameter = Argument; - NTSTATUS status = OriginNtCreateThreadEx( + NTSTATUS status = MmpGlobalDataPtr->MmpTls.Hooks.OriginNtCreateThreadEx( ThreadHandle, DesiredAccess, ObjectAttributes, @@ -382,7 +377,7 @@ VOID NTAPI HookLdrShutdownThread(VOID) { // // Call the original function // - OriginLdrShutdownThread(); + MmpGlobalDataPtr->MmpTls.Hooks.OriginLdrShutdownThread(); } BOOL NTAPI PreHookNtSetInformationProcess() { @@ -463,7 +458,7 @@ NTSTATUS NTAPI HookNtSetInformationProcess( _In_ ULONG ProcessInformationLength) { if (ProcessInformationClass != ProcessTlsInformation) { - return OriginNtSetInformationProcess( + return MmpGlobalDataPtr->MmpTls.Hooks.OriginNtSetInformationProcess( ProcessHandle, ProcessInformationClass, ProcessInformation, @@ -537,7 +532,7 @@ NTSTATUS NTAPI HookNtSetInformationProcess( } } - status = OriginNtSetInformationProcess( + status = MmpGlobalDataPtr->MmpTls.Hooks.OriginNtSetInformationProcess( hProcess, ProcessInformationClass, Tls, @@ -826,12 +821,18 @@ BOOL NTAPI MmpTlsInitialize() { // // Hook functions // + + MmpGlobalDataPtr->MmpTls.Hooks.OriginNtCreateThread = NtCreateThread; + MmpGlobalDataPtr->MmpTls.Hooks.OriginNtCreateThreadEx = NtCreateThreadEx; + MmpGlobalDataPtr->MmpTls.Hooks.OriginLdrShutdownThread = LdrShutdownThread; + MmpGlobalDataPtr->MmpTls.Hooks.OriginNtSetInformationProcess = NtSetInformationProcess; + DetourTransactionBegin(); DetourUpdateThread(NtCurrentThread()); - DetourAttach((PVOID*)&OriginNtCreateThread, HookNtCreateThread); - DetourAttach((PVOID*)&OriginNtCreateThreadEx, HookNtCreateThreadEx); - DetourAttach((PVOID*)&OriginLdrShutdownThread, HookLdrShutdownThread); - DetourAttach((PVOID*)&OriginNtSetInformationProcess, HookNtSetInformationProcess); + DetourAttach((PVOID*)&MmpGlobalDataPtr->MmpTls.Hooks.OriginNtCreateThread, HookNtCreateThread); + DetourAttach((PVOID*)&MmpGlobalDataPtr->MmpTls.Hooks.OriginNtCreateThreadEx, HookNtCreateThreadEx); + DetourAttach((PVOID*)&MmpGlobalDataPtr->MmpTls.Hooks.OriginLdrShutdownThread, HookLdrShutdownThread); + DetourAttach((PVOID*)&MmpGlobalDataPtr->MmpTls.Hooks.OriginNtSetInformationProcess, HookNtSetInformationProcess); DetourTransactionCommit(); return TRUE; diff --git a/MemoryModulePP.sln b/MemoryModulePP.sln index 77f852f9..21ce55a0 100644 --- a/MemoryModulePP.sln +++ b/MemoryModulePP.sln @@ -21,8 +21,8 @@ Global {5B1F46DB-036E-4A50-AF5F-F5D6584D42C6}.Debug|x64.Build.0 = Debug|x64 {5B1F46DB-036E-4A50-AF5F-F5D6584D42C6}.Debug|x86.ActiveCfg = DebugDll|Win32 {5B1F46DB-036E-4A50-AF5F-F5D6584D42C6}.Debug|x86.Build.0 = DebugDll|Win32 - {5B1F46DB-036E-4A50-AF5F-F5D6584D42C6}.Release|x64.ActiveCfg = ReleaseDll|x64 - {5B1F46DB-036E-4A50-AF5F-F5D6584D42C6}.Release|x64.Build.0 = ReleaseDll|x64 + {5B1F46DB-036E-4A50-AF5F-F5D6584D42C6}.Release|x64.ActiveCfg = Release|x64 + {5B1F46DB-036E-4A50-AF5F-F5D6584D42C6}.Release|x64.Build.0 = Release|x64 {5B1F46DB-036E-4A50-AF5F-F5D6584D42C6}.Release|x86.ActiveCfg = ReleaseDll|Win32 {5B1F46DB-036E-4A50-AF5F-F5D6584D42C6}.Release|x86.Build.0 = ReleaseDll|Win32 {5B3131BA-178A-4A28-BD54-315A45C97ED1}.Debug|x64.ActiveCfg = Debug|x64 diff --git a/test/test.vcxproj b/test/test.vcxproj index 5b0935cf..2d10375f 100644 --- a/test/test.vcxproj +++ b/test/test.vcxproj @@ -122,6 +122,7 @@ true WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) true + MultiThreaded Console @@ -140,22 +141,27 @@ true NDEBUG;_CONSOLE;%(PreprocessorDefinitions) true + MultiThreaded Console true true true + + - true + + - true + + From 1af4e81913aefdbb0227e7a40584fab48de8f3a9 Mon Sep 17 00:00:00 2001 From: Boring Date: Sat, 1 Oct 2022 21:07:53 +0800 Subject: [PATCH 5/8] Test MMPP multiple initialization --- MemoryModule/Initialize.cpp | 2 +- a/a.vcxproj | 6 +++ a/a.vcxproj.filters | 3 ++ a/load.cpp | 50 ++++++++++++++++++ a/m.def | 1 + test/test.cpp | 100 +++--------------------------------- 6 files changed, 69 insertions(+), 93 deletions(-) create mode 100644 a/load.cpp diff --git a/MemoryModule/Initialize.cpp b/MemoryModule/Initialize.cpp index dde66846..579d3383 100644 --- a/MemoryModule/Initialize.cpp +++ b/MemoryModule/Initialize.cpp @@ -12,7 +12,7 @@ PMMP_GLOBAL_DATA MmpGlobalDataPtr; BOOLEAN MmpBuildSectionName(_Out_ PUNICODE_STRING SectionName) { WCHAR buffer[128]; - wsprintfW(buffer, L"\\Sessions\\%d\\BaseNamedObjects\\MMPP%d", NtCurrentPeb()->SessionId, (unsigned int)NtCurrentProcessId()); + swprintf(buffer, L"\\Sessions\\%d\\BaseNamedObjects\\MMPP*%08X", NtCurrentPeb()->SessionId, (unsigned int)NtCurrentProcessId()); return RtlCreateUnicodeString(SectionName, buffer); } diff --git a/a/a.vcxproj b/a/a.vcxproj index 87fd5fe8..64c97ecb 100644 --- a/a/a.vcxproj +++ b/a/a.vcxproj @@ -172,6 +172,7 @@ + @@ -183,6 +184,11 @@ + + + {5b1f46db-036e-4a50-af5f-f5d6584d42c6} + + diff --git a/a/a.vcxproj.filters b/a/a.vcxproj.filters index bf20d60e..c622f7a5 100644 --- a/a/a.vcxproj.filters +++ b/a/a.vcxproj.filters @@ -18,6 +18,9 @@ Source Files + + Source Files + diff --git a/a/load.cpp b/a/load.cpp new file mode 100644 index 00000000..5262540d --- /dev/null +++ b/a/load.cpp @@ -0,0 +1,50 @@ +#include "../MemoryModule/stdafx.h" +#include + +static PVOID ReadDllFile(LPCSTR FileName) { + LPVOID buffer; + size_t size; + FILE* f = fopen(FileName, "rb"); + if (!f)return 0; + _fseeki64(f, 0, SEEK_END); + if (!(size = _ftelli64(f))) { + fclose(f); + return 0; + } + _fseeki64(f, 0, SEEK_SET); + fread(buffer = new char[size], 1, size, f); + fclose(f); + return buffer; +} + +int __stdcall test_user32() { + HMODULE hModule; + NTSTATUS status; + PVOID buffer = ReadDllFile("C:\\Windows\\System32\\user32.dll"); + if (!buffer) return 0; + + hModule = GetModuleHandleA("user32.dll"); + if (hModule)return 0; + + status = LdrLoadDllMemoryExW( + &hModule, // ModuleHandle + nullptr, // LdrEntry + 0, // Flags + buffer, // Buffer + 0, // Reserved + L"user32.dll", // DllBaseName + L"C:\\Windows\\System32\\user32.dll" // DllFullName + ); + if (NT_SUCCESS(status) && status != STATUS_IMAGE_MACHINE_TYPE_MISMATCH) { + + auto _MessageBoxW = (decltype(&MessageBoxW))GetProcAddress(hModule, "MessageBoxW"); + _MessageBoxW(nullptr, L"Hello, from memory user32!", L"Caption", MB_OK); + + // + // After calling MessageBox, we can't free it. + // + //LdrUnloadDllMemory(hModule); + } + + return 0; +} diff --git a/a/m.def b/a/m.def index 71d549f9..47f3a565 100644 --- a/a/m.def +++ b/a/m.def @@ -4,3 +4,4 @@ test = __test__ thread Socket = ws2_32.WSASocketW VerifyTruse = wintrust.WinVerifyTrust +test_user32 \ No newline at end of file diff --git a/test/test.cpp b/test/test.cpp index 29a047a1..f5a7ac29 100644 --- a/test/test.cpp +++ b/test/test.cpp @@ -18,110 +18,26 @@ static PVOID ReadDllFile(LPCSTR FileName) { return buffer; } -int test_a_dll() { - LPVOID buffer = ReadDllFile("a.dll"); - - HMEMORYMODULE m1 = nullptr, m2 = m1; - HMODULE hModule = nullptr; - FARPROC pfn = nullptr; - DWORD MemoryModuleFeatures = 0; - - typedef int(*_exception)(int code); - _exception exception = nullptr; - HRSRC hRsrc; - DWORD SizeofRes; - HGLOBAL gRes; - char str[10]; - - LdrQuerySystemMemoryModuleFeatures(&MemoryModuleFeatures); - if (MemoryModuleFeatures != MEMORY_FEATURE_ALL) { - printf("not support all features on this version of windows.\n"); - } - - if (!NT_SUCCESS(LdrLoadDllMemoryExW(&m1, nullptr, 0, buffer, 0, L"kernel64", nullptr))) goto end; - LoadLibraryW(L"wininet.dll"); - if (!NT_SUCCESS(LdrLoadDllMemoryExW(&m2, nullptr, 0, buffer, 0, L"kernel128", nullptr))) goto end; - - //forward export - hModule = (HMODULE)m1; - pfn = (decltype(pfn))(GetProcAddress(hModule, "Socket")); //ws2_32.WSASocketW - pfn = (decltype(pfn))(GetProcAddress(hModule, "VerifyTruse")); //wintrust.WinVerifyTrust - hModule = (HMODULE)m2; - pfn = (decltype(pfn))(GetProcAddress(hModule, "Socket")); - pfn = (decltype(pfn))(GetProcAddress(hModule, "VerifyTruse")); - - //exception - hModule = (HMODULE)m1; - exception = (_exception)GetProcAddress(hModule, "exception"); - if (exception) { - for (int i = 0; i < 5; ++i)exception(i); - } - - //tls - pfn = GetProcAddress(hModule, "thread"); - if (pfn && pfn()) { - printf("thread test failed.\n"); - } - - //resource - if (!LoadStringA(hModule, 101, str, 10)) { - printf("load string failed.\n"); - } - else { - printf("%s\n", str); - } - if (!(hRsrc = FindResourceA(hModule, MAKEINTRESOURCEA(102), "BINARY"))) { - printf("find binary resource failed.\n"); - } - else { - if ((SizeofRes = SizeofResource(hModule, hRsrc)) != 0x10) { - printf("invalid res size.\n"); - } - else { - if (!(gRes = LoadResource(hModule, hRsrc))) { - printf("load res failed.\n"); - } - else { - if (!LockResource(gRes))printf("lock res failed.\n"); - else { - printf("resource test success.\n"); - } - } - } - } - -end: - delete[]buffer; - if (m1)LdrUnloadDllMemory(m1); - FreeLibrary(LoadLibraryW(L"wininet.dll")); - FreeLibrary(GetModuleHandleW(L"wininet.dll")); - if (m2)LdrUnloadDllMemory(m2); - - return 0; -} - -int test_user32() { +int test() { HMODULE hModule; NTSTATUS status; - PVOID buffer = ReadDllFile("C:\\Windows\\System32\\user32.dll"); + PVOID buffer = ReadDllFile("a.dll"); if (!buffer) return 0; - hModule = GetModuleHandleA("user32.dll"); - if (hModule)return 0; - status = LdrLoadDllMemoryExW( &hModule, // ModuleHandle nullptr, // LdrEntry 0, // Flags buffer, // Buffer 0, // Reserved - L"user32.dll", // DllBaseName - L"C:\\Windows\\System32\\user32.dll" // DllFullName + L"a.dll", // DllBaseName + L"C:\\Windows\\System32\\a.dll" // DllFullName ); if (NT_SUCCESS(status) && status != STATUS_IMAGE_MACHINE_TYPE_MISMATCH) { - auto _MessageBoxW = (decltype(&MessageBoxW))GetProcAddress(hModule, "MessageBoxW"); - _MessageBoxW(nullptr, L"Hello, from memory user32!", L"Caption", MB_OK); + typedef int(__stdcall* func)(); + func test_user32 = (func)GetProcAddress(hModule, "test_user32"); + test_user32(); // // After calling MessageBox, we can't free it. @@ -133,6 +49,6 @@ int test_user32() { } int main() { - test_a_dll(); + test(); return 0; } From 5d28989ed36173c27efa430069ac5ba6b57f0ac0 Mon Sep 17 00:00:00 2001 From: Boring <1079299053@qq.com> Date: Mon, 3 Oct 2022 17:25:02 +0800 Subject: [PATCH 6/8] refactoring --- MemoryModule/Initialize.cpp | 21 ++- MemoryModule/InvertedFunctionTable.cpp | 4 +- MemoryModule/InvertedFunctionTable.h | 2 +- MemoryModule/LdrEntry.cpp | 56 +++--- MemoryModule/Loader.cpp | 18 +- MemoryModule/MemoryModule.cpp | 13 +- MemoryModule/MemoryModule.h | 1 - MemoryModule/MmpGlobalData.h | 6 + MemoryModule/MmpTls.cpp | 6 +- MemoryModule/Utils.cpp | 236 ++++++++++++++----------- MemoryModule/Utils.h | 16 +- MemoryModulePP.sln | 8 +- a/load.cpp | 3 +- test/test.cpp | 8 +- 14 files changed, 219 insertions(+), 179 deletions(-) diff --git a/MemoryModule/Initialize.cpp b/MemoryModule/Initialize.cpp index 579d3383..48f62f6b 100644 --- a/MemoryModule/Initialize.cpp +++ b/MemoryModule/Initialize.cpp @@ -3,16 +3,10 @@ PMMP_GLOBAL_DATA MmpGlobalDataPtr; -#ifdef _WIN64 -#define FindLdrpInvertedFunctionTable FindLdrpInvertedFunctionTable64 -#else -#define FindLdrpInvertedFunctionTable FindLdrpInvertedFunctionTable32 -#endif - BOOLEAN MmpBuildSectionName(_Out_ PUNICODE_STRING SectionName) { WCHAR buffer[128]; - swprintf(buffer, L"\\Sessions\\%d\\BaseNamedObjects\\MMPP*%08X", NtCurrentPeb()->SessionId, (unsigned int)NtCurrentProcessId()); + swprintf_s(buffer, L"\\Sessions\\%d\\BaseNamedObjects\\MMPP*%08X", NtCurrentPeb()->SessionId, (unsigned int)(ULONG_PTR)NtCurrentProcessId()); return RtlCreateUnicodeString(SectionName, buffer); } @@ -51,6 +45,7 @@ static __forceinline bool IsModuleUnloaded(PLDR_DATA_TABLE_ENTRY entry) { } } +#ifndef _WIN64 PVOID FindLdrpInvertedFunctionTable32() { // _RTL_INVERTED_FUNCTION_TABLE x86 // Count +0x0 ???????? @@ -103,6 +98,8 @@ PVOID FindLdrpInvertedFunctionTable32() { return nullptr; } +#define FindLdrpInvertedFunctionTable FindLdrpInvertedFunctionTable32 +#else PVOID FindLdrpInvertedFunctionTable64() { // _RTL_INVERTED_FUNCTION_TABLE x64 // Count +0x0 ???????? @@ -165,6 +162,9 @@ PVOID FindLdrpInvertedFunctionTable64() { return nullptr; } +#define FindLdrpInvertedFunctionTable FindLdrpInvertedFunctionTable64 +#endif + PLIST_ENTRY FindLdrpHashTable() { PLIST_ENTRY list = nullptr; PLIST_ENTRY head = &NtCurrentPeb()->Ldr->InInitializationOrderModuleList, entry = head->Flink; @@ -255,6 +255,13 @@ NTSTATUS InitializeLockHeld() { GetSystemInfo(&MmpGlobalDataPtr->SystemInfo); + RtlGetNtVersionNumbers( + &MmpGlobalDataPtr->NtVersions.MajorVersion, + &MmpGlobalDataPtr->NtVersions.MinorVersion, + &MmpGlobalDataPtr->NtVersions.BuildNumber + ); + if (MmpGlobalDataPtr->NtVersions.BuildNumber & 0xf0000000)MmpGlobalDataPtr->NtVersions.BuildNumber &= 0xffff; + MmpGlobalDataPtr->MmpBaseAddressIndex.NtdllLdrEntry = RtlFindLdrTableEntryByBaseName(L"ntdll.dll"); MmpGlobalDataPtr->MmpBaseAddressIndex.LdrpModuleBaseAddressIndex = FindLdrpModuleBaseAddressIndex(); diff --git a/MemoryModule/InvertedFunctionTable.cpp b/MemoryModule/InvertedFunctionTable.cpp index c5f90a9d..51597a6b 100644 --- a/MemoryModule/InvertedFunctionTable.cpp +++ b/MemoryModule/InvertedFunctionTable.cpp @@ -136,7 +136,7 @@ static VOID NTAPI RtlpRemoveInvertedFunctionTable(IN PRTL_INVERTED_FUNCTION_TABL return; } -static NTSTATUS NTAPI RtlProtectMrdata(IN SIZE_T Protect) { +static NTSTATUS NTAPI RtlProtectMrdata(IN ULONG Protect) { static PVOID MrdataBase = nullptr; static SIZE_T size = 0; NTSTATUS status; @@ -157,7 +157,7 @@ static NTSTATUS NTAPI RtlProtectMrdata(IN SIZE_T Protect) { return NtProtectVirtualMemory(GetCurrentProcess(), &tmp, &tmp_len, Protect, &old); } -NTSTATUS NTAPI RtlInsertInvertedFunctionTable(IN PVOID BaseAddress, IN size_t ImageSize) { +NTSTATUS NTAPI RtlInsertInvertedFunctionTable(IN PVOID BaseAddress, IN ULONG ImageSize) { auto table = PRTL_INVERTED_FUNCTION_TABLE(MmpGlobalDataPtr->MmpInvertedFunctionTable.LdrpInvertedFunctionTable); if (!table)return STATUS_NOT_SUPPORTED; bool need_virtual_protect = RtlIsWindowsVersionOrGreater(6, 3, 0); diff --git a/MemoryModule/InvertedFunctionTable.h b/MemoryModule/InvertedFunctionTable.h index 979a3e6a..575899e3 100644 --- a/MemoryModule/InvertedFunctionTable.h +++ b/MemoryModule/InvertedFunctionTable.h @@ -52,5 +52,5 @@ typedef RTL_INVERTED_FUNCTION_TABLE_WIN7_32 _RTL_INVERTED_FUNCTION_TABLE, RTL_IN typedef _RTL_INVERTED_FUNCTION_TABLE_ENTRY_WIN7_32 _RTL_INVERTED_FUNCTION_TABLE_ENTRY, RTL_INVERTED_FUNCTION_TABLE_ENTRY, * PRTL_INVERTED_FUNCTION_TABLE_ENTRY; #endif -NTSTATUS NTAPI RtlInsertInvertedFunctionTable(IN PVOID BaseAddress, IN size_t ImageSize); +NTSTATUS NTAPI RtlInsertInvertedFunctionTable(IN PVOID BaseAddress, IN ULONG ImageSize); NTSTATUS NTAPI RtlRemoveInvertedFunctionTable(IN PVOID ImageBase); diff --git a/MemoryModule/LdrEntry.cpp b/MemoryModule/LdrEntry.cpp index 867cd22c..f427c6e6 100644 --- a/MemoryModule/LdrEntry.cpp +++ b/MemoryModule/LdrEntry.cpp @@ -120,14 +120,14 @@ bool NTAPI RtlInitializeLdrDataTableEntry( } switch (NtWindowsVersion()) { - case win10: - case win10_1: - case win10_2: { + case WINDOWS_VERSION::win10: + case WINDOWS_VERSION::win10_1: + case WINDOWS_VERSION::win10_2: { auto entry = (PLDR_DATA_TABLE_ENTRY_WIN10)LdrEntry; entry->ReferenceCount = 1; } - case win8: - case win8_1: { + case WINDOWS_VERSION::win8: + case WINDOWS_VERSION::win8_1: { auto entry = (PLDR_DATA_TABLE_ENTRY_WIN8)LdrEntry; const static bool IsWin8 = RtlIsWindowsVersionInScope(6, 2, 0, 6, 3, -1); NtQuerySystemTime(&entry->LoadTime); @@ -156,14 +156,14 @@ bool NTAPI RtlInitializeLdrDataTableEntry( FlagsProcessed = true; } - case win7: { + case WINDOWS_VERSION::win7: { if (LdrpDataTableEntrySize() == sizeof(LDR_DATA_TABLE_ENTRY_WIN7)) { auto entry = (PLDR_DATA_TABLE_ENTRY_WIN7)LdrEntry; entry->OriginalBase = headers->OptionalHeader.ImageBase; NtQuerySystemTime(&entry->LoadTime); } } - case vista: { + case WINDOWS_VERSION::vista: { if (LdrpDataTableEntrySize() == sizeof(LDR_DATA_TABLE_ENTRY_VISTA) || LdrpDataTableEntrySize() == sizeof(LDR_DATA_TABLE_ENTRY_WIN7)) { auto entry = (PLDR_DATA_TABLE_ENTRY_VISTA)LdrEntry; @@ -172,7 +172,7 @@ bool NTAPI RtlInitializeLdrDataTableEntry( RtlInitializeListEntry(&entry->ServiceTagLinks); } } - case xp: { + case WINDOWS_VERSION::xp: { LdrEntry->DllBase = BaseAddress; LdrEntry->SizeOfImage = headers->OptionalHeader.SizeOfImage; LdrEntry->TimeDateStamp = headers->FileHeader.TimeDateStamp; @@ -194,18 +194,18 @@ bool NTAPI RtlInitializeLdrDataTableEntry( bool NTAPI RtlFreeLdrDataTableEntry(IN PLDR_DATA_TABLE_ENTRY LdrEntry) { HANDLE heap = NtCurrentPeb()->ProcessHeap; switch (NtWindowsVersion()) { - case win10: - case win10_1: - case win10_2: - case win8: - case win8_1: { + case WINDOWS_VERSION::win10: + case WINDOWS_VERSION::win10_1: + case WINDOWS_VERSION::win10_2: + case WINDOWS_VERSION::win8: + case WINDOWS_VERSION::win8_1: { auto entry = (PLDR_DATA_TABLE_ENTRY_WIN10)LdrEntry; RtlFreeDependencies(entry); RtlFreeHeap(heap, 0, entry->DdagNode); RtlRemoveModuleBaseAddressIndexNode(LdrEntry); } - case win7: - case vista: { + case WINDOWS_VERSION::win7: + case WINDOWS_VERSION::vista: { if (LdrpDataTableEntrySize() == sizeof(LDR_DATA_TABLE_ENTRY_VISTA) || LdrpDataTableEntrySize() == sizeof(LDR_DATA_TABLE_ENTRY_WIN7)) { PLDR_DATA_TABLE_ENTRY_VISTA entry = (decltype(entry))LdrEntry; @@ -218,7 +218,7 @@ bool NTAPI RtlFreeLdrDataTableEntry(IN PLDR_DATA_TABLE_ENTRY LdrEntry) { } } } - case xp: { + case WINDOWS_VERSION::xp: { RtlFreeHeap(heap, 0, LdrEntry->BaseDllName.Buffer); RtlFreeHeap(heap, 0, LdrEntry->FullDllName.Buffer); RemoveEntryList(&LdrEntry->InLoadOrderLinks); @@ -266,13 +266,13 @@ VOID NTAPI RtlInsertMemoryTableEntry(IN PLDR_DATA_TABLE_ENTRY LdrEntry) { } VOID NTAPI RtlRbInsertNodeEx(IN PRTL_RB_TREE Tree, IN PRTL_BALANCED_NODE Parent, IN BOOLEAN Right, OUT PRTL_BALANCED_NODE Node) { - decltype(&RtlRbInsertNodeEx)_RtlRbInsertNodeEx = decltype(_RtlRbInsertNodeEx)(RtlGetNtProcAddress("RtlRbInsertNodeEx")); + static decltype(&RtlRbInsertNodeEx)_RtlRbInsertNodeEx = decltype(_RtlRbInsertNodeEx)(RtlGetNtProcAddress("RtlRbInsertNodeEx")); if (!_RtlRbInsertNodeEx)return; return _RtlRbInsertNodeEx(Tree, Parent, Right, Node); } VOID NTAPI RtlRbRemoveNode(IN PRTL_RB_TREE Tree, IN PRTL_BALANCED_NODE Node) { - decltype(&RtlRbRemoveNode)_RtlRbRemoveNode = decltype(_RtlRbRemoveNode)(RtlGetNtProcAddress("RtlRbRemoveNode")); + static decltype(&RtlRbRemoveNode)_RtlRbRemoveNode = decltype(_RtlRbRemoveNode)(RtlGetNtProcAddress("RtlRbRemoveNode")); if (!_RtlRbRemoveNode)return; return _RtlRbRemoveNode(Tree, Node); } @@ -296,8 +296,8 @@ PLDR_DATA_TABLE_ENTRY NTAPI RtlFindLdrTableEntryByBaseName(PCWSTR BaseName) { while (ListEntry != ListHead) { CurEntry = CONTAINING_RECORD(ListEntry, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks); ListEntry = ListEntry->Flink; - if (!wcsnicmp(BaseName, CurEntry->BaseDllName.Buffer, (CurEntry->BaseDllName.Length / sizeof(wchar_t)) - 4) || - !wcsnicmp(BaseName, CurEntry->BaseDllName.Buffer, CurEntry->BaseDllName.Length / sizeof(wchar_t))) { + if (!_wcsnicmp(BaseName, CurEntry->BaseDllName.Buffer, (CurEntry->BaseDllName.Length / sizeof(wchar_t)) - 4) || + !_wcsnicmp(BaseName, CurEntry->BaseDllName.Buffer, CurEntry->BaseDllName.Length / sizeof(wchar_t))) { return CurEntry; } } @@ -322,14 +322,14 @@ size_t NTAPI LdrpDataTableEntrySize() { if (size)return size; switch (NtWindowsVersion()) { - case xp:return size = sizeof(LDR_DATA_TABLE_ENTRY_XP); - case vista:return size = sizeof(LDR_DATA_TABLE_ENTRY_VISTA); - case win7:return size = sizeof(LDR_DATA_TABLE_ENTRY_WIN7); - case win8:return size = sizeof(LDR_DATA_TABLE_ENTRY_WIN8); - case win8_1:return size = sizeof(LDR_DATA_TABLE_ENTRY_WIN8_1); - case win10:return size = sizeof(LDR_DATA_TABLE_ENTRY_WIN10); - case win10_1:return size = sizeof(LDR_DATA_TABLE_ENTRY_WIN10_1); - case win10_2:return size = sizeof(LDR_DATA_TABLE_ENTRY_WIN10_2); + case WINDOWS_VERSION::xp:return size = sizeof(LDR_DATA_TABLE_ENTRY_XP); + case WINDOWS_VERSION::vista:return size = sizeof(LDR_DATA_TABLE_ENTRY_VISTA); + case WINDOWS_VERSION::win7:return size = sizeof(LDR_DATA_TABLE_ENTRY_WIN7); + case WINDOWS_VERSION::win8:return size = sizeof(LDR_DATA_TABLE_ENTRY_WIN8); + case WINDOWS_VERSION::win8_1:return size = sizeof(LDR_DATA_TABLE_ENTRY_WIN8_1); + case WINDOWS_VERSION::win10:return size = sizeof(LDR_DATA_TABLE_ENTRY_WIN10); + case WINDOWS_VERSION::win10_1:return size = sizeof(LDR_DATA_TABLE_ENTRY_WIN10_1); + case WINDOWS_VERSION::win10_2:return size = sizeof(LDR_DATA_TABLE_ENTRY_WIN10_2); default:return size = sizeof(LDR_DATA_TABLE_ENTRY_WIN10_2); } } diff --git a/MemoryModule/Loader.cpp b/MemoryModule/Loader.cpp index 5dbf8360..b3316944 100644 --- a/MemoryModule/Loader.cpp +++ b/MemoryModule/Loader.cpp @@ -13,7 +13,7 @@ static NTSTATUS NTAPI LdrMapDllMemory(IN HMEMORYMODULE ViewBase, IN DWORD dwFlag if (!(LdrEntry = RtlAllocateDataTableEntry(ViewBase))) return STATUS_NO_MEMORY; - if (!RtlResolveDllNameUnicodeString(DllName, lpFullDllName, &BaseDllName, &FullDllName)) { + if (!NT_SUCCESS(RtlResolveDllNameUnicodeString(DllName, lpFullDllName, &BaseDllName, &FullDllName))) { RtlFreeHeap(heap, 0, LdrEntry); return STATUS_NO_MEMORY; } @@ -31,7 +31,7 @@ static NTSTATUS NTAPI LdrMapDllMemory(IN HMEMORYMODULE ViewBase, IN DWORD dwFlag } NTSTATUS NTAPI LdrLoadDllMemory(OUT HMEMORYMODULE* BaseAddress, IN LPVOID BufferAddress, IN size_t BufferSize) { - return LdrLoadDllMemoryExW(BaseAddress, nullptr, LOAD_FLAGS_NOT_FAIL_IF_HANDLE_TLS, BufferAddress, BufferSize, nullptr, nullptr); + return LdrLoadDllMemoryExW(BaseAddress, nullptr, 0, BufferAddress, BufferSize, nullptr, nullptr); } NTSTATUS NTAPI LdrLoadDllMemoryExW( @@ -76,8 +76,8 @@ NTSTATUS NTAPI LdrLoadDllMemoryExW( /* Check if it's being unloaded */ if (!CurEntry->InMemoryOrderLinks.Flink) continue; /* Check if name matches */ - if (!wcsnicmp(DllName, CurEntry->BaseDllName.Buffer, (CurEntry->BaseDllName.Length / sizeof(wchar_t)) - 4) || - !wcsnicmp(DllName, CurEntry->BaseDllName.Buffer, CurEntry->BaseDllName.Length / sizeof(wchar_t))) { + if (!_wcsnicmp(DllName, CurEntry->BaseDllName.Buffer, (CurEntry->BaseDllName.Length / sizeof(wchar_t)) - 4) || + !_wcsnicmp(DllName, CurEntry->BaseDllName.Buffer, CurEntry->BaseDllName.Length / sizeof(wchar_t))) { /* Let's compare their headers */ if (!(h2 = RtlImageNtHeader(CurEntry->DllBase)))continue; if (!(module = MapMemoryModuleHandle((HMEMORYMODULE)CurEntry->DllBase)))continue; @@ -94,7 +94,7 @@ NTSTATUS NTAPI LdrLoadDllMemoryExW( } } - status = MemoryLoadLibrary(BaseAddress, BufferAddress, BufferSize); + status = MemoryLoadLibrary(BaseAddress, BufferAddress, (DWORD)BufferSize); if (!NT_SUCCESS(status) || status == STATUS_IMAGE_MACHINE_TYPE_MISMATCH)return status; if (!(module = MapMemoryModuleHandle(*BaseAddress))) { @@ -204,16 +204,16 @@ NTSTATUS NTAPI LdrLoadDllMemoryExA( if (DllName) { size = strlen(DllName) + 1; _DllName = new wchar_t[size]; - mbstowcs(_DllName, DllName, size); + mbstowcs_s(nullptr, _DllName, size, DllName, size); } if (DllFullName) { size = strlen(DllFullName) + 1; _DllFullName = new wchar_t[size]; - mbstowcs(_DllFullName, DllFullName, size); + mbstowcs_s(nullptr, _DllFullName, size, DllFullName, size); } status = LdrLoadDllMemoryExW(BaseAddress, LdrEntry, dwFlags, BufferAddress, BufferSize, _DllName, _DllFullName); - if (_DllName)delete[]_DllName; - if (_DllFullName)delete[]_DllFullName; + delete[]_DllName; + delete[]_DllFullName; return status; } diff --git a/MemoryModule/MemoryModule.cpp b/MemoryModule/MemoryModule.cpp index 6c1731fe..7c4f9ccf 100644 --- a/MemoryModule/MemoryModule.cpp +++ b/MemoryModule/MemoryModule.cpp @@ -81,16 +81,12 @@ NTSTATUS MemoryResolveImportTable( } if (importDesc && count) { - if (!(hMemoryModule->hModulesList = new HMODULE[count])) { + hMemoryModule->hModulesList = (HMODULE*)RtlAllocateHeap(NtCurrentPeb()->ProcessHeap, HEAP_ZERO_MEMORY, sizeof(HMODULE) * count); + if (!hMemoryModule->hModulesList) { status = STATUS_NO_MEMORY; break; } - RtlZeroMemory( - hMemoryModule->hModulesList, - sizeof(HMODULE) * count - ); - for (DWORD i = 0; i < count; ++i, ++importDesc) { uintptr_t* thunkRef; FARPROC* funcRef; @@ -131,7 +127,7 @@ NTSTATUS MemoryResolveImportTable( for (DWORD i = 0; i < hMemoryModule->dwModulesCount; ++i) FreeLibrary(hMemoryModule->hModulesList[i]); - delete[]hMemoryModule->hModulesList; + RtlFreeHeap(NtCurrentPeb()->ProcessHeap, 0, hMemoryModule->hModulesList); hMemoryModule->hModulesList = nullptr; hMemoryModule->dwModulesCount = 0; } @@ -418,7 +414,8 @@ bool MemoryFreeLibrary(HMEMORYMODULE mod) { FreeLibrary(module->hModulesList[i]); } } - delete[] module->hModulesList; + + RtlFreeHeap(NtCurrentPeb()->ProcessHeap, 0, module->hModulesList); } if (module->codeBase) VirtualFree(mod, 0, MEM_RELEASE); diff --git a/MemoryModule/MemoryModule.h b/MemoryModule/MemoryModule.h index b0b14ec9..e1b18cdd 100644 --- a/MemoryModule/MemoryModule.h +++ b/MemoryModule/MemoryModule.h @@ -1,5 +1,4 @@ #pragma once -#pragma warning(disable:4996) #ifndef __MEMORY_MODULE_HEADER #define __MEMORY_MODULE_HEADER diff --git a/MemoryModule/MmpGlobalData.h b/MemoryModule/MmpGlobalData.h index d672a7f7..78068abc 100644 --- a/MemoryModule/MmpGlobalData.h +++ b/MemoryModule/MmpGlobalData.h @@ -66,6 +66,12 @@ typedef struct _MMP_GLOBAL_DATA { DWORD MmpFeatures; + struct { + DWORD MajorVersion; + DWORD MinorVersion; + DWORD BuildNumber; + }NtVersions; + SYSTEM_INFO SystemInfo; MMP_BASE_ADDRESS_INDEX_DATA MmpBaseAddressIndex; diff --git a/MemoryModule/MmpTls.cpp b/MemoryModule/MmpTls.cpp index 78876354..61842d0b 100644 --- a/MemoryModule/MmpTls.cpp +++ b/MemoryModule/MmpTls.cpp @@ -513,7 +513,7 @@ NTSTATUS NTAPI HookNtSetInformationProcess( } Tls->OperationType = ProcessTlsReplaceIndex; - for (auto i = 0; i < Tls->ThreadDataCount; ++i) { + for (ULONG i = 0; i < Tls->ThreadDataCount; ++i) { Tls->ThreadData[i].TlsModulePointer = Tls->ThreadData[i].TlsVector[ProcessTlsInformation->TlsVectorLength]; } } @@ -543,7 +543,7 @@ NTSTATUS NTAPI HookNtSetInformationProcess( // Modify our mapping // EnterCriticalSection(&MmpGlobalDataPtr->MmpTls.MmpTlspLock); - for (auto i = 0; i < Tls->ThreadDataCount; ++i) { + for (ULONG i = 0; i < Tls->ThreadDataCount; ++i) { bool found = false; PLIST_ENTRY entry = MmpGlobalDataPtr->MmpTls.MmpThreadLocalStoragePointer.Flink; @@ -769,7 +769,7 @@ NTSTATUS NTAPI MmpHandleTlsData(_In_ PLDR_DATA_TABLE_ENTRY lpModuleEntry) { nullptr, // hack PROCESSINFOCLASS::ProcessTlsInformation, ProcessTlsInformation, - Length + (ULONG)Length ); for (DWORD i = 0; i < ProcessTlsInformation->ThreadDataCount; ++i) { diff --git a/MemoryModule/Utils.cpp b/MemoryModule/Utils.cpp index 3fe4e270..c12e62c4 100644 --- a/MemoryModule/Utils.cpp +++ b/MemoryModule/Utils.cpp @@ -2,68 +2,115 @@ #include #pragma comment(lib,"ntdll.lib") -bool NTAPI RtlResolveDllNameUnicodeString( - IN PCWSTR DllName OPTIONAL, IN PCWSTR DllFullName OPTIONAL, - OUT PUNICODE_STRING BaseDllName, OUT PUNICODE_STRING FullDllName) { +NTSTATUS NTAPI RtlResolveDllNameUnicodeString( + _In_opt_ PCWSTR DllName, + _In_opt_ PCWSTR DllFullName, + _Out_ PUNICODE_STRING BaseDllName, + _Out_ PUNICODE_STRING FullDllName) { std::random_device random; - size_t Length = 0; - size_t FullLength = 0; - PWSTR _DllName = nullptr, _DllFullName = _DllName; HANDLE heap = NtCurrentPeb()->ProcessHeap; - bool result = false; - if (DllName) { - bool add = false; - if ((Length = wcslen(DllName)) <= 4 || wcsnicmp(DllName + Length - 4, L".dll", 4)) { - add = true; - Length += 4; + NTSTATUS status = STATUS_SUCCESS; + size_t length; + + RtlZeroMemory(BaseDllName, sizeof(*BaseDllName)); + RtlZeroMemory(FullDllName, sizeof(*FullDllName)); + + do { + + if (DllName && *DllName) { + bool extend = false; + + length = wcslen(DllName); + if (length <= 4 || _wcsnicmp(DllName + length - 4, L".dll", 4)) { + length += 4; + extend = true; + } + + if (++length >= 0xffff) { + status = STATUS_OBJECT_NAME_INVALID; + break; + } + + BaseDllName->MaximumLength = (USHORT)(length * sizeof(WCHAR)); + BaseDllName->Length = BaseDllName->MaximumLength - sizeof(WCHAR); + BaseDllName->Buffer = (PWSTR)RtlAllocateHeap(heap, 0, BaseDllName->MaximumLength); + if (!BaseDllName->Buffer) { + status = STATUS_NO_MEMORY; + break; + } + + swprintf_s(BaseDllName->Buffer, length, extend ? L"%s.dll" : L"%s", DllName); } - _DllName = new wchar_t[++Length]; - wcscpy(_DllName, DllName); - if (add)wcscat(_DllName, L".DLL"); - } - else { - Length = 16 + 4 + 1; //hex(ULONG64) + ".dll" + '\0' - _DllName = new wchar_t[Length]; - swprintf(_DllName, L"%016llX.DLL", ((ULONG64)random() << 32) | random()); - } - if (DllFullName) { - bool add = false; - FullLength = wcslen(DllFullName); - if (DllName && !wcsstr(DllFullName, DllName) && wcsnicmp(DllFullName + FullLength - 4, L".dll", 4)) { - add = true; - FullLength += Length; + else { + DllName = nullptr; + + BaseDllName->MaximumLength = (16 + 4 + 1) * sizeof(WCHAR); //hex(ULONG64) + ".dll" + '\0' + BaseDllName->Length = BaseDllName->MaximumLength - sizeof(WCHAR); + BaseDllName->Buffer = (PWSTR)RtlAllocateHeap(heap, 0, BaseDllName->MaximumLength); + if (!BaseDllName->Buffer) { + status = STATUS_NO_MEMORY; + break; + } + + swprintf_s(BaseDllName->Buffer, BaseDllName->MaximumLength / sizeof(WCHAR), L"%016llX.DLL", ((ULONG64)random() << 32) | random()); } - wcscpy(_DllFullName = new wchar_t[++FullLength], DllFullName); - if (add) swprintf(_DllFullName, L"%s\\%s", _DllFullName, _DllName); - } - else { - FullLength = 16 + 1 + Length; //hex(ULONG64) + '\\' + _DllName - swprintf(_DllFullName = new wchar_t[FullLength], L"%016llX\\%s", ((ULONG64)random() << 32) | random(), _DllName); - } - FullLength *= sizeof(wchar_t); - Length *= sizeof(wchar_t); - - /* Allocate space for full DLL name */ - if (!(FullDllName->Buffer = (PWSTR)RtlAllocateHeap(heap, HEAP_ZERO_MEMORY, FullLength))) goto end; - FullDllName->Length = FullLength - sizeof(wchar_t); - FullDllName->MaximumLength = FullLength; - wcscpy(FullDllName->Buffer, _DllFullName); - - /* Construct base DLL name */ - BaseDllName->Length = Length - sizeof(wchar_t); - BaseDllName->MaximumLength = Length; - BaseDllName->Buffer = (PWSTR)RtlAllocateHeap(heap, HEAP_ZERO_MEMORY, Length); - if (!BaseDllName->Buffer) { + + if (DllFullName && *DllFullName) { + bool extend = false, backslash = false; + + unsigned int wc = BaseDllName->Length / sizeof(WCHAR); + length = wcslen(DllFullName); + if (length <= wc + 1 || _wcsicmp(DllFullName + length - wc, BaseDllName->Buffer) || *(DllFullName + length - wc - 1) != '\\') { + extend = true; + + if (DllFullName[length - 1] != '\\') { + backslash = true; + + ++length; + } + + length += BaseDllName->Length / sizeof(WCHAR); + } + + if (++length >= 0xffff) { + status = STATUS_OBJECT_NAME_INVALID; + break; + } + + FullDllName->MaximumLength = (USHORT)(length * sizeof(WCHAR)); + FullDllName->Length = FullDllName->MaximumLength - sizeof(WCHAR); + FullDllName->Buffer = (PWSTR)RtlAllocateHeap(heap, 0, FullDllName->MaximumLength); + if (!FullDllName->Buffer) { + status = STATUS_NO_MEMORY; + break; + } + + swprintf_s(FullDllName->Buffer, length, extend ? backslash ? L"%s\\%s" : L"%s%s" : L"%s", DllFullName, BaseDllName->Buffer); + } + else { + FullDllName->MaximumLength = (16 + 1 + 1) * sizeof(WCHAR) + BaseDllName->Length; //hex(ULONG64) + '\\' + BaseDllName + '\0' + FullDllName->Length = FullDllName->MaximumLength - sizeof(WCHAR); + FullDllName->Buffer = (PWSTR)RtlAllocateHeap(heap, 0, FullDllName->MaximumLength); + if (!FullDllName->Buffer) { + status = STATUS_NO_MEMORY; + break; + } + + swprintf_s(FullDllName->Buffer, FullDllName->MaximumLength / sizeof(WCHAR), L"%016llX\\%s", ((ULONG64)random() << 32) | random(), BaseDllName->Buffer); + } + + } while (false); + + if (!NT_SUCCESS(status)) { RtlFreeHeap(heap, 0, BaseDllName->Buffer); - goto end; + RtlFreeHeap(heap, 0, FullDllName->Buffer); + + RtlZeroMemory(BaseDllName, sizeof(*BaseDllName)); + RtlZeroMemory(FullDllName, sizeof(*FullDllName)); } - wcscpy(BaseDllName->Buffer, _DllName); - result = true; -end: - delete[]_DllName; - delete[]_DllFullName; - return result; + + return status; } BOOL NTAPI LdrpExecuteTLS(PMEMORYMODULE module) { @@ -256,7 +303,7 @@ BOOLEAN NTAPI RtlIsValidImageBuffer( IMAGE_FIRST_SECTION(headers.nt32); ProbeForRead(Buffer, SizeofImage); if (Size)*Size = SizeofImage; - result = CheckSumBufferedFile(Buffer, SizeofImage); + result = CheckSumBufferedFile(Buffer, (DWORD)SizeofImage); } __except (EXCEPTION_EXECUTE_HANDLER) { SetLastError(RtlNtStatusToDosError(GetExceptionCode())); @@ -268,20 +315,6 @@ FARPROC NTAPI RtlGetNtProcAddress(LPCSTR func_name) { return GetProcAddress(GetModuleHandleA("ntdll.dll"), func_name); } -VOID NTAPI RtlGetNtVersionNumbersEx(OUT DWORD* MajorVersion, OUT DWORD* MinorVersion, OUT DWORD* BuildNumber) { - static DWORD Versions[3]{ 0 }; - - if (Versions[0]) goto ret; - RtlGetNtVersionNumbers(Versions, Versions + 1, Versions + 2); - if (Versions[2] & 0xf0000000)Versions[2] &= 0xffff; - -ret: - if (MajorVersion)*MajorVersion = Versions[0]; - if (MinorVersion)*MinorVersion = Versions[1]; - if (BuildNumber)*BuildNumber = Versions[2]; - return; -} - BOOLEAN NTAPI VirtualAccessCheckNoException(LPCVOID pBuffer, size_t size, ACCESS_MASK protect) { if (size) { MEMORY_BASIC_INFORMATION mbi{}; @@ -303,23 +336,18 @@ BOOLEAN NTAPI VirtualAccessCheck(LPCVOID pBuffer, size_t size, ACCESS_MASK prote } bool NTAPI RtlVerifyVersion(IN DWORD MajorVersion, IN DWORD MinorVersion OPTIONAL, IN DWORD BuildNumber OPTIONAL, IN BYTE Flags) { - DWORD Versions[3]; - RtlGetNtVersionNumbersEx(Versions, Versions + 1, Versions + 2); - if (Versions[0] == MajorVersion && - ((Flags & RTL_VERIFY_FLAGS_MINOR_VERSION) ? Versions[1] == MinorVersion : true) && - ((Flags & RTL_VERIFY_FLAGS_BUILD_NUMBERS) ? Versions[2] == BuildNumber : true))return true; + if (MmpGlobalDataPtr->NtVersions.MajorVersion == MajorVersion && + ((Flags & RTL_VERIFY_FLAGS_MINOR_VERSION) ? MmpGlobalDataPtr->NtVersions.MinorVersion == MinorVersion : true) && + ((Flags & RTL_VERIFY_FLAGS_BUILD_NUMBERS) ? MmpGlobalDataPtr->NtVersions.BuildNumber == BuildNumber : true))return true; return false; } bool NTAPI RtlIsWindowsVersionOrGreater(IN DWORD MajorVersion, IN DWORD MinorVersion, IN DWORD BuildNumber) { - static DWORD Versions[3]{}; - if (!Versions[0])RtlGetNtVersionNumbersEx(Versions, Versions + 1, Versions + 2); - - if (Versions[0] == MajorVersion) { - if (Versions[1] == MinorVersion) return Versions[2] >= BuildNumber; - else return (Versions[1] > MinorVersion); + if (MmpGlobalDataPtr->NtVersions.MajorVersion == MajorVersion) { + if (MmpGlobalDataPtr->NtVersions.MinorVersion == MinorVersion) return MmpGlobalDataPtr->NtVersions.BuildNumber >= BuildNumber; + else return (MmpGlobalDataPtr->NtVersions.MinorVersion > MinorVersion); } - else return Versions[0] > MajorVersion; + else return MmpGlobalDataPtr->NtVersions.MajorVersion > MajorVersion; } bool NTAPI RtlIsWindowsVersionInScope( @@ -330,29 +358,27 @@ bool NTAPI RtlIsWindowsVersionInScope( } WINDOWS_VERSION NTAPI NtWindowsVersion() { - static WINDOWS_VERSION version = null; - DWORD versions[3]{}; - if (version)return version; - RtlGetNtVersionNumbersEx(versions, versions + 1, versions + 2); + static WINDOWS_VERSION version = WINDOWS_VERSION::null; + if (version!=WINDOWS_VERSION::null)return version; - switch (versions[0]) { + switch (MmpGlobalDataPtr->NtVersions.MajorVersion) { case 5: { - switch (versions[1]) { - case 1:return version = versions[2] == 2600 ? xp : invalid; - case 2:return version = versions[2] == 3790 ? xp : invalid; + switch (MmpGlobalDataPtr->NtVersions.MinorVersion) { + case 1:return version = MmpGlobalDataPtr->NtVersions.BuildNumber == 2600 ? WINDOWS_VERSION::xp : WINDOWS_VERSION::invalid; + case 2:return version = MmpGlobalDataPtr->NtVersions.BuildNumber == 3790 ? WINDOWS_VERSION::xp : WINDOWS_VERSION::invalid; default:break; } break; } break; case 6: { - switch (versions[1]) { + switch (MmpGlobalDataPtr->NtVersions.MinorVersion) { case 0: { - switch (versions[2]) { + switch (MmpGlobalDataPtr->NtVersions.BuildNumber) { case 6000: case 6001: case 6002: - return version = vista; + return version = WINDOWS_VERSION::vista; default: break; } @@ -360,10 +386,10 @@ WINDOWS_VERSION NTAPI NtWindowsVersion() { } break; case 1: { - switch (versions[2]) { + switch (MmpGlobalDataPtr->NtVersions.BuildNumber) { case 7600: case 7601: - return version = win7; + return version = WINDOWS_VERSION::win7; default: break; } @@ -371,12 +397,12 @@ WINDOWS_VERSION NTAPI NtWindowsVersion() { } break; case 2: { - if (versions[2] == 9200)return version = win8; + if (MmpGlobalDataPtr->NtVersions.BuildNumber == 9200)return version = WINDOWS_VERSION::win8; break; } break; case 3: { - if (versions[2] == 9600)return version = win8_1; + if (MmpGlobalDataPtr->NtVersions.BuildNumber == 9600)return version = WINDOWS_VERSION::win8_1; break; } break; @@ -387,17 +413,17 @@ WINDOWS_VERSION NTAPI NtWindowsVersion() { } break; case 10: { - if (versions[1])break; - switch (versions[2]) { + if (MmpGlobalDataPtr->NtVersions.MinorVersion)break; + switch (MmpGlobalDataPtr->NtVersions.BuildNumber) { case 10240: - case 10586: return version = win10; - case 14393: return version = win10_1; + case 10586: return version = WINDOWS_VERSION::win10; + case 14393: return version = WINDOWS_VERSION::win10_1; case 15063: case 16299: case 17134: case 17763: - case 18362:return version = win10_2; - default:if (RtlIsWindowsVersionOrGreater(versions[0], versions[1], 15063))return version = win10_2; + case 18362:return version = WINDOWS_VERSION::win10_2; + default:if (RtlIsWindowsVersionOrGreater(MmpGlobalDataPtr->NtVersions.MajorVersion, MmpGlobalDataPtr->NtVersions.MinorVersion, 15063))return version = WINDOWS_VERSION::win10_2; break; } break; @@ -406,9 +432,10 @@ WINDOWS_VERSION NTAPI NtWindowsVersion() { default: break; } - return version = invalid; + return version = WINDOWS_VERSION::invalid; } +#ifndef _WIN64 int NTAPI RtlCaptureImageExceptionValues(PVOID BaseAddress, PDWORD SEHandlerTable, PDWORD SEHandlerCount) { PIMAGE_LOAD_CONFIG_DIRECTORY pLoadConfigDirectory; PIMAGE_COR20_HEADER pCor20; @@ -436,3 +463,4 @@ int NTAPI RtlCaptureImageExceptionValues(PVOID BaseAddress, PDWORD SEHandlerTabl *SEHandlerTable = *SEHandlerCount = ((pCor20 && pCor20->Flags & 1) ? -1 : 0); return 0; } +#endif diff --git a/MemoryModule/Utils.h b/MemoryModule/Utils.h index afe375de..96b7c0c5 100644 --- a/MemoryModule/Utils.h +++ b/MemoryModule/Utils.h @@ -28,7 +28,12 @@ NTSTATUS NTAPI RtlFindMemoryBlockFromModuleSection( typedef BOOL(WINAPI* PDLL_STARTUP_ROUTINE)(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved); -bool NTAPI RtlResolveDllNameUnicodeString(IN PCWSTR DllName OPTIONAL, IN PCWSTR DllFullName OPTIONAL, OUT PUNICODE_STRING BaseDllName, OUT PUNICODE_STRING FullDllName); +NTSTATUS NTAPI RtlResolveDllNameUnicodeString( + _In_opt_ PCWSTR DllName, + _In_opt_ PCWSTR DllFullName, + _Out_ PUNICODE_STRING BaseDllName, + _Out_ PUNICODE_STRING FullDllName +); BOOL NTAPI LdrpExecuteTLS(PMEMORYMODULE module); @@ -38,11 +43,6 @@ BOOLEAN NTAPI RtlIsValidImageBuffer(PVOID Buffer, size_t* Size); FARPROC NTAPI RtlGetNtProcAddress(LPCSTR func_name); -VOID NTAPI RtlGetNtVersionNumbersEx( - OUT DWORD* MajorVersion, - OUT DWORD* MinorVersion, - OUT DWORD* BuildNumber); - BOOLEAN NTAPI VirtualAccessCheck(LPCVOID pBuffer, size_t size, ACCESS_MASK protect); BOOLEAN NTAPI VirtualAccessCheckNoException(LPCVOID pBuffer, size_t size, ACCESS_MASK protect); #define ProbeForRead(pBuffer, size) VirtualAccessCheck(pBuffer, size, PAGE_READONLY | PAGE_READWRITE | PAGE_EXECUTE_READ | PAGE_EXECUTE_READWRITE) @@ -72,7 +72,7 @@ bool NTAPI RtlIsWindowsVersionInScope( ); -typedef enum _WINDOWS_VERSION { +typedef enum class _WINDOWS_VERSION { null, xp, vista, @@ -87,4 +87,6 @@ typedef enum _WINDOWS_VERSION { WINDOWS_VERSION NTAPI NtWindowsVersion(); +#ifndef _WIN64 int NTAPI RtlCaptureImageExceptionValues(PVOID BaseAddress, PDWORD SEHandlerTable, PDWORD SEHandlerCount); +#endif diff --git a/MemoryModulePP.sln b/MemoryModulePP.sln index 21ce55a0..0b985a5c 100644 --- a/MemoryModulePP.sln +++ b/MemoryModulePP.sln @@ -19,12 +19,12 @@ Global GlobalSection(ProjectConfigurationPlatforms) = postSolution {5B1F46DB-036E-4A50-AF5F-F5D6584D42C6}.Debug|x64.ActiveCfg = Debug|x64 {5B1F46DB-036E-4A50-AF5F-F5D6584D42C6}.Debug|x64.Build.0 = Debug|x64 - {5B1F46DB-036E-4A50-AF5F-F5D6584D42C6}.Debug|x86.ActiveCfg = DebugDll|Win32 - {5B1F46DB-036E-4A50-AF5F-F5D6584D42C6}.Debug|x86.Build.0 = DebugDll|Win32 + {5B1F46DB-036E-4A50-AF5F-F5D6584D42C6}.Debug|x86.ActiveCfg = Debug|Win32 + {5B1F46DB-036E-4A50-AF5F-F5D6584D42C6}.Debug|x86.Build.0 = Debug|Win32 {5B1F46DB-036E-4A50-AF5F-F5D6584D42C6}.Release|x64.ActiveCfg = Release|x64 {5B1F46DB-036E-4A50-AF5F-F5D6584D42C6}.Release|x64.Build.0 = Release|x64 - {5B1F46DB-036E-4A50-AF5F-F5D6584D42C6}.Release|x86.ActiveCfg = ReleaseDll|Win32 - {5B1F46DB-036E-4A50-AF5F-F5D6584D42C6}.Release|x86.Build.0 = ReleaseDll|Win32 + {5B1F46DB-036E-4A50-AF5F-F5D6584D42C6}.Release|x86.ActiveCfg = Release|Win32 + {5B1F46DB-036E-4A50-AF5F-F5D6584D42C6}.Release|x86.Build.0 = Release|Win32 {5B3131BA-178A-4A28-BD54-315A45C97ED1}.Debug|x64.ActiveCfg = Debug|x64 {5B3131BA-178A-4A28-BD54-315A45C97ED1}.Debug|x64.Build.0 = Debug|x64 {5B3131BA-178A-4A28-BD54-315A45C97ED1}.Debug|x64.Deploy.0 = Debug|x64 diff --git a/a/load.cpp b/a/load.cpp index 5262540d..72babcbe 100644 --- a/a/load.cpp +++ b/a/load.cpp @@ -4,7 +4,8 @@ static PVOID ReadDllFile(LPCSTR FileName) { LPVOID buffer; size_t size; - FILE* f = fopen(FileName, "rb"); + FILE* f; + fopen_s(&f, FileName, "rb"); if (!f)return 0; _fseeki64(f, 0, SEEK_END); if (!(size = _ftelli64(f))) { diff --git a/test/test.cpp b/test/test.cpp index f5a7ac29..701ac74b 100644 --- a/test/test.cpp +++ b/test/test.cpp @@ -1,11 +1,11 @@ #include "../MemoryModule/stdafx.h" #include -#pragma warning(disable:4996) static PVOID ReadDllFile(LPCSTR FileName) { LPVOID buffer; size_t size; - FILE* f = fopen(FileName, "rb"); + FILE* f; + fopen_s(&f, FileName, "rb"); if (!f)return 0; _fseeki64(f, 0, SEEK_END); if (!(size = _ftelli64(f))) { @@ -30,8 +30,8 @@ int test() { 0, // Flags buffer, // Buffer 0, // Reserved - L"a.dll", // DllBaseName - L"C:\\Windows\\System32\\a.dll" // DllFullName + nullptr, // DllBaseName + nullptr // DllFullName ); if (NT_SUCCESS(status) && status != STATUS_IMAGE_MACHINE_TYPE_MISMATCH) { From ff8a663acae27c74a28f05ead7dee261b3162af4 Mon Sep 17 00:00:00 2001 From: Boring <1079299053@qq.com> Date: Mon, 3 Oct 2022 17:25:02 +0800 Subject: [PATCH 7/8] refactoring --- MemoryModule/BaseAddressIndex.cpp | 6 +- MemoryModule/BaseAddressIndex.h | 7 +- MemoryModule/Initialize.cpp | 149 +++++++++++- MemoryModule/InvertedFunctionTable.cpp | 17 +- MemoryModule/InvertedFunctionTable.h | 8 +- MemoryModule/LdrEntry.cpp | 144 ++++++------ MemoryModule/LdrEntry.h | 50 ++-- MemoryModule/LoadDllMemoryApi.cpp | 24 +- MemoryModule/LoadDllMemoryApi.h | 26 ++- MemoryModule/Loader.cpp | 63 ++--- MemoryModule/Loader.h | 41 ++-- MemoryModule/MemoryModule.cpp | 23 +- MemoryModule/MemoryModule.h | 5 +- MemoryModule/MmpGlobalData.h | 23 ++ MemoryModule/MmpTls.cpp | 6 +- MemoryModule/MmpTls.h | 4 +- MemoryModule/Utils.cpp | 309 +++++++++++-------------- MemoryModule/Utils.h | 63 ++--- MemoryModulePP.sln | 8 +- a/load.cpp | 3 +- test/test.cpp | 8 +- 21 files changed, 584 insertions(+), 403 deletions(-) diff --git a/MemoryModule/BaseAddressIndex.cpp b/MemoryModule/BaseAddressIndex.cpp index eacbf897..5b6f1805 100644 --- a/MemoryModule/BaseAddressIndex.cpp +++ b/MemoryModule/BaseAddressIndex.cpp @@ -1,6 +1,8 @@ #include "stdafx.h" -NTSTATUS NTAPI RtlInsertModuleBaseAddressIndexNode(IN PLDR_DATA_TABLE_ENTRY DataTableEntry, IN PVOID BaseAddress) { +NTSTATUS NTAPI RtlInsertModuleBaseAddressIndexNode( + _In_ PLDR_DATA_TABLE_ENTRY DataTableEntry, + _In_ PVOID BaseAddress) { auto LdrpModuleBaseAddressIndex = MmpGlobalDataPtr->MmpBaseAddressIndex.LdrpModuleBaseAddressIndex; if (!LdrpModuleBaseAddressIndex)return STATUS_UNSUCCESSFUL; @@ -32,7 +34,7 @@ NTSTATUS NTAPI RtlInsertModuleBaseAddressIndexNode(IN PLDR_DATA_TABLE_ENTRY Data return STATUS_SUCCESS; } -NTSTATUS NTAPI RtlRemoveModuleBaseAddressIndexNode(IN PLDR_DATA_TABLE_ENTRY DataTableEntry) { +NTSTATUS NTAPI RtlRemoveModuleBaseAddressIndexNode(_In_ PLDR_DATA_TABLE_ENTRY DataTableEntry) { static auto tree{ MmpGlobalDataPtr->MmpBaseAddressIndex.LdrpModuleBaseAddressIndex }; if (!tree->Root)return STATUS_UNSUCCESSFUL; RtlRbRemoveNode(tree, &PLDR_DATA_TABLE_ENTRY_WIN8(DataTableEntry)->BaseAddressIndexNode); diff --git a/MemoryModule/BaseAddressIndex.h b/MemoryModule/BaseAddressIndex.h index c19ff532..f40016f2 100644 --- a/MemoryModule/BaseAddressIndex.h +++ b/MemoryModule/BaseAddressIndex.h @@ -1,5 +1,8 @@ #pragma once -NTSTATUS NTAPI RtlInsertModuleBaseAddressIndexNode(IN PLDR_DATA_TABLE_ENTRY DataTableEntry, IN PVOID BaseAddress); +NTSTATUS NTAPI RtlInsertModuleBaseAddressIndexNode( + _In_ PLDR_DATA_TABLE_ENTRY DataTableEntry, + _In_ PVOID BaseAddress +); -NTSTATUS NTAPI RtlRemoveModuleBaseAddressIndexNode(IN PLDR_DATA_TABLE_ENTRY DataTableEntry); +NTSTATUS NTAPI RtlRemoveModuleBaseAddressIndexNode(_In_ PLDR_DATA_TABLE_ENTRY DataTableEntry); diff --git a/MemoryModule/Initialize.cpp b/MemoryModule/Initialize.cpp index 579d3383..da27d025 100644 --- a/MemoryModule/Initialize.cpp +++ b/MemoryModule/Initialize.cpp @@ -3,16 +3,10 @@ PMMP_GLOBAL_DATA MmpGlobalDataPtr; -#ifdef _WIN64 -#define FindLdrpInvertedFunctionTable FindLdrpInvertedFunctionTable64 -#else -#define FindLdrpInvertedFunctionTable FindLdrpInvertedFunctionTable32 -#endif - BOOLEAN MmpBuildSectionName(_Out_ PUNICODE_STRING SectionName) { WCHAR buffer[128]; - swprintf(buffer, L"\\Sessions\\%d\\BaseNamedObjects\\MMPP*%08X", NtCurrentPeb()->SessionId, (unsigned int)NtCurrentProcessId()); + swprintf_s(buffer, L"\\Sessions\\%d\\BaseNamedObjects\\MMPP*%08X", NtCurrentPeb()->SessionId, (unsigned int)(ULONG_PTR)NtCurrentProcessId()); return RtlCreateUnicodeString(SectionName, buffer); } @@ -51,6 +45,7 @@ static __forceinline bool IsModuleUnloaded(PLDR_DATA_TABLE_ENTRY entry) { } } +#ifndef _WIN64 PVOID FindLdrpInvertedFunctionTable32() { // _RTL_INVERTED_FUNCTION_TABLE x86 // Count +0x0 ???????? @@ -103,6 +98,8 @@ PVOID FindLdrpInvertedFunctionTable32() { return nullptr; } +#define FindLdrpInvertedFunctionTable FindLdrpInvertedFunctionTable32 +#else PVOID FindLdrpInvertedFunctionTable64() { // _RTL_INVERTED_FUNCTION_TABLE x64 // Count +0x0 ???????? @@ -165,6 +162,9 @@ PVOID FindLdrpInvertedFunctionTable64() { return nullptr; } +#define FindLdrpInvertedFunctionTable FindLdrpInvertedFunctionTable64 +#endif + PLIST_ENTRY FindLdrpHashTable() { PLIST_ENTRY list = nullptr; PLIST_ENTRY head = &NtCurrentPeb()->Ldr->InInitializationOrderModuleList, entry = head->Flink; @@ -183,6 +183,94 @@ PLIST_ENTRY FindLdrpHashTable() { return list; } +VOID InitializeWindowsVersion() { + + WINDOWS_VERSION version = WINDOWS_VERSION::invalid; + + switch (MmpGlobalDataPtr->NtVersions.MajorVersion) { + case 5: { + switch (MmpGlobalDataPtr->NtVersions.MinorVersion) { + case 1: + version = MmpGlobalDataPtr->NtVersions.BuildNumber == 2600 ? WINDOWS_VERSION::xp : WINDOWS_VERSION::invalid; + break; + + case 2: + version = MmpGlobalDataPtr->NtVersions.BuildNumber == 3790 ? WINDOWS_VERSION::xp : WINDOWS_VERSION::invalid; + break; + } + break; + } + + case 6: { + switch (MmpGlobalDataPtr->NtVersions.MinorVersion) { + case 0: { + switch (MmpGlobalDataPtr->NtVersions.BuildNumber) { + case 6000: + case 6001: + case 6002: + version = WINDOWS_VERSION::vista; + break; + } + break; + } + + case 1: { + switch (MmpGlobalDataPtr->NtVersions.BuildNumber) { + case 7600: + case 7601: + version = WINDOWS_VERSION::win7; + break; + } + break; + } + + case 2: { + if (MmpGlobalDataPtr->NtVersions.BuildNumber == 9200) version = WINDOWS_VERSION::win8; + break; + } + + case 3: { + if (MmpGlobalDataPtr->NtVersions.BuildNumber == 9600) version = WINDOWS_VERSION::win8_1; + break; + } + + } + break; + } + + case 10: { + if (MmpGlobalDataPtr->NtVersions.MinorVersion)break; + switch (MmpGlobalDataPtr->NtVersions.BuildNumber) { + case 10240: + case 10586: + version = WINDOWS_VERSION::win10; + break; + + case 14393: + version = WINDOWS_VERSION::win10_1; + break; + + case 15063: + case 16299: + case 17134: + case 17763: + case 18362: + version = WINDOWS_VERSION::win10_2; + break; + + default: + if (RtlIsWindowsVersionOrGreater(MmpGlobalDataPtr->NtVersions.MajorVersion, MmpGlobalDataPtr->NtVersions.MinorVersion, 15063)) version = WINDOWS_VERSION::win10_2; + break; + } + + break; + } + + } + + MmpGlobalDataPtr->WindowsVersion = version; +} + NTSTATUS InitializeLockHeld() { NTSTATUS status = STATUS_UNSUCCESSFUL; HANDLE hSection = nullptr; @@ -255,6 +343,53 @@ NTSTATUS InitializeLockHeld() { GetSystemInfo(&MmpGlobalDataPtr->SystemInfo); + RtlGetNtVersionNumbers( + &MmpGlobalDataPtr->NtVersions.MajorVersion, + &MmpGlobalDataPtr->NtVersions.MinorVersion, + &MmpGlobalDataPtr->NtVersions.BuildNumber + ); + if (MmpGlobalDataPtr->NtVersions.BuildNumber & 0xf0000000)MmpGlobalDataPtr->NtVersions.BuildNumber &= 0xffff; + + InitializeWindowsVersion(); + + switch (MmpGlobalDataPtr->WindowsVersion) { + case WINDOWS_VERSION::xp: + MmpGlobalDataPtr->LdrDataTableEntrySize = sizeof(LDR_DATA_TABLE_ENTRY_XP); + break; + + case WINDOWS_VERSION::vista: + MmpGlobalDataPtr->LdrDataTableEntrySize = sizeof(LDR_DATA_TABLE_ENTRY_VISTA); + break; + + case WINDOWS_VERSION::win7: + MmpGlobalDataPtr->LdrDataTableEntrySize = sizeof(LDR_DATA_TABLE_ENTRY_WIN7); + break; + + case WINDOWS_VERSION::win8: + MmpGlobalDataPtr->LdrDataTableEntrySize = sizeof(LDR_DATA_TABLE_ENTRY_WIN8); + break; + + case WINDOWS_VERSION::win8_1: + MmpGlobalDataPtr->LdrDataTableEntrySize = sizeof(LDR_DATA_TABLE_ENTRY_WIN8_1); + break; + + case WINDOWS_VERSION::win10: + MmpGlobalDataPtr->LdrDataTableEntrySize = sizeof(LDR_DATA_TABLE_ENTRY_WIN10); + break; + + case WINDOWS_VERSION::win10_1: + MmpGlobalDataPtr->LdrDataTableEntrySize = sizeof(LDR_DATA_TABLE_ENTRY_WIN10_1); + break; + + case WINDOWS_VERSION::win10_2: + MmpGlobalDataPtr->LdrDataTableEntrySize = sizeof(LDR_DATA_TABLE_ENTRY_WIN10_2); + break; + + default: + MmpGlobalDataPtr->LdrDataTableEntrySize = sizeof(LDR_DATA_TABLE_ENTRY_WIN10_2); + break; + } + MmpGlobalDataPtr->MmpBaseAddressIndex.NtdllLdrEntry = RtlFindLdrTableEntryByBaseName(L"ntdll.dll"); MmpGlobalDataPtr->MmpBaseAddressIndex.LdrpModuleBaseAddressIndex = FindLdrpModuleBaseAddressIndex(); diff --git a/MemoryModule/InvertedFunctionTable.cpp b/MemoryModule/InvertedFunctionTable.cpp index c5f90a9d..572a410c 100644 --- a/MemoryModule/InvertedFunctionTable.cpp +++ b/MemoryModule/InvertedFunctionTable.cpp @@ -1,6 +1,9 @@ #include "stdafx.h" -static VOID NTAPI RtlpInsertInvertedFunctionTable(IN PRTL_INVERTED_FUNCTION_TABLE InvertedTable, IN PVOID ImageBase, IN ULONG SizeOfImage) { +static VOID RtlpInsertInvertedFunctionTable( + _In_ PRTL_INVERTED_FUNCTION_TABLE InvertedTable, + _In_ PVOID ImageBase, + _In_ ULONG SizeOfImage) { #ifdef _WIN64 ULONG CurrentSize; PIMAGE_RUNTIME_FUNCTION_ENTRY FunctionTable; @@ -86,7 +89,9 @@ static VOID NTAPI RtlpInsertInvertedFunctionTable(IN PRTL_INVERTED_FUNCTION_TABL return; } -static VOID NTAPI RtlpRemoveInvertedFunctionTable(IN PRTL_INVERTED_FUNCTION_TABLE InvertedTable, IN PVOID ImageBase) { +static VOID RtlpRemoveInvertedFunctionTable( + _In_ PRTL_INVERTED_FUNCTION_TABLE InvertedTable, + _In_ PVOID ImageBase) { ULONG CurrentSize; ULONG Index; //bool need = RtlIsWindowsVersionOrGreater(6, 2, 0); @@ -136,7 +141,7 @@ static VOID NTAPI RtlpRemoveInvertedFunctionTable(IN PRTL_INVERTED_FUNCTION_TABL return; } -static NTSTATUS NTAPI RtlProtectMrdata(IN SIZE_T Protect) { +static NTSTATUS RtlProtectMrdata(_In_ ULONG Protect) { static PVOID MrdataBase = nullptr; static SIZE_T size = 0; NTSTATUS status; @@ -157,7 +162,9 @@ static NTSTATUS NTAPI RtlProtectMrdata(IN SIZE_T Protect) { return NtProtectVirtualMemory(GetCurrentProcess(), &tmp, &tmp_len, Protect, &old); } -NTSTATUS NTAPI RtlInsertInvertedFunctionTable(IN PVOID BaseAddress, IN size_t ImageSize) { +NTSTATUS NTAPI RtlInsertInvertedFunctionTable( + _In_ PVOID BaseAddress, + _In_ ULONG ImageSize) { auto table = PRTL_INVERTED_FUNCTION_TABLE(MmpGlobalDataPtr->MmpInvertedFunctionTable.LdrpInvertedFunctionTable); if (!table)return STATUS_NOT_SUPPORTED; bool need_virtual_protect = RtlIsWindowsVersionOrGreater(6, 3, 0); @@ -176,7 +183,7 @@ NTSTATUS NTAPI RtlInsertInvertedFunctionTable(IN PVOID BaseAddress, IN size_t Im STATUS_NO_MEMORY : STATUS_SUCCESS; } -NTSTATUS NTAPI RtlRemoveInvertedFunctionTable(IN PVOID ImageBase) { +NTSTATUS NTAPI RtlRemoveInvertedFunctionTable(_In_ PVOID ImageBase) { auto table = PRTL_INVERTED_FUNCTION_TABLE(MmpGlobalDataPtr->MmpInvertedFunctionTable.LdrpInvertedFunctionTable); bool need_virtual_protect = RtlIsWindowsVersionOrGreater(6, 3, 0); NTSTATUS status; diff --git a/MemoryModule/InvertedFunctionTable.h b/MemoryModule/InvertedFunctionTable.h index 979a3e6a..6f8e2291 100644 --- a/MemoryModule/InvertedFunctionTable.h +++ b/MemoryModule/InvertedFunctionTable.h @@ -52,5 +52,9 @@ typedef RTL_INVERTED_FUNCTION_TABLE_WIN7_32 _RTL_INVERTED_FUNCTION_TABLE, RTL_IN typedef _RTL_INVERTED_FUNCTION_TABLE_ENTRY_WIN7_32 _RTL_INVERTED_FUNCTION_TABLE_ENTRY, RTL_INVERTED_FUNCTION_TABLE_ENTRY, * PRTL_INVERTED_FUNCTION_TABLE_ENTRY; #endif -NTSTATUS NTAPI RtlInsertInvertedFunctionTable(IN PVOID BaseAddress, IN size_t ImageSize); -NTSTATUS NTAPI RtlRemoveInvertedFunctionTable(IN PVOID ImageBase); +NTSTATUS NTAPI RtlInsertInvertedFunctionTable( + _In_ PVOID BaseAddress, + _In_ ULONG ImageSize +); + +NTSTATUS NTAPI RtlRemoveInvertedFunctionTable(_In_ PVOID ImageBase); diff --git a/MemoryModule/LdrEntry.cpp b/MemoryModule/LdrEntry.cpp index 867cd22c..d35db8a3 100644 --- a/MemoryModule/LdrEntry.cpp +++ b/MemoryModule/LdrEntry.cpp @@ -1,7 +1,7 @@ #include "stdafx.h" #include -static NTSTATUS NTAPI RtlFreeDependencies(IN PLDR_DATA_TABLE_ENTRY_WIN10 LdrEntry) { +static NTSTATUS RtlFreeDependencies(_In_ PLDR_DATA_TABLE_ENTRY_WIN10 LdrEntry) { _LDR_DDAG_NODE* DependentDdgeNode = nullptr; PLDR_DATA_TABLE_ENTRY_WIN10 ModuleEntry = nullptr; _LDRP_CSLIST* head = (decltype(head))LdrEntry->DdagNode->Dependencies, * entry = head; @@ -81,7 +81,7 @@ static NTSTATUS NTAPI RtlFreeDependencies(IN PLDR_DATA_TABLE_ENTRY_WIN10 LdrEntr return STATUS_SUCCESS; } -PLDR_DATA_TABLE_ENTRY NTAPI RtlAllocateDataTableEntry(IN PVOID BaseAddress) { +PLDR_DATA_TABLE_ENTRY NTAPI RtlAllocateDataTableEntry(_In_ PVOID BaseAddress) { PLDR_DATA_TABLE_ENTRY LdrEntry = nullptr; PIMAGE_NT_HEADERS NtHeader; HANDLE heap = NtCurrentPeb()->ProcessHeap; @@ -89,22 +89,22 @@ PLDR_DATA_TABLE_ENTRY NTAPI RtlAllocateDataTableEntry(IN PVOID BaseAddress) { /* Make sure the header is valid */ if (NtHeader = RtlImageNtHeader(BaseAddress)) { /* Allocate an entry */ - LdrEntry = (PLDR_DATA_TABLE_ENTRY)RtlAllocateHeap(heap, HEAP_ZERO_MEMORY, LdrpDataTableEntrySize()); + LdrEntry = (PLDR_DATA_TABLE_ENTRY)RtlAllocateHeap(heap, HEAP_ZERO_MEMORY, MmpGlobalDataPtr->LdrDataTableEntrySize); } /* Return the entry */ return LdrEntry; } -bool NTAPI RtlInitializeLdrDataTableEntry( - OUT PLDR_DATA_TABLE_ENTRY LdrEntry, - IN DWORD dwFlags, - IN PVOID BaseAddress, - IN UNICODE_STRING& DllBaseName, - IN UNICODE_STRING& DllFullName) { - RtlZeroMemory(LdrEntry, LdrpDataTableEntrySize()); +BOOL NTAPI RtlInitializeLdrDataTableEntry( + _Out_ PLDR_DATA_TABLE_ENTRY LdrEntry, + _In_ DWORD dwFlags, + _In_ PVOID BaseAddress, + _In_ UNICODE_STRING& DllBaseName, + _In_ UNICODE_STRING& DllFullName) { + RtlZeroMemory(LdrEntry, MmpGlobalDataPtr->LdrDataTableEntrySize); PIMAGE_NT_HEADERS headers = RtlImageNtHeader(BaseAddress); - if (!headers)return false; + if (!headers)return FALSE; HANDLE heap = NtCurrentPeb()->ProcessHeap; bool FlagsProcessed = false; @@ -119,24 +119,24 @@ bool NTAPI RtlInitializeLdrDataTableEntry( } } - switch (NtWindowsVersion()) { - case win10: - case win10_1: - case win10_2: { + switch (MmpGlobalDataPtr->WindowsVersion) { + case WINDOWS_VERSION::win10: + case WINDOWS_VERSION::win10_1: + case WINDOWS_VERSION::win10_2: { auto entry = (PLDR_DATA_TABLE_ENTRY_WIN10)LdrEntry; entry->ReferenceCount = 1; } - case win8: - case win8_1: { + case WINDOWS_VERSION::win8: + case WINDOWS_VERSION::win8_1: { auto entry = (PLDR_DATA_TABLE_ENTRY_WIN8)LdrEntry; const static bool IsWin8 = RtlIsWindowsVersionInScope(6, 2, 0, 6, 3, -1); NtQuerySystemTime(&entry->LoadTime); entry->OriginalBase = headers->OptionalHeader.ImageBase; entry->BaseNameHashValue = LdrHashEntry(DllBaseName, false); entry->LoadReason = LoadReasonDynamicLoad; - if (!NT_SUCCESS(RtlInsertModuleBaseAddressIndexNode(LdrEntry, BaseAddress)))return false; + if (!NT_SUCCESS(RtlInsertModuleBaseAddressIndexNode(LdrEntry, BaseAddress)))return FALSE; if (!(entry->DdagNode = (decltype(entry->DdagNode)) - RtlAllocateHeap(heap, HEAP_ZERO_MEMORY, IsWin8 ? sizeof(_LDR_DDAG_NODE_WIN8) : sizeof(_LDR_DDAG_NODE))))return false; + RtlAllocateHeap(heap, HEAP_ZERO_MEMORY, IsWin8 ? sizeof(_LDR_DDAG_NODE_WIN8) : sizeof(_LDR_DDAG_NODE))))return FALSE; //RtlInitializeListEntry(&entry->NodeModuleLink); //RtlInitializeListEntry(&entry->DdagNode->Modules); //RtlInitializeSingleEntry(&entry->DdagNode->CondenseLink); @@ -156,23 +156,23 @@ bool NTAPI RtlInitializeLdrDataTableEntry( FlagsProcessed = true; } - case win7: { - if (LdrpDataTableEntrySize() == sizeof(LDR_DATA_TABLE_ENTRY_WIN7)) { + case WINDOWS_VERSION::win7: { + if (MmpGlobalDataPtr->LdrDataTableEntrySize == sizeof(LDR_DATA_TABLE_ENTRY_WIN7)) { auto entry = (PLDR_DATA_TABLE_ENTRY_WIN7)LdrEntry; entry->OriginalBase = headers->OptionalHeader.ImageBase; NtQuerySystemTime(&entry->LoadTime); } } - case vista: { - if (LdrpDataTableEntrySize() == sizeof(LDR_DATA_TABLE_ENTRY_VISTA) || - LdrpDataTableEntrySize() == sizeof(LDR_DATA_TABLE_ENTRY_WIN7)) { + case WINDOWS_VERSION::vista: { + if (MmpGlobalDataPtr->LdrDataTableEntrySize == sizeof(LDR_DATA_TABLE_ENTRY_VISTA) || + MmpGlobalDataPtr->LdrDataTableEntrySize == sizeof(LDR_DATA_TABLE_ENTRY_WIN7)) { auto entry = (PLDR_DATA_TABLE_ENTRY_VISTA)LdrEntry; - RtlInitializeListEntry(&entry->ForwarderLinks); - RtlInitializeListEntry(&entry->StaticLinks); - RtlInitializeListEntry(&entry->ServiceTagLinks); + InitializeListHead(&entry->ForwarderLinks); + InitializeListHead(&entry->StaticLinks); + InitializeListHead(&entry->ServiceTagLinks); } } - case xp: { + case WINDOWS_VERSION::xp: { LdrEntry->DllBase = BaseAddress; LdrEntry->SizeOfImage = headers->OptionalHeader.SizeOfImage; LdrEntry->TimeDateStamp = headers->FileHeader.TimeDateStamp; @@ -184,30 +184,30 @@ bool NTAPI RtlInitializeLdrDataTableEntry( LdrEntry->Flags = LDRP_IMAGE_DLL | LDRP_ENTRY_INSERTED | LDRP_ENTRY_PROCESSED | LDRP_PROCESS_ATTACH_CALLED; if (CorImage)LdrEntry->Flags |= LDRP_COR_IMAGE; } - RtlInitializeListEntry(&LdrEntry->HashLinks); - return true; + InitializeListHead(&LdrEntry->HashLinks); + return TRUE; } - default:return false; + default:return FALSE; } } -bool NTAPI RtlFreeLdrDataTableEntry(IN PLDR_DATA_TABLE_ENTRY LdrEntry) { +BOOL NTAPI RtlFreeLdrDataTableEntry(_In_ PLDR_DATA_TABLE_ENTRY LdrEntry) { HANDLE heap = NtCurrentPeb()->ProcessHeap; - switch (NtWindowsVersion()) { - case win10: - case win10_1: - case win10_2: - case win8: - case win8_1: { + switch (MmpGlobalDataPtr->WindowsVersion) { + case WINDOWS_VERSION::win10: + case WINDOWS_VERSION::win10_1: + case WINDOWS_VERSION::win10_2: + case WINDOWS_VERSION::win8: + case WINDOWS_VERSION::win8_1: { auto entry = (PLDR_DATA_TABLE_ENTRY_WIN10)LdrEntry; RtlFreeDependencies(entry); RtlFreeHeap(heap, 0, entry->DdagNode); RtlRemoveModuleBaseAddressIndexNode(LdrEntry); } - case win7: - case vista: { - if (LdrpDataTableEntrySize() == sizeof(LDR_DATA_TABLE_ENTRY_VISTA) || - LdrpDataTableEntrySize() == sizeof(LDR_DATA_TABLE_ENTRY_WIN7)) { + case WINDOWS_VERSION::win7: + case WINDOWS_VERSION::vista: { + if (MmpGlobalDataPtr->LdrDataTableEntrySize == sizeof(LDR_DATA_TABLE_ENTRY_VISTA) || + MmpGlobalDataPtr->LdrDataTableEntrySize == sizeof(LDR_DATA_TABLE_ENTRY_WIN7)) { PLDR_DATA_TABLE_ENTRY_VISTA entry = (decltype(entry))LdrEntry; PLIST_ENTRY head = &entry->ForwarderLinks, next = head->Flink; while (head != next) { @@ -218,7 +218,7 @@ bool NTAPI RtlFreeLdrDataTableEntry(IN PLDR_DATA_TABLE_ENTRY LdrEntry) { } } } - case xp: { + case WINDOWS_VERSION::xp: { RtlFreeHeap(heap, 0, LdrEntry->BaseDllName.Buffer); RtlFreeHeap(heap, 0, LdrEntry->FullDllName.Buffer); RemoveEntryList(&LdrEntry->InLoadOrderLinks); @@ -226,13 +226,15 @@ bool NTAPI RtlFreeLdrDataTableEntry(IN PLDR_DATA_TABLE_ENTRY LdrEntry) { RemoveEntryList(&LdrEntry->InInitializationOrderLinks); RemoveEntryList(&LdrEntry->HashLinks); RtlFreeHeap(heap, 0, LdrEntry); - return true; + return TRUE; } - default:return false; + default:return FALSE; } } -NTSTATUS NTAPI RtlUpdateReferenceCount(IN OUT PMEMORYMODULE pModule, IN DWORD Flags) { +NTSTATUS NTAPI RtlUpdateReferenceCount( + _Inout_ PMEMORYMODULE pModule, + _In_ DWORD Flags) { if (Flags != FLAG_REFERENCE && Flags != FLAG_DEREFERENCE)return STATUS_INVALID_PARAMETER_2; if (Flags == FLAG_REFERENCE && pModule->dwReferenceCount != 0xffffffff) @@ -243,14 +245,16 @@ NTSTATUS NTAPI RtlUpdateReferenceCount(IN OUT PMEMORYMODULE pModule, IN DWORD Fl return STATUS_SUCCESS; } -NTSTATUS NTAPI RtlGetReferenceCount(IN PMEMORYMODULE pModule, OUT PULONG Count) { +NTSTATUS NTAPI RtlGetReferenceCount( + _In_ PMEMORYMODULE pModule, + _Out_ PULONG Count) { *Count = pModule->dwReferenceCount; return STATUS_SUCCESS; } -VOID NTAPI RtlInsertMemoryTableEntry(IN PLDR_DATA_TABLE_ENTRY LdrEntry) { +VOID NTAPI RtlInsertMemoryTableEntry(_In_ PLDR_DATA_TABLE_ENTRY LdrEntry) { PPEB_LDR_DATA PebData = NtCurrentPeb()->Ldr; PLIST_ENTRY LdrpHashTable = MmpGlobalDataPtr->MmpLdrEntry.LdrpHashTable; ULONG i; @@ -265,19 +269,28 @@ VOID NTAPI RtlInsertMemoryTableEntry(IN PLDR_DATA_TABLE_ENTRY LdrEntry) { InsertTailList(&PebData->InInitializationOrderModuleList, &LdrEntry->InInitializationOrderLinks); } -VOID NTAPI RtlRbInsertNodeEx(IN PRTL_RB_TREE Tree, IN PRTL_BALANCED_NODE Parent, IN BOOLEAN Right, OUT PRTL_BALANCED_NODE Node) { - decltype(&RtlRbInsertNodeEx)_RtlRbInsertNodeEx = decltype(_RtlRbInsertNodeEx)(RtlGetNtProcAddress("RtlRbInsertNodeEx")); +VOID NTAPI RtlRbInsertNodeEx( + _In_ PRTL_RB_TREE Tree, + _In_ PRTL_BALANCED_NODE Parent, + _In_ BOOLEAN Right, + _Out_ PRTL_BALANCED_NODE Node) { + static decltype(&RtlRbInsertNodeEx)_RtlRbInsertNodeEx = decltype(_RtlRbInsertNodeEx)(RtlGetNtProcAddress("RtlRbInsertNodeEx")); + + RtlZeroMemory(Node, sizeof(*Node)); + if (!_RtlRbInsertNodeEx)return; return _RtlRbInsertNodeEx(Tree, Parent, Right, Node); } -VOID NTAPI RtlRbRemoveNode(IN PRTL_RB_TREE Tree, IN PRTL_BALANCED_NODE Node) { - decltype(&RtlRbRemoveNode)_RtlRbRemoveNode = decltype(_RtlRbRemoveNode)(RtlGetNtProcAddress("RtlRbRemoveNode")); +VOID NTAPI RtlRbRemoveNode( + _In_ PRTL_RB_TREE Tree, + _In_ PRTL_BALANCED_NODE Node) { + static decltype(&RtlRbRemoveNode)_RtlRbRemoveNode = decltype(_RtlRbRemoveNode)(RtlGetNtProcAddress("RtlRbRemoveNode")); if (!_RtlRbRemoveNode)return; return _RtlRbRemoveNode(Tree, Node); } -PLDR_DATA_TABLE_ENTRY NTAPI RtlFindLdrTableEntryByHandle(PVOID BaseAddress) { +PLDR_DATA_TABLE_ENTRY NTAPI RtlFindLdrTableEntryByHandle(_In_ PVOID BaseAddress) { PLIST_ENTRY ListHead = &NtCurrentPeb()->Ldr->InLoadOrderModuleList, ListEntry = ListHead->Flink; PLDR_DATA_TABLE_ENTRY CurEntry; while (ListEntry != ListHead) { @@ -290,21 +303,21 @@ PLDR_DATA_TABLE_ENTRY NTAPI RtlFindLdrTableEntryByHandle(PVOID BaseAddress) { return nullptr; } -PLDR_DATA_TABLE_ENTRY NTAPI RtlFindLdrTableEntryByBaseName(PCWSTR BaseName) { +PLDR_DATA_TABLE_ENTRY NTAPI RtlFindLdrTableEntryByBaseName(_In_z_ PCWSTR BaseName) { PLIST_ENTRY ListHead = &NtCurrentPeb()->Ldr->InLoadOrderModuleList, ListEntry = ListHead->Flink; PLDR_DATA_TABLE_ENTRY CurEntry; while (ListEntry != ListHead) { CurEntry = CONTAINING_RECORD(ListEntry, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks); ListEntry = ListEntry->Flink; - if (!wcsnicmp(BaseName, CurEntry->BaseDllName.Buffer, (CurEntry->BaseDllName.Length / sizeof(wchar_t)) - 4) || - !wcsnicmp(BaseName, CurEntry->BaseDllName.Buffer, CurEntry->BaseDllName.Length / sizeof(wchar_t))) { + if (!_wcsnicmp(BaseName, CurEntry->BaseDllName.Buffer, (CurEntry->BaseDllName.Length / sizeof(wchar_t)) - 4) || + !_wcsnicmp(BaseName, CurEntry->BaseDllName.Buffer, CurEntry->BaseDllName.Length / sizeof(wchar_t))) { return CurEntry; } } return nullptr; } -ULONG NTAPI LdrHashEntry(IN UNICODE_STRING& str, IN bool _xor) { +ULONG NTAPI LdrHashEntry(_In_ UNICODE_STRING& str, _In_ BOOL _xor) { ULONG result = 0; if (RtlIsWindowsVersionOrGreater(6, 2, 0)) { RtlHashUnicodeString(&str, TRUE, HASH_STRING_ALGORITHM_DEFAULT, &result); @@ -316,20 +329,3 @@ ULONG NTAPI LdrHashEntry(IN UNICODE_STRING& str, IN bool _xor) { if (_xor)result &= (LDR_HASH_TABLE_ENTRIES - 1); return result; } - -size_t NTAPI LdrpDataTableEntrySize() { - static size_t size = 0; - if (size)return size; - - switch (NtWindowsVersion()) { - case xp:return size = sizeof(LDR_DATA_TABLE_ENTRY_XP); - case vista:return size = sizeof(LDR_DATA_TABLE_ENTRY_VISTA); - case win7:return size = sizeof(LDR_DATA_TABLE_ENTRY_WIN7); - case win8:return size = sizeof(LDR_DATA_TABLE_ENTRY_WIN8); - case win8_1:return size = sizeof(LDR_DATA_TABLE_ENTRY_WIN8_1); - case win10:return size = sizeof(LDR_DATA_TABLE_ENTRY_WIN10); - case win10_1:return size = sizeof(LDR_DATA_TABLE_ENTRY_WIN10_1); - case win10_2:return size = sizeof(LDR_DATA_TABLE_ENTRY_WIN10_2); - default:return size = sizeof(LDR_DATA_TABLE_ENTRY_WIN10_2); - } -} diff --git a/MemoryModule/LdrEntry.h b/MemoryModule/LdrEntry.h index fb6ec014..bd760faf 100644 --- a/MemoryModule/LdrEntry.h +++ b/MemoryModule/LdrEntry.h @@ -3,21 +3,33 @@ #define FLAG_REFERENCE 0 #define FLAG_DEREFERENCE 1 -PLDR_DATA_TABLE_ENTRY NTAPI RtlAllocateDataTableEntry(IN PVOID BaseAddress); +PLDR_DATA_TABLE_ENTRY NTAPI RtlAllocateDataTableEntry(_In_ PVOID BaseAddress); -bool NTAPI RtlInitializeLdrDataTableEntry(OUT PLDR_DATA_TABLE_ENTRY LdrEntry, IN DWORD dwFlags, IN PVOID BaseAddress, IN UNICODE_STRING& DllBaseName, IN UNICODE_STRING& DllFullName); +BOOL NTAPI RtlInitializeLdrDataTableEntry( + _Out_ PLDR_DATA_TABLE_ENTRY LdrEntry, + _In_ DWORD dwFlags, + _In_ PVOID BaseAddress, + _In_ UNICODE_STRING& DllBaseName, + _In_ UNICODE_STRING& DllFullName +); -bool NTAPI RtlFreeLdrDataTableEntry(IN PLDR_DATA_TABLE_ENTRY LdrEntry); +BOOL NTAPI RtlFreeLdrDataTableEntry(_In_ PLDR_DATA_TABLE_ENTRY LdrEntry); -NTSTATUS NTAPI RtlUpdateReferenceCount(IN OUT PMEMORYMODULE pModule, IN DWORD Flags); +NTSTATUS NTAPI RtlUpdateReferenceCount( + _Inout_ PMEMORYMODULE pModule, + _In_ DWORD Flags +); -NTSTATUS NTAPI RtlGetReferenceCount(IN PMEMORYMODULE pModule, OUT PULONG Count); +NTSTATUS NTAPI RtlGetReferenceCount( + _In_ PMEMORYMODULE pModule, + _Out_ PULONG Count +); -VOID NTAPI RtlInsertMemoryTableEntry(IN PLDR_DATA_TABLE_ENTRY LdrEntry); +VOID NTAPI RtlInsertMemoryTableEntry(_In_ PLDR_DATA_TABLE_ENTRY LdrEntry); -PLDR_DATA_TABLE_ENTRY NTAPI RtlFindLdrTableEntryByHandle(PVOID BaseAddress); +PLDR_DATA_TABLE_ENTRY NTAPI RtlFindLdrTableEntryByHandle(_In_ PVOID BaseAddress); -PLDR_DATA_TABLE_ENTRY NTAPI RtlFindLdrTableEntryByBaseName(PCWSTR BaseName); +PLDR_DATA_TABLE_ENTRY NTAPI RtlFindLdrTableEntryByBaseName(_In_z_ PCWSTR BaseName); // // Loader Data Table Entry Flags @@ -50,10 +62,17 @@ PLDR_DATA_TABLE_ENTRY NTAPI RtlFindLdrTableEntryByBaseName(PCWSTR BaseName); #define LDR_GET_HASH_ENTRY(x) (RtlUpcaseUnicodeChar((x)) & (LDR_HASH_TABLE_ENTRIES - 1)) #define LDR_HASH_TABLE_ENTRIES 32 -// RtlRbInsertNodeEx -VOID NTAPI RtlRbInsertNodeEx(IN PRTL_RB_TREE Tree, IN PRTL_BALANCED_NODE Parent, IN BOOLEAN Right, OUT PRTL_BALANCED_NODE Node); -// RtlRbRemoveNode -VOID NTAPI RtlRbRemoveNode(IN PRTL_RB_TREE Tree, IN PRTL_BALANCED_NODE Node); +VOID NTAPI RtlRbInsertNodeEx( + _In_ PRTL_RB_TREE Tree, + _In_ PRTL_BALANCED_NODE Parent, + _In_ BOOLEAN Right, + _Out_ PRTL_BALANCED_NODE Node +); + +VOID NTAPI RtlRbRemoveNode( + _In_ PRTL_RB_TREE Tree, + _In_ PRTL_BALANCED_NODE Node +); struct _LDR_DDAG_NODE_WIN8 { _LIST_ENTRY Modules; //0x0 @@ -326,9 +345,4 @@ typedef struct _LDR_DATA_TABLE_ENTRY_WIN10_2 { UCHAR SigningLevel; //0x11c }LDR_DATA_TABLE_ENTRY_WIN10_2, * PLDR_DATA_TABLE_ENTRY_WIN10_2; -ULONG NTAPI LdrHashEntry(IN UNICODE_STRING& str, IN bool _xor = true); - -#define RtlInitializeListEntry(entry) ((entry)->Blink = (entry)->Flink = (entry)) -#define RtlInitializeSingleEntry(entry) ((entry->Next = (entry))) - -size_t NTAPI LdrpDataTableEntrySize(); +ULONG NTAPI LdrHashEntry(_In_ UNICODE_STRING& str, _In_ BOOL _xor = TRUE); diff --git a/MemoryModule/LoadDllMemoryApi.cpp b/MemoryModule/LoadDllMemoryApi.cpp index 321d2fde..1d06a959 100644 --- a/MemoryModule/LoadDllMemoryApi.cpp +++ b/MemoryModule/LoadDllMemoryApi.cpp @@ -1,33 +1,43 @@ #include "stdafx.h" -HMEMORYMODULE WINAPI LoadLibraryMemory(PVOID BufferAddress) { +HMEMORYMODULE WINAPI LoadLibraryMemory(_In_ PVOID BufferAddress) { HMEMORYMODULE hMemoryModule = nullptr; NTSTATUS status = LdrLoadDllMemory(&hMemoryModule, BufferAddress, 0); - if (!NT_SUCCESS(status)) { + if (!NT_SUCCESS(status) || status == STATUS_IMAGE_MACHINE_TYPE_MISMATCH) { SetLastError(RtlNtStatusToDosError(status)); } return hMemoryModule; } -HMEMORYMODULE WINAPI LoadLibraryMemoryExA(PVOID BufferAddress, size_t Reserved, LPCSTR DllBaseName, LPCSTR DllFullName, DWORD Flags) { +HMEMORYMODULE WINAPI LoadLibraryMemoryExA( + _In_ PVOID BufferAddress, + _In_ size_t Reserved, + _In_opt_ LPCSTR DllBaseName, + _In_opt_ LPCSTR DllFullName, + _In_ DWORD Flags) { HMEMORYMODULE hMemoryModule = nullptr; NTSTATUS status = LdrLoadDllMemoryExA(&hMemoryModule, nullptr, Flags, BufferAddress, Reserved, DllBaseName, DllFullName); - if (!NT_SUCCESS(status)) { + if (!NT_SUCCESS(status) || status == STATUS_IMAGE_MACHINE_TYPE_MISMATCH) { SetLastError(RtlNtStatusToDosError(status)); } return hMemoryModule; } -HMEMORYMODULE WINAPI LoadLibraryMemoryExW(PVOID BufferAddress, size_t Reserved, LPCWSTR DllBaseName, LPCWSTR DllFullName, DWORD Flags) { +HMEMORYMODULE WINAPI LoadLibraryMemoryExW( + _In_ PVOID BufferAddress, + _In_ size_t Reserved, + _In_opt_ LPCWSTR DllBaseName, + _In_opt_ LPCWSTR DllFullName, + _In_ DWORD Flags) { HMEMORYMODULE hMemoryModule = nullptr; NTSTATUS status = LdrLoadDllMemoryExW(&hMemoryModule, nullptr, Flags, BufferAddress, Reserved, DllBaseName, DllFullName); - if (!NT_SUCCESS(status)) { + if (!NT_SUCCESS(status) || status == STATUS_IMAGE_MACHINE_TYPE_MISMATCH) { SetLastError(RtlNtStatusToDosError(status)); } return hMemoryModule; } -BOOL WINAPI FreeLibraryMemory(HMEMORYMODULE hMemoryModule) { +BOOL WINAPI FreeLibraryMemory(_In_ HMEMORYMODULE hMemoryModule) { NTSTATUS status = LdrUnloadDllMemory(hMemoryModule); if (!NT_SUCCESS(status)) { SetLastError(RtlNtStatusToDosError(status)); diff --git a/MemoryModule/LoadDllMemoryApi.h b/MemoryModule/LoadDllMemoryApi.h index 2c962474..54d8368a 100644 --- a/MemoryModule/LoadDllMemoryApi.h +++ b/MemoryModule/LoadDllMemoryApi.h @@ -10,13 +10,25 @@ typedef HMODULE HMEMORYMODULE; #define NT_SUCCESS(Status) (((NTSTATUS)(Status)) >= 0) #endif -HMEMORYMODULE WINAPI LoadLibraryMemory(PVOID BufferAddress); - -HMEMORYMODULE WINAPI LoadLibraryMemoryExA(PVOID BufferAddress, size_t Reserved, LPCSTR DllBaseName, LPCSTR DllFullName, DWORD Flags); - -HMEMORYMODULE WINAPI LoadLibraryMemoryExW(PVOID BufferAddress, size_t Reserved, LPCWSTR DllBaseName, LPCWSTR DllFullName, DWORD Flags); - -BOOL WINAPI FreeLibraryMemory(HMEMORYMODULE hMemoryModule); +HMEMORYMODULE WINAPI LoadLibraryMemory(_In_ PVOID BufferAddress); + +HMEMORYMODULE WINAPI LoadLibraryMemoryExA( + _In_ PVOID BufferAddress, + _In_ size_t Reserved, + _In_opt_ LPCSTR DllBaseName, + _In_opt_ LPCSTR DllFullName, + _In_ DWORD Flags +); + +HMEMORYMODULE WINAPI LoadLibraryMemoryExW( + _In_ PVOID BufferAddress, + _In_ size_t Reserved, + _In_opt_ LPCWSTR DllBaseName, + _In_opt_ LPCWSTR DllFullName, + _In_ DWORD Flags +); + +BOOL WINAPI FreeLibraryMemory(_In_ HMEMORYMODULE hMemoryModule); #define NtLoadDllMemory LdrLoadDllMemory #define NtLoadDllMemoryExA LdrLoadDllMemoryExA diff --git a/MemoryModule/Loader.cpp b/MemoryModule/Loader.cpp index 5dbf8360..eb95b899 100644 --- a/MemoryModule/Loader.cpp +++ b/MemoryModule/Loader.cpp @@ -1,8 +1,12 @@ #include "stdafx.h" #include -static NTSTATUS NTAPI LdrMapDllMemory(IN HMEMORYMODULE ViewBase, IN DWORD dwFlags, IN PCWSTR DllName OPTIONAL, - IN PCWSTR lpFullDllName OPTIONAL, OUT PLDR_DATA_TABLE_ENTRY* DataTableEntry OPTIONAL) { +static NTSTATUS NTAPI LdrMapDllMemory( + _In_ HMEMORYMODULE ViewBase, + _In_ DWORD dwFlags, + _In_opt_ PCWSTR DllName, + _In_opt_ PCWSTR lpFullDllName, + _Out_opt_ PLDR_DATA_TABLE_ENTRY* DataTableEntry) { UNICODE_STRING FullDllName, BaseDllName; PIMAGE_NT_HEADERS NtHeaders; @@ -13,7 +17,7 @@ static NTSTATUS NTAPI LdrMapDllMemory(IN HMEMORYMODULE ViewBase, IN DWORD dwFlag if (!(LdrEntry = RtlAllocateDataTableEntry(ViewBase))) return STATUS_NO_MEMORY; - if (!RtlResolveDllNameUnicodeString(DllName, lpFullDllName, &BaseDllName, &FullDllName)) { + if (!NT_SUCCESS(RtlResolveDllNameUnicodeString(DllName, lpFullDllName, &BaseDllName, &FullDllName))) { RtlFreeHeap(heap, 0, LdrEntry); return STATUS_NO_MEMORY; } @@ -30,18 +34,21 @@ static NTSTATUS NTAPI LdrMapDllMemory(IN HMEMORYMODULE ViewBase, IN DWORD dwFlag return STATUS_SUCCESS; } -NTSTATUS NTAPI LdrLoadDllMemory(OUT HMEMORYMODULE* BaseAddress, IN LPVOID BufferAddress, IN size_t BufferSize) { - return LdrLoadDllMemoryExW(BaseAddress, nullptr, LOAD_FLAGS_NOT_FAIL_IF_HANDLE_TLS, BufferAddress, BufferSize, nullptr, nullptr); +NTSTATUS NTAPI LdrLoadDllMemory( + _Out_ HMEMORYMODULE* BaseAddress, + _In_ LPVOID BufferAddress, + _In_ size_t Reserved) { + return LdrLoadDllMemoryExW(BaseAddress, nullptr, 0, BufferAddress, Reserved, nullptr, nullptr); } NTSTATUS NTAPI LdrLoadDllMemoryExW( - OUT HMEMORYMODULE* BaseAddress, - OUT PVOID* LdrEntry OPTIONAL, - IN DWORD dwFlags, - IN LPVOID BufferAddress, - IN size_t BufferSize, - IN LPCWSTR DllName OPTIONAL, - IN LPCWSTR DllFullName OPTIONAL) { + _Out_ HMEMORYMODULE* BaseAddress, + _Out_opt_ PVOID* LdrEntry, + _In_ DWORD dwFlags, + _In_ LPVOID BufferAddress, + _In_ size_t BufferSize, + _In_opt_ LPCWSTR DllName, + _In_opt_ LPCWSTR DllFullName) { PMEMORYMODULE module = nullptr; NTSTATUS status = STATUS_SUCCESS; PLDR_DATA_TABLE_ENTRY ModuleEntry = nullptr; @@ -76,8 +83,8 @@ NTSTATUS NTAPI LdrLoadDllMemoryExW( /* Check if it's being unloaded */ if (!CurEntry->InMemoryOrderLinks.Flink) continue; /* Check if name matches */ - if (!wcsnicmp(DllName, CurEntry->BaseDllName.Buffer, (CurEntry->BaseDllName.Length / sizeof(wchar_t)) - 4) || - !wcsnicmp(DllName, CurEntry->BaseDllName.Buffer, CurEntry->BaseDllName.Length / sizeof(wchar_t))) { + if (!_wcsnicmp(DllName, CurEntry->BaseDllName.Buffer, (CurEntry->BaseDllName.Length / sizeof(wchar_t)) - 4) || + !_wcsnicmp(DllName, CurEntry->BaseDllName.Buffer, CurEntry->BaseDllName.Length / sizeof(wchar_t))) { /* Let's compare their headers */ if (!(h2 = RtlImageNtHeader(CurEntry->DllBase)))continue; if (!(module = MapMemoryModuleHandle((HMEMORYMODULE)CurEntry->DllBase)))continue; @@ -94,7 +101,7 @@ NTSTATUS NTAPI LdrLoadDllMemoryExW( } } - status = MemoryLoadLibrary(BaseAddress, BufferAddress, BufferSize); + status = MemoryLoadLibrary(BaseAddress, BufferAddress, (DWORD)BufferSize); if (!NT_SUCCESS(status) || status == STATUS_IMAGE_MACHINE_TYPE_MISMATCH)return status; if (!(module = MapMemoryModuleHandle(*BaseAddress))) { @@ -191,33 +198,33 @@ NTSTATUS NTAPI LdrLoadDllMemoryExW( } NTSTATUS NTAPI LdrLoadDllMemoryExA( - OUT HMEMORYMODULE* BaseAddress, - OUT PVOID* LdrEntry OPTIONAL, - IN DWORD dwFlags, - IN LPVOID BufferAddress, - IN size_t BufferSize, - IN LPCSTR DllName OPTIONAL, - IN LPCSTR DllFullName OPTIONAL){ + _Out_ HMEMORYMODULE* BaseAddress, + _Out_opt_ PVOID* LdrEntry, + _In_ DWORD dwFlags, + _In_ LPVOID BufferAddress, + _In_ size_t BufferSize, + _In_opt_ LPCSTR DllName, + _In_opt_ LPCSTR DllFullName) { LPWSTR _DllName = nullptr, _DllFullName = nullptr; size_t size; NTSTATUS status; if (DllName) { size = strlen(DllName) + 1; _DllName = new wchar_t[size]; - mbstowcs(_DllName, DllName, size); + mbstowcs_s(nullptr, _DllName, size, DllName, size); } if (DllFullName) { size = strlen(DllFullName) + 1; _DllFullName = new wchar_t[size]; - mbstowcs(_DllFullName, DllFullName, size); + mbstowcs_s(nullptr, _DllFullName, size, DllFullName, size); } status = LdrLoadDllMemoryExW(BaseAddress, LdrEntry, dwFlags, BufferAddress, BufferSize, _DllName, _DllFullName); - if (_DllName)delete[]_DllName; - if (_DllFullName)delete[]_DllFullName; + delete[]_DllName; + delete[]_DllFullName; return status; } -NTSTATUS NTAPI LdrUnloadDllMemory(IN HMEMORYMODULE BaseAddress) { +NTSTATUS NTAPI LdrUnloadDllMemory(_In_ HMEMORYMODULE BaseAddress) { __try { ProbeForRead(BaseAddress, sizeof(size_t)); } @@ -280,7 +287,7 @@ NTSTATUS NTAPI LdrUnloadDllMemory(IN HMEMORYMODULE BaseAddress) { } __declspec(noreturn) -VOID NTAPI LdrUnloadDllMemoryAndExitThread(IN HMEMORYMODULE BaseAddress, IN DWORD dwExitCode) { +VOID NTAPI LdrUnloadDllMemoryAndExitThread(_In_ HMEMORYMODULE BaseAddress, _In_ DWORD dwExitCode) { LdrUnloadDllMemory(BaseAddress); RtlExitUserThread(dwExitCode); } diff --git a/MemoryModule/Loader.h b/MemoryModule/Loader.h index 9217b124..2819b3ee 100644 --- a/MemoryModule/Loader.h +++ b/MemoryModule/Loader.h @@ -2,9 +2,9 @@ //Load dll from the provided buffer. NTSTATUS NTAPI LdrLoadDllMemory( - OUT HMEMORYMODULE* BaseAddress, // Output module base address - IN LPVOID BufferAddress, // Pointer to the dll file data buffer - IN size_t Reserved // Reserved parameter, must be 0 + _Out_ HMEMORYMODULE* BaseAddress, // Output module base address + _In_ LPVOID BufferAddress, // Pointer to the dll file data buffer + _In_ size_t Reserved // Reserved parameter, must be 0 ); #define MEMORY_FEATURE_SUPPORT_VERSION 0x00000001 @@ -56,27 +56,27 @@ NTSTATUS NTAPI LdrQuerySystemMemoryModuleFeatures(_Out_ PDWORD pFeatures); NTSTATUS NTAPI LdrLoadDllMemoryExW( - OUT HMEMORYMODULE* BaseAddress, // Output module base address - OUT PVOID* LdrEntry OPTIONAL, // Receive a pointer to the LDR node of the module - IN DWORD dwFlags, // Flags - IN LPVOID BufferAddress, // Pointer to the dll file data buffer - IN size_t Reserved, // Reserved parameter, must be 0 - IN LPCWSTR DllName OPTIONAL, // Module file name - IN LPCWSTR DllFullName OPTIONAL // Module file full path + _Out_ HMEMORYMODULE* BaseAddress, // Output module base address + _Out_opt_ PVOID* LdrEntry, // Receive a pointer to the LDR node of the module + _In_ DWORD dwFlags, // Flags + _In_ LPVOID BufferAddress, // Pointer to the dll file data buffer + _In_ size_t Reserved, // Reserved parameter, must be 0 + _In_opt_ LPCWSTR DllName, // Module file name + _In_opt_ LPCWSTR DllFullName // Module file full path ); NTSTATUS NTAPI LdrLoadDllMemoryExA( - OUT HMEMORYMODULE* BaseAddress, - OUT PVOID* LdrEntry OPTIONAL, - IN DWORD dwFlags, - IN LPVOID BufferAddress, - IN size_t Reserved, - IN LPCSTR DllName OPTIONAL, - IN LPCSTR DllFullName OPTIONAL + _Out_ HMEMORYMODULE* BaseAddress, + _Out_opt_ PVOID* LdrEntry, + _In_ DWORD dwFlags, + _In_ LPVOID BufferAddress, + _In_ size_t Reserved, + _In_opt_ LPCSTR DllName, + _In_opt_ LPCSTR DllFullName ); //Unload modules previously loaded from memory -NTSTATUS NTAPI LdrUnloadDllMemory(IN HMEMORYMODULE BaseAddress); +NTSTATUS NTAPI LdrUnloadDllMemory(_In_ HMEMORYMODULE BaseAddress); #ifndef _USRDLL #ifdef _WIN64 @@ -89,5 +89,8 @@ NTSTATUS NTAPI LdrUnloadDllMemory(IN HMEMORYMODULE BaseAddress); #endif extern "C" { - __declspec(noreturn) VOID NTAPI LdrUnloadDllMemoryAndExitThread(IN HMEMORYMODULE BaseAddress, IN DWORD dwExitCode); + __declspec(noreturn) VOID NTAPI LdrUnloadDllMemoryAndExitThread( + _In_ HMEMORYMODULE BaseAddress, + _In_ DWORD dwExitCode + ); } diff --git a/MemoryModule/MemoryModule.cpp b/MemoryModule/MemoryModule.cpp index 6c1731fe..54740699 100644 --- a/MemoryModule/MemoryModule.cpp +++ b/MemoryModule/MemoryModule.cpp @@ -51,7 +51,7 @@ PMEMORYMODULE WINAPI MapMemoryModuleHandle(HMEMORYMODULE hModule) { return pModule; } -bool WINAPI IsValidMemoryModuleHandle(HMEMORYMODULE hModule) { +BOOL WINAPI IsValidMemoryModuleHandle(HMEMORYMODULE hModule) { return MapMemoryModuleHandle(hModule) != nullptr; } @@ -81,16 +81,12 @@ NTSTATUS MemoryResolveImportTable( } if (importDesc && count) { - if (!(hMemoryModule->hModulesList = new HMODULE[count])) { + hMemoryModule->hModulesList = (HMODULE*)RtlAllocateHeap(NtCurrentPeb()->ProcessHeap, HEAP_ZERO_MEMORY, sizeof(HMODULE) * count); + if (!hMemoryModule->hModulesList) { status = STATUS_NO_MEMORY; break; } - RtlZeroMemory( - hMemoryModule->hModulesList, - sizeof(HMODULE) * count - ); - for (DWORD i = 0; i < count; ++i, ++importDesc) { uintptr_t* thunkRef; FARPROC* funcRef; @@ -131,7 +127,7 @@ NTSTATUS MemoryResolveImportTable( for (DWORD i = 0; i < hMemoryModule->dwModulesCount; ++i) FreeLibrary(hMemoryModule->hModulesList[i]); - delete[]hMemoryModule->hModulesList; + RtlFreeHeap(NtCurrentPeb()->ProcessHeap, 0, hMemoryModule->hModulesList); hMemoryModule->hModulesList = nullptr; hMemoryModule->dwModulesCount = 0; } @@ -406,21 +402,22 @@ NTSTATUS MemoryLoadLibrary( return status; } -bool MemoryFreeLibrary(HMEMORYMODULE mod) { +BOOL MemoryFreeLibrary(HMEMORYMODULE mod) { PMEMORYMODULE module = MapMemoryModuleHandle(mod); PIMAGE_NT_HEADERS headers = RtlImageNtHeader(mod); - if (!module) return false; - if (module->loadFromNtLoadDllMemory && !module->underUnload)return false; + if (!module) return FALSE; + if (module->loadFromNtLoadDllMemory && !module->underUnload)return FALSE; if (module->hModulesList) { for (DWORD i = 0; i < module->dwModulesCount; ++i) { if (module->hModulesList[i]) { FreeLibrary(module->hModulesList[i]); } } - delete[] module->hModulesList; + + RtlFreeHeap(NtCurrentPeb()->ProcessHeap, 0, module->hModulesList); } if (module->codeBase) VirtualFree(mod, 0, MEM_RELEASE); - return true; + return TRUE; } diff --git a/MemoryModule/MemoryModule.h b/MemoryModule/MemoryModule.h index b0b14ec9..db1bf2e0 100644 --- a/MemoryModule/MemoryModule.h +++ b/MemoryModule/MemoryModule.h @@ -1,5 +1,4 @@ #pragma once -#pragma warning(disable:4996) #ifndef __MEMORY_MODULE_HEADER #define __MEMORY_MODULE_HEADER @@ -81,9 +80,9 @@ extern "C" { _In_ PIMAGE_NT_HEADERS lpNtHeaders ); - bool MemoryFreeLibrary(HMEMORYMODULE); + BOOL MemoryFreeLibrary(HMEMORYMODULE); - bool WINAPI IsValidMemoryModuleHandle(HMEMORYMODULE hModule); + BOOL WINAPI IsValidMemoryModuleHandle(HMEMORYMODULE hModule); PMEMORYMODULE WINAPI MapMemoryModuleHandle(HMEMORYMODULE hModule); diff --git a/MemoryModule/MmpGlobalData.h b/MemoryModule/MmpGlobalData.h index d672a7f7..42d8b083 100644 --- a/MemoryModule/MmpGlobalData.h +++ b/MemoryModule/MmpGlobalData.h @@ -59,6 +59,19 @@ typedef struct _MMP_DOT_NET_DATA { }Hooks; }MMP_DOT_NET_DATA, * PMMP_DOT_NET_DATA; +typedef enum class _WINDOWS_VERSION :BYTE { + null, + xp, + vista, + win7, + win8, + win8_1, + win10, + win10_1, + win10_2, + invalid +}WINDOWS_VERSION; + typedef struct _MMP_GLOBAL_DATA { WORD MajorVersion; @@ -66,6 +79,16 @@ typedef struct _MMP_GLOBAL_DATA { DWORD MmpFeatures; + struct { + DWORD MajorVersion; + DWORD MinorVersion; + DWORD BuildNumber; + }NtVersions; + + WINDOWS_VERSION WindowsVersion; + + WORD LdrDataTableEntrySize; + SYSTEM_INFO SystemInfo; MMP_BASE_ADDRESS_INDEX_DATA MmpBaseAddressIndex; diff --git a/MemoryModule/MmpTls.cpp b/MemoryModule/MmpTls.cpp index 78876354..61842d0b 100644 --- a/MemoryModule/MmpTls.cpp +++ b/MemoryModule/MmpTls.cpp @@ -513,7 +513,7 @@ NTSTATUS NTAPI HookNtSetInformationProcess( } Tls->OperationType = ProcessTlsReplaceIndex; - for (auto i = 0; i < Tls->ThreadDataCount; ++i) { + for (ULONG i = 0; i < Tls->ThreadDataCount; ++i) { Tls->ThreadData[i].TlsModulePointer = Tls->ThreadData[i].TlsVector[ProcessTlsInformation->TlsVectorLength]; } } @@ -543,7 +543,7 @@ NTSTATUS NTAPI HookNtSetInformationProcess( // Modify our mapping // EnterCriticalSection(&MmpGlobalDataPtr->MmpTls.MmpTlspLock); - for (auto i = 0; i < Tls->ThreadDataCount; ++i) { + for (ULONG i = 0; i < Tls->ThreadDataCount; ++i) { bool found = false; PLIST_ENTRY entry = MmpGlobalDataPtr->MmpTls.MmpThreadLocalStoragePointer.Flink; @@ -769,7 +769,7 @@ NTSTATUS NTAPI MmpHandleTlsData(_In_ PLDR_DATA_TABLE_ENTRY lpModuleEntry) { nullptr, // hack PROCESSINFOCLASS::ProcessTlsInformation, ProcessTlsInformation, - Length + (ULONG)Length ); for (DWORD i = 0; i < ProcessTlsInformation->ThreadDataCount; ++i) { diff --git a/MemoryModule/MmpTls.h b/MemoryModule/MmpTls.h index ebcc64a4..33de5c9c 100644 --- a/MemoryModule/MmpTls.h +++ b/MemoryModule/MmpTls.h @@ -2,6 +2,6 @@ BOOL NTAPI MmpTlsInitialize(); -NTSTATUS NTAPI MmpReleaseTlsEntry(PLDR_DATA_TABLE_ENTRY lpModuleEntry); +NTSTATUS NTAPI MmpReleaseTlsEntry(_In_ PLDR_DATA_TABLE_ENTRY lpModuleEntry); -NTSTATUS NTAPI MmpHandleTlsData(PLDR_DATA_TABLE_ENTRY lpModuleEntry); +NTSTATUS NTAPI MmpHandleTlsData(_In_ PLDR_DATA_TABLE_ENTRY lpModuleEntry); diff --git a/MemoryModule/Utils.cpp b/MemoryModule/Utils.cpp index 3fe4e270..aa584706 100644 --- a/MemoryModule/Utils.cpp +++ b/MemoryModule/Utils.cpp @@ -2,68 +2,115 @@ #include #pragma comment(lib,"ntdll.lib") -bool NTAPI RtlResolveDllNameUnicodeString( - IN PCWSTR DllName OPTIONAL, IN PCWSTR DllFullName OPTIONAL, - OUT PUNICODE_STRING BaseDllName, OUT PUNICODE_STRING FullDllName) { +NTSTATUS NTAPI RtlResolveDllNameUnicodeString( + _In_opt_ PCWSTR DllName, + _In_opt_ PCWSTR DllFullName, + _Out_ PUNICODE_STRING BaseDllName, + _Out_ PUNICODE_STRING FullDllName) { std::random_device random; - size_t Length = 0; - size_t FullLength = 0; - PWSTR _DllName = nullptr, _DllFullName = _DllName; HANDLE heap = NtCurrentPeb()->ProcessHeap; - bool result = false; - if (DllName) { - bool add = false; - if ((Length = wcslen(DllName)) <= 4 || wcsnicmp(DllName + Length - 4, L".dll", 4)) { - add = true; - Length += 4; + NTSTATUS status = STATUS_SUCCESS; + size_t length; + + RtlZeroMemory(BaseDllName, sizeof(*BaseDllName)); + RtlZeroMemory(FullDllName, sizeof(*FullDllName)); + + do { + + if (DllName && *DllName) { + bool extend = false; + + length = wcslen(DllName); + if (length <= 4 || _wcsnicmp(DllName + length - 4, L".dll", 4)) { + length += 4; + extend = true; + } + + if (++length >= 0xffff) { + status = STATUS_OBJECT_NAME_INVALID; + break; + } + + BaseDllName->MaximumLength = (USHORT)(length * sizeof(WCHAR)); + BaseDllName->Length = BaseDllName->MaximumLength - sizeof(WCHAR); + BaseDllName->Buffer = (PWSTR)RtlAllocateHeap(heap, 0, BaseDllName->MaximumLength); + if (!BaseDllName->Buffer) { + status = STATUS_NO_MEMORY; + break; + } + + swprintf_s(BaseDllName->Buffer, length, extend ? L"%s.dll" : L"%s", DllName); } - _DllName = new wchar_t[++Length]; - wcscpy(_DllName, DllName); - if (add)wcscat(_DllName, L".DLL"); - } - else { - Length = 16 + 4 + 1; //hex(ULONG64) + ".dll" + '\0' - _DllName = new wchar_t[Length]; - swprintf(_DllName, L"%016llX.DLL", ((ULONG64)random() << 32) | random()); - } - if (DllFullName) { - bool add = false; - FullLength = wcslen(DllFullName); - if (DllName && !wcsstr(DllFullName, DllName) && wcsnicmp(DllFullName + FullLength - 4, L".dll", 4)) { - add = true; - FullLength += Length; + else { + DllName = nullptr; + + BaseDllName->MaximumLength = (16 + 4 + 1) * sizeof(WCHAR); //hex(ULONG64) + ".dll" + '\0' + BaseDllName->Length = BaseDllName->MaximumLength - sizeof(WCHAR); + BaseDllName->Buffer = (PWSTR)RtlAllocateHeap(heap, 0, BaseDllName->MaximumLength); + if (!BaseDllName->Buffer) { + status = STATUS_NO_MEMORY; + break; + } + + swprintf_s(BaseDllName->Buffer, BaseDllName->MaximumLength / sizeof(WCHAR), L"%016llX.DLL", ((ULONG64)random() << 32) | random()); } - wcscpy(_DllFullName = new wchar_t[++FullLength], DllFullName); - if (add) swprintf(_DllFullName, L"%s\\%s", _DllFullName, _DllName); - } - else { - FullLength = 16 + 1 + Length; //hex(ULONG64) + '\\' + _DllName - swprintf(_DllFullName = new wchar_t[FullLength], L"%016llX\\%s", ((ULONG64)random() << 32) | random(), _DllName); - } - FullLength *= sizeof(wchar_t); - Length *= sizeof(wchar_t); - - /* Allocate space for full DLL name */ - if (!(FullDllName->Buffer = (PWSTR)RtlAllocateHeap(heap, HEAP_ZERO_MEMORY, FullLength))) goto end; - FullDllName->Length = FullLength - sizeof(wchar_t); - FullDllName->MaximumLength = FullLength; - wcscpy(FullDllName->Buffer, _DllFullName); - - /* Construct base DLL name */ - BaseDllName->Length = Length - sizeof(wchar_t); - BaseDllName->MaximumLength = Length; - BaseDllName->Buffer = (PWSTR)RtlAllocateHeap(heap, HEAP_ZERO_MEMORY, Length); - if (!BaseDllName->Buffer) { + + if (DllFullName && *DllFullName) { + bool extend = false, backslash = false; + + unsigned int wc = BaseDllName->Length / sizeof(WCHAR); + length = wcslen(DllFullName); + if (length <= wc + 1 || _wcsicmp(DllFullName + length - wc, BaseDllName->Buffer) || *(DllFullName + length - wc - 1) != '\\') { + extend = true; + + if (DllFullName[length - 1] != '\\') { + backslash = true; + + ++length; + } + + length += BaseDllName->Length / sizeof(WCHAR); + } + + if (++length >= 0xffff) { + status = STATUS_OBJECT_NAME_INVALID; + break; + } + + FullDllName->MaximumLength = (USHORT)(length * sizeof(WCHAR)); + FullDllName->Length = FullDllName->MaximumLength - sizeof(WCHAR); + FullDllName->Buffer = (PWSTR)RtlAllocateHeap(heap, 0, FullDllName->MaximumLength); + if (!FullDllName->Buffer) { + status = STATUS_NO_MEMORY; + break; + } + + swprintf_s(FullDllName->Buffer, length, extend ? backslash ? L"%s\\%s" : L"%s%s" : L"%s", DllFullName, BaseDllName->Buffer); + } + else { + FullDllName->MaximumLength = (16 + 1 + 1) * sizeof(WCHAR) + BaseDllName->Length; //hex(ULONG64) + '\\' + BaseDllName + '\0' + FullDllName->Length = FullDllName->MaximumLength - sizeof(WCHAR); + FullDllName->Buffer = (PWSTR)RtlAllocateHeap(heap, 0, FullDllName->MaximumLength); + if (!FullDllName->Buffer) { + status = STATUS_NO_MEMORY; + break; + } + + swprintf_s(FullDllName->Buffer, FullDllName->MaximumLength / sizeof(WCHAR), L"%016llX\\%s", ((ULONG64)random() << 32) | random(), BaseDllName->Buffer); + } + + } while (false); + + if (!NT_SUCCESS(status)) { RtlFreeHeap(heap, 0, BaseDllName->Buffer); - goto end; + RtlFreeHeap(heap, 0, FullDllName->Buffer); + + RtlZeroMemory(BaseDllName, sizeof(*BaseDllName)); + RtlZeroMemory(FullDllName, sizeof(*FullDllName)); } - wcscpy(BaseDllName->Buffer, _DllName); - result = true; -end: - delete[]_DllName; - delete[]_DllFullName; - return result; + + return status; } BOOL NTAPI LdrpExecuteTLS(PMEMORYMODULE module) { @@ -118,9 +165,9 @@ SIZE_T NTAPI _RtlCompareMemory( #endif NTSTATUS NTAPI RtlFindMemoryBlockFromModuleSection( - IN HMODULE hModule OPTIONAL, - IN LPCSTR lpSectionName OPTIONAL, - IN OUT PSEARCH_CONTEXT SearchContext) { + _In_ HMODULE hModule, + _In_ LPCSTR lpSectionName, + _Inout_ PSEARCH_CONTEXT SearchContext) { NTSTATUS status = STATUS_SUCCESS; size_t begin = 0, buffer = 0; @@ -142,7 +189,7 @@ NTSTATUS NTAPI RtlFindMemoryBlockFromModuleSection( if (!headers)return STATUS_INVALID_PARAMETER_1; section = IMAGE_FIRST_SECTION(headers); for (WORD i = 0; i < headers->FileHeader.NumberOfSections; ++i) { - if (!_stricmp(lpSectionName, (LPCSTR)section->Name)) { + if (!_strnicmp(lpSectionName, (LPCSTR)section->Name, 8)) { begin = SearchContext->OutBufferPtr = (size_t)hModule + section->VirtualAddress; Length = SearchContext->RemainingLength = section->Misc.VirtualSize; break; @@ -256,7 +303,7 @@ BOOLEAN NTAPI RtlIsValidImageBuffer( IMAGE_FIRST_SECTION(headers.nt32); ProbeForRead(Buffer, SizeofImage); if (Size)*Size = SizeofImage; - result = CheckSumBufferedFile(Buffer, SizeofImage); + result = CheckSumBufferedFile(Buffer, (DWORD)SizeofImage); } __except (EXCEPTION_EXECUTE_HANDLER) { SetLastError(RtlNtStatusToDosError(GetExceptionCode())); @@ -268,20 +315,6 @@ FARPROC NTAPI RtlGetNtProcAddress(LPCSTR func_name) { return GetProcAddress(GetModuleHandleA("ntdll.dll"), func_name); } -VOID NTAPI RtlGetNtVersionNumbersEx(OUT DWORD* MajorVersion, OUT DWORD* MinorVersion, OUT DWORD* BuildNumber) { - static DWORD Versions[3]{ 0 }; - - if (Versions[0]) goto ret; - RtlGetNtVersionNumbers(Versions, Versions + 1, Versions + 2); - if (Versions[2] & 0xf0000000)Versions[2] &= 0xffff; - -ret: - if (MajorVersion)*MajorVersion = Versions[0]; - if (MinorVersion)*MinorVersion = Versions[1]; - if (BuildNumber)*BuildNumber = Versions[2]; - return; -} - BOOLEAN NTAPI VirtualAccessCheckNoException(LPCVOID pBuffer, size_t size, ACCESS_MASK protect) { if (size) { MEMORY_BASIC_INFORMATION mbi{}; @@ -302,113 +335,44 @@ BOOLEAN NTAPI VirtualAccessCheck(LPCVOID pBuffer, size_t size, ACCESS_MASK prote return TRUE; } -bool NTAPI RtlVerifyVersion(IN DWORD MajorVersion, IN DWORD MinorVersion OPTIONAL, IN DWORD BuildNumber OPTIONAL, IN BYTE Flags) { - DWORD Versions[3]; - RtlGetNtVersionNumbersEx(Versions, Versions + 1, Versions + 2); - if (Versions[0] == MajorVersion && - ((Flags & RTL_VERIFY_FLAGS_MINOR_VERSION) ? Versions[1] == MinorVersion : true) && - ((Flags & RTL_VERIFY_FLAGS_BUILD_NUMBERS) ? Versions[2] == BuildNumber : true))return true; - return false; +BOOL NTAPI RtlVerifyVersion( + _In_ DWORD MajorVersion, + _In_ DWORD MinorVersion, + _In_ DWORD BuildNumber, + _In_ BYTE Flags +) { + if (MmpGlobalDataPtr->NtVersions.MajorVersion == MajorVersion && + ((Flags & RTL_VERIFY_FLAGS_MINOR_VERSION) ? MmpGlobalDataPtr->NtVersions.MinorVersion == MinorVersion : true) && + ((Flags & RTL_VERIFY_FLAGS_BUILD_NUMBERS) ? MmpGlobalDataPtr->NtVersions.BuildNumber == BuildNumber : true))return TRUE; + return FALSE; } -bool NTAPI RtlIsWindowsVersionOrGreater(IN DWORD MajorVersion, IN DWORD MinorVersion, IN DWORD BuildNumber) { - static DWORD Versions[3]{}; - if (!Versions[0])RtlGetNtVersionNumbersEx(Versions, Versions + 1, Versions + 2); - - if (Versions[0] == MajorVersion) { - if (Versions[1] == MinorVersion) return Versions[2] >= BuildNumber; - else return (Versions[1] > MinorVersion); +BOOL NTAPI RtlIsWindowsVersionOrGreater( + _In_ DWORD MajorVersion, + _In_ DWORD MinorVersion, + _In_ DWORD BuildNumber +) { + if (MmpGlobalDataPtr->NtVersions.MajorVersion == MajorVersion) { + if (MmpGlobalDataPtr->NtVersions.MinorVersion == MinorVersion) return MmpGlobalDataPtr->NtVersions.BuildNumber >= BuildNumber; + else return (MmpGlobalDataPtr->NtVersions.MinorVersion > MinorVersion); } - else return Versions[0] > MajorVersion; + else return MmpGlobalDataPtr->NtVersions.MajorVersion > MajorVersion; } -bool NTAPI RtlIsWindowsVersionInScope( - IN DWORD MinMajorVersion, IN DWORD MinMinorVersion, IN DWORD MinBuildNumber, - IN DWORD MaxMajorVersion, IN DWORD MaxMinorVersion, IN DWORD MaxBuildNumber) { +BOOL NTAPI RtlIsWindowsVersionInScope( + _In_ DWORD MinMajorVersion, + _In_ DWORD MinMinorVersion, + _In_ DWORD MinBuildNumber, + + _In_ DWORD MaxMajorVersion, + _In_ DWORD MaxMinorVersion, + _In_ DWORD MaxBuildNumber +) { return RtlIsWindowsVersionOrGreater(MinMajorVersion, MinMinorVersion, MinBuildNumber) && !RtlIsWindowsVersionOrGreater(MaxMajorVersion, MaxMinorVersion, MaxBuildNumber); } -WINDOWS_VERSION NTAPI NtWindowsVersion() { - static WINDOWS_VERSION version = null; - DWORD versions[3]{}; - if (version)return version; - RtlGetNtVersionNumbersEx(versions, versions + 1, versions + 2); - - switch (versions[0]) { - case 5: { - switch (versions[1]) { - case 1:return version = versions[2] == 2600 ? xp : invalid; - case 2:return version = versions[2] == 3790 ? xp : invalid; - default:break; - } - break; - } - break; - case 6: { - switch (versions[1]) { - case 0: { - switch (versions[2]) { - case 6000: - case 6001: - case 6002: - return version = vista; - default: - break; - } - break; - } - break; - case 1: { - switch (versions[2]) { - case 7600: - case 7601: - return version = win7; - default: - break; - } - break; - } - break; - case 2: { - if (versions[2] == 9200)return version = win8; - break; - } - break; - case 3: { - if (versions[2] == 9600)return version = win8_1; - break; - } - break; - default: - break; - } - break; - } - break; - case 10: { - if (versions[1])break; - switch (versions[2]) { - case 10240: - case 10586: return version = win10; - case 14393: return version = win10_1; - case 15063: - case 16299: - case 17134: - case 17763: - case 18362:return version = win10_2; - default:if (RtlIsWindowsVersionOrGreater(versions[0], versions[1], 15063))return version = win10_2; - break; - } - break; - } - break; - default: - break; - } - return version = invalid; -} - +#ifndef _WIN64 int NTAPI RtlCaptureImageExceptionValues(PVOID BaseAddress, PDWORD SEHandlerTable, PDWORD SEHandlerCount) { PIMAGE_LOAD_CONFIG_DIRECTORY pLoadConfigDirectory; PIMAGE_COR20_HEADER pCor20; @@ -436,3 +400,4 @@ int NTAPI RtlCaptureImageExceptionValues(PVOID BaseAddress, PDWORD SEHandlerTabl *SEHandlerTable = *SEHandlerCount = ((pCor20 && pCor20->Flags & 1) ? -1 : 0); return 0; } +#endif diff --git a/MemoryModule/Utils.h b/MemoryModule/Utils.h index afe375de..8d945fd3 100644 --- a/MemoryModule/Utils.h +++ b/MemoryModule/Utils.h @@ -21,28 +21,31 @@ typedef struct _SEARCH_CONTEXT { }SEARCH_CONTEXT, * PSEARCH_CONTEXT; NTSTATUS NTAPI RtlFindMemoryBlockFromModuleSection( - IN HMODULE hModule OPTIONAL, - IN LPCSTR lpSectionName OPTIONAL, - IN OUT PSEARCH_CONTEXT SearchContext + _In_ HMODULE hModule, + _In_ LPCSTR lpSectionName, + _Inout_ PSEARCH_CONTEXT SearchContext ); typedef BOOL(WINAPI* PDLL_STARTUP_ROUTINE)(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved); -bool NTAPI RtlResolveDllNameUnicodeString(IN PCWSTR DllName OPTIONAL, IN PCWSTR DllFullName OPTIONAL, OUT PUNICODE_STRING BaseDllName, OUT PUNICODE_STRING FullDllName); +NTSTATUS NTAPI RtlResolveDllNameUnicodeString( + _In_opt_ PCWSTR DllName, + _In_opt_ PCWSTR DllFullName, + _Out_ PUNICODE_STRING BaseDllName, + _Out_ PUNICODE_STRING FullDllName +); BOOL NTAPI LdrpExecuteTLS(PMEMORYMODULE module); BOOL NTAPI LdrpCallInitializers(PMEMORYMODULE module, DWORD dwReason); -BOOLEAN NTAPI RtlIsValidImageBuffer(PVOID Buffer, size_t* Size); +BOOLEAN NTAPI RtlIsValidImageBuffer( + _In_ PVOID Buffer, + _Out_opt_ size_t* Size +); FARPROC NTAPI RtlGetNtProcAddress(LPCSTR func_name); -VOID NTAPI RtlGetNtVersionNumbersEx( - OUT DWORD* MajorVersion, - OUT DWORD* MinorVersion, - OUT DWORD* BuildNumber); - BOOLEAN NTAPI VirtualAccessCheck(LPCVOID pBuffer, size_t size, ACCESS_MASK protect); BOOLEAN NTAPI VirtualAccessCheckNoException(LPCVOID pBuffer, size_t size, ACCESS_MASK protect); #define ProbeForRead(pBuffer, size) VirtualAccessCheck(pBuffer, size, PAGE_READONLY | PAGE_READWRITE | PAGE_EXECUTE_READ | PAGE_EXECUTE_READWRITE) @@ -62,29 +65,29 @@ BOOLEAN NTAPI VirtualAccessCheckNoException(LPCVOID pBuffer, size_t size, ACCESS #define RTL_VERIFY_FLAGS_BUILD_NUMBERS 2 #define RTL_VERIFY_FLAGS_DEFAULT RTL_VERIFY_FLAGS_MAJOR_VERSION|RTL_VERIFY_FLAGS_MINOR_VERSION|RTL_VERIFY_FLAGS_BUILD_NUMBERS -bool NTAPI RtlVerifyVersion(IN DWORD MajorVersion, IN DWORD MinorVersion OPTIONAL, IN DWORD BuildNumber OPTIONAL, IN BYTE Flags); - -bool NTAPI RtlIsWindowsVersionOrGreater(IN DWORD MajorVersion, IN DWORD MinorVersion, IN DWORD BuildNumber); - -bool NTAPI RtlIsWindowsVersionInScope( - IN DWORD MinMajorVersion, IN DWORD MinMinorVersion, IN DWORD MinBuildNumber, - IN DWORD MaxMajorVersion, IN DWORD MaxMinorVersion, IN DWORD MaxBuildNumber +BOOL NTAPI RtlVerifyVersion( + _In_ DWORD MajorVersion, + _In_ DWORD MinorVersion, + _In_ DWORD BuildNumber, + _In_ BYTE Flags ); +BOOL NTAPI RtlIsWindowsVersionOrGreater( + _In_ DWORD MajorVersion, + _In_ DWORD MinorVersion, + _In_ DWORD BuildNumber +); -typedef enum _WINDOWS_VERSION { - null, - xp, - vista, - win7, - win8, - win8_1, - win10, - win10_1, - win10_2, - invalid -}WINDOWS_VERSION; +BOOL NTAPI RtlIsWindowsVersionInScope( + _In_ DWORD MinMajorVersion, + _In_ DWORD MinMinorVersion, + _In_ DWORD MinBuildNumber, -WINDOWS_VERSION NTAPI NtWindowsVersion(); + _In_ DWORD MaxMajorVersion, + _In_ DWORD MaxMinorVersion, + _In_ DWORD MaxBuildNumber +); +#ifndef _WIN64 int NTAPI RtlCaptureImageExceptionValues(PVOID BaseAddress, PDWORD SEHandlerTable, PDWORD SEHandlerCount); +#endif diff --git a/MemoryModulePP.sln b/MemoryModulePP.sln index 21ce55a0..0b985a5c 100644 --- a/MemoryModulePP.sln +++ b/MemoryModulePP.sln @@ -19,12 +19,12 @@ Global GlobalSection(ProjectConfigurationPlatforms) = postSolution {5B1F46DB-036E-4A50-AF5F-F5D6584D42C6}.Debug|x64.ActiveCfg = Debug|x64 {5B1F46DB-036E-4A50-AF5F-F5D6584D42C6}.Debug|x64.Build.0 = Debug|x64 - {5B1F46DB-036E-4A50-AF5F-F5D6584D42C6}.Debug|x86.ActiveCfg = DebugDll|Win32 - {5B1F46DB-036E-4A50-AF5F-F5D6584D42C6}.Debug|x86.Build.0 = DebugDll|Win32 + {5B1F46DB-036E-4A50-AF5F-F5D6584D42C6}.Debug|x86.ActiveCfg = Debug|Win32 + {5B1F46DB-036E-4A50-AF5F-F5D6584D42C6}.Debug|x86.Build.0 = Debug|Win32 {5B1F46DB-036E-4A50-AF5F-F5D6584D42C6}.Release|x64.ActiveCfg = Release|x64 {5B1F46DB-036E-4A50-AF5F-F5D6584D42C6}.Release|x64.Build.0 = Release|x64 - {5B1F46DB-036E-4A50-AF5F-F5D6584D42C6}.Release|x86.ActiveCfg = ReleaseDll|Win32 - {5B1F46DB-036E-4A50-AF5F-F5D6584D42C6}.Release|x86.Build.0 = ReleaseDll|Win32 + {5B1F46DB-036E-4A50-AF5F-F5D6584D42C6}.Release|x86.ActiveCfg = Release|Win32 + {5B1F46DB-036E-4A50-AF5F-F5D6584D42C6}.Release|x86.Build.0 = Release|Win32 {5B3131BA-178A-4A28-BD54-315A45C97ED1}.Debug|x64.ActiveCfg = Debug|x64 {5B3131BA-178A-4A28-BD54-315A45C97ED1}.Debug|x64.Build.0 = Debug|x64 {5B3131BA-178A-4A28-BD54-315A45C97ED1}.Debug|x64.Deploy.0 = Debug|x64 diff --git a/a/load.cpp b/a/load.cpp index 5262540d..72babcbe 100644 --- a/a/load.cpp +++ b/a/load.cpp @@ -4,7 +4,8 @@ static PVOID ReadDllFile(LPCSTR FileName) { LPVOID buffer; size_t size; - FILE* f = fopen(FileName, "rb"); + FILE* f; + fopen_s(&f, FileName, "rb"); if (!f)return 0; _fseeki64(f, 0, SEEK_END); if (!(size = _ftelli64(f))) { diff --git a/test/test.cpp b/test/test.cpp index f5a7ac29..701ac74b 100644 --- a/test/test.cpp +++ b/test/test.cpp @@ -1,11 +1,11 @@ #include "../MemoryModule/stdafx.h" #include -#pragma warning(disable:4996) static PVOID ReadDllFile(LPCSTR FileName) { LPVOID buffer; size_t size; - FILE* f = fopen(FileName, "rb"); + FILE* f; + fopen_s(&f, FileName, "rb"); if (!f)return 0; _fseeki64(f, 0, SEEK_END); if (!(size = _ftelli64(f))) { @@ -30,8 +30,8 @@ int test() { 0, // Flags buffer, // Buffer 0, // Reserved - L"a.dll", // DllBaseName - L"C:\\Windows\\System32\\a.dll" // DllFullName + nullptr, // DllBaseName + nullptr // DllFullName ); if (NT_SUCCESS(status) && status != STATUS_IMAGE_MACHINE_TYPE_MISMATCH) { From 609d7e7d5619124d9b5fa06ac5ff8623cbc75c02 Mon Sep 17 00:00:00 2001 From: Boring <1079299053@qq.com> Date: Fri, 7 Oct 2022 09:00:51 +0800 Subject: [PATCH 8/8] Extend LDR_DATA_TABLE_ENTRY to Windows 11 --- MemoryModule/Initialize.cpp | 71 ++++++++++++++++++++------------- MemoryModule/LdrEntry.cpp | 34 ++++++++-------- MemoryModule/LdrEntry.h | 77 ++++++------------------------------ MemoryModule/Loader.cpp | 2 +- MemoryModule/MmpGlobalData.h | 6 ++- MemoryModule/Utils.cpp | 6 +-- MemoryModule/Utils.h | 4 -- test/test.cpp | 18 ++++++++- 8 files changed, 98 insertions(+), 120 deletions(-) diff --git a/MemoryModule/Initialize.cpp b/MemoryModule/Initialize.cpp index da27d025..6fc0e90e 100644 --- a/MemoryModule/Initialize.cpp +++ b/MemoryModule/Initialize.cpp @@ -191,11 +191,13 @@ VOID InitializeWindowsVersion() { case 5: { switch (MmpGlobalDataPtr->NtVersions.MinorVersion) { case 1: - version = MmpGlobalDataPtr->NtVersions.BuildNumber == 2600 ? WINDOWS_VERSION::xp : WINDOWS_VERSION::invalid; + if (MmpGlobalDataPtr->NtVersions.BuildNumber == 2600) + version = WINDOWS_VERSION::xp; break; case 2: - version = MmpGlobalDataPtr->NtVersions.BuildNumber == 3790 ? WINDOWS_VERSION::xp : WINDOWS_VERSION::invalid; + if (MmpGlobalDataPtr->NtVersions.BuildNumber == 3790) + version = WINDOWS_VERSION::xp; break; } break; @@ -225,12 +227,14 @@ VOID InitializeWindowsVersion() { } case 2: { - if (MmpGlobalDataPtr->NtVersions.BuildNumber == 9200) version = WINDOWS_VERSION::win8; + if (MmpGlobalDataPtr->NtVersions.BuildNumber == 9200) + version = WINDOWS_VERSION::win8; break; } case 3: { - if (MmpGlobalDataPtr->NtVersions.BuildNumber == 9600) version = WINDOWS_VERSION::win8_1; + if (MmpGlobalDataPtr->NtVersions.BuildNumber == 9600) + version = WINDOWS_VERSION::winBlue; break; } @@ -240,27 +244,29 @@ VOID InitializeWindowsVersion() { case 10: { if (MmpGlobalDataPtr->NtVersions.MinorVersion)break; - switch (MmpGlobalDataPtr->NtVersions.BuildNumber) { - case 10240: - case 10586: - version = WINDOWS_VERSION::win10; - break; - - case 14393: - version = WINDOWS_VERSION::win10_1; - break; - case 15063: - case 16299: - case 17134: - case 17763: - case 18362: - version = WINDOWS_VERSION::win10_2; - break; - - default: - if (RtlIsWindowsVersionOrGreater(MmpGlobalDataPtr->NtVersions.MajorVersion, MmpGlobalDataPtr->NtVersions.MinorVersion, 15063)) version = WINDOWS_VERSION::win10_2; - break; + DWORD BuildNumber = MmpGlobalDataPtr->NtVersions.BuildNumber; + if (BuildNumber >= 10240) { + if (BuildNumber >= 14393) { + if (BuildNumber >= 15063) { + if (BuildNumber >= 22000) { + // [22000, ?) + version = WINDOWS_VERSION::win11; + } + else { + // [15063, 22000) + version = WINDOWS_VERSION::win10_2; + } + } + else { + // [13494, 15063) + version = WINDOWS_VERSION::win10_1; + } + } + else { + // [10240, 14393) + version = WINDOWS_VERSION::win10; + } } break; @@ -369,8 +375,8 @@ NTSTATUS InitializeLockHeld() { MmpGlobalDataPtr->LdrDataTableEntrySize = sizeof(LDR_DATA_TABLE_ENTRY_WIN8); break; - case WINDOWS_VERSION::win8_1: - MmpGlobalDataPtr->LdrDataTableEntrySize = sizeof(LDR_DATA_TABLE_ENTRY_WIN8_1); + case WINDOWS_VERSION::winBlue: + MmpGlobalDataPtr->LdrDataTableEntrySize = sizeof(LDR_DATA_TABLE_ENTRY_WINBLUE); break; case WINDOWS_VERSION::win10: @@ -385,14 +391,25 @@ NTSTATUS InitializeLockHeld() { MmpGlobalDataPtr->LdrDataTableEntrySize = sizeof(LDR_DATA_TABLE_ENTRY_WIN10_2); break; + case WINDOWS_VERSION::win11: + MmpGlobalDataPtr->LdrDataTableEntrySize = sizeof(LDR_DATA_TABLE_ENTRY_WIN11); + break; + default: - MmpGlobalDataPtr->LdrDataTableEntrySize = sizeof(LDR_DATA_TABLE_ENTRY_WIN10_2); + NtUnmapViewOfSection(NtCurrentProcess(), BaseAddress); + status = STATUS_NOT_SUPPORTED; break; } + if (!NT_SUCCESS(status))break; + MmpGlobalDataPtr->MmpBaseAddressIndex.NtdllLdrEntry = RtlFindLdrTableEntryByBaseName(L"ntdll.dll"); MmpGlobalDataPtr->MmpBaseAddressIndex.LdrpModuleBaseAddressIndex = FindLdrpModuleBaseAddressIndex(); + HMODULE hNtdll = (HMODULE)MmpGlobalDataPtr->MmpBaseAddressIndex.NtdllLdrEntry->DllBase; + MmpGlobalDataPtr->MmpLdrEntry._RtlRbInsertNodeEx = decltype(&RtlRbInsertNodeEx)(GetProcAddress(hNtdll, "RtlRbInsertNodeEx")); + MmpGlobalDataPtr->MmpLdrEntry._RtlRbRemoveNode = decltype(&RtlRbRemoveNode)(GetProcAddress(hNtdll, "RtlRbRemoveNode")); + MmpGlobalDataPtr->MmpLdrEntry.LdrpHashTable = FindLdrpHashTable(); MmpGlobalDataPtr->MmpInvertedFunctionTable.LdrpInvertedFunctionTable = FindLdrpInvertedFunctionTable(); diff --git a/MemoryModule/LdrEntry.cpp b/MemoryModule/LdrEntry.cpp index d35db8a3..d510e409 100644 --- a/MemoryModule/LdrEntry.cpp +++ b/MemoryModule/LdrEntry.cpp @@ -120,6 +120,11 @@ BOOL NTAPI RtlInitializeLdrDataTableEntry( } switch (MmpGlobalDataPtr->WindowsVersion) { + case WINDOWS_VERSION::win11: { + auto entry = (PLDR_DATA_TABLE_ENTRY_WIN11)LdrEntry; + entry->CheckSum = headers->OptionalHeader.CheckSum; + } + case WINDOWS_VERSION::win10: case WINDOWS_VERSION::win10_1: case WINDOWS_VERSION::win10_2: { @@ -127,7 +132,7 @@ BOOL NTAPI RtlInitializeLdrDataTableEntry( entry->ReferenceCount = 1; } case WINDOWS_VERSION::win8: - case WINDOWS_VERSION::win8_1: { + case WINDOWS_VERSION::winBlue: { auto entry = (PLDR_DATA_TABLE_ENTRY_WIN8)LdrEntry; const static bool IsWin8 = RtlIsWindowsVersionInScope(6, 2, 0, 6, 3, -1); NtQuerySystemTime(&entry->LoadTime); @@ -137,9 +142,7 @@ BOOL NTAPI RtlInitializeLdrDataTableEntry( if (!NT_SUCCESS(RtlInsertModuleBaseAddressIndexNode(LdrEntry, BaseAddress)))return FALSE; if (!(entry->DdagNode = (decltype(entry->DdagNode)) RtlAllocateHeap(heap, HEAP_ZERO_MEMORY, IsWin8 ? sizeof(_LDR_DDAG_NODE_WIN8) : sizeof(_LDR_DDAG_NODE))))return FALSE; - //RtlInitializeListEntry(&entry->NodeModuleLink); - //RtlInitializeListEntry(&entry->DdagNode->Modules); - //RtlInitializeSingleEntry(&entry->DdagNode->CondenseLink); + entry->NodeModuleLink.Flink = &entry->DdagNode->Modules; entry->NodeModuleLink.Blink = &entry->DdagNode->Modules; entry->DdagNode->Modules.Flink = &entry->NodeModuleLink; @@ -198,7 +201,7 @@ BOOL NTAPI RtlFreeLdrDataTableEntry(_In_ PLDR_DATA_TABLE_ENTRY LdrEntry) { case WINDOWS_VERSION::win10_1: case WINDOWS_VERSION::win10_2: case WINDOWS_VERSION::win8: - case WINDOWS_VERSION::win8_1: { + case WINDOWS_VERSION::winBlue: { auto entry = (PLDR_DATA_TABLE_ENTRY_WIN10)LdrEntry; RtlFreeDependencies(entry); RtlFreeHeap(heap, 0, entry->DdagNode); @@ -274,20 +277,17 @@ VOID NTAPI RtlRbInsertNodeEx( _In_ PRTL_BALANCED_NODE Parent, _In_ BOOLEAN Right, _Out_ PRTL_BALANCED_NODE Node) { - static decltype(&RtlRbInsertNodeEx)_RtlRbInsertNodeEx = decltype(_RtlRbInsertNodeEx)(RtlGetNtProcAddress("RtlRbInsertNodeEx")); - RtlZeroMemory(Node, sizeof(*Node)); - if (!_RtlRbInsertNodeEx)return; - return _RtlRbInsertNodeEx(Tree, Parent, Right, Node); + if (!MmpGlobalDataPtr->MmpLdrEntry._RtlRbInsertNodeEx)return; + return MmpGlobalDataPtr->MmpLdrEntry._RtlRbInsertNodeEx(Tree, Parent, Right, Node); } VOID NTAPI RtlRbRemoveNode( _In_ PRTL_RB_TREE Tree, _In_ PRTL_BALANCED_NODE Node) { - static decltype(&RtlRbRemoveNode)_RtlRbRemoveNode = decltype(_RtlRbRemoveNode)(RtlGetNtProcAddress("RtlRbRemoveNode")); - if (!_RtlRbRemoveNode)return; - return _RtlRbRemoveNode(Tree, Node); + if (!MmpGlobalDataPtr->MmpLdrEntry._RtlRbRemoveNode)return; + return MmpGlobalDataPtr->MmpLdrEntry._RtlRbRemoveNode(Tree, Node); } PLDR_DATA_TABLE_ENTRY NTAPI RtlFindLdrTableEntryByHandle(_In_ PVOID BaseAddress) { @@ -317,15 +317,15 @@ PLDR_DATA_TABLE_ENTRY NTAPI RtlFindLdrTableEntryByBaseName(_In_z_ PCWSTR BaseNam return nullptr; } -ULONG NTAPI LdrHashEntry(_In_ UNICODE_STRING& str, _In_ BOOL _xor) { +ULONG NTAPI LdrHashEntry(_In_ UNICODE_STRING& DllBaseName, _In_ BOOL ToIndex) { ULONG result = 0; if (RtlIsWindowsVersionOrGreater(6, 2, 0)) { - RtlHashUnicodeString(&str, TRUE, HASH_STRING_ALGORITHM_DEFAULT, &result); + RtlHashUnicodeString(&DllBaseName, TRUE, HASH_STRING_ALGORITHM_DEFAULT, &result); } else { - for (USHORT i = 0; i < (str.Length / sizeof(wchar_t)); ++i) - result += 0x1003F * RtlUpcaseUnicodeChar(str.Buffer[i]); + for (USHORT i = 0; i < (DllBaseName.Length / sizeof(wchar_t)); ++i) + result += 0x1003F * RtlUpcaseUnicodeChar(DllBaseName.Buffer[i]); } - if (_xor)result &= (LDR_HASH_TABLE_ENTRIES - 1); + if (ToIndex)result &= (LDR_HASH_TABLE_ENTRIES - 1); return result; } diff --git a/MemoryModule/LdrEntry.h b/MemoryModule/LdrEntry.h index bd760faf..74c22fc4 100644 --- a/MemoryModule/LdrEntry.h +++ b/MemoryModule/LdrEntry.h @@ -199,9 +199,9 @@ typedef struct _LDR_DATA_TABLE_ENTRY_WIN8 { }LDR_DATA_TABLE_ENTRY_WIN8, * PLDR_DATA_TABLE_ENTRY_WIN8; //6.3.9600 Windows 8.1 | 2012R2 RTM | 2012R2 Update 1 -typedef struct _LDR_DATA_TABLE_ENTRY_WIN8_1 :public _LDR_DATA_TABLE_ENTRY_WIN8 { +typedef struct _LDR_DATA_TABLE_ENTRY_WINBLUE :public _LDR_DATA_TABLE_ENTRY_WIN8 { ULONG ImplicitPathOptions; -}LDR_DATA_TABLE_ENTRY_WIN8_1, * PLDR_DATA_TABLE_ENTRY_WIN8_1; +}LDR_DATA_TABLE_ENTRY_WINBLUE, * PLDR_DATA_TABLE_ENTRY_WINBLUE; //10.0.10240 Windows 10 | 2016 1507 Threshold 1 //10.0.10586 Windows 10 | 2016 1511 Threshold 2 @@ -280,69 +280,18 @@ typedef struct _LDR_DATA_TABLE_ENTRY_WIN10_1 :public _LDR_DATA_TABLE_ENTRY_WIN10 //10.0.18362 Windows 10 | 2016 1903 19H1 (May 2019 Update) | 2016 1909 19H2 (November 2019 Update) //10.0.19041 Windows 10 | 2016 2004 20H1 (May 2020 Update) //10.0.19042 Windows 10 | 2016 2009 20H2 (October 2020 Update) -typedef struct _LDR_DATA_TABLE_ENTRY_WIN10_2 { - _LIST_ENTRY InLoadOrderLinks; //0x0 - _LIST_ENTRY InMemoryOrderLinks; //0x10 - _LIST_ENTRY InInitializationOrderLinks; //0x20 - VOID* DllBase; //0x30 - VOID* EntryPoint; //0x38 - ULONG SizeOfImage; //0x40 - _UNICODE_STRING FullDllName; //0x48 - _UNICODE_STRING BaseDllName; //0x58 - union { - UCHAR FlagGroup[4]; //0x68 - ULONG Flags; //0x68 - struct { - ULONG PackagedBinary : 1; //0x68 - ULONG MarkedForRemoval : 1; //0x68 - ULONG ImageDll : 1; //0x68 - ULONG LoadNotificationsSent : 1; //0x68 - ULONG TelemetryEntryProcessed : 1; //0x68 - ULONG ProcessStaticImport : 1; //0x68 - ULONG InLegacyLists : 1; //0x68 - ULONG InIndexes : 1; //0x68 - ULONG ShimDll : 1; //0x68 - ULONG InExceptionTable : 1; //0x68 - ULONG ReservedFlags1 : 2; //0x68 - ULONG LoadInProgress : 1; //0x68 - ULONG LoadConfigProcessed : 1; //0x68 - ULONG EntryProcessed : 1; //0x68 - ULONG ProtectDelayLoad : 1; //0x68 - ULONG ReservedFlags3 : 2; //0x68 - ULONG DontCallForThreads : 1; //0x68 - ULONG ProcessAttachCalled : 1; //0x68 - ULONG ProcessAttachFailed : 1; //0x68 - ULONG CorDeferredValidate : 1; //0x68 - ULONG CorImage : 1; //0x68 - ULONG DontRelocate : 1; //0x68 - ULONG CorILOnly : 1; //0x68 - ULONG ReservedFlags5 : 3; //0x68 - ULONG Redirected : 1; //0x68 - ULONG ReservedFlags6 : 2; //0x68 - ULONG CompatDatabaseProcessed : 1; //0x68 - }; - }; - USHORT ObsoleteLoadCount; //0x6c - USHORT TlsIndex; //0x6e - _LIST_ENTRY HashLinks; //0x70 - ULONG TimeDateStamp; //0x80 - _ACTIVATION_CONTEXT* EntryPointActivationContext; //0x88 - VOID* Lock; //0x90 - _LDR_DDAG_NODE* DdagNode; //0x98 - _LIST_ENTRY NodeModuleLink; //0xa0 - VOID* LoadContext; //0xb0 - VOID* ParentDllBase; //0xb8 - VOID* SwitchBackContext; //0xc0 - _RTL_BALANCED_NODE BaseAddressIndexNode; //0xc8 - _RTL_BALANCED_NODE MappingInfoIndexNode; //0xe0 - ULONGLONG OriginalBase; //0xf8 - _LARGE_INTEGER LoadTime; //0x100 - ULONG BaseNameHashValue; //0x108 - _LDR_DLL_LOAD_REASON LoadReason; //0x10c - ULONG ImplicitPathOptions; //0x110 - ULONG ReferenceCount; //0x114 +typedef struct _LDR_DATA_TABLE_ENTRY_WIN10_2 :LDR_DATA_TABLE_ENTRY_WIN10 { ULONG DependentLoadFlags; //0x118 UCHAR SigningLevel; //0x11c }LDR_DATA_TABLE_ENTRY_WIN10_2, * PLDR_DATA_TABLE_ENTRY_WIN10_2; -ULONG NTAPI LdrHashEntry(_In_ UNICODE_STRING& str, _In_ BOOL _xor = TRUE); +//10.0.22000 Windows 11 Insider Preview (Jun 2021) +//10.0.22000 Windows 11 21H2 (RTM) +//10.0.22621 Windows 11 22H2 (2022 Update) +typedef struct _LDR_DATA_TABLE_ENTRY_WIN11 :LDR_DATA_TABLE_ENTRY_WIN10_2 { + ULONG CheckSum; //0x120 + VOID* ActivePatchImageBase; //0x128 + LDR_HOT_PATCH_STATE HotPatchState; //0x130 +}LDR_DATA_TABLE_ENTRY_WIN11, * PLDR_DATA_TABLE_ENTRY_WIN11; + +ULONG NTAPI LdrHashEntry(_In_ UNICODE_STRING& DllBaseName, _In_ BOOL ToIndex = TRUE); diff --git a/MemoryModule/Loader.cpp b/MemoryModule/Loader.cpp index eb95b899..22890442 100644 --- a/MemoryModule/Loader.cpp +++ b/MemoryModule/Loader.cpp @@ -256,7 +256,7 @@ NTSTATUS NTAPI LdrUnloadDllMemory(_In_ HMEMORYMODULE BaseAddress) { if (!(count & ~1)) { module->underUnload = true; if (module->initialized) { - PDLL_STARTUP_ROUTINE((LPVOID)(module->codeBase + headers->OptionalHeader.AddressOfEntryPoint))( + PLDR_INIT_ROUTINE((LPVOID)(module->codeBase + headers->OptionalHeader.AddressOfEntryPoint))( (HINSTANCE)module->codeBase, DLL_PROCESS_DETACH, 0 diff --git a/MemoryModule/MmpGlobalData.h b/MemoryModule/MmpGlobalData.h index 42d8b083..8870f433 100644 --- a/MemoryModule/MmpGlobalData.h +++ b/MemoryModule/MmpGlobalData.h @@ -14,6 +14,9 @@ typedef struct _MMP_INVERTED_FUNCTION_TABLE_DATA { //LdrEntry.cpp typedef struct _MMP_LDR_ENTRY_DATA { PLIST_ENTRY LdrpHashTable; + + decltype(&RtlRbInsertNodeEx)_RtlRbInsertNodeEx; + decltype(&RtlRbRemoveNode)_RtlRbRemoveNode; }MMP_LDR_ENTRY_DATA, * PMMP_LDR_ENTRY_DATA; //MmpTls.cpp @@ -65,10 +68,11 @@ typedef enum class _WINDOWS_VERSION :BYTE { vista, win7, win8, - win8_1, + winBlue, win10, win10_1, win10_2, + win11, invalid }WINDOWS_VERSION; diff --git a/MemoryModule/Utils.cpp b/MemoryModule/Utils.cpp index aa584706..1b2c7568 100644 --- a/MemoryModule/Utils.cpp +++ b/MemoryModule/Utils.cpp @@ -138,7 +138,7 @@ BOOL NTAPI LdrpCallInitializers(PMEMORYMODULE module, DWORD dwReason) { if (headers->OptionalHeader.AddressOfEntryPoint) { __try { // notify library about attaching to process - if (((PDLL_STARTUP_ROUTINE)(module->codeBase + headers->OptionalHeader.AddressOfEntryPoint))((HINSTANCE)module->codeBase, dwReason, 0)) { + if (((PLDR_INIT_ROUTINE)(module->codeBase + headers->OptionalHeader.AddressOfEntryPoint))((HINSTANCE)module->codeBase, dwReason, 0)) { module->initialized = TRUE; return TRUE; } @@ -311,10 +311,6 @@ BOOLEAN NTAPI RtlIsValidImageBuffer( return result; } -FARPROC NTAPI RtlGetNtProcAddress(LPCSTR func_name) { - return GetProcAddress(GetModuleHandleA("ntdll.dll"), func_name); -} - BOOLEAN NTAPI VirtualAccessCheckNoException(LPCVOID pBuffer, size_t size, ACCESS_MASK protect) { if (size) { MEMORY_BASIC_INFORMATION mbi{}; diff --git a/MemoryModule/Utils.h b/MemoryModule/Utils.h index 8d945fd3..21f4b0da 100644 --- a/MemoryModule/Utils.h +++ b/MemoryModule/Utils.h @@ -26,8 +26,6 @@ NTSTATUS NTAPI RtlFindMemoryBlockFromModuleSection( _Inout_ PSEARCH_CONTEXT SearchContext ); -typedef BOOL(WINAPI* PDLL_STARTUP_ROUTINE)(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved); - NTSTATUS NTAPI RtlResolveDllNameUnicodeString( _In_opt_ PCWSTR DllName, _In_opt_ PCWSTR DllFullName, @@ -44,8 +42,6 @@ BOOLEAN NTAPI RtlIsValidImageBuffer( _Out_opt_ size_t* Size ); -FARPROC NTAPI RtlGetNtProcAddress(LPCSTR func_name); - BOOLEAN NTAPI VirtualAccessCheck(LPCVOID pBuffer, size_t size, ACCESS_MASK protect); BOOLEAN NTAPI VirtualAccessCheckNoException(LPCVOID pBuffer, size_t size, ACCESS_MASK protect); #define ProbeForRead(pBuffer, size) VirtualAccessCheck(pBuffer, size, PAGE_READONLY | PAGE_READWRITE | PAGE_EXECUTE_READ | PAGE_EXECUTE_READWRITE) diff --git a/test/test.cpp b/test/test.cpp index 701ac74b..e05b7e27 100644 --- a/test/test.cpp +++ b/test/test.cpp @@ -49,6 +49,22 @@ int test() { } int main() { - test(); + if (MmpGlobalDataPtr->WindowsVersion == WINDOWS_VERSION::win11) { + auto head = &NtCurrentPeb()->Ldr->InLoadOrderModuleList; + auto entry = head->Flink; + while (entry != head) { + PLDR_DATA_TABLE_ENTRY_WIN11 __entry = CONTAINING_RECORD(entry, LDR_DATA_TABLE_ENTRY_WIN11, InLoadOrderLinks); + wprintf(L"%s\t0x%08X, 0x%08X, 0x%p, %d\n", + __entry->BaseDllName.Buffer, + __entry->CheckSum, + RtlImageNtHeader(__entry->DllBase)->OptionalHeader.CheckSum, + __entry->ActivePatchImageBase, + __entry->HotPatchState + ); + + entry = entry->Flink; + } + } + return 0; }