From 41e666e31455456657da1b4507bc8fb2b33b8801 Mon Sep 17 00:00:00 2001 From: Boring <1079299053@qq.com> Date: Fri, 15 Dec 2023 08:40:27 +0800 Subject: [PATCH 01/17] LoadLibraryMemoryExA pass the Flags parameter --- MemoryModule/LoadDllMemoryApi.cpp | 2 +- MemoryModule/MmpGlobalData.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/MemoryModule/LoadDllMemoryApi.cpp b/MemoryModule/LoadDllMemoryApi.cpp index 3e61cdf9..01aaeb65 100644 --- a/MemoryModule/LoadDllMemoryApi.cpp +++ b/MemoryModule/LoadDllMemoryApi.cpp @@ -51,7 +51,7 @@ HMEMORYMODULE WINAPI LoadLibraryMemoryExA( mbstowcs_s(nullptr, _DllFullName, size, DllFullName, size); } - result = LoadLibraryMemoryExW(BufferAddress, 0, _DllName, _DllFullName, 0); + result = LoadLibraryMemoryExW(BufferAddress, 0, _DllName, _DllFullName, Flags); } while (false); RtlFreeHeap(heap, 0, _DllName); diff --git a/MemoryModule/MmpGlobalData.h b/MemoryModule/MmpGlobalData.h index 35752ecd..2f73ddf7 100644 --- a/MemoryModule/MmpGlobalData.h +++ b/MemoryModule/MmpGlobalData.h @@ -100,7 +100,7 @@ typedef enum class _WINDOWS_VERSION :BYTE { #define MEMORY_MODULE_GET_MINOR_VERSION(MinorVersion) (~0x8000&(MinorVersion)) #define MEMORY_MODULE_MAJOR_VERSION 2 -#define MEMORY_MODULE_MINOR_VERSION MEMORY_MODULE_MAKE_PREVIEW(0) +#define MEMORY_MODULE_MINOR_VERSION 0 typedef struct _MMP_GLOBAL_DATA { From 8d1454fab1b560da086c6f129d0bb38a8614b498 Mon Sep 17 00:00:00 2001 From: Boring <1079299053@qq.com> Date: Fri, 15 Dec 2023 15:21:02 +0800 Subject: [PATCH 02/17] MmpPostponedTls shuts down gracefully. --- MemoryModule/MmpTlsFiber.cpp | 77 +++++++++++++++++--------- test/test.cpp | 101 ++++++++++++++++++++--------------- 2 files changed, 110 insertions(+), 68 deletions(-) diff --git a/MemoryModule/MmpTlsFiber.cpp b/MemoryModule/MmpTlsFiber.cpp index 60b89dc1..3b5391e2 100644 --- a/MemoryModule/MmpTlsFiber.cpp +++ b/MemoryModule/MmpTlsFiber.cpp @@ -27,42 +27,48 @@ DWORD WINAPI MmpReleasePostponedTlsWorker(PVOID) { EnterCriticalSection(&MmpPostponedTlsLock); - auto iter = MmpPostponedTlsList->begin(); + if (MmpPostponedTlsList) { + auto iter = MmpPostponedTlsList->begin(); - while (iter != MmpPostponedTlsList->end()) { - const auto& item = *iter; - GetExitCodeThread(item.hThread, &code); + while (iter != MmpPostponedTlsList->end()) { + const auto& item = *iter; + GetExitCodeThread(item.hThread, &code); - if (code == STILL_ACTIVE) { - ++iter; - } - else { + if (code == STILL_ACTIVE) { + ++iter; + } + else { - RtlAcquireSRWLockExclusive(&MmpGlobalDataPtr->MmpTls->MmpTlsListLock); + RtlAcquireSRWLockExclusive(&MmpGlobalDataPtr->MmpTls->MmpTlsListLock); - auto TlspMmpBlock = (PVOID*)item.lpOldTlsVector->ModuleTlsData; - auto entry = MmpGlobalDataPtr->MmpTls->MmpTlsList.Flink; - while (entry != &MmpGlobalDataPtr->MmpTls->MmpTlsList) { + auto TlspMmpBlock = (PVOID*)item.lpOldTlsVector->ModuleTlsData; + auto 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]); + auto p = CONTAINING_RECORD(entry, TLS_ENTRY, TlsEntryLinks); + RtlFreeHeap(RtlProcessHeap(), 0, TlspMmpBlock[p->TlsDirectory.Characteristics]); - entry = entry->Flink; - } + entry = entry->Flink; + } - RtlFreeHeap(RtlProcessHeap(), 0, CONTAINING_RECORD(item.lpTlsRecord->TlspLdrBlock, TLS_VECTOR, TLS_VECTOR::ModuleTlsData)); - RtlFreeHeap(RtlProcessHeap(), 0, item.lpTlsRecord); - RtlFreeHeap(RtlProcessHeap(), 0, item.lpOldTlsVector); + RtlFreeHeap(RtlProcessHeap(), 0, CONTAINING_RECORD(item.lpTlsRecord->TlspLdrBlock, TLS_VECTOR, TLS_VECTOR::ModuleTlsData)); + RtlFreeHeap(RtlProcessHeap(), 0, item.lpTlsRecord); + RtlFreeHeap(RtlProcessHeap(), 0, item.lpOldTlsVector); - RtlReleaseSRWLockExclusive(&MmpGlobalDataPtr->MmpTls->MmpTlsListLock); + RtlReleaseSRWLockExclusive(&MmpGlobalDataPtr->MmpTls->MmpTlsListLock); + + CloseHandle(item.hThread); + iter = MmpPostponedTlsList->erase(iter); + } - CloseHandle(item.hThread); - iter = MmpPostponedTlsList->erase(iter); } + waitTime = MmpPostponedTlsList->empty() ? INFINITE : 1000; + } + else { + LeaveCriticalSection(&MmpPostponedTlsLock); + break; } - - waitTime = MmpPostponedTlsList->empty() ? INFINITE : 1000; LeaveCriticalSection(&MmpPostponedTlsLock); } @@ -100,16 +106,35 @@ VOID WINAPI MmpQueuePostponedTls(PMMP_TLSP_RECORD record) { EnterCriticalSection(&MmpPostponedTlsLock); - MmpPostponedTlsList->push_back(item); - SetEvent(MmpPostponedTlsEvent); + if (MmpPostponedTlsList) { + MmpPostponedTlsList->push_back(item); + SetEvent(MmpPostponedTlsEvent); + } + else { + RtlFreeHeap(RtlProcessHeap(), 0, item.lpOldTlsVector); + } LeaveCriticalSection(&MmpPostponedTlsLock); } +VOID OnExit() { + EnterCriticalSection(&MmpPostponedTlsLock); + + MmpPostponedTlsList->~vector(); + HeapFree(RtlProcessHeap(), 0, MmpPostponedTlsList); + MmpPostponedTlsList = nullptr; + + CloseHandle(MmpPostponedTlsEvent); + + LeaveCriticalSection(&MmpPostponedTlsLock); +} + VOID MmpTlsFiberInitialize() { InitializeCriticalSection(&MmpPostponedTlsLock); MmpPostponedTlsEvent = CreateEvent(nullptr, FALSE, FALSE, nullptr); MmpPostponedTlsList = new(HeapAlloc(GetProcessHeap(), 0, sizeof(std::vector))) std::vector(); + + atexit(OnExit); CreateThread(nullptr, 0, MmpReleasePostponedTlsWorker_Wrap, nullptr, 0, nullptr); } diff --git a/test/test.cpp b/test/test.cpp index 98d5b49c..2345189a 100644 --- a/test/test.cpp +++ b/test/test.cpp @@ -62,62 +62,79 @@ PVOID ReadDllFile2(LPCSTR FileName) { return nullptr; } -#define LIBRARY_PATH "\\\\DESKTOP-1145141919810\\Debug\\" +int test() { + LPVOID buffer = ReadDllFile2("a.vmp.dll"); + + 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(&hModule, nullptr, 0, buffer, 0, L"kernel64", nullptr))) goto end; -HMODULE WINAPI MyLoadLibrary(LPCSTR lpModuleName) { - HMODULE hModule; - PVOID buffer; + //forward export + pfn = (decltype(pfn))(GetProcAddress(hModule, "Socket")); //ws2_32.WSASocketW + pfn = (decltype(pfn))(GetProcAddress(hModule, "VerifyTruse")); //wintrust.WinVerifyTrust - if (0 == _stricmp(lpModuleName, "CTestClassLibrary1.dll")) { - buffer = ReadDllFile(LIBRARY_PATH"CTestClassLibrary1.dll"); + //exception + exception = (_exception)GetProcAddress(hModule, "exception"); + if (exception) { + for (int i = 0; i < 5; ++i)exception(i); } - else if (0 == _stricmp(lpModuleName, "CTestClassLibrary2.dll")) { - buffer = ReadDllFile(LIBRARY_PATH"CTestClassLibrary2.dll"); + + //tls + pfn = GetProcAddress(hModule, "thread"); + if (pfn && pfn()) { + printf("thread test failed.\n"); } - else if (0 == _stricmp(lpModuleName, "CTestClassLibrary1Dep.dll")) { - buffer = ReadDllFile(LIBRARY_PATH"CTestClassLibrary1Dep.dll"); + + //resource + if (!LoadStringA(hModule, 101, str, 10)) { + printf("load string failed.\n"); } else { - return nullptr; + printf("%s\n", str); } - - hModule = LoadLibraryMemoryExA(buffer, 0, lpModuleName, nullptr, 0); - delete[]buffer; - return hModule; -} - -VOID TestImportTableResolver() { - - // - // Register the import table resolver. - // - HANDLE hResolver = MmRegisterImportTableResolver(MyLoadLibrary, FreeLibraryMemory); - - // - // |-> CTestClassLibrary1.dll -> CTestClassLibrary1Dep.dll - // CTestClient.dll -| - // |-> CTestClassLibrary2.dll - // - - PVOID Client = ReadDllFile2("CTestClient.dll"); - HMODULE hm = LoadLibraryMemoryEx(Client, 0, TEXT("CTestClient.dll"), nullptr, 0); - delete[]Client; - - if (hm) { - auto pfn = GetProcAddress(hm, "TestProc"); - if (pfn) { - pfn(); + 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"); + } + } } - - FreeLibraryMemory(hm); } - MmRemoveImportTableResolver(hResolver); +end: + LdrUnloadDllMemory(hModule); + delete[]buffer; + return 0; } int main() { DisplayStatus(); - TestImportTableResolver(); + test(); return 0; } From 2aa3cf99c8532ff46d0f8f654eb852f49819e05f Mon Sep 17 00:00:00 2001 From: Boring <1079299053@qq.com> Date: Sun, 17 Dec 2023 15:08:33 +0800 Subject: [PATCH 03/17] Reflective initialization in release configuration --- MemoryModule/Initialize.cpp | 6 ++-- MemoryModule/Loader.h | 2 +- MemoryModule/MemoryModule.vcxproj | 16 ++++----- test/test.cpp | 57 ++++++++++++++++++++++++------- test/test.vcxproj | 5 --- 5 files changed, 58 insertions(+), 28 deletions(-) diff --git a/MemoryModule/Initialize.cpp b/MemoryModule/Initialize.cpp index 86f4d0db..42da0ba5 100644 --- a/MemoryModule/Initialize.cpp +++ b/MemoryModule/Initialize.cpp @@ -1,7 +1,7 @@ #include "stdafx.h" #include "LoaderPrivate.h" #include -#include +#include PMMP_GLOBAL_DATA MmpGlobalDataPtr; @@ -544,7 +544,9 @@ BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReser if (ul_reason_for_call == DLL_PROCESS_ATTACH) { if (NT_SUCCESS(Initialize())) { if (lpReserved == (PVOID)-1) { - assert(ReflectiveMapDll(hModule)); + if (!ReflectiveMapDll(hModule)) { + RtlRaiseStatus(STATUS_NOT_SUPPORTED); + } } return TRUE; diff --git a/MemoryModule/Loader.h b/MemoryModule/Loader.h index 9ce45eda..310ab6a1 100644 --- a/MemoryModule/Loader.h +++ b/MemoryModule/Loader.h @@ -61,7 +61,7 @@ NTSTATUS NTAPI LdrLoadDllMemoryExW( //Unload modules previously loaded from memory NTSTATUS NTAPI LdrUnloadDllMemory(_In_ HMEMORYMODULE BaseAddress); -#ifndef _USRDLL +#if (!defined(_USRDLL) && defined(_MEMORY_MODULE)) #ifdef _WIN64 #pragma comment(linker,"/export:LdrUnloadDllMemoryAndExitThread") #pragma comment(linker,"/export:FreeLibraryMemoryAndExitThread=LdrUnloadDllMemoryAndExitThread") diff --git a/MemoryModule/MemoryModule.vcxproj b/MemoryModule/MemoryModule.vcxproj index b152c6d4..51b0ac39 100644 --- a/MemoryModule/MemoryModule.vcxproj +++ b/MemoryModule/MemoryModule.vcxproj @@ -265,7 +265,7 @@ NotUsing Level3 true - WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) + _MEMORY_MODULE;WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) true @@ -283,7 +283,7 @@ NotUsing Level3 true - WIN32;_DEBUG;_USRDLL;%(PreprocessorDefinitions) + _MEMORY_MODULE;WIN32;_DEBUG;_USRDLL;%(PreprocessorDefinitions) true @@ -302,7 +302,7 @@ NotUsing Level3 true - _DEBUG;_LIB;%(PreprocessorDefinitions) + _MEMORY_MODULE;_DEBUG;_LIB;%(PreprocessorDefinitions) true @@ -320,7 +320,7 @@ NotUsing Level3 true - _DEBUG;_USRDLL;%(PreprocessorDefinitions) + _MEMORY_MODULE;_DEBUG;_USRDLL;%(PreprocessorDefinitions) true @@ -341,7 +341,7 @@ true true true - WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) + _MEMORY_MODULE;WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) true @@ -363,7 +363,7 @@ true true true - WIN32;NDEBUG;_USRDLL;%(PreprocessorDefinitions) + _MEMORY_MODULE;WIN32;NDEBUG;_USRDLL;%(PreprocessorDefinitions) true @@ -386,7 +386,7 @@ true true true - NDEBUG;_LIB;%(PreprocessorDefinitions) + _MEMORY_MODULE;NDEBUG;_LIB;%(PreprocessorDefinitions) true @@ -408,7 +408,7 @@ true true true - NDEBUG;_USRDLL;%(PreprocessorDefinitions) + _MEMORY_MODULE;NDEBUG;_USRDLL;%(PreprocessorDefinitions) true diff --git a/test/test.cpp b/test/test.cpp index 2345189a..09b68f08 100644 --- a/test/test.cpp +++ b/test/test.cpp @@ -1,8 +1,12 @@ #include "../MemoryModule/stdafx.h" #include "../MemoryModule/LoadDllMemoryApi.h" #include +#pragma comment(lib,"ntdll.lib") -//PMMP_GLOBAL_DATA MmpGlobalDataPtr = *(PMMP_GLOBAL_DATA*)GetProcAddress(GetModuleHandleA("MemoryModule.dll"), "MmpGlobalDataPtr"); +PMMP_GLOBAL_DATA MmpGlobalDataPtr; + +decltype(&LdrLoadDllMemoryExW)__LdrLoadDllMemoryExW; +decltype(&LdrUnloadDllMemory)__LdrUnloadDllMemory; static void DisplayStatus() { printf( @@ -41,7 +45,10 @@ static PVOID ReadDllFile(LPCSTR FileName) { return 0; } _fseeki64(f, 0, SEEK_SET); - fread(buffer = new char[size], 1, size, f); + + buffer = VirtualAlloc(0, size, MEM_COMMIT, PAGE_EXECUTE_READWRITE); + + fread(buffer, 1, size, f); fclose(f); return buffer; } @@ -63,11 +70,10 @@ PVOID ReadDllFile2(LPCSTR FileName) { } int test() { - LPVOID buffer = ReadDllFile2("a.vmp.dll"); + LPVOID buffer = ReadDllFile2("a.dll"); HMODULE hModule = nullptr; FARPROC pfn = nullptr; - DWORD MemoryModuleFeatures = 0; typedef int(*_exception)(int code); _exception exception = nullptr; @@ -76,12 +82,7 @@ int test() { 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(&hModule, nullptr, 0, buffer, 0, L"kernel64", nullptr))) goto end; + if (!NT_SUCCESS(__LdrLoadDllMemoryExW(&hModule, nullptr, 0, buffer, 0, L"kernel64", nullptr))) goto end; //forward export pfn = (decltype(pfn))(GetProcAddress(hModule, "Socket")); //ws2_32.WSASocketW @@ -127,12 +128,44 @@ int test() { } end: - LdrUnloadDllMemory(hModule); - delete[]buffer; + __LdrUnloadDllMemory(hModule); + VirtualFree(buffer, 0, MEM_RELEASE); return 0; } +ULONG_PTR ReflectiveLoaderOffset() { + ULONG_PTR offset = 0; + + auto hm = LoadLibrary(L"MemoryModule.dll"); + if (hm) { + auto pfn = GetProcAddress(hm, "ReflectiveLoader"); + offset = ULONG_PTR(pfn) - ULONG_PTR(hm); + + auto header = RtlImageNtHeader(hm); + auto section = IMAGE_FIRST_SECTION(header); + for (int i = 0; i < header->FileHeader.NumberOfSections; ++i, ++section) { + if (offset >= section->VirtualAddress && offset < section->VirtualAddress + section->SizeOfRawData) { + offset = ULONG_PTR(pfn) - (ULONG_PTR(hm) + section->VirtualAddress) + section->PointerToRawData; + break; + } + } + } + + return offset; +} + +typedef ULONG_PTR(WINAPI* LOADER)(PVOID); + int main() { + printf("%08x\n", ReflectiveLoaderOffset()); + auto buffer = ReadDllFile2("MemoryModule.dll"); + auto loader = LOADER(ULONG_PTR(buffer) + 0x96e0); //ReflectiveLoaderOffset() -> 0x96e0 + auto hm = (HMODULE)loader(buffer); + + MmpGlobalDataPtr = *(PMMP_GLOBAL_DATA*)GetProcAddress(hm, "MmpGlobalDataPtr"); + __LdrLoadDllMemoryExW = (decltype(&LdrLoadDllMemoryExW))GetProcAddress(hm, "LdrLoadDllMemoryExW"); + __LdrUnloadDllMemory = (decltype(&LdrUnloadDllMemory))GetProcAddress(hm, "LdrUnloadDllMemory"); + DisplayStatus(); test(); diff --git a/test/test.vcxproj b/test/test.vcxproj index e0883c90..f6c4203e 100644 --- a/test/test.vcxproj +++ b/test/test.vcxproj @@ -164,11 +164,6 @@ - - - {5b1f46db-036e-4a50-af5f-f5d6584d42c6} - - From a6c494a0d119d5001533f8714051533b915e7e7b Mon Sep 17 00:00:00 2001 From: Boring <1079299053@qq.com> Date: Thu, 4 Jan 2024 14:54:25 +0800 Subject: [PATCH 04/17] #39 Add ARM and ARM64 configuration. --- .gitignore | 3 +- MemoryModule/Loader.cpp | 10 + MemoryModule/Loader.h | 10 - MemoryModule/MemoryModule.cpp | 6 +- MemoryModule/MemoryModule.vcxproj | 322 ++++++++++++++++++++++++++++++ MemoryModule/MmpGlobalData.h | 2 +- MemoryModule/MmpTls.cpp | 4 +- MemoryModule/ReflectiveLoader.c | 2 +- MemoryModulePP.sln | 32 ++- a/a.vcxproj | 166 ++++++++++++++- a/a.vcxproj.filters | 6 - a/load.cpp | 51 ----- a/m.def | 2 - a/unhandled_exception.cpp | 49 ----- test/test.cpp | 41 +--- test/test.vcxproj | 149 ++++++++++++++ 16 files changed, 684 insertions(+), 171 deletions(-) delete mode 100644 a/load.cpp delete mode 100644 a/unhandled_exception.cpp diff --git a/.gitignore b/.gitignore index 8173ee7f..f0e7d6de 100644 --- a/.gitignore +++ b/.gitignore @@ -338,4 +338,5 @@ ASALocalRun/ # BeatPulse healthcheck temp database healthchecksdb -/test/a.dll \ No newline at end of file +/test/a.dll +/MemoryModule/DebugDll diff --git a/MemoryModule/Loader.cpp b/MemoryModule/Loader.cpp index a3f2a130..73eb5ffe 100644 --- a/MemoryModule/Loader.cpp +++ b/MemoryModule/Loader.cpp @@ -1,6 +1,16 @@ #include "stdafx.h" #include +#ifdef _USRDLL +#if (defined(_WIN64) || defined(_M_ARM)) +#pragma comment(linker,"/export:LdrUnloadDllMemoryAndExitThread") +#pragma comment(linker,"/export:FreeLibraryMemoryAndExitThread=LdrUnloadDllMemoryAndExitThread") +#else +#pragma comment(linker,"/export:LdrUnloadDllMemoryAndExitThread=_LdrUnloadDllMemoryAndExitThread@8") +#pragma comment(linker,"/export:FreeLibraryMemoryAndExitThread=_LdrUnloadDllMemoryAndExitThread@8") +#endif +#endif + NTSTATUS NTAPI LdrMapDllMemory( _In_ HMEMORYMODULE ViewBase, _In_ DWORD dwFlags, diff --git a/MemoryModule/Loader.h b/MemoryModule/Loader.h index 310ab6a1..8bdce287 100644 --- a/MemoryModule/Loader.h +++ b/MemoryModule/Loader.h @@ -61,16 +61,6 @@ NTSTATUS NTAPI LdrLoadDllMemoryExW( //Unload modules previously loaded from memory NTSTATUS NTAPI LdrUnloadDllMemory(_In_ HMEMORYMODULE BaseAddress); -#if (!defined(_USRDLL) && defined(_MEMORY_MODULE)) -#ifdef _WIN64 -#pragma comment(linker,"/export:LdrUnloadDllMemoryAndExitThread") -#pragma comment(linker,"/export:FreeLibraryMemoryAndExitThread=LdrUnloadDllMemoryAndExitThread") -#else -#pragma comment(linker,"/export:LdrUnloadDllMemoryAndExitThread=_LdrUnloadDllMemoryAndExitThread@8") -#pragma comment(linker,"/export:FreeLibraryMemoryAndExitThread=_LdrUnloadDllMemoryAndExitThread@8") -#endif -#endif - extern "C" { __declspec(noreturn) VOID NTAPI LdrUnloadDllMemoryAndExitThread( _In_ HMEMORYMODULE BaseAddress, diff --git a/MemoryModule/MemoryModule.cpp b/MemoryModule/MemoryModule.cpp index 166d9421..32ff600c 100644 --- a/MemoryModule/MemoryModule.cpp +++ b/MemoryModule/MemoryModule.cpp @@ -1,6 +1,10 @@ #include "stdafx.h" -#ifdef _WIN64 +#if defined(_M_ARM64) +#define HOST_MACHINE IMAGE_FILE_MACHINE_ARM64 +#elif defined(_M_ARM) +#define HOST_MACHINE IMAGE_FILE_MACHINE_ARM +#elif defined(_WIN64) #define HOST_MACHINE IMAGE_FILE_MACHINE_AMD64 #else #define HOST_MACHINE IMAGE_FILE_MACHINE_I386 diff --git a/MemoryModule/MemoryModule.vcxproj b/MemoryModule/MemoryModule.vcxproj index 51b0ac39..5ea04bc9 100644 --- a/MemoryModule/MemoryModule.vcxproj +++ b/MemoryModule/MemoryModule.vcxproj @@ -1,6 +1,14 @@ + + DebugDll + ARM + + + DebugDll + ARM64 + DebugDll Win32 @@ -9,10 +17,26 @@ DebugDll x64 + + Debug + ARM + + + Debug + ARM64 + Debug Win32 + + ReleaseDll + ARM + + + ReleaseDll + ARM64 + ReleaseDll Win32 @@ -21,6 +45,14 @@ ReleaseDll x64 + + Release + ARM + + + Release + ARM64 + Release Win32 @@ -59,17 +91,29 @@ false + false false + false false + false false + false false + false false + false false + false false + false false + false false + false false + false false + false @@ -144,12 +188,24 @@ v142 Unicode + + StaticLibrary + true + v142 + Unicode + DynamicLibrary true v142 Unicode + + DynamicLibrary + true + v142 + Unicode + StaticLibrary false @@ -157,6 +213,13 @@ true Unicode + + StaticLibrary + false + v142 + true + Unicode + DynamicLibrary false @@ -164,6 +227,13 @@ true Unicode + + DynamicLibrary + false + v142 + true + Unicode + StaticLibrary true @@ -171,6 +241,13 @@ Unicode false + + StaticLibrary + true + v142 + Unicode + false + DynamicLibrary true @@ -178,6 +255,13 @@ Unicode false + + DynamicLibrary + true + v142 + Unicode + false + StaticLibrary false @@ -185,6 +269,13 @@ true Unicode + + StaticLibrary + false + v142 + true + Unicode + DynamicLibrary false @@ -192,6 +283,13 @@ true Unicode + + DynamicLibrary + false + v142 + true + Unicode + @@ -201,65 +299,121 @@ + + + + + + + + + + + + + + + + + + + + + + + + true $(VC_IncludePath);$(WindowsSDK_IncludePath);$(SolutionDir); $(SolutionDir)$(Configuration)\ + + true + $(VC_IncludePath);$(WindowsSDK_IncludePath);$(SolutionDir); + true $(VC_IncludePath);$(WindowsSDK_IncludePath);$(SolutionDir); $(SolutionDir)Debug\ + + true + $(VC_IncludePath);$(WindowsSDK_IncludePath);$(SolutionDir); + true $(VC_IncludePath);$(WindowsSDK_IncludePath);$(SolutionDir); + + true + $(VC_IncludePath);$(WindowsSDK_IncludePath);$(SolutionDir); + true $(VC_IncludePath);$(WindowsSDK_IncludePath);$(SolutionDir); $(SolutionDir)$(Platform)\Debug\ + + true + $(VC_IncludePath);$(WindowsSDK_IncludePath);$(SolutionDir); + false $(VC_IncludePath);$(WindowsSDK_IncludePath);$(SolutionDir); + + 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); + + false + $(VC_IncludePath);$(WindowsSDK_IncludePath);$(SolutionDir); + false $(VC_IncludePath);$(WindowsSDK_IncludePath);$(SolutionDir); $(SolutionDir)$(Platform)\Release\ + + false + $(VC_IncludePath);$(WindowsSDK_IncludePath);$(SolutionDir); + NotUsing @@ -278,6 +432,25 @@ MemoryModulePP.def + + + NotUsing + Level3 + true + _MEMORY_MODULE;WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) + true + + + + + MultiThreadedDebug + + + Windows + true + MemoryModulePP.def + + NotUsing @@ -297,6 +470,25 @@ MemoryModulePP.def + + + NotUsing + Level3 + true + _MEMORY_MODULE;WIN32;_DEBUG;_USRDLL;%(PreprocessorDefinitions) + true + + + + + MultiThreadedDebug + + + Windows + true + MemoryModulePP.def + + NotUsing @@ -315,6 +507,25 @@ MemoryModulePP.def + + + NotUsing + Level3 + true + _MEMORY_MODULE;_DEBUG;_LIB;%(PreprocessorDefinitions) + true + + + + + MultiThreadedDebug + + + Windows + true + MemoryModulePP.def + + NotUsing @@ -334,6 +545,25 @@ MemoryModulePP.def + + + NotUsing + Level3 + true + _MEMORY_MODULE;_DEBUG;_USRDLL;%(PreprocessorDefinitions) + true + + + + + MultiThreadedDebug + + + Windows + true + MemoryModulePP.def + + NotUsing @@ -356,6 +586,29 @@ MemoryModulePP.def + + + NotUsing + Level3 + true + true + true + _MEMORY_MODULE;WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) + true + + + + + MultiThreaded + + + Windows + true + true + true + MemoryModulePP.def + + NotUsing @@ -379,6 +632,29 @@ MemoryModulePP.def + + + NotUsing + Level3 + true + true + true + _MEMORY_MODULE;WIN32;NDEBUG;_USRDLL;%(PreprocessorDefinitions) + true + + + + + MultiThreaded + + + Windows + true + true + true + MemoryModulePP.def + + NotUsing @@ -401,6 +677,29 @@ MemoryModulePP.def + + + NotUsing + Level3 + true + true + true + _MEMORY_MODULE;NDEBUG;_LIB;%(PreprocessorDefinitions) + true + + + + + MultiThreaded + + + Windows + true + true + true + MemoryModulePP.def + + NotUsing @@ -424,6 +723,29 @@ MemoryModulePP.def + + + NotUsing + Level3 + true + true + true + _MEMORY_MODULE;NDEBUG;_USRDLL;%(PreprocessorDefinitions) + true + + + + + MultiThreaded + + + Windows + true + true + true + MemoryModulePP.def + + diff --git a/MemoryModule/MmpGlobalData.h b/MemoryModule/MmpGlobalData.h index 2f73ddf7..e4530a2d 100644 --- a/MemoryModule/MmpGlobalData.h +++ b/MemoryModule/MmpGlobalData.h @@ -100,7 +100,7 @@ typedef enum class _WINDOWS_VERSION :BYTE { #define MEMORY_MODULE_GET_MINOR_VERSION(MinorVersion) (~0x8000&(MinorVersion)) #define MEMORY_MODULE_MAJOR_VERSION 2 -#define MEMORY_MODULE_MINOR_VERSION 0 +#define MEMORY_MODULE_MINOR_VERSION MEMORY_MODULE_MAKE_PREVIEW(1) typedef struct _MMP_GLOBAL_DATA { diff --git a/MemoryModule/MmpTls.cpp b/MemoryModule/MmpTls.cpp index 112847a3..b2cd34b0 100644 --- a/MemoryModule/MmpTls.cpp +++ b/MemoryModule/MmpTls.cpp @@ -231,7 +231,7 @@ DWORD NTAPI MmpUserThreadStart(LPVOID lpThreadParameter) { return Context.ThreadStartRoutine(Context.ThreadParameter); } -#ifdef _WIN64 +#if (defined(_WIN64) || defined(_M_ARM)) VOID NTAPI HookRtlUserThreadStart( _In_ PTHREAD_START_ROUTINE Function, _In_ PVOID Parameter) { @@ -256,7 +256,7 @@ HookRtlUserThreadStart( // Context.ThreadParameter = Parameter; mov dword ptr ds : [esp + 4] , ebx; - + mov eax, MmpUserThreadStart; mov ebx, esp; diff --git a/MemoryModule/ReflectiveLoader.c b/MemoryModule/ReflectiveLoader.c index 7044911b..7845adcc 100644 --- a/MemoryModule/ReflectiveLoader.c +++ b/MemoryModule/ReflectiveLoader.c @@ -1,4 +1,4 @@ -#ifdef _USRDLL +#if !(defined(_M_ARM) || defined(_M_ARM64) || defined(_USRDLL)) //===============================================================================================// // Copyright (c) 2012, Stephen Fewer of Harmony Security (www.harmonysecurity.com) diff --git a/MemoryModulePP.sln b/MemoryModulePP.sln index 0b985a5c..3df6af94 100644 --- a/MemoryModulePP.sln +++ b/MemoryModulePP.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 16 -VisualStudioVersion = 16.0.29709.97 +# Visual Studio Version 17 +VisualStudioVersion = 17.7.34202.233 MinimumVisualStudioVersion = 10.0.40219.1 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MemoryModule", "MemoryModule\MemoryModule.vcxproj", "{5B1F46DB-036E-4A50-AF5F-F5D6584D42C6}" EndProject @@ -11,34 +11,62 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "a", "a\a.vcxproj", "{DA79C6 EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|ARM = Debug|ARM + Debug|ARM64 = Debug|ARM64 Debug|x64 = Debug|x64 Debug|x86 = Debug|x86 + Release|ARM = Release|ARM + Release|ARM64 = Release|ARM64 Release|x64 = Release|x64 Release|x86 = Release|x86 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution + {5B1F46DB-036E-4A50-AF5F-F5D6584D42C6}.Debug|ARM.ActiveCfg = Debug|ARM + {5B1F46DB-036E-4A50-AF5F-F5D6584D42C6}.Debug|ARM.Build.0 = Debug|ARM + {5B1F46DB-036E-4A50-AF5F-F5D6584D42C6}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {5B1F46DB-036E-4A50-AF5F-F5D6584D42C6}.Debug|ARM64.Build.0 = Debug|ARM64 {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|ARM.ActiveCfg = Release|ARM + {5B1F46DB-036E-4A50-AF5F-F5D6584D42C6}.Release|ARM.Build.0 = Release|ARM + {5B1F46DB-036E-4A50-AF5F-F5D6584D42C6}.Release|ARM64.ActiveCfg = Release|ARM64 + {5B1F46DB-036E-4A50-AF5F-F5D6584D42C6}.Release|ARM64.Build.0 = Release|ARM64 {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 + {5B3131BA-178A-4A28-BD54-315A45C97ED1}.Debug|ARM.ActiveCfg = Debug|ARM + {5B3131BA-178A-4A28-BD54-315A45C97ED1}.Debug|ARM.Build.0 = Debug|ARM + {5B3131BA-178A-4A28-BD54-315A45C97ED1}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {5B3131BA-178A-4A28-BD54-315A45C97ED1}.Debug|ARM64.Build.0 = Debug|ARM64 {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 {5B3131BA-178A-4A28-BD54-315A45C97ED1}.Debug|x86.ActiveCfg = Debug|Win32 {5B3131BA-178A-4A28-BD54-315A45C97ED1}.Debug|x86.Build.0 = Debug|Win32 {5B3131BA-178A-4A28-BD54-315A45C97ED1}.Debug|x86.Deploy.0 = Debug|Win32 + {5B3131BA-178A-4A28-BD54-315A45C97ED1}.Release|ARM.ActiveCfg = Release|ARM + {5B3131BA-178A-4A28-BD54-315A45C97ED1}.Release|ARM.Build.0 = Release|ARM + {5B3131BA-178A-4A28-BD54-315A45C97ED1}.Release|ARM64.ActiveCfg = Release|ARM64 + {5B3131BA-178A-4A28-BD54-315A45C97ED1}.Release|ARM64.Build.0 = Release|ARM64 {5B3131BA-178A-4A28-BD54-315A45C97ED1}.Release|x64.ActiveCfg = Release|x64 {5B3131BA-178A-4A28-BD54-315A45C97ED1}.Release|x64.Build.0 = Release|x64 {5B3131BA-178A-4A28-BD54-315A45C97ED1}.Release|x86.ActiveCfg = Release|Win32 {5B3131BA-178A-4A28-BD54-315A45C97ED1}.Release|x86.Build.0 = Release|Win32 + {DA79C619-BDAC-4CF1-A38C-B1F5E05F4485}.Debug|ARM.ActiveCfg = Debug|ARM + {DA79C619-BDAC-4CF1-A38C-B1F5E05F4485}.Debug|ARM.Build.0 = Debug|ARM + {DA79C619-BDAC-4CF1-A38C-B1F5E05F4485}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {DA79C619-BDAC-4CF1-A38C-B1F5E05F4485}.Debug|ARM64.Build.0 = Debug|ARM64 {DA79C619-BDAC-4CF1-A38C-B1F5E05F4485}.Debug|x64.ActiveCfg = Debug|x64 {DA79C619-BDAC-4CF1-A38C-B1F5E05F4485}.Debug|x64.Build.0 = Debug|x64 {DA79C619-BDAC-4CF1-A38C-B1F5E05F4485}.Debug|x86.ActiveCfg = Debug|Win32 {DA79C619-BDAC-4CF1-A38C-B1F5E05F4485}.Debug|x86.Build.0 = Debug|Win32 + {DA79C619-BDAC-4CF1-A38C-B1F5E05F4485}.Release|ARM.ActiveCfg = Release|ARM + {DA79C619-BDAC-4CF1-A38C-B1F5E05F4485}.Release|ARM.Build.0 = Release|ARM + {DA79C619-BDAC-4CF1-A38C-B1F5E05F4485}.Release|ARM64.ActiveCfg = Release|ARM64 + {DA79C619-BDAC-4CF1-A38C-B1F5E05F4485}.Release|ARM64.Build.0 = Release|ARM64 {DA79C619-BDAC-4CF1-A38C-B1F5E05F4485}.Release|x64.ActiveCfg = Release|x64 {DA79C619-BDAC-4CF1-A38C-B1F5E05F4485}.Release|x64.Build.0 = Release|x64 {DA79C619-BDAC-4CF1-A38C-B1F5E05F4485}.Release|x86.ActiveCfg = Release|Win32 diff --git a/a/a.vcxproj b/a/a.vcxproj index 2bdc7fc0..b157e902 100644 --- a/a/a.vcxproj +++ b/a/a.vcxproj @@ -1,10 +1,26 @@ + + Debug + ARM + + + Debug + ARM64 + Debug Win32 + + Release + ARM + + + Release + ARM64 + Release Win32 @@ -33,6 +49,13 @@ Unicode false + + DynamicLibrary + true + v142 + Unicode + false + DynamicLibrary false @@ -40,12 +63,25 @@ true Unicode + + DynamicLibrary + false + v142 + true + Unicode + DynamicLibrary true v142 Unicode + + DynamicLibrary + true + v142 + Unicode + DynamicLibrary false @@ -53,6 +89,13 @@ true Unicode + + DynamicLibrary + false + v142 + true + Unicode + @@ -61,28 +104,52 @@ + + + + + + + + + + + + true + + true + true + + true + false + + false + false + + false + NotUsing @@ -104,6 +171,29 @@ true + + + NotUsing + Level3 + true + WIN32;_DEBUG;A_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + true + + + MultiThreadedDebug + + + Sync + + + Windows + true + false + m.def + + + + NotUsing @@ -123,6 +213,26 @@ m.def + + + NotUsing + Level3 + true + _DEBUG;A_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + true + + + MultiThreadedDebug + + + + + Windows + true + false + m.def + + NotUsing @@ -146,6 +256,30 @@ m.def + + + NotUsing + Level3 + true + true + true + WIN32;NDEBUG;A_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + true + + + MultiThreaded + + + + + Windows + true + true + true + false + m.def + + NotUsing @@ -170,13 +304,36 @@ m.def + + + NotUsing + Level3 + true + true + true + NDEBUG;A_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + true + + + MultiThreaded + Sync + + + + + Windows + true + true + true + false + m.def + + - - @@ -188,11 +345,6 @@ - - - {5b1f46db-036e-4a50-af5f-f5d6584d42c6} - - diff --git a/a/a.vcxproj.filters b/a/a.vcxproj.filters index 3cd8839c..6239210a 100644 --- a/a/a.vcxproj.filters +++ b/a/a.vcxproj.filters @@ -18,18 +18,12 @@ Source Files - - Source Files - Source Files Source Files - - Source Files - Source Files diff --git a/a/load.cpp b/a/load.cpp deleted file mode 100644 index 72babcbe..00000000 --- a/a/load.cpp +++ /dev/null @@ -1,51 +0,0 @@ -#include "../MemoryModule/stdafx.h" -#include - -static PVOID ReadDllFile(LPCSTR FileName) { - LPVOID buffer; - size_t size; - FILE* f; - fopen_s(&f, 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 545acdc0..95aaa7bb 100644 --- a/a/m.def +++ b/a/m.def @@ -4,6 +4,4 @@ test = __test__ thread Socket = ws2_32.WSASocketW VerifyTruse = wintrust.WinVerifyTrust -test_user32 -unhandled_exception GdiplusTest \ No newline at end of file diff --git a/a/unhandled_exception.cpp b/a/unhandled_exception.cpp deleted file mode 100644 index f442ed2a..00000000 --- a/a/unhandled_exception.cpp +++ /dev/null @@ -1,49 +0,0 @@ -#include -#include - -#ifdef _WIN64 -DWORD Value; -volatile LPDWORD lpAddr; - -LONG WINAPI Filter(_In_ struct _EXCEPTION_POINTERS* ExceptionInfo) { - - if (ExceptionInfo->ExceptionRecord->ExceptionCode == STATUS_ACCESS_VIOLATION) { - - lpAddr = &Value; - - // +++++++ - // begin compiler specific - // +++++++ - - //ExceptionInfo->ContextRecord->Rip -= 7; - ExceptionInfo->ContextRecord->Rax = (ULONG_PTR)lpAddr; - - // +++++++ - // end compiler specific - // +++++++ - - return EXCEPTION_CONTINUE_EXECUTION; - } - - return EXCEPTION_CONTINUE_SEARCH; -} -#endif - -int unhandled_exception() { -#ifdef _WIN64 - auto filter = SetUnhandledExceptionFilter(Filter); - auto ff = SetUnhandledExceptionFilter(filter); - - if (ff != Filter) { - printf("%p\t%p\t%p\nfailed\n", filter, ff, Filter); - return 0; - } - - filter = SetUnhandledExceptionFilter(Filter); - lpAddr = nullptr; - *lpAddr = 1; - SetUnhandledExceptionFilter(filter); -#endif - - return 1234; -} diff --git a/test/test.cpp b/test/test.cpp index 09b68f08..3ea4e308 100644 --- a/test/test.cpp +++ b/test/test.cpp @@ -3,11 +3,6 @@ #include #pragma comment(lib,"ntdll.lib") -PMMP_GLOBAL_DATA MmpGlobalDataPtr; - -decltype(&LdrLoadDllMemoryExW)__LdrLoadDllMemoryExW; -decltype(&LdrUnloadDllMemory)__LdrUnloadDllMemory; - static void DisplayStatus() { printf( "\ @@ -82,7 +77,7 @@ int test() { HGLOBAL gRes; char str[10]; - if (!NT_SUCCESS(__LdrLoadDllMemoryExW(&hModule, nullptr, 0, buffer, 0, L"kernel64", nullptr))) goto end; + if (!NT_SUCCESS(LdrLoadDllMemoryExW(&hModule, nullptr, 0, buffer, 0, L"kernel64", nullptr))) goto end; //forward export pfn = (decltype(pfn))(GetProcAddress(hModule, "Socket")); //ws2_32.WSASocketW @@ -128,45 +123,15 @@ int test() { } end: - __LdrUnloadDllMemory(hModule); + LdrUnloadDllMemory(hModule); VirtualFree(buffer, 0, MEM_RELEASE); return 0; } -ULONG_PTR ReflectiveLoaderOffset() { - ULONG_PTR offset = 0; - - auto hm = LoadLibrary(L"MemoryModule.dll"); - if (hm) { - auto pfn = GetProcAddress(hm, "ReflectiveLoader"); - offset = ULONG_PTR(pfn) - ULONG_PTR(hm); - - auto header = RtlImageNtHeader(hm); - auto section = IMAGE_FIRST_SECTION(header); - for (int i = 0; i < header->FileHeader.NumberOfSections; ++i, ++section) { - if (offset >= section->VirtualAddress && offset < section->VirtualAddress + section->SizeOfRawData) { - offset = ULONG_PTR(pfn) - (ULONG_PTR(hm) + section->VirtualAddress) + section->PointerToRawData; - break; - } - } - } - - return offset; -} - -typedef ULONG_PTR(WINAPI* LOADER)(PVOID); - int main() { - printf("%08x\n", ReflectiveLoaderOffset()); - auto buffer = ReadDllFile2("MemoryModule.dll"); - auto loader = LOADER(ULONG_PTR(buffer) + 0x96e0); //ReflectiveLoaderOffset() -> 0x96e0 - auto hm = (HMODULE)loader(buffer); - - MmpGlobalDataPtr = *(PMMP_GLOBAL_DATA*)GetProcAddress(hm, "MmpGlobalDataPtr"); - __LdrLoadDllMemoryExW = (decltype(&LdrLoadDllMemoryExW))GetProcAddress(hm, "LdrLoadDllMemoryExW"); - __LdrUnloadDllMemory = (decltype(&LdrUnloadDllMemory))GetProcAddress(hm, "LdrUnloadDllMemory"); DisplayStatus(); + test(); return 0; diff --git a/test/test.vcxproj b/test/test.vcxproj index f6c4203e..a7616ce9 100644 --- a/test/test.vcxproj +++ b/test/test.vcxproj @@ -1,10 +1,26 @@ + + Debug + ARM + + + Debug + ARM64 + Debug Win32 + + Release + ARM + + + Release + ARM64 + Release Win32 @@ -32,6 +48,12 @@ v142 Unicode + + Application + true + v142 + Unicode + Application false @@ -39,12 +61,25 @@ true Unicode + + Application + false + v142 + true + Unicode + Application true v142 Unicode + + Application + true + v142 + Unicode + Application false @@ -52,6 +87,13 @@ true Unicode + + Application + false + v142 + true + Unicode + @@ -60,28 +102,52 @@ + + + + + + + + + + + + true + + true + true + + true + false + + false + false + + false + @@ -97,6 +163,21 @@ true + + + + + Level3 + true + _DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + MultiThreadedDebug + + + Console + true + + @@ -112,6 +193,21 @@ true + + + + + Level3 + true + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + MultiThreadedDebug + + + Console + true + + @@ -131,6 +227,25 @@ true + + + + + Level3 + true + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + MultiThreaded + + + Console + true + true + true + + @@ -152,18 +267,52 @@ + + + + + Level3 + true + true + true + NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + MultiThreaded + + + Console + true + true + true + + + + + + + + + + + + + + + {5b1f46db-036e-4a50-af5f-f5d6584d42c6} + + From 54cacf2bf74e4d6cc9a6a61199d2f03a35d183a1 Mon Sep 17 00:00:00 2001 From: Boring <1079299053@qq.com> Date: Mon, 15 Jan 2024 13:08:33 +0800 Subject: [PATCH 05/17] Update ProcessAttachCalled flag --- MemoryModule/LdrEntry.cpp | 4 +--- MemoryModule/Utils.cpp | 10 ++++++++++ 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/MemoryModule/LdrEntry.cpp b/MemoryModule/LdrEntry.cpp index c03d710c..a0e8fbfe 100644 --- a/MemoryModule/LdrEntry.cpp +++ b/MemoryModule/LdrEntry.cpp @@ -152,7 +152,7 @@ BOOL NTAPI RtlInitializeLdrDataTableEntry( if (IsWin8) ((_LDR_DDAG_NODE_WIN8*)(entry->DdagNode))->ReferenceCount = 1; entry->ImageDll = entry->LoadNotificationsSent = entry->EntryProcessed = entry->InLegacyLists = entry->InIndexes = true; - entry->ProcessAttachCalled = headers->OptionalHeader.AddressOfEntryPoint != 0; + entry->ProcessAttachCalled = false; entry->InExceptionTable = !(dwFlags & LOAD_FLAGS_NOT_ADD_INVERTED_FUNCTION); entry->CorImage = CorImage; entry->CorILOnly = CorIL; @@ -187,8 +187,6 @@ BOOL NTAPI RtlInitializeLdrDataTableEntry( if (!FlagsProcessed) { LdrEntry->Flags = LDRP_IMAGE_DLL | LDRP_ENTRY_INSERTED | LDRP_ENTRY_PROCESSED; - if (headers->OptionalHeader.AddressOfEntryPoint != 0)LdrEntry->Flags |= LDRP_PROCESS_ATTACH_CALLED; - if (CorImage)LdrEntry->Flags |= LDRP_COR_IMAGE; } InitializeListHead(&LdrEntry->HashLinks); diff --git a/MemoryModule/Utils.cpp b/MemoryModule/Utils.cpp index a150cf5a..3e4e4dac 100644 --- a/MemoryModule/Utils.cpp +++ b/MemoryModule/Utils.cpp @@ -140,6 +140,16 @@ BOOL NTAPI LdrpCallInitializers(PMEMORYMODULE module, DWORD dwReason) { // notify library about attaching to process if (((PLDR_INIT_ROUTINE)(module->codeBase + headers->OptionalHeader.AddressOfEntryPoint))((HINSTANCE)module->codeBase, dwReason, 0)) { module->initialized = TRUE; + + if (dwReason == DLL_PROCESS_ATTACH) { + if (MmpGlobalDataPtr->WindowsVersion <= WINDOWS_VERSION::winBlue) { + PLDR_DATA_TABLE_ENTRY_WINBLUE(module->LdrEntry)->ProcessAttachCalled = TRUE; + } + else { + PLDR_DATA_TABLE_ENTRY(module->LdrEntry)->Flags |= LDRP_PROCESS_ATTACH_CALLED; + } + } + return TRUE; } SetLastError(ERROR_DLL_INIT_FAILED); From b409e6d11b2873b07a2936ed67b890da6e1e2c8a Mon Sep 17 00:00:00 2001 From: Boring <1079299053@qq.com> Date: Tue, 16 Jan 2024 16:29:44 +0800 Subject: [PATCH 06/17] MmpTls --- MemoryModule/MmpTls.cpp | 45 +++++++++++++++++++++++++++++++++++------ 1 file changed, 39 insertions(+), 6 deletions(-) diff --git a/MemoryModule/MmpTls.cpp b/MemoryModule/MmpTls.cpp index b2cd34b0..da25f90d 100644 --- a/MemoryModule/MmpTls.cpp +++ b/MemoryModule/MmpTls.cpp @@ -109,11 +109,33 @@ DWORD NTAPI MmpGetThreadCount() { PMMP_TLSP_RECORD MmpFindTlspRecordLockHeld() { PLIST_ENTRY entry = MmpGlobalDataPtr->MmpTls->MmpThreadLocalStoragePointer.Flink; + PTEB teb = NtCurrentTeb(); + while (entry != &MmpGlobalDataPtr->MmpTls->MmpThreadLocalStoragePointer) { auto p = CONTAINING_RECORD(entry, MMP_TLSP_RECORD, InMmpThreadLocalStoragePointer); - if (p->UniqueThread == NtCurrentThreadId()) { - assert(p->TlspMmpBlock == NtCurrentTeb()->ThreadLocalStoragePointer); + + if (p->UniqueThread == NtCurrentProcess() && p->TlspLdrBlock == teb->ThreadLocalStoragePointer) { + PVOID cookie; + LdrLockLoaderLock(LDR_LOCK_LOADER_LOCK_FLAG_RAISE_ON_ERRORS, nullptr, &cookie); + + auto size = CONTAINING_RECORD(p->TlspLdrBlock, TLS_VECTOR, ModuleTlsData)->Length; + if ((HANDLE)(ULONG_PTR)size != NtCurrentThreadId()) { + RtlCopyMemory( + p->TlspMmpBlock, + p->TlspLdrBlock, + size * sizeof(PVOID) + ); + } + + teb->ThreadLocalStoragePointer = p->TlspMmpBlock; + p->UniqueThread = NtCurrentThreadId(); + + LdrUnlockLoaderLock(LDR_UNLOCK_LOADER_LOCK_FLAG_RAISE_ON_ERRORS, cookie); + return p; + } + else if (p->UniqueThread == NtCurrentThreadId()) { + assert(p->TlspMmpBlock == teb->ThreadLocalStoragePointer); return p; } @@ -520,11 +542,22 @@ NTSTATUS NTAPI HookNtSetInformationProcess( entry = entry->Flink; } - //assert(found); - if (found) { - ProcessTlsInformation->ThreadData[i].Flags = Tls->ThreadData[i].Flags; - ProcessTlsInformation->ThreadData[i].ThreadId = Tls->ThreadData[i].ThreadId; + ProcessTlsInformation->ThreadData[i].Flags = Tls->ThreadData[i].Flags; + ProcessTlsInformation->ThreadData[i].ThreadId = Tls->ThreadData[i].ThreadId; + + if (!found && Tls->ThreadData[i].Flags == 2) { + auto const& LdrTls = Tls->ThreadData[i]; + auto record = PMMP_TLSP_RECORD(RtlAllocateHeap(RtlProcessHeap(), 0, sizeof(MMP_TLSP_RECORD))); + assert(record); + + record->TlspLdrBlock = LdrTls.TlsVector; + record->TlspMmpBlock = (PVOID*)MmpAllocateTlsp(); + record->UniqueThread = NtCurrentProcess(); + + assert(record->TlspMmpBlock); + InsertTailList(&MmpGlobalDataPtr->MmpTls->MmpThreadLocalStoragePointer, &record->InMmpThreadLocalStoragePointer); } + } LeaveCriticalSection(&MmpGlobalDataPtr->MmpTls->MmpTlspLock); From 88425436e0dc2ec7445ae0fdacf02ca6929e418c Mon Sep 17 00:00:00 2001 From: Boring <1079299053@qq.com> Date: Tue, 16 Jan 2024 21:17:54 +0800 Subject: [PATCH 07/17] MmpTls #40 --- MemoryModule/MmpTls.cpp | 78 ++++++++++++++++------------------------- 1 file changed, 30 insertions(+), 48 deletions(-) diff --git a/MemoryModule/MmpTls.cpp b/MemoryModule/MmpTls.cpp index da25f90d..4bc0aa30 100644 --- a/MemoryModule/MmpTls.cpp +++ b/MemoryModule/MmpTls.cpp @@ -115,26 +115,7 @@ PMMP_TLSP_RECORD MmpFindTlspRecordLockHeld() { auto p = CONTAINING_RECORD(entry, MMP_TLSP_RECORD, InMmpThreadLocalStoragePointer); - if (p->UniqueThread == NtCurrentProcess() && p->TlspLdrBlock == teb->ThreadLocalStoragePointer) { - PVOID cookie; - LdrLockLoaderLock(LDR_LOCK_LOADER_LOCK_FLAG_RAISE_ON_ERRORS, nullptr, &cookie); - - auto size = CONTAINING_RECORD(p->TlspLdrBlock, TLS_VECTOR, ModuleTlsData)->Length; - if ((HANDLE)(ULONG_PTR)size != NtCurrentThreadId()) { - RtlCopyMemory( - p->TlspMmpBlock, - p->TlspLdrBlock, - size * sizeof(PVOID) - ); - } - - teb->ThreadLocalStoragePointer = p->TlspMmpBlock; - p->UniqueThread = NtCurrentThreadId(); - - LdrUnlockLoaderLock(LDR_UNLOCK_LOADER_LOCK_FLAG_RAISE_ON_ERRORS, cookie); - return p; - } - else if (p->UniqueThread == NtCurrentThreadId()) { + if (p->UniqueThread == NtCurrentThreadId()) { assert(p->TlspMmpBlock == teb->ThreadLocalStoragePointer); return p; } @@ -145,23 +126,10 @@ PMMP_TLSP_RECORD MmpFindTlspRecordLockHeld() { return nullptr; } -DWORD NTAPI MmpUserThreadStart(LPVOID lpThreadParameter) { - - THREAD_CONTEXT Context; +DWORD MmpAllocateTlsLockHeld() { bool success = false; PMMP_TLSP_RECORD record = nullptr; - __try { - RtlCopyMemory( - &Context, - lpThreadParameter, - sizeof(Context) - ); - } - __except (EXCEPTION_EXECUTE_HANDLER) { - return GetExceptionCode(); - } - if (!NtCurrentTeb()->ThreadLocalStoragePointer) { goto __skip_tls; } @@ -250,6 +218,34 @@ DWORD NTAPI MmpUserThreadStart(LPVOID lpThreadParameter) { InterlockedIncrement(&MmpGlobalDataPtr->MmpTls->MmpActiveThreadCount); __skip_tls: + return ERROR_SUCCESS; +} + +DWORD NTAPI MmpUserThreadStart(LPVOID lpThreadParameter) { + + THREAD_CONTEXT Context; + + __try { + RtlCopyMemory( + &Context, + lpThreadParameter, + sizeof(Context) + ); + } + __except (EXCEPTION_EXECUTE_HANDLER) { + return GetExceptionCode(); + } + + PVOID cookie; + LdrLockLoaderLock(LDR_LOCK_LOADER_LOCK_FLAG_RAISE_ON_ERRORS, nullptr, &cookie); + + __try { + MmpAllocateTlsLockHeld(); + } + __finally { + LdrUnlockLoaderLock(LDR_UNLOCK_LOADER_LOCK_FLAG_RAISE_ON_ERRORS, cookie); + } + return Context.ThreadStartRoutine(Context.ThreadParameter); } @@ -544,20 +540,6 @@ NTSTATUS NTAPI HookNtSetInformationProcess( ProcessTlsInformation->ThreadData[i].Flags = Tls->ThreadData[i].Flags; ProcessTlsInformation->ThreadData[i].ThreadId = Tls->ThreadData[i].ThreadId; - - if (!found && Tls->ThreadData[i].Flags == 2) { - auto const& LdrTls = Tls->ThreadData[i]; - auto record = PMMP_TLSP_RECORD(RtlAllocateHeap(RtlProcessHeap(), 0, sizeof(MMP_TLSP_RECORD))); - assert(record); - - record->TlspLdrBlock = LdrTls.TlsVector; - record->TlspMmpBlock = (PVOID*)MmpAllocateTlsp(); - record->UniqueThread = NtCurrentProcess(); - - assert(record->TlspMmpBlock); - InsertTailList(&MmpGlobalDataPtr->MmpTls->MmpThreadLocalStoragePointer, &record->InMmpThreadLocalStoragePointer); - } - } LeaveCriticalSection(&MmpGlobalDataPtr->MmpTls->MmpTlspLock); From f6f506a16185ec1147d6a6fdda859cebb1585631 Mon Sep 17 00:00:00 2001 From: Boring <1079299053@qq.com> Date: Tue, 6 Feb 2024 09:46:49 +0800 Subject: [PATCH 08/17] #43 Preprocessor directives for ReflectiveLoader --- MemoryModule/ReflectiveLoader.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MemoryModule/ReflectiveLoader.c b/MemoryModule/ReflectiveLoader.c index 7845adcc..a51750b7 100644 --- a/MemoryModule/ReflectiveLoader.c +++ b/MemoryModule/ReflectiveLoader.c @@ -1,4 +1,4 @@ -#if !(defined(_M_ARM) || defined(_M_ARM64) || defined(_USRDLL)) +#if !(defined(_M_ARM) || defined(_M_ARM64) || !defined(_USRDLL)) //===============================================================================================// // Copyright (c) 2012, Stephen Fewer of Harmony Security (www.harmonysecurity.com) From 6561a3b6d3a115badd65884efd69e14f6d7a4b9a Mon Sep 17 00:00:00 2001 From: Boring <1079299053@qq.com> Date: Mon, 19 Feb 2024 20:56:09 +0800 Subject: [PATCH 09/17] AlignValueUp #44 --- MemoryModule/MemoryModule.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MemoryModule/MemoryModule.cpp b/MemoryModule/MemoryModule.cpp index 32ff600c..18db5a1f 100644 --- a/MemoryModule/MemoryModule.cpp +++ b/MemoryModule/MemoryModule.cpp @@ -12,7 +12,7 @@ #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 AlignValueUp(value, alignment) ((size_t(value) + size_t(alignment) - 1) & ~(size_t(alignment) - 1)) #define OffsetPointer(data, offset) LPVOID(LPBYTE(data) + ptrdiff_t(offset)) From 61a80f4ec94a33107156087918c15f07dd08b8ab Mon Sep 17 00:00:00 2001 From: Boring <1079299053@qq.com> Date: Mon, 1 Jul 2024 22:23:54 +0800 Subject: [PATCH 10/17] Update page protection access mask. --- MemoryModule/Utils.h | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/MemoryModule/Utils.h b/MemoryModule/Utils.h index bd1a2418..d110a04b 100644 --- a/MemoryModule/Utils.h +++ b/MemoryModule/Utils.h @@ -34,13 +34,14 @@ BOOLEAN NTAPI RtlIsValidImageBuffer( 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) -#define ProbeForWrite(pBuffer, size) VirtualAccessCheck(pBuffer, size, PAGE_READWRITE | PAGE_EXECUTE_WRITECOPY | PAGE_WRITECOPY | PAGE_EXECUTE_READWRITE) -#define ProbeForReadWrite(pBuffer, size) VirtualAccessCheck(pBuffer, size, PAGE_EXECUTE_READWRITE | PAGE_READWRITE) +#define ProbeForRead(pBuffer, size) VirtualAccessCheck(pBuffer, size, PAGE_READONLY | PAGE_READWRITE | PAGE_EXECUTE | PAGE_EXECUTE_READ | PAGE_EXECUTE_READWRITE | PAGE_EXECUTE_WRITECOPY | PAGE_WRITECOPY) +#define ProbeForWrite(pBuffer, size) VirtualAccessCheck(pBuffer, size, PAGE_READWRITE | PAGE_WRITECOPY | PAGE_EXECUTE_READWRITE | PAGE_EXECUTE_WRITECOPY) +#define ProbeForReadWrite ProbeForWrite #define ProbeForExecute(pBuffer, size) VirtualAccessCheck(pBuffer, size, PAGE_EXECUTE | PAGE_EXECUTE_READ | PAGE_EXECUTE_READWRITE | PAGE_EXECUTE_WRITECOPY) -#define _ProbeForRead(pBuffer, size) VirtualAccessCheckNoException(pBuffer, size, PAGE_READONLY | PAGE_READWRITE | PAGE_EXECUTE_READ | PAGE_EXECUTE_READWRITE) -#define _ProbeForWrite(pBuffer, size) VirtualAccessCheckNoException(pBuffer, size, PAGE_READWRITE | PAGE_EXECUTE_WRITECOPY | PAGE_WRITECOPY | PAGE_EXECUTE_READWRITE) -#define _ProbeForReadWrite(pBuffer, size) VirtualAccessCheckNoException(pBuffer, size, PAGE_EXECUTE_READWRITE | PAGE_READWRITE) + +#define _ProbeForRead(pBuffer, size) VirtualAccessCheckNoException(pBuffer, size, PAGE_READONLY | PAGE_READWRITE | PAGE_EXECUTE | PAGE_EXECUTE_READ | PAGE_EXECUTE_READWRITE | PAGE_EXECUTE_WRITECOPY | PAGE_WRITECOPY) +#define _ProbeForWrite(pBuffer, size) VirtualAccessCheckNoException(pBuffer, size, PAGE_READWRITE | PAGE_WRITECOPY | PAGE_EXECUTE_READWRITE | PAGE_EXECUTE_WRITECOPY) +#define _ProbeForReadWrite _ProbeForWrite #define _ProbeForExecute(pBuffer, size) VirtualAccessCheckNoException(pBuffer, size, PAGE_EXECUTE | PAGE_EXECUTE_READ | PAGE_EXECUTE_READWRITE | PAGE_EXECUTE_WRITECOPY) #define RtlClearBit(BitMapHeader,BitNumber) RtlClearBits((BitMapHeader),(BitNumber),1) From 252e628a71e9f817288b10bc68e24316d81d7917 Mon Sep 17 00:00:00 2001 From: Boring <1079299053@qq.com> Date: Wed, 3 Jul 2024 12:49:50 +0800 Subject: [PATCH 11/17] base relocation --- MemoryModule/MemoryModule.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MemoryModule/MemoryModule.cpp b/MemoryModule/MemoryModule.cpp index 18db5a1f..34573acf 100644 --- a/MemoryModule/MemoryModule.cpp +++ b/MemoryModule/MemoryModule.cpp @@ -285,7 +285,7 @@ NTSTATUS MemoryLoadLibrary( PIMAGE_BASE_RELOCATION_HEADER relocation = (PIMAGE_BASE_RELOCATION_HEADER)(LPBYTE(base) + dir->VirtualAddress); if (dir->Size && dir->VirtualAddress) { - while (relocation->VirtualAddress > 0) { + while ((LPBYTE(relocation) < LPBYTE(base) + dir->VirtualAddress + dir->Size) && relocation->VirtualAddress > 0) { auto relInfo = (_REBASE_INFO*)&relocation->TypeOffset; for (DWORD i = 0; i < relocation->TypeOffsetCount(); ++i, ++relInfo) { switch (relInfo->Type) { From 06968d8feb68622e55fad11772d6855df5ee1721 Mon Sep 17 00:00:00 2001 From: Boring <1079299053@qq.com> Date: Thu, 3 Oct 2024 01:04:09 +0800 Subject: [PATCH 12/17] #49 #52 add initialize/cleanup to achieve graceful shutdown --- 3rdparty/phnt/include/ntioapi.h | 53 ---------------- MemoryModule/Initialize.cpp | 76 +++++++++++++++++++++-- MemoryModule/Initialize.h | 9 +++ MemoryModule/LoadDllMemoryApi.h | 1 + MemoryModule/Loader.cpp | 14 ++++- MemoryModule/MemoryModule.vcxproj | 33 +++++----- MemoryModule/MemoryModule.vcxproj.filters | 3 + MemoryModule/MmpDotNet.cpp | 35 +++++++++++ MemoryModule/MmpDotNet.h | 3 +- MemoryModule/MmpGlobalData.h | 4 +- MemoryModule/MmpTls.cpp | 11 ++++ MemoryModule/MmpTls.h | 2 + MemoryModule/MmpTlsFiber.cpp | 15 ++--- test/test.cpp | 2 +- test/test.vcxproj | 2 +- 15 files changed, 176 insertions(+), 87 deletions(-) create mode 100644 MemoryModule/Initialize.h diff --git a/3rdparty/phnt/include/ntioapi.h b/3rdparty/phnt/include/ntioapi.h index a08f8775..bfcaf20d 100644 --- a/3rdparty/phnt/include/ntioapi.h +++ b/3rdparty/phnt/include/ntioapi.h @@ -774,22 +774,6 @@ typedef struct _FILE_ID_EXTD_BOTH_DIR_INFORMATION WCHAR FileName[1]; } FILE_ID_EXTD_BOTH_DIR_INFORMATION, *PFILE_ID_EXTD_BOTH_DIR_INFORMATION; -// private -typedef struct _FILE_STAT_INFORMATION -{ - LARGE_INTEGER FileId; - LARGE_INTEGER CreationTime; - LARGE_INTEGER LastAccessTime; - LARGE_INTEGER LastWriteTime; - LARGE_INTEGER ChangeTime; - LARGE_INTEGER AllocationSize; - LARGE_INTEGER EndOfFile; - ULONG FileAttributes; - ULONG ReparseTag; - ULONG NumberOfLinks; - ACCESS_MASK EffectiveAccess; -} FILE_STAT_INFORMATION, *PFILE_STAT_INFORMATION; - // private typedef struct _FILE_MEMORY_PARTITION_INFORMATION { @@ -805,43 +789,6 @@ typedef struct _FILE_MEMORY_PARTITION_INFORMATION } Flags; } FILE_MEMORY_PARTITION_INFORMATION, *PFILE_MEMORY_PARTITION_INFORMATION; -// LxFlags -#define LX_FILE_METADATA_HAS_UID 0x1 -#define LX_FILE_METADATA_HAS_GID 0x2 -#define LX_FILE_METADATA_HAS_MODE 0x4 -#define LX_FILE_METADATA_HAS_DEVICE_ID 0x8 -#define LX_FILE_CASE_SENSITIVE_DIR 0x10 - -// private -typedef struct _FILE_STAT_LX_INFORMATION -{ - LARGE_INTEGER FileId; - LARGE_INTEGER CreationTime; - LARGE_INTEGER LastAccessTime; - LARGE_INTEGER LastWriteTime; - LARGE_INTEGER ChangeTime; - LARGE_INTEGER AllocationSize; - LARGE_INTEGER EndOfFile; - ULONG FileAttributes; - ULONG ReparseTag; - ULONG NumberOfLinks; - ACCESS_MASK EffectiveAccess; - ULONG LxFlags; - ULONG LxUid; - ULONG LxGid; - ULONG LxMode; - ULONG LxDeviceIdMajor; - ULONG LxDeviceIdMinor; -} FILE_STAT_LX_INFORMATION, *PFILE_STAT_LX_INFORMATION; - -#define FILE_CS_FLAG_CASE_SENSITIVE_DIR 0x00000001 - -// private -typedef struct _FILE_CASE_SENSITIVE_INFORMATION -{ - ULONG Flags; -} FILE_CASE_SENSITIVE_INFORMATION, *PFILE_CASE_SENSITIVE_INFORMATION; - // private typedef enum _FILE_KNOWN_FOLDER_TYPE { diff --git a/MemoryModule/Initialize.cpp b/MemoryModule/Initialize.cpp index 42da0ba5..aa023c8e 100644 --- a/MemoryModule/Initialize.cpp +++ b/MemoryModule/Initialize.cpp @@ -438,6 +438,7 @@ NTSTATUS InitializeLockHeld() { status = STATUS_NOT_SUPPORTED; } else { + ++MmpGlobalDataPtr->ReferenceCount; status = STATUS_SUCCESS; } } @@ -448,6 +449,7 @@ NTSTATUS InitializeLockHeld() { MmpGlobalDataPtr->MajorVersion = MEMORY_MODULE_MAJOR_VERSION; MmpGlobalDataPtr->MinorVersion = MEMORY_MODULE_MINOR_VERSION; MmpGlobalDataPtr->BaseAddress = MmpGlobalDataPtr; + MmpGlobalDataPtr->ReferenceCount = 1; GetSystemInfo(&MmpGlobalDataPtr->SystemInfo); @@ -504,16 +506,74 @@ NTSTATUS InitializeLockHeld() { return status; } -NTSTATUS NTAPI Initialize() { +NTSTATUS NTAPI MmInitialize() { NTSTATUS status; - RtlAcquirePebLock(); - status = InitializeLockHeld(); - RtlReleasePebLock(); + PVOID cookie; + LdrLockLoaderLock(LDR_LOCK_LOADER_LOCK_FLAG_RAISE_ON_ERRORS, nullptr, &cookie); + + __try { + status = InitializeLockHeld(); + } + __finally { + LdrUnlockLoaderLock(LDR_UNLOCK_LOADER_LOCK_FLAG_RAISE_ON_ERRORS, cookie); + } return status; } +NTSTATUS CleanupLockHeld() { + + 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 (IsValidMemoryModuleHandle((HMEMORYMODULE)CurEntry->DllBase)) { + + // + // Make sure all memory module is unloaded. + // + + return STATUS_NOT_SUPPORTED; + } + } + + if (--MmpGlobalDataPtr->ReferenceCount > 0) { + return STATUS_SUCCESS; + } + + MmpTlsCleanup(); + MmpCleanupDotNetHooks(); + + NtUnmapViewOfSection(NtCurrentProcess(), MmpGlobalDataPtr->BaseAddress); + MmpGlobalDataPtr = nullptr; + return STATUS_SUCCESS; +} + +NTSTATUS NTAPI MmCleanup() { + NTSTATUS status; + PVOID cookie; + LdrLockLoaderLock(LDR_LOCK_LOADER_LOCK_FLAG_RAISE_ON_ERRORS, nullptr, &cookie); + + __try { + + if (MmpGlobalDataPtr == nullptr) { + status = STATUS_ACCESS_VIOLATION; + __leave; + } + + status = CleanupLockHeld(); + } + __finally { + LdrUnlockLoaderLock(LDR_UNLOCK_LOADER_LOCK_FLAG_RAISE_ON_ERRORS, cookie); + } + + return status; +} + #ifdef _USRDLL extern "C" __declspec(dllexport) BOOL WINAPI ReflectiveMapDll(HMODULE hModule) { PIMAGE_NT_HEADERS headers = RtlImageNtHeader(hModule); @@ -542,7 +602,8 @@ extern "C" __declspec(dllexport) BOOL WINAPI ReflectiveMapDll(HMODULE hModule) { BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) { if (ul_reason_for_call == DLL_PROCESS_ATTACH) { - if (NT_SUCCESS(Initialize())) { +#ifdef _HAS_AUTO_INITIALIZE + if (NT_SUCCESS(MmInitialize())) { if (lpReserved == (PVOID)-1) { if (!ReflectiveMapDll(hModule)) { RtlRaiseStatus(STATUS_NOT_SUPPORTED); @@ -553,10 +614,13 @@ BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReser } return FALSE; +#endif } return TRUE; } #else -const NTSTATUS Initializer = Initialize(); +#ifdef _HAS_AUTO_INITIALIZE +const NTSTATUS Initializer = MmInitialize(); +#endif #endif diff --git a/MemoryModule/Initialize.h b/MemoryModule/Initialize.h new file mode 100644 index 00000000..655df6ed --- /dev/null +++ b/MemoryModule/Initialize.h @@ -0,0 +1,9 @@ +#pragma once + +NTSTATUS NTAPI MmInitialize(); +NTSTATUS NTAPI MmCleanup(); + +// +// This function is available only if the MMPP is compiled as a DLL. +// +BOOL WINAPI ReflectiveMapDll(HMODULE hModule); diff --git a/MemoryModule/LoadDllMemoryApi.h b/MemoryModule/LoadDllMemoryApi.h index 54d8368a..f6251486 100644 --- a/MemoryModule/LoadDllMemoryApi.h +++ b/MemoryModule/LoadDllMemoryApi.h @@ -3,6 +3,7 @@ typedef HMODULE HMEMORYMODULE; #include "Loader.h" +#include "Initialize.h" #define MemoryModuleToModule(_hMemoryModule_) (_hMemoryModule_) diff --git a/MemoryModule/Loader.cpp b/MemoryModule/Loader.cpp index 73eb5ffe..846ad818 100644 --- a/MemoryModule/Loader.cpp +++ b/MemoryModule/Loader.cpp @@ -61,7 +61,14 @@ NTSTATUS NTAPI LdrLoadDllMemoryExW( __try { *BaseAddress = nullptr; if (LdrEntry)*LdrEntry = nullptr; - if (!RtlIsValidImageBuffer(BufferAddress, &BufferSize) && !(dwFlags & LOAD_FLAGS_PASS_IMAGE_CHECK))status = STATUS_INVALID_IMAGE_FORMAT; + + if (!RtlIsValidImageBuffer(BufferAddress, &BufferSize) && !(dwFlags & LOAD_FLAGS_PASS_IMAGE_CHECK)) { + status = STATUS_INVALID_IMAGE_FORMAT; + } + + if (MmpGlobalDataPtr == nullptr) { + status = STATUS_INVALID_PARAMETER; + } } __except (EXCEPTION_EXECUTE_HANDLER) { status = GetExceptionCode(); @@ -229,6 +236,11 @@ NTSTATUS NTAPI LdrUnloadDllMemory(_In_ HMEMORYMODULE BaseAddress) { break; } + if (MmpGlobalDataPtr == nullptr) { + status = STATUS_INVALID_PARAMETER; + break; + } + //Mapping dll failed if (!module->MappedDll) { module->underUnload = true; diff --git a/MemoryModule/MemoryModule.vcxproj b/MemoryModule/MemoryModule.vcxproj index 5ea04bc9..ebcea8da 100644 --- a/MemoryModule/MemoryModule.vcxproj +++ b/MemoryModule/MemoryModule.vcxproj @@ -152,6 +152,7 @@ + @@ -419,7 +420,7 @@ NotUsing Level3 true - _MEMORY_MODULE;WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) + _MEMORY_MODULE;_HAS_AUTO_INITIALIZE;WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) true @@ -437,7 +438,7 @@ NotUsing Level3 true - _MEMORY_MODULE;WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) + _MEMORY_MODULE;_HAS_AUTO_INITIALIZE;WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) true @@ -456,7 +457,7 @@ NotUsing Level3 true - _MEMORY_MODULE;WIN32;_DEBUG;_USRDLL;%(PreprocessorDefinitions) + _MEMORY_MODULE;_HAS_AUTO_INITIALIZE;WIN32;_DEBUG;_USRDLL;%(PreprocessorDefinitions) true @@ -475,7 +476,7 @@ NotUsing Level3 true - _MEMORY_MODULE;WIN32;_DEBUG;_USRDLL;%(PreprocessorDefinitions) + _MEMORY_MODULE;_HAS_AUTO_INITIALIZE;WIN32;_DEBUG;_USRDLL;%(PreprocessorDefinitions) true @@ -494,7 +495,7 @@ NotUsing Level3 true - _MEMORY_MODULE;_DEBUG;_LIB;%(PreprocessorDefinitions) + _MEMORY_MODULE;_HAS_AUTO_INITIALIZE;_DEBUG;_LIB;%(PreprocessorDefinitions) true @@ -512,7 +513,7 @@ NotUsing Level3 true - _MEMORY_MODULE;_DEBUG;_LIB;%(PreprocessorDefinitions) + _MEMORY_MODULE;_HAS_AUTO_INITIALIZE;_DEBUG;_LIB;%(PreprocessorDefinitions) true @@ -531,7 +532,7 @@ NotUsing Level3 true - _MEMORY_MODULE;_DEBUG;_USRDLL;%(PreprocessorDefinitions) + _MEMORY_MODULE;_HAS_AUTO_INITIALIZE;_DEBUG;_USRDLL;%(PreprocessorDefinitions) true @@ -550,7 +551,7 @@ NotUsing Level3 true - _MEMORY_MODULE;_DEBUG;_USRDLL;%(PreprocessorDefinitions) + _MEMORY_MODULE;_HAS_AUTO_INITIALIZE;_DEBUG;_USRDLL;%(PreprocessorDefinitions) true @@ -571,7 +572,7 @@ true true true - _MEMORY_MODULE;WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) + _MEMORY_MODULE;_HAS_AUTO_INITIALIZE;WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) true @@ -593,7 +594,7 @@ true true true - _MEMORY_MODULE;WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) + _MEMORY_MODULE;_HAS_AUTO_INITIALIZE;WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) true @@ -616,7 +617,7 @@ true true true - _MEMORY_MODULE;WIN32;NDEBUG;_USRDLL;%(PreprocessorDefinitions) + _MEMORY_MODULE;_HAS_AUTO_INITIALIZE;WIN32;NDEBUG;_USRDLL;%(PreprocessorDefinitions) true @@ -639,7 +640,7 @@ true true true - _MEMORY_MODULE;WIN32;NDEBUG;_USRDLL;%(PreprocessorDefinitions) + _MEMORY_MODULE;_HAS_AUTO_INITIALIZE;WIN32;NDEBUG;_USRDLL;%(PreprocessorDefinitions) true @@ -662,7 +663,7 @@ true true true - _MEMORY_MODULE;NDEBUG;_LIB;%(PreprocessorDefinitions) + _MEMORY_MODULE;_HAS_AUTO_INITIALIZE;NDEBUG;_LIB;%(PreprocessorDefinitions) true @@ -684,7 +685,7 @@ true true true - _MEMORY_MODULE;NDEBUG;_LIB;%(PreprocessorDefinitions) + _MEMORY_MODULE;_HAS_AUTO_INITIALIZE;NDEBUG;_LIB;%(PreprocessorDefinitions) true @@ -707,7 +708,7 @@ true true true - _MEMORY_MODULE;NDEBUG;_USRDLL;%(PreprocessorDefinitions) + _MEMORY_MODULE;_HAS_AUTO_INITIALIZE;NDEBUG;_USRDLL;%(PreprocessorDefinitions) true @@ -730,7 +731,7 @@ true true true - _MEMORY_MODULE;NDEBUG;_USRDLL;%(PreprocessorDefinitions) + _MEMORY_MODULE;_HAS_AUTO_INITIALIZE;NDEBUG;_USRDLL;%(PreprocessorDefinitions) true diff --git a/MemoryModule/MemoryModule.vcxproj.filters b/MemoryModule/MemoryModule.vcxproj.filters index 9413f3cc..e38f9fdb 100644 --- a/MemoryModule/MemoryModule.vcxproj.filters +++ b/MemoryModule/MemoryModule.vcxproj.filters @@ -260,6 +260,9 @@ Header Files + + Header Files + diff --git a/MemoryModule/MmpDotNet.cpp b/MemoryModule/MmpDotNet.cpp index 5f5e9585..ca8bcc1c 100644 --- a/MemoryModule/MmpDotNet.cpp +++ b/MemoryModule/MmpDotNet.cpp @@ -443,3 +443,38 @@ BOOL WINAPI MmpInitializeHooksForDotNet() { return FALSE; } + +VOID WINAPI MmpCleanupDotNetHooks() { + EnterCriticalSection(NtCurrentPeb()->FastPebLock); + + if (MmpGlobalDataPtr->MmpDotNet->PreHooked) { + DetourTransactionBegin(); + DetourUpdateThread(NtCurrentThread()); + + DetourDetach((PVOID*)&MmpGlobalDataPtr->MmpDotNet->Hooks.OriginCreateFileW, HookCreateFileW); + DetourDetach((PVOID*)&MmpGlobalDataPtr->MmpDotNet->Hooks.OriginGetFileInformationByHandle, HookGetFileInformationByHandle); + DetourDetach((PVOID*)&MmpGlobalDataPtr->MmpDotNet->Hooks.OriginGetFileAttributesExW, HookGetFileAttributesExW); + DetourDetach((PVOID*)&MmpGlobalDataPtr->MmpDotNet->Hooks.OriginGetFileSize, HookGetFileSize); + DetourDetach((PVOID*)&MmpGlobalDataPtr->MmpDotNet->Hooks.OriginGetFileSizeEx, HookGetFileSizeEx); + DetourDetach((PVOID*)&MmpGlobalDataPtr->MmpDotNet->Hooks.OriginCreateFileMappingW, HookCreateFileMappingW); + DetourDetach((PVOID*)&MmpGlobalDataPtr->MmpDotNet->Hooks.OriginMapViewOfFileEx, HookMapViewOfFileEx); + DetourDetach((PVOID*)&MmpGlobalDataPtr->MmpDotNet->Hooks.OriginMapViewOfFile, HookMapViewOfFile); + DetourDetach((PVOID*)&MmpGlobalDataPtr->MmpDotNet->Hooks.OriginUnmapViewOfFile, HookUnmapViewOfFile); + DetourDetach((PVOID*)&MmpGlobalDataPtr->MmpDotNet->Hooks.OriginCloseHandle, HookCloseHandle); + DetourDetach((PVOID*)&MmpGlobalDataPtr->MmpDotNet->Hooks.OriginGetFileVersion2, HookGetFileVersion); + + DetourTransactionCommit(); + + MmpGlobalDataPtr->MmpDotNet->PreHooked = FALSE; + } + + if (MmpGlobalDataPtr->MmpDotNet->Initialized) { + DetourTransactionBegin(); + DetourUpdateThread(NtCurrentThread()); + DetourDetach((PVOID*)&MmpGlobalDataPtr->MmpDotNet->Hooks.OriginGetFileVersion1, HookGetFileVersion); + DetourTransactionCommit(); + MmpGlobalDataPtr->MmpDotNet->Initialized = FALSE; + } + + LeaveCriticalSection(NtCurrentPeb()->FastPebLock); +} diff --git a/MemoryModule/MmpDotNet.h b/MemoryModule/MmpDotNet.h index 14253e58..be433b04 100644 --- a/MemoryModule/MmpDotNet.h +++ b/MemoryModule/MmpDotNet.h @@ -8,4 +8,5 @@ typedef HRESULT(WINAPI* GetFileVersion_T)( ); BOOL WINAPI MmpPreInitializeHooksForDotNet(); -BOOL WINAPI MmpInitializeHooksForDotNet(); \ No newline at end of file +BOOL WINAPI MmpInitializeHooksForDotNet(); +VOID WINAPI MmpCleanupDotNetHooks(); diff --git a/MemoryModule/MmpGlobalData.h b/MemoryModule/MmpGlobalData.h index e4530a2d..2a986b0e 100644 --- a/MemoryModule/MmpGlobalData.h +++ b/MemoryModule/MmpGlobalData.h @@ -100,7 +100,7 @@ typedef enum class _WINDOWS_VERSION :BYTE { #define MEMORY_MODULE_GET_MINOR_VERSION(MinorVersion) (~0x8000&(MinorVersion)) #define MEMORY_MODULE_MAJOR_VERSION 2 -#define MEMORY_MODULE_MINOR_VERSION MEMORY_MODULE_MAKE_PREVIEW(1) +#define MEMORY_MODULE_MINOR_VERSION MEMORY_MODULE_MAKE_PREVIEW(2) typedef struct _MMP_GLOBAL_DATA { @@ -137,6 +137,8 @@ typedef struct _MMP_GLOBAL_DATA { PMMP_IAT_DATA MmpIat; + DWORD ReferenceCount; + }MMP_GLOBAL_DATA, * PMMP_GLOBAL_DATA; #define MMP_GLOBAL_DATA_SIZE (\ diff --git a/MemoryModule/MmpTls.cpp b/MemoryModule/MmpTls.cpp index 4bc0aa30..733e6b27 100644 --- a/MemoryModule/MmpTls.cpp +++ b/MemoryModule/MmpTls.cpp @@ -798,4 +798,15 @@ BOOL NTAPI MmpTlsInitialize() { return TRUE; } +VOID NTAPI MmpTlsCleanup() { + + DetourTransactionBegin(); + DetourUpdateThread(NtCurrentThread()); + DetourDetach((PVOID*)&MmpGlobalDataPtr->MmpTls->Hooks.OriginLdrShutdownThread, HookLdrShutdownThread); + DetourDetach((PVOID*)&MmpGlobalDataPtr->MmpTls->Hooks.OriginNtSetInformationProcess, HookNtSetInformationProcess); + DetourDetach((PVOID*)&MmpGlobalDataPtr->MmpTls->Hooks.OriginRtlUserThreadStart, HookRtlUserThreadStart); + DetourTransactionCommit(); + +} + #endif diff --git a/MemoryModule/MmpTls.h b/MemoryModule/MmpTls.h index 33de5c9c..4c2fe0e3 100644 --- a/MemoryModule/MmpTls.h +++ b/MemoryModule/MmpTls.h @@ -2,6 +2,8 @@ BOOL NTAPI MmpTlsInitialize(); +VOID NTAPI MmpTlsCleanup(); + NTSTATUS NTAPI MmpReleaseTlsEntry(_In_ PLDR_DATA_TABLE_ENTRY lpModuleEntry); NTSTATUS NTAPI MmpHandleTlsData(_In_ PLDR_DATA_TABLE_ENTRY lpModuleEntry); diff --git a/MemoryModule/MmpTlsFiber.cpp b/MemoryModule/MmpTlsFiber.cpp index 3b5391e2..7ea4d8c9 100644 --- a/MemoryModule/MmpTlsFiber.cpp +++ b/MemoryModule/MmpTlsFiber.cpp @@ -3,6 +3,7 @@ #include "MmpTlsFiber.h" #include +#include typedef struct _MMP_POSTPONED_TLS { @@ -31,8 +32,7 @@ DWORD WINAPI MmpReleasePostponedTlsWorker(PVOID) { auto iter = MmpPostponedTlsList->begin(); while (iter != MmpPostponedTlsList->end()) { - const auto& item = *iter; - GetExitCodeThread(item.hThread, &code); + GetExitCodeThread(iter->hThread, &code); if (code == STILL_ACTIVE) { ++iter; @@ -41,7 +41,7 @@ DWORD WINAPI MmpReleasePostponedTlsWorker(PVOID) { RtlAcquireSRWLockExclusive(&MmpGlobalDataPtr->MmpTls->MmpTlsListLock); - auto TlspMmpBlock = (PVOID*)item.lpOldTlsVector->ModuleTlsData; + auto TlspMmpBlock = (PVOID*)iter->lpOldTlsVector->ModuleTlsData; auto entry = MmpGlobalDataPtr->MmpTls->MmpTlsList.Flink; while (entry != &MmpGlobalDataPtr->MmpTls->MmpTlsList) { @@ -51,13 +51,13 @@ DWORD WINAPI MmpReleasePostponedTlsWorker(PVOID) { entry = entry->Flink; } - RtlFreeHeap(RtlProcessHeap(), 0, CONTAINING_RECORD(item.lpTlsRecord->TlspLdrBlock, TLS_VECTOR, TLS_VECTOR::ModuleTlsData)); - RtlFreeHeap(RtlProcessHeap(), 0, item.lpTlsRecord); - RtlFreeHeap(RtlProcessHeap(), 0, item.lpOldTlsVector); + RtlFreeHeap(RtlProcessHeap(), 0, CONTAINING_RECORD(iter->lpTlsRecord->TlspLdrBlock, TLS_VECTOR, TLS_VECTOR::ModuleTlsData)); + RtlFreeHeap(RtlProcessHeap(), 0, iter->lpTlsRecord); + RtlFreeHeap(RtlProcessHeap(), 0, iter->lpOldTlsVector); RtlReleaseSRWLockExclusive(&MmpGlobalDataPtr->MmpTls->MmpTlsListLock); - CloseHandle(item.hThread); + CloseHandle(iter->hThread); iter = MmpPostponedTlsList->erase(iter); } @@ -95,6 +95,7 @@ VOID WINAPI MmpQueuePostponedTls(PMMP_TLSP_RECORD record) { ); item.lpOldTlsVector = MmpAllocateTlsp(); + assert(item.lpOldTlsVector); item.lpTlsRecord = record; diff --git a/test/test.cpp b/test/test.cpp index 3ea4e308..e5c964af 100644 --- a/test/test.cpp +++ b/test/test.cpp @@ -129,7 +129,7 @@ int test() { } int main() { - + DisplayStatus(); test(); diff --git a/test/test.vcxproj b/test/test.vcxproj index a7616ce9..aee15d34 100644 --- a/test/test.vcxproj +++ b/test/test.vcxproj @@ -39,7 +39,7 @@ {5B3131BA-178A-4A28-BD54-315A45C97ED1} Win32Proj test - 10.0 + 10.0.22621.0 From 63087b87f146afb4abeb675d66a6d964cb05ed81 Mon Sep 17 00:00:00 2001 From: Boring <1079299053@qq.com> Date: Tue, 8 Oct 2024 02:14:12 +0800 Subject: [PATCH 13/17] #52 Improved stability of MmpTls --- MemoryModule/MemoryModulePP.def | 4 + MemoryModule/MmpTls.cpp | 166 ++++++++++++++++++++++++++------ 2 files changed, 138 insertions(+), 32 deletions(-) diff --git a/MemoryModule/MemoryModulePP.def b/MemoryModule/MemoryModulePP.def index 7491bc1e..fcbae96d 100644 --- a/MemoryModule/MemoryModulePP.def +++ b/MemoryModule/MemoryModulePP.def @@ -1,5 +1,9 @@ LIBRARY EXPORTS + +MmInitialize +MmCleanup + LoadLibraryMemory LoadLibraryMemoryExA LoadLibraryMemoryExW diff --git a/MemoryModule/MmpTls.cpp b/MemoryModule/MmpTls.cpp index 733e6b27..71f7d358 100644 --- a/MemoryModule/MmpTls.cpp +++ b/MemoryModule/MmpTls.cpp @@ -7,6 +7,7 @@ #include #include #include <3rdparty/Detours/detours.h> +#include PVOID NTAPI MmpQuerySystemInformation( @@ -402,6 +403,96 @@ BOOL NTAPI PreHookNtSetInformationProcess() { return success; } +int MmpSyncThreadTlsData() { + PSYSTEM_PROCESS_INFORMATION pspi = (PSYSTEM_PROCESS_INFORMATION)MmpQuerySystemInformation(SYSTEM_INFORMATION_CLASS::SystemProcessInformation, nullptr); + PSYSTEM_PROCESS_INFORMATION current = pspi; + std::setthreads; + int count = 0; + + // + // Build thread id set. + // + + PLIST_ENTRY entry = MmpGlobalDataPtr->MmpTls->MmpThreadLocalStoragePointer.Flink; + while (entry != &MmpGlobalDataPtr->MmpTls->MmpThreadLocalStoragePointer) { + PMMP_TLSP_RECORD j = CONTAINING_RECORD(entry, MMP_TLSP_RECORD, InMmpThreadLocalStoragePointer); + threads.insert(j->UniqueThread); + + entry = entry->Flink; + } + + while (pspi) { + + if (current->UniqueProcessId == NtCurrentTeb()->ClientId.UniqueProcess) { + + for (ULONG index = 0; index < current->NumberOfThreads; ++index) { + CLIENT_ID cid = current->Threads[index].ClientId; + + if (threads.find(cid.UniqueThread) == threads.end()) { + + HANDLE hThread; + OBJECT_ATTRIBUTES oa{}; + NTSTATUS status = NtOpenThread(&hThread, THREAD_QUERY_INFORMATION, &oa, &cid); + if (NT_SUCCESS(status)) { + + THREAD_BASIC_INFORMATION tbi{}; + status = NtQueryInformationThread(hThread, THREADINFOCLASS::ThreadBasicInformation, &tbi, sizeof(tbi), nullptr); + if (NT_SUCCESS(status)) { + + PTEB teb = tbi.TebBaseAddress; + if (teb->ThreadLocalStoragePointer) { + + // + // Allocate TLS record + // + + auto record = PMMP_TLSP_RECORD(RtlAllocateHeap(RtlProcessHeap(), 0, sizeof(MMP_TLSP_RECORD))); + if (record) { + record->TlspLdrBlock = (PVOID*)teb->ThreadLocalStoragePointer; + record->TlspMmpBlock = (PVOID*)MmpAllocateTlsp(); + record->UniqueThread = cid.UniqueThread; + if (record->TlspMmpBlock) { + record->TlspMmpBlock = ((PTLS_VECTOR)record->TlspMmpBlock)->ModuleTlsData; + + auto size = CONTAINING_RECORD(record->TlspLdrBlock, TLS_VECTOR, ModuleTlsData)->Length; + if ((HANDLE)(ULONG_PTR)size != record->UniqueThread) { + RtlCopyMemory( + record->TlspMmpBlock, + record->TlspLdrBlock, + size * sizeof(PVOID) + ); + } + + teb->ThreadLocalStoragePointer = record->TlspMmpBlock; + InsertTailList(&MmpGlobalDataPtr->MmpTls->MmpThreadLocalStoragePointer, &record->InMmpThreadLocalStoragePointer); + InterlockedIncrement(&MmpGlobalDataPtr->MmpTls->MmpActiveThreadCount); + + ++count; + } + else { + RtlFreeHeap(RtlProcessHeap(), 0, record); + } + } + } + } + + NtClose(hThread); + } + + } + } + + break; + } + + if (!current->NextEntryOffset)break; + current = (PSYSTEM_PROCESS_INFORMATION)((PBYTE)current + current->NextEntryOffset); + } + + RtlFreeHeap(RtlProcessHeap(), 0, pspi); + return count; +} + NTSTATUS NTAPI HookNtSetInformationProcess( _In_opt_ HANDLE ProcessHandle, _In_ PROCESSINFOCLASS ProcessInformationClass, @@ -423,6 +514,12 @@ NTSTATUS NTAPI HookNtSetInformationProcess( PPROCESS_TLS_INFORMATION Tls = nullptr; NTSTATUS status = STATUS_SUCCESS; + // + // Sync thread data with ntdll!Ldr. + // + + MmpSyncThreadTlsData(); + do { if (ProcessTlsInformation->OperationType >= MaxProcessTlsOperation) { status = STATUS_INVALID_PARAMETER; @@ -456,7 +553,7 @@ NTSTATUS NTAPI HookNtSetInformationProcess( break; } - // reserved 0x50 PVOID for ntdll loader + // reserved 0x80 PVOID for ntdll loader if (ProcessTlsInformation->TlsVectorLength >= MMP_START_TLS_INDEX) { status = STATUS_NO_MEMORY; break; @@ -496,50 +593,55 @@ NTSTATUS NTAPI HookNtSetInformationProcess( // EnterCriticalSection(&MmpGlobalDataPtr->MmpTls->MmpTlspLock); for (ULONG i = 0; i < Tls->ThreadDataCount; ++i) { - BOOL found = FALSE; - PLIST_ENTRY entry = MmpGlobalDataPtr->MmpTls->MmpThreadLocalStoragePointer.Flink; - // Find thread-spec tlsp - while (entry != &MmpGlobalDataPtr->MmpTls->MmpThreadLocalStoragePointer) { + if (Tls->ThreadData[i].Flags == 2) { - PMMP_TLSP_RECORD j = CONTAINING_RECORD(entry, MMP_TLSP_RECORD, InMmpThreadLocalStoragePointer); + BOOL found = FALSE; + PLIST_ENTRY entry = MmpGlobalDataPtr->MmpTls->MmpThreadLocalStoragePointer.Flink; - if (ProcessTlsInformation->OperationType == ProcessTlsReplaceVector) { - if (j->TlspMmpBlock[ProcessTlsInformation->TlsVectorLength] == ProcessTlsInformation->ThreadData[i].TlsVector[ProcessTlsInformation->TlsVectorLength]) { - found = TRUE; + // Find thread-spec tlsp + while (entry != &MmpGlobalDataPtr->MmpTls->MmpThreadLocalStoragePointer) { - // Copy old data to new pointer - RtlCopyMemory( - ProcessTlsInformation->ThreadData[i].TlsVector, - j->TlspMmpBlock, - sizeof(PVOID) * ProcessTlsInformation->TlsVectorLength - ); + PMMP_TLSP_RECORD j = CONTAINING_RECORD(entry, MMP_TLSP_RECORD, InMmpThreadLocalStoragePointer); - // Swap the tlsp - std::swap( - j->TlspLdrBlock, - ProcessTlsInformation->ThreadData[i].TlsVector - ); + if (ProcessTlsInformation->OperationType == ProcessTlsReplaceVector) { + if (j->TlspMmpBlock[ProcessTlsInformation->TlsVectorLength] == ProcessTlsInformation->ThreadData[i].TlsVector[ProcessTlsInformation->TlsVectorLength]) { + found = TRUE; + + // Copy old data to new pointer + RtlCopyMemory( + ProcessTlsInformation->ThreadData[i].TlsVector, + j->TlspMmpBlock, + sizeof(PVOID) * ProcessTlsInformation->TlsVectorLength + ); + + // Swap the tlsp + std::swap( + j->TlspLdrBlock, + ProcessTlsInformation->ThreadData[i].TlsVector + ); + } } - } - else { - if (j->TlspMmpBlock[ProcessTlsInformation->TlsIndex] == ProcessTlsInformation->ThreadData[i].TlsModulePointer) { - found = TRUE; + else { + if (j->TlspMmpBlock[ProcessTlsInformation->TlsIndex] == ProcessTlsInformation->ThreadData[i].TlsModulePointer) { + found = TRUE; + + if (ProcessHandle) { + j->TlspLdrBlock[ProcessTlsInformation->TlsIndex] = ProcessTlsInformation->ThreadData[i].TlsModulePointer; + } - if (ProcessHandle) { - j->TlspLdrBlock[ProcessTlsInformation->TlsIndex] = ProcessTlsInformation->ThreadData[i].TlsModulePointer; + ProcessTlsInformation->ThreadData[i].TlsModulePointer = Tls->ThreadData[i].TlsModulePointer; } - - ProcessTlsInformation->ThreadData[i].TlsModulePointer = Tls->ThreadData[i].TlsModulePointer; } + + if (found)break; + entry = entry->Flink; } - if (found)break; - entry = entry->Flink; + ProcessTlsInformation->ThreadData[i].Flags = Tls->ThreadData[i].Flags; + ProcessTlsInformation->ThreadData[i].ThreadId = Tls->ThreadData[i].ThreadId; } - ProcessTlsInformation->ThreadData[i].Flags = Tls->ThreadData[i].Flags; - ProcessTlsInformation->ThreadData[i].ThreadId = Tls->ThreadData[i].ThreadId; } LeaveCriticalSection(&MmpGlobalDataPtr->MmpTls->MmpTlspLock); From 0391e3ccc1b97baae8e81efbd9d0dea7358eb4d3 Mon Sep 17 00:00:00 2001 From: Boring <1079299053@qq.com> Date: Thu, 7 Nov 2024 17:19:37 +0800 Subject: [PATCH 14/17] add extern "C" for public api --- MemoryModule/LoadDllMemoryApi.h | 42 ++++++++++++++++++--------------- MemoryModule/Loader.h | 30 +++++++++++------------ 2 files changed, 38 insertions(+), 34 deletions(-) diff --git a/MemoryModule/LoadDllMemoryApi.h b/MemoryModule/LoadDllMemoryApi.h index f6251486..0a413b50 100644 --- a/MemoryModule/LoadDllMemoryApi.h +++ b/MemoryModule/LoadDllMemoryApi.h @@ -11,25 +11,29 @@ typedef HMODULE HMEMORYMODULE; #define NT_SUCCESS(Status) (((NTSTATUS)(Status)) >= 0) #endif -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); +extern "C" { + + 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.h b/MemoryModule/Loader.h index 8bdce287..a71afe7f 100644 --- a/MemoryModule/Loader.h +++ b/MemoryModule/Loader.h @@ -9,9 +9,6 @@ #define MEMORY_FEATURE_LDRP_RELEASE_TLS_ENTRY 0x00000040 #define MEMORY_FEATURE_ALL 0x0000007f -//Get the implementation of the currently running operating system. -NTSTATUS NTAPI LdrQuerySystemMemoryModuleFeatures(_Out_ PDWORD pFeatures); - /* LdrLoadDllMemoryEx dwFlags @@ -47,21 +44,24 @@ NTSTATUS NTAPI LdrQuerySystemMemoryModuleFeatures(_Out_ PDWORD pFeatures); //Hook for dotnet dlls #define LOAD_FLAGS_HOOK_DOT_NET 0x00000010 +extern "C" { -NTSTATUS NTAPI LdrLoadDllMemoryExW( - _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 -); + //Get the implementation of the currently running operating system. + NTSTATUS NTAPI LdrQuerySystemMemoryModuleFeatures(_Out_ PDWORD pFeatures); + + NTSTATUS NTAPI LdrLoadDllMemoryExW( + _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 + ); -//Unload modules previously loaded from memory -NTSTATUS NTAPI LdrUnloadDllMemory(_In_ HMEMORYMODULE BaseAddress); + //Unload modules previously loaded from memory + NTSTATUS NTAPI LdrUnloadDllMemory(_In_ HMEMORYMODULE BaseAddress); -extern "C" { __declspec(noreturn) VOID NTAPI LdrUnloadDllMemoryAndExitThread( _In_ HMEMORYMODULE BaseAddress, _In_ DWORD dwExitCode From 36a4377b0190acbf693f48e98bce78b860dc6400 Mon Sep 17 00:00:00 2001 From: kotori2 Date: Sun, 2 Feb 2025 00:20:59 -0800 Subject: [PATCH 15/17] Fix Ldrp finder --- MemoryModule/MmpLdrpTls.cpp | 114 ++++++++++++++++++++++++------------ 1 file changed, 77 insertions(+), 37 deletions(-) diff --git a/MemoryModule/MmpLdrpTls.cpp b/MemoryModule/MmpLdrpTls.cpp index 9b97cf60..a8deb54b 100644 --- a/MemoryModule/MmpLdrpTls.cpp +++ b/MemoryModule/MmpLdrpTls.cpp @@ -6,35 +6,13 @@ static bool stdcall; static PVOID LdrpHandleTlsData; static PVOID LdrpReleaseTlsEntry; -static NTSTATUS NTAPI RtlFindLdrpHandleTlsData() { +static NTSTATUS NTAPI RtlFindLdrpHandleTlsDataOld() { NTSTATUS status = STATUS_SUCCESS; LPCVOID Feature = nullptr; BYTE Size = 0; WORD OffsetOfFunctionBegin = 0; switch (MmpGlobalDataPtr->NtVersions.MajorVersion) { - case 10: { - if (MmpGlobalDataPtr->NtVersions.MinorVersion)return STATUS_NOT_SUPPORTED; - - if (MmpGlobalDataPtr->NtVersions.BuildNumber >= 22621) { -#ifdef _WIN64 - Feature = "\x39\x1D\x23\xFC\x17\x00\x74\x37\x44\x8D\x43\x09\x44\x39\x81\x0C\x01\x00\x00\x74\x2A"; - Size = 22; - OffsetOfFunctionBegin = 0x43; -#else - return STATUS_NOT_SUPPORTED; -#endif - } - // - // Add more conditions here. - // - // else if (MmpGlobalDataPtr->NtVersions.BuildNumber >= XXXXXXXXX) - else { - return STATUS_NOT_SUPPORTED; - } - - break; - } case 6: { switch (MmpGlobalDataPtr->NtVersions.MinorVersion) { //8.1 @@ -94,6 +72,79 @@ static NTSTATUS NTAPI RtlFindLdrpHandleTlsData() { return status; } +static NTSTATUS NTAPI RtlFindLdrpHandleTlsData10() { + LPVOID DllBase = MmpGlobalDataPtr->MmpBaseAddressIndex->NtdllLdrEntry->DllBase; +#ifdef _WIN64 + // search for LdrpHandleTls string literal + SEARCH_CONTEXT SearchContext{ SearchContext.SearchPattern = LPBYTE("LdrpHandleTlsData\x00"), SearchContext.PatternSize = 18 }; + if (!NT_SUCCESS(RtlFindMemoryBlockFromModuleSection(HMODULE(DllBase), ".rdata", &SearchContext))) + return STATUS_NOT_SUPPORTED; + LPBYTE StringOffset = SearchContext.Result; + + SearchContext.Result = nullptr; + SearchContext.PatternSize = 3; + SearchContext.SearchPattern = LPBYTE("\x48\x8D\x15"); + LPBYTE ExceptionBlock = nullptr; + + // Search for lea rdx,[rip+0x????] + // ???? is the relative offset from RIP to LdrpHandleTls string literal + while (NT_SUCCESS(RtlFindMemoryBlockFromModuleSection(HMODULE(DllBase), ".text", &SearchContext))) { + DWORD InsOff = *(DWORD*)(SearchContext.Result + 3); + if (StringOffset == SearchContext.Result + InsOff + 7) { + ExceptionBlock = SearchContext.Result; + break; + } + } + if (!ExceptionBlock) return STATUS_NOT_SUPPORTED; + + // Search back for exception block function header + while (*ExceptionBlock != 0xcc) { + // Normally ~13 bytes, but just in case... + if (SearchContext.Result - ExceptionBlock > 0x50) return STATUS_NOT_SUPPORTED; + ExceptionBlock--; + } + ExceptionBlock++; + + // search for C_SCOPE_TABLE + union Converter { + BYTE Bytes[4]; + DWORD Dword; + }; + Converter ExceptionBlockAddress{ .Dword = DWORD(ExceptionBlock - LPBYTE(DllBase)) }; + SearchContext.Result = nullptr; + SearchContext.PatternSize = 4; + SearchContext.SearchPattern = ExceptionBlockAddress.Bytes; + if (!NT_SUCCESS(RtlFindMemoryBlockFromModuleSection(HMODULE(DllBase), ".rdata", &SearchContext))) + return STATUS_NOT_SUPPORTED; + + // C_SCOPE_TABLE$$Begin + LPBYTE LdrpHandleTlsDataBlock = *(LPDWORD)(SearchContext.Result - 8) + LPBYTE(DllBase); + LPBYTE LdrpHandleTlsDataBlockBackup = LdrpHandleTlsDataBlock; + + // Search back for LdrpHandleTls + // Search up for 0xCC, and make sure it's not false positive by checking alignment (0x4) + while (*LdrpHandleTlsDataBlock != 0xcc || (((LONGLONG)LdrpHandleTlsDataBlock + 1) % 0x4) != 0) { + // Normally ~0x140 bytes + if (LdrpHandleTlsDataBlockBackup - LdrpHandleTlsDataBlock > 0x400) return STATUS_NOT_SUPPORTED; + LdrpHandleTlsDataBlock--; + } + LdrpHandleTlsDataBlock++; + LdrpHandleTlsData = LdrpHandleTlsDataBlock; + return STATUS_SUCCESS; +#else + return STATUS_NOT_SUPPORTED; +#endif +} + +static NTSTATUS NTAPI RtlFindLdrpHandleTlsData() { + if (MmpGlobalDataPtr->NtVersions.MajorVersion >= 10) { + return RtlFindLdrpHandleTlsData10(); + } + else { + return RtlFindLdrpHandleTlsDataOld(); + } +} + static NTSTATUS NTAPI RtlFindLdrpReleaseTlsEntry() { NTSTATUS status = STATUS_SUCCESS; LPCVOID Feature = nullptr; @@ -104,23 +155,12 @@ static NTSTATUS NTAPI RtlFindLdrpReleaseTlsEntry() { case 10: { if (MmpGlobalDataPtr->NtVersions.MinorVersion) return STATUS_NOT_SUPPORTED; - if (MmpGlobalDataPtr->NtVersions.BuildNumber >= 22621) { #ifdef _WIN64 - Feature = "\x74\x34\x48\x8B\x08\x48\x39\x41\x08\x75\x65\x48\x8B\x40\x08\x48\x39\x18\x75\x5C\x48\x89\x08"; - Size = 24; - OffsetOfFunctionBegin = 0x2F; + Feature = "\x48\x89\x5c\x24\x08\x57\x48\x83\xec\x20\x48\x8b\xfa\x48\x8b\xd9\x48\x85\xd2\x75\x0c"; + Size = 21; #else - return STATUS_NOT_SUPPORTED; + return STATUS_NOT_SUPPORTED; #endif - } - // - // Add more conditions here. - // - // else if (MmpGlobalDataPtr->NtVersions.BuildNumber >= XXXXXXXXX) - else { - return STATUS_NOT_SUPPORTED; - } - break; } default: From 4ae15d8ef72c7f204405594e66e44981096a0728 Mon Sep 17 00:00:00 2001 From: kotori2 Date: Thu, 6 Feb 2025 21:08:27 -0800 Subject: [PATCH 16/17] Search by 4 bytes --- MemoryModule/MmpLdrpTls.cpp | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/MemoryModule/MmpLdrpTls.cpp b/MemoryModule/MmpLdrpTls.cpp index a8deb54b..d03ce4d0 100644 --- a/MemoryModule/MmpLdrpTls.cpp +++ b/MemoryModule/MmpLdrpTls.cpp @@ -118,17 +118,19 @@ static NTSTATUS NTAPI RtlFindLdrpHandleTlsData10() { return STATUS_NOT_SUPPORTED; // C_SCOPE_TABLE$$Begin - LPBYTE LdrpHandleTlsDataBlock = *(LPDWORD)(SearchContext.Result - 8) + LPBYTE(DllBase); - LPBYTE LdrpHandleTlsDataBlockBackup = LdrpHandleTlsDataBlock; + LPDWORD LdrpHandleTlsBlock = LPDWORD(*(LPDWORD)(SearchContext.Result - 8) + LPBYTE(DllBase)); + // Pad to 0x04 + LdrpHandleTlsBlock = LPDWORD(LONGLONG(LdrpHandleTlsBlock) / 0x04 * 0x04); + LPDWORD LdrpHandleTlsBlockBackup = LdrpHandleTlsBlock; // Search back for LdrpHandleTls - // Search up for 0xCC, and make sure it's not false positive by checking alignment (0x4) - while (*LdrpHandleTlsDataBlock != 0xcc || (((LONGLONG)LdrpHandleTlsDataBlock + 1) % 0x4) != 0) { + // Search up for 4 consecutive 0xCC + while (*LdrpHandleTlsBlock != 0xcccccccc) { // Normally ~0x140 bytes - if (LdrpHandleTlsDataBlockBackup - LdrpHandleTlsDataBlock > 0x400) return STATUS_NOT_SUPPORTED; - LdrpHandleTlsDataBlock--; + if (LdrpHandleTlsBlockBackup - LdrpHandleTlsBlock > 0x400) return STATUS_NOT_SUPPORTED; + LdrpHandleTlsBlock--; } - LdrpHandleTlsDataBlock++; + LdrpHandleTlsBlock++; LdrpHandleTlsData = LdrpHandleTlsDataBlock; return STATUS_SUCCESS; #else From 588b48ebc728bb24438d2db71cf2747454593bdb Mon Sep 17 00:00:00 2001 From: Boring <1079299053@qq.com> Date: Tue, 11 Feb 2025 21:20:05 +0800 Subject: [PATCH 17/17] Add MmpTlsCleanup routine. --- MemoryModule/MmpLdrpTls.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/MemoryModule/MmpLdrpTls.cpp b/MemoryModule/MmpLdrpTls.cpp index d03ce4d0..286ddd51 100644 --- a/MemoryModule/MmpLdrpTls.cpp +++ b/MemoryModule/MmpLdrpTls.cpp @@ -110,7 +110,9 @@ static NTSTATUS NTAPI RtlFindLdrpHandleTlsData10() { BYTE Bytes[4]; DWORD Dword; }; - Converter ExceptionBlockAddress{ .Dword = DWORD(ExceptionBlock - LPBYTE(DllBase)) }; + Converter ExceptionBlockAddress{}; // { .Dword = DWORD(ExceptionBlock - LPBYTE(DllBase)) }; + ExceptionBlockAddress.Dword = DWORD(ExceptionBlock - LPBYTE(DllBase)); + SearchContext.Result = nullptr; SearchContext.PatternSize = 4; SearchContext.SearchPattern = ExceptionBlockAddress.Bytes; @@ -131,7 +133,7 @@ static NTSTATUS NTAPI RtlFindLdrpHandleTlsData10() { LdrpHandleTlsBlock--; } LdrpHandleTlsBlock++; - LdrpHandleTlsData = LdrpHandleTlsDataBlock; + LdrpHandleTlsData = LdrpHandleTlsBlock; return STATUS_SUCCESS; #else return STATUS_NOT_SUPPORTED; @@ -192,6 +194,10 @@ BOOL NTAPI MmpTlsInitialize() { return TRUE; } +VOID NTAPI MmpTlsCleanup() { + ; +} + NTSTATUS NTAPI MmpReleaseTlsEntry(_In_ PLDR_DATA_TABLE_ENTRY lpModuleEntry) { typedef NTSTATUS(__stdcall* STDCALL)(PLDR_DATA_TABLE_ENTRY, PVOID*); typedef NTSTATUS(__thiscall* THISCALL)(PLDR_DATA_TABLE_ENTRY, PVOID*);