示例#1
0
def test_replacement_solver():
    sr = claripy.SolverReplacement()
    x = claripy.BVS('x', 32)
    nose.tools.assert_equal(len(sr.eval(x, 10)), 10)
    sr.add_replacement(x, claripy.BVV(0x101, 32))
    nose.tools.assert_equal(sr.eval(x, 10), (0x101, ))

    y = claripy.BVS('y', 32)
    sr.add([y + 1 == 200])
    assert (y + 1).cache_key in sr._replacements
    assert sr._replacement(y + 1) is claripy.BVV(200, 32)

    srb = sr.branch()
    assert len(srb.constraints) == len(sr.constraints)  #pylint:disable=no-member
    assert (y + 1).cache_key in sr._replacements
    assert sr._replacement(y + 1) is claripy.BVV(200, 32)

    sr = claripy.SolverReplacement()
    b = claripy.BoolS('b')
    assert sr._replacement(b) is b
    sr.add(claripy.Not(b))
    assert sr._replacement(b) is claripy.false

    sr = claripy.SolverReplacement(claripy.SolverVSA(),
                                   complex_auto_replace=True)
    x = claripy.BVS('x', 64)
    sr.add([x + 8 <= 0xffffffffffffffff])
    sr.add([x + 8 >= 0])
    assert sr._replacement(x) is not x
示例#2
0
def test_replacement_solver():
    sr = claripy.ReplacementFrontend(claripy.FullFrontend(claripy.backends.z3))
    x = claripy.BVS('x', 32)
    nose.tools.assert_equals(len(sr.eval(x, 10)), 10)
    sr.result = None
    sr.add_replacement(x, claripy.BVV(0x101, 32))
    nose.tools.assert_items_equal(sr.eval(x, 10), [0x101])

    y = claripy.BVS('y', 32)
    sr.add([y+1 == 200])
    assert (y+1).cache_key in sr._replacements
    assert sr._replacement(y+1) is claripy.BVV(200, 32)

    srb = sr.branch()
    assert len(srb.constraints) == len(sr.constraints)
    assert (y+1).cache_key in sr._replacements
    assert sr._replacement(y+1) is claripy.BVV(200, 32)

    sr = claripy.ReplacementFrontend(claripy.FullFrontend(claripy.backends.z3))
    b = claripy.BoolS('b')
    assert sr._replacement(b) is b
    sr.add(claripy.Not(b))
    assert sr._replacement(b) is claripy.false

    sr = claripy.ReplacementFrontend(claripy.LightFrontend(claripy.backends.vsa), complex_auto_replace=True)
    x = claripy.BVS('x', 64)
    sr.add([x + 8 <= 0xffffffffffffffff])
    sr.add([x + 8 >= 0])
    assert sr._replacement(x) is not x
示例#3
0
def test_canonical():
    x1 = claripy.BVS('x', 32)
    b1 = claripy.BoolS('b')
    c1 = claripy.BoolS('c')
    x2 = claripy.BVS('x', 32)
    b2 = claripy.BoolS('b')
    c2 = claripy.BoolS('c')

    y1 = claripy.If(claripy.And(b1, c1), x1, ((x1+x1)*x1)+1)
    y2 = claripy.If(claripy.And(b2, c2), x2, ((x2+x2)*x2)+1)

    one_names = frozenset.union(x1.variables, b1.variables, c1.variables)
    two_names = frozenset.union(x2.variables, b2.variables, c2.variables)

    assert frozenset.union(*[a.variables for a in y1.recursive_leaf_asts]) == one_names
    assert frozenset.union(*[a.variables for a in y2.recursive_leaf_asts]) == two_names
    assert y1.canonicalize()[-1] is y2.canonicalize()[-1]
示例#4
0
def perf_boolean_and_simplification_1():
    # Create a gigantic And AST with many operands, many variables at a time
    bool_vars = [claripy.BoolS("b%d" % i) for i in range(500)]
    v = bool_vars[0]
    for i in range(1, len(bool_vars)):
        if v.op == "And":
            v = claripy.And(*(v.args + (bool_vars[i] == False, )))  # pylint:disable=singleton-comparison
        else:
            v = claripy.And(v, bool_vars[i])
