From bcf869f51be40080172df47ef02e1b3b1d630708 Mon Sep 17 00:00:00 2001 From: BeneficialCode <40847073+BeneficialCode@users.noreply.github.com> Date: Wed, 6 Mar 2024 14:34:02 +0800 Subject: [PATCH 1/6] Update README.md 404 not found --- README.md | 3 --- 1 file changed, 3 deletions(-) diff --git a/README.md b/README.md index 137d30d..3249670 100644 --- a/README.md +++ b/README.md @@ -17,8 +17,6 @@ Telegram Group: [t.me/WinArk_dev](https://t.me/WinArk_dev) Contributing to WinArk is super appreciated. If you want to contribute to WinArk, please read the [Coding Conventions](doc/Coding%20Conventions.md) -If anyone wants to support me, you may do so by donating me some money: https://www.paypal.me/VirtualCCSimon - ## Screenshots ![](./Untitled%2016.png) @@ -39,7 +37,6 @@ If anyone wants to support me, you may do so by donating me some money: https:// - Core features by [SystemExplorer](https://github.com/zodiacon/SystemExplorer) - Disassembly powered by [capstone](https://github.com/capstone-engine/capstone) - PE parser by [TotalPE](https://github.com/zodiacon/PEParser) -- Network Explorer by [NetworkExplorer](https://github.com/zodiacon/NetworkExplorer) - Registry Explorer by [TotalRegistry](https://github.com/zodiacon/TotalRegistry) - DeviceExplorer by [DeviceExplorer](https://github.com/zodiacon/DeviceExplorer) - Event Trace by [ProcMonXv2](https://github.com/zodiacon/ProcMonXv2) From 12c026a08900468f191e38079d9eef297b3e4d16 Mon Sep 17 00:00:00 2001 From: BeneficialCode <3123132899@qq.com> Date: Sat, 23 Mar 2024 17:29:08 +0800 Subject: [PATCH 2/6] Fixup the kernel module list error on Windows 7 x64. --- PEParser/PEParser.cpp | 17 +++++++++++----- PEParser/PEParser.h | 5 ++--- WinArk/WinArk.vcxproj | 2 +- WinSysCore/KernelModuleTracker.cpp | 31 +++++++++++++++++++++++++++++- WinSysCore/WinSysCore.vcxproj | 13 +++++++++---- 5 files changed, 54 insertions(+), 14 deletions(-) diff --git a/PEParser/PEParser.cpp b/PEParser/PEParser.cpp index 6a739ba..401c4c0 100644 --- a/PEParser/PEParser.cpp +++ b/PEParser/PEParser.cpp @@ -110,14 +110,14 @@ void* PEParser::GetBaseAddress() const { return _address; } -CString PEParser::GetSectionName(ULONG section) const { +std::string PEParser::GetSectionName(ULONG section) const { auto header = GetSectionHeader(section); if (header == nullptr) - return L""; + return ""; if (header->Name[IMAGE_SIZEOF_SHORT_NAME - 1] == '\0') - return CString((PCSTR)header->Name); - return CString((PCSTR)header->Name, IMAGE_SIZEOF_SHORT_NAME); + return std::string((PCSTR)header->Name); + return std::string((PCSTR)header->Name, IMAGE_SIZEOF_SHORT_NAME); } std::vector PEParser::GetExports() const { @@ -251,10 +251,17 @@ void* PEParser::GetAddress(unsigned rva) const { } SubsystemType PEParser::GetSubsystemType() const { - return static_cast(GetOptionalHeader64().Subsystem); + if (IsPe64()) + return static_cast(GetOptionalHeader64().Subsystem); + else + return static_cast(GetOptionalHeader32().Subsystem); } void PEParser::CheckValidity() { + if (_address == nullptr) { + _valid = false; + return; + } if (::strncmp((PCSTR)_address, "!\n", 8) == 0) { // LIB import library _importLib = true; diff --git a/PEParser/PEParser.h b/PEParser/PEParser.h index 6fc8669..f5ad7ba 100644 --- a/PEParser/PEParser.h +++ b/PEParser/PEParser.h @@ -1,5 +1,4 @@ #pragma once - class CLRMetadataParser; struct ExportedSymbol { @@ -136,7 +135,7 @@ enum class MachineType : unsigned short { }; struct ResourceInfo { - CString Name; + std::string Name; DWORD Rva; DWORD Size; void* Address; @@ -177,7 +176,7 @@ class PEParser final { ULONG GetEAT() const; - CString GetSectionName(ULONG section) const; + std::string GetSectionName(ULONG section) const; void* RVA2FA(unsigned rva) const; diff --git a/WinArk/WinArk.vcxproj b/WinArk/WinArk.vcxproj index a6d1627..e21df1d 100644 --- a/WinArk/WinArk.vcxproj +++ b/WinArk/WinArk.vcxproj @@ -21,7 +21,7 @@ 16.0 {B8B52E8A-3A29-449D-B324-7A72994F83E2} - 10.0 + 10.0.19041.0 diff --git a/WinSysCore/KernelModuleTracker.cpp b/WinSysCore/KernelModuleTracker.cpp index 289fb96..be6726f 100644 --- a/WinSysCore/KernelModuleTracker.cpp +++ b/WinSysCore/KernelModuleTracker.cpp @@ -1,5 +1,7 @@ #include "pch.h" #include "KernelModuleTracker.h" +#include +#include "Helpers.h" using namespace WinSys; @@ -8,6 +10,13 @@ uint32_t WinSys::KernelModuleTracker::EnumModules() { DWORD size = 1 << 18; wil::unique_virtualalloc_ptr<> buffer(::VirtualAlloc(nullptr, size,MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE)); + PVOID SystemRangeStart = 0; + NtQuerySystemInformation(SystemRangeStartInformation, + &SystemRangeStart, + sizeof(SystemRangeStart), + NULL); + + NTSTATUS status; status = ::NtQuerySystemInformation(SystemModuleInformationEx, buffer.get(), size, nullptr); if (!NT_SUCCESS(status)) @@ -22,7 +31,7 @@ uint32_t WinSys::KernelModuleTracker::EnumModules() { ::GetWindowsDirectoryA(winDir, _countof(winDir)); static const std::string root("\\SystemRoot\\"); static const std::string global("\\??\\"); - + for (;;) { if (p->BaseInfo.ImageBase == 0) break; @@ -34,6 +43,26 @@ uint32_t WinSys::KernelModuleTracker::EnumModules() { m->FullPath = m->FullPath.substr(global.size()); if (m->FullPath.find(root) == 0) m->FullPath = winDir + m->FullPath.substr(root.size() - 1); + + if (p->BaseInfo.ImageBase < SystemRangeStart) { + if (p->NextOffset == 0) + break; + p = (RTL_PROCESS_MODULE_INFORMATION_EX*)((BYTE*)p + p->NextOffset); + continue; + } + + std::wstring path = Helpers::StringToWstring(m->FullPath); + PEParser parser(path.c_str()); + if (parser.IsValid()) { + auto type = parser.GetSubsystemType(); + if (type != SubsystemType::Native) { + if (p->NextOffset == 0) + break; + p = (RTL_PROCESS_MODULE_INFORMATION_EX*)((BYTE*)p + p->NextOffset); + continue; + } + } + m->ImageBase = p->BaseInfo.ImageBase; m->MappedBase = p->BaseInfo.MappedBase; m->ImageSize = p->BaseInfo.ImageSize; diff --git a/WinSysCore/WinSysCore.vcxproj b/WinSysCore/WinSysCore.vcxproj index 749186d..0cefbca 100644 --- a/WinSysCore/WinSysCore.vcxproj +++ b/WinSysCore/WinSysCore.vcxproj @@ -88,7 +88,7 @@ true WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) true - ..\phnt + ..\phnt;..\PEParser; stdcpplatest MultiThreadedDebug @@ -105,7 +105,7 @@ true WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) true - ..\phnt + ..\phnt;..\PEParser; stdcpplatest MultiThreaded @@ -125,7 +125,7 @@ Use pch.h stdcpplatest - ..\phnt + ..\phnt;..\PEParser; MultiThreadedDebug @@ -141,7 +141,7 @@ true NDEBUG;_CONSOLE;%(PreprocessorDefinitions) true - ..\phnt + ..\phnt;..\PEParser; stdcpp20 MultiThreaded false @@ -228,6 +228,11 @@ + + + {cc899776-2282-4442-bc9d-f21130c80fe1} + + From 1b9773b6f3a8d69455b012a28b6e80081643a60e Mon Sep 17 00:00:00 2001 From: BeneficialCode <3123132899@qq.com> Date: Fri, 26 Apr 2024 20:06:20 +0800 Subject: [PATCH 3/6] Update the OB_CALLBACK_CONTEXT_BLOCK define. --- Anti-Rootkit/AntiRootkit.h | 2 +- KernelLibrary/KernelLibrary.vcxproj | 2 +- KernelLibrary/SysMon.cpp | 64 ++++++++++++++--------------- KernelLibrary/SysMon.h | 16 ++++---- WinArk/ObjectCallbackTable.cpp | 2 +- 5 files changed, 43 insertions(+), 43 deletions(-) diff --git a/Anti-Rootkit/AntiRootkit.h b/Anti-Rootkit/AntiRootkit.h index 986b0f3..782da52 100644 --- a/Anti-Rootkit/AntiRootkit.h +++ b/Anti-Rootkit/AntiRootkit.h @@ -223,7 +223,7 @@ struct ObCallbackInfo{ PVOID PostOperation; ObjectCallbackType Type; PVOID CallbackEntry; - bool Enabled; + ULONG Flags; ULONG Operations; }; diff --git a/KernelLibrary/KernelLibrary.vcxproj b/KernelLibrary/KernelLibrary.vcxproj index 4c58c4e..d116b97 100644 --- a/KernelLibrary/KernelLibrary.vcxproj +++ b/KernelLibrary/KernelLibrary.vcxproj @@ -42,7 +42,7 @@ Debug Win32 KernelLibrary - $(LatestTargetPlatformVersion) + 10.0.19041.0 diff --git a/KernelLibrary/SysMon.cpp b/KernelLibrary/SysMon.cpp index 2238f33..8bca175 100644 --- a/KernelLibrary/SysMon.cpp +++ b/KernelLibrary/SysMon.cpp @@ -551,9 +551,9 @@ bool EnumObCallbackNotify(ULONG callbackListOffset,ObCallbackInfo* info) { nextEntry = callbackListHead->Flink; while (nextEntry != callbackListHead) { - callbackEntry = CONTAINING_RECORD(nextEntry, OB_CALLBACK_ENTRY, CallbackList); - if (ExAcquireRundownProtection(&callbackEntry->RundownProtect)) { - KdPrint(("PreOperation %p, PostOperation: %p\n", callbackEntry->PreOperation, callbackEntry->PostOperation)); + callbackEntry = CONTAINING_RECORD(nextEntry, OB_CALLBACK_ENTRY, CallbackListEntry); + if (ExAcquireRundownProtection(&callbackEntry->RundownReference)) { + KdPrint(("PreOperation %p, PostOperation: %p\n", callbackEntry->PreCallback, callbackEntry->PostCallback)); if (FlagOn(callbackEntry->Operations, OB_OPERATION_HANDLE_CREATE)) KdPrint(("Protect handle from creating\n")); if (FlagOn(callbackEntry->Operations, OB_OPERATION_HANDLE_DUPLICATE)) @@ -561,12 +561,12 @@ bool EnumObCallbackNotify(ULONG callbackListOffset,ObCallbackInfo* info) { info[i].Type = ObjectCallbackType::Thread; info[i].Operations = callbackEntry->Operations; info[i].CallbackEntry = callbackEntry; - info[i].PostOperation = callbackEntry->PostOperation; - info[i].PreOperation = callbackEntry->PreOperation; - info[i].RegistrationHandle = callbackEntry->RegistrationHandle; - info[i].Enabled = callbackEntry->Enabled; + info[i].PostOperation = callbackEntry->PostCallback; + info[i].PreOperation = callbackEntry->PreCallback; + info[i].RegistrationHandle = callbackEntry->Registration; + info[i].Flags = callbackEntry->Flags; i++; - ExReleaseRundownProtection(&callbackEntry->RundownProtect); + ExReleaseRundownProtection(&callbackEntry->RundownReference); } nextEntry = nextEntry->Flink; } @@ -575,9 +575,9 @@ bool EnumObCallbackNotify(ULONG callbackListOffset,ObCallbackInfo* info) { nextEntry = callbackListHead->Flink; while (nextEntry != callbackListHead) { - callbackEntry = CONTAINING_RECORD(nextEntry, OB_CALLBACK_ENTRY, CallbackList); - if (ExAcquireRundownProtection(&callbackEntry->RundownProtect)) { - KdPrint(("PreOperation %p, PostOperation: %p\n", callbackEntry->PreOperation, callbackEntry->PostOperation)); + callbackEntry = CONTAINING_RECORD(nextEntry, OB_CALLBACK_ENTRY, CallbackListEntry); + if (ExAcquireRundownProtection(&callbackEntry->RundownReference)) { + KdPrint(("PreOperation %p, PostOperation: %p\n", callbackEntry->PreCallback, callbackEntry->PostCallback)); if (FlagOn(callbackEntry->Operations, OB_OPERATION_HANDLE_CREATE)) KdPrint(("Protect handle from creating\n")); if (FlagOn(callbackEntry->Operations, OB_OPERATION_HANDLE_DUPLICATE)) @@ -585,12 +585,12 @@ bool EnumObCallbackNotify(ULONG callbackListOffset,ObCallbackInfo* info) { info[i].Type = ObjectCallbackType::Process; info[i].Operations = callbackEntry->Operations; info[i].CallbackEntry = callbackEntry; - info[i].PostOperation = callbackEntry->PostOperation; - info[i].PreOperation = callbackEntry->PreOperation; - info[i].RegistrationHandle = callbackEntry->RegistrationHandle; - info[i].Enabled = callbackEntry->Enabled; + info[i].PostOperation = callbackEntry->PostCallback; + info[i].PreOperation = callbackEntry->PreCallback; + info[i].RegistrationHandle = callbackEntry->Registration; + info[i].Flags = callbackEntry->Flags; i++; - ExReleaseRundownProtection(&callbackEntry->RundownProtect); + ExReleaseRundownProtection(&callbackEntry->RundownReference); } nextEntry = nextEntry->Flink; } @@ -599,9 +599,9 @@ bool EnumObCallbackNotify(ULONG callbackListOffset,ObCallbackInfo* info) { nextEntry = callbackListHead->Flink; while (nextEntry != callbackListHead) { - callbackEntry = CONTAINING_RECORD(nextEntry, OB_CALLBACK_ENTRY, CallbackList); - if (ExAcquireRundownProtection(&callbackEntry->RundownProtect)) { - LogInfo("PreOperation %p, PostOperation: %p\n", callbackEntry->PreOperation, callbackEntry->PostOperation); + callbackEntry = CONTAINING_RECORD(nextEntry, OB_CALLBACK_ENTRY, CallbackListEntry); + if (ExAcquireRundownProtection(&callbackEntry->RundownReference)) { + LogInfo("PreOperation %p, PostOperation: %p\n", callbackEntry->PreCallback, callbackEntry->PostCallback); if (FlagOn(callbackEntry->Operations, OB_OPERATION_HANDLE_CREATE)) LogInfo("Protect handle from creating\n"); if (FlagOn(callbackEntry->Operations, OB_OPERATION_HANDLE_DUPLICATE)) @@ -609,12 +609,12 @@ bool EnumObCallbackNotify(ULONG callbackListOffset,ObCallbackInfo* info) { info[i].Type = ObjectCallbackType::Desktop; info[i].Operations = callbackEntry->Operations; info[i].CallbackEntry = callbackEntry; - info[i].PostOperation = callbackEntry->PostOperation; - info[i].PreOperation = callbackEntry->PreOperation; - info[i].RegistrationHandle = callbackEntry->RegistrationHandle; - info[i].Enabled = callbackEntry->Enabled; + info[i].PostOperation = callbackEntry->PostCallback; + info[i].PreOperation = callbackEntry->PreCallback; + info[i].RegistrationHandle = callbackEntry->Registration; + info[i].Flags = callbackEntry->Flags; i++; - ExReleaseRundownProtection(&callbackEntry->RundownProtect); + ExReleaseRundownProtection(&callbackEntry->RundownReference); } nextEntry = nextEntry->Flink; } @@ -637,7 +637,7 @@ LONG GetObCallbackCount(ULONG callbackListOffset) { nextEntry = callbackListHead->Flink; while (nextEntry != callbackListHead) { - callbackEntry = CONTAINING_RECORD(nextEntry, OB_CALLBACK_ENTRY, CallbackList); + callbackEntry = CONTAINING_RECORD(nextEntry, OB_CALLBACK_ENTRY, CallbackListEntry); InterlockedIncrement(&count); nextEntry = nextEntry->Flink; } @@ -647,7 +647,7 @@ LONG GetObCallbackCount(ULONG callbackListOffset) { nextEntry = callbackListHead->Flink; while (nextEntry != callbackListHead) { - callbackEntry = CONTAINING_RECORD(nextEntry, OB_CALLBACK_ENTRY, CallbackList); + callbackEntry = CONTAINING_RECORD(nextEntry, OB_CALLBACK_ENTRY, CallbackListEntry); InterlockedIncrement(&count); nextEntry = nextEntry->Flink; } @@ -657,7 +657,7 @@ LONG GetObCallbackCount(ULONG callbackListOffset) { nextEntry = callbackListHead->Flink; while (nextEntry != callbackListHead) { - callbackEntry = CONTAINING_RECORD(nextEntry, OB_CALLBACK_ENTRY, CallbackList); + callbackEntry = CONTAINING_RECORD(nextEntry, OB_CALLBACK_ENTRY, CallbackListEntry); InterlockedIncrement(&count); nextEntry = nextEntry->Flink; } @@ -848,10 +848,10 @@ bool RemoveObCallbackNotify(POB_CALLBACK_ENTRY pCallbackEntry){ if (!pCallbackEntry) { return false; } - pCallbackEntry->RegistrationHandle->Count = 0; - bool ret = RemoveEntryList(&pCallbackEntry->CallbackList); + pCallbackEntry->Registration->RegistrationCount = 0; + bool ret = RemoveEntryList(&pCallbackEntry->CallbackListEntry); if (!ret) { - ObUnRegisterCallbacks(pCallbackEntry->RegistrationHandle); + ObUnRegisterCallbacks(pCallbackEntry->Registration); } return ret; } @@ -1132,11 +1132,11 @@ bool StopLogDriverHash() { void DisableObCallbackNotify(POB_CALLBACK_ENTRY pCallbackEntry) { if (!pCallbackEntry) return; - pCallbackEntry->Enabled = FALSE; + pCallbackEntry->Flags = FALSE; } void EnableObCallbackNotify(POB_CALLBACK_ENTRY pCallbackEntry) { if (!pCallbackEntry) return; - pCallbackEntry->Enabled = TRUE; + pCallbackEntry->Flags = TRUE; } \ No newline at end of file diff --git a/KernelLibrary/SysMon.h b/KernelLibrary/SysMon.h index 3966efc..e9f73e9 100644 --- a/KernelLibrary/SysMon.h +++ b/KernelLibrary/SysMon.h @@ -72,14 +72,14 @@ typedef struct _CM_CALLBACK_CONTEXT_BLOCKEX struct _OB_CALLBACK_BLOCK; typedef struct _OB_CALLBACK_ENTRY { - LIST_ENTRY CallbackList; + LIST_ENTRY CallbackListEntry; OB_OPERATION Operations; // 1 for Creations, 2 for Duplications - BOOLEAN Enabled; - struct _OB_CALLBACK_BLOCK* RegistrationHandle; // Points to the OB_CALLBACK_BLOCK used for ObUnRegisterCallback + ULONG Flags; + struct _OB_CALLBACK_BLOCK* Registration; // Points to the OB_CALLBACK_BLOCK used for ObUnRegisterCallback POBJECT_TYPE ObjectType; - POB_PRE_OPERATION_CALLBACK PreOperation; - POB_POST_OPERATION_CALLBACK PostOperation; - EX_RUNDOWN_REF RundownProtect; + POB_PRE_OPERATION_CALLBACK PreCallback; + POB_POST_OPERATION_CALLBACK PostCallback; + EX_RUNDOWN_REF RundownReference; }OB_CALLBACK_ENTRY, * POB_CALLBACK_ENTRY; @@ -88,10 +88,10 @@ typedef struct _OB_CALLBACK_ENTRY { // x64 0x20 0x40 32 64 typedef struct _OB_CALLBACK_BLOCK { USHORT Version; - USHORT Count; + USHORT RegistrationCount; POB_OPERATION_REGISTRATION RegistrationContext; UNICODE_STRING Altitude; - OB_CALLBACK_ENTRY Items[ANYSIZE_ARRAY]; // Callback array + OB_CALLBACK_ENTRY CallbackContext[ANYSIZE_ARRAY]; // Callback array }OB_CALLBACK_BLOCK, * POB_CALLBACK_BLOCK; diff --git a/WinArk/ObjectCallbackTable.cpp b/WinArk/ObjectCallbackTable.cpp index b625adc..a0b3894 100644 --- a/WinArk/ObjectCallbackTable.cpp +++ b/WinArk/ObjectCallbackTable.cpp @@ -237,7 +237,7 @@ void CObjectCallbackTable::Refresh() { ObjectCallbackInfo info; info.CallbackEntry = p[i].CallbackEntry; info.Operations = p[i].Operations; - info.Enabled = p[i].Enabled; + info.Enabled = p[i].Flags; info.RegistrationHandle = p[i].RegistrationHandle; info.PreOperation = p[i].PreOperation; info.PostOperation = p[i].PostOperation; From 18d09a76aea7c2bcf1b4d69ac4992e1c877afdbb Mon Sep 17 00:00:00 2001 From: BeneficialCode <3123132899@qq.com> Date: Sat, 27 Apr 2024 07:29:09 +0800 Subject: [PATCH 4/6] tweak the CM_CALLBACK_CONTEXT define. --- KernelLibrary/SysMon.cpp | 4 ++-- KernelLibrary/SysMon.h | 11 ++++++----- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/KernelLibrary/SysMon.cpp b/KernelLibrary/SysMon.cpp index 8bca175..40d116e 100644 --- a/KernelLibrary/SysMon.cpp +++ b/KernelLibrary/SysMon.cpp @@ -521,10 +521,10 @@ bool EnumRegistryNotify(PLIST_ENTRY pListHead,CmCallbackInfo* info) { PLIST_ENTRY callbackListHead = pListHead; PLIST_ENTRY nextEntry = callbackListHead->Flink; - PCM_CALLBACK_CONTEXT_BLOCKEX callbackEntry = nullptr; + PCM_CALLBACK_CONTEXT callbackEntry = nullptr; int i = 0; while (nextEntry != callbackListHead) { - callbackEntry = CONTAINING_RECORD(nextEntry, CM_CALLBACK_CONTEXT_BLOCKEX, ListEntry); + callbackEntry = CONTAINING_RECORD(nextEntry, CM_CALLBACK_CONTEXT, CallbackListEntry); LogInfo("Cookie %p, Function: %p\n", callbackEntry->Cookie, callbackEntry->Function); info[i].Address = callbackEntry->Function; info[i].Cookie = callbackEntry->Cookie; diff --git a/KernelLibrary/SysMon.h b/KernelLibrary/SysMon.h index e9f73e9..c5afacc 100644 --- a/KernelLibrary/SysMon.h +++ b/KernelLibrary/SysMon.h @@ -56,17 +56,18 @@ typedef struct _EX_CALLBACK #define MAX_FAST_REFS 7 #endif -typedef struct _CM_CALLBACK_CONTEXT_BLOCKEX +typedef struct _CM_CALLBACK_CONTEXT { - LIST_ENTRY ListEntry; - ULONG PreCallListCount; - ULONG Pad; + LIST_ENTRY CallbackListEntry; + ULONG ActiveCalls; LARGE_INTEGER Cookie; PVOID CallerContext; PVOID Function; UNICODE_STRING Altitude; LIST_ENTRY ObjectContextListHead; -} CM_CALLBACK_CONTEXT_BLOCKEX, * PCM_CALLBACK_CONTEXT_BLOCKEX; +} CM_CALLBACK_CONTEXT, * PCM_CALLBACK_CONTEXT; + + struct _OB_CALLBACK_BLOCK; From b3fca73ab6f9fffadbff4fb3ee4480e2b96328c5 Mon Sep 17 00:00:00 2001 From: BeneficialCode <3123132899@qq.com> Date: Sat, 27 Apr 2024 17:15:17 +0800 Subject: [PATCH 5/6] modify the hash table. --- KernelLibrary/HashTable.cpp | 47 ++++++++++++++++++------------------- KernelLibrary/HashTable.h | 14 +++++------ Test/Test.vcxproj | 1 + Test/test.cpp | 8 +++---- 4 files changed, 34 insertions(+), 36 deletions(-) diff --git a/KernelLibrary/HashTable.cpp b/KernelLibrary/HashTable.cpp index 5bdc1a1..fcdc683 100644 --- a/KernelLibrary/HashTable.cpp +++ b/KernelLibrary/HashTable.cpp @@ -21,15 +21,15 @@ UINT32 GetHighestBitIndex(UINT32 value) { return index; } -void HashTableInitialize(PHASH_TABLE Hash, UINT32 Flags, +void HashTableInitialize(PHASH_TABLE Hash, UINT32 MaskBitCount, UINT32 BucketCount, PSINGLE_LIST_ENTRY Buckets) { UINT32 count = RoundToPowerOfTwo(BucketCount, FALSE); if (count > 0x4000000) count = 0x4000000; - Hash->ItemCount = 0; - Hash->BucketCount = (count << 5) | Hash->BucketCount & 0x1F; + Hash->EntryCount = 0; + Hash->BucketCount = count; Hash->Buckets = Buckets; - Hash->BucketCount = Flags & 0x1F | Hash->BucketCount & 0xFFFFFFE0; + Hash->MaskBitCount = MaskBitCount; PSINGLE_LIST_ENTRY p = Buckets; PSINGLE_LIST_ENTRY pEnd = &Buckets[count]; if (p) { @@ -87,14 +87,13 @@ UINT32 HashTableGetBucketIndex(UINT32 bucketCount, UINT64 key) { } UINT32 HashTableInsert(PHASH_TABLE Hash, PHASH_BUCKET pBucket) { - UINT32 count = (Hash->BucketCount >> 5) & 0x7FFFFFF; - UINT32 flags = Hash->BucketCount & 0x1F; - UINT64 key = (MAXULONG_PTR << flags) & pBucket->HashValue; + UINT32 count = Hash->BucketCount; + UINT64 key = (MAXULONG_PTR << Hash->MaskBitCount) & pBucket->Key; UINT32 idx = HashTableGetBucketIndex(count, key); PushEntryList(&Hash->Buckets[idx], (PSINGLE_LIST_ENTRY)pBucket); - count = Hash->ItemCount + 1; - Hash->ItemCount = count; + count = Hash->EntryCount + 1; + Hash->EntryCount = count; return count; } @@ -113,14 +112,14 @@ PSINGLE_LIST_ENTRY HashTableChangeTable(PHASH_TABLE Hash, ULONG allocCount, PSIN p->Next = (PSINGLE_LIST_ENTRY)((ULONG_PTR)Hash | 1); } - UINT64 value = MAXULONG_PTR << (Hash->BucketCount & 0x1F); - UINT32 bucketCount = (Hash->BucketCount >> 5) & 0x7FFFFFF; + UINT64 value = MAXULONG_PTR << Hash->MaskBitCount; + UINT32 bucketCount = Hash->BucketCount; for (UINT32 j = 0; j < bucketCount; ++j) { PSINGLE_LIST_ENTRY pBucket = &Hash->Buckets[j]; while (!HashBucketLastLink(pBucket)) { PSINGLE_LIST_ENTRY pEntry = pBucket->Next; pBucket->Next = pBucket->Next->Next; - UINT64 hashValue = ((PHASH_BUCKET)pEntry)->HashValue; + UINT64 hashValue = ((PHASH_BUCKET)pEntry)->Key; UINT32 idx = HashTableGetBucketIndex(bucketCount, value & hashValue); PushEntryList(&pBuckets[idx], pEntry); } @@ -128,13 +127,13 @@ PSINGLE_LIST_ENTRY HashTableChangeTable(PHASH_TABLE Hash, ULONG allocCount, PSIN pOldBuckets = Hash->Buckets; Hash->Buckets = pBuckets; - Hash->BucketCount = (count << 5) | Hash->BucketCount & 0x1F; + Hash->BucketCount = count; return pOldBuckets; } PSINGLE_LIST_ENTRY HashTableFindNext(PHASH_TABLE Hash, UINT64 HashValue, PSINGLE_LIST_ENTRY pLink) { - UINT64 value = MAXULONG_PTR << (Hash->BucketCount & 0x1F); + UINT64 value = MAXULONG_PTR << Hash->MaskBitCount; UINT64 k1 = value & HashValue; BOOL bLastLink = FALSE; PSINGLE_LIST_ENTRY p = pLink; @@ -143,7 +142,7 @@ PSINGLE_LIST_ENTRY HashTableFindNext(PHASH_TABLE Hash, UINT64 HashValue, PSINGLE bLastLink = HashBucketLastLink(pLink); } else { - UINT32 count = (Hash->BucketCount >> 5) & 0x7FFFFFF; + UINT32 count = Hash->BucketCount; if (count == 0) return NULL; UINT32 idx = HashTableGetBucketIndex(count, k1); @@ -153,7 +152,7 @@ PSINGLE_LIST_ENTRY HashTableFindNext(PHASH_TABLE Hash, UINT64 HashValue, PSINGLE for (bLastLink = HashBucketLastLink(p); !bLastLink; bLastLink = HashBucketLastLink(p)) { - UINT64 k2 = value & ((PHASH_BUCKET)p->Next)->HashValue; + UINT64 k2 = value & ((PHASH_BUCKET)p->Next)->Key; if (k1 == k2) { return p->Next; } @@ -177,7 +176,7 @@ PHASH_TABLE HashTableGetTable(PSINGLE_LIST_ENTRY HashEntry) { PSINGLE_LIST_ENTRY pEntry = NULL; do { - UINT64 hashValue = ((PHASH_BUCKET)HashEntry)->HashValue; + UINT64 hashValue = ((PHASH_BUCKET)HashEntry)->Key; pEntry = HashTableFindNext(pHash, hashValue, pEntry); } while (pEntry && pEntry != HashEntry); @@ -189,22 +188,22 @@ PSINGLE_LIST_ENTRY HashTableCleanup(PHASH_TABLE Hash) { } PSINGLE_LIST_ENTRY HashTableRemoveKey(PHASH_TABLE Hash, UINT64 HashValue) { - if (!Hash->ItemCount) + if (!Hash->EntryCount) return NULL; - UINT64 value = MAXULONG_PTR << (Hash->BucketCount & 0x1F); + UINT64 value = MAXULONG_PTR << Hash->MaskBitCount; UINT64 k1 = value & HashValue; - UINT32 count = (Hash->BucketCount >> 5) & 0x7FFFFFF; + UINT32 count = Hash->BucketCount; UINT32 idx = HashTableGetBucketIndex(count, k1); PSINGLE_LIST_ENTRY p = &Hash->Buckets[idx]; BOOL bLastLink; for (bLastLink = HashBucketLastLink(p); !bLastLink; bLastLink = HashBucketLastLink(p)) { PSINGLE_LIST_ENTRY pNext = p->Next; - UINT64 k2 = value & ((PHASH_BUCKET)p)->HashValue; + UINT64 k2 = value & ((PHASH_BUCKET)p)->Key; if (k1 == k2) { p->Next = pNext->Next; - --Hash->ItemCount; + --Hash->EntryCount; pNext->Next = (PSINGLE_LIST_ENTRY)((ULONG_PTR)pNext->Next | 0x8000000000000002); return p->Next; } @@ -229,7 +228,7 @@ PSINGLE_LIST_ENTRY HashTableIterGetNext(PHASH_TABLE_ITERATOR Iterator) { PHASH_TABLE Hash = Iterator->Hash; PSINGLE_LIST_ENTRY pBucket = Iterator->Bucket + 1; - count = (Hash->BucketCount >> 5) & 0x7FFFFFF; + count = Hash->BucketCount; PSINGLE_LIST_ENTRY pEnd = &Hash->Buckets[count]; while (TRUE) { @@ -258,7 +257,7 @@ PSINGLE_LIST_ENTRY HashTableIterRemove(PHASH_TABLE_ITERATOR Iterator) { for (bLastLink = HashBucketLastLink(pBucket); !bLastLink; bLastLink = HashBucketLastLink(pBucket)) { if (pBucket->Next == pHashEntry) { pBucket->Next = pHashEntry->Next; - --Iterator->Hash->ItemCount; + --Iterator->Hash->EntryCount; pHashEntry->Next = (PSINGLE_LIST_ENTRY)((ULONG_PTR)pHashEntry->Next | 0x8000000000000002); Iterator->HashEntry = pBucket; return pHashEntry; diff --git a/KernelLibrary/HashTable.h b/KernelLibrary/HashTable.h index 60359f7..fe226ee 100644 --- a/KernelLibrary/HashTable.h +++ b/KernelLibrary/HashTable.h @@ -1,16 +1,14 @@ #pragma once typedef struct _HASH_BUCKET { - union { - ULONG_PTR Hash; - SINGLE_LIST_ENTRY Link; - }; - UINT64 HashValue; + SINGLE_LIST_ENTRY BucketLink; + UINT64 Key; }HASH_BUCKET, * PHASH_BUCKET; typedef struct _HASH_TABLE { - UINT32 ItemCount; - UINT32 BucketCount; + UINT32 EntryCount; + UINT32 MaskBitCount : 5; + UINT32 BucketCount : 27; PSINGLE_LIST_ENTRY Buckets; }HASH_TABLE, * PHASH_TABLE; @@ -32,7 +30,7 @@ UINT32 RoundToPowerOfTwo(UINT32 value, BOOLEAN roundUpToNext); BOOLEAN IsPowerOfTwo(UINT32 x); -void HashTableInitialize(PHASH_TABLE Hash, UINT32 Flags, +void HashTableInitialize(PHASH_TABLE Hash, UINT32 MaskBitCount, UINT32 BucketCount, PSINGLE_LIST_ENTRY Buckets); UINT32 HashTableGetBucketIndex(UINT32 BucketCount, UINT64 Key); UINT32 HashTableInsert(PHASH_TABLE Hash, PHASH_BUCKET pBucket); diff --git a/Test/Test.vcxproj b/Test/Test.vcxproj index 6aab2a5..f452bae 100644 --- a/Test/Test.vcxproj +++ b/Test/Test.vcxproj @@ -42,6 +42,7 @@ Debug Win32 Test + 10.0.19041.0 diff --git a/Test/test.cpp b/Test/test.cpp index 9f98f34..7df78a8 100644 --- a/Test/test.cpp +++ b/Test/test.cpp @@ -2,7 +2,6 @@ #include #include #include -#include "..\KernelLibrary\reflector.h" #include "..\KernelLibrary\detours.h" #include "..\KernelLibrary\khook.h" #include "..\KernelLibrary\HashTable.h" @@ -59,13 +58,13 @@ DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath) { item->height = 183; item->name = "ShuaiGeZengZhenDeShuai"; UINT64 hash = HashUlongPtr((UINT64)item->name); - item->bucket.HashValue = hash; + item->bucket.Key = hash; item2->age = 19; item2->height = 182; item2->name = "ShuaiGeCunZhenDeShuai"; UINT64 hash2 = HashUlongPtr((UINT64)item2->name); - item2->bucket.HashValue = hash2; + item2->bucket.Key = hash2; HashTableInsert(&g_Table, &item->bucket); @@ -107,7 +106,8 @@ DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath) { DbgBreakPoint(); HASH_TABLE_ITERATOR iter; - HashTableIterInit(&iter, (PHASH_TABLE)(0xfffff80010bf0000 + 0x20AF0)); + // WdBoot.sys 0xFFFFF80167830000 0xA000 25 Microsoft Corporation C:\Windows\system32\drivers\wd\WdBoot.sys + HashTableIterInit(&iter, (PHASH_TABLE)(0xFFFFF80167830000 + 0x20AF0)); while (HashTableIterGetNext(&iter)) { KdPrint(("result %p", iter.HashEntry)); From d37d7178704be29189dd100e060ee733005ed7b6 Mon Sep 17 00:00:00 2001 From: BeneficialCode <3123132899@qq.com> Date: Sun, 28 Apr 2024 22:23:08 +0800 Subject: [PATCH 6/6] fixup the virtual address. --- WinArk/BigPoolView.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/WinArk/BigPoolView.cpp b/WinArk/BigPoolView.cpp index 37740bf..31b97c4 100644 --- a/WinArk/BigPoolView.cpp +++ b/WinArk/BigPoolView.cpp @@ -265,8 +265,11 @@ LRESULT CBigPoolView::OnGetDisplayInfo(int, LPNMHDR nmhdr, BOOL&) { break; case ColumnType::VirtualAddress: - StringCchPrintf(item.pszText, item.cchTextMax, L"0x%p", info.BigPoolInfo.VirtualAddress); + { + ULONG_PTR addr = info.BigPoolInfo.NonPaged ? (ULONG_PTR)info.BigPoolInfo.VirtualAddress - 1 : (ULONG_PTR)info.BigPoolInfo.VirtualAddress; + StringCchPrintf(item.pszText, item.cchTextMax, L"0x%p", addr); break; + } case ColumnType::Size: {