diff --git a/MemoryModule/Initialize.cpp b/MemoryModule/Initialize.cpp index 173f337..fe1d12e 100644 --- a/MemoryModule/Initialize.cpp +++ b/MemoryModule/Initialize.cpp @@ -446,6 +446,7 @@ NTSTATUS InitializeLockHeld() { MmpGlobalDataPtr->MmpLdrEntry = (PMMP_LDR_ENTRY_DATA)((LPBYTE)MmpGlobalDataPtr->MmpInvertedFunctionTable + sizeof(MMP_INVERTED_FUNCTION_TABLE_DATA)); MmpGlobalDataPtr->MmpTls = (PMMP_TLS_DATA)((LPBYTE)MmpGlobalDataPtr->MmpLdrEntry + sizeof(MMP_LDR_ENTRY_DATA)); MmpGlobalDataPtr->MmpDotNet = (PMMP_DOT_NET_DATA)((LPBYTE)MmpGlobalDataPtr->MmpTls + sizeof(MMP_TLS_DATA)); + MmpGlobalDataPtr->MmpFunctions = (PMMP_FUNCTIONS)((LPBYTE)MmpGlobalDataPtr->MmpDotNet + sizeof(MMP_DOT_NET_DATA)); PLDR_DATA_TABLE_ENTRY pNtdllEntry = RtlFindLdrTableEntryByBaseName(L"ntdll.dll"); MmpGlobalDataPtr->MmpBaseAddressIndex->NtdllLdrEntry = pNtdllEntry; @@ -462,6 +463,12 @@ NTSTATUS InitializeLockHeld() { if (MmpGlobalDataPtr->MmpLdrEntry->LdrpHashTable)MmpGlobalDataPtr->MmpFeatures |= MEMORY_FEATURE_LDRP_HASH_TABLE; if (MmpGlobalDataPtr->MmpInvertedFunctionTable->LdrpInvertedFunctionTable)MmpGlobalDataPtr->MmpFeatures |= MEMORY_FEATURE_INVERTED_FUNCTION_TABLE; + MmpGlobalDataPtr->MmpFunctions->_LdrLoadDllMemoryExW = LdrLoadDllMemoryExW; + MmpGlobalDataPtr->MmpFunctions->_LdrUnloadDllMemory = LdrUnloadDllMemory; + MmpGlobalDataPtr->MmpFunctions->_LdrUnloadDllMemoryAndExitThread = LdrUnloadDllMemoryAndExitThread; + MmpGlobalDataPtr->MmpFunctions->_MmpHandleTlsData = MmpHandleTlsData; + MmpGlobalDataPtr->MmpFunctions->_MmpReleaseTlsEntry = MmpReleaseTlsEntry; + MmpTlsInitialize(); MmpGlobalDataPtr->MmpDotNet->Initialized = MmpGlobalDataPtr->MmpDotNet->PreHooked = FALSE; diff --git a/MemoryModule/Loader.cpp b/MemoryModule/Loader.cpp index efc5c46..d2ebde3 100644 --- a/MemoryModule/Loader.cpp +++ b/MemoryModule/Loader.cpp @@ -158,7 +158,7 @@ NTSTATUS NTAPI LdrLoadDllMemoryExW( } if (!(dwFlags & LOAD_FLAGS_NOT_HANDLE_TLS)) { - status = MmpHandleTlsData(ModuleEntry); + status = MmpGlobalDataPtr->MmpFunctions->_MmpHandleTlsData(ModuleEntry); if (!NT_SUCCESS(status)) { if (dwFlags & LOAD_FLAGS_NOT_FAIL_IF_HANDLE_TLS) status = 0x7fffffff; if (!NT_SUCCESS(status))break; @@ -246,7 +246,7 @@ NTSTATUS NTAPI LdrUnloadDllMemory(_In_ HMEMORYMODULE BaseAddress) { } if (module->TlsHandled) { - status = MmpReleaseTlsEntry(CurEntry); + status = MmpGlobalDataPtr->MmpFunctions->_MmpReleaseTlsEntry(CurEntry); if (!NT_SUCCESS(status)) __fastfail(FAST_FAIL_FATAL_APP_EXIT); } diff --git a/MemoryModule/MemoryModule.vcxproj b/MemoryModule/MemoryModule.vcxproj index 526246d..faee58b 100644 --- a/MemoryModule/MemoryModule.vcxproj +++ b/MemoryModule/MemoryModule.vcxproj @@ -49,6 +49,7 @@ + diff --git a/MemoryModule/MemoryModule.vcxproj.filters b/MemoryModule/MemoryModule.vcxproj.filters index 2aa9155..201a6b5 100644 --- a/MemoryModule/MemoryModule.vcxproj.filters +++ b/MemoryModule/MemoryModule.vcxproj.filters @@ -90,6 +90,9 @@ Source Files + + Source Files + diff --git a/MemoryModule/MmpGlobalData.h b/MemoryModule/MmpGlobalData.h index e93adf1..6bc58f8 100644 --- a/MemoryModule/MmpGlobalData.h +++ b/MemoryModule/MmpGlobalData.h @@ -63,6 +63,15 @@ typedef struct _MMP_DOT_NET_DATA { }Hooks; }MMP_DOT_NET_DATA, * PMMP_DOT_NET_DATA; +typedef struct _MMP_FUNCTIONS { + decltype(&LdrLoadDllMemoryExW) _LdrLoadDllMemoryExW; + decltype(&LdrUnloadDllMemory) _LdrUnloadDllMemory; + decltype(&LdrUnloadDllMemoryAndExitThread) _LdrUnloadDllMemoryAndExitThread; + + decltype(&MmpHandleTlsData) _MmpHandleTlsData; + decltype(&MmpReleaseTlsEntry) _MmpReleaseTlsEntry; +}MMP_FUNCTIONS, * PMMP_FUNCTIONS; + typedef enum class _WINDOWS_VERSION :BYTE { null, xp, @@ -78,7 +87,7 @@ typedef enum class _WINDOWS_VERSION :BYTE { }WINDOWS_VERSION; #define MEMORY_MODULE_MAJOR_VERSION 1 -#define MEMORY_MODULE_MINOR_VERSION 2 +#define MEMORY_MODULE_MINOR_VERSION 3 typedef struct _MMP_GLOBAL_DATA { @@ -111,6 +120,8 @@ typedef struct _MMP_GLOBAL_DATA { PVOID BaseAddress; + PMMP_FUNCTIONS MmpFunctions; + }MMP_GLOBAL_DATA, * PMMP_GLOBAL_DATA; #define MMP_GLOBAL_DATA_SIZE (\ @@ -119,7 +130,8 @@ typedef struct _MMP_GLOBAL_DATA { sizeof(MMP_INVERTED_FUNCTION_TABLE_DATA) + \ sizeof(MMP_LDR_ENTRY_DATA) + \ sizeof(MMP_TLS_DATA) + \ - sizeof(MMP_DOT_NET_DATA)\ + sizeof(MMP_DOT_NET_DATA) + \ + sizeof(PMMP_FUNCTIONS)\ ) extern PMMP_GLOBAL_DATA MmpGlobalDataPtr; diff --git a/MemoryModule/MmpLdrpTls.cpp b/MemoryModule/MmpLdrpTls.cpp new file mode 100644 index 0000000..008de30 --- /dev/null +++ b/MemoryModule/MmpLdrpTls.cpp @@ -0,0 +1,189 @@ +#include "stdafx.h" + +#if (!MMPP_USE_TLS) + +static bool stdcall; +static PVOID LdrpHandleTlsData; +static PVOID LdrpReleaseTlsEntry; + +static NTSTATUS NTAPI RtlFindLdrpHandleTlsData() { + 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 + case 3: { +#ifdef _WIN64 + Size = 10; + OffsetOfFunctionBegin = 0x43; + Feature = "\x44\x8d\x43\x09\x4c\x8d\x4c\x24\x38"; +#else + Size = 8; + OffsetOfFunctionBegin = 0x1B; + Feature = "\x50\x6a\x09\x6a\x01\x8b\xc1"; +#endif + break; + } + //8 + case 2: { +#ifdef _WIN64 + Size = 9; + OffsetOfFunctionBegin = 0x49; + Feature = "\x48\x8b\x79\x30\x45\x8d\x66\x01"; +#else + Size = 7; + OffsetOfFunctionBegin = 0xC; + Feature = "\x8b\x45\x08\x89\x45\xa0"; +#endif + break; + } + //7 + case 1: { +#ifdef _WIN64 + Size = 12; + OffsetOfFunctionBegin = 0x27; + Feature = "\x41\xb8\x09\x00\x00\x00\x48\x8d\x44\x24\x38"; +#else + Size = 9; + OffsetOfFunctionBegin = 0x14; + Feature = "\x74\x20\x8d\x45\xd4\x50\x6a\x09"; +#endif + break; + } + default:return STATUS_NOT_SUPPORTED; + } + break; + } + + default: { + return STATUS_NOT_SUPPORTED; + } + } + + SEARCH_CONTEXT SearchContext{ SearchContext.SearchPattern = LPBYTE(Feature),SearchContext.PatternSize = Size - 1 }; + if (!NT_SUCCESS(RtlFindMemoryBlockFromModuleSection(HMODULE(MmpGlobalDataPtr->MmpBaseAddressIndex->NtdllLdrEntry->DllBase), ".text", &SearchContext))) + return STATUS_NOT_SUPPORTED; + + LdrpHandleTlsData = SearchContext.Result - OffsetOfFunctionBegin; + return status; +} + +static NTSTATUS NTAPI RtlFindLdrpReleaseTlsEntry() { + 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 = "\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; +#else + return STATUS_NOT_SUPPORTED; +#endif + } + // + // Add more conditions here. + // + // else if (MmpGlobalDataPtr->NtVersions.BuildNumber >= XXXXXXXXX) + else { + return STATUS_NOT_SUPPORTED; + } + + break; + } + default: + return STATUS_NOT_SUPPORTED; + } + + SEARCH_CONTEXT SearchContext{ SearchContext.SearchPattern = LPBYTE(Feature),SearchContext.PatternSize = Size - 1 }; + if (!NT_SUCCESS(RtlFindMemoryBlockFromModuleSection(HMODULE(MmpGlobalDataPtr->MmpBaseAddressIndex->NtdllLdrEntry->DllBase), ".text", &SearchContext))) + return STATUS_NOT_SUPPORTED; + + LdrpReleaseTlsEntry = SearchContext.Result - OffsetOfFunctionBegin; + return status; +} + +BOOL NTAPI MmpTlsInitialize() { + if (!NT_SUCCESS(RtlFindLdrpHandleTlsData()) || + !NT_SUCCESS(RtlFindLdrpReleaseTlsEntry())) { + MmpGlobalDataPtr->MmpFeatures &= ~MEMORY_FEATURE_LDRP_HANDLE_TLS_DATA; + return FALSE; + } + + stdcall = !RtlIsWindowsVersionOrGreater(6, 3, 0); + return TRUE; +} + +NTSTATUS NTAPI MmpReleaseTlsEntry(_In_ PLDR_DATA_TABLE_ENTRY lpModuleEntry) { + typedef NTSTATUS(__stdcall* STDCALL)(PLDR_DATA_TABLE_ENTRY); + typedef NTSTATUS(__stdcall* THISCALL)(PLDR_DATA_TABLE_ENTRY); + + union { + STDCALL stdcall; + THISCALL thiscall; + + PVOID ptr; + }fp; + fp.ptr = LdrpReleaseTlsEntry; + + if (fp.ptr) { + return stdcall ? fp.stdcall(lpModuleEntry): fp.thiscall(lpModuleEntry); + } + else { + return STATUS_NOT_SUPPORTED; + } +} + +NTSTATUS NTAPI MmpHandleTlsData(_In_ PLDR_DATA_TABLE_ENTRY lpModuleEntry) { + typedef NTSTATUS(__stdcall* STDCALL)(PLDR_DATA_TABLE_ENTRY); + typedef NTSTATUS(__stdcall* THISCALL)(PLDR_DATA_TABLE_ENTRY); + + union { + STDCALL stdcall; + THISCALL thiscall; + + PVOID ptr; + }fp; + fp.ptr = LdrpHandleTlsData; + + if (fp.ptr) { + return stdcall ? fp.stdcall(lpModuleEntry) : fp.thiscall(lpModuleEntry); + } + else { + return STATUS_NOT_SUPPORTED; + } +} + +#endif diff --git a/MemoryModule/MmpTls.cpp b/MemoryModule/MmpTls.cpp index 4f1960b..98f6fb7 100644 --- a/MemoryModule/MmpTls.cpp +++ b/MemoryModule/MmpTls.cpp @@ -1,4 +1,6 @@ #include "stdafx.h" + +#if (MMPP_USE_TLS) #include #include #include <3rdparty/Detours/detours.h> @@ -849,3 +851,5 @@ BOOL NTAPI MmpTlsInitialize() { return TRUE; } + +#endif diff --git a/MemoryModule/stdafx.h b/MemoryModule/stdafx.h index 0affb02..3e8708e 100644 --- a/MemoryModule/stdafx.h +++ b/MemoryModule/stdafx.h @@ -8,6 +8,11 @@ #include #endif +// +// Determine whether to use MmpTls(1) or LdrpTls(0) +// +#define MMPP_USE_TLS 1 + // offsetof() #include