FAQ для раздела Assembler, MASM, TASM - Assembler - Ответ 5366447
21.11.2013, 10:26. Показов 143643. Ответов 65
Ответ
Тема на одном из форумов натолкнула меня на написание драйвера, позволяющего установить глобальный хук на всё время работы системы до перезагрузки. В данном случае будет изменена функция MessageBoxA из библиотеки user32.dll. Это пример для Windows x32, но и на х64 можно сделать подобное. Требуется только цифровая подпись драйвера.
Assembler | 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
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
| UNICODE__STRING struct
Length_ dw ?
MaxLength dw ?
Buffer dd ?
UNICODE__STRING ends
unis macro name,string
local s,e
len sizestr <string>
align 4
sstr substr <string>,2,len-2
s label word
% forc n,<sstr>
dw '&n'
endm
e dw 0
align 4
k=(e-s)
name UNICODE__STRING {k,k+2,s}
endm
.686P
.model flat,stdcall
option casemap:none
include \masm32\include\ntstatus.inc
include \masm32\include\ntddk.inc
include \masm32\include\ntoskrnl.inc
include \masm32\include\native.inc
includelib \masm32\lib\ntoskrnl.lib
include \masm32\macros\strings.mac
include \masm32\macros\du.mac
.const
function db 'MessageBoxA',0
unis ndirectory,'\KnownDlls'
unis ndll,'user32.dll'
fin dd fin_
.code
assume fs:nothing
DriverUnload proc uses ebx edi esi pdrobject:dword
invoke DbgPrint,$CTA0("UNLOADING")
mov eax,STATUS_SUCCESS
ret
DriverUnload endp
; -------------------------------------------------------------------------
.code; INIT
driver_entry proc uses ebx edi esi pdrobject:dword,pregpath:dword
local oa:OBJECT_ATTRIBUTES
local iob:IO_STATUS_BLOCK
local li:LARGE_INTEGER
local hdll,pmem,hdir,hsec,cbytes:dword
local pspace:dword
and pmem,0
and li.LowPart,0
and li.HighPart,0
invoke RtlZeroMemory,addr oa,sizeof oa
mov oa._Length,sizeof oa
lea eax,ndirectory
mov oa.ObjectName,eax
mov oa.Attributes,OBJ_KERNEL_HANDLE
invoke ZwOpenDirectoryObject,addr hdir,0fh,addr oa ; получаем описатель директории \KnownDlls
test eax,eax
js @1
invoke DbgPrint,$CTA0("Handle directory 0x%X"),hdir
push hdir
pop oa.RootDirectory
lea eax,ndll
mov oa.ObjectName,eax
invoke ZwOpenSection,addr hsec,SECTION_ALL_ACCESS,addr oa ; открываем секцию user32.dll
test eax,eax
js @f
invoke NtClose,hdir
invoke DbgPrint,$CTA0("Handle section 0x%x"),hsec
; отображаем в адресное пространство своего процесса
invoke ZwMapViewOfSection,hsec,-1,addr pmem,0,li.LowPart,0,addr li,1,0,PAGE_EXECUTE_READWRITE
test eax,eax
js @f
push pmem
call get_address
test eax,eax
js @f
mov ebx,eax
push pmem
call get_space
mov pspace,eax
mov eax,(get_space-my_messagebox)
cmp ecx,eax
ja @ok
invoke DbgPrint,$CTA0("Free space is too small, fail...")
jmp @un
@ok:
try
cli
mov eax,cr0 ; сбрасываем бит WP в регистре CR0, тем самым разрешая запись
and eax,0fffeffffh ; на readonly страницы
mov cr0,eax
sti
mov eax,[ebx] ; несмотря на то, что запись разрешена, попытка записи без предварительного
mov byte ptr [ebx],0e8h ;чтения приведёт к краху
mov eax,pspace ; правим функцию MessageBoxA
sub eax,5
sub eax,ebx
mov [ebx+1],eax
mov edi,pspace
mov eax,[edi]
mov ecx,(get_space-my_messagebox)
mov esi,offset my_messagebox
rep movsb ; теперь до перезагрузки системы любой диалог, выданный функцией MessageBoxA
; будет иметь загловок и текст "Hook!"
cli
mov eax,cr0
or eax,10000h
mov cr0,eax
sti
invoke DbgPrint,$CTA0("MessageBox address 0x%X"),ebx
fin_::
finally
@un:
invoke ZwUnmapViewOfSection,-1,pmem ; закрываем проекцию секции, при этом в ней сохранятся
; все сделанные изменения.
@@:
invoke NtClose,hsec
@1:
invoke DbgPrint,$CTA0("Last Error 0x%X"),eax
mov eax,pdrobject
mov (DRIVER_OBJECT ptr [eax]).DriverUnload,offset DriverUnload
mov eax,STATUS_SUCCESS
ret
driver_entry endp
except fin
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
my_messagebox proc
call @f
@@:
pop eax
sub eax,offset @b
add eax,offset message
mov [esp+10h],eax
mov [esp+0ch],eax
mov eax,[esp]
add esp,4
push ebp
mov ebp,esp
jmp eax
message db 'Hook!',0
my_messagebox endp
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
get_space proc uses ebx edi esi psection
mov ebx,psection
push ebx
add ebx,(IMAGE_DOS_HEADER ptr [ebx]).e_lfanew
movzx esi,(IMAGE_NT_HEADERS ptr [ebx]).FileHeader.SizeOfOptionalHeader
movzx ecx,(IMAGE_NT_HEADERS ptr [ebx]).FileHeader.NumberOfSections
add esi,ebx
lea esi,[esi+sizeof IMAGE_FILE_HEADER+4]
mov edi,(IMAGE_NT_HEADERS ptr [ebx]).OptionalHeader.SizeOfCode
mov ebx,(IMAGE_NT_HEADERS ptr [ebx]).OptionalHeader.BaseOfCode
pop eax
add ebx,eax
invoke DbgPrint,$CTA0("ImageBase 0x%X, Base of Code 0x%X"),psection,ebx
@@:
cmp edi,(IMAGE_SECTION_HEADER ptr [esi]).SizeOfRawData
je @f
add esi,sizeof IMAGE_SECTION_HEADER
loop @b
xor eax,eax
jmp @ret
@@:
mov esi,(IMAGE_SECTION_HEADER ptr [esi]).Misc.VirtualSize
sub edi,esi
add ebx,esi
invoke DbgPrint,$CTA0("Base of space 0x%X, Size 0x%X"),ebx,edi
mov eax,ebx
mov ecx,edi
@ret:
ret
get_space endp
; -------------------------------------------------------------------------
get_address proc uses ebx edi esi psection
mov eax,psection
mov ebx,eax
add ebx,(IMAGE_DOS_HEADER ptr [eax]).e_lfanew
lea ebx,(IMAGE_NT_HEADERS ptr [ebx]).OptionalHeader
mov ebx,(IMAGE_OPTIONAL_HEADER ptr [ebx]).DataDirectory.VirtualAddress
add ebx,eax
lea esi,function
mov edi,(IMAGE_EXPORT_DIRECTORY ptr [ebx]).AddressOfNames
push ebx
mov ebx,(IMAGE_EXPORT_DIRECTORY ptr [ebx]).NumberOfNames
lea edi,[edi+eax-4]
mov edx,-1
@@:
add edi,4
push edi
mov edi,[edi]
add edi,eax
inc edx
push esi
mov ecx,sizeof function-1
repe cmpsb
pop esi
pop edi
je @f
dec ebx
jne @b
pop ebx
mov eax,-1
jmp @ret
@@:
pop ebx
mov esi,(IMAGE_EXPORT_DIRECTORY ptr [ebx]).AddressOfNameOrdinals
shl edx,1
add edx,esi
add edx,eax
movzx edx,word ptr [edx]
mov ebx,(IMAGE_EXPORT_DIRECTORY ptr [ebx]).AddressOfFunctions
add ebx,eax
shl edx,2
add edx,ebx
mov edx,[edx]
add eax,edx
@ret:
ret
get_address endp
end driver_entry |
|
Коды драйверов под х32 и х64, позволяющие найти адрес неэкспортируемой ядром функции, в данных примерах это ZwProtectVirtualMemory. Сначала в библиотеке ntdll.dll находится номер соответствующего системного сервиса, затем, от адреса экспортируемой функции ядра по определённому смещению, фиксированному как в х32, так и в х64 системах проверяются номера системных сервисов до совпадения с требуемым. Имя функции, адрес которой взят за точку отсчёта, определено в дизассембелере. Источник вдохновения - та же тема на том же форуме, название которого здесь нельзя привести.
Кликните здесь для просмотра всего текста
Assembler | 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
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
| .686P
.model flat,stdcall
option casemap:none
include \masm32\include\ntstatus.inc
include \masm32\include\ntddk.inc
include \masm32\include\ntoskrnl.inc
include \masm32\include\native.inc
includelib \masm32\lib\ntoskrnl.lib
include \masm32\macros\strings.mac
include \masm32\macros\du.mac
.const
nfunction db 'ZwProtectVirtualMemory',0
unis function,'ZwPulseEvent'
unis nfile,'\SystemRoot\system32\ntdll.dll'
.code
assume fs:nothing
DriverUnload proc uses ebx edi esi pdrobject:dword
invoke DbgPrint,$CTA0("UNLOADING")
mov eax,STATUS_SUCCESS
ret
DriverUnload endp
; -------------------------------------------------------------------------
.code; INIT
driver_entry proc uses ebx edi esi pdrobject:dword,pregpath:dword
local oa:OBJECT_ATTRIBUTES
local iob:IO_STATUS_BLOCK
local li:LARGE_INTEGER
local hfile,pmem,hdo,hsec:dword
and pmem,0
and li.LowPart,0
and li.HighPart,0
invoke RtlZeroMemory,addr oa,sizeof oa
mov oa._Length,sizeof oa
lea eax,nfile
mov oa.ObjectName,eax
mov oa.Attributes,OBJ_KERNEL_HANDLE
invoke ZwCreateFile,addr hfile,FILE_READ_DATA+FILE_EXECUTE,addr oa,addr iob,0,0,FILE_SHARE_READ,FILE_OPEN,0,0,0
test eax,eax
js @1
invoke DbgPrint,$CTA0("Handle file 0x%X"),hfile
mov oa.ObjectName,0
invoke ZwCreateSection,addr hsec,SECTION_MAP_EXECUTE+SECTION_MAP_READ,addr oa,0,PAGE_EXECUTE_READ,SEC_IMAGE,hfile
push eax
invoke NtClose,hfile
pop eax
test eax,eax
js @1
invoke DbgPrint,$CTA0("Handle section 0x%x"),hsec
invoke ZwMapViewOfSection,hsec,-1,addr pmem,0,li.LowPart,0,addr li,1,0,PAGE_EXECUTE_READ
test eax,eax
js @f
push pmem
call get_service_number
test eax,eax
js @f
mov ebx,[eax]
mov eax,ebx
shr eax,8
invoke DbgPrint,$CTA0("Service number 0x%X"),eax
invoke ZwUnmapViewOfSection,-1,pmem
call search
test eax,eax
jz @1
invoke DbgPrint,$CTA0("Kernel address 0x%X"),eax
@@:
invoke NtClose,hsec
@1:
invoke DbgPrint,$CTA0("Last Error 0x%X"),eax
mov eax,pdrobject
mov (DRIVER_OBJECT ptr [eax]).DriverUnload,offset DriverUnload
mov eax,STATUS_SUCCESS
ret
driver_entry endp
; -------------------------------------------------------------------------
search proc uses ebx edi esi
local psearch:dword
invoke MmGetSystemRoutineAddress,addr function
test eax,eax
js @r
mov psearch,eax
mov esi,eax
mov edx,14h
mov edi,2
@1:
mov ecx,30
@@:
mov eax,[esi]
cmp eax,ebx
je @f
add esi,edx
loop @b
mov esi,psearch
neg edx
dec edi
jnz @1
xor eax,eax
jmp @r
@@:
mov eax,esi
@r:
ret
search endp
; -------------------------------------------------------------------------
get_service_number proc uses ebx edi esi psection
mov eax,psection
mov ebx,eax
add ebx,(IMAGE_DOS_HEADER ptr [eax]).e_lfanew
lea ebx,(IMAGE_NT_HEADERS ptr [ebx]).OptionalHeader
mov ebx,(IMAGE_OPTIONAL_HEADER ptr [ebx]).DataDirectory.VirtualAddress
add ebx,eax
lea esi,nfunction
mov edi,(IMAGE_EXPORT_DIRECTORY ptr [ebx]).AddressOfNames
push ebx
mov ebx,(IMAGE_EXPORT_DIRECTORY ptr [ebx]).NumberOfNames
lea edi,[edi+eax-4]
mov edx,-1
@@:
add edi,4
push edi
mov edi,[edi]
add edi,eax
inc edx
push esi
mov ecx,sizeof nfunction-1
repe cmpsb
pop esi
pop edi
je @f
dec ebx
jne @b
pop ebx
mov eax,-1
jmp @ret
@@:
pop ebx
mov esi,(IMAGE_EXPORT_DIRECTORY ptr [ebx]).AddressOfNameOrdinals
shl edx,1
add edx,esi
add edx,eax
movzx edx,word ptr [edx]
mov ebx,(IMAGE_EXPORT_DIRECTORY ptr [ebx]).AddressOfFunctions
add ebx,eax
shl edx,2
add edx,ebx
mov edx,[edx]
add eax,edx
@ret:
ret
get_service_number endp
end driver_entry
;x64
include f:\masm32\include64\win64.inc
include f:\masm32\include64\ntddk.inc
include f:\masm32\macros\strings.mac
include f:\masm32\include64\ntdef.inc
include f:\masm32\include64\ntstatus.inc
include f:\masm32\include64\rtl.inc
includelib f:\masm32\lib64\ntoskrnl.lib
include f:\masm32\macros\x64.mac
extrn DbgPrint:proc
extrn RtlZeroMemory:proc
extrn ZwCreateFile:proc
extrn ZwCreateSection:proc
extrn ZwMapViewOfSection:proc
extrn ZwUnmapViewOfSection:proc
extrn NtClose:proc
extrn MmGetSystemRoutineAddress:proc
.const
nfunction db 'ZwProtectVirtualMemory',0
unis function,'ZwQuerySection'
unis nfile,'\SystemRoot\system32\ntdll.dll'
.code
DriverUnload proc uses rbx rdi pdrobject:qword
mov pdrobject,rcx
invoke DbgPrint,$CTA0("Unload")
mov rax,STATUS_SUCCESS
ret
DriverUnload endp
; -------------------------------------------------------------------------
.code
driver_entry proc uses rbx rdi rsi pdrobject:qword,pregpath:qword
local oa:OBJECT_ATTRIBUTES
local iob:IO_STATUS_BLOCK
local li:LARGE_INTEGER
local hfile:qword
local hsec:qword
local hdo:qword
local pmem:qword
mov pdrobject,rcx
mov pregpath,rdx
and pmem,0
and li.LowPart,0
and li.HighPart,0
invoke RtlZeroMemory,addr oa,sizeof oa
mov oa._Length,sizeof oa
lea rax,nfile
mov oa.ObjectName,rax
mov oa.Attributes,OBJ_KERNEL_HANDLE
invoke ZwCreateFile,addr hfile,FILE_READ_DATA+FILE_EXECUTE,addr oa,addr iob,0,0,FILE_SHARE_READ,FILE_OPEN,0,0,0
test eax,eax
js @1
invoke DbgPrint,$CTA0("Handle file 0x%X"),hfile
mov oa.ObjectName,0
invoke ZwCreateSection,addr hsec,SECTION_MAP_EXECUTE+SECTION_MAP_READ,addr oa,0,PAGE_EXECUTE_READ,SEC_IMAGE,hfile
push rax
invoke NtClose,hfile
pop rax
test eax,eax
js @1
invoke DbgPrint,$CTA0("Handle section 0x%x"),hsec
invoke ZwMapViewOfSection,hsec,-1,addr pmem,0,li.QuadPart,0,addr li,1,0,PAGE_EXECUTE_READ
test eax,eax
js @f
invoke DbgPrint,$CTA0("Memory address 0x%X"),pmem
mov rcx,pmem
sub rsp,20h
call get_service_number
add rsp,20h
test eax,eax
js @f
add eax,3
mov ebx,[eax]
mov eax,ebx
shr eax,8
invoke DbgPrint,$CTA0("Service number 0x%X"),rax
invoke ZwUnmapViewOfSection,-1,pmem
sub rsp,20h
call search
add rsp,20h
test eax,eax
jz @1
mov rbx,rax
shr rax,32
invoke DbgPrint,$CTA0("ZwProtectVirtualMemory address 0x%X%X"),rax,rbx
@@:
invoke NtClose,hsec
@1:
invoke DbgPrint,$CTA0("Last Error 0x%X"),rax
mov rax,pdrobject
lea rcx,DriverUnload
mov (DRIVER_OBJECT ptr [rax]).DriverUnload,rcx
mov rax,STATUS_SUCCESS
ret
driver_entry endp
; -------------------------------------------------------------------------
search proc uses rbx rdi rsi
local psearch:qword
invoke MmGetSystemRoutineAddress,addr function
test eax,eax
jz @r
push rax
mov rcx,rax
shr rax,32
invoke DbgPrint,$CTA0("ZwQuerySection address 0x%X%X"),rax,rcx
pop rax
add rax,14h
mov psearch,rax
mov rsi,rax
mov rdx,20h
mov rdi,2
@1:
mov rcx,50
@@:
mov rax,[rsi]
cmp ax,bx
je @f
add rsi,rdx
loop @b
mov rsi,psearch
neg rdx
dec rdi
jnz @1
xor eax,eax
jmp @r
@@:
mov rax,rsi
sub rax,14h
@r:
ret
search endp
; -------------------------------------------------------------------------
get_service_number proc uses rbx rdi rsi psection:qword
mov psection,rcx
mov rax,rcx
mov rbx,rax
and rdi,0
add ebx,(IMAGE_DOS_HEADER ptr [rax]).e_lfanew
lea rbx,(IMAGE_NT_HEADERS ptr [ebx]).OptionalHeader
mov ebx,(IMAGE_OPTIONAL_HEADER ptr [rbx]).DataDirectory.VirtualAddress
add ebx,eax
lea rsi,nfunction
mov edi,(IMAGE_EXPORT_DIRECTORY ptr [ebx]).AddressOfNames
push rbx
and rbx,0ffffffffh
mov ebx,(IMAGE_EXPORT_DIRECTORY ptr [ebx]).NumberOfNames
lea edi,[edi+eax-4]
mov rdx,-1
@@:
add rdi,4
push rdi
mov edi,[rdi]
add edi,eax
inc edx
push rsi
mov ecx,sizeof nfunction-1
repe cmpsb
pop rsi
pop rdi
je @f
dec ebx
jne @b
pop rbx
mov eax,-1
jmp @ret
@@:
pop rbx
mov esi,(IMAGE_EXPORT_DIRECTORY ptr [ebx]).AddressOfNameOrdinals
shl rdx,1
add edx,esi
add edx,eax
movzx edx,word ptr [edx]
mov ebx,(IMAGE_EXPORT_DIRECTORY ptr [ebx]).AddressOfFunctions
add ebx,eax
shl edx,2
add edx,ebx
mov rdx,[edx]
add eax,edx
@ret:
ret
get_service_number endp
end |
|
Макрос unis для х64.
Assembler | 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
| UNICODE__STRING struct
Length_ dw ?
MaxLength dw ?
Reserve dd 0
Buffer dq ?
UNICODE__STRING ends
unis macro name,string
local s,e
len sizestr <string>
align 4
sstr substr <string>,2,len-2
s label word
% forc n,<sstr>
dw '&n'
endm
e dw 0
align 8
k=(e-s)
name UNICODE__STRING {k,k+2,0,s}
endm |
|
Вернуться к обсуждению: FAQ для раздела Assembler, MASM, TASM Assembler
4
|