-
-
Notifications
You must be signed in to change notification settings - Fork 18
Expand file tree
/
Copy pathTimerWorks.bat
More file actions
264 lines (180 loc) · 8.74 KB
/
Copy pathTimerWorks.bat
File metadata and controls
264 lines (180 loc) · 8.74 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
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
253
254
255
256
257
258
259
260
261
262
263
264
;@echo off
;goto make
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
;
; TimerWorks - Creates, sets, waits for and cancels the timer.
;
; Written by Four-F (four-f@mail.ru)
;
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
.386
.model flat, stdcall
option casemap:none
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
; I N C L U D E F I L E S
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
include \masm32\include\w2k\ntstatus.inc
include \masm32\include\w2k\ntddk.inc
include \masm32\include\w2k\ntoskrnl.inc
include \masm32\include\w2k\hal.inc
includelib \masm32\lib\w2k\ntoskrnl.lib
includelib \masm32\lib\w2k\hal.lib
include \masm32\Macros\Strings.mac
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
; R E A D O N L Y D A T A
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
.const
CCOUNTED_UNICODE_STRING "\\Device\\TimerWorks", g_usDeviceName, 4
CCOUNTED_UNICODE_STRING "\\DosDevices\\TimerWorks", g_usSymbolicLinkName, 4
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
; U N I N I T I A L I Z E D D A T A
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
.data?
g_pkThread PVOID ? ; PTR KTHREAD
g_fStop BOOL ?
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
; C O D E
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
.code
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
; ThreadProc
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
ThreadProc proc Param:DWORD
local dwCounter:DWORD
local pkThread:PVOID ; PKTHREAD
local status:NTSTATUS
local kTimer:KTIMER
local liDueTime:LARGE_INTEGER
and dwCounter, 0
invoke DbgPrint, $CTA0("\nTimerWorks: Entering ThreadProc\n")
;::::::::::::::::::::::::::::::
; Just for educational purposes
invoke KeGetCurrentIrql
invoke DbgPrint, $CTA0("TimerWorks: IRQL = %d\n"), eax
invoke KeGetCurrentThread
mov pkThread, eax
invoke KeQueryPriorityThread, eax
push eax
invoke DbgPrint, $CTA0("TimerWorks: Thread Priority = %d\n"), eax
pop eax
inc eax
inc eax
invoke KeSetPriorityThread, pkThread, eax
; Bear in mind that threads running in kernel mode with priority in the range
; LOW_REALTIME_PRIORITY-HIGH_PRIORITY are preemptible only by a thread with higher priority.
invoke KeQueryPriorityThread, pkThread
invoke DbgPrint, $CTA0("TimerWorks: Thread Priority = %d\n"), eax
; Just for educational purposes
;::::::::::::::::::::::::::::::
invoke KeInitializeTimerEx, addr kTimer, SynchronizationTimer
; relative time at which the timer expires
; in 100-nanosecond intervalss = 5 secs
or liDueTime.HighPart, -1
mov liDueTime.LowPart, -50000000
; period for the timer in milliseconds = 1 sec
invoke KeSetTimerEx, addr kTimer, liDueTime.LowPart, liDueTime.HighPart, 1000, NULL
invoke DbgPrint, $CTA0("TimerWorks: Timer is set. It starts counting in 5 seconds...\n")
.while dwCounter < 10
invoke KeWaitForSingleObject, addr kTimer, Executive, KernelMode, FALSE, NULL
; Basically we don't need to check status because the only reason
; the wait is satisfied is the timer gets signalled.
inc dwCounter
invoke DbgPrint, $CTA0("TimerWorks: Counter = %d\n"), dwCounter
; If DriverUnload routine called it's time to break the loop
.if g_fStop
invoke DbgPrint, $CTA0("TimerWorks: Stop counting to let the driver to be uloaded\n")
.break
.endif
.endw
invoke KeCancelTimer, addr kTimer
invoke DbgPrint, $CTA0("TimerWorks: Timer is canceled. Leaving ThreadProc\n")
invoke DbgPrint, $CTA0("TimerWorks: Our thread is about to terminate\n")
invoke PsTerminateSystemThread, STATUS_SUCCESS
ret
ThreadProc endp
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
; DriverUnload
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
DriverUnload proc pDriverObject:PDRIVER_OBJECT
invoke DbgPrint, $CTA0("\nTimerWorks: Entering DriverUnload\n")
mov g_fStop, TRUE ; Break the timer loop if it's counting
; We must not unload driver till our system thread is runing
; because ThredProc resides in our driver's body. So we will wait.
; It's not good, btw, because we block one of the system thread.
; Another solution is zero out DRIVER_OBJECT.DriverUnload
; to make the driver unloadable and later restore this field.
invoke DbgPrint, $CTA0("TimerWorks: Wait for thread exits...\n")
invoke KeWaitForSingleObject, g_pkThread, Executive, KernelMode, FALSE, NULL
; Basically we don't need to check status because the only reason
; the wait is satisfied is terminating the thread g_pkThread pointed to.
invoke ObDereferenceObject, g_pkThread
invoke IoDeleteSymbolicLink, addr g_usSymbolicLinkName
mov eax, pDriverObject
invoke IoDeleteDevice, (DRIVER_OBJECT PTR [eax]).DeviceObject
invoke DbgPrint, $CTA0("TimerWorks: Leaving DriverUnload\n")
ret
DriverUnload endp
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
; D I S C A R D A B L E C O D E
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
.code INIT
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
; StartThread
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
StartThread proc
local status:NTSTATUS
local oa:OBJECT_ATTRIBUTES
local hThread:HANDLE
invoke DbgPrint, $CTA0("\nTimerWorks: Entering StartThread\n")
invoke PsCreateSystemThread, addr hThread, THREAD_ALL_ACCESS, NULL, NULL, NULL, ThreadProc, NULL
mov status, eax
.if eax == STATUS_SUCCESS
invoke ObReferenceObjectByHandle, hThread, THREAD_ALL_ACCESS, NULL, KernelMode, addr g_pkThread, NULL
invoke ZwClose, hThread
invoke DbgPrint, $CTA0("TimerWorks: Thread created\n")
.else
invoke DbgPrint, $CTA0("TimerWorks: Can't create Thread. Status: %08X\n"), eax
.endif
invoke DbgPrint, $CTA0("TimerWorks: Leaving StartThread\n")
mov eax, status
ret
StartThread endp
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
; DriverEntry
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
DriverEntry proc pDriverObject:PDRIVER_OBJECT, pusRegistryPath:PUNICODE_STRING
local status:NTSTATUS
local pDeviceObject:PDEVICE_OBJECT
mov status, STATUS_DEVICE_CONFIGURATION_ERROR
invoke IoCreateDevice, pDriverObject, 0, addr g_usDeviceName, FILE_DEVICE_UNKNOWN, 0, TRUE, addr pDeviceObject
.if eax == STATUS_SUCCESS
invoke IoCreateSymbolicLink, addr g_usSymbolicLinkName, addr g_usDeviceName
.if eax == STATUS_SUCCESS
invoke StartThread
.if eax == STATUS_SUCCESS
and g_fStop, FALSE ; reset global flag
mov eax, pDriverObject
mov (DRIVER_OBJECT PTR [eax]).DriverUnload, offset DriverUnload
mov status, STATUS_SUCCESS
.else
invoke IoDeleteSymbolicLink, addr g_usSymbolicLinkName
invoke IoDeleteDevice, pDeviceObject
.endif
.else
invoke IoDeleteDevice, pDeviceObject
.endif
.endif
mov eax, status
ret
DriverEntry endp
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
;
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
end DriverEntry
:make
set drv=TimerWorks
\masm32\bin\ml /nologo /c /coff %drv%.bat
\masm32\bin\link /nologo /driver /base:0x10000 /align:32 /out:%drv%.sys /subsystem:native /ignore:4078 %drv%.obj
del %drv%.obj
echo.
pause