Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix missing consts in CLI args #1337

Merged
merged 5 commits into from
Jan 10, 2019
Merged
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 0 additions & 3 deletions manticore/__init__.py
Original file line number Diff line number Diff line change
@@ -7,7 +7,4 @@
from .utils import config, log
from .utils.helpers import issymbolic, istainted

consts = config.get_group('main')
consts.add('stdin_size', default=256, description='Maximum symbolic stdin size')

__all__ = [issymbolic.__name__, istainted.__name__]
14 changes: 5 additions & 9 deletions manticore/__main__.py
Original file line number Diff line number Diff line change
@@ -8,19 +8,21 @@
import pkg_resources

from .core.manticore import ManticoreBase
from .utils import config, log
from .ethereum.cli import ethereum_main
from .utils import config, log, install_helper

consts = config.get_group('main')
consts.add('recursionlimit', default=10000,
description="Value to set for Python recursion limit")
consts.add('timeout', default=0,
description='Timeout, in seconds, for Manticore invocation')


# XXX(yan): This would normally be __name__, but then logger output will be pre-
# pended by 'm.__main__: ', which is not very pleasing. hard-coding to 'main'
logger = logging.getLogger('manticore.main')

if install_helper.has_native:
from manticore.native.cli import native_main


def main():
"""
@@ -36,10 +38,8 @@ def main():
ManticoreBase.verbosity(args.v)

if args.argv[0].endswith('.sol'):
from manticore.ethereum.cli import ethereum_main
ethereum_main(args, logger)
else:
from manticore.native.cli import native_main
native_main(args, logger)


@@ -73,8 +73,6 @@ def positive(value):
help='Number of parallel processes to spawn')
parser.add_argument('argv', type=str, nargs='*', default=[],
help="Path to program, and arguments ('+' in arguments indicates symbolic byte).")
parser.add_argument('--timeout', type=int, default=consts.timeout,
help='Timeout. Abort exploration after TIMEOUT seconds')
parser.add_argument('-v', action='count', default=1,
help='Specify verbosity level from -v to -vvvv')
parser.add_argument('--workspace', type=str, default=None,
@@ -86,8 +84,6 @@ def positive(value):
help='Show program version information')
parser.add_argument('--config', type=str,
help='Manticore config file (.yml) to use. (default config file pattern is: ./[.]m[anti]core.yml)')
parser.add_argument('--stdin_size', type=int, default=consts.stdin_size,
help='Control the maximum symbolic stdin size')

bin_flags = parser.add_argument_group('Binary flags')
bin_flags.add_argument('--entrysymbol', type=str, default=None,
19 changes: 13 additions & 6 deletions manticore/core/manticore.py
Original file line number Diff line number Diff line change
@@ -26,6 +26,10 @@
logger = logging.getLogger(__name__)


consts = config.get_group('core')
consts.add('timeout', default=0, description='Timeout, in seconds, for Manticore invocation')


class ManticoreBase(Eventful):
'''
Base class for the central analysis object.
@@ -39,16 +43,19 @@ class ManticoreBase(Eventful):

_published_events = {'start_run', 'finish_run', 'generate_testcase'}

def __init__(self, initial_state, workspace_url=None, policy='random', **kwargs):
def __init__(self, initial_state, workspace_url=None, policy='random', timeout=None, **kwargs):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need the timeout here if it is already a global config value ?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's the question where should the user specify it if they want to do so. Do you think they should use config.core.timeout instead?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's leave it as an argument here as someone might want to use it when playing with scripts.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok. Note though that she may still need to do some config.py setting even from a script.

"""

