Esempio n. 1
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)
Esempio n. 2
0
    def test_mulmod(self):
        """
        (declare-fun BV () (_ BitVec 256))
        (declare-fun BV_2 () (_ BitVec 256))
        (declare-fun BV_1 () (_ BitVec 256))
        (declare-fun a_1 () (_ BitVec 256))(assert (= a_1 (bvmul BV BV_1)))
        (declare-fun a_2 () (_ BitVec 512))(assert (= a_2 ((_ zero_extend 256) BV)))
        (declare-fun a_3 () (_ BitVec 512))(assert (= a_3 ((_ zero_extend 256) BV_1)))
        (declare-fun a_4 () (_ BitVec 512))(assert (= a_4 (bvmul a_2 a_3)))
        (declare-fun a_5 () (_ BitVec 512))(assert (= a_5 ((_ zero_extend 256) BV_2)))
        (declare-fun a_6 () (_ BitVec 512))(assert (= a_6 (bvsmod a_4 a_5)))
        (declare-fun a_7 () (_ BitVec 256))(assert (= a_7 ((_ extract 255 0) a_6)))
        (declare-fun a_8 () (_ BitVec 256))(assert (= a_8 (bvsmod a_1 BV_2)))
        (declare-fun a_9 () Bool)(assert (= a_9 (= a_7 a_8)))
        (assert (not a_9))

        (check-sat)
        """
        from manticore.platforms import evm
        from manticore.core.smtlib import ConstraintSet, Z3Solver, Operators

        constraints = ConstraintSet()

        address = 0x41414141414141414141
        data = b""
        caller = 0x42424242424242424242
        value = 0
        bytecode = ""
        vm = evm.EVM(constraints, address, data, caller, value, bytecode)

        self.assertEqual(vm.MULMOD(12323, 2343, 20), 9)
        self.assertEqual(vm.MULMOD(12323, 2343, 0), 0)

        A, B, C = (
            110427941548649020598956093796432407239217743554726184882600387580788736,
            1048576,
            4194319,
        )
        self.assertEqual(vm.MULMOD(A, B, C), 2423129)
        a, b, c = (
            constraints.new_bitvec(256),
            constraints.new_bitvec(256),
            constraints.new_bitvec(256),
        )
        constraints.add(a == A)
        constraints.add(b == B)
        constraints.add(c == C)
        result = vm.MULMOD(a, b, c)
        # 0x8000000000000000000000000000000000000000000000000000000082000011
        self.assertEqual(
            Z3Solver.instance().get_all_values(constraints, result), [2423129])
Esempio n. 3
0
    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))
Esempio n. 4
0
    def testBasicArraySymbIdx(self):
        cs = ConstraintSet()
        array = cs.new_array(index_bits=32, value_bits=32, name="array")
        key = cs.new_bitvec(32, name="key")
        index = cs.new_bitvec(32, name="index")

        array[key] = 1  # Write 1 to a single location

        cs.add(array.get(index, default=0) !=
               0)  # Constrain index so it selects that location

        cs.add(index != key)
        # key and index are the same there is only one slot in 1
        self.assertFalse(self.solver.check(cs))
Esempio n. 5
0
    def test_SAR(self):
        solver = self.solver
        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))
Esempio n. 6
0
    def testBasicPickle(self):
        import pickle
        cs = ConstraintSet()

        #make array of 32->8 bits
        array = cs.new_array(32)
        #make free 32bit bitvector
        key = cs.new_bitvec(32)

        #assert that the array is 'A' at key position
        array = array.store(key, ord('A'))
        #let's restrict key to be greater than 1000
        cs.add(key.ugt(1000))
        cs = pickle.loads(pickle.dumps(cs))
        self.assertTrue(self.solver.check(cs))
Esempio n. 7
0
    def test_signed_unsigned_LT_complex(self):
        mask = (1 << 32) - 1

        cs = ConstraintSet()
        _a = cs.new_bitvec(32)
        _b = cs.new_bitvec(32)

        cs.add(_a == 0x1)
        cs.add(_b == (0x80000000 - 1))

        a = _a & mask
        b = (_b + 1) & mask

        lt = b < a
        ult = b.ult(a)

        self.assertFalse(self.solver.can_be_true(cs, ult))
        self.assertTrue(self.solver.must_be_true(cs, lt))