示例#5
0
    def run(self, this_ref, key_ref):
        log.debug('Called SimProcedure java.util.Map.containsKey with args: {} {}'.format(this_ref, key_ref))

        if this_ref.symbolic:
            return claripy.BoolS('contains_key')

        try:
            this_ref.load_field(self.state, get_map_key(self.state, key_ref), 'java.lang.Object')
            return claripy.BoolV(1)

        except (KeyError, AttributeError):
            return claripy.BoolV(0)
示例#6
0
    def _bool_variable_from_ail_condition(self, condition):

        # Unpack a condition all the way to the leaves

        _mapping = {
            'LogicalAnd':
            lambda expr, conv: claripy.And(conv(expr.operands[0]),
                                           conv(expr.operands[1])),
            'LogicalOr':
            lambda expr, conv: claripy.Or(conv(expr.operands[0]),
                                          conv(expr.operands[1])),
            'CmpEQ':
            lambda expr, conv: conv(expr.operands[0]) == conv(expr.operands[1]
                                                              ),
            'CmpLE':
            lambda expr, conv: conv(expr.operands[0]) <= conv(expr.operands[1]
                                                              ),
            'Not':
            lambda expr, conv: claripy.Not(conv(expr.operand)),
            'Xor':
            lambda expr, conv: conv(expr.operands[0]) ^ conv(expr.operands[1]),
        }

        if isinstance(condition, (ailment.Expr.Load, ailment.Expr.Register,
                                  ailment.Expr.DirtyExpression)):
            var = claripy.BVS('ailexpr_%s' % repr(condition),
                              condition.bits,
                              explicit_name=True)
            self._condition_mapping[var] = condition
            return var
        elif isinstance(condition, ailment.Expr.Convert):
            # convert is special. if it generates a 1-bit variable, it should be treated as a BVS
            if condition.to_bits == 1:
                var = claripy.BoolS('ailcond_%s' % repr(condition),
                                    explicit_name=True)
            else:
                var = claripy.BVS('ailexpr_%s' % repr(condition),
                                  condition.to_bits,
                                  explicit_name=True)
            self._condition_mapping[var] = condition
            return var
        elif isinstance(condition, ailment.Expr.Const):
            var = claripy.BVV(condition.value, condition.bits)
            return var

        lambda_expr = _mapping.get(condition.op, None)
        if lambda_expr is None:
            raise NotImplementedError(
                "Unsupported AIL expression operation %s. Consider implementing."
                % condition.op)
        return lambda_expr(condition, self._bool_variable_from_ail_condition)
示例#7
0
    def run(self, this_ref):
        log.debug(
            'Called SimProcedure java.util.Iterator.hasNext with args: {}'.
            format(this_ref))

        if this_ref.symbolic:
            return claripy.BoolS('iterator.hasNext')

        iterator_size = this_ref.load_field(self.state, SIZE, 'int')
        iterator_index = this_ref.load_field(self.state, INDEX, 'int')

        has_next = self.state.solver.eval(
            iterator_index) < self.state.solver.eval(iterator_size)

        return claripy.BoolV(has_next)
示例#8
0
def test_bool_simplification():
    def assert_correct(a, b):
        nose.tools.assert_true(
            claripy.backends.z3.identical(claripy.simplify(a), b))

    a, b, c = (claripy.BoolS(name) for name in ('a', 'b', 'c'))

    assert_correct(claripy.And(a, claripy.Not(a)), claripy.false)
    assert_correct(claripy.Or(a, claripy.Not(a)), claripy.true)

    complex_true_expression = claripy.Or(
        claripy.And(a, b),
        claripy.Or(claripy.And(a, claripy.Not(b)),
                   claripy.And(claripy.Not(a), c)),
        claripy.Or(claripy.And(a, claripy.Not(b)),
                   claripy.And(claripy.Not(a), claripy.Not(c))))
    assert_correct(complex_true_expression, claripy.true)
