-
Notifications
You must be signed in to change notification settings - Fork 6
/
WoW64Utils.asm
377 lines (333 loc) · 14.9 KB
/
WoW64Utils.asm
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
format COFF
; © Wolk-1024
; v01.10.2016
public x64Call as '_x64Call'
public GetModuleHandle64 as '_GetModuleHandle64'
public GetProcAddress64 as '_GetProcAddress64'
public memcpy64 as '_memcpy64'
public memcmp64 as '_memcmp64'
public memset64 as '_memset64'
public GetTeb64 as '_GetTeb64'
public GetPeb64 as '_GetPeb64'
public IsWoW64 as '_IsWoW64'
include '..\include\win32ax.inc'
macro %IsWoW64
{
xor eax, eax
dec eax
neg eax
}
macro retfq val
{
if ~ val eq
db 0xCA ; retf val
dw val
else
db 0xCB ; retf
end if
}
macro %jmp33 Address
{
use32
if ~ Address eq
jmp far 0x33:Address
else
push 0x33 ; Heavens Gate
call $ + 5
add dword [esp], 5
retf
end if
use64
}
macro %jmp23 Address
{
use64
if ~ Address eq
push 0x23
push Address
retf
else
push 0x23
call $ + 5
add qword [rsp], 7
retf
end if
use32
}
WIN32_SEGMENT = 0x1B
WOW64_SEGMENT = 0x23
WIN64_SEGMENT = 0x33
IMAGE_NT_SIGNATURE = 0x00004550 ; PE
IMAGE_DOS_SIGNATURE = 0x5A4D ; MZ
IMAGE_FILE_MACHINE_AMD64 = 0x8664
;--------------------------------------------------------;
; x64Call ;
;--------------------------------------------------------;
; [in] pfnProc64 - Óêàçàòåëü íà âûçûâàåìóþ ôóíêöèþ. ;
; [in] nArgs - Êîëè÷åñòâî ïåðåäàâàåìûõ ïàðàìåòðîâ. ;
; [in] ... - Ñïèñîê ïàðàìåòðîâ äëÿ ôóíêöèè. ;
; [out] EDX:EAX - Ðåçóëüòàò âûçîâà. ;
;--------------------------------------------------------;
proc x64Call c uses ebx esi edi, pfnProc64:qword, nArgs:dword, ...:dword
%jmp33 ; Ïðûãàåì â 64-áèòíûé ñåãìåíò.
mov ebx, esp ; Ñîõðàíÿåì óêàçàòåëü íà ñòåê.
mov rax, qword [pfnProc64] ; RAX = Âûçûâàåìàÿ ôóíêöèÿ.
mov ecx, dword [nArgs] ; ECX = Êîëè÷åñòâî ïåðåäàâàåìûõ àðãóìåíòîâ.
lea esi, dword [...] ; ESI = Àäðåñ íà÷àëà ñïèñêà àðãóìåíòîâ.
lea edx, [ecx*8] ; EDX = Ðàçìåð ïàðàìåòðîâ.
add edx, 32 ;
and edx, 0xE0 ; Âûðàâíèâàåì ðàçìåð ïàðàìåòðîâ ïî 32 áàéòíîé ãðàíèöå.
and esp, 0xFFFFFFF0 ; Win64 òðåáóåò âûðàâíèâàíèå ñòåêà íà 16 áàéò.
sub esp, edx ; Âûäåëÿåì áóôåð äëÿ ïàðàìåòðîâ.
mov edi, esp ; EDI = Óêàçàòåëü íà áóôåð.
cld ;
repe movsq ; Êîïèðóåì ïàðàìåòðû â áóôåð.
mov rcx, [rsp + 0 * 8] ; 1-é ïàðàìåòð.
mov rdx, [rsp + 1 * 8] ; 2-é
mov r8, [rsp + 2 * 8] ; 3
mov r9, [rsp + 3 * 8] ; 4
movd xmm0, ecx ; Ïàðàìåòðû ñ ïëàâàþùåé çàïÿòîé.
movd xmm1, edx ;
movd xmm2, r8d ;
movd xmm3, r9d ;
call rax ; Âûçûâàåì ôóíêöèþ.
mov esp, ebx ; Âîññòàíàâëèâàåì ñòåê.
mov rdx, rax ;
shr rdx, 32 ;
%jmp23 ;
ret ;
endp
;--------------------------------------------------------;
; GetModuleHandle64 ;
;--------------------------------------------------------;
; [in] ModuleName - Èìÿ èñêîìîé áèáëèîòåêè. ;
; [out] EDX:EAX - Àäðåñ çàãðóçêè èëè 0. ;
;--------------------------------------------------------;
proc GetModuleHandle64 c uses esi edi, ModuleName:dword
%jmp33 ;
mov rax, 0x60 ;
mov rax, qword [gs:rax] ; RAX = PEB64
mov rax, qword [rax+0x18] ; RAX = PEB64->Ldr
mov rax, qword [rax+0x10] ; RAX = PEB64->Ldr.InLoadOrderModuleList.Flink (Ïåðâûé ìîäóëü)
mov rdx, rax ;
cld ;
mov r8d, [ModuleName] ;
test r8d, r8d ;
je .Found ;
.NextModule: ;
movzx rcx, word [rax+0x58] ; RCX = LdrDataTableEntry.BaseDllName.Length
mov rsi, qword [rax+0x60] ; RSI = LdrDataTableEntry.BaseDllName.Buffer
mov edi, r8d ;
shr ecx, 1 ;
repe cmpsw ;
je .Found ;
mov rax, qword [rax] ; RAX = InLoadOrderModuleList[n].Flink (Ñëåäóþùèé ìîäóëü)
cmp rdx, qword [rax] ; Ïðîâåðÿåì íå êîíåö ëè ñïèñêà.
jne .NextModule ;
xor eax, eax ;
jmp .Exit ;
.Found: ;
mov rax, qword [rax+0x30] ; RAX = LdrDataTableEntry.DllBase
.Exit: ;
mov rdx, rax ;
shr rdx, 32 ;
%jmp23 ;
ret ;
endp
;--------------------------------------------------------;
; GetProcAddress64 ;
;--------------------------------------------------------;
; [in] ModuleHandle - Àäðåñ çàãðóçêè áèáëèîòåêè. ;
; [in] ProcedureName - Èìÿ èëè îðäèíàë èñêîìîé ôóíêöèè. ;
; [out] EDX:EAX - Âåðí¸ò 0 èëè àäðåñ. ;
;--------------------------------------------------------;
proc GetProcAddress64 c uses esi edi, ModuleHandle:qword, ProcedureName:dword
%jmp33 ;
mov rdx, qword [ModuleHandle] ;
test rdx, rdx ;
jle .Error ;
cmp word [rdx], 'MZ' ; IMAGE_DOS_SIGNATURE
jne .Error ;
mov eax, dword [rdx+0x3C] ; ImageDosHeader->e_lfanew
add rax, rdx ;
cmp dword [rax], 'PE' ; IMAGE_NT_SIGNATURE
jne .Error ;
cmp word [rax+0x04], 0x8664 ; IMAGE_FILE_MACHINE_AMD64
mov ecx, 0x88 ;
je .Lib64 ;
sub ecx, 0x10 ;
.Lib64: ;
mov r8d, dword [rax+rcx] ; ImageNtHeaders64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress
test r8d, r8d ;
jle .Error ;
add r8, rdx ;
mov r9d, dword [r8+0x20] ; ImageExportDirectory->AddressOfNames (RVA)
add r9, rdx ;
mov ecx, dword [r8+0x18] ; ImageExportDirectory->NumberOfNames
mov r10, rdx ;
mov edx, dword [ProcedureName] ;
test edx, 0xffff0000 ; if (((DWORD)lpProcName & 0xffff0000) == 0)
je .Ordinal ;
cld ;
.NextProc: ;
dec ecx ;
je .Error ;
mov esi, dword [r9+rcx*4] ; char* Name = (char*)(AddressOfNames[IndexName] + hModule);
add rsi, r10 ;
mov edi, edx ; edi = ProcedureName
.Char: ;
lodsb ;
shl eax, 8 ;
xchg rdi, rsi ;
lodsb ;
test ax, ax ; if ((Str1[i] == 0) && (Str2[i] == 0))
je .Found ;
cmp al, ah ;
je .Char ;
jmp .NextProc ;
.Ordinal: ;
mov ecx, dword [r8+0x10] ; ImageExportDirectory->Base
mov eax, dword [r8+0x14] ; ImageExportDirectory->NumberOfFunctions
add eax, ecx ;
cmp edx, eax ; if (Ordinal >= ExportDirectory->Base + ExportDirectory->NumberOfFunctions)
jae .Error ;
cmp edx, ecx ; if (Ordinal < ExportDirectory->Base)
jl .Error ;
xchg ecx, edx ;
sub ecx, edx ; FunctionIndex = Ordinal - ExportDirectory->Base;
jmp @f ;
.Found: ;
mov eax, dword [r8+0x24] ; ImageExportDirectory->AddressOfNameOrdinals (RVA)
add rax, r10 ;
movzx ecx, word [rax+rcx*2] ; FunctionIndex = AddressOfNameOrdinals[IndexName]
@@: ;
mov eax, dword [r8+0x1C] ; ImageExportDirectory->AddressOfFunctions (RVA)
add rax, r10 ;
mov eax, dword [rax+rcx*4] ; AddressOfFunctions[FunctionIndex]
add rax, r10 ;
jmp .Exit ;
.Error: ;
xor eax, eax ;
.Exit: ;
mov rdx, rax ;
shr rdx, 32 ;
%jmp23 ;
ret ;
endp
;--------------------------------------------------------;
; memcpy64 ;
;--------------------------------------------------------;
; [in] Dest - Àäðåñ áóôåðà íàçíà÷åíèÿ. ;
; [in] Src - Àäðåñ èñòî÷íèêà. ;
; [in] Size - Äëèíà äàííûõ. ;
; [out] Íè÷åãî. ;
;--------------------------------------------------------;
proc memcpy64 c uses esi edi, Dest:qword, Src:qword, Size:dword
%jmp33 ;
mov rsi, [Src] ;
mov rdi, [Dest] ;
mov ecx, [Size] ;
test ecx, ecx ;
jle .Exit ;
cld ;
mov edx, ecx ;
shr ecx, 3 ;
repe movsq ;
mov ecx, edx ;
and ecx, 7 ;
repe movsb ;
.Exit: ;
%jmp23 ;
ret ;
endp
;--------------------------------------------------------;
; memcmp64 ;
;--------------------------------------------------------;
; [in] Ptr1 - Óêàçàòåëü íà ïåðâûé áëîê ïàìÿòè. ;
; [in] Ptr2 - Óêàçàòåëü íà âòîðîé áëîê ïàìÿòè. ;
; [in] Size - Äëèíà ñðàâíèâàåìûõ äàííûõ. ;
; [out] EAX - TRUE èëè FALSE ;
;--------------------------------------------------------;
proc memcmp64 c uses esi edi, Ptr1:qword, Ptr2:qword, Size:dword
%jmp33 ;
mov rsi, [Ptr1] ;
mov rdi, [Ptr2] ;
mov ecx, [Size] ;
xor eax, eax ;
test ecx, ecx ;
jle .Exit ;
cld ;
mov edx, ecx ;
shr ecx, 3 ;
repe cmpsq ;
jne .Exit ;
mov ecx, edx ;
and ecx, 7 ;
repe cmpsb ;
sete al ; Åñëè ZF = 1, òî eax = 1
.Exit: ;
%jmp23 ;
ret ;
endp
;--------------------------------------------------------;
; memset64 ;
;--------------------------------------------------------;
; [in] Dest - Óêàçàòåëü íà áëîê ïàìÿòè äëÿ çàïîëíåíèÿ. ;
; [in] Val - Çàïîëíÿþùèé áàéò. ;
; [in] Size - Äëèíà çàïîëíÿåìûõ äàííûõ. ;
; [out] Íè÷åãî. ;
;--------------------------------------------------------;
proc memset64 c uses edi, Dest:qword, Val:byte, Size:dword
%jmp33 ;
mov rdi, [Dest] ;
movzx eax, [Val] ;
mov ecx, [Size] ;
test ecx, ecx ;
jle .Exit ;
mov rdx, 0x101010101010101 ; Ðàñøèðÿåì áàéò-çàïîëíèòåëü äî 64-õ áèòîâ.
imul rax, rdx ;
cld ;
mov edx, ecx ;
shr ecx, 3 ;
rep stosq ;
mov ecx, edx ;
and ecx, 7 ;
rep stosb ;
.Exit: ;
%jmp23 ;
ret ;
endp
;--------------------------------------------------------;
; GetTeb64 ;
;--------------------------------------------------------;
; [out] EDX:EAX - 64-áèòíûé TEB. ;
;--------------------------------------------------------;
proc GetTeb64
mov edx, 0x30 ; TEB64->NtTib.Self
mov eax, dword [gs:edx] ;
mov edx, dword [gs:edx+0x04] ;
ret ;
endp
;--------------------------------------------------------;
; GetPeb64 ;
;--------------------------------------------------------;
; [out] EDX:EAX - 64-áèòíûé PEB. ;
;--------------------------------------------------------;
proc GetPeb64
mov edx, 0x60 ; TEB64->PEB64
mov eax, dword [gs:edx] ;
mov edx, dword [gs:edx+0x04] ;
ret ;
endp
;--------------------------------------------------------;
; IsWoW64 ;
;--------------------------------------------------------;
; [out] EAX - TRUE èëè FALSE ;
;--------------------------------------------------------;
proc IsWoW64
xor eax, eax ;
mov edx, cs ;
cmp edx, 0x23 ; WOW64_SEGMENT
sete al ;
ret ;
endp