diff --git a/mythril/disassembler/disassembly.py b/mythril/disassembler/disassembly.py index b7414529..de1c9bad 100644 --- a/mythril/disassembler/disassembly.py +++ b/mythril/disassembler/disassembly.py @@ -12,11 +12,11 @@ class Disassembly: self.addr_to_func = {} self.bytecode = code - signatures = Signatures(enable_online_lookkup=True) # control if you want to have online sighash lookups + signatures = Signatures(enable_online_lookup=True) # control if you want to have online sighash lookups try: signatures.open() # open from default locations except FileNotFoundError: - logging.info("Missing function signature file. Resolving of function names from disabled.") + logging.info("Missing function signature file. Resolving of function names from signature file disabled.") # Parse jump table & resolve function names @@ -25,7 +25,15 @@ class Disassembly: for i in jmptable_indices: func_hash = self.instruction_list[i]['argument'] try: - func_name = signatures.get(func_hash) # tries local cache, file and optional online lookup + # tries local cache, file and optional online lookup + # may return more than one function signature. since we cannot probe for the correct one we'll use the first + func_names = signatures.get(func_hash) + if len(func_names) > 1: + # ambigious result + func_name = "**ambiguous** %s"%func_names[0] # return first hit but note that result was ambiguous + else: + # only one item + func_name = func_names[0] except KeyError: func_name = "_function_" + func_hash diff --git a/mythril/support/signatures.py b/mythril/support/signatures.py index 5fb21737..04fde734 100644 --- a/mythril/support/signatures.py +++ b/mythril/support/signatures.py @@ -56,9 +56,9 @@ def add_signatures_from_file(file, sigs={}): class Signatures(object): - def __init__(self, enable_online_lookkup=True): + def __init__(self, enable_online_lookup=True): self.signatures = {} # signatures in-mem cache - self.enable_online_lookup =enable_online_lookkup # enable online funcsig resolving + self.enable_online_lookup =enable_online_lookup # enable online funcsig resolving def open(self, path=None): if not path: @@ -91,14 +91,17 @@ class Signatures(object): :return: list of function signatures """ if not self.signatures.get(sighash) and self.enable_online_lookup: - self.signatures[sighash] = Signatures.lookup_online(sighash) # might return multiple sigs - return self.signatures.get(sighash) + funcsigs = Signatures.lookup_online(sighash) # might return multiple sigs + if funcsigs: + # only store if we get at least one result + self.signatures[sighash] = funcsigs + return self.signatures[sighash] # raise keyerror @staticmethod def lookup_online(sighash): """ - Lookup function signatures from 4bytes.directory. + Lookup function signatures from 4byte.directory. //tintinweb: the smart-contract-sanctuary project dumps contracts from etherscan.io and feeds them into 4bytes.directory. https://github.com/tintinweb/smart-contract-sanctuary