Skip to content

Commit cdc2659

Browse files
committed
Arm: add parallel instructions
1 parent a839800 commit cdc2659

File tree

6 files changed

+564
-1
lines changed

6 files changed

+564
-1
lines changed

miasm/arch/arm/arch.py

+24
Original file line numberDiff line numberDiff line change
@@ -1709,6 +1709,30 @@ def armtop(name, fields, args=None, alias=False):
17091709
armop("isb", [bs8(0xF5), bs8(0x7F), bs8(0xF0), bs8(0x6F)])
17101710
armop("nop", [bs8(0xE3), bs8(0x20), bs8(0xF0), bs8(0)])
17111711

1712+
1713+
parallel_arith_name = {
1714+
'Q': 0b01100010,
1715+
'S': 0b01100001,
1716+
'SH': 0b01100011,
1717+
'U': 0b01100101,
1718+
'UH': 0b01100111,
1719+
'UQ': 0b01100110,
1720+
}
1721+
bs_parallel_arith = bs_name(l=8, name=parallel_arith_name)
1722+
1723+
parallel_modarith_name = {
1724+
0b0001 : 'ADD16',
1725+
0b0011 : 'ADDSUBX',
1726+
0b0101 : 'SUBADDX',
1727+
0b0111 : 'SUB16',
1728+
0b1001 : 'ADD8',
1729+
0b1111 : 'SUB8',
1730+
}
1731+
bs_parallel_modarith = bs_mod_name(l=4, mn_mod=parallel_modarith_name)
1732+
1733+
armop("arith", [bs_parallel_arith, rn, rd, bs('1111'), bs_parallel_modarith, rm], [rd, rn, rm])
1734+
1735+
17121736
class arm_widthm1(arm_imm, m_arg):
17131737
def decode(self, v):
17141738
self.expr = ExprInt(v+1, 32)

miasm/arch/arm/sem.py

+96
Original file line numberDiff line numberDiff line change
@@ -1285,6 +1285,97 @@ def uadd8(ir, instr, a, b, c):
12851285
return e, []
12861286

12871287

1288+
def uadd16(ir, instr, a, b, c):
1289+
e = []
1290+
sums = []
1291+
ges = []
1292+
for i in range(0, 32, 16):
1293+
sums.append(b[i:i+16] + c[i:i+16])
1294+
ges.append((b[i:i+16].zeroExtend(17) + c[i:i+16].zeroExtend(17))[16:17])
1295+
1296+
e.append(ExprAssign(a, ExprCompose(*sums)))
1297+
1298+
for i, value in enumerate(ges):
1299+
e.append(ExprAssign(ge_regs[2 * i], value))
1300+
e.append(ExprAssign(ge_regs[2 * i + 1], value))
1301+
return e, []
1302+
1303+
1304+
def uaddsubx(ir, instr, a, b, c):
1305+
e = []
1306+
sums = []
1307+
ges = []
1308+
1309+
1310+
part1, part2 = b[16:32], c[0:16]
1311+
sums.append(part1 + part2)
1312+
ges.append((part1.zeroExtend(17) + part2.zeroExtend(17))[16:17])
1313+
1314+
part1, part2 = b[0:16], c[16:32]
1315+
sums.append(part1 - part2)
1316+
ges.append(ExprOp("FLAG_SIGN_SUB", part1, part2))
1317+
1318+
e.append(ExprAssign(a, ExprCompose(*sums[::-1])))
1319+
1320+
for i, value in enumerate(ges[::-1]):
1321+
e.append(ExprAssign(ge_regs[2 * i], value))
1322+
e.append(ExprAssign(ge_regs[2 * i + 1], value))
1323+
return e, []
1324+
1325+
1326+
def sadd8(ir, instr, a, b, c):
1327+
e = []
1328+
sums = []
1329+
ges = []
1330+
for i in range(0, 32, 8):
1331+
sums.append(b[i:i+8] + c[i:i+8])
1332+
ges.append(ExprOp("FLAG_SIGN_SUB", ExprInt(0, 9), b[i:i+8].signExtend(9) + c[i:i+8].signExtend(9)))
1333+
1334+
e.append(ExprAssign(a, ExprCompose(*sums)))
1335+
1336+
for i, value in enumerate(ges):
1337+
e.append(ExprAssign(ge_regs[i], value))
1338+
return e, []
1339+
1340+
1341+
def sadd16(ir, instr, a, b, c):
1342+
e = []
1343+
sums = []
1344+
ges = []
1345+
for i in range(0, 32, 16):
1346+
sums.append(b[i:i+16] + c[i:i+16])
1347+
ges.append(ExprOp("FLAG_SIGN_SUB", ExprInt(0, 17), b[i:i+16].signExtend(17) + c[i:i+16].signExtend(17)))
1348+
1349+
e.append(ExprAssign(a, ExprCompose(*sums)))
1350+
1351+
for i, value in enumerate(ges):
1352+
e.append(ExprAssign(ge_regs[2 * i], value))
1353+
e.append(ExprAssign(ge_regs[2 * i + 1], value))
1354+
return e, []
1355+
1356+
1357+
def saddsubx(ir, instr, a, b, c):
1358+
e = []
1359+
sums = []
1360+
ges = []
1361+
1362+
1363+
part1, part2 = b[16:32], c[0:16]
1364+
sums.append(part1 + part2)
1365+
ges.append(ExprOp("FLAG_SIGN_SUB", ExprInt(0, 17), part1.signExtend(17) + part2.signExtend(17)))
1366+
1367+
part1, part2 = b[0:16], c[16:32]
1368+
sums.append(part1 - part2)
1369+
ges.append(~ExprOp("FLAG_SIGN_SUB", part1, part2))
1370+
1371+
e.append(ExprAssign(a, ExprCompose(*sums[::-1])))
1372+
1373+
for i, value in enumerate(ges[::-1]):
1374+
e.append(ExprAssign(ge_regs[2 * i], value))
1375+
e.append(ExprAssign(ge_regs[2 * i + 1], value))
1376+
return e, []
1377+
1378+
12881379
def sel(ir, instr, a, b, c):
12891380
e = []
12901381
cond = nf ^ of ^ ExprInt(1, 1)
@@ -1641,6 +1732,11 @@ def add_condition_expr(ir, instr, cond, instr_ir, extra_ir):
16411732
'smlatb': smlatb,
16421733
'smlatt': smlatt,
16431734
'uadd8': uadd8,
1735+
'uadd16': uadd16,
1736+
'uaddsubx': uaddsubx,
1737+
'sadd8': sadd8,
1738+
'sadd16': sadd16,
1739+
'saddsubx': saddsubx,
16441740
'sel': sel,
16451741
}
16461742