Esempio n. 8
0
    def testBitvector_max(self):
        cs = ConstraintSet()
        a = cs.new_bitvec(32)
        cs.add(a <= 200)
        cs.add(a >= 100)
        self.assertTrue(self.solver.check(cs))
        self.assertEqual(self.solver.minmax(cs, a), (100, 200))
        from manticore import config

        consts = config.get_group("smt")
        consts.optimize = False
        cs = ConstraintSet()
        a = cs.new_bitvec(32)
        cs.add(a <= 200)
        cs.add(a >= 100)
        self.assertTrue(self.solver.check(cs))
        self.assertEqual(self.solver.minmax(cs, a), (100, 200))
        consts.optimize = True
Esempio n. 9
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)))
Esempio n. 10
0
    def test_ULT(self):
        solver = self.solver
        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.ULT(a, b)))
        self.assertTrue(solver.must_be_true(cs, Operators.ULT(a, c)))
        self.assertTrue(solver.must_be_true(cs, Operators.ULT(c, b)))
        self.assertTrue(solver.must_be_true(cs, Operators.ULT(a, 0xF2)))
        self.assertTrue(solver.must_be_true(cs, Operators.ULT(b, 0x99)))
        self.assertTrue(solver.must_be_true(cs, Operators.ULT(c, 0x12)))
        self.assertTrue(solver.must_be_true(cs, Operators.ULT(3, 0xF2)))
        self.assertTrue(solver.must_be_true(cs, Operators.ULT(3, 4)))
        self.assertTrue(solver.must_be_true(cs, Operators.ULT(0, a)))
        self.assertTrue(solver.must_be_true(cs, Operators.ULT(0x85, b)))
        self.assertTrue(solver.must_be_true(cs, Operators.ULT(0x10, c)))
Esempio n. 11
0
    def testBasicArrayStore(self):
        name = "bitarray"
        cs = ConstraintSet()
        # make array of 32->8 bits
        array = cs.new_array(32, name=name)
        # make free 32bit bitvector
        key = cs.new_bitvec(32)

        # assert that the array is 'A' at key position
        array = array.store(key, ord("A"))
        # let's restrict key to be greater than 1000
        cs.add(key.ugt(1000))

        # 1001 position of array can be 'A'
        self.assertTrue(
            self.solver.can_be_true(cs,
                                    array.select(1001) == ord("A")))

        # 1001 position of array can be 'B'
        self.assertTrue(
            self.solver.can_be_true(cs,
                                    array.select(1001) == ord("B")))

        # name is correctly proxied
        self.assertEqual(array.name, name)

        with cs as temp_cs:
            # but if it is 'B' ...
            temp_cs.add(array.select(1001) == ord("B"))
            # then key can not be 1001
            temp_cs.add(key == 1001)
            self.assertFalse(self.solver.check(temp_cs))

        with cs as temp_cs:
            # If 1001 position is 'B' ...
            temp_cs.add(array.select(1001) == ord("B"))
            # then key can be 1002 for ex..
            temp_cs.add(key != 1002)
            self.assertTrue(self.solver.check(temp_cs))
Esempio n. 12
0
    def testBasicArray256(self):
        cs = ConstraintSet()
        # make array of 32->8 bits
        array = cs.new_array(32, value_bits=256)
        # make free 32bit bitvector
        key = cs.new_bitvec(32)

        # assert that the array is 111...111 at key position
        cs.add(array[key] == 11111111111111111111111111111111111111111111)
        # let's restrict key to be greater than 1000
        cs.add(key.ugt(1000))

        with cs as temp_cs:
            # 1001 position of array can be 111...111
            temp_cs.add(
                array[1001] == 11111111111111111111111111111111111111111111)
            self.assertTrue(self.solver.check(temp_cs))

        with cs as temp_cs:
            # 1001 position of array can also be 222...222
            temp_cs.add(
                array[1001] == 22222222222222222222222222222222222222222222)
            self.assertTrue(self.solver.check(temp_cs))

        with cs as temp_cs:
            # but if it is 222...222 ...
            temp_cs.add(
                array[1001] == 22222222222222222222222222222222222222222222)
            # then key can not be 1001
            temp_cs.add(key == 1001)
            self.assertFalse(self.solver.check(temp_cs))

        with cs as temp_cs:
            # If 1001 position is 222...222 ...
            temp_cs.add(
                array[1001] == 22222222222222222222222222222222222222222222)
            # then key can be 1002 for ex..
            temp_cs.add(key == 1002)
            self.assertTrue(self.solver.check(temp_cs))
Esempio n. 13
0
    def test_UDIV(self):
        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)
Esempio n. 14
0
    def test_SREM(self):
        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.SREM(b, c))
        cs.add(d == b.srem(c))
        cs.add(a == d)

        self.assertTrue(solver.check(cs))
        self.assertEqual(solver.get_value(cs, a), -3 & 0xFF)
