def test_PUSH_28(self): #Make the constraint store constraints = ConstraintSet() #make the ethereum world state world = evm.EVMWorld(constraints) address = 0x222222222222222222222222222222222222200 caller = origin = 0x111111111111111111111111111111111111100 price = 0 value = 10000 bytecode = '{' data = 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' header = { 'coinbase': 0, 'timestamp': 0, 'number': 0, 'difficulty': 0, 'gaslimit': 0, } gas = 1000000 new_vm = evm.EVM(constraints, address, origin, price, data, caller, value, bytecode, header, gas=gas, global_storage=world.storage) last_exception, last_returned = self._execute(new_vm) self.assertEqual(last_exception, None) self.assertEqual(new_vm.pc, 29) self.assertEqual(new_vm.stack, [0])
def test_CALLDATALOAD_5(self): # Make the constraint store constraints = ConstraintSet() # make the ethereum world state world = evm.EVMWorld(constraints) address = 0x222222222222222222222222222222222222200 caller = origin = 0x111111111111111111111111111111111111100 price = 0 value = 10000 bytecode = b"5" data = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" header = { "coinbase": 0, "timestamp": 0, "number": 0, "difficulty": 0, "gaslimit": 0 } gas = 1000000 new_vm = evm.EVM(constraints, address, data, caller, value, bytecode, gas=gas, world=world) new_vm._push( 3618502788666131106986593281521497120414687020801267626233049500247285301263 ) last_exception, last_returned = self._execute(new_vm) self.assertEqual(last_exception, None) self.assertEqual(new_vm.pc, 1) self.assertEqual(new_vm.stack, [0])
def test_CALLDATALOAD_1(self): # Make the constraint store constraints = ConstraintSet() # make the ethereum world state world = evm.EVMWorld(constraints) address = 0x222222222222222222222222222222222222200 caller = origin = 0x111111111111111111111111111111111111100 price = 0 value = 10000 bytecode = b"5" data = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" header = { "coinbase": 0, "timestamp": 0, "number": 0, "difficulty": 0, "gaslimit": 0 } gas = 1000000 new_vm = evm.EVM(constraints, address, data, caller, value, bytecode, gas=gas, world=world) new_vm._push( 115792089237316195423570985008687907853269984665640564039457584007913129639935 ) last_exception, last_returned = self._execute(new_vm) self.assertEqual(last_exception, None) self.assertEqual(new_vm.pc, 1) self.assertEqual(new_vm.stack, [0])
def test_INVALID_1(self): #Make the constraint store constraints = ConstraintSet() #make the ethereum world state world = evm.EVMWorld(constraints) address=0x222222222222222222222222222222222222200 caller=origin=0x111111111111111111111111111111111111100 price=0 value=10000 bytecode='\xfe' data = 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' header = { 'coinbase': 0, 'timestamp': 0, 'number': 0, 'difficulty': 0, 'gaslimit': 0, } gas = 1000000 new_vm = evm.EVM(constraints, address, data, caller, value, bytecode, gas=gas, world=world) last_exception, last_returned = self._execute(new_vm) self.assertEqual(last_exception, 'INVALID') self.assertEqual(new_vm.gas, 1000000)
def test_CALLDATALOAD_4(self): # Make the constraint store constraints = ConstraintSet() # make the ethereum world state world = evm.EVMWorld(constraints) address = 0x222222222222222222222222222222222222200 caller = origin = 0x111111111111111111111111111111111111100 price = 0 value = 10000 bytecode = b"5" data = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" header = { "coinbase": 0, "timestamp": 0, "number": 0, "difficulty": 0, "gaslimit": 0 } gas = 1000000 new_vm = evm.EVM(constraints, address, data, caller, value, bytecode, gas=gas, world=world) new_vm._push( 57896044618658097711785492504343953926634992332820282019728792003956564819952 ) last_exception, last_returned = self._execute(new_vm) self.assertEqual(last_exception, None) self.assertEqual(new_vm.pc, 1) self.assertEqual(new_vm.stack, [0])
def test_ISZERO_5(self): #Make the constraint store constraints = ConstraintSet() #make the ethereum world state world = evm.EVMWorld(constraints) address = 0x222222222222222222222222222222222222200 caller = origin = 0x111111111111111111111111111111111111100 price = 0 value = 10000 bytecode = b'\x15' data = 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' header = { 'coinbase': 0, 'timestamp': 0, 'number': 0, 'difficulty': 0, 'gaslimit': 0, } gas = 1000000 new_vm = evm.EVM(constraints, address, data, caller, value, bytecode, gas=gas, world=world) new_vm._push( 3618502788666131106986593281521497120414687020801267626233049500247285301263 ) last_exception, last_returned = self._execute(new_vm) self.assertEqual(last_exception, None) self.assertEqual(new_vm.pc, 1) self.assertEqual(new_vm.stack, [0])
def test_ISZERO_1(self): #Make the constraint store constraints = ConstraintSet() #make the ethereum world state world = evm.EVMWorld(constraints) address = 0x222222222222222222222222222222222222200 caller = origin = 0x111111111111111111111111111111111111100 price = 0 value = 10000 bytecode = b'\x15' data = 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' header = { 'coinbase': 0, 'timestamp': 0, 'number': 0, 'difficulty': 0, 'gaslimit': 0, } gas = 1000000 new_vm = evm.EVM(constraints, address, data, caller, value, bytecode, gas=gas, world=world) new_vm._push( 115792089237316195423570985008687907853269984665640564039457584007913129639935 ) last_exception, last_returned = self._execute(new_vm) self.assertEqual(last_exception, None) self.assertEqual(new_vm.pc, 1) self.assertEqual(new_vm.stack, [0])
def test_ISZERO_4(self): #Make the constraint store constraints = ConstraintSet() #make the ethereum world state world = evm.EVMWorld(constraints) address = 0x222222222222222222222222222222222222200 caller = origin = 0x111111111111111111111111111111111111100 price = 0 value = 10000 bytecode = b'\x15' data = 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' header = { 'coinbase': 0, 'timestamp': 0, 'number': 0, 'difficulty': 0, 'gaslimit': 0, } gas = 1000000 new_vm = evm.EVM(constraints, address, data, caller, value, bytecode, gas=gas, world=world) new_vm._push( 57896044618658097711785492504343953926634992332820282019728792003956564819952 ) last_exception, last_returned = self._execute(new_vm) self.assertEqual(last_exception, None) self.assertEqual(new_vm.pc, 1) self.assertEqual(new_vm.stack, [0])
def test_CALLDATALOAD_2(self): #Make the constraint store constraints = ConstraintSet() #make the ethereum world state world = evm.EVMWorld(constraints) address = 0x222222222222222222222222222222222222200 caller = origin = 0x111111111111111111111111111111111111100 price = 0 value = 10000 bytecode = '5' data = 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' header = { 'coinbase': 0, 'timestamp': 0, 'number': 0, 'difficulty': 0, 'gaslimit': 0, } gas = 1000000 new_vm = evm.EVM(constraints, address, data, caller, value, bytecode, gas=gas, world=world) new_vm._push(0) last_exception, last_returned = self._execute(new_vm) self.assertEqual(last_exception, None) self.assertEqual(new_vm.pc, 1) self.assertEqual(new_vm.stack, [ 29515630589904128245223976570842015727304113738300535931626442982409229107200L ])
def test_REVERT_11(self): #Make the constraint store constraints = ConstraintSet() #make the ethereum world state world = evm.EVMWorld(constraints) address = 0x222222222222222222222222222222222222200 caller = origin = 0x111111111111111111111111111111111111100 price = 0 value = 10000 bytecode = '\xfd' data = 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' header = { 'coinbase': 0, 'timestamp': 0, 'number': 0, 'difficulty': 0, 'gaslimit': 0, } gas = 1000000 new_vm = evm.EVM(constraints, address, origin, price, data, caller, value, bytecode, header, gas=gas, global_storage=world.storage) new_vm._push(6089590155545428825848686802984512581899718912L) new_vm._push(6089590155545428825848686802984512581899718912L) last_exception, last_returned = self._execute(new_vm) self.assertEqual(last_exception, 'OOG')
def test_NOT_9(self): #Make the constraint store constraints = ConstraintSet() #make the ethereum world state world = evm.EVMWorld(constraints) address = 0x222222222222222222222222222222222222200 caller = origin = 0x111111111111111111111111111111111111100 price = 0 value = 10000 bytecode = '\x19' data = 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' header = { 'coinbase': 0, 'timestamp': 0, 'number': 0, 'difficulty': 0, 'gaslimit': 0, } gas = 1000000 new_vm = evm.EVM(constraints, address, data, caller, value, bytecode, gas=gas, world=world) new_vm._push(6089590155545428825848686802984512581899718912L) last_exception, last_returned = self._execute(new_vm) self.assertEqual(last_exception, None) self.assertEqual(new_vm.pc, 1) self.assertEqual(new_vm.stack, [ 115792089237316195423570985008681818263114439236814715352654599495331229921023L ])
def __init__(self): #Make the constraint store constraints = ConstraintSet() #make the ethereum world state world = evm.EVMWorld(constraints) initial_state = State(constraints, world) super(ManticoreEVM, self).__init__(initial_state) #The following should go to manticore.context so we can use multiprocessing self.code = {} self.context['seth'] = {} self.context['seth']['_pending_transaction'] = None self.context['seth']['_saved_states'] = [] self.context['seth']['_final_states'] = [] self._executor.subscribe('did_load_state', self.load_state_callback) self._executor.subscribe('will_terminate_state', self.terminate_state_callback) self._executor.subscribe('will_execute_instruction', self.will_execute_instruction_callback) self._executor.subscribe('did_read_code', self.did_read_code) self._executor.subscribe('on_symbolic_sha3', self.symbolic_sha3) self._executor.subscribe('on_concrete_sha3', self.concrete_sha3)
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))
def setUp(self): dirname = os.path.dirname(__file__) l = linux.Linux(os.path.join(dirname, "binaries", "basic_linux_amd64")) self.state = State(ConstraintSet(), l)
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')
def setUp(self): l = linux.Linux('/bin/ls') self.state = State(ConstraintSet(), l) self.lock = manager.Condition(manager.RLock())
def _clear_constraints(self): self.state._constraints = ConstraintSet()
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]
def test_ConstraintsForking(self): solver = self.solver 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))
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))
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))
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)
def _clear_constraints(self): self.state.context['migration_map'] = None self.state._constraints = ConstraintSet()
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 ], )
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')
def testRelated(self): cs = ConstraintSet() aa1 = cs.new_bool(name="AA1") aa2 = cs.new_bool(name="AA2") bb1 = cs.new_bool(name="BB1") bb2 = cs.new_bool(name="BB2") cs.add(Operators.OR(aa1, aa2)) cs.add(Operators.OR(bb1, bb2)) self.assertTrue(self.solver.check(cs)) # No BB variables related to AA self.assertNotIn("BB", cs.related_to(aa1).to_string()) self.assertNotIn("BB", cs.related_to(aa2).to_string()) self.assertNotIn("BB", cs.related_to(aa1 == aa2).to_string()) self.assertNotIn("BB", cs.related_to(aa1 == False).to_string()) # No AA variables related to BB self.assertNotIn("AA", cs.related_to(bb1).to_string()) self.assertNotIn("AA", cs.related_to(bb2).to_string()) self.assertNotIn("AA", cs.related_to(bb1 == bb2).to_string()) self.assertNotIn("AA", cs.related_to(bb1 == False).to_string()) # Nothing is related to tautologies? self.assertEqual("", cs.related_to(simplify(bb1 == bb1)).to_string()) # But if the tautollogy can not get simplified we have to ask the solver # and send in all the other stuff self.assertNotIn("AA", cs.related_to(bb1 == bb1).to_string())
def make_mock_evm_state(): cs = ConstraintSet() fakestate = State(cs, EVMWorld(cs)) return fakestate
def testBasicConstraints(self): cs = ConstraintSet() a = cs.new_bitvec(32) b = cs.new_bitvec(32) cs.add(a + b > 100)
def test_SELFDESTRUCT_8(self): #Make the constraint store constraints = ConstraintSet() #make the ethereum world state world = evm.EVMWorld(constraints) address = 0x3032323232323232323232323232323232323230 balance = 0 code = '' storage = {} world.create_account(address=address, balance=balance, code=code, storage=storage) address = 0x30 balance = 0 code = '' storage = {} world.create_account(address=address, balance=balance, code=code, storage=storage) address = 0x111111111111111111111111111111111111100 balance = 0 code = '' storage = {} world.create_account(address=address, balance=balance, code=code, storage=storage) address = 0x222222222222222222222222222222222222200 balance = 0 code = '' storage = {} world.create_account(address=address, balance=balance, code=code, storage=storage) address = 0x222222222222222222222222222222222222200 caller = origin = 0x111111111111111111111111111111111111100 price = 0 value = 10000 bytecode = '\xff' data = 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' header = { 'coinbase': 0, 'timestamp': 0, 'number': 0, 'difficulty': 0, 'gaslimit': 0, } gas = 1000000 new_vm = evm.EVM(constraints, address, data, caller, value, bytecode, gas=gas, world=world) new_vm._push(48) last_exception, last_returned = self._execute(new_vm) self.assertEqual(last_exception, 'SELFDESTRUCT') self.assertEqual(new_vm.gas, 995000)
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))