|
|
@ -18,6 +18,7 @@ from mythril.exceptions import CompilerError |
|
|
|
from mythril.analysis.symbolic import StateSpace |
|
|
|
from mythril.analysis.symbolic import StateSpace |
|
|
|
from mythril.analysis.callgraph import generate_graph |
|
|
|
from mythril.analysis.callgraph import generate_graph |
|
|
|
from mythril.analysis.security import fire_lasers |
|
|
|
from mythril.analysis.security import fire_lasers |
|
|
|
|
|
|
|
from web3 import Web3 |
|
|
|
from ethereum import utils |
|
|
|
from ethereum import utils |
|
|
|
from pathlib import Path |
|
|
|
from pathlib import Path |
|
|
|
from json.decoder import JSONDecodeError |
|
|
|
from json.decoder import JSONDecodeError |
|
|
@ -62,7 +63,7 @@ utils = parser.add_argument_group('utilities') |
|
|
|
utils.add_argument('-d', '--disassemble', action='store_true', help='print disassembly') |
|
|
|
utils.add_argument('-d', '--disassemble', action='store_true', help='print disassembly') |
|
|
|
utils.add_argument('--xrefs', action='store_true', help='get xrefs from a contract') |
|
|
|
utils.add_argument('--xrefs', action='store_true', help='get xrefs from a contract') |
|
|
|
utils.add_argument('--hash', help='calculate function signature hash', metavar='SIGNATURE') |
|
|
|
utils.add_argument('--hash', help='calculate function signature hash', metavar='SIGNATURE') |
|
|
|
utils.add_argument('--storage', help='read data from storage index, use with -a', metavar='INDEX') |
|
|
|
utils.add_argument('--storage', help='read state variables from storage index (index,length,array(in case of arrays)), use with -a', metavar='INDEX') |
|
|
|
|
|
|
|
|
|
|
|
options = parser.add_argument_group('options') |
|
|
|
options = parser.add_argument_group('options') |
|
|
|
options.add_argument('--ipc', help='use IPC interface instead of RPC', action='store_true') |
|
|
|
options.add_argument('--ipc', help='use IPC interface instead of RPC', action='store_true') |
|
|
@ -247,12 +248,33 @@ if args.storage: |
|
|
|
if not args.address: |
|
|
|
if not args.address: |
|
|
|
exitWithError("To read storage, provide the address of a deployed contract with the -a option.") |
|
|
|
exitWithError("To read storage, provide the address of a deployed contract with the -a option.") |
|
|
|
else: |
|
|
|
else: |
|
|
|
|
|
|
|
position = 0 |
|
|
|
|
|
|
|
length = 1 |
|
|
|
|
|
|
|
array = 0 |
|
|
|
|
|
|
|
|
|
|
|
try: |
|
|
|
try: |
|
|
|
position = int(args.storage) |
|
|
|
params = (args.storage).split(",") |
|
|
|
|
|
|
|
if len(params) >= 1 and len(params) <= 3: |
|
|
|
|
|
|
|
position = int(params[0]) |
|
|
|
|
|
|
|
if len(params) >= 2 and len(params) <= 3: |
|
|
|
|
|
|
|
length = int(params[1]) |
|
|
|
|
|
|
|
if len(params) == 3: |
|
|
|
|
|
|
|
if re.match("array",params[2]): |
|
|
|
|
|
|
|
array = 1 |
|
|
|
|
|
|
|
if len(params) >= 4: |
|
|
|
|
|
|
|
exitWithError("Invalid amount of parameters.") |
|
|
|
except ValueError: |
|
|
|
except ValueError: |
|
|
|
exitWithError("Invalid storage index. Please provide a numeric value.") |
|
|
|
exitWithError("Invalid storage index. Please provide a numeric value.") |
|
|
|
|
|
|
|
|
|
|
|
print(eth.eth_getStorageAt(args.address, position=position, block='latest')) |
|
|
|
if array: |
|
|
|
|
|
|
|
position_formated = str(position).zfill(64) |
|
|
|
|
|
|
|
position = int(Web3.sha3(position_formated),16) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if length == 1: |
|
|
|
|
|
|
|
print("{}: ".format(position) + eth.eth_getStorageAt(args.address, position)); |
|
|
|
|
|
|
|
else: |
|
|
|
|
|
|
|
for i in range(position, position + length): |
|
|
|
|
|
|
|
print("{}: ".format(hex(i)) + eth.eth_getStorageAt(args.address, i)); |
|
|
|
|
|
|
|
|
|
|
|
elif (args.disassemble): |
|
|
|
elif (args.disassemble): |
|
|
|
|
|
|
|
|
|
|
|