miasm2.arch.arm.sem module
from miasm2.expression.expression import * from miasm2.ir.ir import IntermediateRepresentation, IRBlock, AssignBlock from miasm2.arch.arm.arch import mn_arm, mn_armt from miasm2.arch.arm.regs import * from miasm2.jitter.csts import EXCEPT_DIV_BY_ZERO, EXCEPT_INT_XX # liris.cnrs.fr/~mmrissa/lib/exe/fetch.php?media=armv7-a-r-manual.pdf EXCEPT_SOFT_BP = (1 << 1) EXCEPT_PRIV_INSN = (1 << 17) # CPSR: N Z C V def update_flag_zf(a): return [ExprAff(zf, ExprOp("FLAG_EQ", a))] def update_flag_zf_eq(a, b): return [ExprAff(zf, ExprOp("FLAG_EQ_CMP", a, b))] def update_flag_nf(arg): return [ ExprAff( nf, ExprOp("FLAG_SIGN_SUB", arg, ExprInt(0, arg.size)) ) ] def update_flag_zn(a): e = [] e += update_flag_zf(a) e += update_flag_nf(a) return e # XXX TODO: set cf if ROT imm in argument def check_ops_msb(a, b, c): if not a or not b or not c or a != b or a != c: raise ValueError('bad ops size %s %s %s' % (a, b, c)) def update_flag_add_cf(op1, op2): "Compute cf in @op1 + @op2" return [ExprAff(cf, ExprOp("FLAG_ADD_CF", op1, op2))] def update_flag_add_of(op1, op2): "Compute of in @op1 + @op2" return [ExprAff(of, ExprOp("FLAG_ADD_OF", op1, op2))] def update_flag_sub_cf(op1, op2): "Compote CF in @op1 - @op2" return [ExprAff(cf, ExprOp("FLAG_SUB_CF", op1, op2) ^ ExprInt(1, 1))] def update_flag_sub_of(op1, op2): "Compote OF in @op1 - @op2" return [ExprAff(of, ExprOp("FLAG_SUB_OF", op1, op2))] def update_flag_arith_add_co(arg1, arg2): e = [] e += update_flag_add_cf(arg1, arg2) e += update_flag_add_of(arg1, arg2) return e def update_flag_arith_add_zn(arg1, arg2): """ Compute zf and nf flags for (arg1 + arg2) """ e = [] e += update_flag_zf_eq(arg1, -arg2) e += [ExprAff(nf, ExprOp("FLAG_SIGN_SUB", arg1, -arg2))] return e def update_flag_arith_sub_co(arg1, arg2): """ Compute cf and of flags for (arg1 - arg2) """ e = [] e += update_flag_sub_cf(arg1, arg2) e += update_flag_sub_of(arg1, arg2) return e def update_flag_arith_sub_zn(arg1, arg2): """ Compute zf and nf flags for (arg1 - arg2) """ e = [] e += update_flag_zf_eq(arg1, arg2) e += [ExprAff(nf, ExprOp("FLAG_SIGN_SUB", arg1, arg2))] return e def update_flag_zfaddwc_eq(arg1, arg2, arg3): return [ExprAff(zf, ExprOp("FLAG_EQ_ADDWC", arg1, arg2, arg3))] def update_flag_zfsubwc_eq(arg1, arg2, arg3): return [ExprAff(zf, ExprOp("FLAG_EQ_SUBWC", arg1, arg2, arg3))] def update_flag_arith_addwc_zn(arg1, arg2, arg3): """ Compute znp flags for (arg1 + arg2 + cf) """ e = [] e += update_flag_zfaddwc_eq(arg1, arg2, arg3) e += [ExprAff(nf, ExprOp("FLAG_SIGN_ADDWC", arg1, arg2, arg3))] return e def update_flag_arith_subwc_zn(arg1, arg2, arg3): """ Compute znp flags for (arg1 - (arg2 + cf)) """ e = [] e += update_flag_zfsubwc_eq(arg1, arg2, arg3) e += [ExprAff(nf, ExprOp("FLAG_SIGN_SUBWC", arg1, arg2, arg3))] return e def update_flag_addwc_cf(op1, op2, op3): "Compute cf in @res = @op1 + @op2 + @op3" return [ExprAff(cf, ExprOp("FLAG_ADDWC_CF", op1, op2, op3))] def update_flag_addwc_of(op1, op2, op3): "Compute of in @res = @op1 + @op2 + @op3" return [ExprAff(of, ExprOp("FLAG_ADDWC_OF", op1, op2, op3))] def update_flag_arith_addwc_co(arg1, arg2, arg3): e = [] e += update_flag_addwc_cf(arg1, arg2, arg3) e += update_flag_addwc_of(arg1, arg2, arg3) return e def update_flag_subwc_cf(op1, op2, op3): "Compute cf in @res = @op1 + @op2 + @op3" return [ExprAff(cf, ExprOp("FLAG_SUBWC_CF", op1, op2, op3) ^ ExprInt(1, 1))] def update_flag_subwc_of(op1, op2, op3): "Compute of in @res = @op1 + @op2 + @op3" return [ExprAff(of, ExprOp("FLAG_SUBWC_OF", op1, op2, op3))] def update_flag_arith_subwc_co(arg1, arg2, arg3): e = [] e += update_flag_subwc_cf(arg1, arg2, arg3) e += update_flag_subwc_of(arg1, arg2, arg3) return e def get_dst(a): if a == PC: return PC return None # instruction definition ############## def adc(ir, instr, a, b, c=None): e = [] if c is None: b, c = a, b arg1, arg2 = b, c r = b + c + cf.zeroExtend(32) if instr.name == 'ADCS' and a != PC: e += update_flag_arith_addwc_zn(arg1, arg2, cf) e += update_flag_arith_addwc_co(arg1, arg2, cf) e.append(ExprAff(a, r)) dst = get_dst(a) if dst is not None: e.append(ExprAff(ir.IRDst, r)) return e, [] def add(ir, instr, a, b, c=None): e = [] if c is None: b, c = a, b arg1, arg2 = b, c r = b + c if instr.name == 'ADDS' and a != PC: e += update_flag_arith_add_zn(arg1, arg2) e += update_flag_arith_add_co(arg1, arg2) e.append(ExprAff(a, r)) dst = get_dst(a) if dst is not None: e.append(ExprAff(ir.IRDst, r)) return e, [] def l_and(ir, instr, a, b, c=None): e = [] if c is None: b, c = a, b r = b & c if instr.name == 'ANDS' and a != PC: e += [ExprAff(zf, ExprOp('FLAG_EQ_AND', b, c))] e += update_flag_nf(r) e.append(ExprAff(a, r)) dst = get_dst(a) if dst is not None: e.append(ExprAff(ir.IRDst, r)) return e, [] def sub(ir, instr, a, b, c=None): e = [] if c is None: b, c = a, b r = b - c e.append(ExprAff(a, r)) dst = get_dst(a) if dst is not None: e.append(ExprAff(ir.IRDst, r)) return e, [] def subs(ir, instr, a, b, c=None): e = [] if c is None: b, c = a, b arg1, arg2 = b, c r = b - c e += update_flag_arith_sub_zn(arg1, arg2) e += update_flag_arith_sub_co(arg1, arg2) e.append(ExprAff(a, r)) dst = get_dst(a) if dst is not None: e.append(ExprAff(ir.IRDst, r)) return e, [] def eor(ir, instr, a, b, c=None): e = [] if c is None: b, c = a, b r = b ^ c e.append(ExprAff(a, r)) dst = get_dst(a) if dst is not None: e.append(ExprAff(ir.IRDst, r)) return e, [] def eors(ir, instr, a, b, c=None): e = [] if c is None: b, c = a, b arg1, arg2 = b, c r = arg1 ^ arg2 e += [ExprAff(zf, ExprOp('FLAG_EQ_CMP', arg1, arg2))] e += update_flag_nf(r) e.append(ExprAff(a, r)) dst = get_dst(a) if dst is not None: e.append(ExprAff(ir.IRDst, r)) return e, [] def rsb(ir, instr, a, b, c=None): e = [] if c is None: b, c = a, b r = c - b e.append(ExprAff(a, r)) dst = get_dst(a) if dst is not None: e.append(ExprAff(ir.IRDst, r)) return e, [] def rsbs(ir, instr, a, b, c=None): e = [] if c is None: b, c = a, b arg1, arg2 = c, b r = arg1 - arg2 e += update_flag_arith_sub_zn(arg1, arg2) e += update_flag_arith_sub_co(arg1, arg2) e.append(ExprAff(a, r)) dst = get_dst(a) if dst is not None: e.append(ExprAff(ir.IRDst, r)) return e, [] def sbc(ir, instr, a, b, c=None): e = [] if c is None: b, c = a, b arg1, arg2 = b, c r = arg1 - (arg2 + (~cf).zeroExtend(32)) e.append(ExprAff(a, r)) dst = get_dst(a) if dst is not None: e.append(ExprAff(ir.IRDst, r)) return e, [] def sbcs(ir, instr, a, b, c=None): e = [] if c is None: b, c = a, b arg1, arg2 = b, c r = arg1 - (arg2 + (~cf).zeroExtend(32)) e += update_flag_arith_subwc_zn(arg1, arg2, ~cf) e += update_flag_arith_subwc_co(arg1, arg2, ~cf) e.append(ExprAff(a, r)) dst = get_dst(a) if dst is not None: e.append(ExprAff(ir.IRDst, r)) return e, [] def rsc(ir, instr, a, b, c=None): e = [] if c is None: b, c = a, b arg1, arg2 = c, b r = arg1 - (arg2 + (~cf).zeroExtend(32)) e.append(ExprAff(a, r)) dst = get_dst(a) if dst is not None: e.append(ExprAff(ir.IRDst, r)) return e, [] def rscs(ir, instr, a, b, c=None): e = [] if c is None: b, c = a, b arg1, arg2 = c, b r = arg1 - (arg2 + (~cf).zeroExtend(32)) e += update_flag_arith_subwc_zn(arg1, arg2, ~cf) e += update_flag_arith_subwc_co(arg1, arg2, ~cf) e.append(ExprAff(a, r)) dst = get_dst(a) if dst is not None: e.append(ExprAff(ir.IRDst, r)) return e, [] def tst(ir, instr, a, b): e = [] arg1, arg2 = a, b r = arg1 & arg2 e += [ExprAff(zf, ExprOp('FLAG_EQ_AND', arg1, arg2))] e += update_flag_nf(r) return e, [] def teq(ir, instr, a, b, c=None): e = [] if c is None: b, c = a, b arg1, arg2 = b, c r = arg1 ^ arg2 e += [ExprAff(zf, ExprOp('FLAG_EQ_CMP', arg1, arg2))] e += update_flag_nf(r) return e, [] def l_cmp(ir, instr, a, b, c=None): e = [] if c is None: b, c = a, b arg1, arg2 = b, c r = b - c e += update_flag_arith_sub_zn(arg1, arg2) e += update_flag_arith_sub_co(arg1, arg2) return e, [] def cmn(ir, instr, a, b, c=None): e = [] if c is None: b, c = a, b arg1, arg2 = b, c r = b + c e += update_flag_arith_add_zn(arg1, arg2) e += update_flag_arith_add_co(arg1, arg2) return e, [] def orr(ir, instr, a, b, c=None): e = [] if c is None: b, c = a, b r = b | c e.append(ExprAff(a, r)) dst = get_dst(a) if dst is not None: e.append(ExprAff(ir.IRDst, r)) return e, [] def orn(ir, instr, a, b, c=None): e = [] if c is None: b, c = a, b r = ~(b | c) e.append(ExprAff(a, r)) dst = get_dst(a) if dst is not None: e.append(ExprAff(ir.IRDst, r)) return e, [] def orrs(ir, instr, a, b, c=None): e = [] if c is None: b, c = a, b arg1, arg2 = b, c r = b | c e += [ExprAff(zf, ExprOp('FLAG_EQ', r))] e += update_flag_nf(r) e.append(ExprAff(a, r)) dst = get_dst(a) 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) if dst is not None: e.append(ExprAff(ir.IRDst, b)) return e, [] def movt(ir, instr, a, b): r = a | b << ExprInt(16, 32) e = [ExprAff(a, r)] dst = get_dst(a) if dst is not None: e.append(ExprAff(ir.IRDst, r)) return e, [] def movs(ir, instr, a, b): e = [] e.append(ExprAff(a, b)) # XXX TODO check e += [ExprAff(zf, ExprOp('FLAG_EQ', b))] e += update_flag_nf(b) dst = get_dst(a) if dst is not None: e.append(ExprAff(ir.IRDst, b)) return e, [] def mvn(ir, instr, a, b): r = b ^ ExprInt(-1, 32) e = [ExprAff(a, r)] dst = get_dst(a) if dst is not None: e.append(ExprAff(ir.IRDst, r)) return e, [] def mvns(ir, instr, a, b): e = [] r = b ^ ExprInt(-1, 32) e.append(ExprAff(a, r)) # XXX TODO check e += [ExprAff(zf, ExprOp('FLAG_EQ', r))] e += update_flag_nf(r) dst = get_dst(a) if dst is not None: e.append(ExprAff(ir.IRDst, r)) return e, [] def mrs(ir, instr, a, b): e = [] if b.is_id('CPSR_cxsf'): out = [] out.append(ExprInt(0x10, 28)) out.append(of) out.append(cf) out.append(zf) out.append(nf) e.append(ExprAff(a, ExprCompose(*out))) else: raise NotImplementedError("MSR not implemented") return e, [] def msr(ir, instr, a, b): e = [] if a.is_id('CPSR_cf'): e.append(ExprAff(nf, b[31:32])) e.append(ExprAff(zf, b[30:31])) e.append(ExprAff(cf, b[29:30])) e.append(ExprAff(of, b[28:29])) else: raise NotImplementedError("MRS not implemented") return e, [] def neg(ir, instr, a, b): e = [] r = - b e.append(ExprAff(a, r)) dst = get_dst(a) if dst is not None: e.append(ExprAff(ir.IRDst, r)) return e, [] def negs(ir, instr, a, b): return subs(ir, instr, a, ExprInt(0, b.size), b) def bic(ir, instr, a, b, c=None): e = [] if c is None: b, c = a, b r = b & (c ^ ExprInt(-1, 32)) e.append(ExprAff(a, r)) dst = get_dst(a) if dst is not None: e.append(ExprAff(ir.IRDst, r)) return e, [] def bics(ir, instr, a, b, c=None): e = [] if c is None: b, c = a, b tmp1, tmp2 = b, ~c r = tmp1 & tmp2 e += [ExprAff(zf, ExprOp('FLAG_EQ_AND', tmp1, tmp2))] e += update_flag_nf(r) e.append(ExprAff(a, r)) dst = get_dst(a) if dst is not None: e.append(ExprAff(ir.IRDst, r)) return e, [] def sdiv(ir, instr, a, b, c=None): e = [] if c is None: b, c = a, b loc_div = ExprLoc(ir.loc_db.add_location(), ir.IRDst.size) loc_except = ExprId(ir.loc_db.add_location(), ir.IRDst.size) loc_next = ExprLoc(ir.get_next_loc_key(instr), ir.IRDst.size) e.append(ExprAff(ir.IRDst, ExprCond(c, loc_div, loc_except))) do_except = [] do_except.append(ExprAff(exception_flags, ExprInt(EXCEPT_DIV_BY_ZERO, exception_flags.size))) do_except.append(ExprAff(ir.IRDst, loc_next)) blk_except = IRBlock(loc_except.loc_key, [AssignBlock(do_except, instr)]) r = ExprOp("idiv", b, c) do_div = [] do_div.append(ExprAff(a, r)) dst = get_dst(a) if dst is not None: do_div.append(ExprAff(ir.IRDst, r)) do_div.append(ExprAff(ir.IRDst, loc_next)) blk_div = IRBlock(loc_div.loc_key, [AssignBlock(do_div, instr)]) return e, [blk_div, blk_except] def udiv(ir, instr, a, b, c=None): e = [] if c is None: b, c = a, b loc_div = ExprLoc(ir.loc_db.add_location(), ir.IRDst.size) loc_except = ExprLoc(ir.loc_db.add_location(), ir.IRDst.size) loc_next = ExprLoc(ir.get_next_loc_key(instr), ir.IRDst.size) e.append(ExprAff(ir.IRDst, ExprCond(c, loc_div, loc_except))) do_except = [] do_except.append(ExprAff(exception_flags, ExprInt(EXCEPT_DIV_BY_ZERO, exception_flags.size))) do_except.append(ExprAff(ir.IRDst, loc_next)) blk_except = IRBlock(loc_except.loc_key, [AssignBlock(do_except, instr)]) r = ExprOp("udiv", b, c) do_div = [] do_div.append(ExprAff(a, r)) dst = get_dst(a) if dst is not None: do_div.append(ExprAff(ir.IRDst, r)) do_div.append(ExprAff(ir.IRDst, loc_next)) blk_div = IRBlock(loc_div.loc_key, [AssignBlock(do_div, instr)]) return e, [blk_div, blk_except] def mla(ir, instr, a, b, c, d): e = [] r = (b * c) + d e.append(ExprAff(a, r)) dst = get_dst(a) if dst is not None: e.append(ExprAff(ir.IRDst, r)) return e, [] def mlas(ir, instr, a, b, c, d): e = [] r = (b * c) + d e += update_flag_zn(r) e.append(ExprAff(a, r)) dst = get_dst(a) if dst is not None: e.append(ExprAff(ir.IRDst, r)) return e, [] def mls(ir, instr, a, b, c, d): e = [] r = d - (b * c) e.append(ExprAff(a, r)) dst = get_dst(a) if dst is not None: e.append(ExprAff(ir.IRDst, r)) return e, [] def mul(ir, instr, a, b, c=None): e = [] if c is None: b, c = a, b r = b * c e.append(ExprAff(a, r)) dst = get_dst(a) if dst is not None: e.append(ExprAff(ir.IRDst, r)) return e, [] def muls(ir, instr, a, b, c=None): e = [] if c is None: b, c = a, b r = b * c e += update_flag_zn(r) e.append(ExprAff(a, r)) dst = get_dst(a) if dst is not None: e.append(ExprAff(ir.IRDst, r)) return e, [] def umull(ir, instr, a, b, c, d): e = [] r = c.zeroExtend(64) * d.zeroExtend(64) e.append(ExprAff(a, r[0:32])) e.append(ExprAff(b, r[32:64])) # r15/IRDst not allowed as output return e, [] def umlal(ir, instr, a, b, c, d): e = [] r = c.zeroExtend(64) * d.zeroExtend(64) + ExprCompose(a, b) e.append(ExprAff(a, r[0:32])) e.append(ExprAff(b, r[32:64])) # r15/IRDst not allowed as output return e, [] def smull(ir, instr, a, b, c, d): e = [] r = c.signExtend(64) * d.signExtend(64) e.append(ExprAff(a, r[0:32])) e.append(ExprAff(b, r[32:64])) # r15/IRDst not allowed as output return e, [] def smlal(ir, instr, a, b, c, d): e = [] r = c.signExtend(64) * d.signExtend(64) + ExprCompose(a, b) e.append(ExprAff(a, r[0:32])) e.append(ExprAff(b, r[32:64])) # r15/IRDst not allowed as output return e, [] def b(ir, instr, a): e = [] e.append(ExprAff(PC, a)) e.append(ExprAff(ir.IRDst, a)) return e, [] def bl(ir, instr, a): e = [] l = ExprInt(instr.offset + instr.l, 32) e.append(ExprAff(PC, a)) e.append(ExprAff(ir.IRDst, a)) e.append(ExprAff(LR, l)) return e, [] def bx(ir, instr, a): e = [] e.append(ExprAff(PC, a)) e.append(ExprAff(ir.IRDst, a)) return e, [] def blx(ir, instr, a): e = [] l = ExprInt(instr.offset + instr.l, 32) e.append(ExprAff(PC, a)) e.append(ExprAff(ir.IRDst, a)) e.append(ExprAff(LR, l)) return e, [] def st_ld_r(ir, instr, a, a2, b, store=False, size=32, s_ext=False, z_ext=False): e = [] wb = False b = b.copy() postinc = False b = b.arg if isinstance(b, ExprOp): if b.op == "wback": wb = True b = b.args[0] if b.op == "postinc": postinc = True if isinstance(b, ExprOp) and b.op in ["postinc", 'preinc']: # XXX TODO CHECK base, off = b.args[0], b.args[1] # ExprInt(size/8, 32) else: base, off = b, ExprInt(0, 32) if postinc: ad = base else: ad = base + off # PC base lookup uses PC 4 byte alignemnt ad = ad.replace_expr({PC: PC & ExprInt(0xFFFFFFFC, 32)}) dmem = False if size in [8, 16]: if store: a = a[:size] m = ExprMem(ad, size=size) elif s_ext: m = ExprMem(ad, size=size).signExtend(a.size) elif z_ext: m = ExprMem(ad, size=size).zeroExtend(a.size) else: raise ValueError('unhandled case') elif size == 32: m = ExprMem(ad, size=size) pass elif size == 64: assert a2 is not None m = ExprMem(ad, size=32) dmem = True size = 32 else: raise ValueError('the size DOES matter') dst = None if store: e.append(ExprAff(m, a)) if dmem: e.append(ExprAff(ExprMem(ad + ExprInt(4, 32), size=size), a2)) 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 + ExprInt(4, 32), size=size))) # XXX TODO check multiple write cause by wb if wb or postinc: e.append(ExprAff(base, base + off)) return e, [] def ldr(ir, instr, a, b): return st_ld_r(ir, instr, a, None, b, store=False) def ldrd(ir, instr, a, b, c=None): if c is None: a2 = ir.arch.regs.all_regs_ids[ir.arch.regs.all_regs_ids.index(a) + 1] else: a2 = b b = c return st_ld_r(ir, instr, a, a2, b, store=False, size=64) def l_str(ir, instr, a, b): return st_ld_r(ir, instr, a, None, b, store=True) def l_strd(ir, instr, a, b, c=None): if c is None: a2 = ir.arch.regs.all_regs_ids[ir.arch.regs.all_regs_ids.index(a) + 1] else: a2 = b b = c return st_ld_r(ir, instr, a, a2, b, store=True, size=64) def ldrb(ir, instr, a, b): return st_ld_r(ir, instr, a, None, b, store=False, size=8, z_ext=True) def ldrsb(ir, instr, a, b): return st_ld_r(ir, instr, a, None, b, store=False, size=8, s_ext=True, z_ext=False) def strb(ir, instr, a, b): return st_ld_r(ir, instr, a, None, b, store=True, size=8) def ldrh(ir, instr, a, b): return st_ld_r(ir, instr, a, None, b, store=False, size=16, z_ext=True) def strh(ir, instr, a, b): return st_ld_r(ir, instr, a, None, b, store=True, size=16, z_ext=True) def ldrsh(ir, instr, a, b): return st_ld_r(ir, instr, a, None, b, store=False, size=16, s_ext=True, z_ext=False) def st_ld_m(ir, instr, a, b, store=False, postinc=False, updown=False): e = [] wb = False dst = None if isinstance(a, ExprOp) and a.op == 'wback': wb = True a = a.args[0] if isinstance(b, ExprOp) and b.op == 'sbit': b = b.args[0] regs = b.args base = a if updown: step = 4 else: step = -4 regs = regs[::-1] if postinc: pass else: base += ExprInt(step, 32) for i, r in enumerate(regs): ad = base + ExprInt(i * step, 32) if store: e.append(ExprAff(ExprMem(ad, 32), r)) else: e.append(ExprAff(r, ExprMem(ad, 32))) if r == PC: e.append(ExprAff(ir.IRDst, ExprMem(ad, 32))) # XXX TODO check multiple write cause by wb if wb: if postinc: e.append(ExprAff(a, base + ExprInt(len(regs) * step, 32))) else: e.append(ExprAff(a, base + ExprInt((len(regs) - 1) * step, 32))) if store: pass else: assert(isinstance(b, ExprOp) and b.op == "reglist") return e, [] def ldmia(ir, instr, a, b): return st_ld_m(ir, instr, a, b, store=False, postinc=True, updown=True) def ldmib(ir, instr, a, b): return st_ld_m(ir, instr, a, b, store=False, postinc=False, updown=True) def ldmda(ir, instr, a, b): return st_ld_m(ir, instr, a, b, store=False, postinc=True, updown=False) def ldmdb(ir, instr, a, b): return st_ld_m(ir, instr, a, b, store=False, postinc=False, updown=False) def stmia(ir, instr, a, b): return st_ld_m(ir, instr, a, b, store=True, postinc=True, updown=True) def stmib(ir, instr, a, b): return st_ld_m(ir, instr, a, b, store=True, postinc=False, updown=True) def stmda(ir, instr, a, b): return st_ld_m(ir, instr, a, b, store=True, postinc=True, updown=False) def stmdb(ir, instr, a, b): return st_ld_m(ir, instr, a, b, store=True, postinc=False, updown=False) def svc(ir, instr, a): e = [] except_int = EXCEPT_INT_XX e.append(ExprAff(exception_flags, ExprInt(except_int, 32))) e.append(ExprAff(interrupt_num, a)) return e, [] def und(ir, instr, a, b): # XXX TODO implement e = [] return e, [] # TODO XXX implement correct CF for shifters def lsr(ir, instr, a, b, c=None): e = [] if c is None: b, c = a, b r = b >> c e.append(ExprAff(a, r)) dst = get_dst(a) if dst is not None: e.append(ExprAff(ir.IRDst, r)) return e, [] def lsrs(ir, instr, a, b, c=None): e = [] if c is None: b, c = a, b r = b >> c e.append(ExprAff(a, r)) e += [ExprAff(zf, ExprOp('FLAG_EQ', r))] e += update_flag_nf(r) dst = get_dst(a) if dst is not None: e.append(ExprAff(ir.IRDst, r)) return e, [] def asr(ir, instr, a, b, c=None): e = [] if c is None: b, c = a, b r = ExprOp("a>>", b, c) e.append(ExprAff(a, r)) dst = get_dst(a) if dst is not None: e.append(ExprAff(ir.IRDst, r)) return e, [] def asrs(ir, instr, a, b, c=None): e = [] if c is None: b, c = a, b r = ExprOp("a>>", b, c) e.append(ExprAff(a, r)) e += [ExprAff(zf, ExprOp('FLAG_EQ', r))] e += update_flag_nf(r) dst = get_dst(a) if dst is not None: e.append(ExprAff(ir.IRDst, r)) return e, [] def lsl(ir, instr, a, b, c=None): e = [] if c is None: b, c = a, b r = b << c e.append(ExprAff(a, r)) dst = get_dst(a) if dst is not None: e.append(ExprAff(ir.IRDst, r)) return e, [] def lsls(ir, instr, a, b, c=None): e = [] if c is None: b, c = a, b r = b << c e.append(ExprAff(a, r)) e += [ExprAff(zf, ExprOp('FLAG_EQ', r))] e += update_flag_nf(r) dst = get_dst(a) if dst is not None: e.append(ExprAff(ir.IRDst, r)) return e, [] def rors(ir, instr, a, b): e = [] r = ExprOp(">>>", a, b) e.append(ExprAff(a, r)) e += [ExprAff(zf, ExprOp('FLAG_EQ', r))] e += update_flag_nf(r) dst = get_dst(a) if dst is not None: e.append(ExprAff(ir.IRDst, r)) return e, [] def push(ir, instr, a): e = [] regs = list(a.args) for i in xrange(len(regs)): r = SP + ExprInt(-4 * len(regs) + 4 * i, 32) e.append(ExprAff(ExprMem(r, 32), regs[i])) r = SP + ExprInt(-4 * len(regs), 32) e.append(ExprAff(SP, r)) return e, [] def pop(ir, instr, a): e = [] regs = list(a.args) dst = None for i in xrange(len(regs)): r = SP + ExprInt(4 * i, 32) e.append(ExprAff(regs[i], ExprMem(r, 32))) if regs[i] == ir.pc: dst = ExprMem(r, 32) r = SP + ExprInt(4 * len(regs), 32) e.append(ExprAff(SP, r)) if dst is not None: e.append(ExprAff(ir.IRDst, dst)) return e, [] def cbz(ir, instr, a, b): e = [] loc_next = ir.get_next_loc_key(instr) loc_next_expr = ExprLoc(loc_next, 32) e.append(ExprAff(ir.IRDst, ExprCond(a, loc_next_expr, b))) return e, [] def cbnz(ir, instr, a, b): e = [] loc_next = ir.get_next_loc_key(instr) loc_next_expr = ExprLoc(loc_next, 32) e.append(ir.IRDst, ExprCond(a, b, loc_next_expr)) return e, [] def uxtb(ir, instr, a, b): e = [] r = b[:8].zeroExtend(32) e.append(ExprAff(a, r)) dst = None if PC in a.get_r(): dst = PC e.append(ExprAff(ir.IRDst, r)) return e, [] def uxth(ir, instr, a, b): e = [] r = b[:16].zeroExtend(32) e.append(ExprAff(a, r)) dst = None if PC in a.get_r(): dst = PC e.append(ExprAff(ir.IRDst, r)) return e, [] def sxtb(ir, instr, a, b): e = [] r = b[:8].signExtend(32) e.append(ExprAff(a, r)) dst = None if PC in a.get_r(): dst = PC e.append(ExprAff(ir.IRDst, r)) return e, [] def sxth(ir, instr, a, b): e = [] r = b[:16].signExtend(32) e.append(ExprAff(a, r)) dst = None if PC in a.get_r(): dst = PC e.append(ExprAff(ir.IRDst, r)) return e, [] def ubfx(ir, instr, a, b, c, d): e = [] c = int(c) d = int(d) r = b[c:c+d].zeroExtend(32) e.append(ExprAff(a, r)) dst = None if PC in a.get_r(): dst = PC e.append(ExprAff(ir.IRDst, r)) return e, [] def bfc(ir, instr, a, b, c): e = [] start = int(b) stop = start + int(c) out = [] last = 0 if start: out.append(a[:start]) last = start if stop - start: out.append(ExprInt(0, 32)[last:stop]) last = stop if last < 32: out.append(a[last:]) r = ExprCompose(*out) e.append(ExprAff(a, r)) dst = None if PC in a.get_r(): dst = PC e.append(ExprAff(ir.IRDst, r)) return e, [] def rev(ir, instr, a, b): e = [] c = ExprCompose(b[24:32], b[16:24], b[8:16], b[:8]) e.append(ExprAff(a, c)) return e, [] def pld(ir, instr, a): e = [] return e, [] def pldw(ir, instr, a): e = [] return e, [] def clz(ir, instr, a, b): e = [] e.append(ExprAff(a, ExprOp('cntleadzeros', b))) return e, [] def uxtab(ir, instr, a, b, c): e = [] e.append(ExprAff(a, b + (c & ExprInt(0xff, 32)))) return e, [] def bkpt(ir, instr, a): e = [] e.append(ExprAff(exception_flags, ExprInt(EXCEPT_SOFT_BP, 32))) e.append(ExprAff(bp_num, a)) return e, [] def _extract_s16(arg, part): if part == 'B': # bottom 16 bits return arg[0:16] elif part == 'T': # top 16 bits return arg[16:32] def smul(ir, instr, a, b, c): e = [] e.append(ExprAff(a, _extract_s16(b, instr.name[4]).signExtend(32) * _extract_s16(c, instr.name[5]).signExtend(32))) return e, [] def smulw(ir, instr, a, b, c): e = [] prod = b.signExtend(48) * _extract_s16(c, instr.name[5]).signExtend(48) e.append(ExprAff(a, prod[16:48])) return e, [] # signed most significant 32 bits of the 48-bit result def tbb(ir, instr, a): e = [] dst = PC + ExprInt(2, 32) * a.zeroExtend(32) e.append(ExprAff(PC, dst)) e.append(ExprAff(ir.IRDst, dst)) return e, [] def tbh(ir, instr, a): e = [] dst = PC + ExprInt(2, 32) * a.zeroExtend(32) e.append(ExprAff(PC, dst)) e.append(ExprAff(ir.IRDst, dst)) return e, [] def smlabb(ir, instr, a, b, c, d): e = [] result = (b[:16].signExtend(32) * c[:16].signExtend(32)) + d e.append(ExprAff(a, result)) return e, [] def smlabt(ir, instr, a, b, c, d): e = [] result = (b[:16].signExtend(32) * c[16:32].signExtend(32)) + d e.append(ExprAff(a, result)) return e, [] def smlatb(ir, instr, a, b, c, d): e = [] result = (b[16:32].signExtend(32) * c[:16].signExtend(32)) + d e.append(ExprAff(a, result)) return e, [] def smlatt(ir, instr, a, b, c, d): e = [] result = (b[16:32].signExtend(32) * c[16:32].signExtend(32)) + d e.append(ExprAff(a, result)) return e, [] def uadd8(ir, instr, a, b, c): e = [] sums = [] ges = [] for i in xrange(0, 32, 8): sums.append(b[i:i+8] + c[i:i+8]) ges.append((b[i:i+8].zeroExtend(9) + c[i:i+8].zeroExtend(9))[8:9]) e.append(ExprAff(a, ExprCompose(*sums))) for i, value in enumerate(ges): e.append(ExprAff(ge_regs[i], value)) return e, [] def sel(ir, instr, a, b, c): e = [] cond = nf ^ of ^ ExprInt(1, 1) parts = [] for i in xrange(4): parts.append(ExprCond(ge_regs[i], b[i*8:(i+1)*8], c[i*8:(i+1)*8])) result = ExprCompose(*parts) e.append(ExprAff(a, result)) return e, [] def rev(ir, instr, a, b): e = [] result = ExprCompose(b[24:32], b[16:24], b[8:16], b[:8]) e.append(ExprAff(a, result)) return e, [] def nop(ir, instr): e = [] return e, [] def dsb(ir, instr, a): # XXX TODO e = [] return e, [] def cpsie(ir, instr, a): # XXX TODO e = [] return e, [] def cpsid(ir, instr, a): # XXX TODO e = [] return e, [] def wfe(ir, instr): # XXX TODO e = [] return e, [] def wfi(ir, instr): # XXX TODO e = [] return e, [] COND_EQ = 0 COND_NE = 1 COND_CS = 2 COND_CC = 3 COND_MI = 4 COND_PL = 5 COND_VS = 6 COND_VC = 7 COND_HI = 8 COND_LS = 9 COND_GE = 10 COND_LT = 11 COND_GT = 12 COND_LE = 13 COND_AL = 14 COND_NV = 15 cond_dct = { COND_EQ: "EQ", COND_NE: "NE", COND_CS: "CS", COND_CC: "CC", COND_MI: "MI", COND_PL: "PL", COND_VS: "VS", COND_VC: "VC", COND_HI: "HI", COND_LS: "LS", COND_GE: "GE", COND_LT: "LT", COND_GT: "GT", COND_LE: "LE", COND_AL: "AL", # COND_NV: "NV", } cond_dct_inv = dict((name, num) for num, name in cond_dct.iteritems()) """ Code Meaning (for cmp or subs) Flags Tested eq Equal. Z==1 ne Not equal. Z==0 cs or hs Unsigned higher or same (or carry set). C==1 cc or lo Unsigned lower (or carry clear). C==0 mi Negative. The mnemonic stands for "minus". N==1 pl Positive or zero. The mnemonic stands for "plus". N==0 vs Signed overflow. The mnemonic stands for "V set". V==1 vc No signed overflow. The mnemonic stands for "V clear". V==0 hi Unsigned higher. (C==1) && (Z==0) ls Unsigned lower or same. (C==0) || (Z==1) ge Signed greater than or equal. N==V lt Signed less than. N!=V gt Signed greater than. (Z==0) && (N==V) le Signed less than or equal. (Z==1) || (N!=V) al (or omitted) Always executed. None tested. """ tab_cond = {COND_EQ: ExprOp("CC_EQ", zf), COND_NE: ExprOp("CC_NE", zf), COND_CS: ExprOp("CC_U>=", cf ^ ExprInt(1, 1)), # inv cf COND_CC: ExprOp("CC_U<", cf ^ ExprInt(1, 1)), # inv cf COND_MI: ExprOp("CC_NEG", nf), COND_PL: ExprOp("CC_POS", nf), COND_VS: ExprOp("CC_sOVR", of), COND_VC: ExprOp("CC_sNOOVR", of), COND_HI: ExprOp("CC_U>", cf ^ ExprInt(1, 1), zf), # inv cf COND_LS: ExprOp("CC_U<=", cf ^ ExprInt(1, 1), zf), # inv cf COND_GE: ExprOp("CC_S>=", nf, of), COND_LT: ExprOp("CC_S<", nf, of), COND_GT: ExprOp("CC_S>", nf, of, zf), COND_LE: ExprOp("CC_S<=", nf, of, zf), } def is_pc_written(ir, instr_ir): all_pc = ir.mn.pc.values() for ir in instr_ir: if ir.dst in all_pc: return True, ir.dst return False, None def add_condition_expr(ir, instr, cond, instr_ir, extra_ir): if cond == COND_AL: return instr_ir, extra_ir if not cond in tab_cond: raise ValueError('unknown condition %r' % cond) cond = tab_cond[cond] loc_next = ir.get_next_loc_key(instr) loc_next_expr = ExprLoc(loc_next, 32) loc_do = ir.loc_db.add_location() loc_do_expr = ExprLoc(loc_do, 32) dst_cond = ExprCond(cond, loc_do_expr, loc_next_expr) assert(isinstance(instr_ir, list)) 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, loc_next_expr)) e_do = IRBlock(loc_do, [AssignBlock(instr_ir, instr)]) e = [ExprAff(ir.IRDst, dst_cond)] return e, [e_do] + extra_ir mnemo_func = {} mnemo_func_cond = {} mnemo_condm0 = {'add': add, 'sub': sub, 'eor': eor, 'and': l_and, 'rsb': rsb, 'adc': adc, 'sbc': sbc, 'rsc': rsc, 'tst': tst, 'teq': teq, 'cmp': l_cmp, 'cmn': cmn, 'orr': orr, 'mov': mov, 'movt': movt, 'bic': bic, 'mvn': mvn, 'neg': neg, 'sdiv': sdiv, 'udiv': udiv, 'mul': mul, 'umull': umull, 'umlal': umlal, 'smull': smull, 'smlal': smlal, 'mla': mla, 'ldr': ldr, 'ldrd': ldrd, 'str': l_str, 'strd': l_strd, 'b': b, 'bl': bl, 'svc': svc, 'und': und, 'bx': bx, 'ldrh': ldrh, 'strh': strh, 'ldrsh': ldrsh, 'ldsh': ldrsh, 'uxtb': uxtb, 'uxth': uxth, 'sxtb': sxtb, 'sxth': sxth, 'ubfx': ubfx, 'bfc': bfc, 'rev': rev, 'clz': clz, 'uxtab': uxtab, 'bkpt': bkpt, 'smulbb': smul, 'smulbt': smul, 'smultb': smul, 'smultt': smul, 'smulwt': smulw, 'smulwb': smulw, } mnemo_condm1 = {'adds': add, 'subs': subs, 'eors': eors, 'ands': l_and, 'rsbs': rsbs, 'adcs': adc, 'sbcs': sbcs, 'rscs': rscs, 'orrs': orrs, 'movs': movs, 'bics': bics, 'mvns': mvns, 'mrs': mrs, 'msr': msr, 'negs': negs, 'muls': muls, 'mls': mls, 'mlas': mlas, 'blx': blx, 'ldrb': ldrb, 'ldrsb': ldrsb, 'ldsb': ldrsb, 'strb': strb, } mnemo_condm2 = {'ldmia': ldmia, 'ldmib': ldmib, 'ldmda': ldmda, 'ldmdb': ldmdb, 'ldmfa': ldmda, 'ldmfd': ldmia, 'ldmea': ldmdb, 'ldmed': ldmib, # XXX 'stmia': stmia, 'stmib': stmib, 'stmda': stmda, 'stmdb': stmdb, 'stmfa': stmib, 'stmed': stmda, 'stmfd': stmdb, 'stmea': stmia, } mnemo_nocond = {'lsr': lsr, 'lsrs': lsrs, 'lsl': lsl, 'lsls': lsls, 'rors': rors, 'push': push, 'pop': pop, 'asr': asr, 'asrs': asrs, 'cbz': cbz, 'cbnz': cbnz, 'pld': pld, 'pldw': pldw, 'tbb': tbb, 'tbh': tbh, 'nop': nop, 'dsb': dsb, 'cpsie': cpsie, 'cpsid': cpsid, 'wfe': wfe, 'wfi': wfi, 'orn': orn, 'smlabb': smlabb, 'smlabt': smlabt, 'smlatb': smlatb, 'smlatt': smlatt, 'uadd8': uadd8, 'sel': sel, } mn_cond_x = [mnemo_condm0, mnemo_condm1, mnemo_condm2] for index, mn_base in enumerate(mn_cond_x): for mn, mf in mn_base.items(): for cond, cn in cond_dct.items(): if cond == COND_AL: cn = "" cn = cn.lower() if index == 0: mn_mod = mn + cn else: mn_mod = mn[:-index] + cn + mn[-index:] # print mn_mod mnemo_func_cond[mn_mod] = cond, mf for name, mf in mnemo_nocond.items(): mnemo_func_cond[name] = COND_AL, mf def split_expr_dst(ir, instr_ir): out = [] dst = None for i in instr_ir: if i.dst == ir.pc: out.append(i) dst = ir.pc # i.src else: out.append(i) return out, dst 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()] instr_ir, extra_ir = mf(ir, instr, *args) instr, extra_ir = add_condition_expr(ir, instr, cond, instr_ir, extra_ir) return instr, extra_ir get_arm_instr_expr = get_mnemo_expr class arminfo: mode = "arm" # offset class ir_arml(IntermediateRepresentation): def __init__(self, loc_db=None): IntermediateRepresentation.__init__(self, mn_arm, "l", loc_db) self.pc = PC self.sp = SP self.IRDst = ExprId('IRDst', 32) self.addrsize = 32 def mod_pc(self, instr, instr_ir, extra_ir): # fix PC (+8 for arm) pc_fixed = {self.pc: ExprInt(instr.offset + 8, 32)} for i, expr in enumerate(instr_ir): dst, src = expr.dst, expr.src if dst != self.pc: dst = dst.replace_expr(pc_fixed) src = src.replace_expr(pc_fixed) instr_ir[i] = ExprAff(dst, src) for idx, irblock in enumerate(extra_ir): extra_ir[idx] = irblock.modify_exprs(lambda expr: expr.replace_expr(pc_fixed) \ if expr != self.pc else expr, lambda expr: expr.replace_expr(pc_fixed)) def get_ir(self, instr): args = instr.args # ir = get_mnemo_expr(self, self.name.lower(), *args) if len(args) and isinstance(args[-1], ExprOp): if args[-1].op == 'rrx': args[-1] = ExprCompose(args[-1].args[0][1:], cf) elif (args[-1].op in ['<<', '>>', '<<a', 'a>>', '<<<', '>>>'] and isinstance(args[-1].args[-1], ExprId)): args[-1] = ExprOp(args[-1].op, args[-1].args[0], args[-1].args[-1][:8].zeroExtend(32)) instr_ir, extra_ir = get_mnemo_expr(self, instr, *args) self.mod_pc(instr, instr_ir, extra_ir) return instr_ir, extra_ir def parse_itt(self, instr): name = instr.name assert name.startswith('IT') name = name[1:] out = [] for hint in name: if hint == 'T': out.append(0) elif hint == "E": out.append(1) else: raise ValueError("IT name invalid %s" % instr) return out, instr.args[0] def do_it_block(self, loc, index, block, assignments, gen_pc_updt): instr = block.lines[index] it_hints, it_cond = self.parse_itt(instr) cond_num = cond_dct_inv[it_cond.name] cond_eq = tab_cond[cond_num] if not index + len(it_hints) <= len(block.lines): raise NotImplementedError("Splitted IT block non supported yet") ir_blocks_all = [] # Gen dummy irblock for IT instr loc_next = self.get_next_loc_key(instr) dst = ExprAff(self.IRDst, ExprId(loc_next, 32)) dst_blk = AssignBlock([dst], instr) assignments.append(dst_blk) irblock = IRBlock(loc, assignments) ir_blocks_all.append([irblock]) loc = loc_next assignments = [] for hint in it_hints: irblocks = [] index += 1 instr = block.lines[index] # Add conditionnal jump to current irblock loc_do = self.loc_db.add_location() loc_next = self.get_next_loc_key(instr) if hint: local_cond = ~cond_eq else: local_cond = cond_eq dst = ExprAff(self.IRDst, ExprCond(local_cond, ExprLoc(loc_do, 32), ExprLoc(loc_next, 32))) dst_blk = AssignBlock([dst], instr) assignments.append(dst_blk) irblock = IRBlock(loc, assignments) irblocks.append(irblock) assignments = [] loc = loc_do split = self.add_instr_to_current_state( instr, block, assignments, irblocks, gen_pc_updt ) if split: raise NotImplementedError("Unsupported instr in IT block (%s)" % instr) dst = ExprAff(self.IRDst, ExprId(loc_next, 32)) dst_blk = AssignBlock([dst], instr) assignments.append(dst_blk) irblock = IRBlock(loc, assignments) irblocks.append(irblock) loc = loc_next assignments = [] ir_blocks_all.append(irblocks) return index, ir_blocks_all def add_asmblock_to_ircfg(self, block, ircfg, gen_pc_updt=False): """ Add a native block to the current IR @block: native assembly block @gen_pc_updt: insert PC update effects between instructions """ it_hints = None it_cond = None label = block.loc_key assignments = [] ir_blocks_all = [] index = -1 while index + 1 < len(block.lines): index += 1 instr = block.lines[index] if label is None: assignments = [] label = self.get_loc_key_for_instr(instr) if instr.name.startswith("IT"): index, irblocks_it = self.do_it_block(label, index, block, assignments, gen_pc_updt) for irblocks in irblocks_it: ir_blocks_all += irblocks label = None continue split = self.add_instr_to_current_state( instr, block, assignments, ir_blocks_all, gen_pc_updt ) if split: ir_blocks_all.append(IRBlock(label, assignments)) label = None assignments = [] if label is not None: ir_blocks_all.append(IRBlock(label, assignments)) new_ir_blocks_all = self.post_add_asmblock_to_ircfg(block, ircfg, ir_blocks_all) for irblock in new_ir_blocks_all: ircfg.add_irblock(irblock) return new_ir_blocks_all class ir_armb(ir_arml): def __init__(self, loc_db=None): IntermediateRepresentation.__init__(self, mn_arm, "b", loc_db) self.pc = PC self.sp = SP self.IRDst = ExprId('IRDst', 32) self.addrsize = 32 class ir_armtl(ir_arml): def __init__(self, loc_db=None): IntermediateRepresentation.__init__(self, mn_armt, "l", loc_db) self.pc = PC self.sp = SP self.IRDst = ExprId('IRDst', 32) self.addrsize = 32 def mod_pc(self, instr, instr_ir, extra_ir): # fix PC (+4 for thumb) pc_fixed = {self.pc: ExprInt(instr.offset + 4, 32)} for i, expr in enumerate(instr_ir): dst, src = expr.dst, expr.src if dst != self.pc: dst = dst.replace_expr(pc_fixed) src = src.replace_expr(pc_fixed) instr_ir[i] = ExprAff(dst, src) for idx, irblock in enumerate(extra_ir): extra_ir[idx] = irblock.modify_exprs(lambda expr: expr.replace_expr(pc_fixed) \ if expr != self.pc else expr, lambda expr: expr.replace_expr(pc_fixed)) class ir_armtb(ir_armtl): def __init__(self, loc_db=None): IntermediateRepresentation.__init__(self, mn_armt, "b", loc_db) self.pc = PC self.sp = SP self.IRDst = ExprId('IRDst', 32) self.addrsize = 32
Module variables
var COND_AL
var COND_CC
var COND_CS
var COND_EQ
var COND_GE
var COND_GT
var COND_HI
var COND_LE
var COND_LS
var COND_LT
var COND_MI
var COND_NE
var COND_NV
var COND_PL
var COND_VC
var COND_VS
var EXCEPT_DIV_BY_ZERO
var EXCEPT_INT_XX
var EXCEPT_PRIV_INSN
var EXCEPT_SOFT_BP
var EXPRAFF
var EXPRCOMPOSE
var EXPRCOND
var EXPRID
var EXPRINT
var EXPRLOC
var EXPRMEM
var EXPROP
var EXPRSLICE
var EXPR_ORDER_DICT
var PRIORITY_MAX
var TOK_EQUAL
var TOK_INF
var TOK_INF_EQUAL
var TOK_INF_EQUAL_SIGNED
var TOK_INF_EQUAL_UNSIGNED
var TOK_INF_SIGNED
var TOK_INF_UNSIGNED
var TOK_POS
var TOK_POS_STRICT
var all_regs_ids
var all_regs_ids_byname
var all_regs_ids_init
var all_regs_ids_no_alias
var attrib_to_regs
var cn
var cond
var cond_dct
var cond_dct_inv
Code Meaning (for cmp or subs) Flags Tested eq Equal. Z==1 ne Not equal. Z==0 cs or hs Unsigned higher or same (or carry set). C==1 cc or lo Unsigned lower (or carry clear). C==0 mi Negative. The mnemonic stands for "minus". N==1 pl Positive or zero. The mnemonic stands for "plus". N==0 vs Signed overflow. The mnemonic stands for "V set". V==1 vc No signed overflow. The mnemonic stands for "V clear". V==0 hi Unsigned higher. (C==1) && (Z==0) ls Unsigned lower or same. (C==0) || (Z==1) ge Signed greater than or equal. N==V lt Signed less than. N!=V gt Signed greater than. (Z==0) && (N==V) le Signed less than or equal. (Z==1) || (N!=V) al (or omitted) Always executed. None tested.
var ge_regs
var i
var index
var mn
var mn_base
var mn_cond_x
var mn_mod
var mnemo_condm0
var mnemo_condm1
var mnemo_condm2
var mnemo_func
var mnemo_func_cond
var mnemo_nocond
var mod_size2uint
var name
var priorities
var priorities_list
var reg_cf
var reg_ge0
var reg_ge1
var reg_ge2
var reg_ge3
var reg_nf
var reg_of
var reg_zf
var regs32_expr
var regs32_str
var regs_flt_expr
var regs_init
var size_to_IEEE754_info
var tab_cond
Functions
def adc(
ir, instr, a, b, c=None)
def adc(ir, instr, a, b, c=None): e = [] if c is None: b, c = a, b arg1, arg2 = b, c r = b + c + cf.zeroExtend(32) if instr.name == 'ADCS' and a != PC: e += update_flag_arith_addwc_zn(arg1, arg2, cf) e += update_flag_arith_addwc_co(arg1, arg2, cf) e.append(ExprAff(a, r)) dst = get_dst(a) if dst is not None: e.append(ExprAff(ir.IRDst, r)) return e, []
def add(
ir, instr, a, b, c=None)
def add(ir, instr, a, b, c=None): e = [] if c is None: b, c = a, b arg1, arg2 = b, c r = b + c if instr.name == 'ADDS' and a != PC: e += update_flag_arith_add_zn(arg1, arg2) e += update_flag_arith_add_co(arg1, arg2) e.append(ExprAff(a, r)) dst = get_dst(a) if dst is not None: e.append(ExprAff(ir.IRDst, r)) return e, []
def add_condition_expr(
ir, instr, cond, instr_ir, extra_ir)
def add_condition_expr(ir, instr, cond, instr_ir, extra_ir): if cond == COND_AL: return instr_ir, extra_ir if not cond in tab_cond: raise ValueError('unknown condition %r' % cond) cond = tab_cond[cond] loc_next = ir.get_next_loc_key(instr) loc_next_expr = ExprLoc(loc_next, 32) loc_do = ir.loc_db.add_location() loc_do_expr = ExprLoc(loc_do, 32) dst_cond = ExprCond(cond, loc_do_expr, loc_next_expr) assert(isinstance(instr_ir, list)) 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, loc_next_expr)) e_do = IRBlock(loc_do, [AssignBlock(instr_ir, instr)]) e = [ExprAff(ir.IRDst, dst_cond)] return e, [e_do] + extra_ir
def asr(
ir, instr, a, b, c=None)
def asr(ir, instr, a, b, c=None): e = [] if c is None: b, c = a, b r = ExprOp("a>>", b, c) e.append(ExprAff(a, r)) dst = get_dst(a) if dst is not None: e.append(ExprAff(ir.IRDst, r)) return e, []
def asrs(
ir, instr, a, b, c=None)
def asrs(ir, instr, a, b, c=None): e = [] if c is None: b, c = a, b r = ExprOp("a>>", b, c) e.append(ExprAff(a, r)) e += [ExprAff(zf, ExprOp('FLAG_EQ', r))] e += update_flag_nf(r) dst = get_dst(a) if dst is not None: e.append(ExprAff(ir.IRDst, r)) return e, []
def b(
ir, instr, a)
def b(ir, instr, a): e = [] e.append(ExprAff(PC, a)) e.append(ExprAff(ir.IRDst, a)) return e, []
def bfc(
ir, instr, a, b, c)
def bfc(ir, instr, a, b, c): e = [] start = int(b) stop = start + int(c) out = [] last = 0 if start: out.append(a[:start]) last = start if stop - start: out.append(ExprInt(0, 32)[last:stop]) last = stop if last < 32: out.append(a[last:]) r = ExprCompose(*out) e.append(ExprAff(a, r)) dst = None if PC in a.get_r(): dst = PC e.append(ExprAff(ir.IRDst, r)) return e, []
def bic(
ir, instr, a, b, c=None)
def bic(ir, instr, a, b, c=None): e = [] if c is None: b, c = a, b r = b & (c ^ ExprInt(-1, 32)) e.append(ExprAff(a, r)) dst = get_dst(a) if dst is not None: e.append(ExprAff(ir.IRDst, r)) return e, []
def bics(
ir, instr, a, b, c=None)
def bics(ir, instr, a, b, c=None): e = [] if c is None: b, c = a, b tmp1, tmp2 = b, ~c r = tmp1 & tmp2 e += [ExprAff(zf, ExprOp('FLAG_EQ_AND', tmp1, tmp2))] e += update_flag_nf(r) e.append(ExprAff(a, r)) dst = get_dst(a) if dst is not None: e.append(ExprAff(ir.IRDst, r)) return e, []
def bkpt(
ir, instr, a)
def bkpt(ir, instr, a): e = [] e.append(ExprAff(exception_flags, ExprInt(EXCEPT_SOFT_BP, 32))) e.append(ExprAff(bp_num, a)) return e, []
def bl(
ir, instr, a)
def bl(ir, instr, a): e = [] l = ExprInt(instr.offset + instr.l, 32) e.append(ExprAff(PC, a)) e.append(ExprAff(ir.IRDst, a)) e.append(ExprAff(LR, l)) return e, []
def blx(
ir, instr, a)
def blx(ir, instr, a): e = [] l = ExprInt(instr.offset + instr.l, 32) e.append(ExprAff(PC, a)) e.append(ExprAff(ir.IRDst, a)) e.append(ExprAff(LR, l)) return e, []
def bx(
ir, instr, a)
def bx(ir, instr, a): e = [] e.append(ExprAff(PC, a)) e.append(ExprAff(ir.IRDst, a)) return e, []
def cbnz(
ir, instr, a, b)
def cbnz(ir, instr, a, b): e = [] loc_next = ir.get_next_loc_key(instr) loc_next_expr = ExprLoc(loc_next, 32) e.append(ir.IRDst, ExprCond(a, b, loc_next_expr)) return e, []
def cbz(
ir, instr, a, b)
def cbz(ir, instr, a, b): e = [] loc_next = ir.get_next_loc_key(instr) loc_next_expr = ExprLoc(loc_next, 32) e.append(ExprAff(ir.IRDst, ExprCond(a, loc_next_expr, b))) return e, []
def check_ops_msb(
a, b, c)
def check_ops_msb(a, b, c): if not a or not b or not c or a != b or a != c: raise ValueError('bad ops size %s %s %s' % (a, b, c))
def clz(
ir, instr, a, b)
def clz(ir, instr, a, b): e = [] e.append(ExprAff(a, ExprOp('cntleadzeros', b))) return e, []
def cmn(
ir, instr, a, b, c=None)
def cmn(ir, instr, a, b, c=None): e = [] if c is None: b, c = a, b arg1, arg2 = b, c r = b + c e += update_flag_arith_add_zn(arg1, arg2) e += update_flag_arith_add_co(arg1, arg2) return e, []
def cpsid(
ir, instr, a)
def cpsid(ir, instr, a): # XXX TODO e = [] return e, []
def cpsie(
ir, instr, a)
def cpsie(ir, instr, a): # XXX TODO e = [] return e, []
def dsb(
ir, instr, a)
def dsb(ir, instr, a): # XXX TODO e = [] return e, []
def eor(
ir, instr, a, b, c=None)
def eor(ir, instr, a, b, c=None): e = [] if c is None: b, c = a, b r = b ^ c e.append(ExprAff(a, r)) dst = get_dst(a) if dst is not None: e.append(ExprAff(ir.IRDst, r)) return e, []
def eors(
ir, instr, a, b, c=None)
def eors(ir, instr, a, b, c=None): e = [] if c is None: b, c = a, b arg1, arg2 = b, c r = arg1 ^ arg2 e += [ExprAff(zf, ExprOp('FLAG_EQ_CMP', arg1, arg2))] e += update_flag_nf(r) e.append(ExprAff(a, r)) dst = get_dst(a) if dst is not None: e.append(ExprAff(ir.IRDst, r)) return e, []
def get_arm_instr_expr(
ir, instr, *args)
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()] instr_ir, extra_ir = mf(ir, instr, *args) instr, extra_ir = add_condition_expr(ir, instr, cond, instr_ir, extra_ir) return instr, extra_ir
def get_dst(
a)
def get_dst(a): if a == PC: return PC return None
def get_mnemo_expr(
ir, instr, *args)
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()] instr_ir, extra_ir = mf(ir, instr, *args) instr, extra_ir = add_condition_expr(ir, instr, cond, instr_ir, extra_ir) return instr, extra_ir
def is_pc_written(
ir, instr_ir)
def is_pc_written(ir, instr_ir): all_pc = ir.mn.pc.values() for ir in instr_ir: if ir.dst in all_pc: return True, ir.dst return False, None
def l_and(
ir, instr, a, b, c=None)
def l_and(ir, instr, a, b, c=None): e = [] if c is None: b, c = a, b r = b & c if instr.name == 'ANDS' and a != PC: e += [ExprAff(zf, ExprOp('FLAG_EQ_AND', b, c))] e += update_flag_nf(r) e.append(ExprAff(a, r)) dst = get_dst(a) if dst is not None: e.append(ExprAff(ir.IRDst, r)) return e, []
def l_cmp(
ir, instr, a, b, c=None)
def l_cmp(ir, instr, a, b, c=None): e = [] if c is None: b, c = a, b arg1, arg2 = b, c r = b - c e += update_flag_arith_sub_zn(arg1, arg2) e += update_flag_arith_sub_co(arg1, arg2) return e, []
def l_str(
ir, instr, a, b)
def l_str(ir, instr, a, b): return st_ld_r(ir, instr, a, None, b, store=True)
def l_strd(
ir, instr, a, b, c=None)
def l_strd(ir, instr, a, b, c=None): if c is None: a2 = ir.arch.regs.all_regs_ids[ir.arch.regs.all_regs_ids.index(a) + 1] else: a2 = b b = c return st_ld_r(ir, instr, a, a2, b, store=True, size=64)
def ldmda(
ir, instr, a, b)
def ldmda(ir, instr, a, b): return st_ld_m(ir, instr, a, b, store=False, postinc=True, updown=False)
def ldmdb(
ir, instr, a, b)
def ldmdb(ir, instr, a, b): return st_ld_m(ir, instr, a, b, store=False, postinc=False, updown=False)
def ldmia(
ir, instr, a, b)
def ldmia(ir, instr, a, b): return st_ld_m(ir, instr, a, b, store=False, postinc=True, updown=True)
def ldmib(
ir, instr, a, b)
def ldmib(ir, instr, a, b): return st_ld_m(ir, instr, a, b, store=False, postinc=False, updown=True)
def ldr(
ir, instr, a, b)
def ldr(ir, instr, a, b): return st_ld_r(ir, instr, a, None, b, store=False)
def ldrb(
ir, instr, a, b)
def ldrb(ir, instr, a, b): return st_ld_r(ir, instr, a, None, b, store=False, size=8, z_ext=True)
def ldrd(
ir, instr, a, b, c=None)
def ldrd(ir, instr, a, b, c=None): if c is None: a2 = ir.arch.regs.all_regs_ids[ir.arch.regs.all_regs_ids.index(a) + 1] else: a2 = b b = c return st_ld_r(ir, instr, a, a2, b, store=False, size=64)
def ldrh(
ir, instr, a, b)
def ldrh(ir, instr, a, b): return st_ld_r(ir, instr, a, None, b, store=False, size=16, z_ext=True)
def ldrsb(
ir, instr, a, b)
def ldrsb(ir, instr, a, b): return st_ld_r(ir, instr, a, None, b, store=False, size=8, s_ext=True, z_ext=False)
def ldrsh(
ir, instr, a, b)
def ldrsh(ir, instr, a, b): return st_ld_r(ir, instr, a, None, b, store=False, size=16, s_ext=True, z_ext=False)
def lsl(
ir, instr, a, b, c=None)
def lsl(ir, instr, a, b, c=None): e = [] if c is None: b, c = a, b r = b << c e.append(ExprAff(a, r)) dst = get_dst(a) if dst is not None: e.append(ExprAff(ir.IRDst, r)) return e, []
def lsls(
ir, instr, a, b, c=None)
def lsls(ir, instr, a, b, c=None): e = [] if c is None: b, c = a, b r = b << c e.append(ExprAff(a, r)) e += [ExprAff(zf, ExprOp('FLAG_EQ', r))] e += update_flag_nf(r) dst = get_dst(a) if dst is not None: e.append(ExprAff(ir.IRDst, r)) return e, []
def lsr(
ir, instr, a, b, c=None)
def lsr(ir, instr, a, b, c=None): e = [] if c is None: b, c = a, b r = b >> c e.append(ExprAff(a, r)) dst = get_dst(a) if dst is not None: e.append(ExprAff(ir.IRDst, r)) return e, []
def lsrs(
ir, instr, a, b, c=None)
def lsrs(ir, instr, a, b, c=None): e = [] if c is None: b, c = a, b r = b >> c e.append(ExprAff(a, r)) e += [ExprAff(zf, ExprOp('FLAG_EQ', r))] e += update_flag_nf(r) dst = get_dst(a) if dst is not None: e.append(ExprAff(ir.IRDst, r)) return e, []
def mf(
ir, instr, a, b)
def rors(ir, instr, a, b): e = [] r = ExprOp(">>>", a, b) e.append(ExprAff(a, r)) e += [ExprAff(zf, ExprOp('FLAG_EQ', r))] e += update_flag_nf(r) dst = get_dst(a) if dst is not None: e.append(ExprAff(ir.IRDst, r)) return e, []
def mla(
ir, instr, a, b, c, d)
def mla(ir, instr, a, b, c, d): e = [] r = (b * c) + d e.append(ExprAff(a, r)) dst = get_dst(a) if dst is not None: e.append(ExprAff(ir.IRDst, r)) return e, []
def mlas(
ir, instr, a, b, c, d)
def mlas(ir, instr, a, b, c, d): e = [] r = (b * c) + d e += update_flag_zn(r) e.append(ExprAff(a, r)) dst = get_dst(a) if dst is not None: e.append(ExprAff(ir.IRDst, r)) return e, []
def mls(
ir, instr, a, b, c, d)
def mls(ir, instr, a, b, c, d): e = [] r = d - (b * c) e.append(ExprAff(a, r)) dst = get_dst(a) if dst is not None: e.append(ExprAff(ir.IRDst, r)) return e, []
def mov(
ir, instr, a, b)
def mov(ir, instr, a, b): e = [ExprAff(a, b)] dst = get_dst(a) if dst is not None: e.append(ExprAff(ir.IRDst, b)) return e, []
def movs(
ir, instr, a, b)
def movs(ir, instr, a, b): e = [] e.append(ExprAff(a, b)) # XXX TODO check e += [ExprAff(zf, ExprOp('FLAG_EQ', b))] e += update_flag_nf(b) dst = get_dst(a) if dst is not None: e.append(ExprAff(ir.IRDst, b)) return e, []
def movt(
ir, instr, a, b)
def movt(ir, instr, a, b): r = a | b << ExprInt(16, 32) e = [ExprAff(a, r)] dst = get_dst(a) if dst is not None: e.append(ExprAff(ir.IRDst, r)) return e, []
def mrs(
ir, instr, a, b)
def mrs(ir, instr, a, b): e = [] if b.is_id('CPSR_cxsf'): out = [] out.append(ExprInt(0x10, 28)) out.append(of) out.append(cf) out.append(zf) out.append(nf) e.append(ExprAff(a, ExprCompose(*out))) else: raise NotImplementedError("MSR not implemented") return e, []
def msr(
ir, instr, a, b)
def msr(ir, instr, a, b): e = [] if a.is_id('CPSR_cf'): e.append(ExprAff(nf, b[31:32])) e.append(ExprAff(zf, b[30:31])) e.append(ExprAff(cf, b[29:30])) e.append(ExprAff(of, b[28:29])) else: raise NotImplementedError("MRS not implemented") return e, []
def mul(
ir, instr, a, b, c=None)
def mul(ir, instr, a, b, c=None): e = [] if c is None: b, c = a, b r = b * c e.append(ExprAff(a, r)) dst = get_dst(a) if dst is not None: e.append(ExprAff(ir.IRDst, r)) return e, []
def muls(
ir, instr, a, b, c=None)
def muls(ir, instr, a, b, c=None): e = [] if c is None: b, c = a, b r = b * c e += update_flag_zn(r) e.append(ExprAff(a, r)) dst = get_dst(a) if dst is not None: e.append(ExprAff(ir.IRDst, r)) return e, []
def mvn(
ir, instr, a, b)
def mvn(ir, instr, a, b): r = b ^ ExprInt(-1, 32) e = [ExprAff(a, r)] dst = get_dst(a) if dst is not None: e.append(ExprAff(ir.IRDst, r)) return e, []
def mvns(
ir, instr, a, b)
def mvns(ir, instr, a, b): e = [] r = b ^ ExprInt(-1, 32) e.append(ExprAff(a, r)) # XXX TODO check e += [ExprAff(zf, ExprOp('FLAG_EQ', r))] e += update_flag_nf(r) dst = get_dst(a) if dst is not None: e.append(ExprAff(ir.IRDst, r)) return e, []
def neg(
ir, instr, a, b)
def neg(ir, instr, a, b): e = [] r = - b e.append(ExprAff(a, r)) dst = get_dst(a) if dst is not None: e.append(ExprAff(ir.IRDst, r)) return e, []
def negs(
ir, instr, a, b)
def negs(ir, instr, a, b): return subs(ir, instr, a, ExprInt(0, b.size), b)
def nop(
ir, instr)
def nop(ir, instr): e = [] return e, []
def orn(
ir, instr, a, b, c=None)
def orn(ir, instr, a, b, c=None): e = [] if c is None: b, c = a, b r = ~(b | c) e.append(ExprAff(a, r)) dst = get_dst(a) if dst is not None: e.append(ExprAff(ir.IRDst, r)) return e, []
def orr(
ir, instr, a, b, c=None)
def orr(ir, instr, a, b, c=None): e = [] if c is None: b, c = a, b r = b | c e.append(ExprAff(a, r)) dst = get_dst(a) if dst is not None: e.append(ExprAff(ir.IRDst, r)) return e, []
def orrs(
ir, instr, a, b, c=None)
def orrs(ir, instr, a, b, c=None): e = [] if c is None: b, c = a, b arg1, arg2 = b, c r = b | c e += [ExprAff(zf, ExprOp('FLAG_EQ', r))] e += update_flag_nf(r) e.append(ExprAff(a, r)) dst = get_dst(a) if dst is not None: e.append(ExprAff(ir.IRDst, r)) return e, []
def pld(
ir, instr, a)
def pld(ir, instr, a): e = [] return e, []
def pldw(
ir, instr, a)
def pldw(ir, instr, a): e = [] return e, []
def pop(
ir, instr, a)
def pop(ir, instr, a): e = [] regs = list(a.args) dst = None for i in xrange(len(regs)): r = SP + ExprInt(4 * i, 32) e.append(ExprAff(regs[i], ExprMem(r, 32))) if regs[i] == ir.pc: dst = ExprMem(r, 32) r = SP + ExprInt(4 * len(regs), 32) e.append(ExprAff(SP, r)) if dst is not None: e.append(ExprAff(ir.IRDst, dst)) return e, []
def push(
ir, instr, a)
def push(ir, instr, a): e = [] regs = list(a.args) for i in xrange(len(regs)): r = SP + ExprInt(-4 * len(regs) + 4 * i, 32) e.append(ExprAff(ExprMem(r, 32), regs[i])) r = SP + ExprInt(-4 * len(regs), 32) e.append(ExprAff(SP, r)) return e, []
def rev(
ir, instr, a, b)
def rev(ir, instr, a, b): e = [] result = ExprCompose(b[24:32], b[16:24], b[8:16], b[:8]) e.append(ExprAff(a, result)) return e, []
def rors(
ir, instr, a, b)
def rors(ir, instr, a, b): e = [] r = ExprOp(">>>", a, b) e.append(ExprAff(a, r)) e += [ExprAff(zf, ExprOp('FLAG_EQ', r))] e += update_flag_nf(r) dst = get_dst(a) if dst is not None: e.append(ExprAff(ir.IRDst, r)) return e, []
def rsb(
ir, instr, a, b, c=None)
def rsb(ir, instr, a, b, c=None): e = [] if c is None: b, c = a, b r = c - b e.append(ExprAff(a, r)) dst = get_dst(a) if dst is not None: e.append(ExprAff(ir.IRDst, r)) return e, []
def rsbs(
ir, instr, a, b, c=None)
def rsbs(ir, instr, a, b, c=None): e = [] if c is None: b, c = a, b arg1, arg2 = c, b r = arg1 - arg2 e += update_flag_arith_sub_zn(arg1, arg2) e += update_flag_arith_sub_co(arg1, arg2) e.append(ExprAff(a, r)) dst = get_dst(a) if dst is not None: e.append(ExprAff(ir.IRDst, r)) return e, []
def rsc(
ir, instr, a, b, c=None)
def rsc(ir, instr, a, b, c=None): e = [] if c is None: b, c = a, b arg1, arg2 = c, b r = arg1 - (arg2 + (~cf).zeroExtend(32)) e.append(ExprAff(a, r)) dst = get_dst(a) if dst is not None: e.append(ExprAff(ir.IRDst, r)) return e, []
def rscs(
ir, instr, a, b, c=None)
def rscs(ir, instr, a, b, c=None): e = [] if c is None: b, c = a, b arg1, arg2 = c, b r = arg1 - (arg2 + (~cf).zeroExtend(32)) e += update_flag_arith_subwc_zn(arg1, arg2, ~cf) e += update_flag_arith_subwc_co(arg1, arg2, ~cf) e.append(ExprAff(a, r)) dst = get_dst(a) if dst is not None: e.append(ExprAff(ir.IRDst, r)) return e, []
def sbc(
ir, instr, a, b, c=None)
def sbc(ir, instr, a, b, c=None): e = [] if c is None: b, c = a, b arg1, arg2 = b, c r = arg1 - (arg2 + (~cf).zeroExtend(32)) e.append(ExprAff(a, r)) dst = get_dst(a) if dst is not None: e.append(ExprAff(ir.IRDst, r)) return e, []
def sbcs(
ir, instr, a, b, c=None)
def sbcs(ir, instr, a, b, c=None): e = [] if c is None: b, c = a, b arg1, arg2 = b, c r = arg1 - (arg2 + (~cf).zeroExtend(32)) e += update_flag_arith_subwc_zn(arg1, arg2, ~cf) e += update_flag_arith_subwc_co(arg1, arg2, ~cf) e.append(ExprAff(a, r)) dst = get_dst(a) if dst is not None: e.append(ExprAff(ir.IRDst, r)) return e, []
def sdiv(
ir, instr, a, b, c=None)
def sdiv(ir, instr, a, b, c=None): e = [] if c is None: b, c = a, b loc_div = ExprLoc(ir.loc_db.add_location(), ir.IRDst.size) loc_except = ExprId(ir.loc_db.add_location(), ir.IRDst.size) loc_next = ExprLoc(ir.get_next_loc_key(instr), ir.IRDst.size) e.append(ExprAff(ir.IRDst, ExprCond(c, loc_div, loc_except))) do_except = [] do_except.append(ExprAff(exception_flags, ExprInt(EXCEPT_DIV_BY_ZERO, exception_flags.size))) do_except.append(ExprAff(ir.IRDst, loc_next)) blk_except = IRBlock(loc_except.loc_key, [AssignBlock(do_except, instr)]) r = ExprOp("idiv", b, c) do_div = [] do_div.append(ExprAff(a, r)) dst = get_dst(a) if dst is not None: do_div.append(ExprAff(ir.IRDst, r)) do_div.append(ExprAff(ir.IRDst, loc_next)) blk_div = IRBlock(loc_div.loc_key, [AssignBlock(do_div, instr)]) return e, [blk_div, blk_except]
def sel(
ir, instr, a, b, c)
def sel(ir, instr, a, b, c): e = [] cond = nf ^ of ^ ExprInt(1, 1) parts = [] for i in xrange(4): parts.append(ExprCond(ge_regs[i], b[i*8:(i+1)*8], c[i*8:(i+1)*8])) result = ExprCompose(*parts) e.append(ExprAff(a, result)) return e, []
def smlabb(
ir, instr, a, b, c, d)
def smlabb(ir, instr, a, b, c, d): e = [] result = (b[:16].signExtend(32) * c[:16].signExtend(32)) + d e.append(ExprAff(a, result)) return e, []
def smlabt(
ir, instr, a, b, c, d)
def smlabt(ir, instr, a, b, c, d): e = [] result = (b[:16].signExtend(32) * c[16:32].signExtend(32)) + d e.append(ExprAff(a, result)) return e, []
def smlal(
ir, instr, a, b, c, d)
def smlal(ir, instr, a, b, c, d): e = [] r = c.signExtend(64) * d.signExtend(64) + ExprCompose(a, b) e.append(ExprAff(a, r[0:32])) e.append(ExprAff(b, r[32:64])) # r15/IRDst not allowed as output return e, []
def smlatb(
ir, instr, a, b, c, d)
def smlatb(ir, instr, a, b, c, d): e = [] result = (b[16:32].signExtend(32) * c[:16].signExtend(32)) + d e.append(ExprAff(a, result)) return e, []
def smlatt(
ir, instr, a, b, c, d)
def smlatt(ir, instr, a, b, c, d): e = [] result = (b[16:32].signExtend(32) * c[16:32].signExtend(32)) + d e.append(ExprAff(a, result)) return e, []
def smul(
ir, instr, a, b, c)
def smul(ir, instr, a, b, c): e = [] e.append(ExprAff(a, _extract_s16(b, instr.name[4]).signExtend(32) * _extract_s16(c, instr.name[5]).signExtend(32))) return e, []
def smull(
ir, instr, a, b, c, d)
def smull(ir, instr, a, b, c, d): e = [] r = c.signExtend(64) * d.signExtend(64) e.append(ExprAff(a, r[0:32])) e.append(ExprAff(b, r[32:64])) # r15/IRDst not allowed as output return e, []
def smulw(
ir, instr, a, b, c)
def smulw(ir, instr, a, b, c): e = [] prod = b.signExtend(48) * _extract_s16(c, instr.name[5]).signExtend(48) e.append(ExprAff(a, prod[16:48])) return e, [] # signed most significant 32 bits of the 48-bit result
def split_expr_dst(
ir, instr_ir)
def split_expr_dst(ir, instr_ir): out = [] dst = None for i in instr_ir: if i.dst == ir.pc: out.append(i) dst = ir.pc # i.src else: out.append(i) return out, dst
def st_ld_m(
ir, instr, a, b, store=False, postinc=False, updown=False)
def st_ld_m(ir, instr, a, b, store=False, postinc=False, updown=False): e = [] wb = False dst = None if isinstance(a, ExprOp) and a.op == 'wback': wb = True a = a.args[0] if isinstance(b, ExprOp) and b.op == 'sbit': b = b.args[0] regs = b.args base = a if updown: step = 4 else: step = -4 regs = regs[::-1] if postinc: pass else: base += ExprInt(step, 32) for i, r in enumerate(regs): ad = base + ExprInt(i * step, 32) if store: e.append(ExprAff(ExprMem(ad, 32), r)) else: e.append(ExprAff(r, ExprMem(ad, 32))) if r == PC: e.append(ExprAff(ir.IRDst, ExprMem(ad, 32))) # XXX TODO check multiple write cause by wb if wb: if postinc: e.append(ExprAff(a, base + ExprInt(len(regs) * step, 32))) else: e.append(ExprAff(a, base + ExprInt((len(regs) - 1) * step, 32))) if store: pass else: assert(isinstance(b, ExprOp) and b.op == "reglist") return e, []
def st_ld_r(
ir, instr, a, a2, b, store=False, size=32, s_ext=False, z_ext=False)
def st_ld_r(ir, instr, a, a2, b, store=False, size=32, s_ext=False, z_ext=False): e = [] wb = False b = b.copy() postinc = False b = b.arg if isinstance(b, ExprOp): if b.op == "wback": wb = True b = b.args[0] if b.op == "postinc": postinc = True if isinstance(b, ExprOp) and b.op in ["postinc", 'preinc']: # XXX TODO CHECK base, off = b.args[0], b.args[1] # ExprInt(size/8, 32) else: base, off = b, ExprInt(0, 32) if postinc: ad = base else: ad = base + off # PC base lookup uses PC 4 byte alignemnt ad = ad.replace_expr({PC: PC & ExprInt(0xFFFFFFFC, 32)}) dmem = False if size in [8, 16]: if store: a = a[:size] m = ExprMem(ad, size=size) elif s_ext: m = ExprMem(ad, size=size).signExtend(a.size) elif z_ext: m = ExprMem(ad, size=size).zeroExtend(a.size) else: raise ValueError('unhandled case') elif size == 32: m = ExprMem(ad, size=size) pass elif size == 64: assert a2 is not None m = ExprMem(ad, size=32) dmem = True size = 32 else: raise ValueError('the size DOES matter') dst = None if store: e.append(ExprAff(m, a)) if dmem: e.append(ExprAff(ExprMem(ad + ExprInt(4, 32), size=size), a2)) 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 + ExprInt(4, 32), size=size))) # XXX TODO check multiple write cause by wb if wb or postinc: e.append(ExprAff(base, base + off)) return e, []
def stmda(
ir, instr, a, b)
def stmda(ir, instr, a, b): return st_ld_m(ir, instr, a, b, store=True, postinc=True, updown=False)
def stmdb(
ir, instr, a, b)
def stmdb(ir, instr, a, b): return st_ld_m(ir, instr, a, b, store=True, postinc=False, updown=False)
def stmia(
ir, instr, a, b)
def stmia(ir, instr, a, b): return st_ld_m(ir, instr, a, b, store=True, postinc=True, updown=True)
def stmib(
ir, instr, a, b)
def stmib(ir, instr, a, b): return st_ld_m(ir, instr, a, b, store=True, postinc=False, updown=True)
def strb(
ir, instr, a, b)
def strb(ir, instr, a, b): return st_ld_r(ir, instr, a, None, b, store=True, size=8)
def strh(
ir, instr, a, b)
def strh(ir, instr, a, b): return st_ld_r(ir, instr, a, None, b, store=True, size=16, z_ext=True)
def sub(
ir, instr, a, b, c=None)
def sub(ir, instr, a, b, c=None): e = [] if c is None: b, c = a, b r = b - c e.append(ExprAff(a, r)) dst = get_dst(a) if dst is not None: e.append(ExprAff(ir.IRDst, r)) return e, []
def subs(
ir, instr, a, b, c=None)
def subs(ir, instr, a, b, c=None): e = [] if c is None: b, c = a, b arg1, arg2 = b, c r = b - c e += update_flag_arith_sub_zn(arg1, arg2) e += update_flag_arith_sub_co(arg1, arg2) e.append(ExprAff(a, r)) dst = get_dst(a) if dst is not None: e.append(ExprAff(ir.IRDst, r)) return e, []
def svc(
ir, instr, a)
def svc(ir, instr, a): e = [] except_int = EXCEPT_INT_XX e.append(ExprAff(exception_flags, ExprInt(except_int, 32))) e.append(ExprAff(interrupt_num, a)) return e, []
def sxtb(
ir, instr, a, b)
def sxtb(ir, instr, a, b): e = [] r = b[:8].signExtend(32) e.append(ExprAff(a, r)) dst = None if PC in a.get_r(): dst = PC e.append(ExprAff(ir.IRDst, r)) return e, []
def sxth(
ir, instr, a, b)
def sxth(ir, instr, a, b): e = [] r = b[:16].signExtend(32) e.append(ExprAff(a, r)) dst = None if PC in a.get_r(): dst = PC e.append(ExprAff(ir.IRDst, r)) return e, []
def tbb(
ir, instr, a)
def tbb(ir, instr, a): e = [] dst = PC + ExprInt(2, 32) * a.zeroExtend(32) e.append(ExprAff(PC, dst)) e.append(ExprAff(ir.IRDst, dst)) return e, []
def tbh(
ir, instr, a)
def tbh(ir, instr, a): e = [] dst = PC + ExprInt(2, 32) * a.zeroExtend(32) e.append(ExprAff(PC, dst)) e.append(ExprAff(ir.IRDst, dst)) return e, []
def teq(
ir, instr, a, b, c=None)
def teq(ir, instr, a, b, c=None): e = [] if c is None: b, c = a, b arg1, arg2 = b, c r = arg1 ^ arg2 e += [ExprAff(zf, ExprOp('FLAG_EQ_CMP', arg1, arg2))] e += update_flag_nf(r) return e, []
def tst(
ir, instr, a, b)
def tst(ir, instr, a, b): e = [] arg1, arg2 = a, b r = arg1 & arg2 e += [ExprAff(zf, ExprOp('FLAG_EQ_AND', arg1, arg2))] e += update_flag_nf(r) return e, []
def uadd8(
ir, instr, a, b, c)
def uadd8(ir, instr, a, b, c): e = [] sums = [] ges = [] for i in xrange(0, 32, 8): sums.append(b[i:i+8] + c[i:i+8]) ges.append((b[i:i+8].zeroExtend(9) + c[i:i+8].zeroExtend(9))[8:9]) e.append(ExprAff(a, ExprCompose(*sums))) for i, value in enumerate(ges): e.append(ExprAff(ge_regs[i], value)) return e, []
def ubfx(
ir, instr, a, b, c, d)
def ubfx(ir, instr, a, b, c, d): e = [] c = int(c) d = int(d) r = b[c:c+d].zeroExtend(32) e.append(ExprAff(a, r)) dst = None if PC in a.get_r(): dst = PC e.append(ExprAff(ir.IRDst, r)) return e, []
def udiv(
ir, instr, a, b, c=None)
def udiv(ir, instr, a, b, c=None): e = [] if c is None: b, c = a, b loc_div = ExprLoc(ir.loc_db.add_location(), ir.IRDst.size) loc_except = ExprLoc(ir.loc_db.add_location(), ir.IRDst.size) loc_next = ExprLoc(ir.get_next_loc_key(instr), ir.IRDst.size) e.append(ExprAff(ir.IRDst, ExprCond(c, loc_div, loc_except))) do_except = [] do_except.append(ExprAff(exception_flags, ExprInt(EXCEPT_DIV_BY_ZERO, exception_flags.size))) do_except.append(ExprAff(ir.IRDst, loc_next)) blk_except = IRBlock(loc_except.loc_key, [AssignBlock(do_except, instr)]) r = ExprOp("udiv", b, c) do_div = [] do_div.append(ExprAff(a, r)) dst = get_dst(a) if dst is not None: do_div.append(ExprAff(ir.IRDst, r)) do_div.append(ExprAff(ir.IRDst, loc_next)) blk_div = IRBlock(loc_div.loc_key, [AssignBlock(do_div, instr)]) return e, [blk_div, blk_except]
def umlal(
ir, instr, a, b, c, d)
def umlal(ir, instr, a, b, c, d): e = [] r = c.zeroExtend(64) * d.zeroExtend(64) + ExprCompose(a, b) e.append(ExprAff(a, r[0:32])) e.append(ExprAff(b, r[32:64])) # r15/IRDst not allowed as output return e, []
def umull(
ir, instr, a, b, c, d)
def umull(ir, instr, a, b, c, d): e = [] r = c.zeroExtend(64) * d.zeroExtend(64) e.append(ExprAff(a, r[0:32])) e.append(ExprAff(b, r[32:64])) # r15/IRDst not allowed as output return e, []
def und(
ir, instr, a, b)
def und(ir, instr, a, b): # XXX TODO implement e = [] return e, []
def update_flag_add_cf(
op1, op2)
Compute cf in @op1 + @op2
def update_flag_add_cf(op1, op2): "Compute cf in @op1 + @op2" return [ExprAff(cf, ExprOp("FLAG_ADD_CF", op1, op2))]
def update_flag_add_of(
op1, op2)
Compute of in @op1 + @op2
def update_flag_add_of(op1, op2): "Compute of in @op1 + @op2" return [ExprAff(of, ExprOp("FLAG_ADD_OF", op1, op2))]
def update_flag_addwc_cf(
op1, op2, op3)
Compute cf in @res = @op1 + @op2 + @op3
def update_flag_addwc_cf(op1, op2, op3): "Compute cf in @res = @op1 + @op2 + @op3" return [ExprAff(cf, ExprOp("FLAG_ADDWC_CF", op1, op2, op3))]
def update_flag_addwc_of(
op1, op2, op3)
Compute of in @res = @op1 + @op2 + @op3
def update_flag_addwc_of(op1, op2, op3): "Compute of in @res = @op1 + @op2 + @op3" return [ExprAff(of, ExprOp("FLAG_ADDWC_OF", op1, op2, op3))]
def update_flag_arith_add_co(
arg1, arg2)
def update_flag_arith_add_co(arg1, arg2): e = [] e += update_flag_add_cf(arg1, arg2) e += update_flag_add_of(arg1, arg2) return e
def update_flag_arith_add_zn(
arg1, arg2)
Compute zf and nf flags for (arg1 + arg2)
def update_flag_arith_add_zn(arg1, arg2): """ Compute zf and nf flags for (arg1 + arg2) """ e = [] e += update_flag_zf_eq(arg1, -arg2) e += [ExprAff(nf, ExprOp("FLAG_SIGN_SUB", arg1, -arg2))] return e
def update_flag_arith_addwc_co(
arg1, arg2, arg3)
def update_flag_arith_addwc_co(arg1, arg2, arg3): e = [] e += update_flag_addwc_cf(arg1, arg2, arg3) e += update_flag_addwc_of(arg1, arg2, arg3) return e
def update_flag_arith_addwc_zn(
arg1, arg2, arg3)
Compute znp flags for (arg1 + arg2 + cf)
def update_flag_arith_addwc_zn(arg1, arg2, arg3): """ Compute znp flags for (arg1 + arg2 + cf) """ e = [] e += update_flag_zfaddwc_eq(arg1, arg2, arg3) e += [ExprAff(nf, ExprOp("FLAG_SIGN_ADDWC", arg1, arg2, arg3))] return e
def update_flag_arith_sub_co(
arg1, arg2)
Compute cf and of flags for (arg1 - arg2)
def update_flag_arith_sub_co(arg1, arg2): """ Compute cf and of flags for (arg1 - arg2) """ e = [] e += update_flag_sub_cf(arg1, arg2) e += update_flag_sub_of(arg1, arg2) return e
def update_flag_arith_sub_zn(
arg1, arg2)
Compute zf and nf flags for (arg1 - arg2)
def update_flag_arith_sub_zn(arg1, arg2): """ Compute zf and nf flags for (arg1 - arg2) """ e = [] e += update_flag_zf_eq(arg1, arg2) e += [ExprAff(nf, ExprOp("FLAG_SIGN_SUB", arg1, arg2))] return e
def update_flag_arith_subwc_co(
arg1, arg2, arg3)
def update_flag_arith_subwc_co(arg1, arg2, arg3): e = [] e += update_flag_subwc_cf(arg1, arg2, arg3) e += update_flag_subwc_of(arg1, arg2, arg3) return e
def update_flag_arith_subwc_zn(
arg1, arg2, arg3)
Compute znp flags for (arg1 - (arg2 + cf))
def update_flag_arith_subwc_zn(arg1, arg2, arg3): """ Compute znp flags for (arg1 - (arg2 + cf)) """ e = [] e += update_flag_zfsubwc_eq(arg1, arg2, arg3) e += [ExprAff(nf, ExprOp("FLAG_SIGN_SUBWC", arg1, arg2, arg3))] return e
def update_flag_nf(
arg)
def update_flag_nf(arg): return [ ExprAff( nf, ExprOp("FLAG_SIGN_SUB", arg, ExprInt(0, arg.size)) ) ]
def update_flag_sub_cf(
op1, op2)
Compote CF in @op1 - @op2
def update_flag_sub_cf(op1, op2): "Compote CF in @op1 - @op2" return [ExprAff(cf, ExprOp("FLAG_SUB_CF", op1, op2) ^ ExprInt(1, 1))]
def update_flag_sub_of(
op1, op2)
Compote OF in @op1 - @op2
def update_flag_sub_of(op1, op2): "Compote OF in @op1 - @op2" return [ExprAff(of, ExprOp("FLAG_SUB_OF", op1, op2))]
def update_flag_subwc_cf(
op1, op2, op3)
Compute cf in @res = @op1 + @op2 + @op3
def update_flag_subwc_cf(op1, op2, op3): "Compute cf in @res = @op1 + @op2 + @op3" return [ExprAff(cf, ExprOp("FLAG_SUBWC_CF", op1, op2, op3) ^ ExprInt(1, 1))]
def update_flag_subwc_of(
op1, op2, op3)
Compute of in @res = @op1 + @op2 + @op3
def update_flag_subwc_of(op1, op2, op3): "Compute of in @res = @op1 + @op2 + @op3" return [ExprAff(of, ExprOp("FLAG_SUBWC_OF", op1, op2, op3))]
def update_flag_zf(
a)
def update_flag_zf(a): return [ExprAff(zf, ExprOp("FLAG_EQ", a))]
def update_flag_zf_eq(
a, b)
def update_flag_zf_eq(a, b): return [ExprAff(zf, ExprOp("FLAG_EQ_CMP", a, b))]
def update_flag_zfaddwc_eq(
arg1, arg2, arg3)
def update_flag_zfaddwc_eq(arg1, arg2, arg3): return [ExprAff(zf, ExprOp("FLAG_EQ_ADDWC", arg1, arg2, arg3))]
def update_flag_zfsubwc_eq(
arg1, arg2, arg3)
def update_flag_zfsubwc_eq(arg1, arg2, arg3): return [ExprAff(zf, ExprOp("FLAG_EQ_SUBWC", arg1, arg2, arg3))]
def update_flag_zn(
a)
def update_flag_zn(a): e = [] e += update_flag_zf(a) e += update_flag_nf(a) return e
def uxtab(
ir, instr, a, b, c)
def uxtab(ir, instr, a, b, c): e = [] e.append(ExprAff(a, b + (c & ExprInt(0xff, 32)))) return e, []
def uxtb(
ir, instr, a, b)
def uxtb(ir, instr, a, b): e = [] r = b[:8].zeroExtend(32) e.append(ExprAff(a, r)) dst = None if PC in a.get_r(): dst = PC e.append(ExprAff(ir.IRDst, r)) return e, []
def uxth(
ir, instr, a, b)
def uxth(ir, instr, a, b): e = [] r = b[:16].zeroExtend(32) e.append(ExprAff(a, r)) dst = None if PC in a.get_r(): dst = PC e.append(ExprAff(ir.IRDst, r)) return e, []
def wfe(
ir, instr)
def wfe(ir, instr): # XXX TODO e = [] return e, []
def wfi(
ir, instr)
def wfi(ir, instr): # XXX TODO e = [] return e, []
Classes
class arminfo
class arminfo: mode = "arm"
class ir_armb
class ir_armb(ir_arml): def __init__(self, loc_db=None): IntermediateRepresentation.__init__(self, mn_arm, "b", loc_db) self.pc = PC self.sp = SP self.IRDst = ExprId('IRDst', 32) self.addrsize = 32
Ancestors (in MRO)
Instance variables
Methods
def __init__(
self, loc_db=None)
def __init__(self, loc_db=None): IntermediateRepresentation.__init__(self, mn_arm, "b", loc_db) self.pc = PC self.sp = SP self.IRDst = ExprId('IRDst', 32) self.addrsize = 32
def add_asmblock_to_ircfg(
self, block, ircfg, gen_pc_updt=False)
Inheritance:
ir_arml
.add_asmblock_to_ircfg
Add a native block to the current IR @block: native assembly block @gen_pc_updt: insert PC update effects between instructions
def add_asmblock_to_ircfg(self, block, ircfg, gen_pc_updt=False): """ Add a native block to the current IR @block: native assembly block @gen_pc_updt: insert PC update effects between instructions """ it_hints = None it_cond = None label = block.loc_key assignments = [] ir_blocks_all = [] index = -1 while index + 1 < len(block.lines): index += 1 instr = block.lines[index] if label is None: assignments = [] label = self.get_loc_key_for_instr(instr) if instr.name.startswith("IT"): index, irblocks_it = self.do_it_block(label, index, block, assignments, gen_pc_updt) for irblocks in irblocks_it: ir_blocks_all += irblocks label = None continue split = self.add_instr_to_current_state( instr, block, assignments, ir_blocks_all, gen_pc_updt ) if split: ir_blocks_all.append(IRBlock(label, assignments)) label = None assignments = [] if label is not None: ir_blocks_all.append(IRBlock(label, assignments)) new_ir_blocks_all = self.post_add_asmblock_to_ircfg(block, ircfg, ir_blocks_all) for irblock in new_ir_blocks_all: ircfg.add_irblock(irblock) return new_ir_blocks_all
def add_bloc(
self, block, gen_pc_updt=False)
DEPRECATED function Use add_block instead of add_block
def add_bloc(self, block, gen_pc_updt=False): """ DEPRECATED function Use add_block instead of add_block """ self.add_block(block, gen_pc_updt)
def add_block(
self, block, gen_pc_updt=False)
Inheritance:
ir_arml
.add_block
DEPRECATED function Use add_block instead of add_block
def add_block(self, block, gen_pc_updt=False): """ DEPRECATED function Use add_block instead of add_block """ warnings.warn("""DEPRECATION WARNING ircfg is now out of IntermediateRepresentation Use: ircfg = ir_arch.new_ircfg() ir_arch.add_asmblock_to_ircfg(block, ircfg) """) raise RuntimeError("API Deprecated")
def add_instr_to_current_state(
self, instr, block, assignments, ir_blocks_all, gen_pc_updt)
Inheritance:
ir_arml
.add_instr_to_current_state
Add the IR effects of an instruction to the current state.
Returns a bool: True if the current assignments list must be split False in other cases.
@instr: native instruction @block: native block source @assignments: list of current AssignBlocks @ir_blocks_all: list of additional effects @gen_pc_updt: insert PC update effects between instructions
def add_instr_to_current_state(self, instr, block, assignments, ir_blocks_all, gen_pc_updt): """ Add the IR effects of an instruction to the current state. Returns a bool: * True if the current assignments list must be split * False in other cases. @instr: native instruction @block: native block source @assignments: list of current AssignBlocks @ir_blocks_all: list of additional effects @gen_pc_updt: insert PC update effects between instructions """ if gen_pc_updt is not False: self.gen_pc_update(assignments, instr) assignblk, ir_blocks_extra = self.instr2ir(instr) assignments.append(assignblk) ir_blocks_all += ir_blocks_extra if ir_blocks_extra: return True return False
def add_instr_to_ircfg(
self, instr, ircfg, loc_key=None, gen_pc_updt=False)
Inheritance:
ir_arml
.add_instr_to_ircfg
Add the native instruction @instr to the @ircfg @instr: instruction instance @ircfg: IRCFG instance @loc_key: loc_key instance of the instruction destination @gen_pc_updt: insert PC update effects between instructions
def add_instr_to_ircfg(self, instr, ircfg, loc_key=None, gen_pc_updt=False): """ Add the native instruction @instr to the @ircfg @instr: instruction instance @ircfg: IRCFG instance @loc_key: loc_key instance of the instruction destination @gen_pc_updt: insert PC update effects between instructions """ if loc_key is None: offset = getattr(instr, "offset", None) loc_key = self.loc_db.add_location(offset=offset) block = AsmBlock(loc_key) block.lines = [instr] self.add_asmblock_to_ircfg(block, ircfg, gen_pc_updt) return loc_key
def do_it_block(
self, loc, index, block, assignments, gen_pc_updt)
Inheritance:
ir_arml
.do_it_block
def do_it_block(self, loc, index, block, assignments, gen_pc_updt): instr = block.lines[index] it_hints, it_cond = self.parse_itt(instr) cond_num = cond_dct_inv[it_cond.name] cond_eq = tab_cond[cond_num] if not index + len(it_hints) <= len(block.lines): raise NotImplementedError("Splitted IT block non supported yet") ir_blocks_all = [] # Gen dummy irblock for IT instr loc_next = self.get_next_loc_key(instr) dst = ExprAff(self.IRDst, ExprId(loc_next, 32)) dst_blk = AssignBlock([dst], instr) assignments.append(dst_blk) irblock = IRBlock(loc, assignments) ir_blocks_all.append([irblock]) loc = loc_next assignments = [] for hint in it_hints: irblocks = [] index += 1 instr = block.lines[index] # Add conditionnal jump to current irblock loc_do = self.loc_db.add_location() loc_next = self.get_next_loc_key(instr) if hint: local_cond = ~cond_eq else: local_cond = cond_eq dst = ExprAff(self.IRDst, ExprCond(local_cond, ExprLoc(loc_do, 32), ExprLoc(loc_next, 32))) dst_blk = AssignBlock([dst], instr) assignments.append(dst_blk) irblock = IRBlock(loc, assignments) irblocks.append(irblock) assignments = [] loc = loc_do split = self.add_instr_to_current_state( instr, block, assignments, irblocks, gen_pc_updt ) if split: raise NotImplementedError("Unsupported instr in IT block (%s)" % instr) dst = ExprAff(self.IRDst, ExprId(loc_next, 32)) dst_blk = AssignBlock([dst], instr) assignments.append(dst_blk) irblock = IRBlock(loc, assignments) irblocks.append(irblock) loc = loc_next assignments = [] ir_blocks_all.append(irblocks) return index, ir_blocks_all
def expr_fix_regs_for_mode(
self, expr, *args, **kwargs)
Inheritance:
ir_arml
.expr_fix_regs_for_mode
def expr_fix_regs_for_mode(self, expr, *args, **kwargs): return expr
def expraff_fix_regs_for_mode(
self, expr, *args, **kwargs)
Inheritance:
ir_arml
.expraff_fix_regs_for_mode
def expraff_fix_regs_for_mode(self, expr, *args, **kwargs): return expr
def gen_loc_key_and_expr(
self, size)
Inheritance:
ir_arml
.gen_loc_key_and_expr
Return a loc_key and it's corresponding ExprLoc @size: size of expression
def gen_loc_key_and_expr(self, size): """ Return a loc_key and it's corresponding ExprLoc @size: size of expression """ loc_key = self.loc_db.add_location() return loc_key, m2_expr.ExprLoc(loc_key, size)
def gen_pc_update(
self, assignments, instr)
Inheritance:
ir_arml
.gen_pc_update
def gen_pc_update(self, assignments, instr): offset = m2_expr.ExprInt(instr.offset, self.pc.size) assignments.append(AssignBlock({self.pc:offset}, instr))
def get_ir(
self, instr)
def get_ir(self, instr): args = instr.args # ir = get_mnemo_expr(self, self.name.lower(), *args) if len(args) and isinstance(args[-1], ExprOp): if args[-1].op == 'rrx': args[-1] = ExprCompose(args[-1].args[0][1:], cf) elif (args[-1].op in ['<<', '>>', '<<a', 'a>>', '<<<', '>>>'] and isinstance(args[-1].args[-1], ExprId)): args[-1] = ExprOp(args[-1].op, args[-1].args[0], args[-1].args[-1][:8].zeroExtend(32)) instr_ir, extra_ir = get_mnemo_expr(self, instr, *args) self.mod_pc(instr, instr_ir, extra_ir) return instr_ir, extra_ir
def get_loc_key_for_instr(
self, instr)
Inheritance:
ir_arml
.get_loc_key_for_instr
Returns the loc_key associated to an instruction @instr: current instruction
def get_loc_key_for_instr(self, instr): """Returns the loc_key associated to an instruction @instr: current instruction""" return self.loc_db.get_or_create_offset_location(instr.offset)
def get_next_loc_key(
self, instr)
Inheritance:
ir_arml
.get_next_loc_key
def get_next_loc_key(self, instr): loc_key = self.loc_db.get_or_create_offset_location(instr.offset + instr.l) return loc_key
def instr2ir(
self, instr)
def instr2ir(self, instr): ir_bloc_cur, extra_irblocks = self.get_ir(instr) for index, irb in enumerate(extra_irblocks): irs = [] for assignblk in irb: irs.append(AssignBlock(assignblk, instr)) extra_irblocks[index] = IRBlock(irb.loc_key, irs) assignblk = AssignBlock(ir_bloc_cur, instr) return assignblk, extra_irblocks
def irbloc_fix_regs_for_mode(
self, irblock, *args, **kwargs)
Inheritance:
ir_arml
.irbloc_fix_regs_for_mode
def irbloc_fix_regs_for_mode(self, irblock, *args, **kwargs): return irblock
def is_pc_written(
self, block)
Inheritance:
ir_arml
.is_pc_written
Return the first Assignblk of the @blockin which PC is written @block: IRBlock instance
def is_pc_written(self, block): """Return the first Assignblk of the @blockin which PC is written @block: IRBlock instance""" all_pc = self.arch.pc.values() for assignblk in block: if assignblk.dst in all_pc: return assignblk return None
def mod_pc(
self, instr, instr_ir, extra_ir)
def mod_pc(self, instr, instr_ir, extra_ir): # fix PC (+8 for arm) pc_fixed = {self.pc: ExprInt(instr.offset + 8, 32)} for i, expr in enumerate(instr_ir): dst, src = expr.dst, expr.src if dst != self.pc: dst = dst.replace_expr(pc_fixed) src = src.replace_expr(pc_fixed) instr_ir[i] = ExprAff(dst, src) for idx, irblock in enumerate(extra_ir): extra_ir[idx] = irblock.modify_exprs(lambda expr: expr.replace_expr(pc_fixed) \ if expr != self.pc else expr, lambda expr: expr.replace_expr(pc_fixed))
def new_ircfg(
self, *args, **kwargs)
Inheritance:
ir_arml
.new_ircfg
Return a new instance of IRCFG
def new_ircfg(self, *args, **kwargs): """ Return a new instance of IRCFG """ return IRCFG(self.IRDst, self.loc_db, *args, **kwargs)
def new_ircfg_from_asmcfg(
self, asmcfg, *args, **kwargs)
Inheritance:
ir_arml
.new_ircfg_from_asmcfg
Return a new instance of IRCFG from an @asmcfg @asmcfg: AsmCFG instance
def new_ircfg_from_asmcfg(self, asmcfg, *args, **kwargs): """ Return a new instance of IRCFG from an @asmcfg @asmcfg: AsmCFG instance """ ircfg = IRCFG(self.IRDst, self.loc_db, *args, **kwargs) for block in asmcfg.blocks: self.add_asmblock_to_ircfg(block, ircfg) return ircfg
def parse_itt(
self, instr)
Inheritance:
ir_arml
.parse_itt
def parse_itt(self, instr): name = instr.name assert name.startswith('IT') name = name[1:] out = [] for hint in name: if hint == 'T': out.append(0) elif hint == "E": out.append(1) else: raise ValueError("IT name invalid %s" % instr) return out, instr.args[0]
def post_add_asmblock_to_ircfg(
self, block, ircfg, ir_blocks)
Inheritance:
ir_arml
.post_add_asmblock_to_ircfg
def post_add_asmblock_to_ircfg(self, block, ircfg, ir_blocks): self.set_empty_dst_to_next(block, ir_blocks) new_irblocks = [] for irblock in ir_blocks: new_irblock = self.irbloc_fix_regs_for_mode(irblock, self.attrib) ircfg.add_irblock(new_irblock) new_irblocks.append(new_irblock) return new_irblocks
def set_empty_dst_to_next(
self, block, ir_blocks)
Inheritance:
ir_arml
.set_empty_dst_to_next
def set_empty_dst_to_next(self, block, ir_blocks): for index, irblock in enumerate(ir_blocks): if irblock.dst is not None: continue next_loc_key = block.get_next() if next_loc_key is None: loc_key = None if block.lines: line = block.lines[-1] if line.offset is not None: loc_key = self.loc_db.get_or_create_offset_location(line.offset + line.l) if loc_key is None: loc_key = self.loc_db.add_location() block.add_cst(loc_key, AsmConstraint.c_next) else: loc_key = next_loc_key dst = m2_expr.ExprLoc(loc_key, self.pc.size) if irblock.assignblks: instr = irblock.assignblks[-1].instr else: instr = None assignblk = AssignBlock({self.IRDst: dst}, instr) ir_blocks[index] = IRBlock(irblock.loc_key, list(irblock.assignblks) + [assignblk])
class ir_arml
class ir_arml(IntermediateRepresentation): def __init__(self, loc_db=None): IntermediateRepresentation.__init__(self, mn_arm, "l", loc_db) self.pc = PC self.sp = SP self.IRDst = ExprId('IRDst', 32) self.addrsize = 32 def mod_pc(self, instr, instr_ir, extra_ir): # fix PC (+8 for arm) pc_fixed = {self.pc: ExprInt(instr.offset + 8, 32)} for i, expr in enumerate(instr_ir): dst, src = expr.dst, expr.src if dst != self.pc: dst = dst.replace_expr(pc_fixed) src = src.replace_expr(pc_fixed) instr_ir[i] = ExprAff(dst, src) for idx, irblock in enumerate(extra_ir): extra_ir[idx] = irblock.modify_exprs(lambda expr: expr.replace_expr(pc_fixed) \ if expr != self.pc else expr, lambda expr: expr.replace_expr(pc_fixed)) def get_ir(self, instr): args = instr.args # ir = get_mnemo_expr(self, self.name.lower(), *args) if len(args) and isinstance(args[-1], ExprOp): if args[-1].op == 'rrx': args[-1] = ExprCompose(args[-1].args[0][1:], cf) elif (args[-1].op in ['<<', '>>', '<<a', 'a>>', '<<<', '>>>'] and isinstance(args[-1].args[-1], ExprId)): args[-1] = ExprOp(args[-1].op, args[-1].args[0], args[-1].args[-1][:8].zeroExtend(32)) instr_ir, extra_ir = get_mnemo_expr(self, instr, *args) self.mod_pc(instr, instr_ir, extra_ir) return instr_ir, extra_ir def parse_itt(self, instr): name = instr.name assert name.startswith('IT') name = name[1:] out = [] for hint in name: if hint == 'T': out.append(0) elif hint == "E": out.append(1) else: raise ValueError("IT name invalid %s" % instr) return out, instr.args[0] def do_it_block(self, loc, index, block, assignments, gen_pc_updt): instr = block.lines[index] it_hints, it_cond = self.parse_itt(instr) cond_num = cond_dct_inv[it_cond.name] cond_eq = tab_cond[cond_num] if not index + len(it_hints) <= len(block.lines): raise NotImplementedError("Splitted IT block non supported yet") ir_blocks_all = [] # Gen dummy irblock for IT instr loc_next = self.get_next_loc_key(instr) dst = ExprAff(self.IRDst, ExprId(loc_next, 32)) dst_blk = AssignBlock([dst], instr) assignments.append(dst_blk) irblock = IRBlock(loc, assignments) ir_blocks_all.append([irblock]) loc = loc_next assignments = [] for hint in it_hints: irblocks = [] index += 1 instr = block.lines[index] # Add conditionnal jump to current irblock loc_do = self.loc_db.add_location() loc_next = self.get_next_loc_key(instr) if hint: local_cond = ~cond_eq else: local_cond = cond_eq dst = ExprAff(self.IRDst, ExprCond(local_cond, ExprLoc(loc_do, 32), ExprLoc(loc_next, 32))) dst_blk = AssignBlock([dst], instr) assignments.append(dst_blk) irblock = IRBlock(loc, assignments) irblocks.append(irblock) assignments = [] loc = loc_do split = self.add_instr_to_current_state( instr, block, assignments, irblocks, gen_pc_updt ) if split: raise NotImplementedError("Unsupported instr in IT block (%s)" % instr) dst = ExprAff(self.IRDst, ExprId(loc_next, 32)) dst_blk = AssignBlock([dst], instr) assignments.append(dst_blk) irblock = IRBlock(loc, assignments) irblocks.append(irblock) loc = loc_next assignments = [] ir_blocks_all.append(irblocks) return index, ir_blocks_all def add_asmblock_to_ircfg(self, block, ircfg, gen_pc_updt=False): """ Add a native block to the current IR @block: native assembly block @gen_pc_updt: insert PC update effects between instructions """ it_hints = None it_cond = None label = block.loc_key assignments = [] ir_blocks_all = [] index = -1 while index + 1 < len(block.lines): index += 1 instr = block.lines[index] if label is None: assignments = [] label = self.get_loc_key_for_instr(instr) if instr.name.startswith("IT"): index, irblocks_it = self.do_it_block(label, index, block, assignments, gen_pc_updt) for irblocks in irblocks_it: ir_blocks_all += irblocks label = None continue split = self.add_instr_to_current_state( instr, block, assignments, ir_blocks_all, gen_pc_updt ) if split: ir_blocks_all.append(IRBlock(label, assignments)) label = None assignments = [] if label is not None: ir_blocks_all.append(IRBlock(label, assignments)) new_ir_blocks_all = self.post_add_asmblock_to_ircfg(block, ircfg, ir_blocks_all) for irblock in new_ir_blocks_all: ircfg.add_irblock(irblock) return new_ir_blocks_all
Ancestors (in MRO)
- ir_arml
- miasm2.ir.ir.IntermediateRepresentation
- __builtin__.object
Instance variables
var IRDst
var addrsize
var pc
var sp
Methods
def __init__(
self, loc_db=None)
def __init__(self, loc_db=None): IntermediateRepresentation.__init__(self, mn_arm, "l", loc_db) self.pc = PC self.sp = SP self.IRDst = ExprId('IRDst', 32) self.addrsize = 32
def add_asmblock_to_ircfg(
self, block, ircfg, gen_pc_updt=False)
Add a native block to the current IR @block: native assembly block @gen_pc_updt: insert PC update effects between instructions
def add_asmblock_to_ircfg(self, block, ircfg, gen_pc_updt=False): """ Add a native block to the current IR @block: native assembly block @gen_pc_updt: insert PC update effects between instructions """ it_hints = None it_cond = None label = block.loc_key assignments = [] ir_blocks_all = [] index = -1 while index + 1 < len(block.lines): index += 1 instr = block.lines[index] if label is None: assignments = [] label = self.get_loc_key_for_instr(instr) if instr.name.startswith("IT"): index, irblocks_it = self.do_it_block(label, index, block, assignments, gen_pc_updt) for irblocks in irblocks_it: ir_blocks_all += irblocks label = None continue split = self.add_instr_to_current_state( instr, block, assignments, ir_blocks_all, gen_pc_updt ) if split: ir_blocks_all.append(IRBlock(label, assignments)) label = None assignments = [] if label is not None: ir_blocks_all.append(IRBlock(label, assignments)) new_ir_blocks_all = self.post_add_asmblock_to_ircfg(block, ircfg, ir_blocks_all) for irblock in new_ir_blocks_all: ircfg.add_irblock(irblock) return new_ir_blocks_all
def add_bloc(
self, block, gen_pc_updt=False)
DEPRECATED function Use add_block instead of add_block
def add_bloc(self, block, gen_pc_updt=False): """ DEPRECATED function Use add_block instead of add_block """ self.add_block(block, gen_pc_updt)
def add_block(
self, block, gen_pc_updt=False)
DEPRECATED function Use add_block instead of add_block
def add_block(self, block, gen_pc_updt=False): """ DEPRECATED function Use add_block instead of add_block """ warnings.warn("""DEPRECATION WARNING ircfg is now out of IntermediateRepresentation Use: ircfg = ir_arch.new_ircfg() ir_arch.add_asmblock_to_ircfg(block, ircfg) """) raise RuntimeError("API Deprecated")
def add_instr_to_current_state(
self, instr, block, assignments, ir_blocks_all, gen_pc_updt)
Add the IR effects of an instruction to the current state.
Returns a bool: True if the current assignments list must be split False in other cases.
@instr: native instruction @block: native block source @assignments: list of current AssignBlocks @ir_blocks_all: list of additional effects @gen_pc_updt: insert PC update effects between instructions
def add_instr_to_current_state(self, instr, block, assignments, ir_blocks_all, gen_pc_updt): """ Add the IR effects of an instruction to the current state. Returns a bool: * True if the current assignments list must be split * False in other cases. @instr: native instruction @block: native block source @assignments: list of current AssignBlocks @ir_blocks_all: list of additional effects @gen_pc_updt: insert PC update effects between instructions """ if gen_pc_updt is not False: self.gen_pc_update(assignments, instr) assignblk, ir_blocks_extra = self.instr2ir(instr) assignments.append(assignblk) ir_blocks_all += ir_blocks_extra if ir_blocks_extra: return True return False
def add_instr_to_ircfg(
self, instr, ircfg, loc_key=None, gen_pc_updt=False)
Add the native instruction @instr to the @ircfg @instr: instruction instance @ircfg: IRCFG instance @loc_key: loc_key instance of the instruction destination @gen_pc_updt: insert PC update effects between instructions
def add_instr_to_ircfg(self, instr, ircfg, loc_key=None, gen_pc_updt=False): """ Add the native instruction @instr to the @ircfg @instr: instruction instance @ircfg: IRCFG instance @loc_key: loc_key instance of the instruction destination @gen_pc_updt: insert PC update effects between instructions """ if loc_key is None: offset = getattr(instr, "offset", None) loc_key = self.loc_db.add_location(offset=offset) block = AsmBlock(loc_key) block.lines = [instr] self.add_asmblock_to_ircfg(block, ircfg, gen_pc_updt) return loc_key
def do_it_block(
self, loc, index, block, assignments, gen_pc_updt)
def do_it_block(self, loc, index, block, assignments, gen_pc_updt): instr = block.lines[index] it_hints, it_cond = self.parse_itt(instr) cond_num = cond_dct_inv[it_cond.name] cond_eq = tab_cond[cond_num] if not index + len(it_hints) <= len(block.lines): raise NotImplementedError("Splitted IT block non supported yet") ir_blocks_all = [] # Gen dummy irblock for IT instr loc_next = self.get_next_loc_key(instr) dst = ExprAff(self.IRDst, ExprId(loc_next, 32)) dst_blk = AssignBlock([dst], instr) assignments.append(dst_blk) irblock = IRBlock(loc, assignments) ir_blocks_all.append([irblock]) loc = loc_next assignments = [] for hint in it_hints: irblocks = [] index += 1 instr = block.lines[index] # Add conditionnal jump to current irblock loc_do = self.loc_db.add_location() loc_next = self.get_next_loc_key(instr) if hint: local_cond = ~cond_eq else: local_cond = cond_eq dst = ExprAff(self.IRDst, ExprCond(local_cond, ExprLoc(loc_do, 32), ExprLoc(loc_next, 32))) dst_blk = AssignBlock([dst], instr) assignments.append(dst_blk) irblock = IRBlock(loc, assignments) irblocks.append(irblock) assignments = [] loc = loc_do split = self.add_instr_to_current_state( instr, block, assignments, irblocks, gen_pc_updt ) if split: raise NotImplementedError("Unsupported instr in IT block (%s)" % instr) dst = ExprAff(self.IRDst, ExprId(loc_next, 32)) dst_blk = AssignBlock([dst], instr) assignments.append(dst_blk) irblock = IRBlock(loc, assignments) irblocks.append(irblock) loc = loc_next assignments = [] ir_blocks_all.append(irblocks) return index, ir_blocks_all
def expr_fix_regs_for_mode(
self, expr, *args, **kwargs)
def expr_fix_regs_for_mode(self, expr, *args, **kwargs): return expr
def expraff_fix_regs_for_mode(
self, expr, *args, **kwargs)
def expraff_fix_regs_for_mode(self, expr, *args, **kwargs): return expr
def gen_loc_key_and_expr(
self, size)
Return a loc_key and it's corresponding ExprLoc @size: size of expression
def gen_loc_key_and_expr(self, size): """ Return a loc_key and it's corresponding ExprLoc @size: size of expression """ loc_key = self.loc_db.add_location() return loc_key, m2_expr.ExprLoc(loc_key, size)
def gen_pc_update(
self, assignments, instr)
def gen_pc_update(self, assignments, instr): offset = m2_expr.ExprInt(instr.offset, self.pc.size) assignments.append(AssignBlock({self.pc:offset}, instr))
def get_ir(
self, instr)
def get_ir(self, instr): args = instr.args # ir = get_mnemo_expr(self, self.name.lower(), *args) if len(args) and isinstance(args[-1], ExprOp): if args[-1].op == 'rrx': args[-1] = ExprCompose(args[-1].args[0][1:], cf) elif (args[-1].op in ['<<', '>>', '<<a', 'a>>', '<<<', '>>>'] and isinstance(args[-1].args[-1], ExprId)): args[-1] = ExprOp(args[-1].op, args[-1].args[0], args[-1].args[-1][:8].zeroExtend(32)) instr_ir, extra_ir = get_mnemo_expr(self, instr, *args) self.mod_pc(instr, instr_ir, extra_ir) return instr_ir, extra_ir
def get_loc_key_for_instr(
self, instr)
Returns the loc_key associated to an instruction @instr: current instruction
def get_loc_key_for_instr(self, instr): """Returns the loc_key associated to an instruction @instr: current instruction""" return self.loc_db.get_or_create_offset_location(instr.offset)
def get_next_loc_key(
self, instr)
def get_next_loc_key(self, instr): loc_key = self.loc_db.get_or_create_offset_location(instr.offset + instr.l) return loc_key
def instr2ir(
self, instr)
def instr2ir(self, instr): ir_bloc_cur, extra_irblocks = self.get_ir(instr) for index, irb in enumerate(extra_irblocks): irs = [] for assignblk in irb: irs.append(AssignBlock(assignblk, instr)) extra_irblocks[index] = IRBlock(irb.loc_key, irs) assignblk = AssignBlock(ir_bloc_cur, instr) return assignblk, extra_irblocks
def irbloc_fix_regs_for_mode(
self, irblock, *args, **kwargs)
def irbloc_fix_regs_for_mode(self, irblock, *args, **kwargs): return irblock
def is_pc_written(
self, block)
Return the first Assignblk of the @blockin which PC is written @block: IRBlock instance
def is_pc_written(self, block): """Return the first Assignblk of the @blockin which PC is written @block: IRBlock instance""" all_pc = self.arch.pc.values() for assignblk in block: if assignblk.dst in all_pc: return assignblk return None
def mod_pc(
self, instr, instr_ir, extra_ir)
def mod_pc(self, instr, instr_ir, extra_ir): # fix PC (+8 for arm) pc_fixed = {self.pc: ExprInt(instr.offset + 8, 32)} for i, expr in enumerate(instr_ir): dst, src = expr.dst, expr.src if dst != self.pc: dst = dst.replace_expr(pc_fixed) src = src.replace_expr(pc_fixed) instr_ir[i] = ExprAff(dst, src) for idx, irblock in enumerate(extra_ir): extra_ir[idx] = irblock.modify_exprs(lambda expr: expr.replace_expr(pc_fixed) \ if expr != self.pc else expr, lambda expr: expr.replace_expr(pc_fixed))
def new_ircfg(
self, *args, **kwargs)
Return a new instance of IRCFG
def new_ircfg(self, *args, **kwargs): """ Return a new instance of IRCFG """ return IRCFG(self.IRDst, self.loc_db, *args, **kwargs)
def new_ircfg_from_asmcfg(
self, asmcfg, *args, **kwargs)
Return a new instance of IRCFG from an @asmcfg @asmcfg: AsmCFG instance
def new_ircfg_from_asmcfg(self, asmcfg, *args, **kwargs): """ Return a new instance of IRCFG from an @asmcfg @asmcfg: AsmCFG instance """ ircfg = IRCFG(self.IRDst, self.loc_db, *args, **kwargs) for block in asmcfg.blocks: self.add_asmblock_to_ircfg(block, ircfg) return ircfg
def parse_itt(
self, instr)
def parse_itt(self, instr): name = instr.name assert name.startswith('IT') name = name[1:] out = [] for hint in name: if hint == 'T': out.append(0) elif hint == "E": out.append(1) else: raise ValueError("IT name invalid %s" % instr) return out, instr.args[0]
def post_add_asmblock_to_ircfg(
self, block, ircfg, ir_blocks)
def post_add_asmblock_to_ircfg(self, block, ircfg, ir_blocks): self.set_empty_dst_to_next(block, ir_blocks) new_irblocks = [] for irblock in ir_blocks: new_irblock = self.irbloc_fix_regs_for_mode(irblock, self.attrib) ircfg.add_irblock(new_irblock) new_irblocks.append(new_irblock) return new_irblocks
def set_empty_dst_to_next(
self, block, ir_blocks)
def set_empty_dst_to_next(self, block, ir_blocks): for index, irblock in enumerate(ir_blocks): if irblock.dst is not None: continue next_loc_key = block.get_next() if next_loc_key is None: loc_key = None if block.lines: line = block.lines[-1] if line.offset is not None: loc_key = self.loc_db.get_or_create_offset_location(line.offset + line.l) if loc_key is None: loc_key = self.loc_db.add_location() block.add_cst(loc_key, AsmConstraint.c_next) else: loc_key = next_loc_key dst = m2_expr.ExprLoc(loc_key, self.pc.size) if irblock.assignblks: instr = irblock.assignblks[-1].instr else: instr = None assignblk = AssignBlock({self.IRDst: dst}, instr) ir_blocks[index] = IRBlock(irblock.loc_key, list(irblock.assignblks) + [assignblk])
class ir_armtb
class ir_armtb(ir_armtl): def __init__(self, loc_db=None): IntermediateRepresentation.__init__(self, mn_armt, "b", loc_db) self.pc = PC self.sp = SP self.IRDst = ExprId('IRDst', 32) self.addrsize = 32
Ancestors (in MRO)
Instance variables
Methods
def __init__(
self, loc_db=None)
Inheritance:
ir_armtl
.__init__
def __init__(self, loc_db=None): IntermediateRepresentation.__init__(self, mn_armt, "b", loc_db) self.pc = PC self.sp = SP self.IRDst = ExprId('IRDst', 32) self.addrsize = 32
def add_asmblock_to_ircfg(
self, block, ircfg, gen_pc_updt=False)
Inheritance:
ir_armtl
.add_asmblock_to_ircfg
Add a native block to the current IR @block: native assembly block @gen_pc_updt: insert PC update effects between instructions
def add_asmblock_to_ircfg(self, block, ircfg, gen_pc_updt=False): """ Add a native block to the current IR @block: native assembly block @gen_pc_updt: insert PC update effects between instructions """ it_hints = None it_cond = None label = block.loc_key assignments = [] ir_blocks_all = [] index = -1 while index + 1 < len(block.lines): index += 1 instr = block.lines[index] if label is None: assignments = [] label = self.get_loc_key_for_instr(instr) if instr.name.startswith("IT"): index, irblocks_it = self.do_it_block(label, index, block, assignments, gen_pc_updt) for irblocks in irblocks_it: ir_blocks_all += irblocks label = None continue split = self.add_instr_to_current_state( instr, block, assignments, ir_blocks_all, gen_pc_updt ) if split: ir_blocks_all.append(IRBlock(label, assignments)) label = None assignments = [] if label is not None: ir_blocks_all.append(IRBlock(label, assignments)) new_ir_blocks_all = self.post_add_asmblock_to_ircfg(block, ircfg, ir_blocks_all) for irblock in new_ir_blocks_all: ircfg.add_irblock(irblock) return new_ir_blocks_all
def add_bloc(
self, block, gen_pc_updt=False)
Inheritance:
ir_armtl
.add_bloc
DEPRECATED function Use add_block instead of add_block
def add_bloc(self, block, gen_pc_updt=False): """ DEPRECATED function Use add_block instead of add_block """ self.add_block(block, gen_pc_updt)
def add_block(
self, block, gen_pc_updt=False)
Inheritance:
ir_armtl
.add_block
DEPRECATED function Use add_block instead of add_block
def add_block(self, block, gen_pc_updt=False): """ DEPRECATED function Use add_block instead of add_block """ warnings.warn("""DEPRECATION WARNING ircfg is now out of IntermediateRepresentation Use: ircfg = ir_arch.new_ircfg() ir_arch.add_asmblock_to_ircfg(block, ircfg) """) raise RuntimeError("API Deprecated")
def add_instr_to_current_state(
self, instr, block, assignments, ir_blocks_all, gen_pc_updt)
Inheritance:
ir_armtl
.add_instr_to_current_state
Add the IR effects of an instruction to the current state.
Returns a bool: True if the current assignments list must be split False in other cases.
@instr: native instruction @block: native block source @assignments: list of current AssignBlocks @ir_blocks_all: list of additional effects @gen_pc_updt: insert PC update effects between instructions
def add_instr_to_current_state(self, instr, block, assignments, ir_blocks_all, gen_pc_updt): """ Add the IR effects of an instruction to the current state. Returns a bool: * True if the current assignments list must be split * False in other cases. @instr: native instruction @block: native block source @assignments: list of current AssignBlocks @ir_blocks_all: list of additional effects @gen_pc_updt: insert PC update effects between instructions """ if gen_pc_updt is not False: self.gen_pc_update(assignments, instr) assignblk, ir_blocks_extra = self.instr2ir(instr) assignments.append(assignblk) ir_blocks_all += ir_blocks_extra if ir_blocks_extra: return True return False
def add_instr_to_ircfg(
self, instr, ircfg, loc_key=None, gen_pc_updt=False)
Inheritance:
ir_armtl
.add_instr_to_ircfg
Add the native instruction @instr to the @ircfg @instr: instruction instance @ircfg: IRCFG instance @loc_key: loc_key instance of the instruction destination @gen_pc_updt: insert PC update effects between instructions
def add_instr_to_ircfg(self, instr, ircfg, loc_key=None, gen_pc_updt=False): """ Add the native instruction @instr to the @ircfg @instr: instruction instance @ircfg: IRCFG instance @loc_key: loc_key instance of the instruction destination @gen_pc_updt: insert PC update effects between instructions """ if loc_key is None: offset = getattr(instr, "offset", None) loc_key = self.loc_db.add_location(offset=offset) block = AsmBlock(loc_key) block.lines = [instr] self.add_asmblock_to_ircfg(block, ircfg, gen_pc_updt) return loc_key
def do_it_block(
self, loc, index, block, assignments, gen_pc_updt)
Inheritance:
ir_armtl
.do_it_block
def do_it_block(self, loc, index, block, assignments, gen_pc_updt): instr = block.lines[index] it_hints, it_cond = self.parse_itt(instr) cond_num = cond_dct_inv[it_cond.name] cond_eq = tab_cond[cond_num] if not index + len(it_hints) <= len(block.lines): raise NotImplementedError("Splitted IT block non supported yet") ir_blocks_all = [] # Gen dummy irblock for IT instr loc_next = self.get_next_loc_key(instr) dst = ExprAff(self.IRDst, ExprId(loc_next, 32)) dst_blk = AssignBlock([dst], instr) assignments.append(dst_blk) irblock = IRBlock(loc, assignments) ir_blocks_all.append([irblock]) loc = loc_next assignments = [] for hint in it_hints: irblocks = [] index += 1 instr = block.lines[index] # Add conditionnal jump to current irblock loc_do = self.loc_db.add_location() loc_next = self.get_next_loc_key(instr) if hint: local_cond = ~cond_eq else: local_cond = cond_eq dst = ExprAff(self.IRDst, ExprCond(local_cond, ExprLoc(loc_do, 32), ExprLoc(loc_next, 32))) dst_blk = AssignBlock([dst], instr) assignments.append(dst_blk) irblock = IRBlock(loc, assignments) irblocks.append(irblock) assignments = [] loc = loc_do split = self.add_instr_to_current_state( instr, block, assignments, irblocks, gen_pc_updt ) if split: raise NotImplementedError("Unsupported instr in IT block (%s)" % instr) dst = ExprAff(self.IRDst, ExprId(loc_next, 32)) dst_blk = AssignBlock([dst], instr) assignments.append(dst_blk) irblock = IRBlock(loc, assignments) irblocks.append(irblock) loc = loc_next assignments = [] ir_blocks_all.append(irblocks) return index, ir_blocks_all
def expr_fix_regs_for_mode(
self, expr, *args, **kwargs)
Inheritance:
ir_armtl
.expr_fix_regs_for_mode
def expr_fix_regs_for_mode(self, expr, *args, **kwargs): return expr
def expraff_fix_regs_for_mode(
self, expr, *args, **kwargs)
Inheritance:
ir_armtl
.expraff_fix_regs_for_mode
def expraff_fix_regs_for_mode(self, expr, *args, **kwargs): return expr
def gen_loc_key_and_expr(
self, size)
Inheritance:
ir_armtl
.gen_loc_key_and_expr
Return a loc_key and it's corresponding ExprLoc @size: size of expression
def gen_loc_key_and_expr(self, size): """ Return a loc_key and it's corresponding ExprLoc @size: size of expression """ loc_key = self.loc_db.add_location() return loc_key, m2_expr.ExprLoc(loc_key, size)
def gen_pc_update(
self, assignments, instr)
Inheritance:
ir_armtl
.gen_pc_update
def gen_pc_update(self, assignments, instr): offset = m2_expr.ExprInt(instr.offset, self.pc.size) assignments.append(AssignBlock({self.pc:offset}, instr))
def get_ir(
self, instr)
def get_ir(self, instr): args = instr.args # ir = get_mnemo_expr(self, self.name.lower(), *args) if len(args) and isinstance(args[-1], ExprOp): if args[-1].op == 'rrx': args[-1] = ExprCompose(args[-1].args[0][1:], cf) elif (args[-1].op in ['<<', '>>', '<<a', 'a>>', '<<<', '>>>'] and isinstance(args[-1].args[-1], ExprId)): args[-1] = ExprOp(args[-1].op, args[-1].args[0], args[-1].args[-1][:8].zeroExtend(32)) instr_ir, extra_ir = get_mnemo_expr(self, instr, *args) self.mod_pc(instr, instr_ir, extra_ir) return instr_ir, extra_ir
def get_loc_key_for_instr(
self, instr)
Inheritance:
ir_armtl
.get_loc_key_for_instr
Returns the loc_key associated to an instruction @instr: current instruction
def get_loc_key_for_instr(self, instr): """Returns the loc_key associated to an instruction @instr: current instruction""" return self.loc_db.get_or_create_offset_location(instr.offset)
def get_next_loc_key(
self, instr)
Inheritance:
ir_armtl
.get_next_loc_key
def get_next_loc_key(self, instr): loc_key = self.loc_db.get_or_create_offset_location(instr.offset + instr.l) return loc_key
def instr2ir(
self, instr)
Inheritance:
ir_armtl
.instr2ir
def instr2ir(self, instr): ir_bloc_cur, extra_irblocks = self.get_ir(instr) for index, irb in enumerate(extra_irblocks): irs = [] for assignblk in irb: irs.append(AssignBlock(assignblk, instr)) extra_irblocks[index] = IRBlock(irb.loc_key, irs) assignblk = AssignBlock(ir_bloc_cur, instr) return assignblk, extra_irblocks
def irbloc_fix_regs_for_mode(
self, irblock, *args, **kwargs)
Inheritance:
ir_armtl
.irbloc_fix_regs_for_mode
def irbloc_fix_regs_for_mode(self, irblock, *args, **kwargs): return irblock
def is_pc_written(
self, block)
Inheritance:
ir_armtl
.is_pc_written
Return the first Assignblk of the @blockin which PC is written @block: IRBlock instance
def is_pc_written(self, block): """Return the first Assignblk of the @blockin which PC is written @block: IRBlock instance""" all_pc = self.arch.pc.values() for assignblk in block: if assignblk.dst in all_pc: return assignblk return None
def mod_pc(
self, instr, instr_ir, extra_ir)
def mod_pc(self, instr, instr_ir, extra_ir): # fix PC (+4 for thumb) pc_fixed = {self.pc: ExprInt(instr.offset + 4, 32)} for i, expr in enumerate(instr_ir): dst, src = expr.dst, expr.src if dst != self.pc: dst = dst.replace_expr(pc_fixed) src = src.replace_expr(pc_fixed) instr_ir[i] = ExprAff(dst, src) for idx, irblock in enumerate(extra_ir): extra_ir[idx] = irblock.modify_exprs(lambda expr: expr.replace_expr(pc_fixed) \ if expr != self.pc else expr, lambda expr: expr.replace_expr(pc_fixed))
def new_ircfg(
self, *args, **kwargs)
Inheritance:
ir_armtl
.new_ircfg
Return a new instance of IRCFG
def new_ircfg(self, *args, **kwargs): """ Return a new instance of IRCFG """ return IRCFG(self.IRDst, self.loc_db, *args, **kwargs)
def new_ircfg_from_asmcfg(
self, asmcfg, *args, **kwargs)
Inheritance:
ir_armtl
.new_ircfg_from_asmcfg
Return a new instance of IRCFG from an @asmcfg @asmcfg: AsmCFG instance
def new_ircfg_from_asmcfg(self, asmcfg, *args, **kwargs): """ Return a new instance of IRCFG from an @asmcfg @asmcfg: AsmCFG instance """ ircfg = IRCFG(self.IRDst, self.loc_db, *args, **kwargs) for block in asmcfg.blocks: self.add_asmblock_to_ircfg(block, ircfg) return ircfg
def parse_itt(
self, instr)
Inheritance:
ir_armtl
.parse_itt
def parse_itt(self, instr): name = instr.name assert name.startswith('IT') name = name[1:] out = [] for hint in name: if hint == 'T': out.append(0) elif hint == "E": out.append(1) else: raise ValueError("IT name invalid %s" % instr) return out, instr.args[0]
def post_add_asmblock_to_ircfg(
self, block, ircfg, ir_blocks)
Inheritance:
ir_armtl
.post_add_asmblock_to_ircfg
def post_add_asmblock_to_ircfg(self, block, ircfg, ir_blocks): self.set_empty_dst_to_next(block, ir_blocks) new_irblocks = [] for irblock in ir_blocks: new_irblock = self.irbloc_fix_regs_for_mode(irblock, self.attrib) ircfg.add_irblock(new_irblock) new_irblocks.append(new_irblock) return new_irblocks
def set_empty_dst_to_next(
self, block, ir_blocks)
Inheritance:
ir_armtl
.set_empty_dst_to_next
def set_empty_dst_to_next(self, block, ir_blocks): for index, irblock in enumerate(ir_blocks): if irblock.dst is not None: continue next_loc_key = block.get_next() if next_loc_key is None: loc_key = None if block.lines: line = block.lines[-1] if line.offset is not None: loc_key = self.loc_db.get_or_create_offset_location(line.offset + line.l) if loc_key is None: loc_key = self.loc_db.add_location() block.add_cst(loc_key, AsmConstraint.c_next) else: loc_key = next_loc_key dst = m2_expr.ExprLoc(loc_key, self.pc.size) if irblock.assignblks: instr = irblock.assignblks[-1].instr else: instr = None assignblk = AssignBlock({self.IRDst: dst}, instr) ir_blocks[index] = IRBlock(irblock.loc_key, list(irblock.assignblks) + [assignblk])
class ir_armtl
class ir_armtl(ir_arml): def __init__(self, loc_db=None): IntermediateRepresentation.__init__(self, mn_armt, "l", loc_db) self.pc = PC self.sp = SP self.IRDst = ExprId('IRDst', 32) self.addrsize = 32 def mod_pc(self, instr, instr_ir, extra_ir): # fix PC (+4 for thumb) pc_fixed = {self.pc: ExprInt(instr.offset + 4, 32)} for i, expr in enumerate(instr_ir): dst, src = expr.dst, expr.src if dst != self.pc: dst = dst.replace_expr(pc_fixed) src = src.replace_expr(pc_fixed) instr_ir[i] = ExprAff(dst, src) for idx, irblock in enumerate(extra_ir): extra_ir[idx] = irblock.modify_exprs(lambda expr: expr.replace_expr(pc_fixed) \ if expr != self.pc else expr, lambda expr: expr.replace_expr(pc_fixed))
Ancestors (in MRO)
Instance variables
Methods
def __init__(
self, loc_db=None)
def __init__(self, loc_db=None): IntermediateRepresentation.__init__(self, mn_armt, "l", loc_db) self.pc = PC self.sp = SP self.IRDst = ExprId('IRDst', 32) self.addrsize = 32
def add_asmblock_to_ircfg(
self, block, ircfg, gen_pc_updt=False)
Inheritance:
ir_arml
.add_asmblock_to_ircfg
Add a native block to the current IR @block: native assembly block @gen_pc_updt: insert PC update effects between instructions
def add_asmblock_to_ircfg(self, block, ircfg, gen_pc_updt=False): """ Add a native block to the current IR @block: native assembly block @gen_pc_updt: insert PC update effects between instructions """ it_hints = None it_cond = None label = block.loc_key assignments = [] ir_blocks_all = [] index = -1 while index + 1 < len(block.lines): index += 1 instr = block.lines[index] if label is None: assignments = [] label = self.get_loc_key_for_instr(instr) if instr.name.startswith("IT"): index, irblocks_it = self.do_it_block(label, index, block, assignments, gen_pc_updt) for irblocks in irblocks_it: ir_blocks_all += irblocks label = None continue split = self.add_instr_to_current_state( instr, block, assignments, ir_blocks_all, gen_pc_updt ) if split: ir_blocks_all.append(IRBlock(label, assignments)) label = None assignments = [] if label is not None: ir_blocks_all.append(IRBlock(label, assignments)) new_ir_blocks_all = self.post_add_asmblock_to_ircfg(block, ircfg, ir_blocks_all) for irblock in new_ir_blocks_all: ircfg.add_irblock(irblock) return new_ir_blocks_all
def add_bloc(
self, block, gen_pc_updt=False)
DEPRECATED function Use add_block instead of add_block
def add_bloc(self, block, gen_pc_updt=False): """ DEPRECATED function Use add_block instead of add_block """ self.add_block(block, gen_pc_updt)
def add_block(
self, block, gen_pc_updt=False)
Inheritance:
ir_arml
.add_block
DEPRECATED function Use add_block instead of add_block
def add_block(self, block, gen_pc_updt=False): """ DEPRECATED function Use add_block instead of add_block """ warnings.warn("""DEPRECATION WARNING ircfg is now out of IntermediateRepresentation Use: ircfg = ir_arch.new_ircfg() ir_arch.add_asmblock_to_ircfg(block, ircfg) """) raise RuntimeError("API Deprecated")
def add_instr_to_current_state(
self, instr, block, assignments, ir_blocks_all, gen_pc_updt)
Inheritance:
ir_arml
.add_instr_to_current_state
Add the IR effects of an instruction to the current state.
Returns a bool: True if the current assignments list must be split False in other cases.
@instr: native instruction @block: native block source @assignments: list of current AssignBlocks @ir_blocks_all: list of additional effects @gen_pc_updt: insert PC update effects between instructions
def add_instr_to_current_state(self, instr, block, assignments, ir_blocks_all, gen_pc_updt): """ Add the IR effects of an instruction to the current state. Returns a bool: * True if the current assignments list must be split * False in other cases. @instr: native instruction @block: native block source @assignments: list of current AssignBlocks @ir_blocks_all: list of additional effects @gen_pc_updt: insert PC update effects between instructions """ if gen_pc_updt is not False: self.gen_pc_update(assignments, instr) assignblk, ir_blocks_extra = self.instr2ir(instr) assignments.append(assignblk) ir_blocks_all += ir_blocks_extra if ir_blocks_extra: return True return False
def add_instr_to_ircfg(
self, instr, ircfg, loc_key=None, gen_pc_updt=False)
Inheritance:
ir_arml
.add_instr_to_ircfg
Add the native instruction @instr to the @ircfg @instr: instruction instance @ircfg: IRCFG instance @loc_key: loc_key instance of the instruction destination @gen_pc_updt: insert PC update effects between instructions
def add_instr_to_ircfg(self, instr, ircfg, loc_key=None, gen_pc_updt=False): """ Add the native instruction @instr to the @ircfg @instr: instruction instance @ircfg: IRCFG instance @loc_key: loc_key instance of the instruction destination @gen_pc_updt: insert PC update effects between instructions """ if loc_key is None: offset = getattr(instr, "offset", None) loc_key = self.loc_db.add_location(offset=offset) block = AsmBlock(loc_key) block.lines = [instr] self.add_asmblock_to_ircfg(block, ircfg, gen_pc_updt) return loc_key
def do_it_block(
self, loc, index, block, assignments, gen_pc_updt)
Inheritance:
ir_arml
.do_it_block
def do_it_block(self, loc, index, block, assignments, gen_pc_updt): instr = block.lines[index] it_hints, it_cond = self.parse_itt(instr) cond_num = cond_dct_inv[it_cond.name] cond_eq = tab_cond[cond_num] if not index + len(it_hints) <= len(block.lines): raise NotImplementedError("Splitted IT block non supported yet") ir_blocks_all = [] # Gen dummy irblock for IT instr loc_next = self.get_next_loc_key(instr) dst = ExprAff(self.IRDst, ExprId(loc_next, 32)) dst_blk = AssignBlock([dst], instr) assignments.append(dst_blk) irblock = IRBlock(loc, assignments) ir_blocks_all.append([irblock]) loc = loc_next assignments = [] for hint in it_hints: irblocks = [] index += 1 instr = block.lines[index] # Add conditionnal jump to current irblock loc_do = self.loc_db.add_location() loc_next = self.get_next_loc_key(instr) if hint: local_cond = ~cond_eq else: local_cond = cond_eq dst = ExprAff(self.IRDst, ExprCond(local_cond, ExprLoc(loc_do, 32), ExprLoc(loc_next, 32))) dst_blk = AssignBlock([dst], instr) assignments.append(dst_blk) irblock = IRBlock(loc, assignments) irblocks.append(irblock) assignments = [] loc = loc_do split = self.add_instr_to_current_state( instr, block, assignments, irblocks, gen_pc_updt ) if split: raise NotImplementedError("Unsupported instr in IT block (%s)" % instr) dst = ExprAff(self.IRDst, ExprId(loc_next, 32)) dst_blk = AssignBlock([dst], instr) assignments.append(dst_blk) irblock = IRBlock(loc, assignments) irblocks.append(irblock) loc = loc_next assignments = [] ir_blocks_all.append(irblocks) return index, ir_blocks_all
def expr_fix_regs_for_mode(
self, expr, *args, **kwargs)
Inheritance:
ir_arml
.expr_fix_regs_for_mode
def expr_fix_regs_for_mode(self, expr, *args, **kwargs): return expr
def expraff_fix_regs_for_mode(
self, expr, *args, **kwargs)
Inheritance:
ir_arml
.expraff_fix_regs_for_mode
def expraff_fix_regs_for_mode(self, expr, *args, **kwargs): return expr
def gen_loc_key_and_expr(
self, size)
Inheritance:
ir_arml
.gen_loc_key_and_expr
Return a loc_key and it's corresponding ExprLoc @size: size of expression
def gen_loc_key_and_expr(self, size): """ Return a loc_key and it's corresponding ExprLoc @size: size of expression """ loc_key = self.loc_db.add_location() return loc_key, m2_expr.ExprLoc(loc_key, size)
def gen_pc_update(
self, assignments, instr)
Inheritance:
ir_arml
.gen_pc_update
def gen_pc_update(self, assignments, instr): offset = m2_expr.ExprInt(instr.offset, self.pc.size) assignments.append(AssignBlock({self.pc:offset}, instr))
def get_ir(
self, instr)
def get_ir(self, instr): args = instr.args # ir = get_mnemo_expr(self, self.name.lower(), *args) if len(args) and isinstance(args[-1], ExprOp): if args[-1].op == 'rrx': args[-1] = ExprCompose(args[-1].args[0][1:], cf) elif (args[-1].op in ['<<', '>>', '<<a', 'a>>', '<<<', '>>>'] and isinstance(args[-1].args[-1], ExprId)): args[-1] = ExprOp(args[-1].op, args[-1].args[0], args[-1].args[-1][:8].zeroExtend(32)) instr_ir, extra_ir = get_mnemo_expr(self, instr, *args) self.mod_pc(instr, instr_ir, extra_ir) return instr_ir, extra_ir
def get_loc_key_for_instr(
self, instr)
Inheritance:
ir_arml
.get_loc_key_for_instr
Returns the loc_key associated to an instruction @instr: current instruction
def get_loc_key_for_instr(self, instr): """Returns the loc_key associated to an instruction @instr: current instruction""" return self.loc_db.get_or_create_offset_location(instr.offset)
def get_next_loc_key(
self, instr)
Inheritance:
ir_arml
.get_next_loc_key
def get_next_loc_key(self, instr): loc_key = self.loc_db.get_or_create_offset_location(instr.offset + instr.l) return loc_key
def instr2ir(
self, instr)
def instr2ir(self, instr): ir_bloc_cur, extra_irblocks = self.get_ir(instr) for index, irb in enumerate(extra_irblocks): irs = [] for assignblk in irb: irs.append(AssignBlock(assignblk, instr)) extra_irblocks[index] = IRBlock(irb.loc_key, irs) assignblk = AssignBlock(ir_bloc_cur, instr) return assignblk, extra_irblocks
def irbloc_fix_regs_for_mode(
self, irblock, *args, **kwargs)
Inheritance:
ir_arml
.irbloc_fix_regs_for_mode
def irbloc_fix_regs_for_mode(self, irblock, *args, **kwargs): return irblock
def is_pc_written(
self, block)
Inheritance:
ir_arml
.is_pc_written
Return the first Assignblk of the @blockin which PC is written @block: IRBlock instance
def is_pc_written(self, block): """Return the first Assignblk of the @blockin which PC is written @block: IRBlock instance""" all_pc = self.arch.pc.values() for assignblk in block: if assignblk.dst in all_pc: return assignblk return None
def mod_pc(
self, instr, instr_ir, extra_ir)
def mod_pc(self, instr, instr_ir, extra_ir): # fix PC (+4 for thumb) pc_fixed = {self.pc: ExprInt(instr.offset + 4, 32)} for i, expr in enumerate(instr_ir): dst, src = expr.dst, expr.src if dst != self.pc: dst = dst.replace_expr(pc_fixed) src = src.replace_expr(pc_fixed) instr_ir[i] = ExprAff(dst, src) for idx, irblock in enumerate(extra_ir): extra_ir[idx] = irblock.modify_exprs(lambda expr: expr.replace_expr(pc_fixed) \ if expr != self.pc else expr, lambda expr: expr.replace_expr(pc_fixed))
def new_ircfg(
self, *args, **kwargs)
Inheritance:
ir_arml
.new_ircfg
Return a new instance of IRCFG
def new_ircfg(self, *args, **kwargs): """ Return a new instance of IRCFG """ return IRCFG(self.IRDst, self.loc_db, *args, **kwargs)
def new_ircfg_from_asmcfg(
self, asmcfg, *args, **kwargs)
Inheritance:
ir_arml
.new_ircfg_from_asmcfg
Return a new instance of IRCFG from an @asmcfg @asmcfg: AsmCFG instance
def new_ircfg_from_asmcfg(self, asmcfg, *args, **kwargs): """ Return a new instance of IRCFG from an @asmcfg @asmcfg: AsmCFG instance """ ircfg = IRCFG(self.IRDst, self.loc_db, *args, **kwargs) for block in asmcfg.blocks: self.add_asmblock_to_ircfg(block, ircfg) return ircfg
def parse_itt(
self, instr)
Inheritance:
ir_arml
.parse_itt
def parse_itt(self, instr): name = instr.name assert name.startswith('IT') name = name[1:] out = [] for hint in name: if hint == 'T': out.append(0) elif hint == "E": out.append(1) else: raise ValueError("IT name invalid %s" % instr) return out, instr.args[0]
def post_add_asmblock_to_ircfg(
self, block, ircfg, ir_blocks)
Inheritance:
ir_arml
.post_add_asmblock_to_ircfg
def post_add_asmblock_to_ircfg(self, block, ircfg, ir_blocks): self.set_empty_dst_to_next(block, ir_blocks) new_irblocks = [] for irblock in ir_blocks: new_irblock = self.irbloc_fix_regs_for_mode(irblock, self.attrib) ircfg.add_irblock(new_irblock) new_irblocks.append(new_irblock) return new_irblocks
def set_empty_dst_to_next(
self, block, ir_blocks)
Inheritance:
ir_arml
.set_empty_dst_to_next
def set_empty_dst_to_next(self, block, ir_blocks): for index, irblock in enumerate(ir_blocks): if irblock.dst is not None: continue next_loc_key = block.get_next() if next_loc_key is None: loc_key = None if block.lines: line = block.lines[-1] if line.offset is not None: loc_key = self.loc_db.get_or_create_offset_location(line.offset + line.l) if loc_key is None: loc_key = self.loc_db.add_location() block.add_cst(loc_key, AsmConstraint.c_next) else: loc_key = next_loc_key dst = m2_expr.ExprLoc(loc_key, self.pc.size) if irblock.assignblks: instr = irblock.assignblks[-1].instr else: instr = None assignblk = AssignBlock({self.IRDst: dst}, instr) ir_blocks[index] = IRBlock(irblock.loc_key, list(irblock.assignblks) + [assignblk])