Esempio n. 1
0
 def _op_generic_Ctz(self, args):
     """Count the trailing zeroes"""
     wtf_expr = claripy.BVV(self._from_size, self._from_size)
     for a in reversed(range(self._from_size)):
         bit = claripy.Extract(a, a, args[0])
         wtf_expr = claripy.If(bit == 1, claripy.BVV(a, self._from_size),
                               wtf_expr)
     return wtf_expr
Esempio n. 2
0
 def _op_generic_Clz(self, args):
     """Count the leading zeroes"""
     piece_size = len(args[0])
     wtf_expr = claripy.BVV(piece_size, piece_size)
     for a in range(piece_size):
         bit = claripy.Extract(a, a, args[0])
         wtf_expr = claripy.If(bit==1, claripy.BVV(piece_size-a-1, piece_size), wtf_expr)
     return wtf_expr
Esempio n. 3
0
 def _op_generic_Clz(self, args):
     '''Count the leading zeroes'''
     wtf_expr = claripy.BVV(self._from_size, self._from_size)
     for a in range(self._from_size):
         bit = claripy.Extract(a, a, args[0])
         wtf_expr = claripy.If(
             bit == 1, claripy.BVV(self._from_size - a - 1,
                                   self._from_size), wtf_expr)
     return wtf_expr
Esempio n. 4
0
 def _op_vector_float_mapped(self, args):
     rm_part = [] if self._generic_name in self.NO_RM else [args[0]]
     chopped_args = (
             [
                 claripy.Extract((i + 1) * self._vector_size - 1, i * self._vector_size, a).raw_to_fp()
                 for a in (args if self._generic_name in self.NO_RM else args[1:])
             ] for i in reversed(range(self._vector_count))
         )
     return claripy.Concat(*(self._op_float_mapped(rm_part + ca).raw_to_bv() for ca in chopped_args))
Esempio n. 5
0
def test_extract_zeroext():
    x = claripy.BVS('x', 8)
    expr = claripy.Extract(31, 0, claripy.ZeroExt(56, x)) <= claripy.BVV(
        0xe, 32)
    s, r = claripy.balancer.Balancer(claripy.backends.vsa, expr).compat_ret

    assert s is True
    assert len(r) == 1
    assert r[0][0] is x
Esempio n. 6
0
def _consolidate_expr(e0):
    if hasattr(e0, 'op') and e0.op == 'Reverse':
        e1 = e0.args[0]
        if e1.op == 'Extract':
            p0 = e1.args[0]
            p1 = e1.args[1]
            e2 = e1.args[2]
            if e2.op == 'Reverse':
                return claripy.Extract(e2.size()-1-p1, e2.size()-1-p0, e2.args[0])
    return e0
Esempio n. 7
0
def eq_var(v1, v2):
    if isinstance(v1, claripy.ast.bv.BV) and isinstance(v2, claripy.ast.bv.BV):
        v1_size = v1.size()
        v2_size = v2.size()
        if v1_size == v2_size:
            return claripy.ast.Bool(op='__eq__', args=(v1, v2))
        elif v1_size in loose_BV_sizes and v2_size in loose_BV_sizes:
            if v1_size < v2_size:
                return claripy.And(claripy.ast.Bool(op='__eq__', args=(v1, claripy.Extract(v1_size - 1, 0, v2))),
                                   v2[v2_size - 1:v1_size] == 0)
            else:
                return claripy.And(claripy.ast.Bool(op='__eq__', args=(claripy.Extract(v2_size - 1, 0, v1), v2)),
                                   v1[v1_size - 1:v2_size] == 0)
        else:
            return None
    elif isinstance(v1, claripy.ast.bool.Bool) and isinstance(v2, claripy.ast.bool.Bool):
        return claripy.ast.Bool(op='__eq__', args=(v1, v2))
    else:
        raise NotImplementedError()
Esempio n. 8
0
 def _op_divmod(self, args):
     if self.is_signed:
         quotient = (args[0].SDiv(claripy.SignExt(self._from_size - self._to_size, args[1])))
         remainder = (args[0].SMod(claripy.SignExt(self._from_size - self._to_size, args[1])))
         quotient_size = self._to_size
         remainder_size = self._to_size
         return claripy.Concat(
             claripy.Extract(remainder_size - 1, 0, remainder),
             claripy.Extract(quotient_size - 1, 0, quotient)
         )
     else:
         quotient = (args[0] / claripy.ZeroExt(self._from_size - self._to_size, args[1]))
         remainder = (args[0] % claripy.ZeroExt(self._from_size - self._to_size, args[1]))
         quotient_size = self._to_size
         remainder_size = self._to_size
         return claripy.Concat(
             claripy.Extract(remainder_size - 1, 0, remainder),
             claripy.Extract(quotient_size - 1, 0, quotient)
         )
Esempio n. 9
0
    def _handle_DivMod(self, expr):
        arg0, arg1 = expr.args
        r0 = self._expr(arg0)
        r1 = self._expr(arg1)

        result_size = expr.result_size(self.tyenv)
        if r0.data.concrete and r1.data.concrete:
            # constants
            try:
                signed = "U" in expr.op  # Iop_DivModU64to32 vs Iop_DivMod
                from_size = r0.data.size()
                to_size = r1.data.size()
                if signed:
                    quotient = (r0.data.SDiv(
                        claripy.SignExt(from_size - to_size, r1.data)))
                    remainder = (r0.data.SMod(
                        claripy.SignExt(from_size - to_size, r1.data)))
                    quotient_size = to_size
                    remainder_size = to_size
                    result = claripy.Concat(
                        claripy.Extract(remainder_size - 1, 0, remainder),
                        claripy.Extract(quotient_size - 1, 0, quotient))
                else:
                    quotient = (r0.data //
                                claripy.ZeroExt(from_size - to_size, r1.data))
                    remainder = (r0.data %
                                 claripy.ZeroExt(from_size - to_size, r1.data))
                    quotient_size = to_size
                    remainder_size = to_size
                    result = claripy.Concat(
                        claripy.Extract(remainder_size - 1, 0, remainder),
                        claripy.Extract(quotient_size - 1, 0, quotient))

                return RichR(result)
            except ZeroDivisionError:
                pass

        r = self.state.top(result_size)
        return RichR(r)