:param initial_state: State to start from.
:param workspace_url: workspace folder name
:param policy: scheduling policy
:param timeout: the timeout for execution (in seconds)
:param kwargs: other kwargs, e.g.
"""
super().__init__()

self._timeout = consts.timeout if timeout is None else timeout

if isinstance(workspace_url, str):
if ':' not in workspace_url:
ws_path = f'fs:{workspace_url}'
@@ -214,12 +221,12 @@ def _real_context():
context[key] = ctx

@contextmanager
def shutdown_timeout(self, timeout):
if timeout <= 0:
def shutdown_timeout(self):
if self._timeout <= 0:
yield
return

timer = Timer(timeout, self.shutdown)
timer = Timer(self._timeout, self.shutdown)
timer.start()

try:
@@ -414,7 +421,7 @@ def _finish_run(self, profiling=False):

self._publish('did_finish_run')

def run(self, procs=1, timeout=0, should_profile=False):
def run(self, procs=1, should_profile=False):
'''
Runs analysis.

@@ -425,7 +432,7 @@ def run(self, procs=1, timeout=0, should_profile=False):
self._start_run()

self._last_run_stats['time_started'] = time.time()
with self.shutdown_timeout(timeout):
with self.shutdown_timeout():
self._start_workers(procs, profiling=should_profile)

self._join_workers()
2 changes: 1 addition & 1 deletion manticore/ethereum/cli.py
Original file line number Diff line number Diff line change
@@ -62,7 +62,7 @@ def ethereum_main(args, logger):

logger.info('Beginning analysis')

with m.shutdown_timeout(args.timeout):
with m.shutdown_timeout():
m.multi_tx_analysis(args.argv[0], contract_name=args.contract, tx_limit=args.txlimit,
tx_use_coverage=not args.txnocoverage, tx_send_ether=not args.txnoether,
tx_account=args.txaccount, tx_preconstrain=args.txpreconstrain)
6 changes: 3 additions & 3 deletions manticore/native/cli.py
Original file line number Diff line number Diff line change
@@ -2,12 +2,12 @@
from ..core.plugin import InstructionCounter, Visited, Tracer, RecordSymbolicBranches


def native_main(args, logger_):
def native_main(args, _logger):
env = {key: val for key, val in [env[0].split('=') for env in args.env]}

m = Manticore(args.argv[0], argv=args.argv[1:], env=env, entry_symbol=args.entrysymbol,
workspace_url=args.workspace, policy=args.policy,
concrete_start=args.data, pure_symbolic=args.pure_symbolic, stdin_size=args.stdin_size)
concrete_start=args.data, pure_symbolic=args.pure_symbolic)

# Default plugins for now.. FIXME REMOVE!
m.register_plugin(InstructionCounter())
@@ -29,4 +29,4 @@ def init(initial_state):
for file in args.files:
initial_state.platform.add_symbolic_file(file)

m.run(procs=args.procs, timeout=args.timeout, should_profile=args.profile)
m.run(procs=args.procs, should_profile=args.profile)
13 changes: 10 additions & 3 deletions manticore/native/manticore.py
Original file line number Diff line number Diff line change
@@ -14,7 +14,8 @@

logger = logging.getLogger(__name__)

consts = config.get_group('main')
consts = config.get_group('native')
consts.add('stdin_size', default=256, description='Maximum symbolic stdin size')


class Manticore(ManticoreBase):
@@ -38,7 +39,7 @@ def _generate_testcase_callback(self, state, testcase, message):
self._output.save_testcase(state, testcase.prefix, message)

@classmethod
def linux(cls, path, argv=None, envp=None, entry_symbol=None, symbolic_files=None, concrete_start='', pure_symbolic=False, stdin_size=consts.stdin_size, **kwargs):
def linux(cls, path, argv=None, envp=None, entry_symbol=None, symbolic_files=None, concrete_start='', pure_symbolic=False, stdin_size=None, **kwargs):
"""
Constructor for Linux binary analysis.

