mirror of
https://github.com/bb107/MemoryModulePP
synced 2026-06-08 13:15:33 +00:00
update
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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,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 */
|
||||
|
||||
@@ -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
|
||||
//
|
||||
|
||||
@@ -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
@@ -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);
|
||||
|
||||
@@ -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
@@ -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()) {
|
||||
|
||||
Reference in New Issue
Block a user