def _set_value(self, varnode: Varnode, value: BV) -> None: """ Store a value for a given varnode. This method stores to the appropriate register, or unique space, depending on the space indicated by the varnode. :param varnode: Varnode to store into. :param value: Value to store. """ space_name = varnode.space.name # FIXME: Consider moving into behavior.py value = self._adjust_value_size(varnode.size * 8, value) assert varnode.size * 8 == value.size() l.debug("Storing %s %x %s %d", space_name, varnode.offset, value, varnode.size) if space_name == "register": self.state.registers.store(self._map_register_name(varnode), value, size=varnode.size) elif space_name == "unique": self._pcode_tmps[varnode.offset] = value elif space_name in ("ram", "mem"): l.debug("Storing %s to offset %s", value, varnode.offset) self.state.memory.store(varnode.offset, value, endness=self.project.arch.memory_endness) else: raise NotImplementedError()
def _adjust_value_size(num_bits: int, v_in: BV) -> BV: """ Ensure given bv is num_bits bits long by either zero extending or truncating. """ if v_in.size() > num_bits: v_out = v_in[num_bits - 1:0] l.debug('Truncating value %s (%d bits) to %s (%d bits)', v_in, v_in.size(), v_out, num_bits) return v_out elif v_in.size() < num_bits: v_out = v_in.zero_extend(num_bits - v_in.size()) l.debug('Extending value %s (%d bits) to %s (%d bits)', v_in, v_in.size(), v_out, num_bits) return v_out else: return v_in
def evaluate_binary(self, size_out: int, size_in: int, in1: BV, in2: BV) -> BV: if in2.size() < in1.size(): in2 = in2.sign_extend(in1.size() - in2.size()) return (in1 >> (in2 * 8)) & (2**(size_out * 8) - 1)
def booleanize(cls, in1: BV) -> BV: """ Reduce input BV to a single bit of truth: out <- 1 if (in1 != 0) else 0. """ return cls.generic_compare((in1, claripy.BVV(0, in1.size())), operator.ne)
def evaluate_unary(self, size_out: int, size_in: int, in1: BV) -> BV: return self.generic_compare((in1, claripy.BVV(0, in1.size())), operator.eq)
def evaluate_binary(self, size_out: int, size_in: int, in1: BV, in2: BV) -> BV: in1, in2 = make_bv_sizes_equal(in1, in2) return in1.LShR(in2)
def evaluate_unary(self, size_out: int, size_in: int, in1: BV) -> BV: return in1.sign_extend((size_out - size_in) * 8)
def evaluate_binary(self, size_out: int, size_in: int, in1: BV, in2: BV) -> BV: if in2.size() < in1.size(): in2 = in2.sign_extend(in1.size() - in2.size()) return in1.LShR(in2)