示例#9
0
    def run(self, this_ref, obj_ref):
        log.debug(
            'Called SimProcedure java.util.List.add with args: {} {}'.format(
                this_ref, obj_ref))

        if this_ref.symbolic:
            return claripy.BoolS('list.append')

        try:
            array_ref = this_ref.load_field(self.state, ELEMS,
                                            'java.lang.Object[]')
            array_len = this_ref.load_field(self.state, SIZE, 'int')
            self.state.javavm_memory.store_array_element(
                array_ref, array_len, obj_ref)
            # Update size
            new_array_len = claripy.BVV(
                self.state.solver.eval(array_len) + 1, 32)
            this_ref.store_field(self.state, SIZE, 'int', new_array_len)
        except KeyError:
            log.warning('Could not add element to list {}'.format(this_ref))

        return claripy.BoolV(1)
示例#10
0
    def claripy_ast_from_ail_condition(self, condition) -> claripy.ast.Base:

        # Unpack a condition all the way to the leaves
        if isinstance(condition, claripy.ast.Base):  # pylint:disable=isinstance-second-argument-not-valid-type
            return condition

        def _op_with_unified_size(op, conv, operand0, operand1):
            # ensure operand1 is of the same size as operand0
            if isinstance(operand1, ailment.Expr.Const):
                # amazing - we do the eazy thing here
                return op(conv(operand0), operand1.value)
            if operand1.bits == operand0.bits:
                return op(conv(operand0), conv(operand1))
            # extension is required
            assert operand1.bits < operand0.bits
            operand1 = ailment.Expr.Convert(None, operand1.bits, operand0.bits, False, operand1)
            return op(conv(operand0), conv(operand1))

        _mapping = {
            'LogicalAnd': lambda expr, conv: claripy.And(conv(expr.operands[0]), conv(expr.operands[1])),
            'LogicalOr': lambda expr, conv: claripy.Or(conv(expr.operands[0]), conv(expr.operands[1])),
            'CmpEQ': lambda expr, conv: conv(expr.operands[0]) == conv(expr.operands[1]),
            'CmpNE': lambda expr, conv: conv(expr.operands[0]) != conv(expr.operands[1]),
            'CmpLE': lambda expr, conv: conv(expr.operands[0]) <= conv(expr.operands[1]),
            'CmpLEs': lambda expr, conv: claripy.SLE(conv(expr.operands[0]), conv(expr.operands[1])),
            'CmpLT': lambda expr, conv: conv(expr.operands[0]) < conv(expr.operands[1]),
            'CmpLTs': lambda expr, conv: claripy.SLT(conv(expr.operands[0]), conv(expr.operands[1])),
            'CmpGE': lambda expr, conv: conv(expr.operands[0]) >= conv(expr.operands[1]),
            'CmpGEs': lambda expr, conv: claripy.SGE(conv(expr.operands[0]), conv(expr.operands[1])),
            'CmpGT': lambda expr, conv: conv(expr.operands[0]) > conv(expr.operands[1]),
            'CmpGTs': lambda expr, conv: claripy.SGT(conv(expr.operands[0]), conv(expr.operands[1])),
            'Add': lambda expr, conv: conv(expr.operands[0]) + conv(expr.operands[1]),
            'Sub': lambda expr, conv: conv(expr.operands[0]) - conv(expr.operands[1]),
            'Mul': lambda expr, conv: conv(expr.operands[0]) * conv(expr.operands[1]),
            'Not': lambda expr, conv: claripy.Not(conv(expr.operand)),
            'Xor': lambda expr, conv: conv(expr.operands[0]) ^ conv(expr.operands[1]),
            'And': lambda expr, conv: conv(expr.operands[0]) & conv(expr.operands[1]),
            'Or': lambda expr, conv: conv(expr.operands[0]) | conv(expr.operands[1]),
            'Shr': lambda expr, conv: _op_with_unified_size(claripy.LShR, conv, expr.operands[0], expr.operands[1]),
            'Shl': lambda expr, conv: _op_with_unified_size(operator.lshift, conv, expr.operands[0], expr.operands[1]),
            'Sar': lambda expr, conv: _op_with_unified_size(operator.rshift, conv, expr.operands[0], expr.operands[1]),
        }

        if isinstance(condition, (ailment.Expr.Load, ailment.Expr.DirtyExpression, ailment.Expr.BasePointerOffset,
                                  ailment.Expr.ITE, ailment.Stmt.Call)):
            var = claripy.BVS('ailexpr_%s' % repr(condition), condition.bits, explicit_name=True)
            self._condition_mapping[var.args[0]] = condition
            return var
        elif isinstance(condition, ailment.Expr.Register):
            var = claripy.BVS('ailexpr_%s-%d' % (repr(condition), condition.idx), condition.bits, explicit_name=True)
            self._condition_mapping[var.args[0]] = condition
            return var
        elif isinstance(condition, ailment.Expr.Convert):
            # convert is special. if it generates a 1-bit variable, it should be treated as a BVS
            if condition.to_bits == 1:
                var_ = self.claripy_ast_from_ail_condition(condition.operands[0])
                name = 'ailcond_Conv(%d->%d, %s)' % (condition.from_bits, condition.to_bits, repr(var_))
                var = claripy.BoolS(name, explicit_name=True)
            else:
                var_ = self.claripy_ast_from_ail_condition(condition.operands[0])
                name = 'ailexpr_Conv(%d->%d, %s)' % (condition.from_bits, condition.to_bits, repr(var_))
                var = claripy.BVS(name, condition.to_bits, explicit_name=True)
            self._condition_mapping[var.args[0]] = condition
            return var
        elif isinstance(condition, ailment.Expr.Const):
            var = claripy.BVV(condition.value, condition.bits)
            return var
        elif isinstance(condition, ailment.Expr.Tmp):
            l.warning("Left-over ailment.Tmp variable %s.", condition)
            if condition.bits == 1:
                var = claripy.BoolV('ailtmp_%d' % condition.tmp_idx)
            else:
                var = claripy.BVS('ailtmp_%d' % condition.tmp_idx, condition.bits, explicit_name=True)
            self._condition_mapping[var.args[0]] = condition
            return var

        lambda_expr = _mapping.get(condition.verbose_op, None)
        if lambda_expr is None:
            raise NotImplementedError("Unsupported AIL expression operation %s. Consider implementing." % condition.op)
        r = lambda_expr(condition, self.claripy_ast_from_ail_condition)
        if r is NotImplemented:
            r = claripy.BVS("ailexpr_%r" % condition, condition.bits, explicit_name=True)
            self._condition_mapping[r.args[0]] = condition
        else:
            # don't lose tags
            r = r.annotate(TagsAnnotation(**condition.tags))
        return r
