def test_sw(self): """Test SW execution""" # SW Rn,(Rm) exec_instruction("SW R1, (R2)", [(ExprId("R1", 32), ExprInt(0x28071010, 32)), (ExprId("R2", 32), ExprInt(0x10, 32))], [(ExprMem(ExprInt(0x10, 32), 32), ExprInt(0x28071010, 32))]) # SW Rn,disp7.align4(SP) exec_instruction("SW R1, 4(SP)", [(ExprId("R1", 32), ExprInt(0x28071010, 32)), (ExprId("SP", 32), ExprInt(0x10, 32))], [(ExprMem(ExprInt(0x14, 32), 32), ExprInt(0x28071010, 32))]) # SW Rn,disp7.align4(TP) exec_instruction("SW R1, 12(TP)", [(ExprId("R1", 32), ExprInt(0x28071010, 32)), (ExprId("TP", 32), ExprInt(0x10, 32))], [(ExprMem(ExprInt(0x1c, 32), 32), ExprInt(0x28071010, 32))]) # SW Rn,disp16(Rm) exec_instruction("SW R10, 0xF800(R2)", [(ExprId("R10", 32), ExprInt(0xABC7, 32)), (ExprId("R2", 32), ExprInt(0x10, 32))], [(ExprMem(ExprInt(0xFFFFF810, 32), 32), ExprInt(0xABC7, 32))]) # SW Rn,(abs24.align4) exec_instruction("SW R10, (0x1010)", [(ExprId("R10", 32), ExprInt(0xABC7, 32))], [(ExprMem(ExprInt(0x1010, 32), 32), ExprInt(0xABC7, 32))])
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 test_lb(self): """Test LB executon""" # LB Rn,(Rm) exec_instruction("LB R1, (R2)", [(ExprId("R2", 32), ExprInt(0x10, 32)), (ExprMem(ExprInt(0x10, 32), 8), ExprInt(0xF0, 8))], [(ExprId("R1", 32), ExprInt(0xFFFFFFF0, 32))]) # LB Rn[0-7],disp7(TP) exec_instruction("LB R7, 0x3(TP)", [(ExprId("TP", 32), ExprInt(0x10, 32)), (ExprMem(ExprInt(0x13, 32), 8), ExprInt(0xF0, 8))], [(ExprId("R7", 32), ExprInt(0xFFFFFFF0, 32))]) # LB Rn,disp16(Rm) exec_instruction("LB R10, 0xF800(R2)", [(ExprId("R2", 32), ExprInt(0x10, 32)), (ExprMem(ExprInt(0xFFFFF810, 32), 8), ExprInt(0x4, 8))], [(ExprId("R10", 32), ExprInt(0x4, 32))]) exec_instruction("LB R10, 0xF800(R2)", [(ExprId("R2", 32), ExprInt(0x10, 32)), (ExprMem(ExprInt(0xFFFFF810, 32), 8), ExprInt(0xFE, 8))], [(ExprId("R10", 32), ExprInt(0xFFFFFFFE, 32))])
def test_lw(self): """Test SW execution""" # LW Rn,(Rm) exec_instruction("LW R1, (R2)", [(ExprId("R2", 32), ExprInt(0x10, 32)), (ExprMem(ExprInt(0x10, 32), 32), ExprInt(0xABCD, 32))], [(ExprId("R1", 32), ExprInt(0xABCD, 32))]) # LW Rn,disp7.align4(SP) exec_instruction("LW R1, 0x18(SP)", [(ExprId("SP", 32), ExprInt(0x10, 32)), (ExprMem(ExprInt(0x28, 32), 32), ExprInt(0x01234567, 32))], [(ExprId("R1", 32), ExprInt(0x01234567, 32))]) # LW Rn[0-7],disp7.align4(TP) exec_instruction("LW R1, 0x18(TP)", [(ExprId("TP", 32), ExprInt(0x10, 32)), (ExprMem(ExprInt(0x28, 32), 32), ExprInt(0x1010, 32))], [(ExprId("R1", 32), ExprInt(0x1010, 32))]) # LW Rn,disp16(Rm) exec_instruction("LW R9, 0xF000(R2)", [(ExprId("R2", 32), ExprInt(0x42, 32)), (ExprMem(ExprInt(0xFFFFF040, 32), 32), ExprInt(0x10, 32))], [(ExprId("R9", 32), ExprInt(0x10, 32))]) # LW Rn,(abs24.align4) exec_instruction("LW R10, (0x1010)", [(ExprMem(ExprInt(0x1010, 32), 32), ExprInt(0xABC7, 32))], [(ExprId("R10", 32), ExprInt(0xABC7, 32))])
def test_lh(self): """Test lh execution""" # LH Rn,(Rm) exec_instruction("LH R1, (R2)", [(ExprId("R2", 32), ExprInt(0x10, 32)), (ExprMem(ExprInt(0x10, 32), 16), ExprInt(0xF517, 16))], [(ExprId("R1", 32), ExprInt(0xFFFFF517, 32))]) # LH Rn[0-7],disp7.align2(TP) exec_instruction("LH R1, 0x18(R2)", [(ExprId("R2", 32), ExprInt(0x10, 32)), (ExprMem(ExprInt(0x28, 32), 16), ExprInt(0xF517, 16))], [(ExprId("R1", 32), ExprInt(0xFFFFF517, 32))]) # LH Rn,disp16(Rm) exec_instruction("LH R9, 0xF000(R2)", [(ExprId("R2", 32), ExprInt(0x42, 32)), (ExprMem(ExprInt(0xFFFFF042, 32), 16), ExprInt(0x10, 16))], [(ExprId("R9", 32), ExprInt(0x10, 32))]) exec_instruction("LH R9, 0xF000(R2)", [(ExprId("R2", 32), ExprInt(0x42, 32)), (ExprMem(ExprInt(0xFFFFF042, 32), 16), ExprInt(0xABCD, 16))], [(ExprId("R9", 32), ExprInt(0xFFFFABCD, 32))])
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 mem_read(self, expr_mem): if not expr_mem.ptr.is_int(): return super(ESETrackModif, self).mem_read(expr_mem) dst_addr = int(expr_mem.ptr) # Split access in atomic accesses out = [] for addr in range(dst_addr, dst_addr + expr_mem.size // 8): if addr in self.dse_memory_range: # Symbolize memory access out.append(self.dse_memory_to_expr(addr)) continue atomic_access = ExprMem(ExprInt(addr, expr_mem.ptr.size), 8) if atomic_access in self.symbols: out.append( super(EmulatedSymbExec, self).mem_read(atomic_access)) else: # Get concrete value atomic_access = ExprMem(ExprInt(addr, expr_mem.ptr.size), 8) out.append(super(ESETrackModif, self).mem_read(atomic_access)) if len(out) == 1: # Trivial case (optimization) return out[0] # Simplify for constant merging (ex: {ExprInt(1, 8), ExprInt(2, 8)}) return self.expr_simp(ExprCompose(*out))
def bclrm(ir, instr, rm_deref, imm3): """BCLRM - Bit Clear Memory""" # MemByte(Rm) <- MemByte(Rm) and ~(1<<imm3) e = [] shift = ExprOp("<<", i8(1), imm3[:8]) e.append(ExprAssign(ExprMem(rm_deref.ptr, 8), ExprOp("&", ExprMem(rm_deref.ptr, 8), shift.__invert__()))) return e, []
def test_bsetm(self): """Test BSETM execution""" # BSETM (Rm),imm3 exec_instruction("BSETM (R1), 1", [(ExprId("R1", 32), ExprInt(0x28, 32)), (ExprMem(ExprInt(0x28, 32), 8), ExprInt(0x1, 8))], [(ExprMem(ExprInt(0x28, 32), 8), ExprInt(0x3, 8))])
def test_tas(self): """Test TAS execution""" # TAS Rn,(Rm) exec_instruction("TAS R0, (R1)", [(ExprId("R1", 32), ExprInt(0x28, 32)), (ExprMem(ExprInt(0x28, 32), 8), ExprInt(0x2, 8))], [(ExprId("R0", 32), ExprInt(0x2, 32)), (ExprMem(ExprInt(0x28, 32), 8), ExprInt(0x1, 8))])
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 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 simp_mem(_, expr): """ Common simplifications on ExprMem: @32[x?a:b] => x?@32[a]:@32[b] """ if expr.ptr.is_cond(): cond = expr.ptr ret = ExprCond(cond.cond, ExprMem(cond.src1, expr.size), ExprMem(cond.src2, expr.size)) return ret return expr
def test_lmcp(self): """Test LMCP execution""" # LMCP CRn[0-15],(Rm) exec_instruction("LMCP C1, (R2)", [(ExprId("R2", 32), ExprInt(0x10, 32)), (ExprMem(ExprInt(0x10, 32), 32), ExprInt(0xABCD, 32))], [(ExprId("C1", 32), ExprInt(0xABCD, 32))]) # LMCP CRn[0-15],disp16(Rm) exec_instruction("LMCP C9, 0xF000(R2)", [(ExprId("R2", 32), ExprInt(0x17, 32)), (ExprMem(ExprInt(0xFFFFF010, 32), 32), ExprInt(0x10, 32))], [(ExprId("C9", 32), ExprInt(0x10, 32))])
def test_smcp(self): """Test SMCP execution""" # SMCP CRn,(Rm) exec_instruction("SMCP C1, (R2)", [(ExprId("C1", 32), ExprInt(0x28071010, 32)), (ExprId("R2", 32), ExprInt(0x17, 32))], [(ExprMem(ExprInt(0x10, 32), 32), ExprInt(0x28071010, 32))]) # SMCP CRn,disp16(Rm) exec_instruction("SMCP C10, 0xF800(R2)", [(ExprId("C10", 32), ExprInt(0xABC7, 32)), (ExprId("R2", 32), ExprInt(0x17, 32))], [(ExprMem(ExprInt(0xFFFFF810, 32), 32), ExprInt(0xABC7, 32))])
def test(): struct_lookup = StructLookup() ptr = ExprId('ECX', 32) int4 = ExprInt(4, 32) tests = [ (ptr, StructLookup.FIELD_A_PTR), (ptr + int4, StructLookup.FIELD_A_PTR), (ptr + int4 * int4, StructLookup.FIELD_A_PTR), (ExprMem(ptr, 32), StructLookup.FIELD_A), (ExprMem(ptr + int4 * int4, 32), StructLookup.FIELD_A), ] for expr_in, result in tests: assert struct_lookup.reduce(expr_in).info == result
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 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 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 write(self, offset, expr): """ Write @expr at @offset @offset: integer (in bytes) @expr: Expr instance value """ assert expr.size % 8 == 0 assert offset <= self._mask for index in range(expr.size // 8): # Wrap write: # @32[EAX+0xFFFFFFFF] is ok and will write at 0xFFFFFFFF, 0, 1, 2 request_offset = (offset + index) & self._mask # XXX TODO: only little endian here self._offset_to_expr[request_offset] = (index, expr) tmp = self.expr_simp(expr[index * 8: (index + 1) * 8]) # Special case: Simplify slice of pointer (simplification is ok # here, as we won't store the simplified expression) if tmp.is_slice() and tmp.arg.is_mem() and tmp.start % 8 == 0: new_ptr = self.expr_simp( tmp.arg.ptr + ExprInt(tmp.start // 8, tmp.arg.ptr.size) ) tmp = ExprMem(new_ptr, tmp.stop - tmp.start) # Test if write to original value if tmp.is_mem(): src_ptr, src_off = get_expr_base_offset(tmp.ptr) if src_ptr == self.base and src_off == request_offset: del self._offset_to_expr[request_offset]
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 eval_updt_irblock(self, irb, step=False): """ Symbolic execution of the @irb on the current state @irb: IRBlock instance @step: display intermediate steps """ assignblks = [] for index, assignblk in enumerate(irb): new_assignblk = {} links = {} for dst, src in viewitems(assignblk): src = self.propag_expr_cst(src) if dst.is_mem(): ptr = dst.ptr ptr = self.propag_expr_cst(ptr) dst = ExprMem(ptr, dst.size) new_assignblk[dst] = src if assignblk.instr is not None: for arg in assignblk.instr.args: new_arg = self.propag_expr_cst(arg) links[new_arg] = arg self.cst_propag_link[(irb.loc_key, index)] = links self.eval_updt_assignblk(assignblk) assignblks.append(AssignBlock(new_assignblk, assignblk.instr)) self.ircfg.blocks[irb.loc_key] = IRBlock(irb.loc_key, assignblks)
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 manage_mem(self, expr, state, cache, level): ptr = self.apply_expr_on_state_visit_cache(expr.arg, state, cache, level + 1) ret = ExprMem(ptr, expr.size) ret = self.get_mem_state(ret) assert expr.size == ret.size return ret
def decode(self, v): v = v & self.lmask if v >= len(self.reg_info.expr): return False self.expr = self.reg_info.expr[v] self.expr = ExprMem(self.expr, self.expr.size) return True
def asm_ast_to_expr(self, arg, loc_db): """Convert AST to expressions Note: - code inspired by miasm/arch/mips32/arch.py""" if isinstance(arg, AstId): if isinstance(arg.name, ExprId): return arg.name if isinstance(arg.name, str) and arg.name in gpr_names: return None # GV: why? loc_key = loc_db.get_or_create_name_location(arg.name.encode()) return ExprLoc(loc_key, 32) elif isinstance(arg, AstMem): addr = self.asm_ast_to_expr(arg.ptr, loc_db) if addr is None: return None return ExprMem(addr, 32) elif isinstance(arg, AstInt): return ExprInt(arg.value, 32) elif isinstance(arg, AstOp): args = [self.asm_ast_to_expr(tmp, loc_db) for tmp in arg.args] if None in args: return None return ExprOp(arg.op, *args) # Raise an exception if the argument was not processed message = "mep_arg.asm_ast_to_expr(): don't know what \ to do with a '%s' instance." % type(arg) raise Exception(message)
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 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 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, []