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
|
#! /usr/bin/env python2
#-*- coding:utf-8 -*-
from __future__ import print_function
import unittest
import logging
from future.utils import viewitems
from miasm.ir.symbexec import SymbolicExecutionEngine
from miasm.arch.msp430.arch import mn_msp430 as mn, mode_msp430 as mode
from miasm.arch.msp430.sem import Lifter_MSP430 as Lifter
from miasm.arch.msp430.regs import *
from miasm.expression.expression import *
from miasm.core.locationdb import LocationDB
logging.getLogger('cpuhelper').setLevel(logging.ERROR)
loc_db = LocationDB()
EXCLUDE_REGS = set([res, Lifter(loc_db).IRDst])
def M(addr):
return ExprMem(ExprInt(addr, 16), 16)
def compute(asm, inputstate={}, debug=False):
loc_db = LocationDB()
sympool = dict(regs_init)
sympool.update({k: ExprInt(v, k.size) for k, v in viewitems(inputstate)})
lifter = Lifter(loc_db)
ircfg = lifter.new_ircfg()
symexec = SymbolicExecutionEngine(lifter, sympool)
instr = mn.fromstring(asm, mode)
code = mn.asm(instr)[0]
instr = mn.dis(code, mode)
instr.offset = inputstate.get(PC, 0)
loc_key = lifter.add_instr_to_ircfg(instr, ircfg)
symexec.run_at(ircfg, loc_key)
if debug:
for k, v in viewitems(symexec.symbols):
if regs_init.get(k, None) != v:
print(k, v)
result = {
k: int(v) for k, v in viewitems(symexec.symbols)
if k not in EXCLUDE_REGS and regs_init.get(k, None) != v
}
return result
class TestMSP430Semantic(unittest.TestCase):
def test_ADD_W(self):
# Testing status flags
self.assertEqual(compute('add.w 0x0000, R4', {R4: 0x0001, }), {
R4: 0x0001, nf: 0, zf: 0, cf: 0, of: 0})
self.assertEqual(compute('add.w 0x0000, R4', {R4: 0xFFFF, }), {
R4: 0xFFFF, nf: 1, zf: 0, cf: 0, of: 0})
self.assertEqual(compute('add.w 0x0000, R4', {R4: 0x0000, }), {
R4: 0x0000, nf: 0, zf: 1, cf: 0, of: 0})
self.assertEqual(compute('add.w 0x0002, R4', {R4: 0xFFFF, }), {
R4: 0x0001, nf: 0, zf: 0, cf: 1, of: 0})
self.assertEqual(compute('add.w 0x7FFF, R4', {R4: 0x7FFF, }), {
R4: 0xFFFE, nf: 1, zf: 0, cf: 0, of: 1})
self.assertEqual(compute('add.w 0x8001, R4', {R4: 0x8001, }), {
R4: 0x0002, nf: 0, zf: 0, cf: 1, of: 1})
# Testing addressing mode
self.assertEqual(compute('add.w R5, R4', {R4: 0x1F53, R5: 0x28C4, }), {
R4: 0x4817, R5: 0x28C4, nf: 0, zf: 0, cf: 0, of: 0})
self.assertEqual(compute('add.w @R5, R4', {R4: 0x1F53, R5: 0x28C4, M(0x28C4): 0, }), {
R4: 0x1F53, R5: 0x28C4, M(0x28C4): 0, nf: 0, zf: 0, cf: 0, of: 0})
self.assertEqual(compute('add.w @R5+, R4', {R4: 0x1F53, R5: 0x28C4, M(0x28C4): 0, }), {
R4: 0x1F53, R5: 0x28C6, M(0x28C4): 0, nf: 0, zf: 0, cf: 0, of: 0})
self.assertEqual(compute('add.w 1(R5), R4', {R4: 0x1F53, R5: 0x28C4, M(0x28C5): 0, }), {
R4: 0x1F53, R5: 0x28C4, M(0x28C5): 0, nf: 0, zf: 0, cf: 0, of: 0})
self.assertEqual(compute('add.w @0x0000, R4', {R4: 0x1F53, M(0): 0x28C4, }), {
R4: 0x4817, M(0): 0x28C4, nf: 0, zf: 0, cf: 0, of: 0})
self.assertEqual(compute('add.w 0x0000, R4', {R4: 0x1F53, }), {
R4: 0x1F53, nf: 0, zf: 0, cf: 0, of: 0})
def test_AND_B(self):
# Testing status flags
self.assertEqual(compute('and.b 0x0001, R4', {R4: 0x0001, }), {
R4: 0x0001, nf: 0, zf: 0, cf: 1, of: 0})
self.assertEqual(compute('and.b 0xFFFF, R4', {R4: 0xFFFF, }), {
R4: 0x00FF, nf: 1, zf: 0, cf: 1, of: 0})
self.assertEqual(compute('and.b 0x0000, R4', {R4: 0x0000, }), {
R4: 0x0000, nf: 0, zf: 1, cf: 0, of: 0})
# Testing addressing mode
self.assertEqual(compute('and.b R5, R4', {R4: 0x1F53, R5: 0x38C4, }), {
R4: 0x0040, R5: 0x38C4, nf: 0, zf: 0, cf: 1, of: 0})
self.assertEqual(compute('and.b @R5, R4', {R4: 0x1F53, R5: 0x38C4, M(0x38C4): 0, }), {
R4: 0x0000, R5: 0x38C4, M(0x38C4): 0, nf: 0, zf: 1, cf: 0, of: 0})
self.assertEqual(compute('and.b @R5+, R4', {R4: 0x1F53, R5: 0x38C4, M(0x38C4): 0, }), {
R4: 0x0000, R5: 0x38C5, M(0x38C4): 0, nf: 0, zf: 1, cf: 0, of: 0})
self.assertEqual(compute('and.b 1(R5), R4', {R4: 0x1F53, R5: 0x38C4, M(0x38C5): 1, }), {
R4: 0x0001, R5: 0x38C4, M(0x38C5): 1, nf: 0, zf: 0, cf: 1, of: 0})
self.assertEqual(compute('and.b @0x0000, R4', {R4: 0x1F53, M(0): 0x38C4, }), {
R4: 0x0040, M(0): 0x38C4, nf: 0, zf: 0, cf: 1, of: 0})
self.assertEqual(compute('and.b 0xFFFF, R4', {R4: 0x1F53, }), {
R4: 0x0053, nf: 0, zf: 0, cf: 1, of: 0})
def test_AND_W(self):
# Testing status flags
self.assertEqual(compute('and.w 0x0001, R4', {R4: 0x0001, }), {
R4: 0x0001, nf: 0, zf: 0, cf: 1, of: 0})
self.assertEqual(compute('and.w 0xFFFF, R4', {R4: 0xFFFF, }), {
R4: 0xFFFF, nf: 1, zf: 0, cf: 1, of: 0})
self.assertEqual(compute('and.w 0x0000, R4', {R4: 0x0000, }), {
R4: 0x0000, nf: 0, zf: 1, cf: 0, of: 0})
# Testing addressing mode
self.assertEqual(compute('and.w R5, R4', {R4: 0x1F53, R5: 0x38C4, }), {
R4: 0x1840, R5: 0x38C4, nf: 0, zf: 0, cf: 1, of: 0})
self.assertEqual(compute('and.w @R5, R4', {R4: 0x1F53, R5: 0x38C4, M(0x38C4): 0, }), {
R4: 0x0000, R5: 0x38C4, M(0x38C4): 0, nf: 0, zf: 1, cf: 0, of: 0})
self.assertEqual(compute('and.w @R5+, R4', {R4: 0x1F53, R5: 0x38C4, M(0x38C4): 0, }), {
R4: 0x0000, R5: 0x38C6, M(0x38C4): 0, nf: 0, zf: 1, cf: 0, of: 0})
self.assertEqual(compute('and.w 1(R5), R4', {R4: 0x1F53, R5: 0x38C4, M(0x38C5): 1, }), {
R4: 0x0001, R5: 0x38C4, M(0x38C5): 1, nf: 0, zf: 0, cf: 1, of: 0})
self.assertEqual(compute('and.w @0x0000, R4', {R4: 0x1F53, M(0): 0x38C4, }), {
R4: 0x1840, M(0): 0x38C4, nf: 0, zf: 0, cf: 1, of: 0})
self.assertEqual(compute('and.w 0xFFFF, R4', {R4: 0x1F53, }), {
R4: 0x1F53, nf: 0, zf: 0, cf: 1, of: 0})
def test_BIC_B(self):
# Testing addressing mode
self.assertEqual(
compute('bic.b 0x0000, R4', {R4: 0x1F53, }), {R4: 0x0053, })
# self.assertEqual(compute('bic.b 0x0000, @R4', {R4:0x1F53,M(0x1F53):0x569D, }), {R4:0x1F53,M(0x1F53):0x38C4, })
# self.assertEqual(compute('bic.b 0x38C4, @R4+', {R4:0x1F53,M(0x1F53):0x569D, }), {R4:0x1F55,M(0x1F53):0x38C4, })
# self.assertEqual(compute('bic.b 0x38C4, 1(R4)', {R4:0x1F53,M(0x1F54):0x569D, }), {R4:0x1F53,M(0x1F54):0x5619, })
# self.assertEqual(compute('bic.b 0x0000, @0x0000', { M(0x0000):0x569D, }), { M(0x0000):0x38C4, })
# self.assertEqual(compute('bic.b 0x38C4, 0xFFFE', {
# }), { })
def test_CALL(self):
# Testing addressing mode
self.assertEqual(compute('call R4', {PC: 0x0100, SP: 0x0400, R4: 0x1F53, }), {
PC: 0x1F53, SP: 0x03FE, R4: 0x1F53, M(0x03FE): 0x102, })
self.assertEqual(compute('call @R4', {PC: 0x0100, SP: 0x0400, R4: 0x1F53, M(0x1F53): 0x38C4, }), {
PC: 0x38C4, SP: 0x03FE, R4: 0x1F53, M(0x1F53): 0x38C4, M(0x03FE): 0x102, })
self.assertEqual(compute('call @R4+', {PC: 0x0100, SP: 0x0400, R4: 0x1F53, M(0x1F53): 0x38C4, }), {
PC: 0x38C4, SP: 0x03FE, R4: 0x1F55, M(0x1F53): 0x38C4, M(0x03FE): 0x102, })
self.assertEqual(compute('call 1(R4)', {PC: 0x0100, SP: 0x0400, R4: 0x1F53, M(0x1F54): 0x38C4, }), {
PC: 0x38C4, SP: 0x03FE, R4: 0x1F53, M(0x1F54): 0x38C4, M(0x03FE): 0x104, })
self.assertEqual(compute('call @0x0000', {PC: 0x0100, SP: 0x0400, M(0x0000): 0x38C4, }), {
PC: 0x38C4, SP: 0x03FE, M(0x0000): 0x38C4, M(0x03FE): 0x104, })
self.assertEqual(compute('call 0xFFFE', {PC: 0x0100, SP: 0x0400, }), {
PC: 0xFFFE, SP: 0x03FE, M(0x03FE): 0x104, })
if __name__ == '__main__':
testsuite = unittest.TestLoader().loadTestsFromTestCase(TestMSP430Semantic)
report = unittest.TextTestRunner(verbosity=2).run(testsuite)
exit(len(report.errors + report.failures))
|