def execute_contract_creation(laser_evm, contract_initialization_code, contract_name=None): """ Executes a contract creation transaction from all open states""" open_states = laser_evm.open_states[:] del laser_evm.open_states[:] new_account = laser_evm.world_state.create_account(0, concrete_storage=True, dynamic_loader=None) if contract_name: new_account.contract_name = contract_name for open_world_state in open_states: next_transaction_id = get_next_transaction_id() transaction = ContractCreationTransaction( open_world_state, BitVec("creator{}".format(next_transaction_id), 256), next_transaction_id, new_account, Disassembly(contract_initialization_code), [], BitVec("gas_price{}".format(next_transaction_id), 256), BitVec("call_value{}".format(next_transaction_id), 256), BitVec("origin{}".format(next_transaction_id), 256), CalldataType.SYMBOLIC, ) _setup_global_state_for_execution(laser_evm, transaction) laser_evm.exec(True) return new_account
def execute_message_call(laser_evm, callee_address: str) -> None: """Executes a message call transaction from all open states. :param laser_evm: :param callee_address: """ # TODO: Resolve circular import between .transaction and ..svm to import LaserEVM here open_states = laser_evm.open_states[:] del laser_evm.open_states[:] for open_world_state in open_states: if open_world_state[callee_address].deleted: log.debug("Can not execute dead contract, skipping.") continue next_transaction_id = get_next_transaction_id() transaction = MessageCallTransaction( world_state=open_world_state, identifier=next_transaction_id, gas_price=symbol_factory.BitVecSym( "gas_price{}".format(next_transaction_id), 256), gas_limit=8000000, # block gas limit origin=symbol_factory.BitVecSym( "origin{}".format(next_transaction_id), 256), caller=symbol_factory.BitVecVal(ATTACKER_ADDRESS, 256), callee_account=open_world_state[callee_address], call_data=SymbolicCalldata(next_transaction_id), call_value=symbol_factory.BitVecSym( "call_value{}".format(next_transaction_id), 256), ) _setup_global_state_for_execution(laser_evm, transaction) laser_evm.exec()
def execute_contract_creation(laser_evm, contract_initialization_code, contract_name=None) -> Account: """ Executes a contract creation transaction from all open states""" # TODO: Resolve circular import between .transaction and ..svm to import LaserEVM here open_states = laser_evm.open_states[:] del laser_evm.open_states[:] new_account = laser_evm.world_state.create_account(0, concrete_storage=True, dynamic_loader=None) if contract_name: new_account.contract_name = contract_name for open_world_state in open_states: next_transaction_id = get_next_transaction_id() transaction = ContractCreationTransaction( world_state=open_world_state, identifier=next_transaction_id, gas_price=BitVec("gas_price{}".format(next_transaction_id), 256), gas_limit=8000000, # block gas limit origin=BitVec("origin{}".format(next_transaction_id), 256), code=Disassembly(contract_initialization_code), caller=BitVecVal(CREATOR_ADDRESS, 256), callee_account=new_account, call_data=[], call_data_type=CalldataType.SYMBOLIC, call_value=BitVec("call_value{}".format(next_transaction_id), 256), ) _setup_global_state_for_execution(laser_evm, transaction) laser_evm.exec(True) return new_account
def execute_message_call(laser_evm, callee_address): """ Executes a message call transaction from all open states """ open_states = laser_evm.open_states[:] del laser_evm.open_states[:] for open_world_state in open_states: if open_world_state[callee_address].deleted: debug("Can not execute dead contract, skipping.") continue next_transaction_id = get_next_transaction_id() transaction = MessageCallTransaction( world_state=open_world_state, callee_account=open_world_state[callee_address], caller=BitVec("caller{}".format(next_transaction_id), 256), identifier=next_transaction_id, call_data=Calldata(next_transaction_id), gas_price=BitVec("gas_price{}".format(next_transaction_id), 256), call_value=BitVec("call_value{}".format(next_transaction_id), 256), origin=BitVec("origin{}".format(next_transaction_id), 256), call_data_type=CalldataType.SYMBOLIC, ) _setup_global_state_for_execution(laser_evm, transaction) laser_evm.exec()
def execute_message_call( laser_evm, callee_address, caller_address, origin_address, code, data, gas, gas_price, value, ): """ Executes a message call transaction from all open states """ open_states = laser_evm.open_states[:] del laser_evm.open_states[:] for open_world_state in open_states: next_transaction_id = get_next_transaction_id() transaction = MessageCallTransaction( identifier=next_transaction_id, world_state=open_world_state, callee_account=open_world_state[callee_address], caller=caller_address, call_data=Calldata(next_transaction_id, data), gas_price=gas_price, call_value=value, origin=origin_address, call_data_type=CalldataType.SYMBOLIC, code=Disassembly(code), ) _setup_global_state_for_execution(laser_evm, transaction) laser_evm.exec()
def execute_message_call( laser_evm, callee_address, caller_address, origin_address, code, data, gas_limit, gas_price, value, track_gas=False, ) -> Union[None, List[GlobalState]]: """Execute a message call transaction from all open states. :param laser_evm: :param callee_address: :param caller_address: :param origin_address: :param code: :param data: :param gas_limit: :param gas_price: :param value: :param track_gas: :return: """ # TODO: Resolve circular import between .transaction and ..svm to import LaserEVM here open_states = laser_evm.open_states[:] del laser_evm.open_states[:] for open_world_state in open_states: next_transaction_id = get_next_transaction_id() transaction = MessageCallTransaction( world_state=open_world_state, identifier=next_transaction_id, gas_price=gas_price, gas_limit=gas_limit, origin=origin_address, code=Disassembly(code), caller=caller_address, callee_account=open_world_state[callee_address], call_data=ConcreteCalldata(next_transaction_id, data), call_value=value, ) _setup_global_state_for_execution(laser_evm, transaction) return laser_evm.exec(track_gas=track_gas)
def execute_contract_creation( laser_evm, contract_initialization_code, contract_name=None, world_state=None ) -> Account: """Executes a contract creation transaction from all open states. :param laser_evm: :param contract_initialization_code: :param contract_name: :return: """ # TODO: Resolve circular import between .transaction and ..svm to import LaserEVM here del laser_evm.open_states[:] world_state = world_state or WorldState() open_states = [world_state] new_account = None for open_world_state in open_states: next_transaction_id = get_next_transaction_id() # call_data "should" be '[]', but it is easier to model the calldata symbolically # and add logic in codecopy/codesize/calldatacopy/calldatasize than to model code "correctly" transaction = ContractCreationTransaction( world_state=open_world_state, identifier=next_transaction_id, gas_price=symbol_factory.BitVecSym( "gas_price{}".format(next_transaction_id), 256 ), gas_limit=8000000, # block gas limit origin=symbol_factory.BitVecSym( "origin{}".format(next_transaction_id), 256 ), code=Disassembly(contract_initialization_code), caller=symbol_factory.BitVecVal(CREATOR_ADDRESS, 256), contract_name=contract_name, call_data=None, call_value=symbol_factory.BitVecSym( "call_value{}".format(next_transaction_id), 256 ), ) _setup_global_state_for_execution(laser_evm, transaction) new_account = new_account or transaction.callee_account laser_evm.exec(True) return new_account
def execute_message_call(laser_evm, callee_address: str, priority=None) -> None: """ Executes a message call transaction from all open states """ # TODO: Resolve circular import between .transaction and ..svm to import LaserEVM here # TODO: if the function of openstate.node.funcname is not in priority list, dont add it # TODO: This is for deleting repeated variables read # copy the open states from last iteration to this iteration # The working list is always empty when an iteration is done open_states = laser_evm.open_states[:] del laser_evm.open_states[:] for open_world_state in open_states: if open_world_state[callee_address].deleted: debug("Can not execute dead contract, skipping.") continue next_transaction_id = get_next_transaction_id() transaction = MessageCallTransaction( world_state=open_world_state, identifier=next_transaction_id, gas_price=BitVec("gas_price{}".format(next_transaction_id), 256), gas_limit=8000000, # block gas limit origin=BitVec("origin{}".format(next_transaction_id), 256), caller=BitVecVal(ATTACKER_ADDRESS, 256), callee_account=open_world_state[callee_address], call_data=SymbolicCalldata(next_transaction_id), call_data_type=CalldataType.SYMBOLIC, call_value=BitVec("call_value{}".format(next_transaction_id), 256), ) # the open states from last iterations are appended to work list here _setup_global_state_for_execution(laser_evm, transaction, open_world_state.node.function_name) laser_evm.exec(priority=None)
def heuristic_message_call_helper(laser_evm, callee_address: str, priority=None): jump = False open_states_copy = copy(laser_evm.open_states) for open_state in open_states_copy: name = open_state.node.function_name for priority_list in priority['RAW']: if name == priority_list.first.function_name: laser_evm.first_order_work_list.append(open_state) laser_evm.open_states.remove(open_state) jump = True break if jump: jump = False continue for priority_list in priority['WAR']: if name == priority_list.first.function_name: laser_evm.second_order_work_list.append(open_state) laser_evm.open_states.remove(open_state) jump = True break if jump: jump = False continue for priority_list in priority['WAW']: if name == priority_list.first.function_name: laser_evm.third_order_work_list.append(open_state) laser_evm.open_states.remove(open_state) jump = True break if jump: jump = False continue for priority_list in priority['RAR']: if name == priority_list.first.function_name: laser_evm.forth_order_work_list.append(open_state) laser_evm.open_states.remove(open_state) jump = True break if jump: jump = False continue laser_evm.ranking.append(laser_evm.first_order_work_list) laser_evm.ranking.append(laser_evm.second_order_work_list) laser_evm.ranking.append(laser_evm.third_order_work_list) laser_evm.ranking.append(laser_evm.forth_order_work_list) del laser_evm.open_states[:] for items in laser_evm.ranking: title = items[0] list1 = items[1:] for open_world_state in list1: if open_world_state[callee_address].deleted: debug("Can not execute dead contract, skipping.") continue last_func_called = open_world_state.node.function_name next_transaction_id = get_next_transaction_id() transaction = MessageCallTransaction( world_state=open_world_state, callee_account=open_world_state[callee_address], caller=BitVecVal(ATTACKER_ADDRESS, 256), identifier=next_transaction_id, call_data=SymbolicCalldata(next_transaction_id), gas_price=BitVec("gas_price{}".format(next_transaction_id), 256), call_value=BitVec("call_value{}".format(next_transaction_id), 256), origin=BitVec("origin{}".format(next_transaction_id), 256), call_data_type=CalldataType.SYMBOLIC, gas_limit=8000000, # block gas limit ) # the open states from last iterations are appended to work list here _setup_global_state_for_execution(laser_evm, transaction, last_func_called) laser_evm.exec(priority=priority, title=title, laser_obj=laser_evm) # Execute the new open states added to the work list in Instruction.jumpi_ function if title == 'RAW': for gs in laser_evm.second_work_list: laser_evm.work_list.append(gs) laser_evm.exec(priority=priority, title=title, laser_obj=laser_evm) elif title == 'WAR': for gs in laser_evm.third_work_list: laser_evm.work_list.append(gs) laser_evm.exec(priority=priority, title=title, laser_obj=laser_evm) elif title == 'WAW': for gs in laser_evm.forth_work_list: laser_evm.work_list.append(gs) laser_evm.exec(priority=priority, title=title, laser_obj=laser_evm)