Esempio n. 15
0
    def test_SDIV(self):
        solver = self.solver
        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)
Esempio n. 16
0
    def test_UREM(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.UREM(b, c))
        cs.add(d == b.urem(c))
        cs.add(a == d)

        self.assertTrue(solver.check(cs))
        self.assertEqual(solver.get_value(cs, a), 0xF)
Esempio n. 17
0
    def testBasicArray(self):
        cs = ConstraintSet()
        # make array of 32->8 bits
        array = cs.new_array(32)
        # make free 32bit bitvector
        key = cs.new_bitvec(32)

        # assert that the array is 'A' at key position
        # By default an smtlib can contain any value
        cs.add(array[key] == ord("A"))

        # let's restrict key to be greater than 1000
        cs.add(key.ugt(1000))
        with cs as temp_cs:
            # 1001 position of array can be 'A'
            temp_cs.add(array[1001] == ord("A"))
            self.assertTrue(self.solver.check(temp_cs))

        with cs as temp_cs:
            # 1001 position of array can also be 'B'
            temp_cs.add(array[1001] == ord("B"))
            self.assertTrue(self.solver.check(temp_cs))

        with cs as temp_cs:
            # but if it is 'B' ...
            temp_cs.add(array[1001] == ord("B"))
            # then key can not be 1001
            temp_cs.add(key == 1001)
            self.assertFalse(self.solver.check(temp_cs))

        with cs as temp_cs:
            # If 1001 position is 'B' ...
            temp_cs.add(array[1001] == ord("B"))
            # then key can be 1000 for ex..
            temp_cs.add(key == 1002)
            self.assertTrue(self.solver.check(temp_cs))
Esempio n. 18
0
 def testBitvector_add(self):
     cs = ConstraintSet()
     a = cs.new_bitvec(32)
     b = cs.new_bitvec(32)
     c = cs.new_bitvec(32)
     cs.add(c == a + b)
     cs.add(a == 1)
     cs.add(b == 10)
     self.assertTrue(self.solver.check(cs))
     self.assertEqual(self.solver.get_value(cs, c), 11)
Esempio n. 19
0
    def test_ITE(self):
        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)
Esempio n. 20
0
    def testBasicArrayProxySymbIdx(self):
        cs = ConstraintSet()
        array = cs.new_array(index_bits=32, value_bits=32, name="array", default=0)
        key = cs.new_bitvec(32, name="key")
        index = cs.new_bitvec(32, name="index")

        array[key] = 1  # Write 1 to a single location
        cs.add(array.get(index) != 0)  # Constrain index so it selects that location
        a_index = self.solver.get_value(cs, index)  # get a concrete solution for index

        cs.add(array.get(a_index) != 0)  # now storage must have something at that location
        cs.add(a_index != index)  # remove it from the solutions
        # It should not be another solution for index
        self.assertFalse(self.solver.check(cs))
Esempio n. 21
0
    def testBasicMigration(self):
        solver = self.solver
        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]