Esempio n. 10
0
def test_reverse_extract_reverse_simplification():

    # without the reverse_extract_reverse simplifier, loading dx from rdx will result in the following complicated
    # expression:
    #   Reverse(Extract(63, 48, Reverse(BVS('rdx', 64))))

    a = claripy.BVS('rdx', 64)
    dx = claripy.Reverse(claripy.Extract(63, 48, claripy.Reverse(a)))

    # simplification should have kicked in at this moment
    nose.tools.assert_equal(dx.op, 'Extract')
    nose.tools.assert_equal(dx.args[0], 15)
    nose.tools.assert_equal(dx.args[1], 0)
    nose.tools.assert_is(dx.args[2], a)
Esempio n. 11
0
 def generic_shift_thing(self, args, op):
     if self._vector_size is not None:
         shifted = []
         if args[1].length != self._vector_size:
             shift_by = args[1].zero_extend(self._vector_size -
                                            args[1].length)
         else:
             shift_by = args[1]
         for i in reversed(range(self._vector_count)):
             left = claripy.Extract((i + 1) * self._vector_size - 1,
                                    i * self._vector_size, args[0])
             shifted.append(op(left, shift_by))
         return claripy.Concat(*shifted)
     else:
         raise SimOperationError("you done f****d")
Esempio n. 12
0
def get_signed_range(se, expr):
    """
    Calculate the range of the expression with signed boundaries
    """
    size = expr.size()
    umin = umax = smin = smax = None
    if not sat_zero(se, expr):
        try:
            umin = se.min(expr,
                          extra_constraints=[
                              claripy.Extract(size - 1, size - 1, expr) == 0
                          ])
            umax = se.max(expr,
                          extra_constraints=[
                              claripy.Extract(size - 1, size - 1, expr) == 0
                          ])
            return (umin, umax)
        except:
            pass
        try:
            smin = -(1 << size) + se.min(expr,
                                         extra_constraints=[
                                             claripy.Extract(
                                                 size - 1, size - 1, expr) == 1
                                         ])
            smax = -(1 << size) + se.max(expr,
                                         extra_constraints=[
                                             claripy.Extract(
                                                 size - 1, size - 1, expr) == 1
                                         ])
            return (smin, smax)
        except:
            pass
        return None
    else:
        try:
            umax = se.max(expr,
                          extra_constraints=[
                              claripy.Extract(size - 1, size - 1, expr) == 0
                          ])
            smin = 0
            try:
                smin = -(1 << size) + se.min(
                    expr,
                    extra_constraints=[
                        claripy.Extract(size - 1, size - 1, expr) == 1
                    ])
            except:
                pass
            return (smin, umax)
        except:
            pass

        return None
Esempio n. 13
0
 def _op_vector_float_mapped(self, args):
     rm_part = [] if self._generic_name in self.NO_RM else [args[0]]
     chopped_args = ([
         claripy.Extract((i + 1) * self._vector_size - 1,
                         i * self._vector_size, a).raw_to_fp()
         for a in (args if self._generic_name in self.NO_RM else args[1:])
     ] for i in reversed(xrange(self._vector_count)))
     chopped_list = list()
     for ca in chopped_args:
         if str(type(self._op_float_mapped(
                 rm_part + ca))) == "<type 'NotImplementedType'>":
             continue
         else:
             chopped_list.add(ca)
     return claripy.Concat(*(self._op_float_mapped(rm_part +
                                                   ca).raw_to_bv()
                             for ca in chopped_list))
Esempio n. 14
0
def test_zeroext_extract_comparing_against_constant_simplifier():

    a = claripy.BVS('a', 8, explicit_name=True)
    b = claripy.BVV(0x28, 16)

    expr = claripy.Extract(15, 0, claripy.ZeroExt(24, a)) == b
    assert expr is (a == claripy.BVV(0x28, 8))

    expr = claripy.Extract(7, 0, claripy.ZeroExt(24,
                                                 a)) == claripy.BVV(0x28, 8)
    assert expr is (a == claripy.BVV(0x28, 8))

    expr = claripy.Extract(7, 0, claripy.ZeroExt(1, a)) == claripy.BVV(0x28, 8)
    assert expr is (a == claripy.BVV(0x28, 8))

    expr = claripy.Extract(6, 0, claripy.ZeroExt(24,
                                                 a)) == claripy.BVV(0x28, 7)
    assert expr.op == "__eq__"
    assert expr.args[0].op == "Extract" and expr.args[0].args[
        0] == 6 and expr.args[0].args[1] == 0
    assert expr.args[0].args[2] is a
    assert expr.args[1].args == (0x28, 7)

    expr = claripy.Extract(15, 0, claripy.Concat(claripy.BVV(0, 48), a)) == b
    assert expr is (a == claripy.BVV(0x28, 8))

    bb = claripy.BVV(0x28, 24)
    d = claripy.BVS('d', 8, explicit_name=True)
    expr = claripy.Extract(23, 0, claripy.Concat(claripy.BVV(0, 24), d)) == bb
    assert expr is (d == claripy.BVV(0x28, 8))

    dd = claripy.BVS('dd', 23, explicit_name=True)
    expr = claripy.Extract(23, 0, claripy.Concat(claripy.BVV(0, 2), dd)) == bb
    assert expr is (dd == claripy.BVV(0x28, 23))

    # this was incorrect before
    # claripy issue #201
    expr = claripy.Extract(31, 8,
                           claripy.Concat(claripy.BVV(0, 24),
                                          dd)) == claripy.BVV(0xffff, 24)
    assert expr is not (dd == claripy.BVV(0xffff, 23))
