-
Notifications
You must be signed in to change notification settings - Fork 4
Expand file tree
/
Copy pathhal.cpp
More file actions
127 lines (106 loc) · 4.44 KB
/
Copy pathhal.cpp
File metadata and controls
127 lines (106 loc) · 4.44 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
#include "stdafx.h"
#include "hal.h"
#include "hook.h"
#include "utility.h"
_HalpCollectPmcCounters OrgHalpCollectPmcCounters = NULL;
PVOID pHalPrivateDispatchTable = NULL;
PVOID pKiSystemServiceRepeat = NULL;
VOID Hooked_HalpCollectPmcCounters(
PVOID* pPmcCounter,
unsigned long long* ullTraceBufferEnd
)
{
//
// Call original PmcCounter
OrgHalpCollectPmcCounters(pPmcCounter, ullTraceBufferEnd);
if (!pPmcCounter || !ullTraceBufferEnd)
return;
//
// Exclude kernel mode execution
if (ExGetPreviousMode() == KernelMode)
return;
if (pKiSystemServiceRepeat == NULL)
return;
//
// Stack walk and check syscall routine exists
PVOID* pKpcrStackBase = (PVOID*)__readgsqword(0x1A8); // KPCR->RSP Base (Maximum stack base)
PVOID* pCurrentStackFrame = (PVOID*)_AddressOfReturnAddress(); // Stack Frame
const ULONG magic1 = 0x501802; // Stack frame magic value
const USHORT magic2 = 0xf33; // Stack frame magic value, also used in performance counter setup which means syscall enter event id
for (; pCurrentStackFrame < pKpcrStackBase; pCurrentStackFrame++)
{
//
// Check magic number is correctly exists in stack frame
PUSHORT usStack = (PUSHORT)pCurrentStackFrame;
if (*usStack != magic2) continue;
pCurrentStackFrame++;
PULONG ulStack = (PULONG)pCurrentStackFrame;
if (*ulStack != magic1) continue;
for (; pCurrentStackFrame < pKpcrStackBase; pCurrentStackFrame++)
{
//
// Check current stack frame is at pKiSystemServiceRepeat
if ((ULONG_PTR)*pCurrentStackFrame >= (ULONG_PTR)PAGE_ALIGN(pKiSystemServiceRepeat)
&& (ULONG_PTR)*pCurrentStackFrame <= (ULONG_PTR)PAGE_ALIGN((ULONG_PTR)pKiSystemServiceRepeat + PAGE_SIZE * 2))
{
//
// Hook userland syscall
CheckSyscall(pCurrentStackFrame);
break;
}
}
break;
}
}
NTSTATUS HookHalpCollectPmcCounters(
_In_ PVOID pNtoskrnlBaseAddress
)
{
//
// Get HalPrivateDispatchTable offset
UNICODE_STRING strHalPrivateDispatchTable = RTL_CONSTANT_STRING(L"HalPrivateDispatchTable");
pHalPrivateDispatchTable = MmGetSystemRoutineAddress(&strHalPrivateDispatchTable);
if (pHalPrivateDispatchTable == NULL)
{
DbgPrintEx(DPFLTR_ACPI_ID, 0, "[-] Failed to find nt!HalPrivateDispatchTable from exports.\n");
return STATUS_NOT_FOUND;
}
DbgPrintEx(DPFLTR_ACPI_ID, 0, "[+] Found nt!HalPrivateDispatchTable: 0x%p\n", pHalPrivateDispatchTable);
//
// Check HalpCollectPmcCounters offset
memcpy_s(&OrgHalpCollectPmcCounters, sizeof(PVOID), (PVOID)((ULONG_PTR)pHalPrivateDispatchTable + HALP_COLLECT_PMC_COUNTERS_OFFSET), sizeof(PVOID));
if (!MmIsAddressValid(OrgHalpCollectPmcCounters))
{
DbgPrintEx(DPFLTR_ACPI_ID, 0, "[-] Failed to get nt!HalPrivateDispatchTable->HalpCollectPmcCounters offset.\n");
return STATUS_INVALID_ADDRESS;
}
//
// Check if HalpCollectPmcCounters has already hooked by another driver
LPWSTR wsDriverName = GetNearestDriverNameFromOffset(OrgHalpCollectPmcCounters);
if (wsDriverName == NULL)
{
DbgPrintEx(DPFLTR_ACPI_ID, 0, "[-] Unknown offset found at nt!HalPrivateDispatchTable->HalpCollectPmcCounters(): 0x%p\n", OrgHalpCollectPmcCounters);
return STATUS_NOT_FOUND;
}
else if (wcscmp(L"ntoskrnl.exe", wsDriverName) != 0)
{
DbgPrintEx(DPFLTR_ACPI_ID, 0, "[-] HalPrivateDispatchTable->HalpCollectPmcCounters has already hooked by another driver: %ws\n", wsDriverName);
return STATUS_RESOURCE_IN_USE;
}
DbgPrintEx(DPFLTR_ACPI_ID, 0, "[+] Found nt!HalPrivateDispatchTable->HalpCollectPmcCounters: 0x%p)\n", OrgHalpCollectPmcCounters);
//
// Get KiSystemServiceRepeat offset to determine stack frame position
pKiSystemServiceRepeat = (PVOID)((ULONG_PTR)pNtoskrnlBaseAddress + KI_SYSTEM_SERVICE_REPEAT_OFFSET);
DbgPrintEx(DPFLTR_ACPI_ID, 0, "[+] Found nt!KiSystemServiceRepeat(): 0x%p\n", pKiSystemServiceRepeat);
//
// All primitives are done, Hook HalpCollectPmcConuter by changing pointer
PVOID pHookAddress = (PVOID)Hooked_HalpCollectPmcCounters;
memcpy_s((PVOID)((ULONG_PTR)pHalPrivateDispatchTable + HALP_COLLECT_PMC_COUNTERS_OFFSET), sizeof(PVOID), &pHookAddress, sizeof(PVOID));
DbgPrintEx(DPFLTR_ACPI_ID, 0, "[+] Setting up hooking at nt!HalPrivateDispatchTable->HalpCollectPmcCounters is now complete.\n");
return STATUS_SUCCESS;
}
VOID UnhookHalpCollectPmcCounters()
{
memcpy_s((PVOID)((ULONG_PTR)pHalPrivateDispatchTable + HALP_COLLECT_PMC_COUNTERS_OFFSET), sizeof(PVOID), &OrgHalpCollectPmcCounters, sizeof(PVOID));
DbgPrintEx(DPFLTR_ACPI_ID, 0, "[-] Restoring function pointer at nt!HalPrivateDispatchTable->HalpCollectPmcCounters.\n");
}