Esempio n. 22
0
    def test_201503110346PYTHON_PUSH24(self):
        """
        Testcase taken from https://github.com/ethereum/tests
        File: 201503110346PYTHON_PUSH24.json
        sha256sum: 0f512fa3c9cf0e24e246ca46e8e072745df14f1cdfc8fcf6d201aba5e55f7932
        Code:     
        """    
    
        def solve(val):
            return self._solve(constraints, val)

        constraints = ConstraintSet()

        blocknumber = constraints.new_bitvec(256, name='blocknumber')
        constraints.add(blocknumber == 300)

        timestamp = constraints.new_bitvec(256, name='timestamp')
        constraints.add(timestamp == 2)

        difficulty = constraints.new_bitvec(256, name='difficulty')
        constraints.add(difficulty == 115792089237316195423570985008687907853269984665640564039457584007913129639935)

        coinbase = constraints.new_bitvec(256, name='coinbase')
        constraints.add(coinbase == 244687034288125203496486448490407391986876152250)

        gaslimit = constraints.new_bitvec(256, name='gaslimit')
        constraints.add(gaslimit == 1000000)

        world = evm.EVMWorld(constraints, blocknumber=blocknumber, timestamp=timestamp, difficulty=difficulty,
                             coinbase=coinbase, gaslimit=gaslimit)
    
        acc_addr = 0xf572e5295c57f15886f9b263e2f6d2d6c7b5ec6
        acc_code = unhexlify('7745414245403745f31387900a8d55')
            
        acc_balance = constraints.new_bitvec(256, name='balance_0xf572e5295c57f15886f9b263e2f6d2d6c7b5ec6')
        constraints.add(acc_balance == 1000000000000000000)

        acc_nonce = constraints.new_bitvec(256, name='nonce_0xf572e5295c57f15886f9b263e2f6d2d6c7b5ec6')
        constraints.add(acc_nonce == 0)

        world.create_account(address=acc_addr, balance=acc_balance, code=acc_code, nonce=acc_nonce)

        address = 0xf572e5295c57f15886f9b263e2f6d2d6c7b5ec6
        caller = 0xcd1722f3947def4cf144679da39c4c32bdc35681
        price = constraints.new_bitvec(256, name='price')
        constraints.add(price == 100000000000000)

        value = constraints.new_bitvec(256, name='value')
        constraints.add(value == 1000000000000000000)

        gas = constraints.new_bitvec(256, name='gas')
        constraints.add(gas == 10000)

        data = ''
        # open a fake tx, no funds send
        world._open_transaction('CALL', address, price, data, caller, value, gas=gas)

        # This variable might seem redundant in some tests - don't forget it is auto generated
        # and there are cases in which we need it ;)
        result, returndata = self._test_run(world)

        # World sanity checks - those should not change, right?
        self.assertEqual(solve(world.block_number()), 300)
        self.assertEqual(solve(world.block_gaslimit()), 1000000)
        self.assertEqual(solve(world.block_timestamp()), 2)
        self.assertEqual(solve(world.block_difficulty()), 115792089237316195423570985008687907853269984665640564039457584007913129639935)
        self.assertEqual(solve(world.block_coinbase()), 0x2adc25665018aa1fe0e6bc666dac8fc2697ff9ba)

        # Add post checks for account 0xf572e5295c57f15886f9b263e2f6d2d6c7b5ec6
        # check nonce, balance, code
        self.assertEqual(solve(world.get_nonce(0xf572e5295c57f15886f9b263e2f6d2d6c7b5ec6)), 0)
        self.assertEqual(solve(world.get_balance(0xf572e5295c57f15886f9b263e2f6d2d6c7b5ec6)), 1000000000000000000)
        self.assertEqual(world.get_code(0xf572e5295c57f15886f9b263e2f6d2d6c7b5ec6), unhexlify('7745414245403745f31387900a8d55'))
        # check outs
        self.assertEqual(returndata, unhexlify(''))
        # check logs
        logs = [Log(unhexlify('{:040x}'.format(l.address)), l.topics, solve(l.memlog)) for l in world.logs]
        data = rlp.encode(logs)
        self.assertEqual(sha3.keccak_256(data).hexdigest(), '1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347')

        # test used gas
        self.assertEqual(solve(world.current_vm.gas), 9997)
Esempio n. 23
0
    def test_201503110219PYTHON(self):
        """
        Testcase taken from https://github.com/ethereum/tests
        File: 201503110219PYTHON.json
        sha256sum: e153bd49bafe6f1e398ddaeb35a9f0493d823b36c3823908211bf371ec95cb1f
        Code:     BLOCKHASH
                  BLOCKHASH
                  GASLIMIT
                  SWAP2
                  NUMBER
                  BLOCKHASH
                  COINBASE
                  DIFFICULTY
                  DUP1
                  SWAP8
                  MSIZE
                  DUP9
        """    
    
        def solve(val):
            return self._solve(constraints, val)

        constraints = ConstraintSet()

        blocknumber = constraints.new_bitvec(256, name='blocknumber')
        constraints.add(blocknumber == 300)

        timestamp = constraints.new_bitvec(256, name='timestamp')
        constraints.add(timestamp == 2)

        difficulty = constraints.new_bitvec(256, name='difficulty')
        constraints.add(difficulty == 115792089237316195423570985008687907853269984665640564039457584007913129639935)

        coinbase = constraints.new_bitvec(256, name='coinbase')
        constraints.add(coinbase == 244687034288125203496486448490407391986876152250)

        gaslimit = constraints.new_bitvec(256, name='gaslimit')
        constraints.add(gaslimit == 1000000)

        world = evm.EVMWorld(constraints, blocknumber=blocknumber, timestamp=timestamp, difficulty=difficulty,
                             coinbase=coinbase, gaslimit=gaslimit)
    
        acc_addr = 0xf572e5295c57f15886f9b263e2f6d2d6c7b5ec6
        acc_code = unhexlify('4040459143404144809759886d608f')
            
        acc_balance = constraints.new_bitvec(256, name='balance_0xf572e5295c57f15886f9b263e2f6d2d6c7b5ec6')
        constraints.add(acc_balance == 1000000000000000000)

        acc_nonce = constraints.new_bitvec(256, name='nonce_0xf572e5295c57f15886f9b263e2f6d2d6c7b5ec6')
        constraints.add(acc_nonce == 0)

        world.create_account(address=acc_addr, balance=acc_balance, code=acc_code, nonce=acc_nonce)

        address = 0xf572e5295c57f15886f9b263e2f6d2d6c7b5ec6
        caller = 0xcd1722f3947def4cf144679da39c4c32bdc35681
        price = constraints.new_bitvec(256, name='price')
        constraints.add(price == 100000000000000)

        value = constraints.new_bitvec(256, name='value')
        constraints.add(value == 1000000000000000000)

        gas = constraints.new_bitvec(256, name='gas')
        constraints.add(gas == 10000)

        data = ''
        # open a fake tx, no funds send
        world._open_transaction('CALL', address, price, data, caller, value, gas=gas)

        # This variable might seem redundant in some tests - don't forget it is auto generated
        # and there are cases in which we need it ;)
        result, returndata = self._test_run(world)

        # World sanity checks - those should not change, right?
        self.assertEqual(solve(world.block_number()), 300)
        self.assertEqual(solve(world.block_gaslimit()), 1000000)
        self.assertEqual(solve(world.block_timestamp()), 2)
        self.assertEqual(solve(world.block_difficulty()), 115792089237316195423570985008687907853269984665640564039457584007913129639935)
        self.assertEqual(solve(world.block_coinbase()), 0x2adc25665018aa1fe0e6bc666dac8fc2697ff9ba)

        # If test end in exception check it here
        self.assertTrue(result == 'THROW')