Esempio n. 15
0
    def _op_vector_float_mapped(self, args):
        no_rm_arg = self._generic_name in self.NO_RM
        rm_part = [] if no_rm_arg else [args[0]]
        # wtf is up with these guys
        if not no_rm_arg and self.name in {
                'Iop_Add32Fx2', 'Iop_Sub32Fx2', 'Iop_Mul32Fx2',
                'Iop_PwAdd32Fx2'
        }:
            no_rm_arg = True
            rm_part = [claripy.BVV(0, 8)]

        chopped_args = ([
            claripy.Extract((i + 1) * self._vector_size - 1,
                            i * self._vector_size, a).raw_to_fp()
            for a in (args if no_rm_arg else args[1:])
        ] for i in reversed(range(self._vector_count)))
        return claripy.Concat(*(self._op_float_mapped(rm_part +
                                                      ca).raw_to_bv()
                                for ca in chopped_args))
Esempio n. 16
0
    def _handle_Shr(self, expr):
        args, r = self._binop_get_args(expr)
        if args is None: return r
        expr_0, expr_1 = args

        if self._is_top(expr_0) or self._is_top(expr_1):
            return self._top(expr_0.size())

        if isinstance(expr_1, claripy.ast.Base) and expr_1.op == "BVV":
            # convert it to an int when possible
            expr_1 = expr_1.args[0]
        else:
            # make sure the sizes are the same - VEX does not care about it
            if expr_1.size() < expr_0.size():
                expr_1 = claripy.ZeroExt(expr_0.size() - expr_1.size(), expr_1)
            elif expr_1.size() > expr_0.size():
                expr_1 = claripy.Extract(expr_0.size() - 1, 0, expr_1)

        return claripy.LShR(expr_0, expr_1)
Esempio n. 17
0
    def _post_process(self):
        if self._post_processed: return
        self._post_processed = True

        if o.SIMPLIFY_EXPRS in self.state.options:
            self.expr = self.state.se.simplify(self.expr)

        self.state.add_constraints(*self._constraints)

        if self.state.se.symbolic(
                self.expr) and o.CONCRETIZE in self.state.options:
            self.make_concrete()

        # FIXME: add this will cause BV96 data, why?
        if self.expr.size() != self.size_bits():
            l.warning("Inconsistent expression size: should be %d but is %d" %
                      (self.size_bits(), self.expr.size()))
            if self.expr.size() > self.size_bits():
                self.expr = claripy.Extract(self.size_bits() - 1, 0, self.expr)
            else:
                self.expr = claripy.ZeroExt(
                    self.size_bits() - self.expr.size(), self.expr)
Esempio n. 18
0
    def _op_fgeneric_Round(self, args):
        if self._vector_size is not None:
            rm = {
                'RM': claripy.fp.RM_RTN,
                'RP': claripy.fp.RM_RTP,
                'RN': claripy.fp.RM_RNE,
                'RZ': claripy.fp.RM_RTZ,
            }[self._rounding_mode]

            rounded = []
            for i in reversed(range(self._vector_count)):
                #pylint:disable=no-member
                left = claripy.Extract(
                    (i+1) * self._vector_size - 1, i * self._vector_size, args[0]
                ).raw_to_fp()
                rounded.append(claripy.fpToSBV(rm, left, self._vector_size))
            return claripy.Concat(*rounded)
        else:
            # note: this a bad solution because it will cut off high values
            # TODO: look into fixing this
            rm = self._translate_rm(args[0])
            rounded_bv = claripy.fpToSBV(rm, args[1].raw_to_fp(), args[1].length)
            return claripy.fpToFP(claripy.fp.RM_RNE, rounded_bv, claripy.fp.FSort.from_size(args[1].length))
Esempio n. 19
0
 def evaluate_unary(self, size_out: int, size_in: int, in1: BV) -> BV:
     expr = claripy.BVV(0, size_out * 8)
     for a in range(len(in1)):
         expr += claripy.Extract(a, a, in1).zero_extend(size_out * 8 - 1)
     return expr
