Beispiel #1
0
    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)",
        )
Beispiel #2
0
    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)
Beispiel #3
0
    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"))
Beispiel #4
0
    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))
Beispiel #6
0
    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)
Beispiel #7
0
    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)
Beispiel #8
0
    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))
Beispiel #9
0
    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)
Beispiel #10
0
    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)
Beispiel #11
0
    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)
Beispiel #12
0
    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)
Beispiel #13
0
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
Beispiel #14
0
    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)))
Beispiel #15
0
    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)
Beispiel #17
0
def constraints_are_sat(cons):
    "Whether constraints are sat"
    return Z3Solver.instance().check(constraints_to_constraintset(cons))
Beispiel #18
0
 def setUp(self):
     self.solver = Z3Solver.instance()
Beispiel #19
0
    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),
        )
Beispiel #20
0
    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))