Esempio n. 24
0
    def test_timestamp(self):
        """
        Testcase taken from https://github.com/ethereum/tests
        File: timestamp.json
        sha256sum: e0517702c3ba8bc8a593af7dbdb4de4d3ee7a53ae4fffc058776e40c435b20ba
        Code:     TIMESTAMP
                  PUSH1 0x0
                  SSTORE
        """
        def solve(val):
            return self._solve(constraints, val)

        constraints = ConstraintSet()

        blocknumber = constraints.new_bitvec(256, name='blocknumber')
        constraints.add(blocknumber == 0)

        timestamp = constraints.new_bitvec(256, name='timestamp')
        constraints.add(timestamp == 1)

        difficulty = constraints.new_bitvec(256, name='difficulty')
        constraints.add(difficulty == 256)

        coinbase = constraints.new_bitvec(256, name='coinbase')
        constraints.add(
            coinbase == 244687034288125203496486448490407391986876152250)

        gaslimit = constraints.new_bitvec(256, name='gaslimit')
        constraints.add(gaslimit == 1000000)

        world = evm.EVMWorld(constraints,
                             blocknumber=blocknumber,
                             timestamp=timestamp,
                             difficulty=difficulty,
                             coinbase=coinbase,
                             gaslimit=gaslimit)

        acc_addr = 0xf572e5295c57f15886f9b263e2f6d2d6c7b5ec6
        acc_code = unhexlify('42600055')

        acc_balance = constraints.new_bitvec(
            256, name='balance_0xf572e5295c57f15886f9b263e2f6d2d6c7b5ec6')
        constraints.add(acc_balance == 100000000000000000000000)

        acc_nonce = constraints.new_bitvec(
            256, name='nonce_0xf572e5295c57f15886f9b263e2f6d2d6c7b5ec6')
        constraints.add(acc_nonce == 0)

        world.create_account(address=acc_addr,
                             balance=acc_balance,
                             code=acc_code,
                             nonce=acc_nonce)

        address = 0xf572e5295c57f15886f9b263e2f6d2d6c7b5ec6
        caller = 0xcd1722f3947def4cf144679da39c4c32bdc35681
        price = constraints.new_bitvec(256, name='price')
        constraints.add(price == 100000000000000)

        value = constraints.new_bitvec(256, name='value')
        constraints.add(value == 1000000000000000000)

        gas = constraints.new_bitvec(256, name='gas')
        constraints.add(gas == 100000)

        data = ''
        # open a fake tx, no funds send
        world._open_transaction('CALL',
                                address,
                                price,
                                data,
                                caller,
                                value,
                                gas=gas)

        # This variable might seem redundant in some tests - don't forget it is auto generated
        # and there are cases in which we need it ;)
        result, returndata = self._test_run(world)

        # World sanity checks - those should not change, right?
        self.assertEqual(solve(world.block_number()), 0)
        self.assertEqual(solve(world.block_gaslimit()), 1000000)
        self.assertEqual(solve(world.block_timestamp()), 1)
        self.assertEqual(solve(world.block_difficulty()), 256)
        self.assertEqual(solve(world.block_coinbase()),
                         0x2adc25665018aa1fe0e6bc666dac8fc2697ff9ba)

        # Add post checks for account 0xf572e5295c57f15886f9b263e2f6d2d6c7b5ec6
        # check nonce, balance, code
        self.assertEqual(
            solve(world.get_nonce(0xf572e5295c57f15886f9b263e2f6d2d6c7b5ec6)),
            0)
        self.assertEqual(
            solve(
                world.get_balance(0xf572e5295c57f15886f9b263e2f6d2d6c7b5ec6)),
            100000000000000000000000)
        self.assertEqual(
            world.get_code(0xf572e5295c57f15886f9b263e2f6d2d6c7b5ec6),
            unhexlify('42600055'))
        # check storage
        self.assertEqual(
            solve(
                world.get_storage_data(
                    0xf572e5295c57f15886f9b263e2f6d2d6c7b5ec6, 0x00)), 0x01)
        # check outs
        self.assertEqual(returndata, unhexlify(''))
        # check logs
        logs = [
            Log(unhexlify('{:040x}'.format(l.address)), l.topics,
                solve(l.memlog)) for l in world.logs
        ]
        data = rlp.encode(logs)
        self.assertEqual(
            sha3.keccak_256(data).hexdigest(),
            '1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347')

        # test used gas
        self.assertEqual(solve(world.current_vm.gas), 79995)
