def test_arithmetic_simplify(self): cs = ConstraintSet() arr = cs.new_array(name="MEM") a = cs.new_bitvec(32, name="VARA") b = cs.new_bitvec(32, name="VARB") c = a * 2 + b self.assertEqual(translate_to_smtlib(c), "(bvadd (bvmul VARA #x00000002) VARB)") self.assertEqual( translate_to_smtlib((c + 4) - 4), "(bvsub (bvadd (bvadd (bvmul VARA #x00000002) VARB) #x00000004) #x00000004)", ) d = c + 4 s = arithmetic_simplify(d - c) self.assertIsInstance(s, Constant) self.assertEqual(s.value, 4) # size = arithmetic_simplify(size cs2 = ConstraintSet() exp = cs2.new_bitvec(32) exp |= 0 exp &= 1 exp |= 0 self.assertEqual(get_depth(exp), 4) self.assertEqual( translate_to_smtlib(exp), "(bvor (bvand (bvor BIVEC #x00000000) #x00000001) #x00000000)" ) exp = arithmetic_simplify(exp) self.assertTrue(get_depth(exp) < 4) self.assertEqual(translate_to_smtlib(exp), "(bvand BIVEC #x00000001)")
def test_visitors(self): solver = Z3Solver.instance() cs = ConstraintSet() arr = cs.new_array(name="MEM") a = cs.new_bitvec(32, name="VAR") self.assertEqual(get_depth(a), 1) cond = Operators.AND(a < 200, a > 100) arr[0] = ord("a") arr[1] = ord("b") self.assertEqual(get_depth(cond), 3) self.assertEqual(get_depth(arr[a + 1]), 4) self.assertEqual( translate_to_smtlib(arr[a + 1]), "(select (store (store MEM #x00000000 #x61) #x00000001 #x62) (bvadd VAR #x00000001))", ) arr[3] = arr[a + 1] aux = arr[a + Operators.ZEXTEND(arr[a], 32)] self.assertEqual(get_depth(aux), 9) self.maxDiff = 1500 self.assertEqual( translate_to_smtlib(aux), "(select (store (store (store MEM #x00000000 #x61) #x00000001 #x62) #x00000003 (select (store (store MEM #x00000000 #x61) #x00000001 #x62) (bvadd VAR #x00000001))) (bvadd VAR ((_ zero_extend 24) (select (store (store (store MEM #x00000000 #x61) #x00000001 #x62) #x00000003 (select (store (store MEM #x00000000 #x61) #x00000001 #x62) (bvadd VAR #x00000001))) VAR))))", ) values = arr[0:2] self.assertEqual(len(values), 2) self.assertItemsEqual(solver.get_all_values(cs, values[0]), [ord("a")]) self.assertItemsEqual(solver.get_all_values(cs, values[1]), [ord("b")]) arr[1:3] = "cd" values = arr[0:3] self.assertEqual(len(values), 3) self.assertItemsEqual(solver.get_all_values(cs, values[0]), [ord("a")]) self.assertItemsEqual(solver.get_all_values(cs, values[1]), [ord("c")]) self.assertItemsEqual(solver.get_all_values(cs, values[2]), [ord("d")]) self.assertEqual( pretty_print(aux, depth=2), "ArraySelect\n ArrayStore\n ...\n BitVecAdd\n ...\n") self.assertEqual(pretty_print(Operators.EXTRACT(a, 0, 8), depth=1), "BitVecExtract{0:7}\n ...\n") self.assertEqual(pretty_print(a, depth=2), "VAR\n") x = BitVecConstant(32, 100, taint=("important", )) y = BitVecConstant(32, 200, taint=("stuff", )) z = constant_folder(x + y) self.assertItemsEqual(z.taint, ("important", "stuff")) self.assertEqual(z.value, 300) self.assertRaises(Exception, translate_to_smtlib, 1) self.assertEqual( translate_to_smtlib(simplify(Operators.ZEXTEND(a, 32))), "VAR") self.assertEqual( translate_to_smtlib( simplify(Operators.EXTRACT(Operators.EXTRACT(a, 0, 8), 0, 8))), "((_ extract 7 0) VAR)", )
def test_arithmetic_simplify_udiv(self): cs = ConstraintSet() a = cs.new_bitvec(32, name="VARA") b = a + Operators.UDIV(BitVecConstant(size=32, value=0), BitVecConstant(size=32, value=2)) self.assertEqual(translate_to_smtlib(b), "(bvadd VARA (bvudiv #x00000000 #x00000002))") self.assertEqual(translate_to_smtlib(simplify(b)), "VARA") c = a + Operators.UDIV(BitVecConstant(size=32, value=2), BitVecConstant(size=32, value=2)) self.assertEqual(translate_to_smtlib(c), "(bvadd VARA (bvudiv #x00000002 #x00000002))") self.assertEqual(translate_to_smtlib(simplify(c)), "(bvadd VARA #x00000001)")
def testBasicArraySlice(self): hw = bytearray(b"Hello world!") cs = ConstraintSet() # make array of 32->8 bits array = cs.new_array(32, index_max=12) array = array.write(0, hw) array_slice = array[0:2] self.assertTrue(self.solver.must_be_true(cs, array == hw)) self.assertTrue( self.solver.must_be_true(cs, array_slice[0] == array[0])) self.assertTrue( self.solver.must_be_true(cs, array_slice[0:2][1] == array[1])) array_slice[0] = ord("A") self.assertTrue( self.solver.must_be_true(cs, array_slice[0] == ord("A"))) self.assertTrue( self.solver.must_be_true(cs, array_slice[0:2][1] == array[1])) self.assertTrue(self.solver.must_be_true(cs, array == hw)) # Testing some slicing combinations self.assertRaises( IndexError, lambda i: translate_to_smtlib(array_slice[0:1000][i]), 1002) self.assertTrue( self.solver.must_be_true(cs, array_slice[0:1000][0] == ord("A"))) self.assertTrue( self.solver.must_be_true(cs, array_slice[0:1000][1] == array[1])) self.assertTrue( self.solver.must_be_true( cs, array_slice[0:1000][:2][1] == array[:2][1])) self.assertTrue( self.solver.must_be_true(cs, array_slice[0:1000][:2][0] == ord("A")))
def testBasicReplace(self): """ Add """ a = BitVecConstant(size=32, value=100) b1 = BitVecVariable(size=32, name="VAR1") b2 = BitVecVariable(size=32, name="VAR2") c = a + b1 x = replace(c, {b1: b2}) self.assertEqual(translate_to_smtlib(x), "(bvadd #x00000064 VAR2)")
def testBasicReplace(self): ''' Add ''' a = BitVecConstant(32, 100) b1 = BitVecVariable(32, 'VAR1') b2 = BitVecVariable(32, 'VAR2') c = a + b1 x = replace(c, {b1: b2}) self.assertEqual(translate_to_smtlib(x), '(bvadd #x00000064 VAR2)')
def test_related_to(self): import gzip import pickle, sys filename = os.path.abspath( os.path.join(DIRPATH, "data", "ErrRelated.pkl.gz")) # A constraint set and a contraint caught in the act of making related_to fail constraints, constraint = pickle.loads( gzip.open(filename, "rb").read()) Z3Solver.instance().can_be_true.cache_clear() ground_truth = Z3Solver.instance().can_be_true(constraints, constraint) self.assertEqual(ground_truth, False) Z3Solver.instance().can_be_true.cache_clear() self.assertEqual( ground_truth, Z3Solver.instance().can_be_true( constraints.related_to(constraints), constraint), ) # Replace new_constraint = Operators.UGE( Operators.SEXTEND(BitVecConstant(256, 0x1A), 256, 512) * BitVecConstant(512, 1), 0x00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000, ) self.assertEqual(translate_to_smtlib(constraint), translate_to_smtlib(new_constraint)) Z3Solver.instance().can_be_true.cache_clear() self.assertEqual( ground_truth, Z3Solver.instance().can_be_true(constraints, new_constraint)) Z3Solver.instance().can_be_true.cache_clear() self.assertEqual( ground_truth, Z3Solver.instance().can_be_true( constraints.related_to(new_constraint), new_constraint), )
def test_arithmetic_simplify_extract(self): cs = ConstraintSet() arr = cs.new_array(name='MEM') a = cs.new_bitvec(32, name='VARA') b = Operators.CONCAT(32, Operators.EXTRACT(a, 24, 8), Operators.EXTRACT(a, 16, 8), Operators.EXTRACT(a, 8, 8), Operators.EXTRACT(a, 0, 8)) self.assertEqual( translate_to_smtlib(b), '(concat ((_ extract 31 24) VARA) ((_ extract 23 16) VARA) ((_ extract 15 8) VARA) ((_ extract 7 0) VARA))' ) self.assertEqual(translate_to_smtlib(simplify(b)), 'VARA') c = Operators.CONCAT(16, Operators.EXTRACT(a, 16, 8), Operators.EXTRACT(a, 8, 8)) self.assertEqual( translate_to_smtlib(c), '(concat ((_ extract 23 16) VARA) ((_ extract 15 8) VARA))') self.assertEqual(translate_to_smtlib(simplify(c)), '((_ extract 23 8) VARA)')