-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathmsp430.py
101 lines (79 loc) · 3.07 KB
/
msp430.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
from binaryninja import (
Architecture,
BranchType,
FlagRole,
InstructionInfo,
LowLevelILFlagCondition,
RegisterInfo,
)
from .instructions import TYPE3_INSTRUCTIONS, Instruction, Registers
from .lifter import Lifter
class MSP430(Architecture):
name = "msp430"
address_size = 2
default_int_size = 2
global_regs = ["sr"]
stack_pointer = "sp"
regs = {r: RegisterInfo(r, 2) for r in Registers}
flags = ["v", "n", "c", "z"]
# The first flag write type is ignored currently.
# See: https://github.com/Vector35/binaryninja-api/issues/513
flag_write_types = ["", "*", "cnv", "cnz"]
flags_written_by_flag_write_type = {
"*": ["v", "n", "c", "z"],
"cnv": ["v", "n", "c"],
"cnz": ["c", "n", "z"],
}
flag_roles = {
"c": FlagRole.CarryFlagRole,
"n": FlagRole.NegativeSignFlagRole,
"z": FlagRole.ZeroFlagRole,
"v": FlagRole.OverflowFlagRole,
}
flags_required_for_flag_condition = {
LowLevelILFlagCondition.LLFC_UGE: ['c'],
LowLevelILFlagCondition.LLFC_UGT: ['c'],
LowLevelILFlagCondition.LLFC_ULT: ['c'],
LowLevelILFlagCondition.LLFC_ULE: ['c'],
LowLevelILFlagCondition.LLFC_SGE: ['n', 'v'],
LowLevelILFlagCondition.LLFC_SLT: ['n', 'v'],
LowLevelILFlagCondition.LLFC_E: ['z'],
LowLevelILFlagCondition.LLFC_NE: ['z'],
LowLevelILFlagCondition.LLFC_NEG: ['n'],
LowLevelILFlagCondition.LLFC_POS: ['n']
}
def get_instruction_info(self, data, addr):
instr = Instruction.decode(data, addr)
if instr is None:
return None
result = InstructionInfo()
result.length = instr.length
# Add branches
if instr.mnemonic in ["ret", "reti"]:
result.add_branch(BranchType.FunctionReturn)
elif instr.mnemonic in ["jmp", "br"] and instr.src.value is not None:
result.add_branch(BranchType.UnconditionalBranch, instr.src.value)
elif instr.type == 3:
result.add_branch(BranchType.TrueBranch, instr.src.value)
result.add_branch(BranchType.FalseBranch, addr + 2)
elif instr.mnemonic == "call" and instr.src.value is not None:
result.add_branch(BranchType.CallDestination, instr.src.value)
return result
def get_instruction_text(self, data, addr):
instr = Instruction.decode(data, addr)
if instr is None:
return None
tokens = instr.generate_tokens()
return tokens, instr.length
def get_instruction_low_level_il(self, data, addr, il):
instr = Instruction.decode(data, addr)
if instr is None:
return None
# Halting the system means turning off interrupts and just looping
# indefinitely
if instr.mnemonic == "dint":
next_instr = Instruction.decode(data[instr.length :], addr + instr.length)
if next_instr.mnemonic == "jmp" and next_instr.src.value == addr:
instr.mnemonic = "hlt"
Lifter.lift(il, instr)
return instr.length