-
Notifications
You must be signed in to change notification settings - Fork 1k
/
disassembly_utils.py
84 lines (67 loc) · 2.27 KB
/
disassembly_utils.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
import capstone as cs
import logging
from ..misc.ux import once
l = logging.getLogger(name=__name__)
INS_GROUP_INFO = {
'X86': {
cs.x86.X86_GRP_CALL: 'call',
cs.x86.X86_GRP_JUMP: 'branch',
cs.x86.X86_GRP_RET: 'return',
},
'AMD64': {
cs.x86.X86_GRP_CALL: 'call',
cs.x86.X86_GRP_JUMP: 'branch',
cs.x86.X86_GRP_RET: 'return',
},
}
try:
INS_GROUP_INFO['MIPS32'] = {
cs.mips.MIPS_GRP_CALL: 'call',
cs.mips.MIPS_GRP_JUMP: 'branch',
cs.mips.MIPS_GRP_RET: 'return',
}
except AttributeError:
# The installed capstone is too old - it does not support cs.mips.MIPS_GRP_*
pass
INS_INFO = {
'MIPS32': {
cs.mips.MIPS_INS_JAL: 'call',
cs.mips.MIPS_INS_BAL: 'branch',
}
}
def decode_instruction(arch, instr):
# this is clearly architecture specific
arch_name = arch.name
if arch_name == 'MIPS32' and once('mips-instruction-groups'):
l.warning('Your version of capstone does not support MIPS instruction groups.')
insn_info = None
info = INS_GROUP_INFO.get(arch_name, None)
if info is not None:
for group in instr.insn.insn.groups:
insn_info = info.get(group, None)
if insn_info is not None:
break
if insn_info is None:
info = INS_INFO.get(arch_name, None)
if info is not None:
insn_info = info.get(instr.insn.insn.id, None)
if insn_info is None:
return
instr.type = insn_info
if instr.type in ('call', 'branch'):
# determine if this is a direct or indirect call/branch
if arch_name in ('X86', 'AMD64'):
last_operand = instr.insn.operands[-1]
if last_operand.type == cs.x86.X86_OP_IMM:
instr.branch_type = 'direct'
else:
instr.branch_type = 'indirect'
instr.branch_target_operand = len(instr.insn.operands) - 1
elif arch_name == 'MIPS32':
# check the last operand
last_operand = instr.insn.operands[-1]
if last_operand.type == cs.mips.MIPS_OP_REG:
instr.branch_type = 'indirect'
else:
instr.branch_type = 'direct'
instr.branch_target_operand = len(instr.insn.operands) - 1