Add --no-onchain-storage-access flag

pull/646/head
Nikhil Parasaram 6 years ago
parent e260db5056
commit 3aeaf59bea
  1. 10
      mythril/interfaces/cli.py
  2. 6
      mythril/laser/ethereum/call.py
  3. 4
      mythril/laser/ethereum/instructions.py
  4. 2
      mythril/laser/ethereum/state.py
  5. 9
      mythril/mythril.py
  6. 10
      mythril/support/loader.py

@ -90,6 +90,11 @@ def main():
action="store_true", action="store_true",
help="auto-load dependencies from the blockchain", help="auto-load dependencies from the blockchain",
) )
inputs.add_argument(
"--no-onchain-storage-access",
action="store_true",
help="turns off getting the data from onchain contracts",
)
outputs = parser.add_argument_group("output formats") outputs = parser.add_argument_group("output formats")
outputs.add_argument( outputs.add_argument(
@ -268,10 +273,11 @@ def main():
mythril = Mythril( mythril = Mythril(
solv=args.solv, solv=args.solv,
dynld=args.dynld, dynld=args.dynld,
onchain_storage_access=(not args.no_onchain_storage_access),
solc_args=args.solc_args, solc_args=args.solc_args,
enable_online_lookup=args.query_signature, enable_online_lookup=args.query_signature,
) )
if args.dynld and not (args.rpc or args.i): if args.dynld or not args.no_onchain_storage_access and not (args.rpc or args.i):
mythril.set_api_from_config_path() mythril.set_api_from_config_path()
if args.address: if args.address:
@ -280,7 +286,7 @@ def main():
mythril.set_api_rpc_infura() mythril.set_api_rpc_infura()
elif args.rpc: elif args.rpc:
mythril.set_api_rpc(rpc=args.rpc, rpctls=args.rpctls) mythril.set_api_rpc(rpc=args.rpc, rpctls=args.rpctls)
elif not args.dynld: elif not (args.dynld or not args.no_onchain_storage_access):
mythril.set_api_rpc_localhost() mythril.set_api_rpc_localhost()
elif args.search or args.contract_hash_to_address: elif args.search or args.contract_hash_to_address:
# Open LevelDB if necessary # Open LevelDB if necessary

@ -122,9 +122,9 @@ def get_callee_account(global_state, callee_address, dynamic_loader):
try: try:
code = dynamic_loader.dynld(environment.active_account.address, callee_address) code = dynamic_loader.dynld(environment.active_account.address, callee_address)
except Exception: except ValueError as error:
logging.debug("Unable to execute dynamic loader.") logging.debug("Unable to execute dynamic loader because: {}".format(error.message))
raise ValueError() raise ValueError(error.message)
if code is None: if code is None:
logging.debug("No code returned, not a contract account?") logging.debug("No code returned, not a contract account?")
raise ValueError() raise ValueError()

@ -701,8 +701,8 @@ class Instruction:
try: try:
code = self.dynamic_loader.dynld(environment.active_account.address, addr) code = self.dynamic_loader.dynld(environment.active_account.address, addr)
except Exception as e: except ValueError as e:
logging.info("error accessing contract storage due to: " + str(e)) logging.info("error accessing contract storage due to: " + str(e.message))
state.stack.append(global_state.new_bitvec("extcodesize_" + str(addr), 256)) state.stack.append(global_state.new_bitvec("extcodesize_" + str(addr), 256))
return [global_state] return [global_state]

@ -133,7 +133,7 @@ class Storage:
try: try:
return self._storage[item] return self._storage[item]
except KeyError: except KeyError:
if self.address and int(self.address[2:], 16) != 0 and self.dynld: if self.address and int(self.address[2:], 16) != 0 and (self.dynld and self.dynld.storage_loading):
try: try:
self._storage[item] = int( self._storage[item] = int(
self.dynld.read_storage( self.dynld.read_storage(

@ -78,12 +78,13 @@ class Mythril(object):
""" """
def __init__( def __init__(
self, solv=None, solc_args=None, dynld=False, enable_online_lookup=False self, solv=None, solc_args=None, dynld=False, enable_online_lookup=False, onchain_storage_access=True
): ):
self.solv = solv self.solv = solv
self.solc_args = solc_args self.solc_args = solc_args
self.dynld = dynld self.dynld = dynld
self.onchain_storage_access=onchain_storage_access
self.enable_online_lookup = enable_online_lookup self.enable_online_lookup = enable_online_lookup
self.mythril_dir = self._init_mythril_dir() self.mythril_dir = self._init_mythril_dir()
@ -411,7 +412,7 @@ class Mythril(object):
contract, contract,
address, address,
strategy, strategy,
dynloader=DynLoader(self.eth) if self.dynld else None, dynloader=DynLoader(self.eth, storage_loading=self.onchain_storage_access, contract_loading=self.dynld),
max_depth=max_depth, max_depth=max_depth,
execution_timeout=execution_timeout, execution_timeout=execution_timeout,
create_timeout=create_timeout, create_timeout=create_timeout,
@ -434,7 +435,7 @@ class Mythril(object):
contract, contract,
address, address,
strategy, strategy,
dynloader=DynLoader(self.eth) if self.dynld else None, dynloader=DynLoader(self.eth, storage_loading=self.onchain_storage_access, contract_loading=self.dynld),
max_depth=max_depth, max_depth=max_depth,
execution_timeout=execution_timeout, execution_timeout=execution_timeout,
create_timeout=create_timeout, create_timeout=create_timeout,
@ -460,7 +461,7 @@ class Mythril(object):
contract, contract,
address, address,
strategy, strategy,
dynloader=DynLoader(self.eth) if self.dynld else None, dynloader=DynLoader(self.eth, storage_loading=self.onchain_storage_access, contract_loading=self.dynld),
max_depth=max_depth, max_depth=max_depth,
execution_timeout=execution_timeout, execution_timeout=execution_timeout,
create_timeout=create_timeout, create_timeout=create_timeout,

@ -4,12 +4,17 @@ import re
class DynLoader: class DynLoader:
def __init__(self, eth): def __init__(self, eth, contract_loading=True, storage_loading=True):
self.eth = eth self.eth = eth
self.storage_cache = {} self.storage_cache = {}
self.contract_loading = contract_loading
self.storage_loading = storage_loading
def read_storage(self, contract_address, index): def read_storage(self, contract_address, index):
if not self.storage_loading:
raise Exception('Cannot load from the storage when the storage_loading flag is false')
try: try:
contract_ref = self.storage_cache[contract_address] contract_ref = self.storage_cache[contract_address]
data = contract_ref[index] data = contract_ref[index]
@ -36,6 +41,9 @@ class DynLoader:
def dynld(self, contract_address, dependency_address): def dynld(self, contract_address, dependency_address):
if not self.contract_loading:
raise ValueError('Cannot load contract when contract_loading flag is false')
logging.info( logging.info(
"Dynld at contract " + contract_address + ": " + dependency_address "Dynld at contract " + contract_address + ": " + dependency_address
) )

Loading…
Cancel
Save