Merge branch 'develop' into bugfix/665

pull/666/head
Bernhard Mueller 6 years ago committed by GitHub
commit ec2de2e256
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 2
      README.md
  2. 6
      mythril/analysis/symbolic.py
  3. 3
      mythril/ether/ethcontract.py
  4. 9
      mythril/interfaces/cli.py
  5. 2
      mythril/laser/ethereum/svm.py
  6. 15
      mythril/mythril.py
  7. 2
      tests/cmd_line_test.py

@ -9,7 +9,7 @@
![Master Build Status](https://img.shields.io/circleci/project/github/ConsenSys/mythril-classic/master.svg) ![Master Build Status](https://img.shields.io/circleci/project/github/ConsenSys/mythril-classic/master.svg)
[![Waffle.io - Columns and their card count](https://badge.waffle.io/ConsenSys/mythril-classic.svg?columns=In%20Progress)](https://waffle.io/ConsenSys/mythril-classic/) [![Waffle.io - Columns and their card count](https://badge.waffle.io/ConsenSys/mythril-classic.svg?columns=In%20Progress)](https://waffle.io/ConsenSys/mythril-classic/)
[![Sonarcloud - Maintainability](https://sonarcloud.io/api/project_badges/measure?project=mythril&metric=sqale_rating)](https://sonarcloud.io/dashboard?id=mythril) [![Sonarcloud - Maintainability](https://sonarcloud.io/api/project_badges/measure?project=mythril&metric=sqale_rating)](https://sonarcloud.io/dashboard?id=mythril)
[![PyPI Statistics](https://pypistats.com/badge/mythril.svg)](https://pypistats.com/package/mythril) [![Downloads](https://pepy.tech/badge/mythril)](https://pepy.tech/project/mythril)
Mythril Classic is an open-source security analysis tool for Ethereum smart contracts. It uses concolic analysis, taint analysis and control flow checking to detect a variety of security vulnerabilities. Mythril Classic is an open-source security analysis tool for Ethereum smart contracts. It uses concolic analysis, taint analysis and control flow checking to detect a variety of security vulnerabilities.

@ -1,6 +1,6 @@
from mythril.laser.ethereum import svm from mythril.laser.ethereum import svm
from mythril.laser.ethereum.state import Account from mythril.laser.ethereum.state import Account
from mythril.ether.soliditycontract import SolidityContract from mythril.ether.soliditycontract import SolidityContract, ETHContract
import copy import copy
import logging import logging
from .ops import get_variable, SStore, Call, VarType from .ops import get_variable, SStore, Call, VarType
@ -64,6 +64,10 @@ class SymExecWrapper:
self.laser.sym_exec( self.laser.sym_exec(
creation_code=contract.creation_code, contract_name=contract.name creation_code=contract.creation_code, contract_name=contract.name
) )
elif isinstance(contract, ETHContract) and contract.creation_code:
self.laser.sym_exec(
creation_code=contract.creation_code, contract_name=contract.name
)
else: else:
self.laser.sym_exec(address) self.laser.sym_exec(address)

@ -6,7 +6,7 @@ import re
class ETHContract(persistent.Persistent): class ETHContract(persistent.Persistent):
def __init__( def __init__(
self, code, creation_code="", name="Unknown", enable_online_lookup=False self, code="", creation_code="", name="Unknown", enable_online_lookup=False
): ):
# Workaround: We currently do not support compile-time linking. # Workaround: We currently do not support compile-time linking.
@ -27,7 +27,6 @@ class ETHContract(persistent.Persistent):
def as_dict(self): def as_dict(self):
return { return {
"address": self.address,
"name": self.name, "name": self.name,
"code": self.code, "code": self.code,
"creation_code": self.creation_code, "creation_code": self.creation_code,

@ -90,6 +90,11 @@ def main():
action="store_true", action="store_true",
help="auto-load dependencies from the blockchain", help="auto-load dependencies from the blockchain",
) )
inputs.add_argument(
"--bin-runtime",
action="store_true",
help="Only when -c or -f is used. Consider the input bytecode as binary runtime code, default being the contract creation bytecode.",
)
outputs = parser.add_argument_group("output formats") outputs = parser.add_argument_group("output formats")
outputs.add_argument( outputs.add_argument(
@ -317,10 +322,10 @@ def main():
if args.code: if args.code:
# Load from bytecode # Load from bytecode
address, _ = mythril.load_from_bytecode(args.code) address, _ = mythril.load_from_bytecode(args.code, args.bin_runtime)
elif args.codefile: elif args.codefile:
bytecode = "".join([l.strip() for l in args.codefile if len(l.strip()) > 0]) bytecode = "".join([l.strip() for l in args.codefile if len(l.strip()) > 0])
address, _ = mythril.load_from_bytecode(bytecode) address, _ = mythril.load_from_bytecode(bytecode, args.bin_runtime)
elif args.address: elif args.address:
# Get bytecode from a contract address # Get bytecode from a contract address
address, _ = mythril.load_from_address(args.address) address, _ = mythril.load_from_address(args.address)

@ -117,7 +117,7 @@ class LaserEVM:
/ float(coverage[0]) / float(coverage[0])
* 100 * 100
) )
logging.info("Achieved {} coverage for code: {}".format(cov, code)) logging.info("Achieved {:.2f}% coverage for code: {}".format(cov, code))
def _execute_transactions(self, address): def _execute_transactions(self, address):
""" """

@ -311,11 +311,22 @@ class Mythril(object):
print(self.eth_db.contract_hash_to_address(hash)) print(self.eth_db.contract_hash_to_address(hash))
def load_from_bytecode(self, code): def load_from_bytecode(self, code, bin_runtime=False):
address = util.get_indexed_address(0) address = util.get_indexed_address(0)
if bin_runtime:
self.contracts.append( self.contracts.append(
ETHContract( ETHContract(
code, name="MAIN", enable_online_lookup=self.enable_online_lookup code=code,
name="MAIN",
enable_online_lookup=self.enable_online_lookup,
)
)
else:
self.contracts.append(
ETHContract(
creation_code=code,
name="MAIN",
enable_online_lookup=self.enable_online_lookup,
) )
) )
return address, self.contracts[-1] # return address and contract object return address, self.contracts[-1] # return address and contract object

@ -10,7 +10,7 @@ def output_of(command):
class CommandLineToolTestCase(BaseTestCase): class CommandLineToolTestCase(BaseTestCase):
def test_disassemble_code_correctly(self): def test_disassemble_code_correctly(self):
command = "python3 {} MYTH -d -c 0x5050".format(MYTH) command = "python3 {} MYTH -d --bin-runtime -c 0x5050".format(MYTH)
self.assertEqual("0 POP\n1 POP\n", output_of(command)) self.assertEqual("0 POP\n1 POP\n", output_of(command))
def test_disassemble_solidity_file_correctly(self): def test_disassemble_solidity_file_correctly(self):

Loading…
Cancel
Save