示例#1
0
    def test_process_cli(self):

        g = config.get_group("grp")
        g.add("shouldchange", default=123)

        with tempfile.NamedTemporaryFile("w+") as conf:
            conf.file.write(
                'cli: {overwritten: 1, unchanged: "val"}\ngrp: {val: 1}')
            conf.file.close()

            parser = argparse.ArgumentParser("Desc")
            parser.add_argument("--overwritten", type=int, default=0)
            parser.add_argument("--config", default=None)
            parser.add_argument("--unchanged", default=None)

            config.add_config_vars_to_argparse(parser)

            args = parser.parse_args([
                "--overwritten=42", "--grp.shouldchange=23",
                f"--config={conf.name}"
            ])

            config.process_config_values(parser, args)

        # Make sure that cmdline flags get precedence
        g = config.get_group("cli")
        self.assertEqual(g.overwritten, 42)
        self.assertEqual(g.unchanged, "val")

        # Make sure that we can update defined vars
        g = config.get_group("grp")
        self.assertEqual(g.val, 1)
        self.assertEqual(g.shouldchange, 23)
示例#2
0
    def test_process_cli(self):

        g = config.get_group('grp')
        g.add('shouldchange', default=123)

        with tempfile.NamedTemporaryFile('w+') as conf:
            conf.file.write(
                'cli: {overwritten: 1, unchanged: "val"}\ngrp: {val: 1}')
            conf.file.close()

            parser = argparse.ArgumentParser('Desc')
            parser.add_argument('--overwritten', type=int, default=0)
            parser.add_argument('--config', default=None)
            parser.add_argument('--unchanged', default=None)

            config.add_config_vars_to_argparse(parser)

            args = parser.parse_args([
                '--overwritten=42', '--grp.shouldchange=23',
                f'--config={conf.name}'
            ])

            config.process_config_values(parser, args)

        # Make sure that cmdline flags get precedence
        g = config.get_group('cli')
        self.assertEqual(g.overwritten, 42)
        self.assertEqual(g.unchanged, 'val')

        # Make sure that we can update defined vars
        g = config.get_group('grp')
        self.assertEqual(g.val, 1)
        self.assertEqual(g.shouldchange, 23)
示例#3
0
    def test_add_config_vars(self):
        g = config.get_group("few")
        g.add("one", default=0, description="desc")
        g.add("two", default="x", description="desc2t")

        parser = argparse.ArgumentParser("Description")
        config.add_config_vars_to_argparse(parser)
        usage = parser.format_help()

        # There are no public methods to get at the added options so far, so we're just checking with
        # usage string
        self.assertIn("--few.one", usage)
        self.assertIn("--few.two", usage)
示例#4
0
def main():
    from crytic_compile import is_supported, cryticparser

    parser = argparse.ArgumentParser(
        description="Solidity property verifier",
        prog="manticore_verifier",
        # formatter_class=argparse.ArgumentDefaultsHelpFormatter,
    )

    # Add crytic compile arguments
    # See https://github.com/crytic/crytic-compile/wiki/Configuration
    cryticparser.init(parser)

    parser.add_argument(
        "source_code",
        type=str,
        nargs="*",
        default=[],
        help="Contract source code",
    )
    parser.add_argument("-v",
                        action="count",
                        default=0,
                        help="Specify verbosity level from -v to -vvvv")

    parser.add_argument(
        "--workspace",
        type=str,
        default=None,
        help=("A folder name for temporaries and results."
              "(default mcore_?????)"),
    )

    current_version = pkg_resources.get_distribution("manticore").version
    parser.add_argument(
        "--version",
        action="version",
        version=f"Manticore {current_version}",
        help="Show program version information",
    )
    parser.add_argument(
        "--propconfig",
        type=str,
        help="Solidity property accounts config file (.yml)",
    )
    eth_flags = parser.add_argument_group("Ethereum flags")

    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.",
    )
    eth_flags.add_argument(
        "--contract_name",
        type=str,
        help="The target contract name defined in the source code")
    eth_flags.add_argument(
        "--maxfail",
        type=int,
        help="stop after maxfail properties are failing. All if None")
    eth_flags.add_argument(
        "--maxcov",
        type=int,
        default=100,
        help=" Stop after maxcov %% coverage is obtained in the main contract",
    )
    eth_flags.add_argument("--maxt",
                           type=int,
                           default=3,
                           help="Max transaction count to explore")
    eth_flags.add_argument(
        "--deployer",
        type=str,
        help="(optional) address of account used to deploy the contract")
    eth_flags.add_argument(
        "--senders",
        type=str,
        help=
        "(optional) a comma separated list of sender addresses. The properties are going to be tested sending transactions from these addresses.",
    )
    eth_flags.add_argument(
        "--psender",
        type=str,
        help="(optional) address from where the property is tested")
    eth_flags.add_argument(
        "--propre",
        default=r"crytic_.*",
        type=str,
        help="A regular expression for selecting properties",
    )
    eth_flags.add_argument("--timeout",
                           default=240,
                           type=int,
                           help="Exploration timeout in seconds")
    eth_flags.add_argument("--outputspace_url",
                           type=str,
                           help="where to put the extended result")

    config_flags = parser.add_argument_group("Constants")
    config.add_config_vars_to_argparse(config_flags)

    parsed = parser.parse_args(sys.argv[1:])
    config.process_config_values(parser, parsed)

    if not parsed.source_code:
        print(parser.format_usage() +
              "error: You need to provide a contract source code.")
        sys.exit(1)
    args = parsed
    set_verbosity(args.v)
    logger = logging.getLogger("manticore.main")

    # read yaml config file
    deployer = None
    senders = None
    psenders = None
    if args.propconfig:
        """
        deployer: "0x41414141414141414141"  #who deploys the contract
        sender: ["0x51515151515151515151", "0x52525252525252525252"] #who calls the transactions (potentially can be multiple users)
        psender: "0x616161616161616161" #who calls the property
        """
        import yaml

        with open(args.propconfig) as f:
            c = yaml.safe_load(f)
            deployer = c.get("deployer")
            if deployer is not None:
                deployer = int(deployer, 0)

            senders = c.get("sender")
            if senders is not None:
                senders = [int(sender, 0) for sender in senders]

            psender = c.get("psender")
            if psender is not None:
                psender = int(psender, 0)

    # override with commandline args
    deployer = None
    if args.deployer is not None:
        deployer = int(args.deployer, 0)

    senders = None
    if args.senders is not None:
        senders = [int(sender, 0) for sender in args.senders.split(",")]

    psender = None
    if args.psender is not None:
        psender = int(args.psender, 0)

    source_code = args.source_code[0]
    contract_name = args.contract_name
    maxfail = args.maxfail
    maxt = args.maxt
    maxcov = args.maxcov
    return manticore_verifier(source_code,
                              contract_name,
                              maxfail=maxfail,
                              maxt=maxt,
                              maxcov=100,
                              senders=senders,
                              deployer=deployer,
                              psender=psender,
                              timeout=args.timeout,
                              propre=args.propre,
                              compile_args=vars(parsed))
