mirror of
https://github.com/cea-sec/miasm
synced 2026-08-17 10:26:03 -04:00
More arm instructions
This commit is contained in:
parent
0fffa143ce
commit
67d0b838e4
5 changed files with 416 additions and 10 deletions
|
|
@ -50,6 +50,21 @@ gpregs_nosp = reg_info(regs_str[:13] + [str(reg_dum), regs_str[14], regs_str[15]
|
|||
regs_expr[:13] + [reg_dum, regs_expr[14], regs_expr[15]])
|
||||
|
||||
|
||||
# Single-Precision
|
||||
spregs_str = ['S%d' % r for r in range(32)]
|
||||
spregs_expr = [ExprId(x, 32) for x in spregs_str]
|
||||
spregs = reg_info(spregs_str, spregs_expr)
|
||||
|
||||
# Double-Precision
|
||||
dpregs_str = ['D%d' % r for r in range(32)]
|
||||
dpregs_expr = [ExprId(x, 64) for x in dpregs_str]
|
||||
dpregs = reg_info(dpregs_str, dpregs_expr)
|
||||
|
||||
# Quadword
|
||||
qpregs_str = ['Q%d' % r for r in range(16)]
|
||||
qpregs_expr = [ExprId(x, 128) for x in qpregs_str]
|
||||
qpregs = reg_info(qpregs_str, qpregs_expr)
|
||||
|
||||
# psr
|
||||
sr_flags = "cxsf"
|
||||
cpsr_regs_str = []
|
||||
|
|
@ -1834,6 +1849,7 @@ armop("pld", [bs8(0xF5), bs_addi, bs_rw, bs('01'), mem_rn_imm, bs('1111'), imm12
|
|||
|
||||
armop("dsb", [bs('111101010111'), bs('1111'), bs('1111'), bs('0000'), bs('0100'), barrier_option])
|
||||
armop("isb", [bs('111101010111'), bs('1111'), bs('1111'), bs('0000'), bs('0110'), barrier_option])
|
||||
armop("dmb", [bs('111101010111'), bs('1111'), bs('1111'), bs('0000'), bs('0101'), barrier_option])
|
||||
armop("nop", [bs8(0xE3), bs8(0x20), bs8(0xF0), bs8(0)])
|
||||
|
||||
class arm_widthm1(arm_imm, m_arg):
|
||||
|
|
@ -2127,6 +2143,13 @@ class arm_off8sppc(arm_imm):
|
|||
def encodeval(self, v):
|
||||
return v >> 2
|
||||
|
||||
class arm_off8(arm_imm):
|
||||
|
||||
def decodeval(self, v):
|
||||
return v << 2
|
||||
|
||||
def encodeval(self, v):
|
||||
return v >> 2
|
||||
|
||||
class arm_off7(arm_imm):
|
||||
|
||||
|
|
@ -2137,11 +2160,16 @@ class arm_off7(arm_imm):
|
|||
return v >> 2
|
||||
|
||||
class arm_deref_reg_imm(arm_arg):
|
||||
reg_info = gpregs
|
||||
parser = deref_reg_imm
|
||||
|
||||
def decode(self, v):
|
||||
v = v & self.lmask
|
||||
rbase = regs_expr[v]
|
||||
# We should not use regs_expr direct
|
||||
# subclass overwrite reg_info in some case
|
||||
if regs_expr[v] not in self.reg_info.expr:
|
||||
return False
|
||||
rbase = self.reg_info.expr[v]
|
||||
e = ExprOp('preinc', rbase, self.parent.off.expr)
|
||||
self.expr = ExprMem(e, 32)
|
||||
return True
|
||||
|
|
@ -2164,9 +2192,6 @@ class arm_deref_reg_imm(arm_arg):
|
|||
log.debug('cannot encode off %r', off)
|
||||
return False
|
||||
self.value = gpregs.expr.index(e.args[0])
|
||||
if self.value >= 1 << self.l:
|
||||
log.debug('cannot encode reg %r', off)
|
||||
return False
|
||||
return True
|
||||
|
||||
class arm_derefl(arm_deref_reg_imm):
|
||||
|
|
@ -2440,8 +2465,9 @@ class arm_sp(arm_reg):
|
|||
|
||||
off5 = bs(l=5, cls=(arm_imm,), fname="off")
|
||||
off3 = bs(l=3, cls=(arm_imm,), fname="off")
|
||||
off8 = bs(l=8, cls=(arm_imm,), fname="off")
|
||||
imm8 = bs(l=8, cls=(arm_imm,), fname="off")
|
||||
off7 = bs(l=7, cls=(arm_off7,), fname="off")
|
||||
off8 = bs(l=8, cls=(arm_off8,), fname="off", order=-1)
|
||||
|
||||
rdl = bs(l=3, cls=(arm_gpreg_l,), fname="rd")
|
||||
rnl = bs(l=3, cls=(arm_gpreg_l,), fname="rn")
|
||||
|
|
@ -2543,7 +2569,7 @@ bs_br_name = bs_name(l=4, name=br_name)
|
|||
armtop("mshift", [bs('000'), bs_mshift_name, off5, rsl, rdl], [rdl, rsl, off5])
|
||||
armtop("addsubr", [bs('000110'), bs_addsub_name, rnl, rsl, rdl], [rdl, rsl, rnl])
|
||||
armtop("addsubi", [bs('000111'), bs_addsub_name, off3, rsl, rdl], [rdl, rsl, off3])
|
||||
armtop("mcas", [bs('001'), bs_mov_cmp_add_sub_name, rnl, off8])
|
||||
armtop("mcas", [bs('001'), bs_mov_cmp_add_sub_name, rnl, imm8])
|
||||
armtop("alu", [bs('010000'), bs_alu_name, rsl, rdl], [rdl, rsl])
|
||||
# should not be used ??
|
||||
armtop("hiregop00", [bs('010001'), bs_hiregop_name, bs('00'), rsl, rdl], [rdl, rsl])
|
||||
|
|
@ -3436,9 +3462,69 @@ armtop("strd", [bs('1110100'), ppi, updown, bs('1'), wback_no_t, bs('0'), rn_nop
|
|||
armtop("ldrd", [bs('1110100'), ppi, updown, bs('1'), wback_no_t, bs('1'), rn_nopc_noarg, rt, rt2, deref_immpuw00], [rt, rt2, deref_immpuw00])
|
||||
|
||||
|
||||
armtop("ldr", [bs('111110001101'), rn_deref, rt, off12], [rt, rn_deref])
|
||||
armtop("ldr", [bs('111110000101'), rn_noarg, rt, bs('1'), ppi, updown, wback_no_t, deref_immpuw], [rt, deref_immpuw])
|
||||
armtop("ldr", [bs('111110000101'), rn_noarg, rt, bs('000000'), imm2_noarg, rm_deref_reg], [rt, rm_deref_reg])
|
||||
class armt_rn_deref_up(arm_arg):
|
||||
parser = deref_reg_imm
|
||||
|
||||
def decode(self, v):
|
||||
v = v & self.lmask
|
||||
rbase = regs_expr[v]
|
||||
e = None
|
||||
if self.parent.updown.value == 1:
|
||||
e = ExprOp('preinc', rbase, self.parent.off.expr)
|
||||
else:
|
||||
e = ExprOp('preinc', rbase, -self.parent.off.expr)
|
||||
self.expr = ExprMem(e, 32)
|
||||
return True
|
||||
|
||||
def encode(self):
|
||||
self.parent.off.expr = None
|
||||
e = self.expr
|
||||
if not isinstance(e, ExprMem):
|
||||
return False
|
||||
e = e.ptr
|
||||
if not (isinstance(e, ExprOp) and e.op == 'preinc'):
|
||||
log.debug('cannot encode %r', e)
|
||||
return False
|
||||
off = e.args[1]
|
||||
|
||||
if not isinstance(off, ExprInt):
|
||||
log.debug('cannot encode off %r', off)
|
||||
return False
|
||||
|
||||
v = int(off)
|
||||
|
||||
if v < 0 or v & (1 << 31):
|
||||
self.parent.updown.value = 0
|
||||
v = (-v) & 0xFFFFFFFF
|
||||
else:
|
||||
self.parent.updown.value = 1
|
||||
|
||||
self.parent.off.expr = ExprInt(v, 32)
|
||||
self.value = gpregs.expr.index(e.args[0])
|
||||
return True
|
||||
|
||||
class arm_gpreg_nopc_noarg(reg_noarg):
|
||||
reg_info = gpregs_nopc
|
||||
parser = reg_info.parser
|
||||
|
||||
class arm_nopc_deref(arm_deref_reg_imm):
|
||||
reg_info = gpregs_nopc
|
||||
|
||||
class armt_pc_deref_up(armt_rn_deref_up):
|
||||
parser = deref_pc
|
||||
|
||||
class armt_nopc_deref_up(armt_rn_deref_up):
|
||||
pass
|
||||
|
||||
rn_nopc_noarg = bs(l=4, cls=(arm_gpreg_nopc_noarg,), fname="rn")
|
||||
rn_nopc_deref = bs(l=4, cls=(arm_nopc_deref,), fname="rt")
|
||||
rn_nopc_deref_up = bs(l=4, cls=(armt_nopc_deref_up,))
|
||||
pc_deref_up = bs("1111", l=4, cls=(armt_pc_deref_up,))
|
||||
|
||||
armtop("ldr", [bs('11111000'), updown, bs('101'), pc_deref_up, rt, off12], [rt, pc_deref_up])
|
||||
armtop("ldr", [bs('111110001101'), rn_nopc_deref, rt, off12], [rt, rn_nopc_deref])
|
||||
armtop("ldr", [bs('111110000101'), rn_nopc_noarg, rt, bs('1'), ppi, updown, wback_no_t, deref_immpuw], [rt, deref_immpuw])
|
||||
armtop("ldr", [bs('111110000101'), rn_nopc_noarg, rt, bs('000000'), imm2_noarg, rm_deref_reg], [rt, rm_deref_reg])
|
||||
armtop("ldrb", [bs('111110000001'), rn_noarg, rt, bs('000000'), imm2_noarg, rm_deref_reg], [rt, rm_deref_reg])
|
||||
armtop("ldrb", [bs('111110000001'), rn_noarg, rt, bs('1'), ppi, updown, wback_no_t, deref_immpuw], [rt, deref_immpuw])
|
||||
armtop("ldrb", [bs('111110001001'), rn_deref, rt_nopc, off12], [rt_nopc, rn_deref])
|
||||
|
|
@ -3456,3 +3542,106 @@ armtop("tbh", [bs('111010001101'), rn_noarg, bs('11110000000'), bs('1'), bs_der
|
|||
armtop("dsb", [bs('111100111011'), bs('1111'), bs('1000'), bs('1111'), bs('0100'), barrier_option])
|
||||
|
||||
armtop("adr", [bs('11110'), imm12_1, bs('100000'), bs('1111'), bs('0'), imm12_3, rd, imm12_8_t4], [rd, imm12_8_t4])
|
||||
|
||||
class arm_dpregs_1_4(reg_noarg):
|
||||
reg_info = dpregs
|
||||
parser = reg_info.parser
|
||||
|
||||
|
||||
def decode(self, v):
|
||||
v = v & self.lmask
|
||||
v = self.parent.dpregs_1_x.value << 4 | v
|
||||
self.expr = self.reg_info.expr[v]
|
||||
return True
|
||||
|
||||
def encode(self):
|
||||
if not self.expr in self.reg_info.expr:
|
||||
log.debug("cannot encode reg %r", self.expr)
|
||||
return False
|
||||
self.value = self.reg_info.expr.index(self.expr)
|
||||
self.parent.dpregs_1_x.value = self.value >> 4 & self.parent.dpregs_1_x.lmask
|
||||
return True
|
||||
|
||||
|
||||
class arm_spregs_4_1(reg_noarg):
|
||||
reg_info = spregs
|
||||
parser = reg_info.parser
|
||||
|
||||
|
||||
def decode(self, v):
|
||||
v = v & self.lmask
|
||||
v = self.parent.spregs_x_1.value | (v << 1)
|
||||
self.expr = self.reg_info.expr[v]
|
||||
return True
|
||||
|
||||
def encode(self):
|
||||
if not self.expr in self.reg_info.expr:
|
||||
log.debug("cannot encode reg %r", self.expr)
|
||||
return False
|
||||
self.value = self.reg_info.expr.index(self.expr)
|
||||
self.parent.spregs_x_1.value = self.value & self.parent.spregs_x_1.lmask
|
||||
return True
|
||||
|
||||
class arm_dpregs_4_1:
|
||||
reg_info = dpregs
|
||||
parser = reg_info.parser
|
||||
|
||||
def decode(self, v):
|
||||
v = v & self.lmask
|
||||
v = self.parent.dpregs_x_1.value | v << 1
|
||||
self.expr = self.reg_info.expr[v]
|
||||
return True
|
||||
|
||||
def encode(self):
|
||||
if not self.expr in self.reg_info.expr:
|
||||
log.debug("cannot encode reg %r", self.expr)
|
||||
return False
|
||||
self.value = self.reg_info.expr.index(self.expr)
|
||||
self.parent.dpregs_x_1.value = self.value & self.parent.dpregs_x_1.lmask
|
||||
return True
|
||||
|
||||
|
||||
sn_4_1 = bs(l=4, cls=(arm_spregs_4_1, arm_arg))
|
||||
sn_x_1 = bs(l=1, fname="spregs_x_1", order=-1)
|
||||
sm_4_1 = bs(l=4, cls=(arm_spregs_4_1, arm_arg))
|
||||
sm_x_1 = bs(l=1, fname="spregs_x_1", order=-1)
|
||||
dn_1_4 = bs(l=4, cls=(arm_dpregs_1_4, arm_arg))
|
||||
dn_1_x = bs(l=1, fname="dpregs_1_x", order=-1)
|
||||
dm_4_1 = bs(l=4, cls=(arm_dpregs_4_1, arm_arg))
|
||||
dm_x_1 = bs(l=1, fname="dpregs_x_1", order=-1)
|
||||
round_zero = bs('1', l=1, fname="round_zero")
|
||||
vunsigned = bs(l=1, fname="unsigned")
|
||||
|
||||
rt2_nopc = bs(l=4, cls=(arm_gpreg_nopc, arm_arg), fname="rt")
|
||||
rn_sp_nowb = bs("1101", cls=(arm_gpreg,), fname='rnsp')
|
||||
|
||||
armtop("dmb", [bs('111100111011'), bs('1111'), bs('1000'), bs('1111'), bs('0101'), barrier_option])
|
||||
armtop("teq", [bs('111010101001'), rn_nosppc, bs('0'), imm5_3, bs('1111'), imm5_2, imm_stype, rm_sh])
|
||||
|
||||
armtop("btransfersp", [bs('1110100010'), wback, bs_tbtransfer_name, rn_wb, pc_in, lr_in, bs('0'), trlist13pclr])
|
||||
armtop("add", [bs('11110'), imm12_1, bs('10000'), bs('0'), rn_sp_nowb, bs('0'), imm12_3, rd, imm12_8_t4], [rd, rn_sp_nowb, imm12_8_t4])
|
||||
armtop("strb", [bs('111110000000'), rn_noarg, rt, bs('000000'), imm2_noarg, rm_deref_reg], [rt, rm_deref_reg])
|
||||
armtop("strex", [bs('111010000100'), rn_deref, rt, rd, off8], [rd, rt, rn_deref])
|
||||
armtop("ldrex",[bs('111010000101'), rn_deref, rt, bs('1111'), off8], [rt, rn_deref])
|
||||
|
||||
# DDI0406C.d, A8.8.344
|
||||
armtop("vmov", [bs('11101110000'), bs('1'), sn_4_1, rt_nopc, bs('1010'), sn_x_1, bs('0010000')], [rt_nopc, sn_4_1])
|
||||
armtop("vmov", [bs('11101110000'), bs('0'), sn_4_1, rt_nopc, bs('1010'), sn_x_1, bs('0010000')], [sn_4_1, rt_nopc])
|
||||
|
||||
# DDI0406C.d, A8.8.346
|
||||
armtop("vmov", [bs('11101100010'), bs('1'), rt2_nopc, rt_nopc, bs('101100'), dn_1_x, bs('1'), dn_1_4], [rt_nopc, rt2_nopc, dn_1_4])
|
||||
armtop("vmov", [bs('11101100010'), bs('0'), rt2_nopc, rt_nopc, bs('101100'), dn_1_x, bs('1'), dn_1_4], [dn_1_4, rt_nopc, rt2_nopc])
|
||||
|
||||
# DDI0406C.d, A8.8.310
|
||||
armtop("vcvt", [bs('111011101'), sn_x_1, bs('111'), bs("101"), sn_4_1, bs('101'), bs('1'), round_zero, bs('1'), dn_1_x, bs('0'), dn_1_4], [sn_4_1, dn_1_4])
|
||||
armtop("vcvt", [bs('111011101'), sn_x_1, bs('111'), bs("101"), sn_4_1, bs('101'), bs('0'), round_zero, bs('1'), sm_x_1, bs('0'), sm_4_1], [sn_4_1, sm_4_1])
|
||||
armtop("vcvt", [bs('111011101'), sn_x_1, bs('111'), bs("100"), sn_4_1, bs('101'), bs('1'), round_zero, bs('1'), dn_1_x, bs('0'), dn_1_4], [sn_4_1, dn_1_4])
|
||||
armtop("vcvt", [bs('111011101'), sn_x_1, bs('111'), bs("100"), sn_4_1, bs('101'), bs('0'), round_zero, bs('1'), sm_x_1, bs('0'), sm_4_1], [sn_4_1, sm_4_1])
|
||||
armtop("vcvt", [bs('111011101'), dn_1_x, bs('111'), bs("000"), dn_1_4, bs('101'), bs('1'), bs('1'), bs('1'), sm_x_1, bs('0'), sm_4_1], [dn_1_4, sm_4_1])
|
||||
armtop("vcvt", [bs('111011101'), dn_1_x, bs('111'), bs("000"), dn_1_4, bs('101'), bs('1'), bs('0'), bs('1'), sm_x_1, bs('0'), sm_4_1], [dn_1_4, sm_4_1])
|
||||
armtop("vcvt", [bs('111011101'), sn_x_1, bs('111'), bs("000"), sn_4_1, bs('101'), bs('0'), bs('1'), bs('1'), sm_x_1, bs('0'), sm_4_1], [sn_4_1, sm_4_1])
|
||||
armtop("vcvt", [bs('111011101'), sn_x_1, bs('111'), bs("000"), sn_4_1, bs('101'), bs('0'), bs('0'), bs('1'), sm_x_1, bs('0'), sm_4_1], [sn_4_1, sm_4_1])
|
||||
|
||||
# DDI0406C.d, A8.8.414
|
||||
armtop("vstr", [bs('11101101'), updown, dn_1_x, bs('00'), rn_nopc_deref_up, dn_1_4, bs('1011'), off8], [dn_1_4, rn_nopc_deref_up])
|
||||
armtop("vstr", [bs('11101101'), updown, sn_x_1, bs('00'), rn_nopc_deref_up, sn_4_1, bs('1010'), off8], [sn_4_1, rn_nopc_deref_up])
|
||||
|
|
@ -4,6 +4,101 @@ from builtins import range
|
|||
from miasm.expression.expression import *
|
||||
from miasm.core.cpu import gen_reg, gen_regs
|
||||
|
||||
# SP, DP, QP
|
||||
|
||||
spregs_str = ['S%d' % r for r in range(32)]
|
||||
spregs_expr = [ExprId(x, 32) for x in spregs_str]
|
||||
|
||||
dpregs_str = ['D%d' % r for r in range(32)]
|
||||
dpregs_expr = [ExprId(x, 64) for x in dpregs_str]
|
||||
|
||||
qpregs_str = ['Q%d' % r for r in range(16)]
|
||||
qpregs_expr = [ExprId(x, 128) for x in qpregs_str]
|
||||
|
||||
D0 = dpregs_expr[0]
|
||||
D1 = dpregs_expr[1]
|
||||
D2 = dpregs_expr[2]
|
||||
D3 = dpregs_expr[3]
|
||||
D4 = dpregs_expr[4]
|
||||
D5 = dpregs_expr[5]
|
||||
D6 = dpregs_expr[6]
|
||||
D7 = dpregs_expr[7]
|
||||
D8 = dpregs_expr[8]
|
||||
D9 = dpregs_expr[9]
|
||||
D10 = dpregs_expr[10]
|
||||
D11 = dpregs_expr[11]
|
||||
D12 = dpregs_expr[12]
|
||||
D13 = dpregs_expr[13]
|
||||
D14 = dpregs_expr[14]
|
||||
D15 = dpregs_expr[15]
|
||||
D16 = dpregs_expr[16]
|
||||
D17 = dpregs_expr[17]
|
||||
D18 = dpregs_expr[18]
|
||||
D19 = dpregs_expr[19]
|
||||
D20 = dpregs_expr[20]
|
||||
D21 = dpregs_expr[21]
|
||||
D22 = dpregs_expr[22]
|
||||
D23 = dpregs_expr[23]
|
||||
D24 = dpregs_expr[24]
|
||||
D25 = dpregs_expr[25]
|
||||
D26 = dpregs_expr[26]
|
||||
D27 = dpregs_expr[27]
|
||||
D28 = dpregs_expr[28]
|
||||
D29 = dpregs_expr[29]
|
||||
D30 = dpregs_expr[30]
|
||||
D31 = dpregs_expr[31]
|
||||
|
||||
|
||||
S0 = spregs_expr[0]
|
||||
S1 = spregs_expr[1]
|
||||
S2 = spregs_expr[2]
|
||||
S3 = spregs_expr[3]
|
||||
S4 = spregs_expr[4]
|
||||
S5 = spregs_expr[5]
|
||||
S6 = spregs_expr[6]
|
||||
S7 = spregs_expr[7]
|
||||
S8 = spregs_expr[8]
|
||||
S9 = spregs_expr[9]
|
||||
S10 = spregs_expr[10]
|
||||
S11 = spregs_expr[11]
|
||||
S12 = spregs_expr[12]
|
||||
S13 = spregs_expr[13]
|
||||
S14 = spregs_expr[14]
|
||||
S15 = spregs_expr[15]
|
||||
S16 = spregs_expr[16]
|
||||
S17 = spregs_expr[17]
|
||||
S18 = spregs_expr[18]
|
||||
S19 = spregs_expr[19]
|
||||
S20 = spregs_expr[20]
|
||||
S21 = spregs_expr[21]
|
||||
S22 = spregs_expr[22]
|
||||
S23 = spregs_expr[23]
|
||||
S24 = spregs_expr[24]
|
||||
S25 = spregs_expr[25]
|
||||
S26 = spregs_expr[26]
|
||||
S27 = spregs_expr[27]
|
||||
S28 = spregs_expr[28]
|
||||
S29 = spregs_expr[29]
|
||||
S30 = spregs_expr[30]
|
||||
S31 = spregs_expr[31]
|
||||
|
||||
Q0 = qpregs_expr[0]
|
||||
Q1 = qpregs_expr[1]
|
||||
Q2 = qpregs_expr[2]
|
||||
Q3 = qpregs_expr[3]
|
||||
Q4 = qpregs_expr[4]
|
||||
Q5 = qpregs_expr[5]
|
||||
Q6 = qpregs_expr[6]
|
||||
Q7 = qpregs_expr[7]
|
||||
Q8 = qpregs_expr[8]
|
||||
Q9 = qpregs_expr[9]
|
||||
Q10 = qpregs_expr[10]
|
||||
Q11 = qpregs_expr[11]
|
||||
Q12 = qpregs_expr[12]
|
||||
Q13 = qpregs_expr[13]
|
||||
Q14 = qpregs_expr[14]
|
||||
Q15 = qpregs_expr[15]
|
||||
|
||||
# GP
|
||||
|
||||
regs32_str = ["R%d" % i for i in range(13)] + ["SP", "LR", "PC"]
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ from miasm.expression.simplifications import expr_simp
|
|||
from miasm.ir.ir import Lifter, IRBlock, AssignBlock
|
||||
from miasm.arch.arm.arch import mn_arm, mn_armt
|
||||
from miasm.arch.arm.regs import *
|
||||
from miasm.arch.arm.arch import regs_expr
|
||||
|
||||
from miasm.jitter.csts import EXCEPT_DIV_BY_ZERO, EXCEPT_INT_XX
|
||||
|
||||
|
|
@ -1139,6 +1140,60 @@ def blx(ir, instr, a):
|
|||
e.append(ExprAssign(LR, l))
|
||||
return e, []
|
||||
|
||||
def vmov(ir, instr, a, b, c=None):
|
||||
e = []
|
||||
if c is None:
|
||||
if a not in spregs_expr and b not in spregs_expr:
|
||||
raise NotImplementedError('Not implemented')
|
||||
e.append(ExprAssign(a, b))
|
||||
else:
|
||||
if a in dpregs_expr:
|
||||
# two gp to one dp
|
||||
# a[:32] = b
|
||||
# a[32:] = c
|
||||
e.append(ExprAssign(a, (c.zeroExtend(a.size) << ExprInt(32, 64) | b.zeroExtend(a.size))))
|
||||
elif a in regs_expr:
|
||||
# one dp to two gp
|
||||
# a = c[:32]
|
||||
# b = c[32:]
|
||||
e.append(ExprAssign(a, c[:32]))
|
||||
e.append(ExprAssign(b, c[32:]))
|
||||
else:
|
||||
raise NotImplementedError('Not implemented')
|
||||
|
||||
return e, []
|
||||
|
||||
def vstr(ir, instr, a, b):
|
||||
e = []
|
||||
if a in spregs_expr:
|
||||
e.append(ExprAssign(b, a))
|
||||
elif a in dpregs_expr:
|
||||
if instr.mode == 'l':
|
||||
e.append(ExprAssign(b, a[:32]))
|
||||
e.append(ExprAssign(ExprMem(b.ptr + ExprInt(4, 32), 32), a[32:]))
|
||||
else:
|
||||
e.append(ExprAssign(b, a[32:]))
|
||||
e.append(ExprAssign(ExprMem(b.ptr + ExprInt(4, 32), 32), a[:32]))
|
||||
else:
|
||||
raise NotImplementedError('Not implemented')
|
||||
return e, []
|
||||
|
||||
# todo
|
||||
def vcvt(ir, instr, a, b):
|
||||
raise NotImplementedError('Not implemented')
|
||||
|
||||
# todo
|
||||
def strex(ir, instr, a, b, c=None):
|
||||
raise NotImplementedError('Not implemented')
|
||||
|
||||
# todo
|
||||
def ldrex(ir, instr, a, b):
|
||||
raise NotImplementedError('Not implemented')
|
||||
|
||||
def dmb(ir, instr, a):
|
||||
"""Memory barrier"""
|
||||
e = []
|
||||
return e, []
|
||||
|
||||
def st_ld_r(ir, instr, a, a2, b, store=False, size=32, s_ext=False, z_ext=False):
|
||||
e = []
|
||||
|
|
@ -1930,6 +1985,8 @@ mnemo_condm0 = {'add': add,
|
|||
'pkhtb': pkhtb,
|
||||
'pkhbt': pkhbt,
|
||||
|
||||
'ldrex': ldrex,
|
||||
'strex': strex,
|
||||
}
|
||||
|
||||
mnemo_condm1 = {'adds': add,
|
||||
|
|
@ -1959,6 +2016,10 @@ mnemo_condm1 = {'adds': add,
|
|||
'ldrb': ldrb,
|
||||
'ldsb': ldrsb,
|
||||
'strb': strb,
|
||||
|
||||
'vmov': vmov,
|
||||
'vstr': vstr,
|
||||
'vcvt': vcvt
|
||||
}
|
||||
|
||||
mnemo_condm2 = {'ldmia': ldmia,
|
||||
|
|
@ -2014,6 +2075,7 @@ mnemo_nocond = {'lsr': lsr,
|
|||
'smlatt': smlatt,
|
||||
'uadd8': uadd8,
|
||||
'sel': sel,
|
||||
'dmb': dmb
|
||||
}
|
||||
|
||||
mn_cond_x = [mnemo_condm0,
|
||||
|
|
|
|||
|
|
@ -719,6 +719,48 @@ reg_tests_armt = [
|
|||
"B5EB102F"),
|
||||
|
||||
|
||||
("xxxxxxxx LDMIA R0, {R2, R3, R6, R7}",
|
||||
"90E8CC00"),
|
||||
("xxxxxxxx DMB SY",
|
||||
"BFF35F8F"),
|
||||
("xxxxxxxx STRB R3, [R4, R8]",
|
||||
"04F80830"),
|
||||
("xxxxxxxx STRB R2, [R3, R9]",
|
||||
"03F80920"),
|
||||
("xxxxxxxx LDREX R3, [R1]",
|
||||
"51E8003F"),
|
||||
("xxxxxxxx LDREX R2, [R12]",
|
||||
"5CE8002F"),
|
||||
("xxxxxxxx STREX LR, R1, [R3]",
|
||||
"43E8001E"),
|
||||
("xxxxxxxx STREX R0, LR, [R2]",
|
||||
"42E800E0"),
|
||||
("xxxxxxxx TEQ R0, R1",
|
||||
"90EA010F"),
|
||||
("xxxxxxxx ADD R0, SP, 0x714",
|
||||
"0DF21470"),
|
||||
("xxxxxxxx VMOV S0, R0",
|
||||
"00EE100A"),
|
||||
("xxxxxxxx VMOV R2, R3, D0",
|
||||
"53EC102B"),
|
||||
("xxxxxxxx VCVT D0, S0",
|
||||
"B8EEC00B"),
|
||||
("xxxxxxxx VMOV R2, R3, D0",
|
||||
"53EC102B"),
|
||||
("xxxxxxxx VMOV D0, R0, R1",
|
||||
"41EC100B"),
|
||||
("xxxxxxxx VCVT S0, D0",
|
||||
"BDEEC00B"),
|
||||
("xxxxxxxx VSTR S0, [SP, 0x30]",
|
||||
"8DED0C0A"),
|
||||
("xxxxxxxx VSTR D0, [SP, 0x90]",
|
||||
"8DED240B"),
|
||||
("xxxxxxxx ADD R7, SP, 0xC",
|
||||
"03af"),
|
||||
("xxxxxxxx LDR R5, [PC, 0xF80]",
|
||||
"DFF8805F"),
|
||||
("xxxxxxxx LDR R1, [PC, 0xFFFFF970]",
|
||||
"5FF89016"),
|
||||
]
|
||||
print("#" * 40, 'armthumb', '#' * 40)
|
||||
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ import logging
|
|||
from future.utils import viewitems
|
||||
|
||||
from miasm.ir.symbexec import SymbolicExecutionEngine
|
||||
from miasm.arch.arm.arch import mn_arm as mn
|
||||
from miasm.arch.arm.arch import mn_arm, mn_armt
|
||||
from miasm.arch.arm.sem import Lifter_Arml as Lifter
|
||||
from miasm.arch.arm.regs import *
|
||||
from miasm.expression.expression import *
|
||||
|
|
@ -23,8 +23,14 @@ EXCLUDE_REGS = set([Lifter(loc_db).IRDst])
|
|||
def M(addr):
|
||||
return ExprMem(ExprInt(addr, 16), 16)
|
||||
|
||||
# compute for armt
|
||||
def compute_t(asm, inputstate={}, debug=False):
|
||||
return _compute(asm, mn_armt, inputstate, debug)
|
||||
|
||||
def compute(asm, inputstate={}, debug=False):
|
||||
return _compute(asm, mn_arm, inputstate, debug)
|
||||
|
||||
def _compute(asm, mn, inputstate={}, debug=False):
|
||||
loc_db = LocationDB()
|
||||
sympool = dict(regs_init)
|
||||
sympool.update({k: ExprInt(v, k.size) for k, v in viewitems(inputstate)})
|
||||
|
|
@ -546,6 +552,18 @@ class TestARMSemantic(unittest.TestCase):
|
|||
self.assertEqual(compute('SMLAL R2, R3, R4, R5', {R2: 0xffffffff, R3: 0x0, R4: 0x12345678, R5: 0x87654321}), {R2: 0x70b88d77, R3: 0xf76c768e, R4: 0x12345678, R5: 0x87654321})
|
||||
self.assertEqual(compute('SMLAL R2, R3, R4, R5', {R2: 0xffffffff, R3: 0x00000002, R4: 0x12345678, R5: 0x87654321}), {R2: 0x70b88d77, R3: 0xf76c7690, R4: 0x12345678, R5: 0x87654321})
|
||||
|
||||
def test_vmov(self):
|
||||
self.assertEqual(compute_t('VMOV S0, R0', {S0: 0x1, R0: 0x2}), {S0: 0x2, R0: 0x2})
|
||||
self.assertEqual(compute_t('VMOV R0, S0', {S0: 0x1, R0: 0x2}), {S0: 0x1, R0: 0x1})
|
||||
self.assertEqual(compute_t('VMOV D0, R0, R1', {D0: 0x1, R0: 0x2, R1:0x3}), {D0: 0x2 | (0x3 << 32), R0: 0x2, R1: 0x3})
|
||||
self.assertEqual(compute_t('VMOV R0, R1, D0', {D0: 0xfffffffcfffffffe, R0: 0x2, R1:0x3}), {D0: 0xfffffffcfffffffe, R0: 0xfffffffe, R1: 0xfffffffc})
|
||||
self.assertEqual(compute_t('VSTR S0, [SP, 0x30]',
|
||||
{S0: 0x10000, SP: 0x20000, ExprMem(ExprOp('preinc', ExprInt(0x20000, 32), ExprInt(0x30, 32)), 32): 0x50}),
|
||||
{S0: 0x10000, SP: 0x20000, ExprMem(ExprOp('preinc', ExprInt(0x20000, 32), ExprInt(0x30, 32)), 32): 0x10000})
|
||||
self.assertEqual(compute_t('VSTR D0, [SP, 0x30]',
|
||||
{D0: 0x1000000020000000, SP: 0x20000, ExprMem(ExprOp('preinc', ExprInt(0x20000, 32), ExprInt(0x30, 32)), 32): 0x50 , ExprMem(ExprOp('+', ExprOp('preinc', ExprInt(0x20000, 32), ExprInt(0x30, 32)), ExprInt(4, 32)), 32): 0x50}),
|
||||
{D0: 0x1000000020000000, SP: 0x20000, ExprMem(ExprOp('preinc', ExprInt(0x20000, 32), ExprInt(0x30, 32)), 32): 0x20000000, ExprMem(ExprOp('+', ExprOp('preinc', ExprInt(0x20000, 32), ExprInt(0x30, 32)), ExprInt(4, 32)), 32): 0x10000000})
|
||||
|
||||
if __name__ == '__main__':
|
||||
testsuite = unittest.TestLoader().loadTestsFromTestCase(TestARMSemantic)
|
||||
report = unittest.TextTestRunner(verbosity=2).run(testsuite)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue