From 8f6d6b5c9bbc9754874b926c0a6f475017b7a9e5 Mon Sep 17 00:00:00 2001 From: Josselin Date: Tue, 19 Nov 2019 11:43:51 +0100 Subject: [PATCH 1/4] Add --only-alive-testcases flag to generate only testcase for alive states Similar behavior for m.finalize(only_alive_states=True) --- manticore/__main__.py | 6 ++++++ manticore/ethereum/cli.py | 2 +- manticore/ethereum/manticore.py | 7 +++++-- 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/manticore/__main__.py b/manticore/__main__.py index 3e39ea3fe..a8b042f10 100644 --- a/manticore/__main__.py +++ b/manticore/__main__.py @@ -220,6 +220,12 @@ def positive(value): help="Do not generate testcases for discovered states when analysis finishes", ) + eth_flags.add_argument( + "--only-alive-testcases", + action="store_true", + help="Do not generate testcases for invalid/throwing states when analysis finishes", + ) + config_flags = parser.add_argument_group("Constants") config.add_config_vars_to_argparse(config_flags) diff --git a/manticore/ethereum/cli.py b/manticore/ethereum/cli.py index 1550f3ea6..0cdfdae22 100644 --- a/manticore/ethereum/cli.py +++ b/manticore/ethereum/cli.py @@ -112,7 +112,7 @@ def ethereum_main(args, logger): ) if not args.no_testcases: - m.finalize() + m.finalize(only_alive_states=args.only_alive_testcases) else: m.kill() diff --git a/manticore/ethereum/manticore.py b/manticore/ethereum/manticore.py index 8ed985d4a..a4ff419f5 100644 --- a/manticore/ethereum/manticore.py +++ b/manticore/ethereum/manticore.py @@ -1601,7 +1601,7 @@ def _emit_trace_file(filestream, trace): filestream.write(ln) @ManticoreBase.at_not_running - def finalize(self, procs=None): + def finalize(self, procs=None, only_alive_states=False): """ Terminate and generate testcases for all currently alive states (contract states that cleanly executed to a STOP or RETURN in the last symbolic @@ -1618,8 +1618,11 @@ def finalize(self, procs=None): def finalizer(state_id): st = self._load(state_id) if self.fix_unsound_symbolication(st): - logger.debug("Generating testcase for state_id %d", state_id) last_tx = st.platform.last_transaction + # Do not generate killed state if only_alive_states is True + if only_alive_states and last_tx.result in {"REVERT", "THROW", "TXERROR"}: + return + logger.debug("Generating testcase for state_id %d", state_id) message = last_tx.result if last_tx else "NO STATE RESULT (?)" self.generate_testcase(st, message=message) From 1208b05f1c09281dc2445df361dbb99b133bf054 Mon Sep 17 00:00:00 2001 From: Josselin Date: Tue, 19 Nov 2019 11:56:12 +0100 Subject: [PATCH 2/4] Add --quick-mode to Manticore to set default conf for quick exploration --- manticore/__main__.py | 7 +++++++ manticore/ethereum/cli.py | 8 ++++++++ 2 files changed, 15 insertions(+) diff --git a/manticore/__main__.py b/manticore/__main__.py index a8b042f10..08634510e 100644 --- a/manticore/__main__.py +++ b/manticore/__main__.py @@ -226,6 +226,13 @@ def positive(value): help="Do not generate testcases for invalid/throwing states when analysis finishes", ) + eth_flags.add_argument( + "--quick-mode", + action="store_true", + help="Configure Manticore for quick exploration. Disable gas, generate testcase only for alive states, " + "do not explore constant functions. Disable all detectors.", + ) + config_flags = parser.add_argument_group("Constants") config.add_config_vars_to_argparse(config_flags) diff --git a/manticore/ethereum/cli.py b/manticore/ethereum/cli.py index 0cdfdae22..a064587a9 100644 --- a/manticore/ethereum/cli.py +++ b/manticore/ethereum/cli.py @@ -71,6 +71,14 @@ def choose_detectors(args): def ethereum_main(args, logger): m = ManticoreEVM(workspace_url=args.workspace) + + if args.quick_mode: + args.avoid_constant = True + args.exclude_all = True + args.only_alive_testcases = True + consts_evm = config.get_group("evm") + consts_evm.oog = "ignore" + with WithKeyboardInterruptAs(m.kill): m.register_plugin(KeepOnlyIfStorageChanges()) From 9a1ddb5c11ba88d981c3204a56a05a4413bed6aa Mon Sep 17 00:00:00 2001 From: Josselin Date: Tue, 19 Nov 2019 12:39:01 +0100 Subject: [PATCH 3/4] Run black --- manticore/__main__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/manticore/__main__.py b/manticore/__main__.py index 08634510e..abb142d26 100644 --- a/manticore/__main__.py +++ b/manticore/__main__.py @@ -230,7 +230,7 @@ def positive(value): "--quick-mode", action="store_true", help="Configure Manticore for quick exploration. Disable gas, generate testcase only for alive states, " - "do not explore constant functions. Disable all detectors.", + "do not explore constant functions. Disable all detectors.", ) config_flags = parser.add_argument_group("Constants") From ca44a6b3fa5613f61dceb54a4b06c5e9232cd548 Mon Sep 17 00:00:00 2001 From: Josselin Date: Wed, 20 Nov 2019 09:32:23 +0100 Subject: [PATCH 4/4] Finalize: Add docstring --- manticore/ethereum/manticore.py | 1 + 1 file changed, 1 insertion(+) diff --git a/manticore/ethereum/manticore.py b/manticore/ethereum/manticore.py index a4ff419f5..755128880 100644 --- a/manticore/ethereum/manticore.py +++ b/manticore/ethereum/manticore.py @@ -1608,6 +1608,7 @@ def finalize(self, procs=None, only_alive_states=False): transaction). :param procs: force the number of local processes to use in the reporting + :param bool only_alive_states: if True, killed states (revert/throw/txerror) do not generate testscases generation. Uses global configuration constant by default """ if procs is None: