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
|
#! /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.ppc.arch import mn_ppc as mn
from miasm.arch.ppc.sem import Lifter_PPC32b as Lifter
from miasm.arch.ppc.regs import *
from miasm.expression.expression import *
from miasm.core.locationdb import LocationDB
from pdb import pm
logging.getLogger('cpuhelper').setLevel(logging.ERROR)
loc_db = LocationDB()
EXCLUDE_REGS = set([Lifter(loc_db).IRDst])
def M(addr):
return ExprMem(ExprInt(addr, 32), 32)
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, loc_db, "b")
code = mn.asm(instr)[0]
instr = mn.dis(code, "b")
instr.offset = inputstate.get(PC, 0)
lbl = lifter.add_instr_to_ircfg(instr, ircfg)
symexec.run_at(ircfg, lbl)
if debug:
for k, v in viewitems(symexec.symbols):
if regs_init.get(k, None) != v:
print(k, v)
out = {}
for k, v in viewitems(symexec.symbols):
if k in EXCLUDE_REGS:
continue
elif regs_init.get(k, None) == v:
continue
elif isinstance(v, ExprInt):
out[k] = int(v)
else:
out[k] = v
return out
class TestPPC32Semantic(unittest.TestCase):
# def test_condition(self):
# §A8.3: Conditional execution
# pass
def test_shift(self):
self.assertEqual(
compute('SLW R5, R4, R1',
{R1: 8, R4: 0xDEADBEEF, }),
{R1: 8, R4: 0xDEADBEEF, R5: 0xADBEEF00, })
self.assertEqual(
compute('SLW. R5, R4, R1',
{R1: 8, R4: 0xDEADBEEF, }),
{R1: 8, R4: 0xDEADBEEF, R5: 0xADBEEF00,
CR0_LT: 1, CR0_GT: 0, CR0_EQ: 0, CR0_SO: ExprId('XER_SO_init', 1)})
self.assertEqual(
compute('SLW R5, R4, R1',
{R1: 32 | 0xbeef, R4: 0xDEADBEEF, }),
{R1: 32 | 0xbeef, R4: 0xDEADBEEF, R5: 0x0, })
self.assertEqual(
compute('SLW. R5, R4, R1',
{R1: 32 | 0xbeef, R4: 0xDEADBEEF, }),
{R1: 32 | 0xbeef, R4: 0xDEADBEEF, R5: 0x0,
CR0_LT: 0, CR0_GT: 0, CR0_EQ: 1, CR0_SO: ExprId('XER_SO_init', 1)})
# self.assertRaises(ValueError, compute, 'MOV R4, R4 LSL 0')
def test_ADD(self):
self.assertEqual(
compute('ADD R5, R4, R1',
{R1: 0xCAFEBABE, R4: 0xDEADBEEF, }),
{R1: 0xCAFEBABE, R4: 0xDEADBEEF, R5: 0xA9AC79AD, })
self.assertEqual(
compute('ADD. R5, R4, R1',
{R1: 0xCAFEBABE, R4: 0xDEADBEEF, }),
{R1: 0xCAFEBABE, R4: 0xDEADBEEF, R5: 0xA9AC79AD,
CR0_LT: 1, CR0_GT: 0, CR0_EQ: 0, CR0_SO: ExprId('XER_SO_init', 1)})
pass
def test_AND(self):
self.assertEqual(
compute('AND R5, R4, R1',
{R1: 0xCAFEBABE, R4: 0xDEADBEEF, }),
{R1: 0xCAFEBABE, R4: 0xDEADBEEF, R5: 0xCAACBAAE, })
self.assertEqual(
compute('AND. R5, R4, R1',
{R1: 0xCAFEBABE, R4: 0xDEADBEEF, }),
{R1: 0xCAFEBABE, R4: 0xDEADBEEF, R5: 0xCAACBAAE,
CR0_LT: 1, CR0_GT: 0, CR0_EQ: 0, CR0_SO: ExprId('XER_SO_init', 1)})
pass
def test_SUB(self):
self.assertEqual(
compute('SUBF R5, R4, R1',
{R1: 0xCAFEBABE, R4: 0xDEADBEEF, }),
{R1: 0xCAFEBABE, R4: 0xDEADBEEF, R5: 0xEC50FBCF, })
self.assertEqual(
compute('SUBF. R5, R4, R1',
{R1: 0xCAFEBABE, R4: 0xDEADBEEF, }),
{R1: 0xCAFEBABE, R4: 0xDEADBEEF, R5: 0xEC50FBCF,
CR0_LT: 1, CR0_GT: 0, CR0_EQ: 0, CR0_SO: ExprId('XER_SO_init', 1)})
pass
def test_CMP(self):
self.assertEqual(
compute('CMPW CR2, R4, R1',
{R1: 0xCAFEBABE, R4: 0xDEADBEEF, }),
{R1: 0xCAFEBABE, R4: 0xDEADBEEF,
CR2_LT: 0, CR2_GT: 1, CR2_EQ: 0, CR2_SO: ExprId('XER_SO_init', 1)})
pass
if __name__ == '__main__':
testsuite = unittest.TestLoader().loadTestsFromTestCase(TestPPC32Semantic)
report = unittest.TextTestRunner(verbosity=2).run(testsuite)
exit(len(report.errors + report.failures))
|