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
def _solver(self): """ Creates or gets a Claripy solver, based on the state options. """ if self._stored_solver is not None: return self._stored_solver track = o.CONSTRAINT_TRACKING_IN_SOLVER in self.state.options if o.ABSTRACT_SOLVER in self.state.options: self._stored_solver = claripy.SolverVSA() elif o.REPLACEMENT_SOLVER in self.state.options: self._stored_solver = claripy.SolverReplacement(auto_replace=False) elif o.CACHELESS_SOLVER in self.state.options: self._stored_solver = claripy.SolverCacheless(track=track) elif o.COMPOSITE_SOLVER in self.state.options: self._stored_solver = claripy.SolverComposite(track=track) elif o.SYMBOLIC in self.state.options and o.approximation & self.state.options: self._stored_solver = claripy.SolverHybrid(track=track) elif o.SYMBOLIC in self.state.options: self._stored_solver = claripy.Solver(track=track) else: self._stored_solver = claripy.SolverConcrete() return self._stored_solver
def test_replacement_solver(): sr = claripy.SolverReplacement(claripy.SolverVSA(), replace_constraints=True, complex_auto_replace=True) x = claripy.BVS('x', 32) sr.add(x + 8 == 10) assert sr.max(x) == sr.min(x) sr2 = sr.branch() sr2.add(x + 8 < 2000) assert sr2.max(x) == sr2.min(x) == sr.max(x)
def _solver(self): """ Creates or gets a Claripy solver, based on the state options. """ if self._stored_solver is not None: return self._stored_solver track = o.CONSTRAINT_TRACKING_IN_SOLVER in self.state.options approximate_first = o.APPROXIMATE_FIRST in self.state.options if o.STRINGS_ANALYSIS in self.state.options: if 'smtlib_cvc4' in backend_manager.backends._backends_by_name: our_backend = backend_manager.backends.smtlib_cvc4 elif 'smtlib_z3' in backend_manager.backends._backends_by_name: our_backend = backend_manager.backends.smtlib_z3 elif 'smtlib_abc' in backend_manager.backends._backends_by_name: our_backend = backend_manager.backends.smtlib_abc else: l.error( "Cannot find a suitable string solver. Please ensure you have installed a string solver that " "angr supports, and have imported the corresponding solver backend in claripy. You can try " "adding \"from claripy.backends.backend_smtlib_solvers import *\" at the beginning of your " "script.") raise ValueError("Cannot find a suitable string solver") if o.COMPOSITE_SOLVER in self.state.options: self._stored_solver = claripy.SolverComposite( template_solver_string=claripy.SolverCompositeChild( backend=our_backend, track=track)) elif o.ABSTRACT_SOLVER in self.state.options: self._stored_solver = claripy.SolverVSA() elif o.SYMBOLIC in self.state.options and o.REPLACEMENT_SOLVER in self.state.options: self._stored_solver = claripy.SolverReplacement(auto_replace=False) elif o.SYMBOLIC in self.state.options and o.CACHELESS_SOLVER in self.state.options: self._stored_solver = claripy.SolverCacheless(track=track) elif o.SYMBOLIC in self.state.options and o.COMPOSITE_SOLVER in self.state.options: self._stored_solver = claripy.SolverComposite(track=track) elif o.SYMBOLIC in self.state.options and any( opt in self.state.options for opt in o.approximation): self._stored_solver = claripy.SolverHybrid( track=track, approximate_first=approximate_first) elif o.HYBRID_SOLVER in self.state.options: self._stored_solver = claripy.SolverHybrid( track=track, approximate_first=approximate_first) elif o.SYMBOLIC in self.state.options: self._stored_solver = claripy.Solver(track=track) else: self._stored_solver = claripy.SolverConcrete() return self._stored_solver
def _solver(self): """ Creates or gets a Claripy solver, based on the state options. """ if self._stored_solver is not None: return self._stored_solver track = o.CONSTRAINT_TRACKING_IN_SOLVER in self.state.options approximate_first = o.APPROXIMATE_FIRST in self.state.options if o.STRINGS_ANALYSIS in self.state.options: if 'smtlib_cvc4' in backend_manager.backends._backends_by_name: our_backend = backend_manager.backends.smtlib_cvc4 elif 'smtlib_z3' in backend_manager.backends._backends_by_name: our_backend = backend_manager.backends.smtlib_z3 elif 'smtlib_abc' in backend_manager.backends._backends_by_name: our_backend = backend_manager.backends.smtlib_abc else: raise ValueError("Could not find suitable string solver!") if o.COMPOSITE_SOLVER in self.state.options: self._stored_solver = claripy.SolverComposite( template_solver_string=claripy.SolverCompositeChild( backend=our_backend, track=track)) elif o.ABSTRACT_SOLVER in self.state.options: self._stored_solver = claripy.SolverVSA() elif o.SYMBOLIC in self.state.options and o.REPLACEMENT_SOLVER in self.state.options: self._stored_solver = claripy.SolverReplacement(auto_replace=False) elif o.SYMBOLIC in self.state.options and o.CACHELESS_SOLVER in self.state.options: self._stored_solver = claripy.SolverCacheless(track=track) elif o.SYMBOLIC in self.state.options and o.COMPOSITE_SOLVER in self.state.options: self._stored_solver = claripy.SolverComposite(track=track) elif o.SYMBOLIC in self.state.options and any( opt in self.state.options for opt in o.approximation): self._stored_solver = claripy.SolverHybrid( track=track, approximate_first=approximate_first) elif o.HYBRID_SOLVER in self.state.options: self._stored_solver = claripy.SolverHybrid( track=track, approximate_first=approximate_first) elif o.SYMBOLIC in self.state.options: self._stored_solver = claripy.Solver(track=track) else: self._stored_solver = claripy.SolverConcrete() return self._stored_solver
def _solver(self): if self._stored_solver is not None: return self._stored_solver if o.ABSTRACT_SOLVER in self.state.options: self._stored_solver = claripy.SolverVSA() elif o.REPLACEMENT_SOLVER in self.state.options: self._stored_solver = claripy.SolverReplacement(auto_replace=False) elif o.CACHELESS_SOLVER in self.state.options: self._stored_solver = claripy.SolverCacheless() elif o.COMPOSITE_SOLVER in self.state.options: self._stored_solver = claripy.SolverComposite() elif o.SYMBOLIC in self.state.options and o.approximation & self.state.options: self._stored_solver = claripy.SolverHybrid() elif o.SYMBOLIC in self.state.options: self._stored_solver = claripy.Solver() else: self._stored_solver = claripy.SolverConcrete() return self._stored_solver
def test_reverse(): x = claripy.SI(name="TOP", bits=64, lower_bound=0, upper_bound=0xffffffffffffffff, stride=1) # TOP y = claripy.SI(name="range", bits=64, lower_bound=0, upper_bound=1337, stride=1) # [0, 1337] r0 = x.intersection(y) r1 = x.reversed.intersection(y) r2 = x.intersection(y.reversed).reversed r3 = x.reversed.intersection(y.reversed).reversed nose.tools.assert_equal(r0._model_vsa.max, 1337) nose.tools.assert_equal(r1._model_vsa.max, 1337) nose.tools.assert_equal(r2._model_vsa.max, 1337) nose.tools.assert_equal(r3._model_vsa.max, 1337) # See claripy issue #95 for details. si0 = StridedInterval(name='a', bits=32, stride=0, lower_bound=0xffff0000, upper_bound=0xffff0000) si1 = StridedInterval(name='a', bits=32, stride=0, lower_bound=0xffff0001, upper_bound=0xffff0001) dsis = DiscreteStridedIntervalSet(name='b', bits=32, si_set={si0, si1}) dsis_r = dsis.reverse() solver = claripy.SolverVSA() nose.tools.assert_equal(set(solver.eval(dsis_r, 3)), {0xffff, 0x100ffff})
def test_vsa_discrete_value_set(): """ Test cases for DiscreteStridedIntervalSet. """ # Set backend b = claripy.backends.vsa s = claripy.SolverVSA() #pylint:disable=unused-variable SI = claripy.SI BVV = claripy.BVV # Allow the use of DiscreteStridedIntervalSet (cuz we wanna test it!) claripy.vsa.strided_interval.allow_dsis = True # # Union # val_1 = BVV(0, 32) val_2 = BVV(1, 32) r = val_1.union(val_2) nose.tools.assert_true(isinstance(vsa_model(r), DiscreteStridedIntervalSet)) nose.tools.assert_true(vsa_model(r).collapse(), claripy.SI(bits=32, stride=1, lower_bound=0, upper_bound=1)) r = r.union(BVV(3, 32)) ints = b.eval(r, 4) nose.tools.assert_equal(len(ints), 3) nose.tools.assert_equal(ints, [0, 1, 3]) # # Intersection # val_1 = BVV(0, 32) val_2 = BVV(1, 32) r = val_1.intersection(val_2) nose.tools.assert_true(isinstance(vsa_model(r), StridedInterval)) nose.tools.assert_true(vsa_model(r).is_empty) val_1 = claripy.SI(bits=32, stride=1, lower_bound=0, upper_bound=10) val_2 = claripy.SI(bits=32, stride=1, lower_bound=10, upper_bound=20) val_3 = claripy.SI(bits=32, stride=1, lower_bound=15, upper_bound=50) r = val_1.union(val_2) nose.tools.assert_true(isinstance(vsa_model(r), DiscreteStridedIntervalSet)) r = r.intersection(val_3) nose.tools.assert_equal(sorted(b.eval(r, 100)), [ 15, 16, 17, 18, 19, 20 ]) # # Some logical operations # val_1 = claripy.SI(bits=32, stride=1, lower_bound=0, upper_bound=10) val_2 = claripy.SI(bits=32, stride=1, lower_bound=5, upper_bound=20) r_1 = val_1.union(val_2) val_3 = claripy.SI(bits=32, stride=1, lower_bound=20, upper_bound=30) val_4 = claripy.SI(bits=32, stride=1, lower_bound=25, upper_bound=35) r_2 = val_3.union(val_4) nose.tools.assert_true(isinstance(vsa_model(r_1), DiscreteStridedIntervalSet)) nose.tools.assert_true(isinstance(vsa_model(r_2), DiscreteStridedIntervalSet)) # r_1 < r_2 nose.tools.assert_true(BoolResult.is_maybe(vsa_model(r_1 < r_2))) # r_1 <= r_2 nose.tools.assert_true(BoolResult.is_true(vsa_model(r_1 <= r_2))) # r_1 >= r_2 nose.tools.assert_true(BoolResult.is_maybe(vsa_model(r_1 >= r_2))) # r_1 > r_2 nose.tools.assert_true(BoolResult.is_false(vsa_model(r_1 > r_2))) # r_1 == r_2 nose.tools.assert_true(BoolResult.is_maybe(vsa_model(r_1 == r_2))) # r_1 != r_2 nose.tools.assert_true(BoolResult.is_maybe(vsa_model(r_1 != r_2))) # # Some arithmetic operations # val_1 = claripy.SI(bits=32, stride=1, lower_bound=0, upper_bound=10) val_2 = claripy.SI(bits=32, stride=1, lower_bound=5, upper_bound=20) r_1 = val_1.union(val_2) val_3 = claripy.SI(bits=32, stride=1, lower_bound=20, upper_bound=30) val_4 = claripy.SI(bits=32, stride=1, lower_bound=25, upper_bound=35) r_2 = val_3.union(val_4) nose.tools.assert_true(isinstance(vsa_model(r_1), DiscreteStridedIntervalSet)) nose.tools.assert_true(isinstance(vsa_model(r_2), DiscreteStridedIntervalSet)) # r_1 + r_2 r = r_1 + r_2 nose.tools.assert_true(isinstance(vsa_model(r), DiscreteStridedIntervalSet)) nose.tools.assert_true(vsa_model(r).collapse().identical(vsa_model(SI(bits=32, stride=1, lower_bound=20, upper_bound=55)))) # r_2 - r_1 r = r_2 - r_1 nose.tools.assert_true(isinstance(vsa_model(r), DiscreteStridedIntervalSet)) nose.tools.assert_true(vsa_model(r).collapse().identical(vsa_model(SI(bits=32, stride=1, lower_bound=0, upper_bound=35)))) # Disable it in the end claripy.vsa.strided_interval.allow_dsis = False
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) ) )