-
Notifications
You must be signed in to change notification settings - Fork 4
/
driver.cpp
252 lines (196 loc) · 4.46 KB
/
driver.cpp
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
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
#include <ntddk.h>
#define DEVICE_RK 0x00008001
#define MSR_EIP 0x176
#define nCPUs 32
#define PRNTFREQ 1000
typedef struct _MSR
{
DWORD32 loaddr;
DWORD32 highaddr;
}
MSR, *PMSR;
DWORD32 ogMSRval = 0;
DWORD32 currentindex = 0;
const WCHAR *devicepath = L "\\Device\\HookRK";
const WCHAR *linkdevicepath = L "\\DosDevices\\HookRK";
PDEVICE_OBJECT devobj;
NTSTATUS default_dispatch(PDRIVER_OBJECT pobj, PIRP pirp)
{
UNREFERENCED_PARAMETER(pobj);
pirp->IoStatus.Status = STATUS_SUCCESS;
pirp->IoStatus.Information = 0;
IoCompleteRequest(pirp, IO_NO_INCREMENT);
return STATUS_SUCCESS;
}
NTSTATUS RegisterDriverDeviceName(PDRIVER_OBJECT pobj)
{
NTSTATUS ntstatus;
UNICODE_STRING unistring;
RtlInitUnicodeString(&unistring, devicepath);
ntstatus = IoCreateDevice(
pobj,
0,
&unistring,
DEVICE_RK,
0,
TRUE,
&devobj
);
return ntstatus;
}
NTSTATUS RegisterDriverDeviceLink(void)
{
NTSTATUS ntstatus;
UNICODE_STRING deviceunistring;
UNICODE_STRING devicelinkunistring;
RtlInitUnicodeString(&deviceunistring, devicepath);
RtlInitUnicodeString(&devicelinkunistring, linkdevicepath);
ntstatus = IoCreateSymbolicLink(
&devicelinkunistring,
&deviceunistring
);
return ntstatus;
}
void prnthookmsg(DWORD32 dispatchid, DWORD32 stackPtr)
{
if (currentindex == PRNTFREQ)
{
DbgPrint("[PRNTHOOKMSG]: on CPU[%u], (pid=%u, dispatchID=%x), Addr of stack = 0x%x \n",
KeGetCurrentProcessorNumber(), PsGetCurrentProcessId(), dispatchid, &stackPtr);
currentindex = 0;
}
currentindex++;
}
void __declspec(naked) newMSR(void)
{
__asm
{
pushad;
pushfd;
nop;
mov ecx, 0x23;
push 0x30;
pop fs;
mov ds, cx;
mov es, cx;
push edx;
push eax;
call prnthookmsg;
popfd;
popad;
jmp[ogMSRval];
}
}
void read_msr(DWORD32 regnumber, PMSR msr)
{
DWORD32 lowval;
DWORD32 hival;
__asm
{
mov ecx, regnumber;
rdmsr;
mov hival, edx;
mov lowval, eax;
}
msr->highaddr = hival;
msr->loaddr = lowval;
return;
}
void set_msr(DWORD32 regnumber, PMSR msr)
{
DWORD32 lowval;
DWORD32 hival;
hival = msr->highaddr;
lowval = msr->loaddr;
__asm
{
mov ecx, regnumber;
mov edx, hival;
mov eax, lowval;
wrmsr;
}
return;
}
DWORD32 HookCPU(DWORD32 procaddr)
{
PMSR oldmsr = NULL;
PMSR newmsr = NULL;
read_msr(MSR_EIP, oldmsr);
newmsr->loaddr = oldmsr->loaddr;
newmsr->highaddr = newmsr->highaddr;
newmsr->loaddr = procaddr;
set_msr(MSR_EIP, newmsr);
return oldmsr->loaddr;
}
void HookAllCPUs(DWORD32 procaddr)
{
KAFFINITY threadaffinity;
KAFFINITY currentCPU;
threadaffinity = KeQueryActiveProcessors();
for (DWORD32 i = 0; i < nCPUs; i++)
{
currentCPU = threadaffinity &(1 << i);
if (currentCPU != 0)
{
KeSetSystemAffinityThread(threadaffinity);
if (ogMSRval == 0)
{
ogMSRval = HookCPU(procaddr);
}
else
{
HookCPU(procaddr);
}
}
}
KeSetSystemAffinityThread(threadaffinity);
PsTerminateSystemThread(STATUS_SUCCESS);
return;
}
void HookSysEnter(DWORD32 ProcessAddr)
{
HANDLE hthread;
OBJECT_ATTRIBUTES objattributes;
PKTHREAD pkthreadobj = NULL;
LARGE_INTEGER timer;
InitializeObjectAttributes(&objattributes, NULL, 0, NULL, NULL);
PsCreateSystemThread(&hthread, THREAD_ALL_ACCESS, &objattributes, NULL, NULL, (PKSTART_ROUTINE) HookAllCPUs, (PVOID) ProcessAddr);
ObReferenceObjectByHandle(hthread, THREAD_ALL_ACCESS, NULL, KernelMode, (PVOID*) pkthreadobj, NULL);
timer.QuadPart = 300;
while (KeWaitForSingleObject((PVOID) pkthreadobj, Executive, KernelMode, FALSE, &timer) != STATUS_SUCCESS)
{
}
ZwClose(hthread);
return;
}
void unloadDriver(PDRIVER_OBJECT pobj)
{
PDEVICE_OBJECT pdevobj;
UNICODE_STRING unistring;
pdevobj = pobj->DeviceObject;
RtlInitUnicodeString(&unistring, linkdevicepath);
IoDeleteSymbolicLink(&unistring);
RtlInitUnicodeString(&unistring, linkdevicepath);
IoDeleteDevice(pdevobj);
return;
}
extern "C" NTSTATUS DriverEntry(IN PDRIVER_OBJECT pDriverObject, IN PUNICODE_STRING regpath)
{
UNREFERENCED_PARAMETER(regpath);
DbgPrint("Entering The Device Driver Main Fcn\n");
int i;
NTSTATUS ntstatus;
for (i = 0; i < IRP_MJ_MAXIMUM_FUNCTION; i++)
{
pDriverObject->MajorFunction[i] = (PDRIVER_DISPATCH) default_dispatch;
}
pDriverObject->DriverUnload = unloadDriver;
ntstatus = RegisterDriverDeviceName(pDriverObject);
if (!NT_SUCCESS(ntstatus))
return ntstatus;
ntstatus = RegisterDriverDeviceLink();
if (!NT_SUCCESS(ntstatus))
return ntstatus;
HookSysEnter((DWORD32) prnthookmsg);
return STATUS_SUCCESS;
}