-
Notifications
You must be signed in to change notification settings - Fork 25
/
Copy pathdecompiler.py
75 lines (55 loc) · 1.77 KB
/
decompiler.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
import emu
import copy
from op_classes import *
from vm_classes import *
VMI_PREFIX = "VM_"
HANDLER_ID_SIZE = 1
handlers_dict = {}
def emu_decrypt(handler, ctx, vm_code, size):
raw = vm_code.consume(size)
ctx.set_reg(EAX, raw)
proc = handler.decrypt_proc
emu.emulate_list(ctx, proc)
eax = ctx.get_reg(EAX)
return eax
def decompile(main, handlers, vm_code):
for i,h in enumerate(handlers):
handlers_dict[i] = h
ebx = vm_code.vaddr
ctx = Ctx()
ctx.set_reg(EBX, ebx) #ebx is our decryption key
vmis = decompile_(main, ctx, handlers, vm_code)
return vmis
def decompile_(main, ctx, handlers, vm_code):
c = 0
vmis = []
while True:
ebx = ctx.get_reg(EBX)
#print "ebx:", hex(ebx)
id = vm_code.peek(HANDLER_ID_SIZE)
#print "enc id:", hex(id)
vm_code_off = vm_code.offset
next_id = emu_decrypt(main, ctx, vm_code, HANDLER_ID_SIZE)
#0x13 dwords before handlers_tab
next_id = next_id - 0x13
#print "next_id:", hex(next_id)
handler = handlers_dict[next_id]
vmi = handler.vmi
param, param_size = None, None
if handler.takes_esi_params:
param_size = handler.param_size
param = emu_decrypt(handler, ctx, vm_code, param_size)
#print "size:", size, "decrypted param:", hex(param)
if vmi.affects_ctx():
vmi.update_ctx(ctx, vm_code, param)
c += 1
vmi = copy.deepcopy(vmi)
vmi.param = param #we don't know these until decryption
vmi.param_size = param_size
vmi.code_off = vm_code_off
dis = vmi.all_disasm()
print dis
vmis.append(vmi)
if vmi.is_halt():
break
return vmis