Skip to content

Commit

Permalink
Merge pull request #67 from crytic/62-fix-examples
Browse files Browse the repository at this point in the history
Fixes the BrokenMetaCoin example
  • Loading branch information
ESultanik authored Jun 28, 2019
2 parents 8e474c0 + c783d68 commit 4d9a8f0
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 13 deletions.
23 changes: 19 additions & 4 deletions etheno/manticoreclient.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,14 @@ def manticoreimport(name, *args, **kwargs):
# ####END####

from manticore.ethereum import ManticoreEVM
from manticore.exceptions import NoAliveStates
import manticore

from . import logger
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:
Expand Down Expand Up @@ -139,15 +141,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)

Expand All @@ -158,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

Expand Down
39 changes: 34 additions & 5 deletions etheno/manticoreutils.py
Original file line number Diff line number Diff line change
Expand Up @@ -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):
Expand All @@ -50,8 +77,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
Expand All @@ -66,7 +95,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:
Expand Down
4 changes: 0 additions & 4 deletions examples/BrokenMetaCoin/truffle-config.js

This file was deleted.

0 comments on commit 4d9a8f0

Please sign in to comment.