Esempio n. 25
0
 def testBool3(self):
     cs = ConstraintSet()
     bf = BoolConstant(value=False)
     bt = BoolConstant(value=True)
     cs.add(Operators.AND(bt, bt, bf, bt))
     self.assertFalse(self.solver.check(cs))
Esempio n. 26
0
 def testSolver(self):
     cs = ConstraintSet()
     a = cs.new_bitvec(32)
     b = cs.new_bitvec(32)
     cs.add(a + b > 100)
     self.assertTrue(self.solver.check(cs))
Esempio n. 27
0
 def testBasicConstraints(self):
     cs = ConstraintSet()
     a = cs.new_bitvec(32)
     b = cs.new_bitvec(32)
     cs.add(a + b > 100)
Esempio n. 28
0
    def test_201503110206PYTHON(self):
        """
        Testcase taken from https://github.com/ethereum/tests
        File: 201503110206PYTHON.json
        sha256sum: d02dd686767e9a3f281f4dce40244cbe23a022eae7a3e8cc3dd2e747b889500a
        Code:     BLOCKHASH
                  GASLIMIT
                  BLOCKHASH
                  COINBASE
                  GASLIMIT
                  GASLIMIT
                  DIFFICULTY
                  COINBASE
                  CALLVALUE
                  CODECOPY
                  DUP8
                  SELFDESTRUCT
                  CALLDATACOPY
                  CALLDATALOAD
                  DIV
                  ADDRESS
                  SSTORE
        """    
    
        def solve(val):
            return self._solve(constraints, val)

        constraints = ConstraintSet()

        blocknumber = constraints.new_bitvec(256, name='blocknumber')
        constraints.add(blocknumber == 300)

        timestamp = constraints.new_bitvec(256, name='timestamp')
        constraints.add(timestamp == 2)

        difficulty = constraints.new_bitvec(256, name='difficulty')
        constraints.add(difficulty == 115792089237316195423570985008687907853269984665640564039457584007913129639935)

        coinbase = constraints.new_bitvec(256, name='coinbase')
        constraints.add(coinbase == 244687034288125203496486448490407391986876152250)

        gaslimit = constraints.new_bitvec(256, name='gaslimit')
        constraints.add(gaslimit == 1000000)

        world = evm.EVMWorld(constraints, blocknumber=blocknumber, timestamp=timestamp, difficulty=difficulty,
                             coinbase=coinbase, gaslimit=gaslimit)
    
        acc_addr = 0xf572e5295c57f15886f9b263e2f6d2d6c7b5ec6
        acc_code = unhexlify('4045404145454441343987ff3735043055')
            
        acc_balance = constraints.new_bitvec(256, name='balance_0xf572e5295c57f15886f9b263e2f6d2d6c7b5ec6')
        constraints.add(acc_balance == 1000000000000000000)

        acc_nonce = constraints.new_bitvec(256, name='nonce_0xf572e5295c57f15886f9b263e2f6d2d6c7b5ec6')
        constraints.add(acc_nonce == 0)

        world.create_account(address=acc_addr, balance=acc_balance, code=acc_code, nonce=acc_nonce)

        address = 0xf572e5295c57f15886f9b263e2f6d2d6c7b5ec6
        caller = 0xcd1722f3947def4cf144679da39c4c32bdc35681
        price = constraints.new_bitvec(256, name='price')
        constraints.add(price == 100000000000000)

        value = constraints.new_bitvec(256, name='value')
        constraints.add(value == 1000000000000000000)

        gas = constraints.new_bitvec(256, name='gas')
        constraints.add(gas == 10000)

        data = ''
        # open a fake tx, no funds send
        world._open_transaction('CALL', address, price, data, caller, value, gas=gas)

        # This variable might seem redundant in some tests - don't forget it is auto generated
        # and there are cases in which we need it ;)
        result, returndata = self._test_run(world)

        # World sanity checks - those should not change, right?
        self.assertEqual(solve(world.block_number()), 300)
        self.assertEqual(solve(world.block_gaslimit()), 1000000)
        self.assertEqual(solve(world.block_timestamp()), 2)
        self.assertEqual(solve(world.block_difficulty()), 115792089237316195423570985008687907853269984665640564039457584007913129639935)
        self.assertEqual(solve(world.block_coinbase()), 0x2adc25665018aa1fe0e6bc666dac8fc2697ff9ba)

        # If test end in exception check it here
        self.assertTrue(result == 'THROW')
