From d292ceb9edce68034f8784f9ae681f79131324c7 Mon Sep 17 00:00:00 2001 From: Nikhil Parasaram Date: Tue, 29 Oct 2019 20:28:05 +0000 Subject: [PATCH] Fixes regression (#1261) * Fix a regression * Handle new black format --- mythril/analysis/modules/integer.py | 2 +- mythril/ethereum/interface/leveldb/client.py | 4 +- mythril/laser/ethereum/call.py | 9 ++- mythril/laser/ethereum/instructions.py | 84 +++++++++++++++----- mythril/laser/ethereum/state/global_state.py | 2 +- mythril/laser/ethereum/svm.py | 10 ++- 6 files changed, 80 insertions(+), 31 deletions(-) diff --git a/mythril/analysis/modules/integer.py b/mythril/analysis/modules/integer.py index 78d93f31..2879a331 100644 --- a/mythril/analysis/modules/integer.py +++ b/mythril/analysis/modules/integer.py @@ -343,7 +343,7 @@ def _get_address_from_state(state): def _get_overflowunderflow_state_annotation( - state: GlobalState + state: GlobalState, ) -> OverUnderflowStateAnnotation: state_annotations = cast( List[OverUnderflowStateAnnotation], diff --git a/mythril/ethereum/interface/leveldb/client.py b/mythril/ethereum/interface/leveldb/client.py index 3373d3f1..c6289d1d 100644 --- a/mythril/ethereum/interface/leveldb/client.py +++ b/mythril/ethereum/interface/leveldb/client.py @@ -23,8 +23,8 @@ body_prefix = b"b" # body_prefix + num (uint64 big endian) + hash -> block body num_suffix = b"n" # header_prefix + num (uint64 big endian) + num_suffix -> hash block_hash_prefix = b"H" # block_hash_prefix + hash -> num (uint64 big endian) block_receipts_prefix = ( - b"r" -) # block_receipts_prefix + num (uint64 big endian) + hash -> block receipts + b"r" # block_receipts_prefix + num (uint64 big endian) + hash -> block receipts +) # known geth keys head_header_key = b"LastBlock" # head (latest) header hash # custom prefixes diff --git a/mythril/laser/ethereum/call.py b/mythril/laser/ethereum/call.py index 02dc6405..5d0672c9 100644 --- a/mythril/laser/ethereum/call.py +++ b/mythril/laser/ethereum/call.py @@ -42,9 +42,12 @@ def get_call_parameters( """ gas, to = global_state.mstate.pop(2) value = global_state.mstate.pop() if with_value else 0 - memory_input_offset, memory_input_size, memory_out_offset, memory_out_size = global_state.mstate.pop( - 4 - ) + ( + memory_input_offset, + memory_input_size, + memory_out_offset, + memory_out_size, + ) = global_state.mstate.pop(4) callee_address = get_callee_address(global_state, dynamic_loader, to) diff --git a/mythril/laser/ethereum/instructions.py b/mythril/laser/ethereum/instructions.py index 52a0dce0..a91acd8e 100644 --- a/mythril/laser/ethereum/instructions.py +++ b/mythril/laser/ethereum/instructions.py @@ -1858,9 +1858,15 @@ class Instruction: environment = global_state.environment try: - callee_address, callee_account, call_data, value, gas, memory_out_offset, memory_out_size = get_call_parameters( - global_state, self.dynamic_loader, True - ) + ( + callee_address, + callee_account, + call_data, + value, + gas, + memory_out_offset, + memory_out_size, + ) = get_call_parameters(global_state, self.dynamic_loader, True) if callee_account is not None and callee_account.code.bytecode == "": log.debug("The call is related to ether transfer between accounts") @@ -1939,9 +1945,15 @@ class Instruction: environment = global_state.environment try: - callee_address, callee_account, call_data, value, gas, _, _ = get_call_parameters( - global_state, self.dynamic_loader, True - ) + ( + callee_address, + callee_account, + call_data, + value, + gas, + _, + _, + ) = get_call_parameters(global_state, self.dynamic_loader, True) if callee_account is not None and callee_account.code.bytecode == "": log.debug("The call is related to ether transfer between accounts") sender = global_state.environment.active_account.address @@ -1988,9 +2000,15 @@ class Instruction: instr = global_state.get_current_instruction() try: - callee_address, _, _, value, _, memory_out_offset, memory_out_size = get_call_parameters( - global_state, self.dynamic_loader, True - ) + ( + callee_address, + _, + _, + value, + _, + memory_out_offset, + memory_out_size, + ) = get_call_parameters(global_state, self.dynamic_loader, True) except ValueError as e: log.debug( "Could not determine required parameters for call, putting fresh symbol on the stack. \n{}".format( @@ -2054,9 +2072,15 @@ class Instruction: environment = global_state.environment try: - callee_address, callee_account, call_data, value, gas, _, _ = get_call_parameters( - global_state, self.dynamic_loader - ) + ( + callee_address, + callee_account, + call_data, + value, + gas, + _, + _, + ) = get_call_parameters(global_state, self.dynamic_loader) if callee_account is not None and callee_account.code.bytecode == "": log.debug("The call is related to ether transfer between accounts") @@ -2104,9 +2128,15 @@ class Instruction: instr = global_state.get_current_instruction() try: - callee_address, _, _, value, _, memory_out_offset, memory_out_size = get_call_parameters( - global_state, self.dynamic_loader - ) + ( + callee_address, + _, + _, + value, + _, + memory_out_offset, + memory_out_size, + ) = get_call_parameters(global_state, self.dynamic_loader) except ValueError as e: log.debug( "Could not determine required parameters for call, putting fresh symbol on the stack. \n{}".format( @@ -2169,9 +2199,15 @@ class Instruction: instr = global_state.get_current_instruction() environment = global_state.environment try: - callee_address, callee_account, call_data, value, gas, memory_out_offset, memory_out_size = get_call_parameters( - global_state, self.dynamic_loader - ) + ( + callee_address, + callee_account, + call_data, + value, + gas, + memory_out_offset, + memory_out_size, + ) = get_call_parameters(global_state, self.dynamic_loader) if callee_account is not None and callee_account.code.bytecode == "": log.debug("The call is related to ether transfer between accounts") @@ -2225,9 +2261,15 @@ class Instruction: try: with_value = function_name is not "staticcall" - callee_address, callee_account, call_data, value, gas, memory_out_offset, memory_out_size = get_call_parameters( - global_state, self.dynamic_loader, with_value - ) + ( + callee_address, + callee_account, + call_data, + value, + gas, + memory_out_offset, + memory_out_size, + ) = get_call_parameters(global_state, self.dynamic_loader, with_value) except ValueError as e: log.debug( "Could not determine required parameters for {}, putting fresh symbol on the stack. \n{}".format( diff --git a/mythril/laser/ethereum/state/global_state.py b/mythril/laser/ethereum/state/global_state.py index 88d297c4..36aa26b2 100644 --- a/mythril/laser/ethereum/state/global_state.py +++ b/mythril/laser/ethereum/state/global_state.py @@ -102,7 +102,7 @@ class GlobalState: @property def current_transaction( - self + self, ) -> Union["MessageCallTransaction", "ContractCreationTransaction", None]: """ diff --git a/mythril/laser/ethereum/svm.py b/mythril/laser/ethereum/svm.py index 7967b0db..0404d885 100644 --- a/mythril/laser/ethereum/svm.py +++ b/mythril/laser/ethereum/svm.py @@ -354,9 +354,10 @@ class LaserEVM: return [new_global_state], op_code except TransactionEndSignal as end_signal: - transaction, return_global_state = end_signal.global_state.transaction_stack[ - -1 - ] + ( + transaction, + return_global_state, + ) = end_signal.global_state.transaction_stack[-1] log.debug("Ending transaction %s.", transaction) if return_global_state is None: @@ -366,6 +367,9 @@ class LaserEVM: ) and not end_signal.revert: check_potential_issues(global_state) end_signal.global_state.world_state.node = global_state.node + end_signal.global_state.world_state.node.constraints += ( + end_signal.global_state.mstate.constraints + ) self._add_world_state(end_signal.global_state) new_global_states = []