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_CHR(self): solver = Z3Solver.instance() cs = ConstraintSet() a = cs.new_bitvec(8) cs.add(Operators.CHR(a) == Operators.CHR(0x41)) self.assertTrue(solver.check(cs)) self.assertEqual(solver.get_value(cs, a), 0x41)
def test_ORD_proper_extract(self): solver = Z3Solver.instance() cs = ConstraintSet() a = cs.new_bitvec(32) cs.add(Operators.ORD(a) == Operators.ORD("\xff")) self.assertTrue(solver.check(cs)) self.assertEqual(solver.get_value(cs, a), ord("\xff"))
def test_NOT(self): solver = Z3Solver.instance() cs = ConstraintSet() a = cs.new_bitvec(8) b = cs.new_bitvec(8) cs.add(a == 0x1) # 1 cs.add(b == 0x86) # -122 self.assertTrue(solver.must_be_true(cs, Operators.NOT(False))) self.assertTrue(solver.must_be_true(cs, Operators.NOT(a == b)))
def test_CONCAT(self): solver = Z3Solver.instance() cs = ConstraintSet() a = cs.new_bitvec(16) b = cs.new_bitvec(8) c = cs.new_bitvec(8) cs.add(b == 0x41) cs.add(c == 0x42) cs.add(a == Operators.CONCAT(a.size, b, c)) self.assertTrue(solver.check(cs)) self.assertEqual(solver.get_value(cs, a), Operators.CONCAT(a.size, 0x41, 0x42))
def test_ITEBV_2(self): solver = Z3Solver.instance() cs = ConstraintSet() a = cs.new_bitvec(8) b = cs.new_bitvec(8) c = cs.new_bitvec(8) cs.add(b == 0x44) cs.add(c == 0x44) cs.add(a == Operators.ITEBV(8, b == c, b, c)) self.assertTrue(solver.check(cs)) self.assertEqual(solver.get_value(cs, a), 0x44)
def test_ITE(self): solver = Z3Solver.instance() cs = ConstraintSet() a = cs.new_bool() b = cs.new_bool() c = cs.new_bool() cs.add(b == True) cs.add(c == False) cs.add(a == Operators.ITE(b == c, b, c)) self.assertTrue(solver.check(cs)) self.assertEqual(solver.get_value(cs, a), False)
def test_SAR(self): solver = Z3Solver.instance() A = 0xBADF00D for B in range(32): cs = ConstraintSet() a = cs.new_bitvec(32) b = cs.new_bitvec(32) c = cs.new_bitvec(32) cs.add(c == Operators.SAR(32, a, b)) cs.add(a == A) cs.add(b == B) self.assertTrue(solver.check(cs)) self.assertEqual(solver.get_value(cs, c), Operators.SAR(32, A, B))
def test_armv7_syscall_openat_symbolic(self): platform, temp_dir = self._armv7_create_openat_state() try: platform.current.R0 = BitVecVariable(32, 'fd') with self.assertRaises(ConcretizeRegister) as cm: platform.syscall() e = cm.exception _min, _max = Z3Solver.instance().minmax(platform.constraints, e.cpu.read_register(e.reg_name)) self.assertLess(_min, len(platform.files)) self.assertGreater(_max, len(platform.files) - 1) finally: shutil.rmtree(temp_dir)
def test_SDIV(self): solver = Z3Solver.instance() cs = ConstraintSet() a = cs.new_bitvec(8) b = cs.new_bitvec(8) c = cs.new_bitvec(8) d = cs.new_bitvec(8) cs.add(b == 0x86) # -122 cs.add(c == 0x11) # 17 cs.add(a == Operators.SDIV(b, c)) cs.add(d == (b // c)) cs.add(a == d) self.assertTrue(solver.check(cs)) self.assertEqual(solver.get_value(cs, a), -7 & 0xFF)
def test_armv7_syscall_openat_symbolic(self) -> None: platform, temp_dir = self._armv7_create_openat_state() try: platform.current.R0 = platform.constraints.new_bitvec(32, "fd") with self.assertRaises(ConcretizeRegister) as cm: platform.syscall() e = cm.exception _min, _max = Z3Solver.instance().minmax( platform.constraints, e.cpu.read_register(e.reg_name)) self.assertLess(_min, len(platform.fd_table.entries())) self.assertGreater(_max, len(platform.fd_table.entries()) - 1) finally: shutil.rmtree(temp_dir)
def test_UDIV(self): solver = Z3Solver.instance() cs = ConstraintSet() a = cs.new_bitvec(8) b = cs.new_bitvec(8) c = cs.new_bitvec(8) d = cs.new_bitvec(8) cs.add(b == 0x86) # 134 cs.add(c == 0x11) # 17 cs.add(a == Operators.UDIV(b, c)) cs.add(d == b.udiv(c)) cs.add(a == d) self.assertTrue(solver.check(cs)) self.assertEqual(solver.get_value(cs, a), 7)
def input_from_cons(constupl, datas): " solve bytes in |datas| based on " def make_chr(c): try: return chr(c) except Exception: return c newset = constraints_to_constraintset(constupl) ret = "" for data in datas: for c in data: ret += make_chr(Z3Solver.instance().get_value(newset, c)) return ret
def test_ULE(self): solver = Z3Solver.instance() cs = ConstraintSet() a = cs.new_bitvec(8) b = cs.new_bitvec(8) c = cs.new_bitvec(8) cs.add(a == 0x1) # 1 cs.add(b == 0x86) # -122 cs.add(c == 0x11) # 17 self.assertTrue(solver.must_be_true(cs, Operators.ULE(a, b))) self.assertTrue(solver.must_be_true(cs, Operators.ULE(a, c))) self.assertTrue(solver.must_be_true(cs, Operators.ULE(c, b))) self.assertTrue(solver.must_be_true(cs, Operators.ULE(a, 0xF2))) self.assertTrue(solver.must_be_true(cs, Operators.ULE(b, 0x99))) self.assertTrue(solver.must_be_true(cs, Operators.ULE(c, 0x12))) self.assertTrue(solver.must_be_true(cs, Operators.ULE(3, 0xF2))) self.assertTrue(solver.must_be_true(cs, Operators.ULE(3, 3))) self.assertTrue(solver.must_be_true(cs, Operators.ULE(1, a))) self.assertTrue(solver.must_be_true(cs, Operators.ULE(0x85, b))) self.assertTrue(solver.must_be_true(cs, Operators.ULE(0x10, c)))
def testBasicMigration(self): solver = Z3Solver.instance() cs1 = ConstraintSet() cs2 = ConstraintSet() var1 = cs1.new_bitvec(32, "var") var2 = cs2.new_bitvec(32, "var") cs1.add(Operators.ULT(var1, 3)) # var1 can be 0, 1, 2 # make a migration map dict migration_map1 = {} # this expression is composed with variables of both cs expression = var1 > var2 migrated_expression = cs1.migrate(expression, migration_map1) cs1.add(migrated_expression) expression = var2 > 0 migrated_expression = cs1.migrate(expression, migration_map1) cs1.add(migrated_expression) self.assertItemsEqual(solver.get_all_values(cs1, var1), [2]) # should only be [2]
""" Race condition on Reserve buy and sell allows one to steal ethers """ import sys from collections import namedtuple from manticore.ethereum import ManticoreEVM from manticore.utils import config from manticore.ethereum.abi import ABI #from manticore.core.smtlib import solver from manticore.core.smtlib.solver import Z3Solver solver = Z3Solver.instance() from initialize_market import initialize from constants import ONE_ETH consts = config.get_group("evm") consts.oog = "ignore" Account = namedtuple('Account', ['name', 'account', 'initial_supply']) ################ Helpers ####################### def init_user(m, market, name, initial_balance): user_account = m.create_account(balance=initial_balance) print(f"[+] Creating a {name} account {hex(user_account.address)}") market.ether_token_contract.deposit(value=initial_balance, caller=user_account)
def constraints_are_sat(cons): "Whether constraints are sat" return Z3Solver.instance().check(constraints_to_constraintset(cons))
def setUp(self): self.solver = Z3Solver.instance()
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_ConstraintsForking(self): solver = Z3Solver.instance() import pickle cs = ConstraintSet() # make free 32bit bitvectors x = cs.new_bitvec(8) y = cs.new_bitvec(8) # linear relation # cs.add(x+y*5 == 0) # Fork and divide in quadrants saved_up = None saved_up_right = None saved_up_left = None saved_down = None saved_down_right = None saved_down_left = None with cs as cs_up: cs_up.add(y.uge(0x80)) self.assertItemsEqual(solver.get_all_values(cs_up, x), range(0x0, 0x100)) self.assertItemsEqual(solver.get_all_values(cs_up, y), range(0x80, 0x100)) saved_up = pickle_dumps((x, y, cs_up)) self.assertItemsEqual(solver.get_all_values(cs_up, x), range(0x0, 0x100)) self.assertItemsEqual(solver.get_all_values(cs_up, y), range(0x80, 0x100)) with cs_up as cs_up_right: cs_up_right.add(x.uge(0x80)) saved_up_right = pickle_dumps((x, y, cs_up_right)) self.assertItemsEqual(solver.get_all_values(cs_up_right, x), range(0x80, 0x100)) self.assertItemsEqual(solver.get_all_values(cs_up_right, y), range(0x80, 0x100)) self.assertItemsEqual(solver.get_all_values(cs_up, x), range(0x0, 0x100)) self.assertItemsEqual(solver.get_all_values(cs_up, y), range(0x80, 0x100)) with cs_up as cs_up_left: cs_up_left.add(x.ult(0x80)) saved_up_left = pickle_dumps((x, y, cs_up_left)) self.assertItemsEqual(solver.get_all_values(cs_up_left, x), range(0, 0x80)) self.assertItemsEqual(solver.get_all_values(cs_up_left, y), range(0x80, 0x100)) self.assertItemsEqual(solver.get_all_values(cs_up, x), range(0x0, 0x100)) self.assertItemsEqual(solver.get_all_values(cs_up, y), range(0x80, 0x100)) with cs as cs_down: cs_down.add(y.ult(0x80)) self.assertItemsEqual(solver.get_all_values(cs_down, x), range(0x0, 0x100)) self.assertItemsEqual(solver.get_all_values(cs_down, y), range(0, 0x80)) saved_down = pickle_dumps((x, y, cs_down)) self.assertItemsEqual(solver.get_all_values(cs_down, x), range(0x0, 0x100)) self.assertItemsEqual(solver.get_all_values(cs_down, y), range(0, 0x80)) with cs_down as cs_down_right: cs_down_right.add(x.uge(0x80)) saved_down_right = pickle_dumps((x, y, cs_down_right)) self.assertItemsEqual(solver.get_all_values(cs_down_right, x), range(0x80, 0x100)) self.assertItemsEqual(solver.get_all_values(cs_down_right, y), range(0, 0x80)) self.assertItemsEqual(solver.get_all_values(cs_down, x), range(0x0, 0x100)) self.assertItemsEqual(solver.get_all_values(cs_down, y), range(0, 0x80)) with cs_down as cs_down_left: cs_down_left.add(x.ult(0x80)) saved_down_left = pickle_dumps((x, y, cs_down_left)) self.assertItemsEqual(solver.get_all_values(cs_down_left, x), range(0, 0x80)) self.assertItemsEqual(solver.get_all_values(cs_down_left, y), range(0, 0x80)) self.assertItemsEqual(solver.get_all_values(cs_down, x), range(0x0, 0x100)) self.assertItemsEqual(solver.get_all_values(cs_down, y), range(0, 0x80)) x, y, cs_up = pickle.loads(saved_up) self.assertItemsEqual(solver.get_all_values(cs_up, x), range(0x0, 0x100)) self.assertItemsEqual(solver.get_all_values(cs_up, y), range(0x80, 0x100)) x, y, cs_up_right = pickle.loads(saved_up_right) self.assertItemsEqual(solver.get_all_values(cs_up_right, x), range(0x80, 0x100)) self.assertItemsEqual(solver.get_all_values(cs_up_right, y), range(0x80, 0x100)) x, y, cs_up_left = pickle.loads(saved_up_left) self.assertItemsEqual(solver.get_all_values(cs_up_left, x), range(0x00, 0x80)) self.assertItemsEqual(solver.get_all_values(cs_up_left, y), range(0x80, 0x100)) x, y, cs_down = pickle.loads(saved_down) self.assertItemsEqual(solver.get_all_values(cs_down, x), range(0x0, 0x100)) self.assertItemsEqual(solver.get_all_values(cs_down, y), range(0x0, 0x80)) x, y, cs_down_right = pickle.loads(saved_down_right) self.assertItemsEqual(solver.get_all_values(cs_down_right, x), range(0x80, 0x100)) self.assertItemsEqual(solver.get_all_values(cs_down_right, y), range(0x00, 0x80)) x, y, cs_down_left = pickle.loads(saved_down_left) self.assertItemsEqual(solver.get_all_values(cs_down_left, x), range(0x00, 0x80)) self.assertItemsEqual(solver.get_all_values(cs_down_left, y), range(0x00, 0x80))