Esempio n. 20
0
def test_vsa_constraint_to_si():
    # Set backend
    b = claripy.backend_vsa
    s = claripy.LightFrontend(claripy.backend_vsa)  #pylint:disable=unused-variable

    SI = claripy.SI
    BVV = claripy.BVV

    claripy.vsa.strided_interval.allow_dsis = False

    #
    # If(SI == 0, 1, 0) == 1
    #

    s1 = claripy.SI(bits=32, stride=1, lower_bound=0, upper_bound=2)
    ast_true = (claripy.If(s1 == BVV(0, 32), BVV(1, 1), BVV(0,
                                                            1)) == BVV(1, 1))
    ast_false = (claripy.If(s1 == BVV(0, 32), BVV(1, 1), BVV(0, 1)) != BVV(
        1, 1))

    trueside_sat, trueside_replacement = b.constraint_to_si(ast_true)
    nose.tools.assert_equal(trueside_sat, True)
    nose.tools.assert_equal(len(trueside_replacement), 1)
    nose.tools.assert_true(trueside_replacement[0][0] is s1)
    # True side: claripy.SI<32>0[0, 0]
    nose.tools.assert_true(
        claripy.is_true(trueside_replacement[0][1] == claripy.SI(
            bits=32, stride=0, lower_bound=0, upper_bound=0)))

    falseside_sat, falseside_replacement = b.constraint_to_si(ast_false)
    nose.tools.assert_equal(falseside_sat, True)
    nose.tools.assert_equal(len(falseside_replacement), 1)
    nose.tools.assert_true(falseside_replacement[0][0] is s1)
    # False side; claripy.SI<32>1[1, 2]
    nose.tools.assert_true(
        claripy.is_true(falseside_replacement[0][1].identical(
            SI(bits=32, stride=1, lower_bound=1, upper_bound=2))))

    #
    # Extract(0, 0, Concat(BVV(0, 63), If(SI == 0, 1, 0))) == 1
    #

    s2 = claripy.SI(bits=32, stride=1, lower_bound=0, upper_bound=2)
    ast_true = (claripy.Extract(
        0, 0,
        claripy.Concat(BVV(0, 63), claripy.If(s2 == 0, BVV(1, 1),
                                              BVV(0, 1)))) == 1)
    ast_false = (claripy.Extract(
        0, 0,
        claripy.Concat(BVV(0, 63), claripy.If(s2 == 0, BVV(1, 1), BVV(0, 1))))
                 != 1)

    trueside_sat, trueside_replacement = b.constraint_to_si(ast_true)
    nose.tools.assert_equal(trueside_sat, True)
    nose.tools.assert_equal(len(trueside_replacement), 1)
    nose.tools.assert_true(trueside_replacement[0][0] is s2)
    # True side: claripy.SI<32>0[0, 0]
    nose.tools.assert_true(
        claripy.is_true(trueside_replacement[0][1].identical(
            SI(bits=32, stride=0, lower_bound=0, upper_bound=0))))

    falseside_sat, falseside_replacement = b.constraint_to_si(ast_false)
    nose.tools.assert_equal(falseside_sat, True)
    nose.tools.assert_equal(len(falseside_replacement), 1)
    nose.tools.assert_true(falseside_replacement[0][0] is s2)
    # False side; claripy.SI<32>1[1, 2]
    nose.tools.assert_true(
        claripy.is_true(falseside_replacement[0][1].identical(
            SI(bits=32, stride=1, lower_bound=1, upper_bound=2))))

    #
    # Extract(0, 0, ZeroExt(32, If(SI == 0, BVV(1, 32), BVV(0, 32)))) == 1
    #

    s3 = claripy.SI(bits=32, stride=1, lower_bound=0, upper_bound=2)
    ast_true = (claripy.Extract(
        0, 0, claripy.ZeroExt(32, claripy.If(s3 == 0, BVV(1, 32),
                                             BVV(0, 32)))) == 1)
    ast_false = (claripy.Extract(
        0, 0, claripy.ZeroExt(32, claripy.If(s3 == 0, BVV(1, 32), BVV(0, 32))))
                 != 1)

    trueside_sat, trueside_replacement = b.constraint_to_si(ast_true)
    nose.tools.assert_equal(trueside_sat, True)
    nose.tools.assert_equal(len(trueside_replacement), 1)
    nose.tools.assert_true(trueside_replacement[0][0] is s3)
    # True side: claripy.SI<32>0[0, 0]
    nose.tools.assert_true(
        claripy.is_true(trueside_replacement[0][1].identical(
            SI(bits=32, stride=0, lower_bound=0, upper_bound=0))))

    falseside_sat, falseside_replacement = b.constraint_to_si(ast_false)
    nose.tools.assert_equal(falseside_sat, True)
    nose.tools.assert_equal(len(falseside_replacement), 1)
    nose.tools.assert_true(falseside_replacement[0][0] is s3)
    # False side; claripy.SI<32>1[1, 2]
    nose.tools.assert_true(
        claripy.is_true(falseside_replacement[0][1].identical(
            SI(bits=32, stride=1, lower_bound=1, upper_bound=2))))

    #
    # Extract(0, 0, ZeroExt(32, If(Extract(32, 0, (SI & claripy.SI)) < 0, BVV(1, 1), BVV(0, 1))))
    #

    s4 = claripy.SI(bits=64,
                    stride=1,
                    lower_bound=0,
                    upper_bound=0xffffffffffffffff)
    ast_true = (claripy.Extract(
        0, 0,
        claripy.ZeroExt(
            32,
            claripy.If(
                claripy.Extract(31, 0, (s4 & s4)).SLT(0), BVV(1, 32),
                BVV(0, 32)))) == 1)
    ast_false = (claripy.Extract(
        0, 0,
        claripy.ZeroExt(
            32,
            claripy.If(
                claripy.Extract(31, 0, (s4 & s4)).SLT(0), BVV(1, 32), BVV(
                    0, 32)))) != 1)

    trueside_sat, trueside_replacement = b.constraint_to_si(ast_true)
    nose.tools.assert_equal(trueside_sat, True)
    nose.tools.assert_equal(len(trueside_replacement), 1)
    nose.tools.assert_true(trueside_replacement[0][0] is s4)
    # True side: claripy.SI<32>0[0, 0]
    nose.tools.assert_true(
        claripy.is_true(trueside_replacement[0][1].identical(
            SI(bits=64,
               stride=1,
               lower_bound=-0x8000000000000000,
               upper_bound=-1))))

    falseside_sat, falseside_replacement = b.constraint_to_si(ast_false)
    nose.tools.assert_equal(falseside_sat, True)
    nose.tools.assert_equal(len(falseside_replacement), 1)
    nose.tools.assert_true(falseside_replacement[0][0] is s4)
    # False side; claripy.SI<32>1[1, 2]
    nose.tools.assert_true(
        claripy.is_true(falseside_replacement[0][1].identical(
            SI(bits=64,
               stride=1,
               lower_bound=0,
               upper_bound=0x7fffffffffffffff))))
