This commit is contained in:
Boring
2022-10-01 16:28:02 +08:00
parent d6f0715c49
commit ad7986eb6c
9 changed files with 144 additions and 130 deletions
+2 -2
View File
@@ -1,7 +1,7 @@
#include "stdafx.h"
NTSTATUS NTAPI RtlInsertModuleBaseAddressIndexNode(IN PLDR_DATA_TABLE_ENTRY DataTableEntry, IN PVOID BaseAddress) {
auto LdrpModuleBaseAddressIndex = MmpGlobalDataPtr->LdrpModuleBaseAddressIndex;
auto LdrpModuleBaseAddressIndex = MmpGlobalDataPtr->MmpBaseAddressIndex.LdrpModuleBaseAddressIndex;
if (!LdrpModuleBaseAddressIndex)return STATUS_UNSUCCESSFUL;
PLDR_DATA_TABLE_ENTRY_WIN8 LdrNode = decltype(LdrNode)((size_t)LdrpModuleBaseAddressIndex - offsetof(LDR_DATA_TABLE_ENTRY_WIN8, BaseAddressIndexNode));
@@ -33,7 +33,7 @@ NTSTATUS NTAPI RtlInsertModuleBaseAddressIndexNode(IN PLDR_DATA_TABLE_ENTRY Data
}
NTSTATUS NTAPI RtlRemoveModuleBaseAddressIndexNode(IN PLDR_DATA_TABLE_ENTRY DataTableEntry) {
static auto tree{ MmpGlobalDataPtr->LdrpModuleBaseAddressIndex };
static auto tree{ MmpGlobalDataPtr->MmpBaseAddressIndex.LdrpModuleBaseAddressIndex };
if (!tree->Root)return STATUS_UNSUCCESSFUL;
RtlRbRemoveNode(tree, &PLDR_DATA_TABLE_ENTRY_WIN8(DataTableEntry)->BaseAddressIndexNode);
return STATUS_SUCCESS;
+12 -8
View File
@@ -18,7 +18,7 @@ BOOLEAN MmpBuildSectionName(_Out_ PUNICODE_STRING SectionName) {
PRTL_RB_TREE FindLdrpModuleBaseAddressIndex() {
PRTL_RB_TREE LdrpModuleBaseAddressIndex = nullptr;
PLDR_DATA_TABLE_ENTRY_WIN10 nt10 = decltype(nt10)(MmpGlobalDataPtr->LdrpNtdllBase);
PLDR_DATA_TABLE_ENTRY_WIN10 nt10 = decltype(nt10)(MmpGlobalDataPtr->MmpBaseAddressIndex.NtdllLdrEntry);
PRTL_BALANCED_NODE node = nullptr;
if (!nt10 || !RtlIsWindowsVersionOrGreater(6, 2, 0))return nullptr;
node = &nt10->BaseAddressIndexNode;
@@ -253,20 +253,24 @@ NTSTATUS InitializeLockHeld() {
MmpGlobalDataPtr->MajorVersion = 1;
MmpGlobalDataPtr->MinorVersion = 0;
MmpGlobalDataPtr->LdrpNtdllBase = RtlFindNtdllLdrEntry();
MmpGlobalDataPtr->LdrpHashTable = FindLdrpHashTable();
GetSystemInfo(&MmpGlobalDataPtr->SystemInfo);
MmpGlobalDataPtr->LdrpModuleBaseAddressIndex = FindLdrpModuleBaseAddressIndex();
MmpGlobalDataPtr->MmpBaseAddressIndex.NtdllLdrEntry = RtlFindLdrTableEntryByBaseName(L"ntdll.dll");
MmpGlobalDataPtr->MmpBaseAddressIndex.LdrpModuleBaseAddressIndex = FindLdrpModuleBaseAddressIndex();
MmpGlobalDataPtr->LdrpInvertedFunctionTable = FindLdrpInvertedFunctionTable();
MmpGlobalDataPtr->MmpLdrEntry.LdrpHashTable = FindLdrpHashTable();
MmpGlobalDataPtr->MmpInvertedFunctionTable.LdrpInvertedFunctionTable = FindLdrpInvertedFunctionTable();
MmpGlobalDataPtr->MmpFeatures = MEMORY_FEATURE_SUPPORT_VERSION | MEMORY_FEATURE_LDRP_HEAP | MEMORY_FEATURE_LDRP_HANDLE_TLS_DATA | MEMORY_FEATURE_LDRP_RELEASE_TLS_ENTRY;
if (MmpGlobalDataPtr->LdrpModuleBaseAddressIndex)MmpGlobalDataPtr->MmpFeatures |= MEMORY_FEATURE_MODULE_BASEADDRESS_INDEX;
if (MmpGlobalDataPtr->LdrpHashTable)MmpGlobalDataPtr->MmpFeatures |= MEMORY_FEATURE_LDRP_HASH_TABLE;
if (MmpGlobalDataPtr->LdrpInvertedFunctionTable)MmpGlobalDataPtr->MmpFeatures |= MEMORY_FEATURE_INVERTED_FUNCTION_TABLE;
if (MmpGlobalDataPtr->MmpBaseAddressIndex.LdrpModuleBaseAddressIndex)MmpGlobalDataPtr->MmpFeatures |= MEMORY_FEATURE_MODULE_BASEADDRESS_INDEX;
if (MmpGlobalDataPtr->MmpLdrEntry.LdrpHashTable)MmpGlobalDataPtr->MmpFeatures |= MEMORY_FEATURE_LDRP_HASH_TABLE;
if (MmpGlobalDataPtr->MmpInvertedFunctionTable.LdrpInvertedFunctionTable)MmpGlobalDataPtr->MmpFeatures |= MEMORY_FEATURE_INVERTED_FUNCTION_TABLE;
MmpTlsInitialize();
MmpGlobalDataPtr->MmpDotNet.Initialized = MmpGlobalDataPtr->MmpDotNet.PreHooked = FALSE;
} while (false);
if (!NT_SUCCESS(status) && hSection)NtClose(hSection);
+3 -3
View File
@@ -146,7 +146,7 @@ static NTSTATUS NTAPI RtlProtectMrdata(IN SIZE_T Protect) {
if (!MrdataBase) {
MEMORY_BASIC_INFORMATION mbi{};
status = NtQueryVirtualMemory(GetCurrentProcess(), MmpGlobalDataPtr->LdrpInvertedFunctionTable, MemoryBasicInformation, &mbi, sizeof(mbi), nullptr);
status = NtQueryVirtualMemory(GetCurrentProcess(), MmpGlobalDataPtr->MmpInvertedFunctionTable.LdrpInvertedFunctionTable, MemoryBasicInformation, &mbi, sizeof(mbi), nullptr);
if (!NT_SUCCESS(status))return status;
MrdataBase = mbi.BaseAddress;
size = mbi.RegionSize;
@@ -158,7 +158,7 @@ static NTSTATUS NTAPI RtlProtectMrdata(IN SIZE_T Protect) {
}
NTSTATUS NTAPI RtlInsertInvertedFunctionTable(IN PVOID BaseAddress, IN size_t ImageSize) {
auto table = PRTL_INVERTED_FUNCTION_TABLE(MmpGlobalDataPtr->LdrpInvertedFunctionTable);
auto table = PRTL_INVERTED_FUNCTION_TABLE(MmpGlobalDataPtr->MmpInvertedFunctionTable.LdrpInvertedFunctionTable);
if (!table)return STATUS_NOT_SUPPORTED;
bool need_virtual_protect = RtlIsWindowsVersionOrGreater(6, 3, 0);
NTSTATUS status;
@@ -177,7 +177,7 @@ NTSTATUS NTAPI RtlInsertInvertedFunctionTable(IN PVOID BaseAddress, IN size_t Im
}
NTSTATUS NTAPI RtlRemoveInvertedFunctionTable(IN PVOID ImageBase) {
auto table = PRTL_INVERTED_FUNCTION_TABLE(MmpGlobalDataPtr->LdrpInvertedFunctionTable);
auto table = PRTL_INVERTED_FUNCTION_TABLE(MmpGlobalDataPtr->MmpInvertedFunctionTable.LdrpInvertedFunctionTable);
bool need_virtual_protect = RtlIsWindowsVersionOrGreater(6, 3, 0);
NTSTATUS status;
+1 -3
View File
@@ -1,8 +1,6 @@
#include "stdafx.h"
#include <cstddef>
PLDR_DATA_TABLE_ENTRY const LdrpNtdllBase = RtlFindLdrTableEntryByBaseName(L"ntdll.dll");
static NTSTATUS NTAPI RtlFreeDependencies(IN PLDR_DATA_TABLE_ENTRY_WIN10 LdrEntry) {
_LDR_DDAG_NODE* DependentDdgeNode = nullptr;
PLDR_DATA_TABLE_ENTRY_WIN10 ModuleEntry = nullptr;
@@ -254,7 +252,7 @@ NTSTATUS NTAPI RtlGetReferenceCount(IN PMEMORYMODULE pModule, OUT PULONG Count)
VOID NTAPI RtlInsertMemoryTableEntry(IN PLDR_DATA_TABLE_ENTRY LdrEntry) {
PPEB_LDR_DATA PebData = NtCurrentPeb()->Ldr;
PLIST_ENTRY LdrpHashTable = MmpGlobalDataPtr->LdrpHashTable;
PLIST_ENTRY LdrpHashTable = MmpGlobalDataPtr->MmpLdrEntry.LdrpHashTable;
ULONG i;
/* Insert into hash table */
-6
View File
@@ -19,12 +19,6 @@ PLDR_DATA_TABLE_ENTRY NTAPI RtlFindLdrTableEntryByHandle(PVOID BaseAddress);
PLDR_DATA_TABLE_ENTRY NTAPI RtlFindLdrTableEntryByBaseName(PCWSTR BaseName);
extern PLDR_DATA_TABLE_ENTRY const LdrpNtdllBase;
#define RtlFindNtdllLdrEntry() (LdrpNtdllBase)
//
// Loader Data Table Entry Flags
//
+18 -24
View File
@@ -8,6 +8,23 @@
#define GET_HEADER_DICTIONARY(headers, idx) &headers->OptionalHeader.DataDirectory[idx]
#define AlignValueUp(value, alignment) ((size_t(value) + size_t(alignment) + 1) & ~(size_t(alignment) - 1))
#define OffsetPointer(data, offset) LPVOID(LPBYTE(data) + ptrdiff_t(offset))
// Protection flags for memory pages (Executable, Readable, Writeable)
static const int ProtectionFlags[2][2][2] = {
{
// not executable
{PAGE_NOACCESS, PAGE_WRITECOPY},
{PAGE_READONLY, PAGE_READWRITE},
}, {
// executable
{PAGE_EXECUTE, PAGE_EXECUTE_WRITECOPY},
{PAGE_EXECUTE_READ, PAGE_EXECUTE_READWRITE},
},
};
int MmpSizeOfImageHeadersUnsafe(PVOID BaseAddress) {
PIMAGE_DOS_HEADER dh = (PIMAGE_DOS_HEADER)BaseAddress;
PIMAGE_NT_HEADERS nh = (PIMAGE_NT_HEADERS)((LPBYTE)BaseAddress + dh->e_lfanew);
@@ -38,29 +55,6 @@ bool WINAPI IsValidMemoryModuleHandle(HMEMORYMODULE hModule) {
return MapMemoryModuleHandle(hModule) != nullptr;
}
#define AlignValueUp(value, alignment) ((size_t(value) + size_t(alignment) + 1) & ~(size_t(alignment) - 1))
#define OffsetPointer(data, offset) LPVOID(LPBYTE(data) + ptrdiff_t(offset))
// Protection flags for memory pages (Executable, Readable, Writeable)
static int ProtectionFlags[2][2][2] = {
{
// not executable
{PAGE_NOACCESS, PAGE_WRITECOPY},
{PAGE_READONLY, PAGE_READWRITE},
}, {
// executable
{PAGE_EXECUTE, PAGE_EXECUTE_WRITECOPY},
{PAGE_EXECUTE_READ, PAGE_EXECUTE_READWRITE},
},
};
static SYSTEM_INFO sysInfo = []()->SYSTEM_INFO {
SYSTEM_INFO tmp;
GetNativeSystemInfo(&tmp);
return tmp;
}();
NTSTATUS MemoryResolveImportTable(
_In_ LPBYTE base,
@@ -271,7 +265,7 @@ NTSTATUS MemoryLoadLibrary(
//
// Allocate memory for image headers
//
size_t alignedHeadersSize = (DWORD)AlignValueUp(old_header->OptionalHeader.SizeOfHeaders + sizeof(MEMORYMODULE), sysInfo.dwPageSize);
size_t alignedHeadersSize = (DWORD)AlignValueUp(old_header->OptionalHeader.SizeOfHeaders + sizeof(MEMORYMODULE), MmpGlobalDataPtr->SystemInfo.dwPageSize);
if (!VirtualAlloc(base, alignedHeadersSize, MEM_COMMIT, PAGE_READWRITE)) {
VirtualFree(base, 0, MEM_RELEASE);
status = STATUS_NO_MEMORY;
+19 -27
View File
@@ -28,14 +28,6 @@ static decltype(&CloseHandle)OriginCloseHandle = CloseHandle;
static GetFileVersion_T OriginGetFileVersion1 = nullptr;
static GetFileVersion_T OriginGetFileVersion2 = nullptr;
FILETIME AssemblyTimes;
CRITICAL_SECTION MmpFakeHandleListLock;
LIST_ENTRY MmpFakeHandleListHead;
static BOOLEAN g_PreHooked = FALSE;
static BOOLEAN g_Initialized = FALSE;
BOOL MmpIsMemoryModuleFileName(
_In_ LPCWSTR lpFileName,
_Out_opt_ PLDR_DATA_TABLE_ENTRY *LdrEntry) {
@@ -87,17 +79,17 @@ VOID MmpInsertHandleEntry(
entry->value = value;
entry->bImageMapping = bImageMapping;
EnterCriticalSection(&MmpFakeHandleListLock);
InsertTailList(&MmpFakeHandleListHead, &entry->InMmpFakeHandleList);
LeaveCriticalSection(&MmpFakeHandleListLock);
EnterCriticalSection(&MmpGlobalDataPtr->MmpDotNet.MmpFakeHandleListLock);
InsertTailList(&MmpGlobalDataPtr->MmpDotNet.MmpFakeHandleListHead, &entry->InMmpFakeHandleList);
LeaveCriticalSection(&MmpGlobalDataPtr->MmpDotNet.MmpFakeHandleListLock);
}
PMMP_FAKE_HANDLE_LIST_ENTRY MmpFindHandleEntry(HANDLE hObject) {
PMMP_FAKE_HANDLE_LIST_ENTRY result = nullptr;
EnterCriticalSection(&MmpFakeHandleListLock);
EnterCriticalSection(&MmpGlobalDataPtr->MmpDotNet.MmpFakeHandleListLock);
for (auto entry = MmpFakeHandleListHead.Flink; entry != &MmpFakeHandleListHead; entry = entry->Flink) {
for (auto entry = MmpGlobalDataPtr->MmpDotNet.MmpFakeHandleListHead.Flink; entry != &MmpGlobalDataPtr->MmpDotNet.MmpFakeHandleListHead; entry = entry->Flink) {
auto CurEntry = CONTAINING_RECORD(entry, MMP_FAKE_HANDLE_LIST_ENTRY, MMP_FAKE_HANDLE_LIST_ENTRY::InMmpFakeHandleList);
if (CurEntry->hObject == hObject) {
@@ -107,15 +99,15 @@ PMMP_FAKE_HANDLE_LIST_ENTRY MmpFindHandleEntry(HANDLE hObject) {
}
LeaveCriticalSection(&MmpFakeHandleListLock);
LeaveCriticalSection(&MmpGlobalDataPtr->MmpDotNet.MmpFakeHandleListLock);
return result;
}
VOID MmpFreeHandleEntry(PMMP_FAKE_HANDLE_LIST_ENTRY lpHandleEntry) {
EnterCriticalSection(&MmpFakeHandleListLock);
EnterCriticalSection(&MmpGlobalDataPtr->MmpDotNet.MmpFakeHandleListLock);
RemoveEntryList(&lpHandleEntry->InMmpFakeHandleList);
RtlFreeHeap(RtlProcessHeap(), 0, lpHandleEntry);
LeaveCriticalSection(&MmpFakeHandleListLock);
LeaveCriticalSection(&MmpGlobalDataPtr->MmpDotNet.MmpFakeHandleListLock);
}
HANDLE WINAPI HookCreateFileW(
@@ -156,7 +148,7 @@ BOOL WINAPI HookGetFileInformationByHandle(
auto entry = (PLDR_DATA_TABLE_ENTRY)iter->value;
auto module = MapMemoryModuleHandle((HMEMORYMODULE)entry->DllBase);
lpFileInformation->ftCreationTime = lpFileInformation->ftLastAccessTime = lpFileInformation->ftLastWriteTime = AssemblyTimes;
lpFileInformation->ftCreationTime = lpFileInformation->ftLastAccessTime = lpFileInformation->ftLastWriteTime = MmpGlobalDataPtr->MmpDotNet.AssemblyTimes;
lpFileInformation->nFileSizeLow = module->dwImageFileSize;
return TRUE;
@@ -185,7 +177,7 @@ BOOL WINAPI HookGetFileAttributesExW(
LPWIN32_FILE_ATTRIBUTE_DATA data = (LPWIN32_FILE_ATTRIBUTE_DATA)lpFileInformation;
auto module = MapMemoryModuleHandle((HMEMORYMODULE)entry->DllBase);
data->ftCreationTime = data->ftLastAccessTime = data->ftLastWriteTime = AssemblyTimes;
data->ftCreationTime = data->ftLastAccessTime = data->ftLastWriteTime = MmpGlobalDataPtr->MmpDotNet.AssemblyTimes;
data->nFileSizeLow = module->dwImageFileSize;
return TRUE;
}
@@ -394,16 +386,16 @@ BOOL WINAPI MmpPreInitializeHooksForDotNet() {
EnterCriticalSection(NtCurrentPeb()->FastPebLock);
if (!g_PreHooked) {
if (!MmpGlobalDataPtr->MmpDotNet.PreHooked) {
HMODULE hModule = LoadLibraryW(L"mscoree.dll");
if (hModule) {
OriginGetFileVersion2 = (GetFileVersion_T)GetProcAddress(hModule, "GetFileVersion");
if (OriginGetFileVersion2) {
GetSystemTimeAsFileTime(&AssemblyTimes);
GetSystemTimeAsFileTime(&MmpGlobalDataPtr->MmpDotNet.AssemblyTimes);
InitializeCriticalSection(&MmpFakeHandleListLock);
InitializeListHead(&MmpFakeHandleListHead);
InitializeCriticalSection(&MmpGlobalDataPtr->MmpDotNet.MmpFakeHandleListLock);
InitializeListHead(&MmpGlobalDataPtr->MmpDotNet.MmpFakeHandleListHead);
DetourTransactionBegin();
DetourUpdateThread(NtCurrentThread());
@@ -422,14 +414,14 @@ BOOL WINAPI MmpPreInitializeHooksForDotNet() {
DetourTransactionCommit();
g_PreHooked = TRUE;
MmpGlobalDataPtr->MmpDotNet.PreHooked = TRUE;
}
}
}
LeaveCriticalSection(NtCurrentPeb()->FastPebLock);
return g_PreHooked;
return MmpGlobalDataPtr->MmpDotNet.PreHooked;
}
BOOL WINAPI MmpInitializeHooksForDotNet() {
@@ -440,17 +432,17 @@ BOOL WINAPI MmpInitializeHooksForDotNet() {
EnterCriticalSection(NtCurrentPeb()->FastPebLock);
if (!g_PreHooked) {
if (!MmpGlobalDataPtr->MmpDotNet.PreHooked) {
LeaveCriticalSection(NtCurrentPeb()->FastPebLock);
return FALSE;
}
if (!g_Initialized) {
if (!MmpGlobalDataPtr->MmpDotNet.Initialized) {
DetourTransactionBegin();
DetourUpdateThread(NtCurrentThread());
DetourAttach((PVOID*)&OriginGetFileVersion1, HookGetFileVersion);
DetourTransactionCommit();
g_Initialized = TRUE;
MmpGlobalDataPtr->MmpDotNet.Initialized = TRUE;
}
LeaveCriticalSection(NtCurrentPeb()->FastPebLock);
+47 -15
View File
@@ -1,5 +1,42 @@
#pragma once
//BaseAddressIndex.cpp
typedef struct _MMP_BASE_ADDRESS_INDEX_DATA {
PRTL_RB_TREE LdrpModuleBaseAddressIndex;
PLDR_DATA_TABLE_ENTRY NtdllLdrEntry;
}MMP_BASE_ADDRESS_INDEX_DATA, * PMMP_BASE_ADDRESS_INDEX_DATA;
//InvertedFunctionTable.cpp
typedef struct _MMP_INVERTED_FUNCTION_TABLE_DATA {
PVOID LdrpInvertedFunctionTable;
}MMP_INVERTED_FUNCTION_TABLE_DATA, * PMMP_INVERTED_FUNCTION_TABLE_DATA;
//LdrEntry.cpp
typedef struct _MMP_LDR_ENTRY_DATA {
PLIST_ENTRY LdrpHashTable;
}MMP_LDR_ENTRY_DATA, * PMMP_LDR_ENTRY_DATA;
//MmpTls.cpp
typedef struct _MMP_TLS_DATA {
LIST_ENTRY MmpTlsList;
RTL_BITMAP MmpTlsBitmap;
SRWLOCK MmpTlsListLock;
CRITICAL_SECTION MmpTlspLock;
LIST_ENTRY MmpThreadLocalStoragePointer;
DWORD MmpActiveThreadCount;
}MMP_TLS_DATA, * PMMP_TLS_DATA;
//MmpDotNet.cpp
typedef struct _MMP_DOT_NET_DATA {
FILETIME AssemblyTimes;
CRITICAL_SECTION MmpFakeHandleListLock;
LIST_ENTRY MmpFakeHandleListHead;
BOOLEAN PreHooked;
BOOLEAN Initialized;
}MMP_DOT_NET_DATA, * PMMP_DOT_NET_DATA;
typedef struct _MMP_GLOBAL_DATA {
WORD MajorVersion;
@@ -7,23 +44,18 @@ typedef struct _MMP_GLOBAL_DATA {
DWORD MmpFeatures;
//BaseAddressIndex.cpp
PRTL_RB_TREE LdrpModuleBaseAddressIndex;
SYSTEM_INFO SystemInfo;
//InvertedFunctionTable.cpp
PVOID LdrpInvertedFunctionTable;
MMP_BASE_ADDRESS_INDEX_DATA MmpBaseAddressIndex;
//LdrEntry.cpp
PLDR_DATA_TABLE_ENTRY LdrpNtdllBase;
PLIST_ENTRY LdrpHashTable;
MMP_INVERTED_FUNCTION_TABLE_DATA MmpInvertedFunctionTable;
MMP_LDR_ENTRY_DATA MmpLdrEntry;
MMP_TLS_DATA MmpTls;
MMP_DOT_NET_DATA MmpDotNet;
//MmpTls.cpp
LIST_ENTRY MmpTlsList;
RTL_BITMAP MmpTlsBitmap;
SRWLOCK MmpTlsListLock;
CRITICAL_SECTION MmpTlspLock;
LIST_ENTRY MmpThreadLocalStoragePointer;
DWORD MmpActiveThreadCount;
}MMP_GLOBAL_DATA, * PMMP_GLOBAL_DATA;
extern PMMP_GLOBAL_DATA MmpGlobalDataPtr;
extern PMMP_GLOBAL_DATA MmpGlobalDataPtr;
+42 -42
View File
@@ -159,7 +159,7 @@ DWORD NTAPI MmpUserThreadStart(LPVOID lpThreadParameter) {
//
// Allocate and replace ThreadLocalStoragePointer for new thread
//
EnterCriticalSection(&MmpGlobalDataPtr->MmpTlspLock);
EnterCriticalSection(&MmpGlobalDataPtr->MmpTls.MmpTlspLock);
record = PMMP_TLSP_RECORD(RtlAllocateHeap(RtlProcessHeap(), 0, sizeof(MMP_TLSP_RECORD)));
if (record) {
@@ -177,7 +177,7 @@ DWORD NTAPI MmpUserThreadStart(LPVOID lpThreadParameter) {
NtCurrentTeb()->ThreadLocalStoragePointer = record->TlspMmpBlock;
InsertTailList(&MmpGlobalDataPtr->MmpThreadLocalStoragePointer, &record->InMmpThreadLocalStoragePointer);
InsertTailList(&MmpGlobalDataPtr->MmpTls.MmpThreadLocalStoragePointer, &record->InMmpThreadLocalStoragePointer);
success = true;
}
else {
@@ -185,17 +185,17 @@ DWORD NTAPI MmpUserThreadStart(LPVOID lpThreadParameter) {
}
}
LeaveCriticalSection(&MmpGlobalDataPtr->MmpTlspLock);
LeaveCriticalSection(&MmpGlobalDataPtr->MmpTls.MmpTlspLock);
//
// Handle MemoryModule Tls data
//
if (success) {
RtlAcquireSRWLockShared(&MmpGlobalDataPtr->MmpTlsListLock);
RtlAcquireSRWLockShared(&MmpGlobalDataPtr->MmpTls.MmpTlsListLock);
auto ThreadLocalStoragePointer = (PVOID*)NtCurrentTeb()->ThreadLocalStoragePointer;
PLIST_ENTRY entry = MmpGlobalDataPtr->MmpTlsList.Flink;
while (entry != &MmpGlobalDataPtr->MmpTlsList) {
PLIST_ENTRY entry = MmpGlobalDataPtr->MmpTls.MmpTlsList.Flink;
while (entry != &MmpGlobalDataPtr->MmpTls.MmpTlsList) {
PTLS_ENTRY tls = CONTAINING_RECORD(entry, TLS_ENTRY, TlsEntryLinks);
auto len = tls->TlsDirectory.EndAddressOfRawData - tls->TlsDirectory.StartAddressOfRawData;
@@ -217,16 +217,16 @@ DWORD NTAPI MmpUserThreadStart(LPVOID lpThreadParameter) {
entry = entry->Flink;
}
RtlReleaseSRWLockShared(&MmpGlobalDataPtr->MmpTlsListLock);
RtlReleaseSRWLockShared(&MmpGlobalDataPtr->MmpTls.MmpTlsListLock);
}
if (!success) {
return ERROR_NOT_ENOUGH_MEMORY;
}
EnterCriticalSection(&MmpGlobalDataPtr->MmpTlspLock);
++MmpGlobalDataPtr->MmpActiveThreadCount;
LeaveCriticalSection(&MmpGlobalDataPtr->MmpTlspLock);
EnterCriticalSection(&MmpGlobalDataPtr->MmpTls.MmpTlspLock);
++MmpGlobalDataPtr->MmpTls.MmpActiveThreadCount;
LeaveCriticalSection(&MmpGlobalDataPtr->MmpTls.MmpTlspLock);
__skip_tls:
return Context.ThreadStartRoutine(Context.ThreadParameter);
@@ -327,10 +327,10 @@ VOID NTAPI HookLdrShutdownThread(VOID) {
//
// Find our tlsp record
//
EnterCriticalSection(&MmpGlobalDataPtr->MmpTlspLock);
EnterCriticalSection(&MmpGlobalDataPtr->MmpTls.MmpTlspLock);
entry = MmpGlobalDataPtr->MmpThreadLocalStoragePointer.Flink;
while (entry != &MmpGlobalDataPtr->MmpThreadLocalStoragePointer) {
entry = MmpGlobalDataPtr->MmpTls.MmpThreadLocalStoragePointer.Flink;
while (entry != &MmpGlobalDataPtr->MmpTls.MmpThreadLocalStoragePointer) {
auto p = CONTAINING_RECORD(entry, MMP_TLSP_RECORD, InMmpThreadLocalStoragePointer);
if (p->UniqueThread == NtCurrentThreadId()) {
@@ -349,19 +349,19 @@ VOID NTAPI HookLdrShutdownThread(VOID) {
entry = entry->Flink;
}
--MmpGlobalDataPtr->MmpActiveThreadCount;
--MmpGlobalDataPtr->MmpTls.MmpActiveThreadCount;
LeaveCriticalSection(&MmpGlobalDataPtr->MmpTlspLock);
LeaveCriticalSection(&MmpGlobalDataPtr->MmpTls.MmpTlspLock);
//
// Free MemoryModule Tls data
//
RtlAcquireSRWLockExclusive(&MmpGlobalDataPtr->MmpTlsListLock);
RtlAcquireSRWLockExclusive(&MmpGlobalDataPtr->MmpTls.MmpTlsListLock);
if (record) {
auto TlspMmpBlock = (PVOID*)record->TlspMmpBlock;
entry = MmpGlobalDataPtr->MmpTlsList.Flink;
while (entry != &MmpGlobalDataPtr->MmpTlsList) {
entry = MmpGlobalDataPtr->MmpTls.MmpTlsList.Flink;
while (entry != &MmpGlobalDataPtr->MmpTls.MmpTlsList) {
auto p = CONTAINING_RECORD(entry, TLS_ENTRY, TlsEntryLinks);
RtlFreeHeap(RtlProcessHeap(), 0, TlspMmpBlock[p->TlsDirectory.Characteristics]);
@@ -372,12 +372,12 @@ VOID NTAPI HookLdrShutdownThread(VOID) {
RtlFreeHeap(RtlProcessHeap(), 0, TlspMmpBlock);
}
else {
if (MmpGlobalDataPtr->MmpTlsList.Flink != &MmpGlobalDataPtr->MmpTlsList) {
if (MmpGlobalDataPtr->MmpTls.MmpTlsList.Flink != &MmpGlobalDataPtr->MmpTls.MmpTlsList) {
assert(false);
}
}
RtlReleaseSRWLockExclusive(&MmpGlobalDataPtr->MmpTlsListLock);
RtlReleaseSRWLockExclusive(&MmpGlobalDataPtr->MmpTls.MmpTlsListLock);
//
// Call the original function
@@ -433,7 +433,7 @@ BOOL NTAPI PreHookNtSetInformationProcess() {
);
if (NT_SUCCESS(status)) {
EnterCriticalSection(&MmpGlobalDataPtr->MmpTlspLock);
EnterCriticalSection(&MmpGlobalDataPtr->MmpTls.MmpTlspLock);
for (DWORD i = 0; i < CurrentThreadCount; ++i) {
auto const& LdrTls = ProcessTlsInformation->ThreadData[i];
auto const& MmpTls = tmpTlsInformation->ThreadData[i];
@@ -443,9 +443,9 @@ BOOL NTAPI PreHookNtSetInformationProcess() {
record->TlspLdrBlock = LdrTls.TlsVector;
record->TlspMmpBlock = MmpTls.TlsVector;
record->UniqueThread = LdrTls.ThreadId;
InsertTailList(&MmpGlobalDataPtr->MmpThreadLocalStoragePointer, &record->InMmpThreadLocalStoragePointer);
InsertTailList(&MmpGlobalDataPtr->MmpTls.MmpThreadLocalStoragePointer, &record->InMmpThreadLocalStoragePointer);
}
LeaveCriticalSection(&MmpGlobalDataPtr->MmpTlspLock);
LeaveCriticalSection(&MmpGlobalDataPtr->MmpTls.MmpTlspLock);
}
}
@@ -547,14 +547,14 @@ NTSTATUS NTAPI HookNtSetInformationProcess(
//
// Modify our mapping
//
EnterCriticalSection(&MmpGlobalDataPtr->MmpTlspLock);
EnterCriticalSection(&MmpGlobalDataPtr->MmpTls.MmpTlspLock);
for (auto i = 0; i < Tls->ThreadDataCount; ++i) {
bool found = false;
PLIST_ENTRY entry = MmpGlobalDataPtr->MmpThreadLocalStoragePointer.Flink;
PLIST_ENTRY entry = MmpGlobalDataPtr->MmpTls.MmpThreadLocalStoragePointer.Flink;
// Find thread-spec tlsp
while (entry != &MmpGlobalDataPtr->MmpThreadLocalStoragePointer) {
while (entry != &MmpGlobalDataPtr->MmpTls.MmpThreadLocalStoragePointer) {
PMMP_TLSP_RECORD j = CONTAINING_RECORD(entry, MMP_TLSP_RECORD, InMmpThreadLocalStoragePointer);
@@ -598,7 +598,7 @@ NTSTATUS NTAPI HookNtSetInformationProcess(
ProcessTlsInformation->ThreadData[i].ThreadId = Tls->ThreadData[i].ThreadId;
}
}
LeaveCriticalSection(&MmpGlobalDataPtr->MmpTlspLock);
LeaveCriticalSection(&MmpGlobalDataPtr->MmpTls.MmpTlspLock);
} while (false);
@@ -610,7 +610,7 @@ NTSTATUS NTAPI MmpAcquireTlsIndex(_Out_ PULONG TlsIndex) {
*TlsIndex = -1;
ULONG Index = RtlFindClearBitsAndSet(&MmpGlobalDataPtr->MmpTlsBitmap, 1, 0);
ULONG Index = RtlFindClearBitsAndSet(&MmpGlobalDataPtr->MmpTls.MmpTlsBitmap, 1, 0);
if (Index != -1) {
*TlsIndex = Index;
return STATUS_SUCCESS;
@@ -671,9 +671,9 @@ NTSTATUS NTAPI MmpAllocateTlsEntry(
Entry->TlsDirectory.Characteristics =
*PULONG(Entry->TlsDirectory.AddressOfIndex) = TlsIndex;
RtlAcquireSRWLockExclusive(&MmpGlobalDataPtr->MmpTlsListLock);
InsertTailList(&MmpGlobalDataPtr->MmpTlsList, &Entry->TlsEntryLinks);
RtlReleaseSRWLockExclusive(&MmpGlobalDataPtr->MmpTlsListLock);
RtlAcquireSRWLockExclusive(&MmpGlobalDataPtr->MmpTls.MmpTlsListLock);
InsertTailList(&MmpGlobalDataPtr->MmpTls.MmpTlsList, &Entry->TlsEntryLinks);
RtlReleaseSRWLockExclusive(&MmpGlobalDataPtr->MmpTls.MmpTlsListLock);
*lpTlsEntry = Entry;
*lpTlsIndex = TlsIndex;
@@ -682,20 +682,20 @@ NTSTATUS NTAPI MmpAllocateTlsEntry(
NTSTATUS NTAPI MmpReleaseTlsEntry(_In_ PLDR_DATA_TABLE_ENTRY lpModuleEntry) {
RtlAcquireSRWLockExclusive(&MmpGlobalDataPtr->MmpTlsListLock);
RtlAcquireSRWLockExclusive(&MmpGlobalDataPtr->MmpTls.MmpTlsListLock);
for (auto entry = MmpGlobalDataPtr->MmpTlsList.Flink; entry != &MmpGlobalDataPtr->MmpTlsList; entry = entry->Flink) {
for (auto entry = MmpGlobalDataPtr->MmpTls.MmpTlsList.Flink; entry != &MmpGlobalDataPtr->MmpTls.MmpTlsList; entry = entry->Flink) {
auto p = CONTAINING_RECORD(entry, TLS_ENTRY, TlsEntryLinks);
if (p->ModuleEntry == lpModuleEntry) {
RemoveEntryList(&p->TlsEntryLinks);
RtlClearBit(&MmpGlobalDataPtr->MmpTlsBitmap, p->TlsDirectory.Characteristics);
RtlClearBit(&MmpGlobalDataPtr->MmpTls.MmpTlsBitmap, p->TlsDirectory.Characteristics);
RtlFreeHeap(RtlProcessHeap(), 0, p);
break;
}
}
RtlReleaseSRWLockExclusive(&MmpGlobalDataPtr->MmpTlsListLock);
RtlReleaseSRWLockExclusive(&MmpGlobalDataPtr->MmpTls.MmpTlsListLock);
return STATUS_SUCCESS;
}
@@ -728,7 +728,7 @@ NTSTATUS NTAPI MmpHandleTlsData(_In_ PLDR_DATA_TABLE_ENTRY lpModuleEntry) {
return STATUS_INSUFFICIENT_RESOURCES;
}
auto ThreadCount = MmpGlobalDataPtr->MmpActiveThreadCount;
auto ThreadCount = MmpGlobalDataPtr->MmpTls.MmpActiveThreadCount;
auto success = true;
auto Length = sizeof(PROCESS_TLS_INFORMATION) + (ThreadCount - 1) * sizeof(THREAD_TLS_INFORMATION);
auto ProcessTlsInformation = PPROCESS_TLS_INFORMATION(RtlAllocateHeap(RtlProcessHeap(), HEAP_ZERO_MEMORY, Length));
@@ -796,26 +796,26 @@ BOOL NTAPI MmpTlsInitialize() {
//
// Capture thread count
//
MmpGlobalDataPtr->MmpActiveThreadCount = MmpGetThreadCount();
MmpGlobalDataPtr->MmpTls.MmpActiveThreadCount = MmpGetThreadCount();
//
// Initialize tlsp
//
InitializeCriticalSection(&MmpGlobalDataPtr->MmpTlspLock);
InitializeListHead(&MmpGlobalDataPtr->MmpThreadLocalStoragePointer);
InitializeCriticalSection(&MmpGlobalDataPtr->MmpTls.MmpTlspLock);
InitializeListHead(&MmpGlobalDataPtr->MmpTls.MmpThreadLocalStoragePointer);
//
// Initialize tls list
//
InitializeListHead(&MmpGlobalDataPtr->MmpTlsList);
RtlInitializeSRWLock(&MmpGlobalDataPtr->MmpTlsListLock);
InitializeListHead(&MmpGlobalDataPtr->MmpTls.MmpTlsList);
RtlInitializeSRWLock(&MmpGlobalDataPtr->MmpTls.MmpTlsListLock);
PULONG buffer = PULONG(RtlAllocateHeap(RtlProcessHeap(), HEAP_ZERO_MEMORY, MMP_TLSP_INDEX_BUFFER_SIZE));
if (!buffer) RtlRaiseStatus(STATUS_NO_MEMORY);
RtlFillMemory(buffer, MMP_START_TLS_INDEX / 8, -1);
RtlInitializeBitMap(&MmpGlobalDataPtr->MmpTlsBitmap, buffer, MMP_MAXIMUM_TLS_INDEX);
RtlInitializeBitMap(&MmpGlobalDataPtr->MmpTls.MmpTlsBitmap, buffer, MMP_MAXIMUM_TLS_INDEX);
if (NtCurrentTeb()->ThreadLocalStoragePointer) {
if (!PreHookNtSetInformationProcess()) {