示例#5
0
def parse_arguments() -> argparse.Namespace:
    def positive(value):
        ivalue = int(value)
        if ivalue <= 0:
            raise argparse.ArgumentTypeError("Argument must be positive")
        return ivalue

    parser = argparse.ArgumentParser(
        description="Symbolic execution tool",
        prog="manticore",
        formatter_class=argparse.ArgumentDefaultsHelpFormatter,
    )

    # Add crytic compile arguments
    # See https://github.com/crytic/crytic-compile/wiki/Configuration
    cryticparser.init(parser)

    parser.add_argument("--context",
                        type=str,
                        default=None,
                        help=argparse.SUPPRESS)
    parser.add_argument("--coverage",
                        type=str,
                        default="visited.txt",
                        help="Where to write the coverage data")
    parser.add_argument("--names",
                        type=str,
                        default=None,
                        help=argparse.SUPPRESS)

    parser.add_argument("--offset",
                        type=int,
                        default=16,
                        help=argparse.SUPPRESS)
    # FIXME (theo) Add some documentation on the different search policy options
    parser.add_argument(
        "--policy",
        type=str,
        default="random",
        help=("Search policy. random|adhoc|uncovered|dicount"
              "|icount|syscount|depth. (use + (max) or - (min)"
              " to specify order. e.g. +random)"),
    )
    parser.add_argument(
        "argv",
        type=str,
        nargs="*",
        default=[],
        help=
        "Path to program, path to mutants folder and program arguments ('+' in arguments indicates symbolic byte).",
    )

    parser.add_argument(
        "--workspace",
        type=str,
        default=None,
        help=("A folder name for temporaries and results."
              "(default mcore_?????)"),
    )

    parser.add_argument(
        "--config",
        type=str,
        help=
        "Manticore config file (.yml) to use. (default config file pattern is: ./[.]m[anti]core.yml)",
    )

    eth_flags = parser.add_argument_group("Ethereum flags")
    eth_flags.add_argument("--verbose-trace",
                           action="store_true",
                           help="Dump an extra verbose trace for each state")
    eth_flags.add_argument(
        "--txlimit",
        type=positive,
        help=
        "Maximum number of symbolic transactions to run (positive integer)",
    )

    eth_flags.add_argument("--txnocoverage",
                           action="store_true",
                           help="Do not use coverage as stopping criteria")

    eth_flags.add_argument("--txnoether",
                           action="store_true",
                           help="Do not attempt to send ether to contract")

    eth_flags.add_argument(
        "--txaccount",
        type=str,
        default="attacker",
        help=
        'Account used as caller in the symbolic transactions, either "attacker" or '
        '"owner" or "combo1" (uses both)',
    )

    eth_flags.add_argument(
        "--txpreconstrain",
        action="store_true",
        help=
        "Constrain human transactions to avoid exceptions in the contract function dispatcher",
    )

    eth_flags.add_argument(
        "--contract",
        type=str,
        help="Contract name to analyze in case of multiple contracts")

    eth_flags.add_argument(
        "--avoid-constant",
        action="store_true",
        help="Avoid exploring constant functions for human transactions",
    )

    eth_flags.add_argument(
        "--limit-loops",
        action="store_true",
        help="Limit loops depth",
    )

    eth_flags.add_argument(
        "--no-testcases",
        action="store_true",
        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",
    )

    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)

    parsed = parser.parse_args(sys.argv[1:])
    config.process_config_values(parser, parsed)

    if not parsed.argv:
        print(parser.format_usage() +
              "error: the following arguments are required: argv")
        sys.exit(1)

    if parsed.policy.startswith("min"):
        parsed.policy = "-" + parsed.policy[3:]
    elif parsed.policy.startswith("max"):
        parsed.policy = "+" + parsed.policy[3:]

    return parsed