Beispiel #1
0
    def _set_value(self, var_data: VarnodeData, 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 var_data: The varnode to store into.
        :param value:    The value to store.
        """
        space_name = var_data.space.getName()

        # FIXME: Consider moving into behavior.py
        value = self._adjust_value_size(var_data.size * 8, value)
        assert var_data.size * 8 == value.size()

        l.debug("Storing %s %x %s %d", space_name, var_data.offset, value,
                var_data.size)
        if space_name == "register":
            self.state.registers.store(self._map_register_name(var_data),
                                       value,
                                       size=var_data.size)

        elif space_name == "unique":
            self._pcode_tmps[var_data.offset] = value

        elif space_name == "ram":
            l.debug("Storing %s to offset %s", value, var_data.offset)
            self.state.memory.store(var_data.offset,
                                    value,
                                    endness=self.project.arch.memory_endness)

        else:
            raise NotImplementedError()
Beispiel #2
0
 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
Beispiel #3
0
def make_bv_sizes_equal(bv1: BV, bv2: BV) -> Tuple[BV, BV]:
    """
    Makes two BVs equal in length through sign extension.
    """
    if bv1.size() < bv2.size():
        return (bv1.sign_extend(bv2.size() - bv1.size()), bv2)
    elif bv1.size() > bv2.size():
        return (bv1, bv2.sign_extend(bv1.size() - bv2.size()))
    else:
        return (bv1, bv2)
Beispiel #4
0
 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)
Beispiel #5
0
 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)
Beispiel #6
0
 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)
Beispiel #7
0
 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)