mirror of
https://github.com/bb107/MemoryModulePP
synced 2026-06-08 13:15:33 +00:00
refactoring
This commit is contained in:
@@ -3,7 +3,7 @@
|
||||
NTSTATUS NTAPI RtlInsertModuleBaseAddressIndexNode(
|
||||
_In_ PLDR_DATA_TABLE_ENTRY DataTableEntry,
|
||||
_In_ PVOID BaseAddress) {
|
||||
auto LdrpModuleBaseAddressIndex = MmpGlobalDataPtr->MmpBaseAddressIndex.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));
|
||||
@@ -35,7 +35,7 @@ NTSTATUS NTAPI RtlInsertModuleBaseAddressIndexNode(
|
||||
}
|
||||
|
||||
NTSTATUS NTAPI RtlRemoveModuleBaseAddressIndexNode(_In_ PLDR_DATA_TABLE_ENTRY DataTableEntry) {
|
||||
static auto tree{ MmpGlobalDataPtr->MmpBaseAddressIndex.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;
|
||||
|
||||
+153
-143
@@ -12,7 +12,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->MmpBaseAddressIndex.NtdllLdrEntry);
|
||||
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;
|
||||
@@ -186,55 +186,64 @@ PLIST_ENTRY FindLdrpHashTable() {
|
||||
VOID InitializeWindowsVersion() {
|
||||
|
||||
WINDOWS_VERSION version = WINDOWS_VERSION::invalid;
|
||||
DWORD MajorVersion, MinorVersion, BuildNumber, LdrDataTableEntrySize;
|
||||
|
||||
switch (MmpGlobalDataPtr->NtVersions.MajorVersion) {
|
||||
RtlGetNtVersionNumbers(
|
||||
&MajorVersion,
|
||||
&MinorVersion,
|
||||
&BuildNumber
|
||||
);
|
||||
if (BuildNumber & 0xf0000000)BuildNumber &= 0xffff;
|
||||
|
||||
switch (MajorVersion) {
|
||||
case 5: {
|
||||
switch (MmpGlobalDataPtr->NtVersions.MinorVersion) {
|
||||
case 1:
|
||||
if (MmpGlobalDataPtr->NtVersions.BuildNumber == 2600)
|
||||
version = WINDOWS_VERSION::xp;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
if (MmpGlobalDataPtr->NtVersions.BuildNumber == 3790)
|
||||
version = WINDOWS_VERSION::xp;
|
||||
break;
|
||||
if ((MinorVersion == 1 && BuildNumber == 2600) ||
|
||||
(MinorVersion == 2 && BuildNumber == 3790)) {
|
||||
version = WINDOWS_VERSION::xp;
|
||||
LdrDataTableEntrySize = sizeof(LDR_DATA_TABLE_ENTRY_XP);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 6: {
|
||||
switch (MmpGlobalDataPtr->NtVersions.MinorVersion) {
|
||||
switch (MinorVersion) {
|
||||
case 0: {
|
||||
switch (MmpGlobalDataPtr->NtVersions.BuildNumber) {
|
||||
switch (BuildNumber) {
|
||||
case 6000:
|
||||
case 6001:
|
||||
case 6002:
|
||||
version = WINDOWS_VERSION::vista;
|
||||
LdrDataTableEntrySize = sizeof(LDR_DATA_TABLE_ENTRY_VISTA);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case 1: {
|
||||
switch (MmpGlobalDataPtr->NtVersions.BuildNumber) {
|
||||
switch (BuildNumber) {
|
||||
case 7600:
|
||||
case 7601:
|
||||
version = WINDOWS_VERSION::win7;
|
||||
LdrDataTableEntrySize = sizeof(LDR_DATA_TABLE_ENTRY_WIN7);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case 2: {
|
||||
if (MmpGlobalDataPtr->NtVersions.BuildNumber == 9200)
|
||||
if (BuildNumber == 9200) {
|
||||
version = WINDOWS_VERSION::win8;
|
||||
LdrDataTableEntrySize = sizeof(LDR_DATA_TABLE_ENTRY_WIN8);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case 3: {
|
||||
if (MmpGlobalDataPtr->NtVersions.BuildNumber == 9600)
|
||||
if (BuildNumber == 9600) {
|
||||
version = WINDOWS_VERSION::winBlue;
|
||||
LdrDataTableEntrySize = sizeof(LDR_DATA_TABLE_ENTRY_WINBLUE);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -243,29 +252,32 @@ VOID InitializeWindowsVersion() {
|
||||
}
|
||||
|
||||
case 10: {
|
||||
if (MmpGlobalDataPtr->NtVersions.MinorVersion)break;
|
||||
if (MinorVersion)break;
|
||||
|
||||
DWORD BuildNumber = MmpGlobalDataPtr->NtVersions.BuildNumber;
|
||||
if (BuildNumber >= 10240) {
|
||||
if (BuildNumber >= 14393) {
|
||||
if (BuildNumber >= 15063) {
|
||||
if (BuildNumber >= 22000) {
|
||||
// [22000, ?)
|
||||
version = WINDOWS_VERSION::win11;
|
||||
LdrDataTableEntrySize = sizeof(LDR_DATA_TABLE_ENTRY_WIN11);
|
||||
}
|
||||
else {
|
||||
// [15063, 22000)
|
||||
version = WINDOWS_VERSION::win10_2;
|
||||
LdrDataTableEntrySize = sizeof(LDR_DATA_TABLE_ENTRY_WIN10_2);
|
||||
}
|
||||
}
|
||||
else {
|
||||
// [13494, 15063)
|
||||
version = WINDOWS_VERSION::win10_1;
|
||||
LdrDataTableEntrySize = sizeof(LDR_DATA_TABLE_ENTRY_WIN10_1);
|
||||
}
|
||||
}
|
||||
else {
|
||||
// [10240, 14393)
|
||||
version = WINDOWS_VERSION::win10;
|
||||
LdrDataTableEntrySize = sizeof(LDR_DATA_TABLE_ENTRY_WIN10);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -275,158 +287,156 @@ VOID InitializeWindowsVersion() {
|
||||
}
|
||||
|
||||
MmpGlobalDataPtr->WindowsVersion = version;
|
||||
if (version != WINDOWS_VERSION::invalid) {
|
||||
MmpGlobalDataPtr->NtVersions.MajorVersion = MajorVersion;
|
||||
MmpGlobalDataPtr->NtVersions.MinorVersion = MinorVersion;
|
||||
MmpGlobalDataPtr->NtVersions.BuildNumber = BuildNumber;
|
||||
MmpGlobalDataPtr->LdrDataTableEntrySize = (WORD)LdrDataTableEntrySize;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
NTSTATUS MmpAllocateGlobalData() {
|
||||
NTSTATUS status = STATUS_UNSUCCESSFUL;
|
||||
HANDLE hSection = nullptr;
|
||||
OBJECT_ATTRIBUTES oa;
|
||||
LARGE_INTEGER li;
|
||||
UNICODE_STRING us{};
|
||||
|
||||
li.QuadPart = 0x1000;
|
||||
|
||||
do {
|
||||
|
||||
if (!MmpBuildSectionName(&us))break;
|
||||
|
||||
InitializeObjectAttributes(&oa, &us, 0, nullptr, nullptr);
|
||||
|
||||
status = NtCreateSection(
|
||||
&hSection,
|
||||
SECTION_ALL_ACCESS,
|
||||
&oa,
|
||||
&li,
|
||||
PAGE_READWRITE,
|
||||
SEC_COMMIT | SEC_BASED,
|
||||
nullptr
|
||||
);
|
||||
if (!NT_SUCCESS(status)) {
|
||||
if (status != STATUS_OBJECT_NAME_COLLISION) break;
|
||||
|
||||
HANDLE hSection2;
|
||||
status = NtOpenSection(
|
||||
&hSection2,
|
||||
SECTION_ALL_ACCESS,
|
||||
&oa
|
||||
);
|
||||
if (!NT_SUCCESS(status))break;
|
||||
|
||||
SECTION_BASIC_INFORMATION sbi{};
|
||||
status = NtQuerySection(
|
||||
hSection2,
|
||||
SECTION_INFORMATION_CLASS::SectionBasicInformation,
|
||||
&sbi,
|
||||
sizeof(sbi),
|
||||
nullptr
|
||||
);
|
||||
|
||||
NtClose(hSection2);
|
||||
MmpGlobalDataPtr = (PMMP_GLOBAL_DATA)sbi.BaseAddress;
|
||||
break;
|
||||
}
|
||||
|
||||
PVOID BaseAddress = 0;
|
||||
SIZE_T ViewSize = 0;
|
||||
status = NtMapViewOfSection(
|
||||
hSection,
|
||||
NtCurrentProcess(),
|
||||
&BaseAddress,
|
||||
0,
|
||||
0,
|
||||
nullptr,
|
||||
&ViewSize,
|
||||
ViewUnmap,
|
||||
0,
|
||||
PAGE_READWRITE
|
||||
);
|
||||
if (!NT_SUCCESS(status))break;
|
||||
|
||||
MmpGlobalDataPtr = (PMMP_GLOBAL_DATA)BaseAddress;
|
||||
|
||||
} while (false);
|
||||
|
||||
RtlFreeUnicodeString(&us);
|
||||
|
||||
if (NT_SUCCESS(status)) {
|
||||
status = hSection ? status : STATUS_ALREADY_INITIALIZED;
|
||||
}
|
||||
else {
|
||||
if (hSection)NtClose(hSection);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
NTSTATUS InitializeLockHeld() {
|
||||
NTSTATUS status = STATUS_UNSUCCESSFUL;
|
||||
HANDLE hSection = nullptr;
|
||||
OBJECT_ATTRIBUTES oa;
|
||||
LARGE_INTEGER li;
|
||||
UNICODE_STRING us{};
|
||||
|
||||
li.QuadPart = 0x1000;
|
||||
NTSTATUS status;
|
||||
|
||||
do {
|
||||
|
||||
if (!MmpBuildSectionName(&us))break;
|
||||
status = MmpAllocateGlobalData();
|
||||
if (!NT_SUCCESS(status)) {
|
||||
if (status == STATUS_ALREADY_INITIALIZED) {
|
||||
if ((MmpGlobalDataPtr->MajorVersion < MEMORY_MODULE_MAJOR_VERSION) ||
|
||||
(MmpGlobalDataPtr->MajorVersion == MEMORY_MODULE_MAJOR_VERSION && MmpGlobalDataPtr->MinorVersion < MEMORY_MODULE_MINOR_VERSION)) {
|
||||
status = STATUS_NOT_SUPPORTED;
|
||||
}
|
||||
else {
|
||||
status = STATUS_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
InitializeObjectAttributes(&oa, &us, 0, nullptr, nullptr);
|
||||
break;
|
||||
}
|
||||
|
||||
status = NtCreateSection(
|
||||
&hSection,
|
||||
SECTION_ALL_ACCESS,
|
||||
&oa,
|
||||
&li,
|
||||
PAGE_READWRITE,
|
||||
SEC_COMMIT | SEC_BASED,
|
||||
nullptr
|
||||
);
|
||||
if (!NT_SUCCESS(status)) {
|
||||
if (status != STATUS_OBJECT_NAME_COLLISION) break;
|
||||
|
||||
HANDLE hSection2;
|
||||
status = NtOpenSection(
|
||||
&hSection2,
|
||||
SECTION_ALL_ACCESS,
|
||||
&oa
|
||||
);
|
||||
if (!NT_SUCCESS(status))break;
|
||||
|
||||
SECTION_BASIC_INFORMATION sbi{};
|
||||
status = NtQuerySection(
|
||||
hSection2,
|
||||
SECTION_INFORMATION_CLASS::SectionBasicInformation,
|
||||
&sbi,
|
||||
sizeof(sbi),
|
||||
nullptr
|
||||
);
|
||||
|
||||
NtClose(hSection2);
|
||||
MmpGlobalDataPtr = (PMMP_GLOBAL_DATA)sbi.BaseAddress;
|
||||
break;
|
||||
}
|
||||
|
||||
PVOID BaseAddress = 0;
|
||||
SIZE_T ViewSize = 0;
|
||||
status = NtMapViewOfSection(
|
||||
hSection,
|
||||
NtCurrentProcess(),
|
||||
&BaseAddress,
|
||||
0,
|
||||
0,
|
||||
nullptr,
|
||||
&ViewSize,
|
||||
ViewUnmap,
|
||||
0,
|
||||
PAGE_READWRITE
|
||||
);
|
||||
if (!NT_SUCCESS(status))break;
|
||||
|
||||
MmpGlobalDataPtr = (PMMP_GLOBAL_DATA)BaseAddress;
|
||||
|
||||
MmpGlobalDataPtr->MajorVersion = 1;
|
||||
MmpGlobalDataPtr->MinorVersion = 0;
|
||||
MmpGlobalDataPtr->MajorVersion = MEMORY_MODULE_MAJOR_VERSION;
|
||||
MmpGlobalDataPtr->MinorVersion = MEMORY_MODULE_MINOR_VERSION;
|
||||
|
||||
GetSystemInfo(&MmpGlobalDataPtr->SystemInfo);
|
||||
|
||||
RtlGetNtVersionNumbers(
|
||||
&MmpGlobalDataPtr->NtVersions.MajorVersion,
|
||||
&MmpGlobalDataPtr->NtVersions.MinorVersion,
|
||||
&MmpGlobalDataPtr->NtVersions.BuildNumber
|
||||
);
|
||||
if (MmpGlobalDataPtr->NtVersions.BuildNumber & 0xf0000000)MmpGlobalDataPtr->NtVersions.BuildNumber &= 0xffff;
|
||||
|
||||
InitializeWindowsVersion();
|
||||
|
||||
switch (MmpGlobalDataPtr->WindowsVersion) {
|
||||
case WINDOWS_VERSION::xp:
|
||||
MmpGlobalDataPtr->LdrDataTableEntrySize = sizeof(LDR_DATA_TABLE_ENTRY_XP);
|
||||
break;
|
||||
|
||||
case WINDOWS_VERSION::vista:
|
||||
MmpGlobalDataPtr->LdrDataTableEntrySize = sizeof(LDR_DATA_TABLE_ENTRY_VISTA);
|
||||
break;
|
||||
|
||||
case WINDOWS_VERSION::win7:
|
||||
MmpGlobalDataPtr->LdrDataTableEntrySize = sizeof(LDR_DATA_TABLE_ENTRY_WIN7);
|
||||
break;
|
||||
|
||||
case WINDOWS_VERSION::win8:
|
||||
MmpGlobalDataPtr->LdrDataTableEntrySize = sizeof(LDR_DATA_TABLE_ENTRY_WIN8);
|
||||
break;
|
||||
|
||||
case WINDOWS_VERSION::winBlue:
|
||||
MmpGlobalDataPtr->LdrDataTableEntrySize = sizeof(LDR_DATA_TABLE_ENTRY_WINBLUE);
|
||||
break;
|
||||
|
||||
case WINDOWS_VERSION::win10:
|
||||
MmpGlobalDataPtr->LdrDataTableEntrySize = sizeof(LDR_DATA_TABLE_ENTRY_WIN10);
|
||||
break;
|
||||
|
||||
case WINDOWS_VERSION::win10_1:
|
||||
MmpGlobalDataPtr->LdrDataTableEntrySize = sizeof(LDR_DATA_TABLE_ENTRY_WIN10_1);
|
||||
break;
|
||||
|
||||
case WINDOWS_VERSION::win10_2:
|
||||
MmpGlobalDataPtr->LdrDataTableEntrySize = sizeof(LDR_DATA_TABLE_ENTRY_WIN10_2);
|
||||
break;
|
||||
|
||||
case WINDOWS_VERSION::win11:
|
||||
MmpGlobalDataPtr->LdrDataTableEntrySize = sizeof(LDR_DATA_TABLE_ENTRY_WIN11);
|
||||
break;
|
||||
|
||||
default:
|
||||
NtUnmapViewOfSection(NtCurrentProcess(), BaseAddress);
|
||||
if (MmpGlobalDataPtr->WindowsVersion == WINDOWS_VERSION::invalid) {
|
||||
NtUnmapViewOfSection(NtCurrentProcess(), MmpGlobalDataPtr);
|
||||
status = STATUS_NOT_SUPPORTED;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!NT_SUCCESS(status))break;
|
||||
MmpGlobalDataPtr->MmpBaseAddressIndex = (PMMP_BASE_ADDRESS_INDEX_DATA)((LPBYTE)MmpGlobalDataPtr + sizeof(MMP_GLOBAL_DATA));
|
||||
MmpGlobalDataPtr->MmpInvertedFunctionTable = (PMMP_INVERTED_FUNCTION_TABLE_DATA)((LPBYTE)MmpGlobalDataPtr->MmpBaseAddressIndex + sizeof(MMP_BASE_ADDRESS_INDEX_DATA));
|
||||
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->MmpBaseAddressIndex.NtdllLdrEntry = RtlFindLdrTableEntryByBaseName(L"ntdll.dll");
|
||||
MmpGlobalDataPtr->MmpBaseAddressIndex.LdrpModuleBaseAddressIndex = FindLdrpModuleBaseAddressIndex();
|
||||
MmpGlobalDataPtr->MmpBaseAddressIndex->NtdllLdrEntry = RtlFindLdrTableEntryByBaseName(L"ntdll.dll");
|
||||
MmpGlobalDataPtr->MmpBaseAddressIndex->LdrpModuleBaseAddressIndex = FindLdrpModuleBaseAddressIndex();
|
||||
|
||||
HMODULE hNtdll = (HMODULE)MmpGlobalDataPtr->MmpBaseAddressIndex.NtdllLdrEntry->DllBase;
|
||||
MmpGlobalDataPtr->MmpLdrEntry._RtlRbInsertNodeEx = decltype(&RtlRbInsertNodeEx)(GetProcAddress(hNtdll, "RtlRbInsertNodeEx"));
|
||||
MmpGlobalDataPtr->MmpLdrEntry._RtlRbRemoveNode = decltype(&RtlRbRemoveNode)(GetProcAddress(hNtdll, "RtlRbRemoveNode"));
|
||||
HMODULE hNtdll = (HMODULE)MmpGlobalDataPtr->MmpBaseAddressIndex->NtdllLdrEntry->DllBase;
|
||||
MmpGlobalDataPtr->MmpLdrEntry->_RtlRbInsertNodeEx = decltype(&RtlRbInsertNodeEx)(GetProcAddress(hNtdll, "RtlRbInsertNodeEx"));
|
||||
MmpGlobalDataPtr->MmpLdrEntry->_RtlRbRemoveNode = decltype(&RtlRbRemoveNode)(GetProcAddress(hNtdll, "RtlRbRemoveNode"));
|
||||
|
||||
MmpGlobalDataPtr->MmpLdrEntry.LdrpHashTable = FindLdrpHashTable();
|
||||
MmpGlobalDataPtr->MmpLdrEntry->LdrpHashTable = FindLdrpHashTable();
|
||||
|
||||
MmpGlobalDataPtr->MmpInvertedFunctionTable.LdrpInvertedFunctionTable = FindLdrpInvertedFunctionTable();
|
||||
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->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;
|
||||
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;
|
||||
MmpGlobalDataPtr->MmpDotNet->Initialized = MmpGlobalDataPtr->MmpDotNet->PreHooked = FALSE;
|
||||
|
||||
} while (false);
|
||||
|
||||
if (!NT_SUCCESS(status) && hSection)NtClose(hSection);
|
||||
RtlFreeUnicodeString(&us);
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
@@ -151,7 +151,7 @@ static NTSTATUS RtlProtectMrdata(_In_ ULONG Protect) {
|
||||
|
||||
if (!MrdataBase) {
|
||||
MEMORY_BASIC_INFORMATION mbi{};
|
||||
status = NtQueryVirtualMemory(GetCurrentProcess(), MmpGlobalDataPtr->MmpInvertedFunctionTable.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;
|
||||
@@ -165,7 +165,7 @@ static NTSTATUS RtlProtectMrdata(_In_ ULONG Protect) {
|
||||
NTSTATUS NTAPI RtlInsertInvertedFunctionTable(
|
||||
_In_ PVOID BaseAddress,
|
||||
_In_ ULONG ImageSize) {
|
||||
auto table = PRTL_INVERTED_FUNCTION_TABLE(MmpGlobalDataPtr->MmpInvertedFunctionTable.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;
|
||||
@@ -184,7 +184,7 @@ NTSTATUS NTAPI RtlInsertInvertedFunctionTable(
|
||||
}
|
||||
|
||||
NTSTATUS NTAPI RtlRemoveInvertedFunctionTable(_In_ PVOID ImageBase) {
|
||||
auto table = PRTL_INVERTED_FUNCTION_TABLE(MmpGlobalDataPtr->MmpInvertedFunctionTable.LdrpInvertedFunctionTable);
|
||||
auto table = PRTL_INVERTED_FUNCTION_TABLE(MmpGlobalDataPtr->MmpInvertedFunctionTable->LdrpInvertedFunctionTable);
|
||||
bool need_virtual_protect = RtlIsWindowsVersionOrGreater(6, 3, 0);
|
||||
NTSTATUS status;
|
||||
|
||||
|
||||
@@ -240,10 +240,19 @@ NTSTATUS NTAPI RtlUpdateReferenceCount(
|
||||
_In_ DWORD Flags) {
|
||||
if (Flags != FLAG_REFERENCE && Flags != FLAG_DEREFERENCE)return STATUS_INVALID_PARAMETER_2;
|
||||
|
||||
if (Flags == FLAG_REFERENCE && pModule->dwReferenceCount != 0xffffffff)
|
||||
if (pModule->dwReferenceCount == 0xffffffff)return STATUS_SUCCESS;
|
||||
|
||||
if (PLDR_DATA_TABLE_ENTRY(pModule->LdrEntry)->ObsoleteLoadCount == 0xffff) {
|
||||
pModule->dwReferenceCount = 0xffffffff;
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
if (Flags == FLAG_REFERENCE) {
|
||||
++pModule->dwReferenceCount;
|
||||
if (Flags == FLAG_DEREFERENCE && pModule->dwReferenceCount)
|
||||
--pModule->dwReferenceCount;
|
||||
}
|
||||
else {
|
||||
if (pModule->dwReferenceCount)--pModule->dwReferenceCount;
|
||||
}
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
@@ -259,7 +268,7 @@ NTSTATUS NTAPI RtlGetReferenceCount(
|
||||
|
||||
VOID NTAPI RtlInsertMemoryTableEntry(_In_ PLDR_DATA_TABLE_ENTRY LdrEntry) {
|
||||
PPEB_LDR_DATA PebData = NtCurrentPeb()->Ldr;
|
||||
PLIST_ENTRY LdrpHashTable = MmpGlobalDataPtr->MmpLdrEntry.LdrpHashTable;
|
||||
PLIST_ENTRY LdrpHashTable = MmpGlobalDataPtr->MmpLdrEntry->LdrpHashTable;
|
||||
ULONG i;
|
||||
|
||||
/* Insert into hash table */
|
||||
@@ -279,15 +288,15 @@ VOID NTAPI RtlRbInsertNodeEx(
|
||||
_Out_ PRTL_BALANCED_NODE Node) {
|
||||
RtlZeroMemory(Node, sizeof(*Node));
|
||||
|
||||
if (!MmpGlobalDataPtr->MmpLdrEntry._RtlRbInsertNodeEx)return;
|
||||
return MmpGlobalDataPtr->MmpLdrEntry._RtlRbInsertNodeEx(Tree, Parent, Right, Node);
|
||||
if (!MmpGlobalDataPtr->MmpLdrEntry->_RtlRbInsertNodeEx)return;
|
||||
return MmpGlobalDataPtr->MmpLdrEntry->_RtlRbInsertNodeEx(Tree, Parent, Right, Node);
|
||||
}
|
||||
|
||||
VOID NTAPI RtlRbRemoveNode(
|
||||
_In_ PRTL_RB_TREE Tree,
|
||||
_In_ PRTL_BALANCED_NODE Node) {
|
||||
if (!MmpGlobalDataPtr->MmpLdrEntry._RtlRbRemoveNode)return;
|
||||
return MmpGlobalDataPtr->MmpLdrEntry._RtlRbRemoveNode(Tree, Node);
|
||||
if (!MmpGlobalDataPtr->MmpLdrEntry->_RtlRbRemoveNode)return;
|
||||
return MmpGlobalDataPtr->MmpLdrEntry->_RtlRbRemoveNode(Tree, Node);
|
||||
}
|
||||
|
||||
PLDR_DATA_TABLE_ENTRY NTAPI RtlFindLdrTableEntryByHandle(_In_ PVOID BaseAddress) {
|
||||
|
||||
+57
-52
@@ -110,7 +110,7 @@ NTSTATUS NTAPI LdrLoadDllMemoryExW(
|
||||
ExitProcess(STATUS_INVALID_ADDRESS);
|
||||
TerminateProcess(NtCurrentProcess(), STATUS_INVALID_ADDRESS);
|
||||
}
|
||||
module->loadFromNtLoadDllMemory = true;
|
||||
module->loadFromLdrLoadDllMemory = true;
|
||||
|
||||
headers = RtlImageNtHeader(*BaseAddress);
|
||||
if (headers->OptionalHeader.DllCharacteristics & IMAGE_DLLCHARACTERISTICS_NO_SEH)dwFlags |= LOAD_FLAGS_NOT_ADD_INVERTED_FUNCTION;
|
||||
@@ -144,6 +144,7 @@ NTSTATUS NTAPI LdrLoadDllMemoryExW(
|
||||
if (!NT_SUCCESS(status))break;
|
||||
|
||||
module->MappedDll = true;
|
||||
module->LdrEntry = ModuleEntry;
|
||||
|
||||
status = MemoryResolveImportTable(LPBYTE(*BaseAddress), headers, module);
|
||||
if (!NT_SUCCESS(status))break;
|
||||
@@ -225,65 +226,69 @@ NTSTATUS NTAPI LdrLoadDllMemoryExA(
|
||||
}
|
||||
|
||||
NTSTATUS NTAPI LdrUnloadDllMemory(_In_ HMEMORYMODULE BaseAddress) {
|
||||
__try {
|
||||
ProbeForRead(BaseAddress, sizeof(size_t));
|
||||
}
|
||||
__except (EXCEPTION_EXECUTE_HANDLER) {
|
||||
return GetExceptionCode();
|
||||
}
|
||||
|
||||
PLDR_DATA_TABLE_ENTRY CurEntry;
|
||||
ULONG count = 0;
|
||||
NTSTATUS status = STATUS_SUCCESS;
|
||||
PMEMORYMODULE module = MapMemoryModuleHandle(BaseAddress);
|
||||
PIMAGE_NT_HEADERS headers = RtlImageNtHeader(BaseAddress);
|
||||
|
||||
//Not a memory module loaded via LdrLoadDllMemory
|
||||
if (!module || !module->loadFromNtLoadDllMemory)return STATUS_INVALID_HANDLE;
|
||||
do {
|
||||
|
||||
//Mapping dll failed
|
||||
if (module->loadFromNtLoadDllMemory && !module->MappedDll) {
|
||||
module->underUnload = true;
|
||||
return MemoryFreeLibrary(BaseAddress) ? STATUS_SUCCESS : STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
if (CurEntry = RtlFindLdrTableEntryByHandle(BaseAddress)) {
|
||||
PIMAGE_NT_HEADERS headers = RtlImageNtHeader(BaseAddress);
|
||||
if (headers->OptionalHeader.SizeOfImage == CurEntry->SizeOfImage) {
|
||||
if (module->UseReferenceCount) {
|
||||
status = RtlGetReferenceCount(module, &count);
|
||||
if (!NT_SUCCESS(status))return status;
|
||||
}
|
||||
if (!(count & ~1)) {
|
||||
module->underUnload = true;
|
||||
if (module->initialized) {
|
||||
PLDR_INIT_ROUTINE((LPVOID)(module->codeBase + headers->OptionalHeader.AddressOfEntryPoint))(
|
||||
(HINSTANCE)module->codeBase,
|
||||
DLL_PROCESS_DETACH,
|
||||
0
|
||||
);
|
||||
}
|
||||
if (module->MappedDll) {
|
||||
if (module->InsertInvertedFunctionTableEntry) {
|
||||
status = RtlRemoveInvertedFunctionTable(BaseAddress);
|
||||
if (!NT_SUCCESS(status))__fastfail(FAST_FAIL_CORRUPT_LIST_ENTRY);
|
||||
}
|
||||
if (module->TlsHandled) {
|
||||
|
||||
status = MmpReleaseTlsEntry(CurEntry);
|
||||
if (!NT_SUCCESS(status)) __fastfail(FAST_FAIL_FATAL_APP_EXIT);
|
||||
}
|
||||
if (!RtlFreeLdrDataTableEntry(CurEntry))__fastfail(FAST_FAIL_FATAL_APP_EXIT);
|
||||
}
|
||||
if (!MemoryFreeLibrary(BaseAddress))__fastfail(FAST_FAIL_FATAL_APP_EXIT);
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
else {
|
||||
return RtlUpdateReferenceCount(module, FLAG_DEREFERENCE);
|
||||
}
|
||||
//Not a memory module loaded via LdrLoadDllMemory
|
||||
if (!module || !module->loadFromLdrLoadDllMemory) {
|
||||
status = STATUS_INVALID_HANDLE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return STATUS_INVALID_HANDLE;
|
||||
//Mapping dll failed
|
||||
if (!module->MappedDll) {
|
||||
module->underUnload = true;
|
||||
status = (MemoryFreeLibrary(BaseAddress) ? STATUS_SUCCESS : STATUS_UNSUCCESSFUL);
|
||||
break;
|
||||
}
|
||||
|
||||
CurEntry = (PLDR_DATA_TABLE_ENTRY)module->LdrEntry;
|
||||
|
||||
if (headers->OptionalHeader.SizeOfImage != CurEntry->SizeOfImage) __fastfail(FAST_FAIL_FATAL_APP_EXIT);
|
||||
|
||||
if (module->UseReferenceCount) {
|
||||
status = RtlGetReferenceCount(module, &count);
|
||||
if (!NT_SUCCESS(status)) break;
|
||||
}
|
||||
|
||||
if (count & ~1) {
|
||||
status = RtlUpdateReferenceCount(module, FLAG_DEREFERENCE);
|
||||
break;
|
||||
}
|
||||
|
||||
module->underUnload = true;
|
||||
if (module->initialized) {
|
||||
PLDR_INIT_ROUTINE((LPVOID)(module->codeBase + headers->OptionalHeader.AddressOfEntryPoint))(
|
||||
(HINSTANCE)module->codeBase,
|
||||
DLL_PROCESS_DETACH,
|
||||
0
|
||||
);
|
||||
}
|
||||
|
||||
if (module->MappedDll) {
|
||||
if (module->InsertInvertedFunctionTableEntry) {
|
||||
status = RtlRemoveInvertedFunctionTable(BaseAddress);
|
||||
if (!NT_SUCCESS(status)) __fastfail(FAST_FAIL_CORRUPT_LIST_ENTRY);
|
||||
}
|
||||
|
||||
if (module->TlsHandled) {
|
||||
status = MmpReleaseTlsEntry(CurEntry);
|
||||
if (!NT_SUCCESS(status)) __fastfail(FAST_FAIL_FATAL_APP_EXIT);
|
||||
}
|
||||
|
||||
if (!RtlFreeLdrDataTableEntry(CurEntry)) __fastfail(FAST_FAIL_FATAL_APP_EXIT);
|
||||
}
|
||||
|
||||
if (!MemoryFreeLibrary(BaseAddress)) __fastfail(FAST_FAIL_FATAL_APP_EXIT);
|
||||
|
||||
} while (false);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
__declspec(noreturn)
|
||||
|
||||
@@ -407,7 +407,7 @@ BOOL MemoryFreeLibrary(HMEMORYMODULE mod) {
|
||||
PIMAGE_NT_HEADERS headers = RtlImageNtHeader(mod);
|
||||
|
||||
if (!module) return FALSE;
|
||||
if (module->loadFromNtLoadDllMemory && !module->underUnload)return FALSE;
|
||||
if (module->loadFromLdrLoadDllMemory && !module->underUnload)return FALSE;
|
||||
if (module->hModulesList) {
|
||||
for (DWORD i = 0; i < module->dwModulesCount; ++i) {
|
||||
if (module->hModulesList[i]) {
|
||||
|
||||
@@ -27,7 +27,7 @@ typedef struct _MEMORYMODULE {
|
||||
struct {
|
||||
//Status Flags
|
||||
BYTE initialized : 1;
|
||||
BYTE loadFromNtLoadDllMemory : 1;
|
||||
BYTE loadFromLdrLoadDllMemory : 1;
|
||||
BYTE underUnload : 1;
|
||||
BYTE reservedStatusFlags : 5;
|
||||
|
||||
@@ -52,7 +52,9 @@ typedef struct _MEMORYMODULE {
|
||||
DWORD dwReferenceCount;
|
||||
|
||||
DWORD dwImageFileSize;
|
||||
//DWORD headers_align; //headers_align == OptionalHeaders.BaseOfCode;
|
||||
DWORD dwReserved;
|
||||
|
||||
PVOID LdrEntry;
|
||||
|
||||
} MEMORYMODULE, * PMEMORYMODULE;
|
||||
|
||||
|
||||
+55
-55
@@ -59,17 +59,17 @@ VOID MmpInsertHandleEntry(
|
||||
entry->value = value;
|
||||
entry->bImageMapping = bImageMapping;
|
||||
|
||||
EnterCriticalSection(&MmpGlobalDataPtr->MmpDotNet.MmpFakeHandleListLock);
|
||||
InsertTailList(&MmpGlobalDataPtr->MmpDotNet.MmpFakeHandleListHead, &entry->InMmpFakeHandleList);
|
||||
LeaveCriticalSection(&MmpGlobalDataPtr->MmpDotNet.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(&MmpGlobalDataPtr->MmpDotNet.MmpFakeHandleListLock);
|
||||
EnterCriticalSection(&MmpGlobalDataPtr->MmpDotNet->MmpFakeHandleListLock);
|
||||
|
||||
for (auto entry = MmpGlobalDataPtr->MmpDotNet.MmpFakeHandleListHead.Flink; entry != &MmpGlobalDataPtr->MmpDotNet.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) {
|
||||
@@ -79,15 +79,15 @@ PMMP_FAKE_HANDLE_LIST_ENTRY MmpFindHandleEntry(HANDLE hObject) {
|
||||
|
||||
}
|
||||
|
||||
LeaveCriticalSection(&MmpGlobalDataPtr->MmpDotNet.MmpFakeHandleListLock);
|
||||
LeaveCriticalSection(&MmpGlobalDataPtr->MmpDotNet->MmpFakeHandleListLock);
|
||||
return result;
|
||||
}
|
||||
|
||||
VOID MmpFreeHandleEntry(PMMP_FAKE_HANDLE_LIST_ENTRY lpHandleEntry) {
|
||||
EnterCriticalSection(&MmpGlobalDataPtr->MmpDotNet.MmpFakeHandleListLock);
|
||||
EnterCriticalSection(&MmpGlobalDataPtr->MmpDotNet->MmpFakeHandleListLock);
|
||||
RemoveEntryList(&lpHandleEntry->InMmpFakeHandleList);
|
||||
RtlFreeHeap(RtlProcessHeap(), 0, lpHandleEntry);
|
||||
LeaveCriticalSection(&MmpGlobalDataPtr->MmpDotNet.MmpFakeHandleListLock);
|
||||
LeaveCriticalSection(&MmpGlobalDataPtr->MmpDotNet->MmpFakeHandleListLock);
|
||||
}
|
||||
|
||||
HANDLE WINAPI HookCreateFileW(
|
||||
@@ -107,7 +107,7 @@ HANDLE WINAPI HookCreateFileW(
|
||||
return hEvent;
|
||||
}
|
||||
|
||||
return MmpGlobalDataPtr->MmpDotNet.Hooks.OriginCreateFileW(
|
||||
return MmpGlobalDataPtr->MmpDotNet->Hooks.OriginCreateFileW(
|
||||
lpFileName,
|
||||
dwDesiredAccess,
|
||||
dwShareMode,
|
||||
@@ -128,13 +128,13 @@ BOOL WINAPI HookGetFileInformationByHandle(
|
||||
auto entry = (PLDR_DATA_TABLE_ENTRY)iter->value;
|
||||
auto module = MapMemoryModuleHandle((HMEMORYMODULE)entry->DllBase);
|
||||
|
||||
lpFileInformation->ftCreationTime = lpFileInformation->ftLastAccessTime = lpFileInformation->ftLastWriteTime = MmpGlobalDataPtr->MmpDotNet.AssemblyTimes;
|
||||
lpFileInformation->ftCreationTime = lpFileInformation->ftLastAccessTime = lpFileInformation->ftLastWriteTime = MmpGlobalDataPtr->MmpDotNet->AssemblyTimes;
|
||||
lpFileInformation->nFileSizeLow = module->dwImageFileSize;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
else {
|
||||
return MmpGlobalDataPtr->MmpDotNet.Hooks.OriginGetFileInformationByHandle(
|
||||
return MmpGlobalDataPtr->MmpDotNet->Hooks.OriginGetFileInformationByHandle(
|
||||
hFile,
|
||||
lpFileInformation
|
||||
);
|
||||
@@ -157,7 +157,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 = MmpGlobalDataPtr->MmpDotNet.AssemblyTimes;
|
||||
data->ftCreationTime = data->ftLastAccessTime = data->ftLastWriteTime = MmpGlobalDataPtr->MmpDotNet->AssemblyTimes;
|
||||
data->nFileSizeLow = module->dwImageFileSize;
|
||||
return TRUE;
|
||||
}
|
||||
@@ -166,7 +166,7 @@ BOOL WINAPI HookGetFileAttributesExW(
|
||||
}
|
||||
}
|
||||
|
||||
return MmpGlobalDataPtr->MmpDotNet.Hooks.OriginGetFileAttributesExW(
|
||||
return MmpGlobalDataPtr->MmpDotNet->Hooks.OriginGetFileAttributesExW(
|
||||
lpFileName,
|
||||
fInfoLevelId,
|
||||
lpFileInformation
|
||||
@@ -187,7 +187,7 @@ DWORD WINAPI HookGetFileSize(
|
||||
return module->dwImageFileSize;
|
||||
}
|
||||
else {
|
||||
return MmpGlobalDataPtr->MmpDotNet.Hooks.OriginGetFileSize(
|
||||
return MmpGlobalDataPtr->MmpDotNet->Hooks.OriginGetFileSize(
|
||||
hFile,
|
||||
lpFileSizeHigh
|
||||
);
|
||||
@@ -208,7 +208,7 @@ BOOL WINAPI HookGetFileSizeEx(
|
||||
return TRUE;
|
||||
}
|
||||
else {
|
||||
return MmpGlobalDataPtr->MmpDotNet.Hooks.OriginGetFileSizeEx(
|
||||
return MmpGlobalDataPtr->MmpDotNet->Hooks.OriginGetFileSizeEx(
|
||||
hFile,
|
||||
lpFileSize
|
||||
);
|
||||
@@ -232,7 +232,7 @@ HANDLE WINAPI HookCreateFileMappingW(
|
||||
return hEvent;
|
||||
}
|
||||
|
||||
return MmpGlobalDataPtr->MmpDotNet.Hooks.OriginCreateFileMappingW(
|
||||
return MmpGlobalDataPtr->MmpDotNet->Hooks.OriginCreateFileMappingW(
|
||||
hFile,
|
||||
lpFileMappingAttributes,
|
||||
flProtect,
|
||||
@@ -268,7 +268,7 @@ LPVOID WINAPI HookMapViewOfFileEx(
|
||||
return hModule;
|
||||
}
|
||||
|
||||
return MmpGlobalDataPtr->MmpDotNet.Hooks.OriginMapViewOfFileEx(
|
||||
return MmpGlobalDataPtr->MmpDotNet->Hooks.OriginMapViewOfFileEx(
|
||||
hFileMappingObject,
|
||||
dwDesiredAccess,
|
||||
dwFileOffsetHigh,
|
||||
@@ -304,14 +304,14 @@ BOOL WINAPI HookUnmapViewOfFile(_In_ LPCVOID lpBaseAddress) {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return MmpGlobalDataPtr->MmpDotNet.Hooks.OriginUnmapViewOfFile(lpBaseAddress);
|
||||
return MmpGlobalDataPtr->MmpDotNet->Hooks.OriginUnmapViewOfFile(lpBaseAddress);
|
||||
}
|
||||
|
||||
BOOL WINAPI HookCloseHandle(_In_ _Post_ptr_invalid_ HANDLE hObject) {
|
||||
auto iter = MmpFindHandleEntry(hObject);
|
||||
if (iter)MmpFreeHandleEntry(iter);
|
||||
|
||||
return MmpGlobalDataPtr->MmpDotNet.Hooks.OriginCloseHandle(hObject);
|
||||
return MmpGlobalDataPtr->MmpDotNet->Hooks.OriginCloseHandle(hObject);
|
||||
}
|
||||
|
||||
HRESULT WINAPI HookGetFileVersion(
|
||||
@@ -354,7 +354,7 @@ HRESULT WINAPI HookGetFileVersion(
|
||||
|
||||
}
|
||||
|
||||
return MmpGlobalDataPtr->MmpDotNet.Hooks.OriginGetFileVersion1(
|
||||
return MmpGlobalDataPtr->MmpDotNet->Hooks.OriginGetFileVersion1(
|
||||
szFilename,
|
||||
szBuffer,
|
||||
cchBuffer,
|
||||
@@ -366,74 +366,74 @@ BOOL WINAPI MmpPreInitializeHooksForDotNet() {
|
||||
|
||||
EnterCriticalSection(NtCurrentPeb()->FastPebLock);
|
||||
|
||||
if (!MmpGlobalDataPtr->MmpDotNet.PreHooked) {
|
||||
if (!MmpGlobalDataPtr->MmpDotNet->PreHooked) {
|
||||
HMODULE hModule = LoadLibraryW(L"mscoree.dll");
|
||||
if (hModule) {
|
||||
MmpGlobalDataPtr->MmpDotNet.Hooks.OriginGetFileVersion2 = (GetFileVersion_T)GetProcAddress(hModule, "GetFileVersion");
|
||||
if (MmpGlobalDataPtr->MmpDotNet.Hooks.OriginGetFileVersion2) {
|
||||
MmpGlobalDataPtr->MmpDotNet->Hooks.OriginGetFileVersion2 = (GetFileVersion_T)GetProcAddress(hModule, "GetFileVersion");
|
||||
if (MmpGlobalDataPtr->MmpDotNet->Hooks.OriginGetFileVersion2) {
|
||||
|
||||
GetSystemTimeAsFileTime(&MmpGlobalDataPtr->MmpDotNet.AssemblyTimes);
|
||||
GetSystemTimeAsFileTime(&MmpGlobalDataPtr->MmpDotNet->AssemblyTimes);
|
||||
|
||||
InitializeCriticalSection(&MmpGlobalDataPtr->MmpDotNet.MmpFakeHandleListLock);
|
||||
InitializeListHead(&MmpGlobalDataPtr->MmpDotNet.MmpFakeHandleListHead);
|
||||
InitializeCriticalSection(&MmpGlobalDataPtr->MmpDotNet->MmpFakeHandleListLock);
|
||||
InitializeListHead(&MmpGlobalDataPtr->MmpDotNet->MmpFakeHandleListHead);
|
||||
|
||||
MmpGlobalDataPtr->MmpDotNet.Hooks.OriginCreateFileW = CreateFileW;
|
||||
MmpGlobalDataPtr->MmpDotNet.Hooks.OriginGetFileInformationByHandle = GetFileInformationByHandle;
|
||||
MmpGlobalDataPtr->MmpDotNet.Hooks.OriginGetFileAttributesExW = GetFileAttributesExW;
|
||||
MmpGlobalDataPtr->MmpDotNet.Hooks.OriginGetFileSize = GetFileSize;
|
||||
MmpGlobalDataPtr->MmpDotNet.Hooks.OriginGetFileSizeEx = GetFileSizeEx;
|
||||
MmpGlobalDataPtr->MmpDotNet.Hooks.OriginCreateFileMappingW = CreateFileMappingW;
|
||||
MmpGlobalDataPtr->MmpDotNet.Hooks.OriginMapViewOfFileEx = MapViewOfFileEx;
|
||||
MmpGlobalDataPtr->MmpDotNet.Hooks.OriginMapViewOfFile = MapViewOfFile;
|
||||
MmpGlobalDataPtr->MmpDotNet.Hooks.OriginUnmapViewOfFile = UnmapViewOfFile;
|
||||
MmpGlobalDataPtr->MmpDotNet.Hooks.OriginCloseHandle = CloseHandle;
|
||||
MmpGlobalDataPtr->MmpDotNet->Hooks.OriginCreateFileW = CreateFileW;
|
||||
MmpGlobalDataPtr->MmpDotNet->Hooks.OriginGetFileInformationByHandle = GetFileInformationByHandle;
|
||||
MmpGlobalDataPtr->MmpDotNet->Hooks.OriginGetFileAttributesExW = GetFileAttributesExW;
|
||||
MmpGlobalDataPtr->MmpDotNet->Hooks.OriginGetFileSize = GetFileSize;
|
||||
MmpGlobalDataPtr->MmpDotNet->Hooks.OriginGetFileSizeEx = GetFileSizeEx;
|
||||
MmpGlobalDataPtr->MmpDotNet->Hooks.OriginCreateFileMappingW = CreateFileMappingW;
|
||||
MmpGlobalDataPtr->MmpDotNet->Hooks.OriginMapViewOfFileEx = MapViewOfFileEx;
|
||||
MmpGlobalDataPtr->MmpDotNet->Hooks.OriginMapViewOfFile = MapViewOfFile;
|
||||
MmpGlobalDataPtr->MmpDotNet->Hooks.OriginUnmapViewOfFile = UnmapViewOfFile;
|
||||
MmpGlobalDataPtr->MmpDotNet->Hooks.OriginCloseHandle = CloseHandle;
|
||||
|
||||
DetourTransactionBegin();
|
||||
DetourUpdateThread(NtCurrentThread());
|
||||
|
||||
DetourAttach((PVOID*)&MmpGlobalDataPtr->MmpDotNet.Hooks.OriginCreateFileW, HookCreateFileW);
|
||||
DetourAttach((PVOID*)&MmpGlobalDataPtr->MmpDotNet.Hooks.OriginGetFileInformationByHandle, HookGetFileInformationByHandle);
|
||||
DetourAttach((PVOID*)&MmpGlobalDataPtr->MmpDotNet.Hooks.OriginGetFileAttributesExW, HookGetFileAttributesExW);
|
||||
DetourAttach((PVOID*)&MmpGlobalDataPtr->MmpDotNet.Hooks.OriginGetFileSize, HookGetFileSize);
|
||||
DetourAttach((PVOID*)&MmpGlobalDataPtr->MmpDotNet.Hooks.OriginGetFileSizeEx, HookGetFileSizeEx);
|
||||
DetourAttach((PVOID*)&MmpGlobalDataPtr->MmpDotNet.Hooks.OriginCreateFileMappingW, HookCreateFileMappingW);
|
||||
DetourAttach((PVOID*)&MmpGlobalDataPtr->MmpDotNet.Hooks.OriginMapViewOfFileEx, HookMapViewOfFileEx);
|
||||
DetourAttach((PVOID*)&MmpGlobalDataPtr->MmpDotNet.Hooks.OriginMapViewOfFile, HookMapViewOfFile);
|
||||
DetourAttach((PVOID*)&MmpGlobalDataPtr->MmpDotNet.Hooks.OriginUnmapViewOfFile, HookUnmapViewOfFile);
|
||||
DetourAttach((PVOID*)&MmpGlobalDataPtr->MmpDotNet.Hooks.OriginCloseHandle, HookCloseHandle);
|
||||
DetourAttach((PVOID*)&MmpGlobalDataPtr->MmpDotNet.Hooks.OriginGetFileVersion2, HookGetFileVersion);
|
||||
DetourAttach((PVOID*)&MmpGlobalDataPtr->MmpDotNet->Hooks.OriginCreateFileW, HookCreateFileW);
|
||||
DetourAttach((PVOID*)&MmpGlobalDataPtr->MmpDotNet->Hooks.OriginGetFileInformationByHandle, HookGetFileInformationByHandle);
|
||||
DetourAttach((PVOID*)&MmpGlobalDataPtr->MmpDotNet->Hooks.OriginGetFileAttributesExW, HookGetFileAttributesExW);
|
||||
DetourAttach((PVOID*)&MmpGlobalDataPtr->MmpDotNet->Hooks.OriginGetFileSize, HookGetFileSize);
|
||||
DetourAttach((PVOID*)&MmpGlobalDataPtr->MmpDotNet->Hooks.OriginGetFileSizeEx, HookGetFileSizeEx);
|
||||
DetourAttach((PVOID*)&MmpGlobalDataPtr->MmpDotNet->Hooks.OriginCreateFileMappingW, HookCreateFileMappingW);
|
||||
DetourAttach((PVOID*)&MmpGlobalDataPtr->MmpDotNet->Hooks.OriginMapViewOfFileEx, HookMapViewOfFileEx);
|
||||
DetourAttach((PVOID*)&MmpGlobalDataPtr->MmpDotNet->Hooks.OriginMapViewOfFile, HookMapViewOfFile);
|
||||
DetourAttach((PVOID*)&MmpGlobalDataPtr->MmpDotNet->Hooks.OriginUnmapViewOfFile, HookUnmapViewOfFile);
|
||||
DetourAttach((PVOID*)&MmpGlobalDataPtr->MmpDotNet->Hooks.OriginCloseHandle, HookCloseHandle);
|
||||
DetourAttach((PVOID*)&MmpGlobalDataPtr->MmpDotNet->Hooks.OriginGetFileVersion2, HookGetFileVersion);
|
||||
|
||||
DetourTransactionCommit();
|
||||
|
||||
MmpGlobalDataPtr->MmpDotNet.PreHooked = TRUE;
|
||||
MmpGlobalDataPtr->MmpDotNet->PreHooked = TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LeaveCriticalSection(NtCurrentPeb()->FastPebLock);
|
||||
|
||||
return MmpGlobalDataPtr->MmpDotNet.PreHooked;
|
||||
return MmpGlobalDataPtr->MmpDotNet->PreHooked;
|
||||
}
|
||||
|
||||
BOOL WINAPI MmpInitializeHooksForDotNet() {
|
||||
HMODULE hModule = GetModuleHandleW(L"mscoreei.dll");
|
||||
if (hModule) {
|
||||
MmpGlobalDataPtr->MmpDotNet.Hooks.OriginGetFileVersion1 = (GetFileVersion_T)GetProcAddress(hModule, "GetFileVersion");
|
||||
if (MmpGlobalDataPtr->MmpDotNet.Hooks.OriginGetFileVersion1) {
|
||||
MmpGlobalDataPtr->MmpDotNet->Hooks.OriginGetFileVersion1 = (GetFileVersion_T)GetProcAddress(hModule, "GetFileVersion");
|
||||
if (MmpGlobalDataPtr->MmpDotNet->Hooks.OriginGetFileVersion1) {
|
||||
|
||||
EnterCriticalSection(NtCurrentPeb()->FastPebLock);
|
||||
|
||||
if (!MmpGlobalDataPtr->MmpDotNet.PreHooked) {
|
||||
if (!MmpGlobalDataPtr->MmpDotNet->PreHooked) {
|
||||
LeaveCriticalSection(NtCurrentPeb()->FastPebLock);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!MmpGlobalDataPtr->MmpDotNet.Initialized) {
|
||||
if (!MmpGlobalDataPtr->MmpDotNet->Initialized) {
|
||||
DetourTransactionBegin();
|
||||
DetourUpdateThread(NtCurrentThread());
|
||||
DetourAttach((PVOID*)&MmpGlobalDataPtr->MmpDotNet.Hooks.OriginGetFileVersion1, HookGetFileVersion);
|
||||
DetourAttach((PVOID*)&MmpGlobalDataPtr->MmpDotNet->Hooks.OriginGetFileVersion1, HookGetFileVersion);
|
||||
DetourTransactionCommit();
|
||||
MmpGlobalDataPtr->MmpDotNet.Initialized = TRUE;
|
||||
MmpGlobalDataPtr->MmpDotNet->Initialized = TRUE;
|
||||
}
|
||||
|
||||
LeaveCriticalSection(NtCurrentPeb()->FastPebLock);
|
||||
|
||||
@@ -76,6 +76,9 @@ typedef enum class _WINDOWS_VERSION :BYTE {
|
||||
invalid
|
||||
}WINDOWS_VERSION;
|
||||
|
||||
#define MEMORY_MODULE_MAJOR_VERSION 1
|
||||
#define MEMORY_MODULE_MINOR_VERSION 0
|
||||
|
||||
typedef struct _MMP_GLOBAL_DATA {
|
||||
|
||||
WORD MajorVersion;
|
||||
@@ -95,16 +98,25 @@ typedef struct _MMP_GLOBAL_DATA {
|
||||
|
||||
SYSTEM_INFO SystemInfo;
|
||||
|
||||
MMP_BASE_ADDRESS_INDEX_DATA MmpBaseAddressIndex;
|
||||
PMMP_BASE_ADDRESS_INDEX_DATA MmpBaseAddressIndex;
|
||||
|
||||
MMP_INVERTED_FUNCTION_TABLE_DATA MmpInvertedFunctionTable;
|
||||
PMMP_INVERTED_FUNCTION_TABLE_DATA MmpInvertedFunctionTable;
|
||||
|
||||
MMP_LDR_ENTRY_DATA MmpLdrEntry;
|
||||
PMMP_LDR_ENTRY_DATA MmpLdrEntry;
|
||||
|
||||
MMP_TLS_DATA MmpTls;
|
||||
PMMP_TLS_DATA MmpTls;
|
||||
|
||||
MMP_DOT_NET_DATA MmpDotNet;
|
||||
PMMP_DOT_NET_DATA MmpDotNet;
|
||||
|
||||
}MMP_GLOBAL_DATA, * PMMP_GLOBAL_DATA;
|
||||
|
||||
#define MMP_GLOBAL_DATA_SIZE (\
|
||||
sizeof(MMP_GLOBAL_DATA) + \
|
||||
sizeof(MMP_BASE_ADDRESS_INDEX_DATA) + \
|
||||
sizeof(MMP_INVERTED_FUNCTION_TABLE_DATA) + \
|
||||
sizeof(MMP_LDR_ENTRY_DATA) + \
|
||||
sizeof(MMP_TLS_DATA) + \
|
||||
sizeof(MMP_DOT_NET_DATA)\
|
||||
)
|
||||
|
||||
extern PMMP_GLOBAL_DATA MmpGlobalDataPtr;
|
||||
|
||||
+55
-55
@@ -154,7 +154,7 @@ DWORD NTAPI MmpUserThreadStart(LPVOID lpThreadParameter) {
|
||||
//
|
||||
// Allocate and replace ThreadLocalStoragePointer for new thread
|
||||
//
|
||||
EnterCriticalSection(&MmpGlobalDataPtr->MmpTls.MmpTlspLock);
|
||||
EnterCriticalSection(&MmpGlobalDataPtr->MmpTls->MmpTlspLock);
|
||||
|
||||
record = PMMP_TLSP_RECORD(RtlAllocateHeap(RtlProcessHeap(), 0, sizeof(MMP_TLSP_RECORD)));
|
||||
if (record) {
|
||||
@@ -172,7 +172,7 @@ DWORD NTAPI MmpUserThreadStart(LPVOID lpThreadParameter) {
|
||||
|
||||
NtCurrentTeb()->ThreadLocalStoragePointer = record->TlspMmpBlock;
|
||||
|
||||
InsertTailList(&MmpGlobalDataPtr->MmpTls.MmpThreadLocalStoragePointer, &record->InMmpThreadLocalStoragePointer);
|
||||
InsertTailList(&MmpGlobalDataPtr->MmpTls->MmpThreadLocalStoragePointer, &record->InMmpThreadLocalStoragePointer);
|
||||
success = true;
|
||||
}
|
||||
else {
|
||||
@@ -180,17 +180,17 @@ DWORD NTAPI MmpUserThreadStart(LPVOID lpThreadParameter) {
|
||||
}
|
||||
}
|
||||
|
||||
LeaveCriticalSection(&MmpGlobalDataPtr->MmpTls.MmpTlspLock);
|
||||
LeaveCriticalSection(&MmpGlobalDataPtr->MmpTls->MmpTlspLock);
|
||||
|
||||
//
|
||||
// Handle MemoryModule Tls data
|
||||
//
|
||||
if (success) {
|
||||
RtlAcquireSRWLockShared(&MmpGlobalDataPtr->MmpTls.MmpTlsListLock);
|
||||
RtlAcquireSRWLockShared(&MmpGlobalDataPtr->MmpTls->MmpTlsListLock);
|
||||
|
||||
auto ThreadLocalStoragePointer = (PVOID*)NtCurrentTeb()->ThreadLocalStoragePointer;
|
||||
PLIST_ENTRY entry = MmpGlobalDataPtr->MmpTls.MmpTlsList.Flink;
|
||||
while (entry != &MmpGlobalDataPtr->MmpTls.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;
|
||||
@@ -212,16 +212,16 @@ DWORD NTAPI MmpUserThreadStart(LPVOID lpThreadParameter) {
|
||||
entry = entry->Flink;
|
||||
}
|
||||
|
||||
RtlReleaseSRWLockShared(&MmpGlobalDataPtr->MmpTls.MmpTlsListLock);
|
||||
RtlReleaseSRWLockShared(&MmpGlobalDataPtr->MmpTls->MmpTlsListLock);
|
||||
}
|
||||
|
||||
if (!success) {
|
||||
return ERROR_NOT_ENOUGH_MEMORY;
|
||||
}
|
||||
|
||||
EnterCriticalSection(&MmpGlobalDataPtr->MmpTls.MmpTlspLock);
|
||||
++MmpGlobalDataPtr->MmpTls.MmpActiveThreadCount;
|
||||
LeaveCriticalSection(&MmpGlobalDataPtr->MmpTls.MmpTlspLock);
|
||||
EnterCriticalSection(&MmpGlobalDataPtr->MmpTls->MmpTlspLock);
|
||||
++MmpGlobalDataPtr->MmpTls->MmpActiveThreadCount;
|
||||
LeaveCriticalSection(&MmpGlobalDataPtr->MmpTls->MmpTlspLock);
|
||||
|
||||
__skip_tls:
|
||||
return Context.ThreadStartRoutine(Context.ThreadParameter);
|
||||
@@ -257,7 +257,7 @@ NTSTATUS NTAPI HookNtCreateThread(
|
||||
Context.Rdx = ULONG64(_Context);
|
||||
#endif
|
||||
|
||||
status = MmpGlobalDataPtr->MmpTls.Hooks.OriginNtCreateThread(
|
||||
status = MmpGlobalDataPtr->MmpTls->Hooks.OriginNtCreateThread(
|
||||
ThreadHandle,
|
||||
DesiredAccess,
|
||||
ObjectAttributes,
|
||||
@@ -294,7 +294,7 @@ NTSTATUS NTAPI HookNtCreateThreadEx(
|
||||
Context->ThreadStartRoutine = PTHREAD_START_ROUTINE(StartRoutine);
|
||||
Context->ThreadParameter = Argument;
|
||||
|
||||
NTSTATUS status = MmpGlobalDataPtr->MmpTls.Hooks.OriginNtCreateThreadEx(
|
||||
NTSTATUS status = MmpGlobalDataPtr->MmpTls->Hooks.OriginNtCreateThreadEx(
|
||||
ThreadHandle,
|
||||
DesiredAccess,
|
||||
ObjectAttributes,
|
||||
@@ -322,10 +322,10 @@ VOID NTAPI HookLdrShutdownThread(VOID) {
|
||||
//
|
||||
// Find our tlsp record
|
||||
//
|
||||
EnterCriticalSection(&MmpGlobalDataPtr->MmpTls.MmpTlspLock);
|
||||
EnterCriticalSection(&MmpGlobalDataPtr->MmpTls->MmpTlspLock);
|
||||
|
||||
entry = MmpGlobalDataPtr->MmpTls.MmpThreadLocalStoragePointer.Flink;
|
||||
while (entry != &MmpGlobalDataPtr->MmpTls.MmpThreadLocalStoragePointer) {
|
||||
entry = MmpGlobalDataPtr->MmpTls->MmpThreadLocalStoragePointer.Flink;
|
||||
while (entry != &MmpGlobalDataPtr->MmpTls->MmpThreadLocalStoragePointer) {
|
||||
|
||||
auto p = CONTAINING_RECORD(entry, MMP_TLSP_RECORD, InMmpThreadLocalStoragePointer);
|
||||
if (p->UniqueThread == NtCurrentThreadId()) {
|
||||
@@ -344,19 +344,19 @@ VOID NTAPI HookLdrShutdownThread(VOID) {
|
||||
entry = entry->Flink;
|
||||
}
|
||||
|
||||
--MmpGlobalDataPtr->MmpTls.MmpActiveThreadCount;
|
||||
--MmpGlobalDataPtr->MmpTls->MmpActiveThreadCount;
|
||||
|
||||
LeaveCriticalSection(&MmpGlobalDataPtr->MmpTls.MmpTlspLock);
|
||||
LeaveCriticalSection(&MmpGlobalDataPtr->MmpTls->MmpTlspLock);
|
||||
|
||||
//
|
||||
// Free MemoryModule Tls data
|
||||
//
|
||||
RtlAcquireSRWLockExclusive(&MmpGlobalDataPtr->MmpTls.MmpTlsListLock);
|
||||
RtlAcquireSRWLockExclusive(&MmpGlobalDataPtr->MmpTls->MmpTlsListLock);
|
||||
|
||||
if (record) {
|
||||
auto TlspMmpBlock = (PVOID*)record->TlspMmpBlock;
|
||||
entry = MmpGlobalDataPtr->MmpTls.MmpTlsList.Flink;
|
||||
while (entry != &MmpGlobalDataPtr->MmpTls.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]);
|
||||
@@ -367,17 +367,17 @@ VOID NTAPI HookLdrShutdownThread(VOID) {
|
||||
RtlFreeHeap(RtlProcessHeap(), 0, TlspMmpBlock);
|
||||
}
|
||||
else {
|
||||
if (MmpGlobalDataPtr->MmpTls.MmpTlsList.Flink != &MmpGlobalDataPtr->MmpTls.MmpTlsList) {
|
||||
if (MmpGlobalDataPtr->MmpTls->MmpTlsList.Flink != &MmpGlobalDataPtr->MmpTls->MmpTlsList) {
|
||||
assert(false);
|
||||
}
|
||||
}
|
||||
|
||||
RtlReleaseSRWLockExclusive(&MmpGlobalDataPtr->MmpTls.MmpTlsListLock);
|
||||
RtlReleaseSRWLockExclusive(&MmpGlobalDataPtr->MmpTls->MmpTlsListLock);
|
||||
|
||||
//
|
||||
// Call the original function
|
||||
//
|
||||
MmpGlobalDataPtr->MmpTls.Hooks.OriginLdrShutdownThread();
|
||||
MmpGlobalDataPtr->MmpTls->Hooks.OriginLdrShutdownThread();
|
||||
}
|
||||
|
||||
BOOL NTAPI PreHookNtSetInformationProcess() {
|
||||
@@ -428,7 +428,7 @@ BOOL NTAPI PreHookNtSetInformationProcess() {
|
||||
);
|
||||
|
||||
if (NT_SUCCESS(status)) {
|
||||
EnterCriticalSection(&MmpGlobalDataPtr->MmpTls.MmpTlspLock);
|
||||
EnterCriticalSection(&MmpGlobalDataPtr->MmpTls->MmpTlspLock);
|
||||
for (DWORD i = 0; i < CurrentThreadCount; ++i) {
|
||||
auto const& LdrTls = ProcessTlsInformation->ThreadData[i];
|
||||
auto const& MmpTls = tmpTlsInformation->ThreadData[i];
|
||||
@@ -438,9 +438,9 @@ BOOL NTAPI PreHookNtSetInformationProcess() {
|
||||
record->TlspLdrBlock = LdrTls.TlsVector;
|
||||
record->TlspMmpBlock = MmpTls.TlsVector;
|
||||
record->UniqueThread = LdrTls.ThreadId;
|
||||
InsertTailList(&MmpGlobalDataPtr->MmpTls.MmpThreadLocalStoragePointer, &record->InMmpThreadLocalStoragePointer);
|
||||
InsertTailList(&MmpGlobalDataPtr->MmpTls->MmpThreadLocalStoragePointer, &record->InMmpThreadLocalStoragePointer);
|
||||
}
|
||||
LeaveCriticalSection(&MmpGlobalDataPtr->MmpTls.MmpTlspLock);
|
||||
LeaveCriticalSection(&MmpGlobalDataPtr->MmpTls->MmpTlspLock);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -458,7 +458,7 @@ NTSTATUS NTAPI HookNtSetInformationProcess(
|
||||
_In_ ULONG ProcessInformationLength) {
|
||||
|
||||
if (ProcessInformationClass != ProcessTlsInformation) {
|
||||
return MmpGlobalDataPtr->MmpTls.Hooks.OriginNtSetInformationProcess(
|
||||
return MmpGlobalDataPtr->MmpTls->Hooks.OriginNtSetInformationProcess(
|
||||
ProcessHandle,
|
||||
ProcessInformationClass,
|
||||
ProcessInformation,
|
||||
@@ -532,7 +532,7 @@ NTSTATUS NTAPI HookNtSetInformationProcess(
|
||||
}
|
||||
}
|
||||
|
||||
status = MmpGlobalDataPtr->MmpTls.Hooks.OriginNtSetInformationProcess(
|
||||
status = MmpGlobalDataPtr->MmpTls->Hooks.OriginNtSetInformationProcess(
|
||||
hProcess,
|
||||
ProcessInformationClass,
|
||||
Tls,
|
||||
@@ -542,14 +542,14 @@ NTSTATUS NTAPI HookNtSetInformationProcess(
|
||||
//
|
||||
// Modify our mapping
|
||||
//
|
||||
EnterCriticalSection(&MmpGlobalDataPtr->MmpTls.MmpTlspLock);
|
||||
EnterCriticalSection(&MmpGlobalDataPtr->MmpTls->MmpTlspLock);
|
||||
for (ULONG i = 0; i < Tls->ThreadDataCount; ++i) {
|
||||
|
||||
bool found = false;
|
||||
PLIST_ENTRY entry = MmpGlobalDataPtr->MmpTls.MmpThreadLocalStoragePointer.Flink;
|
||||
PLIST_ENTRY entry = MmpGlobalDataPtr->MmpTls->MmpThreadLocalStoragePointer.Flink;
|
||||
|
||||
// Find thread-spec tlsp
|
||||
while (entry != &MmpGlobalDataPtr->MmpTls.MmpThreadLocalStoragePointer) {
|
||||
while (entry != &MmpGlobalDataPtr->MmpTls->MmpThreadLocalStoragePointer) {
|
||||
|
||||
PMMP_TLSP_RECORD j = CONTAINING_RECORD(entry, MMP_TLSP_RECORD, InMmpThreadLocalStoragePointer);
|
||||
|
||||
@@ -593,7 +593,7 @@ NTSTATUS NTAPI HookNtSetInformationProcess(
|
||||
ProcessTlsInformation->ThreadData[i].ThreadId = Tls->ThreadData[i].ThreadId;
|
||||
}
|
||||
}
|
||||
LeaveCriticalSection(&MmpGlobalDataPtr->MmpTls.MmpTlspLock);
|
||||
LeaveCriticalSection(&MmpGlobalDataPtr->MmpTls->MmpTlspLock);
|
||||
|
||||
} while (false);
|
||||
|
||||
@@ -605,7 +605,7 @@ NTSTATUS NTAPI MmpAcquireTlsIndex(_Out_ PULONG TlsIndex) {
|
||||
|
||||
*TlsIndex = -1;
|
||||
|
||||
ULONG Index = RtlFindClearBitsAndSet(&MmpGlobalDataPtr->MmpTls.MmpTlsBitmap, 1, 0);
|
||||
ULONG Index = RtlFindClearBitsAndSet(&MmpGlobalDataPtr->MmpTls->MmpTlsBitmap, 1, 0);
|
||||
if (Index != -1) {
|
||||
*TlsIndex = Index;
|
||||
return STATUS_SUCCESS;
|
||||
@@ -666,9 +666,9 @@ NTSTATUS NTAPI MmpAllocateTlsEntry(
|
||||
Entry->TlsDirectory.Characteristics =
|
||||
*PULONG(Entry->TlsDirectory.AddressOfIndex) = TlsIndex;
|
||||
|
||||
RtlAcquireSRWLockExclusive(&MmpGlobalDataPtr->MmpTls.MmpTlsListLock);
|
||||
InsertTailList(&MmpGlobalDataPtr->MmpTls.MmpTlsList, &Entry->TlsEntryLinks);
|
||||
RtlReleaseSRWLockExclusive(&MmpGlobalDataPtr->MmpTls.MmpTlsListLock);
|
||||
RtlAcquireSRWLockExclusive(&MmpGlobalDataPtr->MmpTls->MmpTlsListLock);
|
||||
InsertTailList(&MmpGlobalDataPtr->MmpTls->MmpTlsList, &Entry->TlsEntryLinks);
|
||||
RtlReleaseSRWLockExclusive(&MmpGlobalDataPtr->MmpTls->MmpTlsListLock);
|
||||
|
||||
*lpTlsEntry = Entry;
|
||||
*lpTlsIndex = TlsIndex;
|
||||
@@ -677,20 +677,20 @@ NTSTATUS NTAPI MmpAllocateTlsEntry(
|
||||
|
||||
NTSTATUS NTAPI MmpReleaseTlsEntry(_In_ PLDR_DATA_TABLE_ENTRY lpModuleEntry) {
|
||||
|
||||
RtlAcquireSRWLockExclusive(&MmpGlobalDataPtr->MmpTls.MmpTlsListLock);
|
||||
RtlAcquireSRWLockExclusive(&MmpGlobalDataPtr->MmpTls->MmpTlsListLock);
|
||||
|
||||
for (auto entry = MmpGlobalDataPtr->MmpTls.MmpTlsList.Flink; entry != &MmpGlobalDataPtr->MmpTls.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->MmpTls.MmpTlsBitmap, p->TlsDirectory.Characteristics);
|
||||
RtlClearBit(&MmpGlobalDataPtr->MmpTls->MmpTlsBitmap, p->TlsDirectory.Characteristics);
|
||||
RtlFreeHeap(RtlProcessHeap(), 0, p);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
RtlReleaseSRWLockExclusive(&MmpGlobalDataPtr->MmpTls.MmpTlsListLock);
|
||||
RtlReleaseSRWLockExclusive(&MmpGlobalDataPtr->MmpTls->MmpTlsListLock);
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
@@ -723,7 +723,7 @@ NTSTATUS NTAPI MmpHandleTlsData(_In_ PLDR_DATA_TABLE_ENTRY lpModuleEntry) {
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
|
||||
auto ThreadCount = MmpGlobalDataPtr->MmpTls.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));
|
||||
@@ -791,26 +791,26 @@ BOOL NTAPI MmpTlsInitialize() {
|
||||
//
|
||||
// Capture thread count
|
||||
//
|
||||
MmpGlobalDataPtr->MmpTls.MmpActiveThreadCount = MmpGetThreadCount();
|
||||
MmpGlobalDataPtr->MmpTls->MmpActiveThreadCount = MmpGetThreadCount();
|
||||
|
||||
//
|
||||
// Initialize tlsp
|
||||
//
|
||||
InitializeCriticalSection(&MmpGlobalDataPtr->MmpTls.MmpTlspLock);
|
||||
InitializeListHead(&MmpGlobalDataPtr->MmpTls.MmpThreadLocalStoragePointer);
|
||||
InitializeCriticalSection(&MmpGlobalDataPtr->MmpTls->MmpTlspLock);
|
||||
InitializeListHead(&MmpGlobalDataPtr->MmpTls->MmpThreadLocalStoragePointer);
|
||||
|
||||
//
|
||||
// Initialize tls list
|
||||
//
|
||||
InitializeListHead(&MmpGlobalDataPtr->MmpTls.MmpTlsList);
|
||||
RtlInitializeSRWLock(&MmpGlobalDataPtr->MmpTls.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->MmpTls.MmpTlsBitmap, buffer, MMP_MAXIMUM_TLS_INDEX);
|
||||
RtlInitializeBitMap(&MmpGlobalDataPtr->MmpTls->MmpTlsBitmap, buffer, MMP_MAXIMUM_TLS_INDEX);
|
||||
|
||||
if (NtCurrentTeb()->ThreadLocalStoragePointer) {
|
||||
if (!PreHookNtSetInformationProcess()) {
|
||||
@@ -822,17 +822,17 @@ BOOL NTAPI MmpTlsInitialize() {
|
||||
// Hook functions
|
||||
//
|
||||
|
||||
MmpGlobalDataPtr->MmpTls.Hooks.OriginNtCreateThread = NtCreateThread;
|
||||
MmpGlobalDataPtr->MmpTls.Hooks.OriginNtCreateThreadEx = NtCreateThreadEx;
|
||||
MmpGlobalDataPtr->MmpTls.Hooks.OriginLdrShutdownThread = LdrShutdownThread;
|
||||
MmpGlobalDataPtr->MmpTls.Hooks.OriginNtSetInformationProcess = NtSetInformationProcess;
|
||||
MmpGlobalDataPtr->MmpTls->Hooks.OriginNtCreateThread = NtCreateThread;
|
||||
MmpGlobalDataPtr->MmpTls->Hooks.OriginNtCreateThreadEx = NtCreateThreadEx;
|
||||
MmpGlobalDataPtr->MmpTls->Hooks.OriginLdrShutdownThread = LdrShutdownThread;
|
||||
MmpGlobalDataPtr->MmpTls->Hooks.OriginNtSetInformationProcess = NtSetInformationProcess;
|
||||
|
||||
DetourTransactionBegin();
|
||||
DetourUpdateThread(NtCurrentThread());
|
||||
DetourAttach((PVOID*)&MmpGlobalDataPtr->MmpTls.Hooks.OriginNtCreateThread, HookNtCreateThread);
|
||||
DetourAttach((PVOID*)&MmpGlobalDataPtr->MmpTls.Hooks.OriginNtCreateThreadEx, HookNtCreateThreadEx);
|
||||
DetourAttach((PVOID*)&MmpGlobalDataPtr->MmpTls.Hooks.OriginLdrShutdownThread, HookLdrShutdownThread);
|
||||
DetourAttach((PVOID*)&MmpGlobalDataPtr->MmpTls.Hooks.OriginNtSetInformationProcess, HookNtSetInformationProcess);
|
||||
DetourAttach((PVOID*)&MmpGlobalDataPtr->MmpTls->Hooks.OriginNtCreateThread, HookNtCreateThread);
|
||||
DetourAttach((PVOID*)&MmpGlobalDataPtr->MmpTls->Hooks.OriginNtCreateThreadEx, HookNtCreateThreadEx);
|
||||
DetourAttach((PVOID*)&MmpGlobalDataPtr->MmpTls->Hooks.OriginLdrShutdownThread, HookLdrShutdownThread);
|
||||
DetourAttach((PVOID*)&MmpGlobalDataPtr->MmpTls->Hooks.OriginNtSetInformationProcess, HookNtSetInformationProcess);
|
||||
DetourTransactionCommit();
|
||||
|
||||
return TRUE;
|
||||
|
||||
Reference in New Issue
Block a user