Merge branch 'develop' into enhance/tests

pull/946/head
Bernhard Mueller 6 years ago committed by GitHub
commit 02f7f15b99
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 4
      README.md
  2. 16
      mythril/analysis/modules/base.py
  3. 5
      mythril/analysis/modules/delegatecall.py
  4. 7
      mythril/analysis/modules/dependence_on_predictable_vars.py
  5. 3
      mythril/analysis/modules/deprecated_ops.py
  6. 3
      mythril/analysis/modules/dos.py
  7. 3
      mythril/analysis/modules/ether_thief.py
  8. 3
      mythril/analysis/modules/exceptions.py
  9. 3
      mythril/analysis/modules/external_calls.py
  10. 2
      mythril/analysis/modules/integer.py
  11. 3
      mythril/analysis/modules/multiple_sends.py
  12. 3
      mythril/analysis/modules/state_change_external_calls.py
  13. 3
      mythril/analysis/modules/suicide.py
  14. 3
      mythril/analysis/modules/unchecked_retval.py
  15. 6
      mythril/analysis/security.py
  16. 4
      mythril/interfaces/cli.py
  17. 6
      mythril/laser/ethereum/svm.py

@ -12,7 +12,9 @@
[![Pypi Installs](https://pepy.tech/badge/mythril)](https://pepy.tech/project/mythril)
[![DockerHub Pulls](https://img.shields.io/docker/pulls/mythril/myth.svg?label=DockerHub Pulls)](https://cloud.docker.com/u/mythril/repository/docker/mythril/myth)
Mythril is an open-source security analysis tool for Ethereum smart contracts. It uses symbolic analysis, taint analysis and control flow checking to detect a variety of security vulnerabilities. It's also used in the backend of [MythX API](https://mythx.io). If you are a smart contract developer, we recommend using [MythX tools](https://github.com/b-mueller/awesome-mythx-smart-contract-security) which are optimized for usability and cover a wider range of security issues.
Mythril is a security analysis tool for EVM bytecode. It detects security vulnerabilities in smart contracts built for Ethereum, Quorum, Vechain, Roostock, Tron and other EVM-compatible blockchains. It uses symbolic execution, SMT solving and taint analysis detect a variety of security vulnerabilities. It's also used (in combination with other tools and techniques) in the [MythX](https://mythx.io) security analysis platform.
If you are a smart contract developer, we recommend using [MythX tools](https://github.com/b-mueller/awesome-mythx-smart-contract-security) which are optimized for usability and cover a wider range of security issues.
Whether you want to contribute, need support, or want to learn what we have cooking for the future, our [Discord server](https://discord.gg/E3YrVtG) will serve your needs.

@ -49,12 +49,26 @@ class DetectionModule:
"""
self._issues = []
def execute(self, statespace):
def execute(self, statespace) -> None:
"""The entry point for execution, which is being called by Mythril.
:param statespace:
:return:
"""
log.debug("Entering analysis module: {}".format(self.__class__.__name__))
self._execute(statespace)
log.debug("Exiting analysis module: {}".format(self.__class__.__name__))
def _execute(self, statespace):
"""Module main method (override this)
:param statespace:
:return:
"""
raise NotImplementedError()
def __repr__(self) -> str:

@ -12,7 +12,6 @@ from mythril.exceptions import UnsatError
from mythril.laser.ethereum.state.annotation import StateAnnotation
from mythril.laser.ethereum.state.global_state import GlobalState
from mythril.laser.smt import symbol_factory, UGT
from mythril.laser.smt import symbol_factory, UGT
log = logging.getLogger(__name__)
@ -80,15 +79,13 @@ class DelegateCallModule(DetectionModule):
pre_hooks=["DELEGATECALL", "RETURN", "STOP"],
)
def execute(self, state: GlobalState) -> list:
def _execute(self, state: GlobalState) -> None:
"""
:param state:
:return:
"""
log.debug("Executing module: DELEGATE_CALL")
self._issues.extend(_analyze_states(state))
return self.issues
def _analyze_states(state: GlobalState) -> List[Issue]:

@ -21,7 +21,7 @@ final_ops = ["CALL", "SUICIDE", "STOP", "RETURN"]
def is_prehook() -> bool:
"""Check if we are in prehook. One of Bernhard's trademark hacks!"""
return "pre_hook" in traceback.format_stack()[-4]
return "pre_hook" in traceback.format_stack()[-5]
class PredictableValueAnnotation:
@ -64,17 +64,14 @@ class PredictableDependenceModule(DetectionModule):
post_hooks=["BLOCKHASH"] + predictable_ops,
)
def execute(self, state: GlobalState) -> list:
def _execute(self, state: GlobalState) -> None:
"""
:param state:
:return:
"""
log.debug("Executing module: DEPENDENCE_ON_PREDICTABLE_VARS")
self._issues.extend(_analyze_states(state))
return self.issues
def _analyze_states(state: GlobalState) -> list:

@ -76,14 +76,13 @@ class DeprecatedOperationsModule(DetectionModule):
pre_hooks=["ORIGIN", "CALLCODE"],
)
def execute(self, state: GlobalState):
def _execute(self, state: GlobalState) -> None:
"""
:param state:
:return:
"""
self._issues.extend(_analyze_state(state))
return self.issues
detector = DeprecatedOperationsModule()

@ -43,13 +43,12 @@ class DOS(DetectionModule):
"""Keeps track of how often jump destinations are reached."""
self._jumpdest_count = {} # type: Dict[object, dict]
def execute(self, state: GlobalState) -> None:
def _execute(self, state: GlobalState) -> None:
"""
:param state:
:return:
"""
log.debug("Executing module: DOS")
self._issues.extend(self._analyze_states(state))

@ -51,14 +51,13 @@ class EtherThief(DetectionModule):
super().reset_module()
self._cache_addresses = {}
def execute(self, state: GlobalState):
def _execute(self, state: GlobalState) -> None:
"""
:param state:
:return:
"""
self._issues.extend(self._analyze_state(state))
return self.issues
def _analyze_state(self, state):
"""

@ -72,14 +72,13 @@ class ReachableExceptionsModule(DetectionModule):
pre_hooks=["ASSERT_FAIL"],
)
def execute(self, state: GlobalState) -> list:
def _execute(self, state: GlobalState) -> None:
"""
:param state:
:return:
"""
self._issues.extend(_analyze_state(state))
return self.issues
detector = ReachableExceptionsModule()

@ -137,14 +137,13 @@ class ExternalCalls(DetectionModule):
pre_hooks=["CALL"],
)
def execute(self, state: GlobalState):
def _execute(self, state: GlobalState) -> None:
"""
:param state:
:return:
"""
self._issues.extend(_analyze_state(state))
return self.issues
detector = ExternalCalls()

@ -84,7 +84,7 @@ class IntegerOverflowUnderflowModule(DetectionModule):
self._overflow_cache = {}
self._underflow_cache = {}
def execute(self, state: GlobalState):
def _execute(self, state: GlobalState) -> None:
"""Executes analysis module for integer underflow and integer overflow.
:param state: Statespace to analyse

@ -43,9 +43,8 @@ class MultipleSendsModule(DetectionModule):
],
)
def execute(self, state: GlobalState):
def _execute(self, state: GlobalState) -> None:
self._issues.extend(_analyze_state(state))
return self.issues
def _analyze_state(state: GlobalState):

@ -84,9 +84,8 @@ class StateChange(DetectionModule):
],
)
def execute(self, state: GlobalState):
def _execute(self, state: GlobalState) -> None:
self._issues.extend(self._analyze_state(state))
return self.issues
@staticmethod
def _add_external_call(global_state: GlobalState) -> None:

