示例#1
0
    def __ne__(self, other: Union[int, "BitVec"]) -> Bool:  # type: ignore
        """Create an inequality expression.

        :param other:
        :return:
        """
        if not isinstance(other, BitVec):
            return Bool(cast(z3.BoolRef, self.raw != other),
                        annotations=self.annotations)

        union = self.annotations + other.annotations
        # MYPY: fix complaints due to z3 overriding __eq__
        return Bool(cast(z3.BoolRef, self.raw != other.raw), annotations=union)
示例#2
0
def _comparison_helper(a: BitVec, b: BitVec, operation: Callable,
                       default_value: bool, inputs_equal: bool) -> Bool:
    annotations = a.annotations.union(b.annotations)
    if isinstance(a, BitVecFunc):
        return _func_comparison_helper(a, b, operation, default_value,
                                       inputs_equal)
    return Bool(operation(a.raw, b.raw), annotations)
示例#3
0
def _comparison_helper(a: BitVec, b: BitVec, operation: Callable,
                       default_value: bool, inputs_equal: bool) -> Bool:
    annotations = a.annotations + b.annotations
    if isinstance(a, BitVecFunc):
        if not a.symbolic and not b.symbolic:
            return Bool(operation(a.raw, b.raw), annotations=annotations)

        if (not isinstance(b, BitVecFunc) or not a.func_name or not a.input_
                or not a.func_name == b.func_name):
            return Bool(z3.BoolVal(default_value), annotations=annotations)

        return And(
            Bool(operation(a.raw, b.raw), annotations=annotations),
            a.input_ == b.input_ if inputs_equal else a.input_ != b.input_,
        )

    return Bool(operation(a.raw, b.raw), annotations)
示例#4
0
    def __ge__(self, other: "BitVec") -> Bool:
        """Create a signed greater than expression.

        :param other:
        :return:
        """
        union = self.annotations + other.annotations
        return Bool(self.raw >= other.raw, annotations=union)
示例#5
0
    def __ne__(self, other: Union[int, "BitVec"]) -> Bool:  # type: ignore
        """Create an inequality expression.

        :param other:
        :return:
        """
        if isinstance(other, BitVecFunc):
            return other != self
        if not isinstance(other, BitVec):
            return Bool(cast(z3.BoolRef, self.raw != other),
                        annotations=self.annotations)

        union = self.annotations.union(other.annotations)
        # Some of the BitVecs can be 512 bit due to sha3()
        neq_check = _padded_operation(self.raw, other.raw, ne)
        # MYPY: fix complaints due to z3 overriding __eq__
        return Bool(cast(z3.BoolRef, neq_check), annotations=union)
示例#6
0
    def __le__(self, other: "BitVec") -> Bool:
        """Create a signed less than expression.

        :param other:
        :return:
        """
        union = self.annotations.union(other.annotations)
        return Bool(self.raw <= other.raw, annotations=union)
示例#7
0
def ULT(a: BitVec, b: BitVec) -> Bool:
    """Create an unsigned less than expression.

    :param a:
    :param b:
    :return:
    """
    annotations = a.annotations + b.annotations
    return Bool(z3.ULT(a.raw, b.raw), annotations)
示例#8
0
def UGE(a: BitVec, b: BitVec) -> Bool:
    """Create an unsigned greater or equals expression.

    :param a:
    :param b:
    :return:
    """
    annotations = a.annotations + b.annotations
    return Bool(z3.UGE(a.raw, b.raw), annotations)
示例#9
0
 def Bool(value: "__builtins__.bool",
          annotations: Annotations = None) -> bool.Bool:
     """
     Creates a Bool with concrete value
     :param value: The boolean value
     :param annotations: The annotations to initialize the bool with
     :return: The freshly created Bool()
     """
     raw = z3.BoolVal(value)
     return Bool(raw, annotations)
示例#10
0
    def __gt__(self, other: "BitVec") -> Bool:
        """Create a signed greater than expression.

        :param other:
        :return:
        """
        if isinstance(other, BitVecFunc):
            return other < self
        union = self.annotations + other.annotations
        return Bool(self.raw > other.raw, annotations=union)
示例#11
0
    def __ge__(self, other: Union[int, "BitVec"]) -> Bool:
        """Create a signed greater than expression.

        :param other:
        :return:
        """
        if not isinstance(other, BitVec):
            other = BitVec(z3.BitVecVal(other, self.size()))
        union = self.annotations.union(other.annotations)
        return Bool(self.raw >= other.raw, annotations=union)
示例#12
0
    def __lt__(self, other: "BitVec") -> Bool:
        """Create a signed less than expression.

        :param other:
        :return:
        """
        if isinstance(other, BitVecFunc):
            return other > self
        union = self.annotations.union(other.annotations)
        return Bool(self.raw < other.raw, annotations=union)