test/arch/arm/arch.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -222,7 +222,8 @@ def u16swap(i):
222222

223223
('XXXXXXXX UXTAB R5, R2, R8 ROR 0x8',
224224
'7854e2e6'),
225-
225+
('XXXXXXXX UADD8 R1, R2, R3',
226+
'931f52e6'),
226227

227228
('XXXXXXXX PKHBT R1, R2, R3 LSL 0x8',
228229
'131482e6'),

test/arch/arm/unit/asm_test.py

+74
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
from builtins import str
2+
from builtins import object
3+
import sys
4+
import os
5+
6+
from future.utils import viewitems
7+
8+
from miasm.arch.arm.arch import mn_arm, base_expr, variable
9+
from miasm.core import parse_asm
10+
from miasm.expression.expression import *
11+
from miasm.core import asmblock
12+
from miasm.loader.strpatchwork import StrPatchwork
13+
from miasm.analysis.machine import Machine
14+
from miasm.jitter.csts import *
15+
16+
reg_and_id = dict(mn_arm.regs.all_regs_ids_byname)
17+
18+
class Asm_Test(object):
19+
run_addr = 0x0
20+
21+
def __init__(self, jitter_engine):
22+
self.myjit = Machine(self.arch_name).jitter(jitter_engine)
23+
self.myjit.init_stack()
24+
25+
def test_init(self):
26+
pass
27+
28+
def prepare(self):
29+
pass
30+
31+
def __call__(self):
32+
self.prepare()
33+
self.asm()
34+
self.init_machine()
35+
self.test_init()
36+
self.run()
37+
self.check()
38+
39+
def run(self):
40+
41+
self.myjit.init_run(self.run_addr)
42+
self.myjit.continue_run()
43+
44+
assert(self.myjit.pc == self.ret_addr)
45+
46+
def asm(self):
47+
blocks, loc_db = parse_asm.parse_txt(
48+
mn_arm, self.arch_attrib, self.TXT,
49+
loc_db = self.myjit.ir_arch.loc_db
50+
)
51+
# fix shellcode addr
52+
loc_db.set_location_offset(loc_db.get_name_location("main"), 0x0)
53+
s = StrPatchwork()
54+
patches = asmblock.asm_resolve_final(mn_arm, blocks, loc_db)
55+
for offset, raw in viewitems(patches):
56+
s[offset] = raw
57+
58+
s = bytes(s)
59+
self.assembly = s
60+
61+
def check(self):
62+
raise NotImplementedError('abstract method')
63+
64+
65+
class Asm_Test(Asm_Test):
66+
arch_name = "arml"
67+
arch_attrib = "l"
68+
ret_addr = 0x1330
69+
70+
def init_machine(self):
71+
self.myjit.vm.add_memory_page(self.run_addr, PAGE_READ | PAGE_WRITE, self.assembly)
72+
self.myjit.push_uint32_t(self.ret_addr)
73+
self.myjit.add_breakpoint(self.ret_addr, lambda x:False)
74+

0 commit comments

Comments
 (0)