result to online lookup can be ambiguous. use first item and note this

in disassembly
pull/308/head
tintinweb 7 years ago
parent 83c5eca66b
commit cdd2738397
  1. 14
      mythril/disassembler/disassembly.py
  2. 13
      mythril/support/signatures.py

@ -12,11 +12,11 @@ class Disassembly:
self.addr_to_func = {} self.addr_to_func = {}
self.bytecode = code 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: try:
signatures.open() # open from default locations signatures.open() # open from default locations
except FileNotFoundError: 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 # Parse jump table & resolve function names
@ -25,7 +25,15 @@ class Disassembly:
for i in jmptable_indices: for i in jmptable_indices:
func_hash = self.instruction_list[i]['argument'] func_hash = self.instruction_list[i]['argument']
try: 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: except KeyError:
func_name = "_function_" + func_hash func_name = "_function_" + func_hash

@ -56,9 +56,9 @@ def add_signatures_from_file(file, sigs={}):
class Signatures(object): class Signatures(object):
def __init__(self, enable_online_lookkup=True): def __init__(self, enable_online_lookup=True):
self.signatures = {} # signatures in-mem cache 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): def open(self, path=None):
if not path: if not path:
@ -91,14 +91,17 @@ class Signatures(object):
:return: list of function signatures :return: list of function signatures
""" """
if not self.signatures.get(sighash) and self.enable_online_lookup: if not self.signatures.get(sighash) and self.enable_online_lookup:
self.signatures[sighash] = Signatures.lookup_online(sighash) # might return multiple sigs funcsigs = Signatures.lookup_online(sighash) # might return multiple sigs
return self.signatures.get(sighash) if funcsigs:
# only store if we get at least one result
self.signatures[sighash] = funcsigs
return self.signatures[sighash] # raise keyerror
@staticmethod @staticmethod
def lookup_online(sighash): 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 //tintinweb: the smart-contract-sanctuary project dumps contracts from etherscan.io and feeds them into
4bytes.directory. 4bytes.directory.
https://github.com/tintinweb/smart-contract-sanctuary https://github.com/tintinweb/smart-contract-sanctuary

Loading…
Cancel
Save