Esempio n. 21
0
def test_vsa_constraint_to_si():
    # Set backend
    b = claripy.backends.vsa
    s = claripy.SolverVSA() #pylint:disable=unused-variable

    SI = claripy.SI
    BVV = claripy.BVV

    claripy.vsa.strided_interval.allow_dsis = False

    #
    # If(SI == 0, 1, 0) == 1
    #

    s1 = claripy.SI(bits=32, stride=1, lower_bound=0, upper_bound=2)
    ast_true = (claripy.If(s1 == BVV(0, 32), BVV(1, 1), BVV(0, 1)) == BVV(1, 1))
    ast_false = (claripy.If(s1 == BVV(0, 32), BVV(1, 1), BVV(0, 1)) != BVV(1, 1))

    trueside_sat, trueside_replacement = b.constraint_to_si(ast_true)
    nose.tools.assert_equal(trueside_sat, True)
    nose.tools.assert_equal(len(trueside_replacement), 1)
    nose.tools.assert_true(trueside_replacement[0][0] is s1)
    # True side: claripy.SI<32>0[0, 0]
    nose.tools.assert_true(
        claripy.backends.vsa.is_true(trueside_replacement[0][1] == claripy.SI(bits=32, stride=0, lower_bound=0, upper_bound=0)))

    falseside_sat, falseside_replacement = b.constraint_to_si(ast_false)
    nose.tools.assert_equal(falseside_sat, True)
    nose.tools.assert_equal(len(falseside_replacement), 1)
    nose.tools.assert_true(falseside_replacement[0][0] is s1)
    # False side; claripy.SI<32>1[1, 2]

    nose.tools.assert_true(
        claripy.backends.vsa.identical(falseside_replacement[0][1], SI(bits=32, stride=1, lower_bound=1, upper_bound=2))
    )

    #
    # If(SI == 0, 1, 0) <= 1
    #

    s1 = SI(bits=32, stride=1, lower_bound=0, upper_bound=2)
    ast_true = (claripy.If(s1 == BVV(0, 32), BVV(1, 1), BVV(0, 1)) <= BVV(1, 1))
    ast_false = (claripy.If(s1 == BVV(0, 32), BVV(1, 1), BVV(0, 1)) > BVV(1, 1))

    trueside_sat, trueside_replacement = b.constraint_to_si(ast_true)
    nose.tools.assert_equal(trueside_sat, True) # Always satisfiable

    falseside_sat, falseside_replacement = b.constraint_to_si(ast_false)
    nose.tools.assert_equal(falseside_sat, False) # Not sat

    #
    # If(SI == 0, 20, 10) > 15
    #

    s1 = SI(bits=32, stride=1, lower_bound=0, upper_bound=2)
    ast_true = (claripy.If(s1 == BVV(0, 32), BVV(20, 32), BVV(10, 32)) > BVV(15, 32))
    ast_false = (claripy.If(s1 == BVV(0, 32), BVV(20, 32), BVV(10, 32)) <= BVV(15, 32))

    trueside_sat, trueside_replacement = b.constraint_to_si(ast_true)
    nose.tools.assert_equal(trueside_sat, True)
    nose.tools.assert_equal(len(trueside_replacement), 1)
    nose.tools.assert_true(trueside_replacement[0][0] is s1)
    # True side: SI<32>0[0, 0]
    nose.tools.assert_true(
        claripy.backends.vsa.identical(trueside_replacement[0][1], SI(bits=32, stride=0, lower_bound=0, upper_bound=0))
    )

    falseside_sat, falseside_replacement = b.constraint_to_si(ast_false)
    nose.tools.assert_equal(falseside_sat, True)
    nose.tools.assert_equal(len(falseside_replacement), 1)
    nose.tools.assert_true(falseside_replacement[0][0] is s1)
    # False side; SI<32>1[1, 2]
    nose.tools.assert_true(
        claripy.backends.vsa.identical(falseside_replacement[0][1], SI(bits=32, stride=1, lower_bound=1, upper_bound=2))
    )

    #
    # If(SI == 0, 20, 10) >= 15
    #

    s1 = SI(bits=32, stride=1, lower_bound=0, upper_bound=2)
    ast_true = (claripy.If(s1 == BVV(0, 32), BVV(15, 32), BVV(10, 32)) >= BVV(15, 32))
    ast_false = (claripy.If(s1 == BVV(0, 32), BVV(15, 32), BVV(10, 32)) < BVV(15, 32))

    trueside_sat, trueside_replacement = b.constraint_to_si(ast_true)
    nose.tools.assert_equal(trueside_sat, True)
    nose.tools.assert_equal(len(trueside_replacement), 1)
    nose.tools.assert_true(trueside_replacement[0][0] is s1)
    # True side: SI<32>0[0, 0]
    nose.tools.assert_true(
        claripy.backends.vsa.identical(trueside_replacement[0][1], SI(bits=32, stride=0, lower_bound=0, upper_bound=0))
    )

    falseside_sat, falseside_replacement = b.constraint_to_si(ast_false)
    nose.tools.assert_equal(falseside_sat, True)
    nose.tools.assert_equal(len(falseside_replacement), 1)
    nose.tools.assert_true(falseside_replacement[0][0] is s1)
    # False side; SI<32>0[0,0]
    nose.tools.assert_true(
        claripy.backends.vsa.identical(falseside_replacement[0][1], SI(bits=32, stride=1, lower_bound=1, upper_bound=2))
    )

    #
    # Extract(0, 0, Concat(BVV(0, 63), If(SI == 0, 1, 0))) == 1
    #

    s2 = claripy.SI(bits=32, stride=1, lower_bound=0, upper_bound=2)
    ast_true = (claripy.Extract(0, 0, claripy.Concat(BVV(0, 63), claripy.If(s2 == 0, BVV(1, 1), BVV(0, 1)))) == 1)
    ast_false = (claripy.Extract(0, 0, claripy.Concat(BVV(0, 63), claripy.If(s2 == 0, BVV(1, 1), BVV(0, 1)))) != 1)

    trueside_sat, trueside_replacement = b.constraint_to_si(ast_true)
    nose.tools.assert_equal(trueside_sat, True)
    nose.tools.assert_equal(len(trueside_replacement), 1)
    nose.tools.assert_true(trueside_replacement[0][0] is s2)
    # True side: claripy.SI<32>0[0, 0]
    nose.tools.assert_true(
        claripy.backends.vsa.identical(trueside_replacement[0][1], SI(bits=32, stride=0, lower_bound=0, upper_bound=0))
    )

    falseside_sat, falseside_replacement = b.constraint_to_si(ast_false)
    nose.tools.assert_equal(falseside_sat, True)
    nose.tools.assert_equal(len(falseside_replacement), 1)
    nose.tools.assert_true(falseside_replacement[0][0] is s2)
    # False side; claripy.SI<32>1[1, 2]
    nose.tools.assert_true(
        claripy.backends.vsa.identical(falseside_replacement[0][1], SI(bits=32, stride=1, lower_bound=1, upper_bound=2))
    )

    #
    # Extract(0, 0, ZeroExt(32, If(SI == 0, BVV(1, 32), BVV(0, 32)))) == 1
    #

    s3 = claripy.SI(bits=32, stride=1, lower_bound=0, upper_bound=2)
    ast_true = (claripy.Extract(0, 0, claripy.ZeroExt(32, claripy.If(s3 == 0, BVV(1, 32), BVV(0, 32)))) == 1)
    ast_false = (claripy.Extract(0, 0, claripy.ZeroExt(32, claripy.If(s3 == 0, BVV(1, 32), BVV(0, 32)))) != 1)

    trueside_sat, trueside_replacement = b.constraint_to_si(ast_true)
    nose.tools.assert_equal(trueside_sat, True)
    nose.tools.assert_equal(len(trueside_replacement), 1)
    nose.tools.assert_true(trueside_replacement[0][0] is s3)
    # True side: claripy.SI<32>0[0, 0]
    nose.tools.assert_true(
        claripy.backends.vsa.identical(trueside_replacement[0][1], SI(bits=32, stride=0, lower_bound=0, upper_bound=0))
    )

    falseside_sat, falseside_replacement = b.constraint_to_si(ast_false)
    nose.tools.assert_equal(falseside_sat, True)
    nose.tools.assert_equal(len(falseside_replacement), 1)
    nose.tools.assert_true(falseside_replacement[0][0] is s3)
    # False side; claripy.SI<32>1[1, 2]
    nose.tools.assert_true(
        claripy.backends.vsa.identical(falseside_replacement[0][1], SI(bits=32, stride=1, lower_bound=1, upper_bound=2))
    )

    #
    # Extract(0, 0, ZeroExt(32, If(Extract(32, 0, (SI & claripy.SI)) < 0, BVV(1, 1), BVV(0, 1))))
    #

    s4 = claripy.SI(bits=64, stride=1, lower_bound=0, upper_bound=0xffffffffffffffff)
    ast_true = (
        claripy.Extract(0, 0, claripy.ZeroExt(32, claripy.If(claripy.Extract(31, 0, (s4 & s4)).SLT(0), BVV(1, 32), BVV(0, 32)))) == 1)
    ast_false = (
        claripy.Extract(0, 0, claripy.ZeroExt(32, claripy.If(claripy.Extract(31, 0, (s4 & s4)).SLT(0), BVV(1, 32), BVV(0, 32)))) != 1)

    trueside_sat, trueside_replacement = b.constraint_to_si(ast_true)
    nose.tools.assert_equal(trueside_sat, True)
    nose.tools.assert_equal(len(trueside_replacement), 1)
    nose.tools.assert_true(trueside_replacement[0][0] is s4[31:0])
    # True side: claripy.SI<32>0[0, 0]
    nose.tools.assert_true(
        claripy.backends.vsa.identical(trueside_replacement[0][1], SI(bits=32, stride=1, lower_bound=-0x80000000, upper_bound=-1))
    )

    falseside_sat, falseside_replacement = b.constraint_to_si(ast_false)
    nose.tools.assert_equal(falseside_sat, True)
    nose.tools.assert_equal(len(falseside_replacement), 1)
    nose.tools.assert_true(falseside_replacement[0][0] is s4[31:0])
    # False side; claripy.SI<32>1[1, 2]
    nose.tools.assert_true(
        claripy.backends.vsa.identical(falseside_replacement[0][1], SI(bits=32, stride=1, lower_bound=0, upper_bound=0x7fffffff))
    )

    #
    # TOP_SI != -1
    #

    s5 = claripy.SI(bits=32, stride=1, lower_bound=0, upper_bound=0xffffffff)
    ast_true = (s5 == claripy.SI(bits=32, stride=1, lower_bound=0xffffffff, upper_bound=0xffffffff))
    ast_false = (s5 != claripy.SI(bits=32, stride=1, lower_bound=0xffffffff, upper_bound=0xffffffff))

    trueside_sat, trueside_replacement = b.constraint_to_si(ast_true)
    nose.tools.assert_true(trueside_sat)
    nose.tools.assert_equal(len(trueside_replacement), 1)
    nose.tools.assert_true(trueside_replacement[0][0] is s5)
    nose.tools.assert_true(claripy.backends.vsa.identical(trueside_replacement[0][1],
                                                          SI(bits=32, stride=1, lower_bound=0xffffffff,
                                                             upper_bound=0xffffffff)
                                                          )
                           )

    falseside_sat, falseside_replacement = b.constraint_to_si(ast_false)
    nose.tools.assert_true(falseside_sat)
    nose.tools.assert_equal(len(falseside_replacement), 1)
    nose.tools.assert_true(falseside_replacement[0][0] is s5)
    nose.tools.assert_true(claripy.backends.vsa.identical(falseside_replacement[0][1],
                                                          SI(bits=32, stride=1, lower_bound=0,
                                                             upper_bound=0xfffffffe)
                                                          )
                           )
