|
|
@ -4,10 +4,11 @@ |
|
|
|
http://www.github.com/b-mueller/mythril |
|
|
|
http://www.github.com/b-mueller/mythril |
|
|
|
""" |
|
|
|
""" |
|
|
|
|
|
|
|
|
|
|
|
from mythril.ether import evm,util |
|
|
|
from mythril.ether import evm |
|
|
|
from mythril.disassembler.disassembly import Disassembly |
|
|
|
from mythril.disassembler.disassembly import Disassembly |
|
|
|
from mythril.disassembler.callgraph import generate_callgraph |
|
|
|
from mythril.disassembler.callgraph import generate_callgraph |
|
|
|
from mythril.ether.contractstorage import get_persistent_storage |
|
|
|
from mythril.ether.contractstorage import get_persistent_storage |
|
|
|
|
|
|
|
from mythril.ether.ethcontract import ETHContract |
|
|
|
from mythril.rpc.client import EthJsonRpc |
|
|
|
from mythril.rpc.client import EthJsonRpc |
|
|
|
from mythril.ipc.client import EthIpc |
|
|
|
from mythril.ipc.client import EthIpc |
|
|
|
from ethereum import utils |
|
|
|
from ethereum import utils |
|
|
@ -40,7 +41,7 @@ commands.add_argument('-t', '--trace', action='store_true', help='trace, use wit |
|
|
|
commands.add_argument('-g', '--graph', help='generate a call graph', metavar='OUTPUT_FILE') |
|
|
|
commands.add_argument('-g', '--graph', help='generate a call graph', metavar='OUTPUT_FILE') |
|
|
|
commands.add_argument('-l', '--fire-lasers', action='store_true', help='detect vulnerabilities, use with -c or -a') |
|
|
|
commands.add_argument('-l', '--fire-lasers', action='store_true', help='detect vulnerabilities, use with -c or -a') |
|
|
|
commands.add_argument('-s', '--search', help='search the contract database') |
|
|
|
commands.add_argument('-s', '--search', help='search the contract database') |
|
|
|
commands.add_argument('--xrefs', help='get xrefs from contract in database', metavar='CONTRACT_HASH') |
|
|
|
commands.add_argument('--xrefs', action='store_true', help='get xrefs from a contract, use with -c or -a') |
|
|
|
commands.add_argument('--hash', help='calculate function signature hash', metavar='SIGNATURE') |
|
|
|
commands.add_argument('--hash', help='calculate function signature hash', metavar='SIGNATURE') |
|
|
|
commands.add_argument('--init-db', action='store_true', help='initialize the contract database') |
|
|
|
commands.add_argument('--init-db', action='store_true', help='initialize the contract database') |
|
|
|
|
|
|
|
|
|
|
@ -70,7 +71,7 @@ if (args.v): |
|
|
|
if (0 <= args.v < 3): |
|
|
|
if (0 <= args.v < 3): |
|
|
|
logging.basicConfig(level=[logging.NOTSET, logging.INFO, logging.DEBUG][args.v]) |
|
|
|
logging.basicConfig(level=[logging.NOTSET, logging.INFO, logging.DEBUG][args.v]) |
|
|
|
|
|
|
|
|
|
|
|
if (args.disassemble or args.graph or args.fire_lasers): |
|
|
|
if (args.disassemble or args.graph or args.fire_lasers or args.xrefs): |
|
|
|
|
|
|
|
|
|
|
|
if (args.code): |
|
|
|
if (args.code): |
|
|
|
encoded_bytecode = args.code |
|
|
|
encoded_bytecode = args.code |
|
|
@ -118,8 +119,15 @@ if (args.disassemble or args.graph or args.fire_lasers): |
|
|
|
with open(args.graph, "w") as f: |
|
|
|
with open(args.graph, "w") as f: |
|
|
|
f.write(html) |
|
|
|
f.write(html) |
|
|
|
except Exception as e: |
|
|
|
except Exception as e: |
|
|
|
|
|
|
|
|
|
|
|
print("Error saving graph: " + str(e)) |
|
|
|
print("Error saving graph: " + str(e)) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
elif (args.xrefs): |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
contract = ETHContract(encoded_bytecode) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
print("\n".join(contract.get_xrefs())) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
elif (args.fire_lasers): |
|
|
|
elif (args.fire_lasers): |
|
|
|
|
|
|
|
|
|
|
@ -154,7 +162,7 @@ elif (args.trace): |
|
|
|
else: |
|
|
|
else: |
|
|
|
print(str(i['pc']) + " " + i['op'] + ";\tSTACK: " + i['stack']) |
|
|
|
print(str(i['pc']) + " " + i['op'] + ";\tSTACK: " + i['stack']) |
|
|
|
|
|
|
|
|
|
|
|
elif args.search or args.xrefs or args.init_db: |
|
|
|
elif args.search or args.init_db: |
|
|
|
|
|
|
|
|
|
|
|
contract_storage = get_persistent_storage(db_dir) |
|
|
|
contract_storage = get_persistent_storage(db_dir) |
|
|
|
|
|
|
|
|
|
|
@ -165,19 +173,6 @@ elif args.search or args.xrefs or args.init_db: |
|
|
|
except SyntaxError: |
|
|
|
except SyntaxError: |
|
|
|
exitWithError("Syntax error in search expression.") |
|
|
|
exitWithError("Syntax error in search expression.") |
|
|
|
|
|
|
|
|
|
|
|
elif (args.xrefs): |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
try: |
|
|
|
|
|
|
|
contract_hash = util.safe_decode(args.xrefs) |
|
|
|
|
|
|
|
except binascii.Error: |
|
|
|
|
|
|
|
exitWithError("Invalid contract hash.") |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
try: |
|
|
|
|
|
|
|
contract = contract_storage.get_contract_by_hash(contract_hash) |
|
|
|
|
|
|
|
print("\n".join(contract.get_xrefs())) |
|
|
|
|
|
|
|
except KeyError: |
|
|
|
|
|
|
|
exitWithError("Contract not found in the database.") |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
elif (args.init_db): |
|
|
|
elif (args.init_db): |
|
|
|
if args.ipc: |
|
|
|
if args.ipc: |
|
|
|
contract_storage.initialize(args.rpchost, args.rpcport, args.rpctls, args.sync_all, args.ipc) |
|
|
|
contract_storage.initialize(args.rpchost, args.rpcport, args.rpctls, args.sync_all, args.ipc) |
|
|
|