def fcmpe(ir, instr, arg1, arg2): e = [] e.append(ExprAssign(nf, ExprOp('fcom_c0', arg1, arg2))) e.append(ExprAssign(cf, ~ExprOp('fcom_c0', arg1, arg2))) e.append(ExprAssign(zf, ExprOp('fcom_c3', arg1, arg2))) e.append(ExprAssign(of, ExprInt(0, 1))) return e, []
def get_mem_access(mem): updt = None if isinstance(mem, ExprOp): if mem.op == 'preinc': addr = mem.args[0] + mem.args[1] elif mem.op == 'segm': base = mem.args[0] op, (reg, shift) = mem.args[1].op, mem.args[1].args if op == 'SXTW': off = reg.signExtend(base.size) << shift.zeroExtend(base.size) addr = base + off elif op == 'UXTW': off = reg.zeroExtend(base.size) << shift.zeroExtend(base.size) addr = base + off elif op == 'LSL': if isinstance(shift, ExprInt) and int(shift) == 0: addr = base + reg.zeroExtend(base.size) else: addr = base + \ (reg.zeroExtend(base.size) << shift.zeroExtend(base.size)) else: raise NotImplementedError('bad op') elif mem.op == "postinc": addr, off = mem.args updt = ExprAssign(addr, addr + off) elif mem.op == "preinc_wb": base, off = mem.args addr = base + off updt = ExprAssign(base, base + off) else: raise NotImplementedError('bad op') else: raise NotImplementedError('bad op') return addr, updt
def stlxrb(ir, instr, arg1, arg2, arg3): assert arg3.is_op('preinc') assert len(arg3.args) == 1 ptr = arg3.args[0] e = [] e.append(ExprAssign(ExprMem(ptr, 8), arg2[:8])) # TODO XXX here, force update success e.append(ExprAssign(arg1, ExprInt(0, arg1.size))) return e, []
def bics(ir, instr, arg1, arg2, arg3): e = [] tmp1, tmp2 = arg2, (~extend_arg(arg2, arg3)) res = tmp1 & tmp2 e += [ExprAssign(zf, ExprOp('FLAG_EQ_AND', tmp1, tmp2))] e += update_flag_nf(res) e.append(ExprAssign(arg1, res)) return e, []
def ands(ir, instr, arg1, arg2, arg3): e = [] arg3 = extend_arg(arg2, arg3) res = arg2 & arg3 e += [ExprAssign(zf, ExprOp('FLAG_EQ_AND', arg2, arg3))] e += update_flag_nf(res) e.append(ExprAssign(arg1, res)) return e, []
def ldp(ir, instr, arg1, arg2, arg3): e = [] addr, updt = get_mem_access(arg3) e.append(ExprAssign(arg1, ExprMem(addr, arg1.size))) e.append( ExprAssign( arg2, ExprMem(addr + ExprInt(arg1.size / 8, addr.size), arg2.size))) if updt: e.append(updt) return e, []
def call_effects(self, ad, instr): print hex(instr.offset), instr stk_before = idc.GetSpd(instr.offset) stk_after = idc.GetSpd(instr.offset + instr.l) stk_diff = stk_after - stk_before print hex(stk_diff) call_assignblk = AssignBlock([ ExprAssign(self.ret_reg, ExprOp('call_func_ret', ad)), ExprAssign(self.sp, self.sp + ExprInt(stk_diff, self.sp.size)) ], instr) return [call_assignblk], []
def movk(ir, instr, arg1, arg2): e = [] if isinstance(arg2, ExprOp): assert (arg2.op == 'slice_at' and isinstance(arg2.args[0], ExprInt) and isinstance(arg2.args[1], ExprInt)) value, shift = int(arg2.args[0].arg), int(arg2.args[1]) e.append(ExprAssign(arg1[shift:shift + 16], ExprInt(value, 16))) else: e.append(ExprAssign(arg1[:16], ExprInt(int(arg2), 16))) return e, []
def bfm(ir, instr, arg1, arg2, arg3, arg4): e = [] rim, sim = int(arg3.arg), int(arg4) + 1 if sim > rim: res = arg2[rim:sim] e.append(ExprAssign(arg1[:sim - rim], res)) else: shift_i = arg2.size - rim shift = ExprInt(shift_i, arg2.size) res = arg2[:sim] e.append(ExprAssign(arg1[shift_i:shift_i + sim], res)) return e, []
def msr(ir, instr, arg1, arg2, arg3, arg4, arg5): e = [] if arg1.is_int(3) and arg2.is_id("c4") and arg3.is_id( "c2") and arg4.is_int(0): e.append(ExprAssign(nf, arg5[31:32])) e.append(ExprAssign(zf, arg5[30:31])) e.append(ExprAssign(cf, arg5[29:30])) e.append(ExprAssign(of, arg5[28:29])) else: raise NotImplementedError("MSR not implemented") return e, []
def __init__(self, irblock): self.loc_key = irblock.loc_key self.infos = [] self.assignblks = [] for assignblk in irblock: gens, kills = set(), set() for dst, src in assignblk.iteritems(): expr = ExprAssign(dst, src) read = expr.get_r(mem_read=True) write = expr.get_w() gens.update(read) kills.update(write) self.infos.append(AssignBlockLivenessInfos(assignblk, gens, kills)) self.assignblks.append(assignblk)
def jmp(ir, instr, reg_or_imm): """JMP - Change PC to a register content or an immediate. Note: the behavior in VLIW mode is not implemented""" take_jmp = ExprInt(1, 32) if isinstance(reg_or_imm, ExprId): # PC <- Rm31..1||0 new_PC = ExprAssign(PC, reg_or_imm) else: # PC <- PC31..28||0000||(target24)23..1||0 new_PC = ExprAssign(PC, ExprOp("+", ExprOp("&", PC, ExprInt(0xF0000000, 32)), reg_or_imm)) return [new_PC, ExprAssign(ir.IRDst, new_PC)], []
def call_effects(self, ad, instr): call_assignblks = AssignBlock([ ExprAssign( self.ret_reg, ExprOp( 'call_func_ret', ad, self.sp, self.arch.regs.R3, self.arch.regs.R4, self.arch.regs.R5, )), ExprAssign(self.sp, ExprOp('call_func_stack', ad, self.sp)), ], instr) return [call_assignblks], []
def csinc(ir, instr, arg1, arg2, arg3, arg4): e = [] cond_expr = cond2expr[arg4.name] e.append( ExprAssign(arg1, ExprCond(cond_expr, arg2, arg3 + ExprInt(1, arg3.size)))) return e, []
def _gen_path_constraints(self, translator, expr, expected): """Generate path constraint from @expr. Handle special case with generated loc_keys """ out = [] expected = self._ircfg.loc_db.canonize_to_exprloc(expected) expected_is_loc_key = expected.is_loc() for consval in possible_values(expr): value = self._ircfg.loc_db.canonize_to_exprloc(consval.value) if expected_is_loc_key and value != expected: continue if not expected_is_loc_key and value.is_loc_key(): continue conds = z3.And(*[ translator.from_expr(cond.to_constraint()) for cond in consval.constraints ]) if expected != value: conds = z3.And( conds, translator.from_expr(ExprAssign(value, expected))) out.append(conds) if out: conds = z3.Or(*out) else: # Ex: expr: lblgen1, expected: 0x1234 # -> Avoid unconsistent solution lblgen1 = 0x1234 conds = translator.from_expr(self.unsat_expr) return conds
def m2instruction_to_r2esil(instruction, loc_db): """Convert a miasm2 instruction to a radare2 ESIL""" # Get the IR try: machine = miasm_machine() ir = machine.ir(loc_db) iir, eiir = ir.get_ir(instruction) except: iir, eiir = [], [] # Convert IRs result = list() if iir: result += [m2expr_to_r2esil(ir, loc_db) for ir in m2_filter_IRDst(iir)] for irblock in eiir: for ir_list in irblock.assignblks: aff = (ExprAssign(dst, src) for dst, src in ir_list.iteritems()) result += (m2expr_to_r2esil(ir, loc_db) for ir in m2_filter_IRDst(aff)) if not len(result): return None return ",".join(result)
def ldrs_size(ir, instr, arg1, arg2, size): e = [] addr, updt = get_mem_access(arg2) e.append(ExprAssign(arg1, ExprMem(addr, size).signExtend(arg1.size))) if updt: e.append(updt) return e, []
def fmov(ir, instr, arg1, arg2): if arg2.is_int(): # Transform int to signed floating-point constant with 3-bit exponent # and normalized 4 bits of precision # VFPExpandImm() of ARM Architecture Reference Manual imm8 = int(arg2) N = arg1.size assert N in [32, 64] E = 8 if N == 32 else 11 F = N - E - 1 # sign = imm8<7>; sign = (imm8 >> 7) & 1 # exp = NOT(imm8<6>):Replicate(imm8<6>,E-3):imm8<5:4>; exp = (((imm8 >> 6) & 1) ^ 1) << (E - 3 + 2) if (imm8 >> 6) & 1: tmp = (1 << (E - 3)) - 1 else: tmp = 0 exp |= tmp << 2 exp |= (imm8 >> 4) & 3 # frac = imm8<3:0>:Zeros(F-4); frac = (imm8 & 0xf) << (F - 4) value = frac value |= exp << (4 + F - 4) value |= sign << (4 + F - 4 + 1 + E - 3 + 2) arg2 = ExprInt(value, N) e = [ExprAssign(arg1, arg2)] return e, []
def strh(ir, instr, arg1, arg2): e = [] addr, updt = get_mem_access(arg2) e.append(ExprAssign(ExprMem(addr, 16), arg1[:16])) if updt: e.append(updt) return e, []
def l_str(ir, instr, arg1, arg2): e = [] addr, updt = get_mem_access(arg2) e.append(ExprAssign(ExprMem(addr, arg1.size), arg1)) if updt: e.append(updt) return e, []
def cset(ir, instr, arg1, arg2): e = [] cond_expr = cond2expr[arg2.name] e.append( ExprAssign( arg1, ExprCond(cond_expr, ExprInt(1, arg1.size), ExprInt(0, arg1.size)))) 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 += [ExprAssign(nf, ExprOp("FLAG_SIGN_SUB", arg1, arg2))] return e
def sbcs(ir, instr, arg1, arg2, arg3): arg3 = extend_arg(arg2, arg3) e = [] r = arg2 - (arg3 + (~cf).zeroExtend(arg3.size)) e.append(ExprAssign(arg1, r)) e += update_flag_arith_subwc_zn(arg2, arg3, ~cf) e += update_flag_arith_subwc_co(arg2, arg3, ~cf) return e, []
def adcs(ir, instr, arg1, arg2, arg3): arg3 = extend_arg(arg2, arg3) e = [] r = arg2 + arg3 + cf.zeroExtend(arg3.size) e.append(ExprAssign(arg1, r)) e += update_flag_arith_addwc_zn(arg2, arg3, cf) e += update_flag_arith_addwc_co(arg2, arg3, cf) return e, []
def _gen_empty_phi(self, expr): """ Generates an empty phi function for a variable :param expr: variable :return: ExprAssign, empty phi function for expr """ phi = ExprId(self.PHI_STR, expr.size) return ExprAssign(expr, phi)
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 += [ExprAssign(nf, ExprOp("FLAG_SIGN_ADDWC", arg1, arg2, arg3))] return e
def ucvtf(ir, instr, arg1, arg2): # XXX TODO: rounding e = [] src = ExprOp('uint_to_fp', arg2) if arg1.size != src.size: src = ExprOp('fpconvert_fp%d' % arg1.size, src) e.append(ExprAssign(arg1, src)) 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 += [ExprAssign(nf, ExprOp("FLAG_SIGN_SUBWC", arg1, arg2, arg3))] return e
def ldaxrb(ir, instr, arg1, arg2): # TODO XXX no memory lock implemented assert arg2.is_op('preinc') assert len(arg2.args) == 1 ptr = arg2.args[0] e = [] e.append(ExprAssign(arg1, ExprMem(ptr, 8).zeroExtend(arg1.size))) return e, []
def rev16(ir, instr, arg1, arg2): out = [] for i in xrange(0, arg2.size / 8): index = (i & ~1) + (1 - (i & 1)) out.append(arg2[index * 8:(index + 1) * 8]) e = [] result = ExprCompose(*out) e.append(ExprAssign(arg1, result)) return e, []