@ -37,14 +37,13 @@ class SuicideModule(DetectionModule):
super().reset_module()
self._cache_address = {}
def execute(self, state: GlobalState):
def _execute(self, state: GlobalState) -> None:
"""
:param state:
:return:
"""
self._issues.extend(self._analyze_state(state))
return self.issues
def _analyze_state(self, state):
log.info("Suicide module: Analyzing suicide instruction")

@ -49,14 +49,13 @@ class UncheckedRetvalModule(DetectionModule):
post_hooks=["CALL", "DELEGATECALL", "STATICCALL", "CALLCODE"],
)
def execute(self, state: GlobalState) -> list:
def _execute(self, state: GlobalState) -> None:
"""
:param state:
:return:
"""
self._issues.extend(_analyze_state(state))
return self.issues
def _analyze_state(state: GlobalState) -> list:

@ -52,6 +52,10 @@ def get_detection_modules(entrypoint, include_modules=()):
:param include_modules:
:return:
"""
module = importlib.import_module("mythril.analysis.modules.base")
module.log.setLevel(log.level)
include_modules = list(include_modules)
_modules = []
@ -62,12 +66,14 @@ def get_detection_modules(entrypoint, include_modules=()):
module = importlib.import_module(
"mythril.analysis.modules." + module_name
)
module.log.setLevel(log.level)
if module.detector.entrypoint == entrypoint:
_modules.append(module)
else:
for module_name in include_modules:
module = importlib.import_module("mythril.analysis.modules." + module_name)
if module.__name__ != "base" and module.detector.entrypoint == entrypoint:
module.log.setLevel(log.level)
_modules.append(module)
log.info("Found %s detection modules", len(_modules))

@ -24,8 +24,6 @@ from mythril.mythril import (
)
from mythril.version import VERSION
# logging.basicConfig(level=logging.DEBUG)
log = logging.getLogger(__name__)
@ -216,7 +214,7 @@ def create_parser(parser: argparse.ArgumentParser) -> None:
options.add_argument(
"--execution-timeout",
type=int,
default=600,
default=86400,
help="The amount of seconds to spend on symbolic execution",
)
options.add_argument(

@ -177,8 +177,9 @@ class LaserEVM:
:param address: Address of the contract
:return:
"""
self.time = datetime.now()
for i in range(self.transaction_count):
self.time = datetime.now()
log.info(
"Starting message call transaction, iteration: {}, {} initial states".format(
i, len(self.open_states)
@ -210,8 +211,7 @@ class LaserEVM:
if (
self.execution_timeout
and self.time
+ timedelta(seconds=self.execution_timeout / self.transaction_count)
and self.time + timedelta(seconds=self.execution_timeout)
<= datetime.now()
and not create
):

Loading…
Cancel
Save