diff options
Diffstat (limited to 'miasm2/arch/arm/sem.py')
| -rw-r--r-- | miasm2/arch/arm/sem.py | 288 |
1 files changed, 190 insertions, 98 deletions
diff --git a/miasm2/arch/arm/sem.py b/miasm2/arch/arm/sem.py index 2f00c56e..8f176947 100644 --- a/miasm2/arch/arm/sem.py +++ b/miasm2/arch/arm/sem.py @@ -117,7 +117,9 @@ def adc(ir, instr, a, b, c=None): e += update_flag_add(b, c, r) e.append(ExprAff(a, r)) dst = get_dst(a) - return dst, e + if dst is not None: + e.append(ExprAff(ir.IRDst, r)) + return e def add(ir, instr, a, b, c=None): @@ -130,7 +132,9 @@ def add(ir, instr, a, b, c=None): e += update_flag_add(b, c, r) e.append(ExprAff(a, r)) dst = get_dst(a) - return dst, e + if dst is not None: + e.append(ExprAff(ir.IRDst, r)) + return e def l_and(ir, instr, a, b, c=None): @@ -142,7 +146,9 @@ def l_and(ir, instr, a, b, c=None): e += update_flag_logic(r) e.append(ExprAff(a, r)) dst = get_dst(a) - return dst, e + if dst is not None: + e.append(ExprAff(ir.IRDst, r)) + return e def sub(ir, instr, a, b, c=None): @@ -152,7 +158,9 @@ def sub(ir, instr, a, b, c=None): r = b - c e.append(ExprAff(a, r)) dst = get_dst(a) - return dst, e + if dst is not None: + e.append(ExprAff(ir.IRDst, r)) + return e def subs(ir, instr, a, b, c=None): @@ -164,7 +172,9 @@ def subs(ir, instr, a, b, c=None): e += update_flag_sub(b, c, r) e.append(ExprAff(a, r)) dst = get_dst(a) - return dst, e + if dst is not None: + e.append(ExprAff(ir.IRDst, r)) + return e def eor(ir, instr, a, b, c=None): @@ -174,7 +184,9 @@ def eor(ir, instr, a, b, c=None): r = b ^ c e.append(ExprAff(a, r)) dst = get_dst(a) - return dst, e + if dst is not None: + e.append(ExprAff(ir.IRDst, r)) + return e def eors(ir, instr, a, b, c=None): @@ -185,7 +197,9 @@ def eors(ir, instr, a, b, c=None): e += update_flag_logic(r) e.append(ExprAff(a, r)) dst = get_dst(a) - return dst, e + if dst is not None: + e.append(ExprAff(ir.IRDst, r)) + return e def rsb(ir, instr, a, b, c=None): @@ -195,7 +209,9 @@ def rsb(ir, instr, a, b, c=None): r = c - b e.append(ExprAff(a, r)) dst = get_dst(a) - return dst, e + if dst is not None: + e.append(ExprAff(ir.IRDst, r)) + return e def rsbs(ir, instr, a, b, c=None): @@ -207,7 +223,9 @@ def rsbs(ir, instr, a, b, c=None): e += update_flag_sub(b, c, r) e.append(ExprAff(a, r)) dst = get_dst(a) - return dst, e + if dst is not None: + e.append(ExprAff(ir.IRDst, r)) + return e def sbc(ir, instr, a, b, c=None): @@ -217,7 +235,9 @@ def sbc(ir, instr, a, b, c=None): r = (b + cf.zeroExtend(32)) - (c + ExprInt32(1)) e.append(ExprAff(a, r)) dst = get_dst(a) - return dst, e + if dst is not None: + e.append(ExprAff(ir.IRDst, r)) + return e def sbcs(ir, instr, a, b, c=None): @@ -229,7 +249,9 @@ def sbcs(ir, instr, a, b, c=None): e += update_flag_sub(b, c, r) e.append(ExprAff(a, r)) dst = get_dst(a) - return dst, e + if dst is not None: + e.append(ExprAff(ir.IRDst, r)) + return e def rsc(ir, instr, a, b, c=None): @@ -239,7 +261,9 @@ def rsc(ir, instr, a, b, c=None): r = (c + cf.zeroExtend(32)) - (b + ExprInt32(1)) e.append(ExprAff(a, r)) dst = get_dst(a) - return dst, e + if dst is not None: + e.append(ExprAff(ir.IRDst, r)) + return e def rscs(ir, instr, a, b, c=None): @@ -252,7 +276,9 @@ def rscs(ir, instr, a, b, c=None): e += update_flag_sub(c, b, r) e.append(ExprAff(a, r)) dst = get_dst(a) - return dst, e + if dst is not None: + e.append(ExprAff(ir.IRDst, r)) + return e def tst(ir, instr, a, b, c=None): @@ -261,7 +287,7 @@ def tst(ir, instr, a, b, c=None): b, c = a, b r = b & c e += update_flag_logic(r) - return None, e + return e def teq(ir, instr, a, b, c=None): @@ -270,7 +296,7 @@ def teq(ir, instr, a, b, c=None): b, c = a, b r = b ^ c e += update_flag_logic(r) - return None, e + return e def l_cmp(ir, instr, a, b, c=None): @@ -280,7 +306,7 @@ def l_cmp(ir, instr, a, b, c=None): r = b - c e += update_flag_arith(r) e += update_flag_sub(c, b, r) - return None, e + return e def cmn(ir, instr, a, b, c=None): @@ -290,7 +316,7 @@ def cmn(ir, instr, a, b, c=None): r = b + c e += update_flag_arith(r) e += update_flag_add(b, c, r) - return None, e + return e def orr(ir, instr, a, b, c=None): @@ -300,7 +326,9 @@ def orr(ir, instr, a, b, c=None): r = b | c e.append(ExprAff(a, r)) dst = get_dst(a) - return dst, e + if dst is not None: + e.append(ExprAff(ir.IRDst, r)) + return e def orrs(ir, instr, a, b, c=None): @@ -311,19 +339,26 @@ def orrs(ir, instr, a, b, c=None): e += update_flag_logic(r) e.append(ExprAff(a, r)) dst = get_dst(a) - return dst, e + if dst is not None: + e.append(ExprAff(ir.IRDst, r)) + return e def mov(ir, instr, a, b): e = [ExprAff(a, b)] dst = get_dst(a) - return dst, e + if dst is not None: + e.append(ExprAff(ir.IRDst, b)) + return e def movt(ir, instr, a, b): - e = [ExprAff(a, a | b << ExprInt32(16))] + r = a | b << ExprInt32(16) + e = [ExprAff(a, r)] dst = get_dst(a) - return dst, e + if dst is not None: + e.append(ExprAff(ir.IRDst, r)) + return e def movs(ir, instr, a, b): @@ -332,13 +367,18 @@ def movs(ir, instr, a, b): # XXX TODO check e += update_flag_logic(b) dst = get_dst(a) - return dst, e + if dst is not None: + e.append(ExprAff(ir.IRDst, b)) + return e def mvn(ir, instr, a, b): - e = [ExprAff(a, b ^ ExprInt32(-1))] + r = b ^ ExprInt32(-1) + e = [ExprAff(a, r)] dst = get_dst(a) - return dst, e + if dst is not None: + e.append(ExprAff(ir.IRDst, r)) + return e def mvns(ir, instr, a, b): @@ -348,7 +388,9 @@ def mvns(ir, instr, a, b): # XXX TODO check e += update_flag_logic(r) dst = get_dst(a) - return dst, e + if dst is not None: + e.append(ExprAff(ir.IRDst, r)) + return e def neg(ir, instr, a, b): @@ -356,11 +398,13 @@ def neg(ir, instr, a, b): r = - b e.append(ExprAff(a, r)) dst = get_dst(a) - return dst, e + if dst is not None: + e.append(ExprAff(ir.IRDst, r)) + return e def negs(ir, instr, a, b): - dst, e = subs(ir, instr, a, ExprInt_from(b, 0), b) - return dst, e + e = subs(ir, instr, a, ExprInt_from(b, 0), b) + return e def bic(ir, instr, a, b, c=None): e = [] @@ -369,7 +413,9 @@ def bic(ir, instr, a, b, c=None): r = b & (c ^ ExprInt(uint32(-1))) e.append(ExprAff(a, r)) dst = get_dst(a) - return dst, e + if dst is not None: + e.append(ExprAff(ir.IRDst, r)) + return e def bics(ir, instr, a, b, c=None): @@ -380,7 +426,9 @@ def bics(ir, instr, a, b, c=None): e += update_flag_logic(r) e.append(ExprAff(a, r)) dst = get_dst(a) - return dst, e + if dst is not None: + e.append(ExprAff(ir.IRDst, r)) + return e def mla(ir, instr, a, b, c, d): @@ -388,7 +436,9 @@ def mla(ir, instr, a, b, c, d): r = (b * c) + d e.append(ExprAff(a, r)) dst = get_dst(a) - return dst, e + if dst is not None: + e.append(ExprAff(ir.IRDst, r)) + return e def mlas(ir, instr, a, b, c, d): @@ -397,7 +447,9 @@ def mlas(ir, instr, a, b, c, d): e += update_flag_zn(r) e.append(ExprAff(a, r)) dst = get_dst(a) - return dst, e + if dst is not None: + e.append(ExprAff(ir.IRDst, r)) + return e def mul(ir, instr, a, b, c = None): @@ -407,7 +459,9 @@ def mul(ir, instr, a, b, c = None): r = b * c e.append(ExprAff(a, r)) dst = get_dst(a) - return dst, e + if dst is not None: + e.append(ExprAff(ir.IRDst, r)) + return e def muls(ir, instr, a, b, c = None): @@ -418,35 +472,41 @@ def muls(ir, instr, a, b, c = None): e += update_flag_zn(r) e.append(ExprAff(a, r)) dst = get_dst(a) - return dst, e + if dst is not None: + e.append(ExprAff(ir.IRDst, r)) + return e def b(ir, instr, a): e = [] e.append(ExprAff(PC, a)) - return a, e + e.append(ExprAff(ir.IRDst, a)) + return e def bl(ir, instr, a): e = [] l = ExprInt32(instr.offset + instr.l) e.append(ExprAff(PC, a)) + e.append(ExprAff(ir.IRDst, a)) e.append(ExprAff(LR, l)) - return a, e + return e def bx(ir, instr, a): e = [] e.append(ExprAff(PC, a)) - return a, e + e.append(ExprAff(ir.IRDst, a)) + return e def blx(ir, instr, a): e = [] l = ExprInt32(instr.offset + instr.l) e.append(ExprAff(PC, a)) + e.append(ExprAff(ir.IRDst, a)) e.append(ExprAff(LR, l)) - return a, e + return e def st_ld_r(ir, instr, a, b, store=False, size=32, s_ext=False, z_ext=False): @@ -502,6 +562,7 @@ def st_ld_r(ir, instr, a, b, store=False, size=32, s_ext=False, z_ext=False): else: if a == PC: dst = PC + e.append(ExprAff(ir.IRDst, m)) e.append(ExprAff(a, m)) if dmem: e.append(ExprAff(a2, ExprMem(ad + ExprInt32(4), size=size))) @@ -509,7 +570,7 @@ def st_ld_r(ir, instr, a, b, store=False, size=32, s_ext=False, z_ext=False): # XXX TODO check multiple write cause by wb if wb or postinc: e.append(ExprAff(base, base + off)) - return dst, e + return e def ldr(ir, instr, a, b): @@ -517,8 +578,8 @@ def ldr(ir, instr, a, b): def ldrd(ir, instr, a, b): - dst, e = st_ld_r(ir, instr, a, b, store=False, size=64) - return dst, e + e = st_ld_r(ir, instr, a, b, store=False, size=64) + return e def l_str(ir, instr, a, b): @@ -526,38 +587,38 @@ def l_str(ir, instr, a, b): def l_strd(ir, instr, a, b): - dst, e = st_ld_r(ir, instr, a, b, store=True, size=64) - return dst, e + e = st_ld_r(ir, instr, a, b, store=True, size=64) + return e def ldrb(ir, instr, a, b): - dst, e = st_ld_r(ir, instr, a, b, store=False, size=8, z_ext=True) - return dst, e + e = st_ld_r(ir, instr, a, b, store=False, size=8, z_ext=True) + return e def ldrsb(ir, instr, a, b): - dst, e = st_ld_r( + e = st_ld_r( ir, instr, a, b, store=False, size=8, s_ext=True, z_ext=False) - return dst, e + return e def strb(ir, instr, a, b): - dst, e = st_ld_r(ir, instr, a, b, store=True, size=8) - return dst, e + e = st_ld_r(ir, instr, a, b, store=True, size=8) + return e def ldrh(ir, instr, a, b): - dst, e = st_ld_r(ir, instr, a, b, store=False, size=16, z_ext=True) - return dst, e + e = st_ld_r(ir, instr, a, b, store=False, size=16, z_ext=True) + return e def strh(ir, instr, a, b): - dst, e = st_ld_r(ir, instr, a, b, store=True, size=16, z_ext=True) - return dst, e + e = st_ld_r(ir, instr, a, b, store=True, size=16, z_ext=True) + return e def ldrsh(ir, instr, a, b): - dst, e = st_ld_r( + e = st_ld_r( ir, instr, a, b, store=False, size=16, s_ext=True, z_ext=False) - return dst, e + return e def st_ld_m(ir, instr, a, b, store=False, postinc=False, updown=False): @@ -588,6 +649,8 @@ def st_ld_m(ir, instr, a, b, store=False, postinc=False, updown=False): e.append(ExprAff(ExprMem(ad), r)) else: e.append(ExprAff(r, ExprMem(ad))) + if r == PC: + e.append(ExprAff(ir.IRDst, ExprMem(ad))) # XXX TODO check multiple write cause by wb if wb: if postinc: @@ -598,10 +661,8 @@ def st_ld_m(ir, instr, a, b, store=False, postinc=False, updown=False): pass else: assert(isinstance(b, ExprOp) and b.op == "reglist") - if PC in b.args: - dst = PC - return dst, e + return e def ldmia(ir, instr, a, b): @@ -640,13 +701,13 @@ def svc(ir, instr, a): # XXX TODO implement e = [ ExprAff(exception_flags, ExprInt32(EXCEPT_PRIV_INSN))] - return None, e + return e def und(ir, instr, a, b): # XXX TODO implement e = [] - return None, e + return e # TODO XXX implement correct CF for shifters def lsr(ir, instr, a, b, c = None): @@ -656,7 +717,9 @@ def lsr(ir, instr, a, b, c = None): r = b >> c e.append(ExprAff(a, r)) dst = get_dst(a) - return dst, e + if dst is not None: + e.append(ExprAff(ir.IRDst, r)) + return e def lsrs(ir, instr, a, b, c = None): @@ -667,7 +730,9 @@ def lsrs(ir, instr, a, b, c = None): e.append(ExprAff(a, r)) e += update_flag_logic(r) dst = get_dst(a) - return dst, e + if dst is not None: + e.append(ExprAff(ir.IRDst, r)) + return e def asr(ir, instr, a, b, c=None): e = [] @@ -676,7 +741,9 @@ def asr(ir, instr, a, b, c=None): r = ExprOp("a>>", b, c) e.append(ExprAff(a, r)) dst = get_dst(a) - return dst, e + if dst is not None: + e.append(ExprAff(ir.IRDst, r)) + return e def asrs(ir, instr, a, b, c): e = [] @@ -686,7 +753,9 @@ def asrs(ir, instr, a, b, c): e.append(ExprAff(a, r)) e += update_flag_logic(r) dst = get_dst(a) - return dst, e + if dst is not None: + e.append(ExprAff(ir.IRDst, r)) + return e def lsl(ir, instr, a, b, c = None): e = [] @@ -695,7 +764,9 @@ def lsl(ir, instr, a, b, c = None): r = b << c e.append(ExprAff(a, r)) dst = get_dst(a) - return dst, e + if dst is not None: + e.append(ExprAff(ir.IRDst, r)) + return e def lsls(ir, instr, a, b, c = None): @@ -706,7 +777,9 @@ def lsls(ir, instr, a, b, c = None): e.append(ExprAff(a, r)) e += update_flag_logic(r) dst = get_dst(a) - return dst, e + if dst is not None: + e.append(ExprAff(ir.IRDst, r)) + return e def push(ir, instr, a): @@ -717,80 +790,92 @@ def push(ir, instr, a): e.append(ExprAff(regs[i], ExprMem(r))) r = SP + ExprInt32(-4 * len(regs)) e.append(ExprAff(SP, r)) - return None, e + return e def pop(ir, instr, a): e = [] regs = list(a.args) + dst = None for i in xrange(len(regs)): r = SP + ExprInt32(4 * i) e.append(ExprAff(regs[i], ExprMem(r))) + if regs[i] == ir.pc: + dst = ExprMem(r) r = SP + ExprInt32(4 * len(regs)) e.append(ExprAff(SP, r)) - dst = None - if PC in a.get_r(): - dst = PC - return dst, e + if dst is not None: + e.append(ExprAff(ir.IRDst, dst)) + return e def cbz(ir, instr, a, b): e = [] lbl_next = ExprId(ir.get_next_label(instr), 32) - dst = ExprCond(a, lbl_next, b) - return dst, e + e.append(ExprAff(ir.IRDst, ExprCond(a, lbl_next, b))) + return e def cbnz(ir, instr, a, b): e = [] lbl_next = ExprId(ir.get_next_label(instr), 32) - dst = ExprCond(a, b, lbl_next) - return dst, e + e.append(ir.IRDst, ExprCond(a, b, lbl_next)) + return e def uxtb(ir, instr, a, b): e = [] - e.append(ExprAff(a, b[:8].zeroExtend(32))) + r = b[:8].zeroExtend(32) + e.append(ExprAff(a, r)) dst = None if PC in a.get_r(): dst = PC - return dst, e + e.append(ExprAff(ir.IRDst, r)) + return e def uxth(ir, instr, a, b): e = [] - e.append(ExprAff(a, b[:16].zeroExtend(32))) + r = b[:16].zeroExtend(32) + e.append(ExprAff(a, r)) dst = None if PC in a.get_r(): dst = PC - return dst, e + e.append(ExprAff(ir.IRDst, r)) + return e def sxtb(ir, instr, a, b): e = [] - e.append(ExprAff(a, b[:8].signExtend(32))) + r = b[:8].signExtend(32) + e.append(ExprAff(a, r)) dst = None if PC in a.get_r(): dst = PC - return dst, e + e.append(ExprAff(ir.IRDst, r)) + return e def sxth(ir, instr, a, b): e = [] - e.append(ExprAff(a, b[:16].signExtend(32))) + r = b[:16].signExtend(32) + e.append(ExprAff(a, r)) dst = None if PC in a.get_r(): dst = PC - return dst, e + e.append(ExprAff(ir.IRDst, r)) + return e def ubfx(ir, instr, a, b, c, d): e = [] c = int(c.arg) d = int(d.arg) - e.append(ExprAff(a, b[c:c+d].zeroExtend(32))) + r = b[c:c+d].zeroExtend(32) + e.append(ExprAff(a, r)) dst = None if PC in a.get_r(): dst = PC - return dst, e + e.append(ExprAff(ir.IRDst, r)) + return e @@ -864,10 +949,9 @@ def is_pc_written(ir, instr_ir): return False, None -def add_condition_expr(ir, instr, cond, instr_ir, dst): - # print "XXX", hex(instr.offset), instr +def add_condition_expr(ir, instr, cond, instr_ir): if cond == COND_AL: - return dst, instr_ir, [] + return instr_ir, [] if not cond in tab_cond: raise ValueError('unknown condition %r' % cond) cond = tab_cond[cond] @@ -878,10 +962,16 @@ def add_condition_expr(ir, instr, cond, instr_ir, dst): dst_cond = ExprCond(cond, lbl_do, lbl_next) assert(isinstance(instr_ir, list)) - if dst is None: - dst = lbl_next - e_do = irbloc(lbl_do.name, dst, [instr_ir]) - return dst_cond, [], [e_do] + has_irdst = False + for e in instr_ir: + if e.dst == ir.IRDst: + has_irdst = True + break + if not has_irdst: + instr_ir.append(ExprAff(ir.IRDst, lbl_next)) + e_do = irbloc(lbl_do.name, [instr_ir]) + e = [ExprAff(ir.IRDst, dst_cond)] + return e, [e_do] mnemo_func = {} mnemo_func_cond = {} @@ -1023,9 +1113,9 @@ def get_mnemo_expr(ir, instr, *args): if not instr.name.lower() in mnemo_func_cond: raise ValueError('unknown mnemo %s' % instr) cond, mf = mnemo_func_cond[instr.name.lower()] - dst, instr_ir = mf(ir, instr, *args) - dst, instr, extra_ir = add_condition_expr(ir, instr, cond, instr_ir, dst) - return dst, instr, extra_ir + instr_ir = mf(ir, instr, *args) + instr, extra_ir = add_condition_expr(ir, instr, cond, instr_ir) + return instr, extra_ir get_arm_instr_expr = get_mnemo_expr @@ -1041,6 +1131,7 @@ class ir_arm(ir): ir.__init__(self, mn_arm, "arm", symbol_pool) self.pc = PC self.sp = SP + self.IRDst = ExprId('IRDst', 32) def get_ir(self, instr): args = instr.args @@ -1053,7 +1144,7 @@ class ir_arm(ir): isinstance(args[-1].args[-1], ExprId)): args[-1].args = args[-1].args[:-1] + ( args[-1].args[-1][:8].zeroExtend(32),) - dst, instr_ir, extra_ir = get_mnemo_expr(self, instr, *args) + instr_ir, extra_ir = get_mnemo_expr(self, instr, *args) # if self.name.startswith('B'): # return instr_ir, extra_ir for i, x in enumerate(instr_ir): @@ -1067,7 +1158,7 @@ class ir_arm(ir): {self.pc: ExprInt32(instr.offset + 8)})) irs[i] = x # return out_ir, extra_ir - return dst, instr_ir, extra_ir + return instr_ir, extra_ir class ir_armt(ir): @@ -1076,6 +1167,7 @@ class ir_armt(ir): ir.__init__(self, mn_armt, "armt", symbol_pool) self.pc = PC self.sp = SP + self.IRDst = ExprId('IRDst', 32) def get_ir(self, instr): return get_mnemo_expr(self, instr, *instr.args) |