Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
BeneficialCode committed May 15, 2024
2 parents 2f11816 + d37d717 commit 2d2cb83
Show file tree
Hide file tree
Showing 16 changed files with 143 additions and 104 deletions.
2 changes: 1 addition & 1 deletion Anti-Rootkit/AntiRootkit.h
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,7 @@ struct ObCallbackInfo{
PVOID PostOperation;
ObjectCallbackType Type;
PVOID CallbackEntry;
bool Enabled;
ULONG Flags;
ULONG Operations;
};

Expand Down
47 changes: 23 additions & 24 deletions KernelLibrary/HashTable.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down Expand Up @@ -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;
}

Expand All @@ -113,28 +112,28 @@ 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);
}
}

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;
Expand All @@ -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);
Expand All @@ -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;
}
Expand All @@ -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);

Expand All @@ -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;
}
Expand All @@ -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)
{
Expand Down Expand Up @@ -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;
Expand Down
14 changes: 6 additions & 8 deletions KernelLibrary/HashTable.h
Original file line number Diff line number Diff line change
@@ -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;

Expand All @@ -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);
Expand Down
2 changes: 1 addition & 1 deletion KernelLibrary/KernelLibrary.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@
<Configuration>Debug</Configuration>
<Platform Condition="'$(Platform)' == ''">Win32</Platform>
<RootNamespace>KernelLibrary</RootNamespace>
<WindowsTargetPlatformVersion>$(LatestTargetPlatformVersion)</WindowsTargetPlatformVersion>
<WindowsTargetPlatformVersion>10.0.19041.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
Expand Down
68 changes: 34 additions & 34 deletions KernelLibrary/SysMon.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -551,22 +551,22 @@ 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))
KdPrint(("Protect handle from duplicating\n"));
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;
}
Expand All @@ -575,22 +575,22 @@ 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))
KdPrint(("Protect handle from duplicating\n"));
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;
}
Expand All @@ -599,22 +599,22 @@ 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))
LogInfo("Protect handle from duplicating\n");
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;
}
Expand All @@ -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;
}
Expand All @@ -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;
}
Expand All @@ -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;
}
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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;
}
Loading

0 comments on commit 2d2cb83

Please sign in to comment.