diff --git a/mythril/analysis/module/module_helpers.py b/mythril/analysis/module/module_helpers.py index 9099ef9d3..f6bc96229 100644 --- a/mythril/analysis/module/module_helpers.py +++ b/mythril/analysis/module/module_helpers.py @@ -2,5 +2,12 @@ def is_prehook() -> bool: - """Check if we are in prehook. One of Bernhard's trademark hacks!""" + """Check if we are in prehook. One of Bernhard's trademark hacks! + Let's leave it to this for now, unless we need to check prehook for + a lot more modules. + """ + + assert ("pre_hook" in traceback.format_stack()[-5]) or ( + "post_hook" in traceback.format_stack()[-5] + ) return "pre_hook" in traceback.format_stack()[-5] diff --git a/mythril/laser/ethereum/call.py b/mythril/laser/ethereum/call.py index a3c359cb9..173687635 100644 --- a/mythril/laser/ethereum/call.py +++ b/mythril/laser/ethereum/call.py @@ -179,6 +179,7 @@ def get_call_data( else memory_size ), ) + if memory_size.symbolic: memory_size = SYMBOLIC_CALLDATA_SIZE try: diff --git a/mythril/laser/ethereum/instructions.py b/mythril/laser/ethereum/instructions.py index 86b235f45..40cf81cb9 100644 --- a/mythril/laser/ethereum/instructions.py +++ b/mythril/laser/ethereum/instructions.py @@ -3,7 +3,7 @@ import logging from copy import copy, deepcopy -from typing import cast, Callable, List, Union +from typing import cast, Callable, List, Union, Tuple from mythril.laser.smt import ( Extract, @@ -306,6 +306,7 @@ def push_(self, global_state: GlobalState) -> List[GlobalState]: new_value = Concat( symbol_factory.BitVecVal(0, 256 - new_value.size()), new_value ) + global_state.mstate.stack.append(new_value) else: @@ -1076,7 +1077,6 @@ def codecopy_(self, global_state: GlobalState) -> List[GlobalState]: if code[0:2] == "0x": code = code[2:] code_size = len(code) // 2 - if isinstance(global_state.current_transaction, ContractCreationTransaction): # Treat creation code after the expected disassembly as calldata. # This is a slightly hacky way to ensure that symbolic constructor @@ -1168,7 +1168,7 @@ def extcodesize_(self, global_state: GlobalState) -> List[GlobalState]: @staticmethod def _code_copy_helper( - code: str, + code: Union[str, Tuple], memory_offset: Union[int, BitVec], code_offset: Union[int, BitVec], size: Union[int, BitVec], @@ -1218,14 +1218,25 @@ def _code_copy_helper( code = code[2:] for i in range(concrete_size): - if 2 * (concrete_code_offset + i + 1) > len(code): - break - global_state.mstate.memory[concrete_memory_offset + i] = int( - code[ - 2 * (concrete_code_offset + i) : 2 * (concrete_code_offset + i + 1) - ], - 16, - ) + if isinstance(code, str): + if 2 * (concrete_code_offset + i + 1) > len(code): + break + + global_state.mstate.memory[concrete_memory_offset + i] = int( + code[ + 2 + * (concrete_code_offset + i) : 2 + * (concrete_code_offset + i + 1) + ], + 16, + ) + else: + if (concrete_code_offset + i + 1) > len(code): + break + + global_state.mstate.memory[concrete_memory_offset + i] = code[ + concrete_code_offset + i + ] return [global_state] @@ -1717,12 +1728,11 @@ def _create_transaction_helper( world_state = global_state.world_state call_data = get_call_data(global_state, mem_offset, mem_offset + mem_size) - code_raw = [] code_end = call_data.size size = call_data.size if isinstance(size, BitVec): - # This should be fine because of the below check + # Other size restriction checks handle this if size.symbolic: size = 10 ** 5 else: diff --git a/mythril/laser/plugin/plugins/coverage/coverage_plugin.py b/mythril/laser/plugin/plugins/coverage/coverage_plugin.py index 523d27fa6..cf123e2dd 100644 --- a/mythril/laser/plugin/plugins/coverage/coverage_plugin.py +++ b/mythril/laser/plugin/plugins/coverage/coverage_plugin.py @@ -53,10 +53,12 @@ def stop_sym_exec_hook(): cov_percentage = 0 else: cov_percentage = sum(code_cov[1]) / float(code_cov[0]) * 100 - + string_code = code + if type(code) == tuple: + string_code = bytearray(code).hex() log.info( "Achieved {:.2f}% coverage for code: {}".format( - cov_percentage, code + cov_percentage, string_code ) )