Esempio n. 29
0
    def test_addmod(self):
        """
        (declare-fun BV () (_ BitVec 256))
        (declare-fun BV_2 () (_ BitVec 256))
        (declare-fun BV_1 () (_ BitVec 256))
        (declare-fun a_1 () (_ BitVec 256))(assert (= a_1 (bvmul BV BV_1)))
        (declare-fun a_2 () (_ BitVec 512))(assert (= a_2 ((_ zero_extend 256) BV)))
        (declare-fun a_3 () (_ BitVec 512))(assert (= a_3 ((_ zero_extend 256) BV_1)))
        (declare-fun a_4 () (_ BitVec 512))(assert (= a_4 (bvmul a_2 a_3)))
        (declare-fun a_5 () (_ BitVec 512))(assert (= a_5 ((_ zero_extend 256) BV_2)))
        (declare-fun a_6 () (_ BitVec 512))(assert (= a_6 (bvsmod a_4 a_5)))
        (declare-fun a_7 () (_ BitVec 256))(assert (= a_7 ((_ extract 255 0) a_6)))
        (declare-fun a_8 () (_ BitVec 256))(assert (= a_8 (bvsmod a_1 BV_2)))
        (declare-fun a_9 () Bool)(assert (= a_9 (= a_7 a_8)))
        (assert (not a_9))

        (check-sat)
        """
        from manticore.platforms import evm
        from manticore.core.smtlib import ConstraintSet, Z3Solver, Operators

        constraints = ConstraintSet()

        address = 0x41414141414141414141
        data = b""
        caller = 0x42424242424242424242
        value = 0
        bytecode = ""
        vm = evm.EVM(constraints,
                     address,
                     data,
                     caller,
                     value,
                     bytecode,
                     gas=23000)

        self.assertEqual(vm.ADDMOD(12323, 2343, 20), 6)
        self.assertEqual(vm.ADDMOD(12323, 2343, 0), 0)

        A, B, C = (
            0x780000002090309A004201626B1400041D318000000200008A0080089C042DA7,
            0xF000000740403F7007C012807BED003BE2CE800000060000FFFFBFF7E4087033,
            0x338000080FFFFF64AAAACFFCF7DBFA408000000000000270120000001E7C2ACF,
        )
        self.assertEqual(
            vm.ADDMOD(A, B, C),
            23067954172474524581131069693479689311231082562138745684554374357070230297856,
        )
        a, b, c = (
            constraints.new_bitvec(256),
            constraints.new_bitvec(256),
            constraints.new_bitvec(256),
        )
        constraints.add(a == A)
        constraints.add(b == B)
        constraints.add(c == C)
        result = vm.ADDMOD(a, b, c)
        # 0x32ffffd700d073ae080133f517d922bd000000000007f1611e003fffc9239d00
        self.assertEqual(
            Z3Solver.instance().get_all_values(constraints, result),
            [
                0x32FFFFD700D073AE080133F517D922BD000000000007F1611E003FFFC9239D00
            ],
        )