@@ -57,6 +58,9 @@ def linux(cls, path, argv=None, envp=None, entry_symbol=None, symbolic_files=Non
:return: Manticore instance, initialized with a Linux State
:rtype: Manticore
"""
if stdin_size is None:
stdin_size = consts.stdin_size

try:
return cls(_make_linux(path, argv, envp, entry_symbol, symbolic_files, concrete_start, pure_symbolic, stdin_size), **kwargs)
except elftools.common.exceptions.ELFError:
@@ -214,13 +218,16 @@ def _make_decree(program, concrete_start='', **kwargs):
return initial_state


def _make_linux(program, argv=None, env=None, entry_symbol=None, symbolic_files=None, concrete_start='', pure_symbolic=False, stdin_size=consts.stdin_size):
def _make_linux(program, argv=None, env=None, entry_symbol=None, symbolic_files=None, concrete_start='', pure_symbolic=False, stdin_size=None):
from ..platforms import linux

env = {} if env is None else env
argv = [] if argv is None else argv
env = [f'{k}={v}' for k, v in env.items()]

if stdin_size is None:
stdin_size = consts.stdin_size

logger.info('Loading program %s', program)

constraints = ConstraintSet()
19 changes: 10 additions & 9 deletions manticore/platforms/evm.py
Original file line number Diff line number Diff line change
@@ -6,7 +6,6 @@
import inspect
from functools import wraps
from typing import List, Set, Tuple, Union
from ..exceptions import EthereumError
from ..utils.helpers import issymbolic, get_taints, taint_with, istainted
from ..platforms.platform import *
from ..core.smtlib import solver, BitVec, Array, ArrayProxy, Operators, Constant, ArrayVariable, ArrayStore, BitVecConstant, translate_to_smtlib, to_constant, simplify
@@ -31,19 +30,21 @@
# This configuration variable allows the user to control and perhaps relax the gas calculation
# pedantic: gas is faithfully accounted and checked at instruction level. State may get forked in OOG/NoOOG
# complete: gas is faithfully accounted and checked at basic blocks limits. State may get forked in OOG/NoOOG
# concrete: Concretize gas. If the fee to be consumed gets to be symbolic. Choose some potential values and fork on those.
# concrete: concretize gas: if the fee to be consumed gets to be symbolic choose some potential values and fork on those
# optimistic: Try not to OOG. If it may be enough gas we ignore the OOG case. A constraint is added to assert the gas is enough and the OOG state is ignored.
# pesimistic: OOG soon. If it may NOT be enough gas we ignore the normal case. A constraint is added to assert the gas is NOT enough and the other state is ignored.
# ignore: Ignore gas. Do not account for it. Do not OOG.
consts = config.get_group('evm')

consts.add('oog', default='pedantic', description='Default behavior for symbolic gas.'
'pedantic: Fully faithful. Test at every instruction. Forks.'
'complete: Mostly faithful. Test at BB limit. Forks.'
'concrete: Incomplete. Concretize gas to MIN/MAX values. Forks.'
'optimistic: Try to not fail due to OOG. If it can be enough gas use it. Ignore the path to OOG. Wont fork'
'pesimistic: Try OOG asap. Fail soon. Ignore the path with enough gas.'
"ignore: Ignore gas. Instructions won't consume gas")
consts.add('oog', default='pedantic', description=(
'Default behavior for symbolic gas.'
'pedantic: Fully faithful. Test at every instruction. Forks.'
'complete: Mostly faithful. Test at BB limit. Forks.'
'concrete: Incomplete. Concretize gas to MIN/MAX values. Forks.'
'optimistic: Try to not fail due to OOG. If it can be enough gas use it. Ignore the path to OOG. Wont fork'
'pesimistic: Try OOG asap. Fail soon. Ignore the path with enough gas.'
"ignore: Ignore gas. Instructions won't consume gas"
))

# Auxiliary constants and functions
TT256 = 2 ** 256
5 changes: 3 additions & 2 deletions manticore/utils/install_helper.py
Original file line number Diff line number Diff line change
@@ -8,7 +8,7 @@


def ensure_native_deps():
if not _has_native:
if not has_native:
raise ImportError(
'Missing some packages for native binary analysis. Please install them with pip install manticore[native].'
)
@@ -24,5 +24,6 @@ def _has_deps(deps):
return True


_has_native = _has_deps('native')
has_native = _has_deps('native')

__all__ = ['ensure_native_deps', 'has_native']