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 call_effects(self, addr, instr): assignblks, extra = super(IRADelModCallStack, self).call_effects(addr, instr) if use_ida_stack: stk_before = idc.get_spd(instr.offset) stk_after = idc.get_spd(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', addr)), ExprAssign(self.sp, self.sp + ExprInt(stk_diff, self.sp.size)) ], instr) return [call_assignblk], [] else: if not dontmodstack: return assignblks, extra out = [] for assignblk in assignblks: dct = dict(assignblk) dct = { dst: src for (dst, src) in viewitems(dct) if dst != self.sp } out.append(AssignBlock(dct, assignblk.instr)) return out, extra
def lmcpi(ir, instr, reg_dst, deref_src): """LMCPI - Load Word from memory, and increment the address""" # CRn <- MemDword(Rm31..3||000); Rm<-Rm+8 e = [] e.append(ExprAssign(reg_dst, ExprMem(deref_src.ptr & i32(0xFFFFFFFC), 32))) e.append(ExprAssign(deref_src.ptr, deref_src.ptr + i32(8))) return e, []
def smcpi(ir, instr, reg_src, deref_dst): """SMCPI - Store Word to memory, and increment the address""" # MemDword(Rm31..3||000) <- CRn; Rm<-Rm+8 e = [] e.append(ExprAssign(ExprMem(deref_dst.ptr & i32(0xFFFFFFF8), 32), reg_src)) e.append(ExprAssign(deref_dst.ptr, deref_dst.ptr + i32(8))) return e, []
def swcpi(ir, instr, reg_src, deref_dst): """SWCPI - Store Word to memory, and increment the address""" # MemWord(Rm31..2||00) <- CRn 31..0; Rm<-Rm+4 e = [] e.append(ExprAssign(ExprMem(deref_dst.ptr & i32(0xFFFFFFFC), 32), reg_src)) e.append(ExprAssign(deref_dst.ptr, deref_dst.ptr + i32(4))) return e, []
def tas(ir, instr, rn, rm_deref): """TAS - Load And Set""" # temp <- Rm; Rn <- ZeroExt(MemByte(temp)); MemByte(temp) <- 1 e = [] temp = rm_deref e.append(ExprAssign(rn, ExprMem(temp.ptr, 8).zeroExtend(32))) e.append(ExprAssign(ExprMem(temp.ptr, 8), i8(1))) return e, []
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 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]), 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 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.get_spd(instr.offset) stk_after = idc.get_spd(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 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 bfm(ir, instr, arg1, arg2, arg3, arg4): e = [] rim, sim = int(arg3), 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 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 _gen_path_constraints(self, translator, expr, expected): """Generate path constraint from @expr. Handle special case with generated loc_keys """ out = [] expected = canonize_to_exprloc(self._ircfg.loc_db, expected) expected_is_loc_key = expected.is_loc() for consval in possible_values(expr): value = canonize_to_exprloc(self._ircfg.loc_db, 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 inconsistent solution lblgen1 = 0x1234 conds = translator.from_expr(self.unsat_expr) return conds
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 smcp(ir, instr, reg_src, deref_dst): """SMCP - Store Word to memory from a coprocessor register""" # MemDword(Rm31..3||000) <- CRn e = [] e.append(ExprAssign(ExprMem(deref_dst.ptr & i32(0xFFFFFFF8), 32), reg_src)) return e, []
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 lmcp(ir, instr, reg_dst, deref_src): """LMCP - Load Word from memory to a coprocessor register""" # CRn <- MemDword(Rm31..3||000) e = [] e.append(ExprAssign(reg_dst, ExprMem(deref_src.ptr & i32(0xFFFFFFF8), 32))) return e, []
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 bsetm(ir, instr, rm_deref, imm3): """BSETM - Bit Set Memory""" # MemByte(Rm) <- MemByte(Rm) or (1<<imm3) e = [] e.append(ExprAssign(ExprMem(rm_deref.ptr, 8), ExprOp("|", ExprMem(rm_deref.ptr, 8), (i8(1) << imm3[:8])))) return e, []
def bnotm(ir, instr, rm_deref, imm3): """BNOTM - Bit Not Memory""" # MemByte(Rm) <- MemByte(Rm) xor (1<<imm3) e = [] e.append(ExprAssign(ExprMem(rm_deref.ptr, 8), ExprOp("^", ExprMem(rm_deref.ptr, 8), (i8(1) << imm3[:8])))) return e, []
def btstm(ir, instr, r0, rm_deref, imm3): """BTSTM - Bit Test Memory""" # R0 <- ZeroExt( MemByte(Rm) and (1<<imm3) ) e = [] e.append(ExprAssign(r0, ExprOp("&", ExprMem(rm_deref.ptr, 8), i8(1) << imm3[:8]).zeroExtend(32))) return e, []
def m2instruction_to_r2esil(instruction, loc_db): """Convert a miasm 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 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 _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)