From df6329c4f819cb06864b9b72e3c595fbca2cc982 Mon Sep 17 00:00:00 2001 From: Evan Sultanik Date: Thu, 27 Jun 2019 22:35:52 -0400 Subject: [PATCH 1/5] The newest versions of Truffle get confused if this file is present (#62) --- examples/BrokenMetaCoin/truffle-config.js | 4 ---- 1 file changed, 4 deletions(-) delete mode 100644 examples/BrokenMetaCoin/truffle-config.js diff --git a/examples/BrokenMetaCoin/truffle-config.js b/examples/BrokenMetaCoin/truffle-config.js deleted file mode 100644 index a6330d6..0000000 --- a/examples/BrokenMetaCoin/truffle-config.js +++ /dev/null @@ -1,4 +0,0 @@ -module.exports = { - // See - // to customize your Truffle configuration! -}; From 06f96c4896835149065f2ff0c89f92c43d48e7cd Mon Sep 17 00:00:00 2001 From: Evan Sultanik Date: Thu, 27 Jun 2019 22:53:50 -0400 Subject: [PATCH 2/5] Add a closure to ensure `self` makes it into the dynamically added function --- etheno/manticoreutils.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/etheno/manticoreutils.py b/etheno/manticoreutils.py index df53eae..8809c7e 100644 --- a/etheno/manticoreutils.py +++ b/etheno/manticoreutils.py @@ -50,8 +50,10 @@ class StopAtDepth(Detector): def __init__(self, max_depth): self.max_depth = max_depth - def will_start_run_callback(self, *args): - with self.manticore.locked_context('seen_rep', dict) as reps: + stop_at_death = self + + def will_start_run_callback(*args): + with stop_at_death.manticore.locked_context('seen_rep', dict) as reps: reps.clear() # this callback got renamed to `will_run_callback` in Manticore 0.3.0 @@ -66,7 +68,7 @@ def will_decode_instruction_callback(self, state, pc): world = state.platform with self.manticore.locked_context('seen_rep', dict) as reps: item = (world.current_transaction.sort == 'CREATE', world.current_transaction.address, pc) - if not item in reps: + if item not in reps: reps[item] = 0 reps[item] += 1 if reps[item] > self.max_depth: From 31806f9429a91ed6c58ae12c7f490a04e050778b Mon Sep 17 00:00:00 2001 From: Evan Sultanik Date: Thu, 27 Jun 2019 23:11:12 -0400 Subject: [PATCH 3/5] Disable currently broken Manticore detectors --- etheno/manticoreutils.py | 31 +++++++++++++++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) diff --git a/etheno/manticoreutils.py b/etheno/manticoreutils.py index 8809c7e..22455fb 100644 --- a/etheno/manticoreutils.py +++ b/etheno/manticoreutils.py @@ -33,15 +33,42 @@ def manticore_is_new_enough(*required_version): return True +"""Detectors that should not be included in the results from `get_detectors()` (e.g., because they are buggy)""" +if manticore_is_new_enough(0, 2, 3): + # At some point after Manticore 0.2.2, these all stopped working: + DETECTOR_BLACKLIST = { + manticore.ethereum.detectors.DetectDelegatecall, + manticore.ethereum.detectors.DetectEnvInstruction, + manticore.ethereum.detectors.DetectExternalCallAndLeak, + manticore.ethereum.detectors.DetectIntegerOverflow, + manticore.ethereum.detectors.DetectInvalid, + manticore.ethereum.detectors.DetectRaceCondition, + manticore.ethereum.detectors.DetectReentrancyAdvanced, + manticore.ethereum.detectors.DetectReentrancySimple, + manticore.ethereum.detectors.DetectSuicidal, + manticore.ethereum.detectors.DetectUninitializedMemory, + manticore.ethereum.detectors.DetectUninitializedStorage, + manticore.ethereum.detectors.DetectUnusedRetVal + } +else: + DETECTOR_BLACKLIST = set() + + def get_detectors(): for name, obj in inspect.getmembers(manticore.ethereum.detectors): - if inspect.isclass(obj) and issubclass(obj, manticore.ethereum.detectors.Detector) and obj != manticore.ethereum.detectors.Detector: + if inspect.isclass(obj)\ + and issubclass(obj, manticore.ethereum.detectors.Detector)\ + and obj != manticore.ethereum.detectors.Detector\ + and obj not in DETECTOR_BLACKLIST: yield obj def register_all_detectors(manticore): for detector in get_detectors(): - manticore.register_detector(detector()) + try: + manticore.register_detector(detector()) + except Exception as e: + manticore.logger.warning(f"Unable to register detector {detector!r}: {e!s}") class StopAtDepth(Detector): From d96d255f60418491a4f3309162450d90a5094372 Mon Sep 17 00:00:00 2001 From: Evan Sultanik Date: Thu, 27 Jun 2019 23:25:02 -0400 Subject: [PATCH 4/5] `is_shutdown` was renamed `is_killed` in Manticore 0.3.0 (#62) --- etheno/manticoreclient.py | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/etheno/manticoreclient.py b/etheno/manticoreclient.py index cea87e8..21c99b2 100644 --- a/etheno/manticoreclient.py +++ b/etheno/manticoreclient.py @@ -36,6 +36,7 @@ def manticoreimport(name, *args, **kwargs): from . import threadwrapper from .client import EthenoClient, jsonrpc, DATA, QUANTITY from .etheno import _CONTROLLER +from .manticoreutils import manticore_is_new_enough def encode_hex(data): if data is None: @@ -139,15 +140,24 @@ def eth_getTransactionReceipt(self, tx_hash, rpc_client_result = None): def multi_tx_analysis(self, contract_address = None, tx_limit=None, tx_use_coverage=True, args=None): if contract_address is None: for contract_address in self.contracts: - self.multi_tx_analysis(contract_address = contract_address, tx_limit = tx_limit, tx_use_coverage = tx_use_coverage, args = args) + self.multi_tx_analysis( + contract_address=contract_address, + tx_limit=tx_limit, + tx_use_coverage=tx_use_coverage, + args=args + ) return tx_account = self.etheno.accounts - prev_coverage = 0 current_coverage = 0 tx_no = 0 - while (current_coverage < 100 or not tx_use_coverage) and not self.manticore.is_shutdown(): + if manticore_is_new_enough(0, 3, 0): + shutdown_test = 'is_killed' + else: + shutdown_test = 'is_shutdown' + + while (current_coverage < 100 or not tx_use_coverage) and not getattr(self.manticore, shutdown_test)(): try: self.logger.info("Starting symbolic transaction: %d" % tx_no) From c783d68c9e5e2da39ebc0f4c9bc1a2033ac3e6c5 Mon Sep 17 00:00:00 2001 From: Evan Sultanik Date: Thu, 27 Jun 2019 23:30:04 -0400 Subject: [PATCH 5/5] `count_running_states` was removed in Manticore v0.3.0 (#62) --- etheno/manticoreclient.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/etheno/manticoreclient.py b/etheno/manticoreclient.py index 21c99b2..0c3355d 100644 --- a/etheno/manticoreclient.py +++ b/etheno/manticoreclient.py @@ -30,6 +30,7 @@ def manticoreimport(name, *args, **kwargs): # ####END#### from manticore.ethereum import ManticoreEVM +from manticore.exceptions import NoAliveStates import manticore from . import logger @@ -168,7 +169,11 @@ def multi_tx_analysis(self, contract_address = None, tx_limit=None, tx_use_cover address=contract_address, data=symbolic_data, value=symbolic_value) - self.logger.info("%d alive states, %d terminated states" % (self.manticore.count_running_states(), self.manticore.count_terminated_states())) + if manticore_is_new_enough(0, 3, 0): + # TODO: find the equivalent functions to get state counts in v0.3.0 + pass + else: + self.logger.info("%d alive states, %d terminated states" % (self.manticore.count_running_states(), self.manticore.count_terminated_states())) except NoAliveStates: break