def _ail_handle_Register(self, expr): # Special handling for SP and BP if self._stack_pointer_tracker is not None: if expr.reg_offset == self.arch.sp_offset: sb_offset = self._stack_pointer_tracker.offset_before( self.ins_addr, self.arch.sp_offset) if sb_offset is not None: new_expr = Expr.StackBaseOffset(None, self.arch.bits, sb_offset) self.state.add_replacement(self._codeloc(), expr, new_expr) return new_expr elif expr.reg_offset == self.arch.bp_offset: sb_offset = self._stack_pointer_tracker.offset_before( self.ins_addr, self.arch.bp_offset) if sb_offset is not None: new_expr = Expr.StackBaseOffset(None, self.arch.bits, sb_offset) self.state.add_replacement(self._codeloc(), expr, new_expr) return new_expr new_expr = self.state.get_variable(expr) if new_expr is not None: l.debug("Add a replacement: %s with %s", expr, new_expr) self.state.add_replacement(self._codeloc(), expr, new_expr) expr = new_expr return expr
def _ail_handle_Register(self, expr): # Special handling for SP and BP if self._stack_pointer_tracker is not None: if expr.reg_offset == self.arch.sp_offset: sb_offset = self._stack_pointer_tracker.offset_before( self.ins_addr, self.arch.sp_offset) if sb_offset is not None: new_expr = Expr.StackBaseOffset(None, self.arch.bits, sb_offset) self.state.add_replacement(self._codeloc(), expr, new_expr) return new_expr elif expr.reg_offset == self.arch.bp_offset: sb_offset = self._stack_pointer_tracker.offset_before( self.ins_addr, self.arch.bp_offset) if sb_offset is not None: new_expr = Expr.StackBaseOffset(None, self.arch.bits, sb_offset) self.state.add_replacement(self._codeloc(), expr, new_expr) return new_expr new_expr = self.state.get_variable(expr) if new_expr is not None: # check if this new_expr uses any expression that has been overwritten if not self.is_using_outdated_def(new_expr): l.debug("Add a replacement: %s with %s", expr, new_expr) self.state.add_replacement(self._codeloc(), expr, new_expr) expr = new_expr return expr
def _ail_handle_Register(self, expr: Expr.Register) -> Optional[PropValue]: self.state: 'PropagatorAILState' # Special handling for SP and BP if self._stack_pointer_tracker is not None: if expr.reg_offset == self.arch.sp_offset: sb_offset = self._stack_pointer_tracker.offset_before(self.ins_addr, self.arch.sp_offset) if sb_offset is not None: new_expr = Expr.StackBaseOffset(None, self.arch.bits, sb_offset) self.state.add_replacement(self._codeloc(), expr, new_expr) return PropValue.from_value_and_details( self.sp_offset(sb_offset), expr.size, new_expr, self._codeloc() ) elif expr.reg_offset == self.arch.bp_offset: sb_offset = self._stack_pointer_tracker.offset_before(self.ins_addr, self.arch.bp_offset) if sb_offset is not None: new_expr = Expr.StackBaseOffset(None, self.arch.bits, sb_offset) self.state.add_replacement(self._codeloc(), expr, new_expr) return PropValue.from_value_and_details( self.sp_offset(sb_offset), expr.size, new_expr, self._codeloc() ) new_expr = self.state.load_register(expr) if new_expr is not None: # check if this new_expr uses any expression that has been overwritten all_subexprs = list(new_expr.all_exprs()) if not any(self.is_using_outdated_def(subexpr) for subexpr in all_subexprs) and \ len(all_subexprs) == 1: subexpr = all_subexprs[0] if subexpr.size == expr.size: l.debug("Add a replacement: %s with %s", expr, subexpr) self.state.add_replacement(self._codeloc(), expr, subexpr) return new_expr return PropValue.from_value_and_details(self.state.top(expr.bits), expr.size, expr, self._codeloc())
def _ail_handle_Register(self, expr: Expr.Register) -> Optional[PropValue]: self.state: 'PropagatorAILState' # Special handling for SP and BP if self._stack_pointer_tracker is not None: if expr.reg_offset == self.arch.sp_offset: sb_offset = self._stack_pointer_tracker.offset_before(self.ins_addr, self.arch.sp_offset) if sb_offset is not None: new_expr = Expr.StackBaseOffset(None, self.arch.bits, sb_offset) self.state.add_replacement(self._codeloc(), expr, new_expr) return PropValue.from_value_and_details( self.sp_offset(sb_offset), expr.size, new_expr, self._codeloc() ) elif expr.reg_offset == self.arch.bp_offset: sb_offset = self._stack_pointer_tracker.offset_before(self.ins_addr, self.arch.bp_offset) if sb_offset is not None: new_expr = Expr.StackBaseOffset(None, self.arch.bits, sb_offset) self.state.add_replacement(self._codeloc(), expr, new_expr) return PropValue.from_value_and_details( self.sp_offset(sb_offset), expr.size, new_expr, self._codeloc() ) def _test_concatenation(pv: PropValue): if pv.offset_and_details is not None and len(pv.offset_and_details) == 2 and 0 in pv.offset_and_details: lo_value = pv.offset_and_details[0] hi_offset = next(iter(k for k in pv.offset_and_details if k != 0)) hi_value = pv.offset_and_details[hi_offset] if lo_value.def_at == hi_value.def_at: # it's the same value! we can apply concatenation here if isinstance(hi_value.expr, Expr.Const) and hi_value.expr.value == 0: # it's probably an up-cast mappings = { # (lo_value.size, hi_value.size): (from_bits, to_bits) (1, 1): (8, 16), # char to short (1, 3): (8, 32), # char to int (1, 7): (8, 64), # char to int64 (2, 2): (16, 32), # short to int (2, 6): (16, 64), # short to int64 (4, 4): (32, 64), # int to int64 } key = (lo_value.size, hi_value.size) if key in mappings: from_bits, to_bits = mappings[key] result_expr = Expr.Convert(None, from_bits, to_bits, False, lo_value.expr) return True, result_expr result_expr = Expr.BinaryOp(None, "Concat", [hi_value.expr, lo_value.expr], False) return True, result_expr return False, None new_expr = self.state.load_register(expr) if new_expr is not None: # check if this new_expr uses any expression that has been overwritten replaced = False outdated = False all_subexprs = list(new_expr.all_exprs()) for _, detail in new_expr.offset_and_details.items(): if detail.expr is None: break if self.is_using_outdated_def(detail.expr, detail.def_at, avoid=expr): outdated = True break if all_subexprs and None not in all_subexprs and not outdated: if len(all_subexprs) == 1: # trivial case subexpr = all_subexprs[0] if subexpr.size == expr.size: replaced = True l.debug("Add a replacement: %s with %s", expr, subexpr) self.state.add_replacement(self._codeloc(), expr, subexpr) else: is_concatenation, result_expr = _test_concatenation(new_expr) if is_concatenation: replaced = True l.debug("Add a replacement: %s with %s", expr, result_expr) self.state.add_replacement(self._codeloc(), expr, result_expr) if not replaced: l.debug("Add a replacement: %s with TOP", expr) self.state.add_replacement(self._codeloc(), expr, self.state.top(expr.bits)) return new_expr return PropValue.from_value_and_details(self.state.top(expr.bits), expr.size, expr, self._codeloc())