Esempio n. 30
0
    def test_return2(self):
        """
        Testcase taken from https://github.com/ethereum/tests
        File: return2.json
        sha256sum: 25972361a5871003f44467255a656b9e7ba3762a5cfe02b56a0197318d375b9a
        Code:     PUSH1 0x37
                  PUSH1 0x0
                  MSTORE8
                  PUSH1 0x0
                  MLOAD
                  PUSH1 0x0
                  SSTORE
                  PUSH1 0x21
                  PUSH1 0x0
                  RETURN
        """
        def solve(val):
            return self._solve(constraints, val)

        constraints = ConstraintSet()

        blocknumber = constraints.new_bitvec(256, name='blocknumber')
        constraints.add(blocknumber == 0)

        timestamp = constraints.new_bitvec(256, name='timestamp')
        constraints.add(timestamp == 1)

        difficulty = constraints.new_bitvec(256, name='difficulty')
        constraints.add(difficulty == 256)

        coinbase = constraints.new_bitvec(256, name='coinbase')
        constraints.add(
            coinbase == 244687034288125203496486448490407391986876152250)

        gaslimit = constraints.new_bitvec(256, name='gaslimit')
        constraints.add(gaslimit == 10000000)

        world = evm.EVMWorld(constraints,
                             blocknumber=blocknumber,
                             timestamp=timestamp,
                             difficulty=difficulty,
                             coinbase=coinbase,
                             gaslimit=gaslimit)

        acc_addr = 0xcd1722f3947def4cf144679da39c4c32bdc35681
        acc_code = unhexlify('603760005360005160005560216000f3')

        acc_balance = constraints.new_bitvec(
            256, name='balance_0xcd1722f3947def4cf144679da39c4c32bdc35681')
        constraints.add(acc_balance == 23)

        acc_nonce = constraints.new_bitvec(
            256, name='nonce_0xcd1722f3947def4cf144679da39c4c32bdc35681')
        constraints.add(acc_nonce == 0)

        world.create_account(address=acc_addr,
                             balance=acc_balance,
                             code=acc_code,
                             nonce=acc_nonce)

        address = 0xcd1722f3947def4cf144679da39c4c32bdc35681
        caller = 0xf572e5295c57f15886f9b263e2f6d2d6c7b5ec6
        price = constraints.new_bitvec(256, name='price')
        constraints.add(price == 100000000000000)

        value = constraints.new_bitvec(256, name='value')
        constraints.add(value == 23)

        gas = constraints.new_bitvec(256, name='gas')
        constraints.add(gas == 100000)

        data = constraints.new_array(index_max=1)
        constraints.add(data == b'\xaa')

        # open a fake tx, no funds send
        world._open_transaction('CALL',
                                address,
                                price,
                                data,
                                caller,
                                value,
                                gas=gas)

        # This variable might seem redundant in some tests - don't forget it is auto generated
        # and there are cases in which we need it ;)
        result, returndata = self._test_run(world)

        # World sanity checks - those should not change, right?
        self.assertEqual(solve(world.block_number()), 0)
        self.assertEqual(solve(world.block_gaslimit()), 10000000)
        self.assertEqual(solve(world.block_timestamp()), 1)
        self.assertEqual(solve(world.block_difficulty()), 256)
        self.assertEqual(solve(world.block_coinbase()),
                         0x2adc25665018aa1fe0e6bc666dac8fc2697ff9ba)

        # Add post checks for account 0xcd1722f3947def4cf144679da39c4c32bdc35681
        # check nonce, balance, code
        self.assertEqual(
            solve(world.get_nonce(0xcd1722f3947def4cf144679da39c4c32bdc35681)),
            0)
        self.assertEqual(
            solve(
                world.get_balance(0xcd1722f3947def4cf144679da39c4c32bdc35681)),
            23)
        self.assertEqual(
            world.get_code(0xcd1722f3947def4cf144679da39c4c32bdc35681),
            unhexlify('603760005360005160005560216000f3'))
        # check storage
        self.assertEqual(
            solve(
                world.get_storage_data(
                    0xcd1722f3947def4cf144679da39c4c32bdc35681, 0x00)),
            0x3700000000000000000000000000000000000000000000000000000000000000)
        # check outs
        self.assertEqual(
            returndata,
            unhexlify(
                '370000000000000000000000000000000000000000000000000000000000000000'
            ))
        # check logs
        logs = [
            Log(unhexlify('{:040x}'.format(l.address)), l.topics,
                solve(l.memlog)) for l in world.logs
        ]
        data = rlp.encode(logs)
        self.assertEqual(
            sha3.keccak_256(data).hexdigest(),
            '1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347')

        # test used gas
        self.assertEqual(solve(world.current_vm.gas), 79970)