def test_concrete_call_symbolic_to(): # arrange address = "0x10" active_account = Account(address) active_account.code = Disassembly("00") environment = Environment(active_account, None, None, None, None, None) state = GlobalState(None, environment, None) state.mstate.memory = ["placeholder", "calldata_bling_0"] node = Node("example") node.contract_name = "the contract name" node.function_name = "the function name" to = Variable("calldata_3", VarType.SYMBOLIC) meminstart = Variable(1, VarType.CONCRETE) call = Call(node, state, None, None, to, None) # act issues = _concrete_call(call, state, address, meminstart) # assert issue = issues[0] assert issue.address == address assert issue.contract == node.contract_name assert issue.function == node.function_name assert issue.title == "Call data forwarded with delegatecall()" assert issue.type == "Informational" assert ( issue.description == "This contract forwards its call data via DELEGATECALL in its fallback function." " This means that any function in the called contract can be executed." " Note that the callee contract will have access to the storage of the " "calling contract.\n DELEGATECALL target: calldata_3" )
def execute_create(): global last_state global created_contract_account if not last_state and not created_contract_account: code_raw = [] for i in range(len(contract_init_code) // 2): code_raw.append(int(contract_init_code[2 * i:2 * (i + 1)], 16)) calldata = ConcreteCalldata(0, code_raw) world_state = WorldState() account = world_state.create_account(balance=1000000, address=101) account.code = Disassembly("60a760006000f000") environment = Environment(account, None, calldata, None, None, None) og_state = GlobalState(world_state, environment, None, MachineState(gas_limit=8000000)) og_state.transaction_stack.append( (MessageCallTransaction(world_state=WorldState(), gas_limit=8000000), None)) laser = LaserEVM() states = [og_state] last_state = og_state for state in states: new_states, op_code = laser.execute_state(state) last_state = state if op_code == "STOP": break states.extend(new_states) created_contract_address = last_state.mstate.stack[-1].value created_contract_account = last_state.world_state.accounts[ created_contract_address] return last_state, created_contract_account
def test_delegate_call(sym_mock, concrete_mock, curr_instruction): # arrange # sym_mock = mocker.patch.object(delegatecall, "_symbolic_call") # concrete_mock = mocker.patch.object(delegatecall, "_concrete_call") sym_mock.return_value = [] concrete_mock.return_value = [] curr_instruction.return_value = {"address": "0x10"} active_account = Account("0x10") active_account.code = Disassembly("00") environment = Environment(active_account, None, None, None, None, None) state = GlobalState(None, environment, Node) state.mstate.memory = ["placeholder", "calldata_bling_0"] state.mstate.stack = [1, 2, 3] assert state.get_current_instruction() == {"address": "0x10"} node = Node("example") node.contract_name = "the contract name" node.function_name = "fallback" to = Variable("storage_1", VarType.SYMBOLIC) call = Call(node, state, None, "DELEGATECALL", to, None) statespace = MagicMock() statespace.calls = [call] # act execute(statespace) # assert assert concrete_mock.call_count == 1 assert sym_mock.call_count == 1
def get_state(): active_account = Account("0x0", code=Disassembly("60606040")) environment = Environment(active_account, None, None, None, None, None) state = GlobalState(None, environment, None, MachineState(gas_limit=8000000)) state.transaction_stack.append( (MessageCallTransaction(world_state=WorldState(), gas_limit=8000000), None) ) return state
def _get_global_state(): active_account = Account("0x0", code=Disassembly("60606040")) passive_account = Account("0x325345346564645654645", code=Disassembly("6060604061626364")) environment = Environment(active_account, None, None, None, None, None) world_state = WorldState() world_state.put_account(active_account) world_state.put_account(passive_account) return GlobalState(world_state, environment, None, MachineState(gas_limit=8000000))
def get_state(): world_state = WorldState() account = world_state.create_account(balance=10, address=101) account.code = Disassembly("60606040") environment = Environment(account, None, None, None, None, None) state = GlobalState(world_state, environment, None, MachineState(gas_limit=8000000)) state.transaction_stack.append( (MessageCallTransaction(world_state=WorldState(), gas_limit=8000000), None)) return state
def initial_global_state(self) -> GlobalState: """Initialize the execution environment.""" environment = Environment( self.callee_account, self.caller, self.call_data, self.gas_price, self.call_value, self.origin, self.code, ) return super().initial_global_state_from_environment( environment, active_function="constructor")
def initial_global_state(self) -> GlobalState: """Initialize the execution environment""" environment = Environment( self.callee_account, self.caller, self.call_data, self.gas_price, self.call_value, self.origin, code=self.code or self.callee_account.code, calldata_type=self.call_data_type, ) return super().initial_global_state_from_environment( environment, active_function="fallback")
def test_codecopy_concrete(): # Arrange active_account = Account("0x0", code=Disassembly("60606040")) environment = Environment(active_account, None, None, None, None, None) og_state = GlobalState(None, environment, None, MachineState(gas=10000000)) og_state.mstate.stack = [2, 2, 2] instruction = Instruction("codecopy", dynamic_loader=None) # Act new_state = instruction.evaluate(og_state)[0] # Assert assert new_state.mstate.memory[2] == 96 assert new_state.mstate.memory[3] == 64
def initial_global_state(self) -> GlobalState: """Initialize the execution environment""" environment = Environment( self.callee_account, self.caller, self.call_data, self.gas_price, self.call_value, self.origin, code=self.code or self.callee_account.code, calldata_type=self.call_data_type, ) global_state = GlobalState(self.world_state, environment, None) global_state.environment.active_function_name = "fallback" return global_state
def test_codecopy_concrete(): # Arrange active_account = Account("0x0", code=Disassembly("60606040")) environment = Environment(active_account, None, None, None, None, None) og_state = GlobalState(None, environment, None, MachineState(gas_limit=8000000)) og_state.transaction_stack.append( (MessageCallTransaction(world_state=WorldState(), gas_limit=8000000), None)) og_state.mstate.stack = [2, 2, 2] instruction = Instruction("codecopy", dynamic_loader=None) # Act new_state = instruction.evaluate(og_state)[0] # Assert assert new_state.mstate.memory[2] == 96 assert new_state.mstate.memory[3] == 64
def test_execute(mocker): active_account = Account("0x00") environment = Environment(active_account, None, None, None, None, None) state_1 = GlobalState(None, environment, None, MachineState(gas_limit=8000000)) state_1.mstate.stack = [1, 2] mocker.patch.object(state_1, "get_current_instruction") state_1.get_current_instruction.return_value = {"opcode": "PUSH"} state_2 = GlobalState(None, environment, None, MachineState(gas_limit=8000000)) state_2.mstate.stack = [1, 2, 3] mocker.patch.object(state_2, "get_current_instruction") state_2.get_current_instruction.return_value = {"opcode": "ADD"} node_1 = Node("Test contract") node_1.states = [state_1, state_2] state_3 = GlobalState(None, environment, None, MachineState(gas_limit=8000000)) state_3.mstate.stack = [1, 2] mocker.patch.object(state_3, "get_current_instruction") state_3.get_current_instruction.return_value = {"opcode": "ADD"} node_2 = Node("Test contract") node_2.states = [state_3] edge = Edge(node_1.uid, node_2.uid) statespace = LaserEVM(None) statespace.edges = [edge] statespace.nodes[node_1.uid] = node_1 statespace.nodes[node_2.uid] = node_2 # Act result = TaintRunner.execute(statespace, node_1, state_1, [True, True]) # Assert print(result) assert len(result.records) == 3 assert result.records[2].states == [] assert state_3 in result.records[1].states
def test_symbolic_call_storage_to(mocker): # arrange address = "0x10" active_account = Account(address) active_account.code = Disassembly("00") environment = Environment(active_account, None, None, None, None, None) state = GlobalState(None, environment, None) state.mstate.memory = ["placeholder", "calldata_bling_0"] node = Node("example") node.contract_name = "the contract name" node.function_name = "the function name" to = Variable("storage_1", VarType.SYMBOLIC) call = Call(node, state, None, "Type: ", to, None) mocker.patch.object(SymExecWrapper, "__init__", lambda x, y: None) statespace = SymExecWrapper(1) mocker.patch.object(statespace, "find_storage_write") statespace.find_storage_write.return_value = "Function name" # act issues = _symbolic_call(call, state, address, statespace) # assert issue = issues[0] assert issue.address == address assert issue.contract == node.contract_name assert issue.function == node.function_name assert issue.title == "Type: to a user-supplied address" assert issue.type == "Informational" assert ( issue.description == "This contract delegates execution to a contract address in storage slot 1." " This storage slot can be written to by calling the function `Function name`. " "Be aware that the called contract gets unrestricted access to this contract's state." )
def test_extcodecopy_fail(): # Arrange new_world_state = WorldState() new_account = new_world_state.create_account(balance=10, address=101) new_account.code = Disassembly("60616240") new_environment = Environment(new_account, None, None, None, None, None) state = GlobalState( new_world_state, new_environment, None, MachineState(gas_limit=8000000) ) state.transaction_stack.append( (MessageCallTransaction(world_state=WorldState(), gas_limit=8000000), None) ) state.mstate.stack = [2, 2, 2, symbol_factory.BitVecSym("FAIL", 256)] instruction = Instruction("extcodecopy", dynamic_loader=None) # Act new_state = instruction.evaluate(state)[0] # Assert assert new_state.mstate.stack == [] assert new_state.mstate.memory._memory == state.mstate.memory._memory
def test_extcodecopy(): # Arrange new_world_state = WorldState() new_account = new_world_state.create_account(balance=10, address=101) new_account.code = Disassembly("60616240") ext_account = new_world_state.create_account(balance=1000, address=121) ext_account.code = Disassembly("6040404040") new_environment = Environment(new_account, None, None, None, None, None) state = GlobalState( new_world_state, new_environment, None, MachineState(gas_limit=8000000) ) state.transaction_stack.append( (MessageCallTransaction(world_state=WorldState(), gas_limit=8000000), None) ) state.mstate.stack = [3, 0, 0, 121] instruction = Instruction("extcodecopy", dynamic_loader=None) # Act new_state = instruction.evaluate(state)[0] # Assert assert new_state.mstate.memory[0:3] == [96, 64, 64]
from mythril.laser.ethereum.state.machine_state import MachineState from mythril.laser.ethereum.state.global_state import GlobalState from mythril.laser.ethereum.state.world_state import WorldState from mythril.laser.ethereum.instructions import Instruction from mythril.laser.ethereum.transaction.transaction_models import MessageCallTransaction from mythril.support.support_utils import get_code_hash from mythril.laser.smt import symbol_factory # Arrange world_state = WorldState() account = world_state.create_account(balance=10, address=101) account.code = Disassembly("60606040") world_state.create_account(balance=10, address=1000) environment = Environment(account, None, None, None, None, None) og_state = GlobalState(world_state, environment, None, MachineState(gas_limit=8000000)) og_state.transaction_stack.append( (MessageCallTransaction(world_state=WorldState(), gas_limit=8000000), None)) instruction = Instruction("extcodehash", dynamic_loader=None) def test_extcodehash_no_account(): # If account does not exist, return 0 og_state.mstate.stack = [symbol_factory.BitVecVal(1, 256)] new_state = instruction.evaluate(og_state)[0] assert new_state.mstate.stack[-1] == 0