示例#11
0
def perf_boolean_and_simplification_0():
    # Create a gigantic And AST with many operands, one variable at a time
    bool_vars = [claripy.BoolS("b%d" % i) for i in range(1500)]
    v = bool_vars[0]
    for i in range(1, len(bool_vars)):
        v = claripy.And(v, bool_vars[i])
示例#12
0
    def claripy_ast_from_ail_condition(self, condition):

        # Unpack a condition all the way to the leaves
        if isinstance(condition, claripy.ast.Base):
            return condition

        _mapping = {
            'LogicalAnd':
            lambda expr, conv: claripy.And(conv(expr.operands[0]),
                                           conv(expr.operands[1])),
            'LogicalOr':
            lambda expr, conv: claripy.Or(conv(expr.operands[0]),
                                          conv(expr.operands[1])),
            'CmpEQ':
            lambda expr, conv: conv(expr.operands[0]) == conv(expr.operands[1]
                                                              ),
            'CmpNE':
            lambda expr, conv: conv(expr.operands[0]) != conv(expr.operands[1]
                                                              ),
            'CmpLE':
            lambda expr, conv: conv(expr.operands[0]) <= conv(expr.operands[1]
                                                              ),
            'CmpLEs':
            lambda expr, conv: claripy.SLE(conv(expr.operands[0]),
                                           conv(expr.operands[1])),
            'CmpLT':
            lambda expr, conv: conv(expr.operands[0]) < conv(expr.operands[1]),
            'CmpLTs':
            lambda expr, conv: claripy.SLT(conv(expr.operands[0]),
                                           conv(expr.operands[1])),
            'CmpGE':
            lambda expr, conv: conv(expr.operands[0]) >= conv(expr.operands[1]
                                                              ),
            'CmpGEs':
            lambda expr, conv: claripy.SGE(conv(expr.operands[0]),
                                           conv(expr.operands[1])),
            'CmpGT':
            lambda expr, conv: conv(expr.operands[0]) > conv(expr.operands[1]),
            'CmpGTs':
            lambda expr, conv: claripy.SGT(conv(expr.operands[0]),
                                           conv(expr.operands[1])),
            'Add':
            lambda expr, conv: conv(expr.operands[0]) + conv(expr.operands[1]),
            'Sub':
            lambda expr, conv: conv(expr.operands[0]) - conv(expr.operands[1]),
            'Not':
            lambda expr, conv: claripy.Not(conv(expr.operand)),
            'Xor':
            lambda expr, conv: conv(expr.operands[0]) ^ conv(expr.operands[1]),
            'And':
            lambda expr, conv: conv(expr.operands[0]) & conv(expr.operands[1]),
            'Or':
            lambda expr, conv: conv(expr.operands[0]) | conv(expr.operands[1]),
            'Shr':
            lambda expr, conv: claripy.LShR(conv(expr.operands[0]), expr.
                                            operands[1].value)
        }

        if isinstance(condition,
                      (ailment.Expr.Load, ailment.Expr.DirtyExpression,
                       ailment.Expr.BasePointerOffset)):
            var = claripy.BVS('ailexpr_%s' % repr(condition),
                              condition.bits,
                              explicit_name=True)
            self._condition_mapping[var] = condition
            return var
        elif isinstance(condition, ailment.Expr.Register):
            var = claripy.BVS('ailexpr_%s-%d' %
                              (repr(condition), condition.idx),
                              condition.bits,
                              explicit_name=True)
            self._condition_mapping[var] = condition
            return var
        elif isinstance(condition, ailment.Expr.Convert):
            # convert is special. if it generates a 1-bit variable, it should be treated as a BVS
            if condition.to_bits == 1:
                var_ = self.claripy_ast_from_ail_condition(
                    condition.operands[0])
                name = 'ailcond_Conv(%d->%d, %s)' % (
                    condition.from_bits, condition.to_bits, repr(var_))
                var = claripy.BoolS(name, explicit_name=True)
            else:
                var_ = self.claripy_ast_from_ail_condition(
                    condition.operands[0])
                name = 'ailexpr_Conv(%d->%d, %s)' % (
                    condition.from_bits, condition.to_bits, repr(var_))
                var = claripy.BVS(name, condition.to_bits, explicit_name=True)
            self._condition_mapping[var] = condition
            return var
        elif isinstance(condition, ailment.Expr.Const):
            var = claripy.BVV(condition.value, condition.bits)
            return var
        elif isinstance(condition, ailment.Expr.Tmp):
            l.warning("Left-over ailment.Tmp variable %s.", condition)
            if condition.bits == 1:
                var = claripy.BoolV('ailtmp_%d' % condition.tmp_idx)
            else:
                var = claripy.BVS('ailtmp_%d' % condition.tmp_idx,
                                  condition.bits)
            self._condition_mapping[var] = condition
            return var

        lambda_expr = _mapping.get(condition.verbose_op, None)
        if lambda_expr is None:
            raise NotImplementedError(
                "Unsupported AIL expression operation %s. Consider implementing."
                % condition.op)
        r = lambda_expr(condition, self.claripy_ast_from_ail_condition)
        if r is NotImplemented:
            r = claripy.BVS("ailexpr_%r" % condition,
                            condition.bits,
                            explicit_name=True)
            self._condition_mapping[r] = condition
        return r
示例#13
0
 def _bool_variable_from_ail_condition(self, block, condition):
     var = claripy.BoolS('structurer-cond_%#x_%s' %
                         (block.addr, repr(condition)),
                         explicit_name=True)
     self._condition_mapping[var] = condition
     return var
示例#14
0
 def _bool_variable_from_ail_condition(block, condition):
     return claripy.BoolS('structurer-cond_%#x_%s' %
                          (block.addr, repr(condition)),
                          explicit_name=True)
示例#15
0
 def eof(self):
     return claripy.BoolS("duplex_eof")