Esempio n. 22
0
def sat_negative(se, expr):
    size = expr.size()
    return se.satisfiable(
        extra_constraints=([claripy.Extract(size - 1, size - 1, expr) == 1]))
Esempio n. 23
0
def sat_positive(se, expr):
    return se.satisfiable(
        extra_constraints=([claripy.Extract(size - 1, size - 1, expr) == 0]))
Esempio n. 24
0
 def _op_generic_GetMSBs(self, args):
     size = self._vector_count * self._vector_size
     bits = [claripy.Extract(i, i, args[0]) for i in range(size - 1, 6, -8)]
     return claripy.Concat(*bits)
Esempio n. 25
0
 def _op_extract(self, args):
     return claripy.Extract(self._to_size - 1, 0, args[0])
Esempio n. 26
0
 def _op_lo_half(self, args):
     return claripy.Extract(args[0].size() // 2 - 1, 0, args[0])
Esempio n. 27
0
 def _op_hi_half(self, args):
     return claripy.Extract(args[0].size() - 1, args[0].size() // 2,
                            args[0])
Esempio n. 28
0
 def _op_vector_mapped(self, args):
     chopped_args = ([
         claripy.Extract((i + 1) * self._vector_size - 1,
                         i * self._vector_size, a) for a in args
     ] for i in reversed(range(self._vector_count)))
     return claripy.Concat(*(self._op_mapped(ca) for ca in chopped_args))
Esempio n. 29
0
    def _ail_handle_Convert(self, expr: Expr.Convert) -> PropValue:
        o_value = self._expr(expr.operand)

        if o_value is None or self.state.is_top(o_value.value):
            new_value = self.state.top(expr.to_bits)
        else:
            if expr.from_bits < expr.to_bits:
                if expr.is_signed:
                    new_value = claripy.SignExt(expr.to_bits - expr.from_bits, o_value.value)
                else:
                    new_value = claripy.ZeroExt(expr.to_bits - expr.from_bits, o_value.value)
            elif expr.from_bits > expr.to_bits:
                new_value = claripy.Extract(expr.to_bits - 1, 0, o_value.value)
            else:
                new_value = o_value.value

        o_expr = o_value.one_expr
        o_defat = o_value.one_defat
        if o_expr is not None:
            # easy cases
            if type(o_expr) is Expr.Convert:
                if expr.from_bits == o_expr.to_bits and expr.to_bits == o_expr.from_bits:
                    # eliminate the redundant Convert
                    new_expr = o_expr.operand
                else:
                    new_expr = Expr.Convert(expr.idx, o_expr.from_bits, expr.to_bits, expr.is_signed, o_expr.operand)
            elif type(o_expr) is Expr.Const:
                # do the conversion right away
                value = o_expr.value
                mask = (2 ** expr.to_bits) - 1
                value &= mask
                new_expr = Expr.Const(expr.idx, o_expr.variable, value, expr.to_bits)
            else:
                new_expr = Expr.Convert(expr.idx, expr.from_bits, expr.to_bits, expr.is_signed, o_expr, **expr.tags)

            if isinstance(new_expr, Expr.Convert) and not new_expr.is_signed \
                    and new_expr.to_bits > new_expr.from_bits and new_expr.from_bits % self.arch.byte_width == 0:
                # special handling for zero-extension: it simplifies the code if we explicitly model zeros
                new_size = new_expr.from_bits // self.arch.byte_width
                offset_and_details = {
                    0: Detail(new_size, new_expr.operand, o_defat),
                    new_size: Detail(
                        new_expr.size - new_size,
                        Expr.Const(expr.idx, None, 0, new_expr.to_bits - new_expr.from_bits),
                        self._codeloc()),
                }
            else:
                offset_and_details = {0: Detail(expr.size, new_expr, self._codeloc())}

            return PropValue(new_value, offset_and_details=offset_and_details)

        elif o_value.offset_and_details:
            # hard cases... we will keep certain labels and eliminate other labels
            start_offset = 0
            end_offset = expr.to_bits // self.arch.byte_width  # end_offset is exclusive
            offset_and_details = {}
            max_offset = max(o_value.offset_and_details.keys())
            for offset_, detail_ in o_value.offset_and_details.items():
                if offset_ < start_offset < offset_ + detail_.size:
                    # we start here
                    off = 0
                    siz = min(end_offset, offset_ + detail_.size) - start_offset
                    expr_ = PropValue.extract_ail_expression(
                        (start_offset - offset_) * self.arch.byte_width,
                        siz * self.arch.byte_width,
                        detail_.expr
                    )
                    offset_and_details[off] = Detail(siz, expr_, detail_.def_at)
                elif offset_ >= start_offset and offset_ + detail_.size <= end_offset:
                    # we include the whole thing
                    off = offset_ - start_offset
                    siz = detail_.size
                    if off == max_offset and off + siz < end_offset:
                        # extend the expr
                        expr_ = PropValue.extend_ail_expression(
                            (end_offset - (off + siz)) * self.arch.byte_width,
                            detail_.expr
                        )
                        siz = end_offset - off
                    else:
                        expr_ = detail_.expr
                    offset_and_details[off] = Detail(siz, expr_, detail_.def_at)
                elif offset_ < end_offset <= offset_ + detail_.size:
                    # we include all the way until end_offset
                    if offset_ < start_offset:
                        off = 0
                        siz = end_offset - start_offset
                    else:
                        off = offset_ - start_offset
                        siz = end_offset - offset_
                    expr_ = PropValue.extract_ail_expression(0, siz * self.arch.byte_width, detail_.expr)
                    offset_and_details[off] = Detail(siz, expr_, detail_.def_at)

            return PropValue(
                new_value,
                offset_and_details=offset_and_details
            )
        else:
            # it's empty... no expression is available for whatever reason
            return PropValue.from_value_and_details(new_value, expr.size, expr, self._codeloc())
 def extend_BV32_to_BV64(f, bvs_dict):
     is_bv = isinstance(f, claripy.ast.bv.BV)
     is_bool = isinstance(f, claripy.ast.bool.Bool)
     if not is_bv and not is_bool:
         return f
     if f.depth == 1:
         if isinstance(f, claripy.ast.bv.BV) and f.size() == 32:
             if f.symbolic:
                 f_name = str(f._encoded_name, 'utf8')
                 f_name = f_name[:f_name.rfind('_')]
                 f_name = f_name[:f_name.rfind('_')]
                 if f_name not in bvs_dict:
                     bvs_dict[f_name] = claripy.BVS(name=f_name, size=64)
                 return bvs_dict[f_name]
             else:
                 if f.args[0] & (1 << 31):
                     return claripy.BVV(0xffffffff00000000 | f.args[0], 64)
                 else:
                     return claripy.BVV(f.args[0], 64)
         else:
             return f
     elif f.depth == 2 and f.op == 'Extract' and f.args[
             2].symbolic and f.args[2].size() == 32:
         # an Extract is regarded as a leaf node
         return claripy.Extract(
             f.args[0], f.args[1],
             FormulaExtractor.extend_BV32_to_BV64(f.args[2], bvs_dict))
     elif f.op == 'Concat':
         # we make sure that Concat will not change the size of f
         new_args = []
         for arg in f.args:
             tmp = FormulaExtractor.extend_BV32_to_BV64(arg, bvs_dict)
             # we Extract the corresponding bits
             tmp = claripy.Extract(arg.size() - 1, 0, tmp)
             new_args.append(tmp)
         return claripy.Concat(*new_args)
     elif hasattr(f, 'args') and hasattr(f, 'size'):
         # many binary op requires same size of left hand side and right hand side
         # if LHS and RHS are 32 bits, we turn both side into 64 bits
         new_args = []
         all_same_size = True
         for i in range(len(f.args) - 1):
             if not hasattr(f.args[i], 'size') or not hasattr(f.args[i + 1], 'size') \
                     or f.args[i].size() != f.args[i + 1].size():
                 all_same_size = False
                 break
         if f.op.startswith('__') and all_same_size:
             new_args = [
                 FormulaExtractor.extend_BV32_to_BV64(
                     f.args[idx], bvs_dict) for idx in range(len(f.args))
             ]
             # we simply think LHS and RHS mush have same size
             if f.args[0].size() == 32:
                 # we extend the size to 64 bits
                 for idx in range(len(f.args)):
                     if new_args[idx].size() < 64:
                         new_args[idx] = claripy.Concat(
                             claripy.BVV(0, 64 - new_args[idx].size()),
                             new_args[idx])
             else:
                 # we make sure the size has not been changed
                 for idx in range(len(f.args)):
                     if new_args[idx].size() > f.args[idx].size():
                         new_args[idx] = claripy.Extract(
                             f.args[idx].size() - 1, 0, new_args[idx])
                     elif new_args[idx].size() < f.args[idx].size():
                         new_args[idx] = claripy.Concat(
                             claripy.BVV(
                                 0,
                                 f.args[idx].size() - new_args[idx].size()),
                             new_args[idx])
         else:
             for arg in f.args:
                 new_args.append(
                     FormulaExtractor.extend_BV32_to_BV64(arg, bvs_dict))
         if is_bv:
             f = claripy.ast.BV(op=f.op, args=tuple(new_args), length=64)
         elif is_bool:
             f = claripy.ast.Bool(op=f.op, args=tuple(new_args))
         return f
     else:
         new_args = []
         for arg in f.args:
             new_args.append(
                 FormulaExtractor.extend_BV32_to_BV64(arg, bvs_dict))
         if is_bv:
             f = claripy.ast.BV(op=f.op, args=tuple(new_args), length=64)
         elif is_bool:
             f = claripy.ast.Bool(op=f.op, args=tuple(new_args))
         return f