示例#13
0
def BVAddNoOverflow(a: Union[BitVec, int], b: Union[BitVec, int],
                    signed: bool) -> Bool:
    """Creates predicate that verifies that the addition doesn't overflow.

    :param a:
    :param b:
    :param signed:
    :return:
    """
    if not isinstance(a, BitVec):
        a = BitVec(z3.BitVecVal(a, 256))
    if not isinstance(b, BitVec):
        b = BitVec(z3.BitVecVal(b, 256))
    return Bool(z3.BVAddNoOverflow(a.raw, b.raw, signed))
示例#14
0
def If(a: Union[Bool, bool], b: Union[BitVec, int], c: Union[BitVec,
                                                             int]) -> BitVec:
    """Create an if-then-else expression.

    :param a:
    :param b:
    :param c:
    :return:
    """
    if not isinstance(a, Bool):
        a = Bool(z3.BoolVal(a))
    if not isinstance(b, BitVec):
        b = BitVec(z3.BitVecVal(b, 256))
    if not isinstance(c, BitVec):
        c = BitVec(z3.BitVecVal(c, 256))
    union = a.annotations + b.annotations + c.annotations
    return BitVec(z3.If(a.raw, b.raw, c.raw), union)
示例#15
0
def If(a: Union[Bool, bool], b: Union[BitVec, int], c: Union[BitVec,
                                                             int]) -> BitVec:
    """Create an if-then-else expression.

    :param a:
    :param b:
    :param c:
    :return:
    """
    # TODO: Handle BitVecFunc

    if not isinstance(a, Bool):
        a = Bool(z3.BoolVal(a))
    if not isinstance(b, BitVec):
        b = BitVec(z3.BitVecVal(b, 256))
    if not isinstance(c, BitVec):
        c = BitVec(z3.BitVecVal(c, 256))
    union = a.annotations.union(b.annotations).union(c.annotations)

    bvf = []  # type: List[BitVecFunc]
    if isinstance(a, BitVecFunc):
        bvf += [a]
    if isinstance(b, BitVecFunc):
        bvf += [b]
    if isinstance(c, BitVecFunc):
        bvf += [c]
    if bvf:
        raw = z3.If(a.raw, b.raw, c.raw)
        nested_functions = [
            nf for func in bvf for nf in func.nested_functions
        ] + bvf
        return BitVecFunc(raw,
                          func_name="Hybrid",
                          nested_functions=nested_functions)

    return BitVec(z3.If(a.raw, b.raw, c.raw), union)
示例#16
0
def _comparison_helper(
    a: "BitVecFunc",
    b: Union[BitVec, int],
    operation: Callable,
    default_value: bool,
    inputs_equal: bool,
) -> Bool:
    """
    Helper function for comparison operations with BitVecFuncs.

    :param a: The BitVecFunc to compare.
    :param b: A BitVec or int to compare to.
    :param operation: The comparison operation to perform.
    :return: The resulting Bool
    """
    # Is there some hack for gt/lt comparisons?
    if isinstance(b, int):
        b = BitVec(z3.BitVecVal(b, a.size()))
    union = a.annotations.union(b.annotations)

    if not a.symbolic and not b.symbolic:
        if operation == z3.UGT:
            operation = operator.gt
        if operation == z3.ULT:
            operation = operator.lt
        return Bool(z3.BoolVal(operation(a.value, b.value)), annotations=union)
    if (
        not isinstance(b, BitVecFunc)
        or not a.func_name
        or not a.input_
        or not a.func_name == b.func_name
        or str(operation) not in ("<built-in function eq>", "<built-in function ne>")
    ):
        return Bool(z3.BoolVal(default_value), annotations=union)

    condition = True
    for a_nest, b_nest in product(a.nested_functions, b.nested_functions):
        if a_nest.func_name != b_nest.func_name:
            continue
        if a_nest.func_name == "Hybrid":
            continue
        # a.input (eq/neq) b.input ==> a == b
        if inputs_equal:
            condition = z3.And(
                condition,
                z3.Or(
                    z3.Not((a_nest.input_ == b_nest.input_).raw),
                    (a_nest.raw == b_nest.raw),
                ),
                z3.Or(
                    z3.Not((a_nest.raw == b_nest.raw)),
                    (a_nest.input_ == b_nest.input_).raw,
                ),
            )
        else:
            condition = z3.And(
                condition,
                z3.Or(
                    z3.Not((a_nest.input_ != b_nest.input_).raw),
                    (a_nest.raw == b_nest.raw),
                ),
                z3.Or(
                    z3.Not((a_nest.raw == b_nest.raw)),
                    (a_nest.input_ != b_nest.input_).raw,
                ),
            )

    return And(
        Bool(cast(z3.BoolRef, operation(a.raw, b.raw)), annotations=union),
        Bool(condition) if b.nested_functions else Bool(True),
        a.input_ == b.input_ if inputs_equal else a.input_ != b.input_,
    )