Security analysis tool for EVM bytecode. Supports smart contracts built for Ethereum, Hedera, Quorum, Vechain, Roostock, Tron and other EVM-compatible blockchains.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
mythril/examples/find-fallback-dcl.py

73 lines
2.3 KiB

from mythril.ether import evm
from mythril.ether.contractstorage import get_persistent_storage
from mythril.disassembler.disassembly import Disassembly
from mythril.rpc.client import EthJsonRpc
from mythril.disassembler.callgraph import generate_callgraph
import os
contract_storage = get_persistent_storage()
contract_keys = list(contract_storage.contracts)
homestead = EthJsonRpc()
# Iterate over all contracts in the database
for k in contract_keys:
contract = contract_storage.contracts[k]
# Run each contract in the PyEthereum EVM trace to check whether DELEGATECALL is reached
# To execute the fallback function, we don't provide any input data
ret = evm.trace(contract.code)
if 'DELEGATECALL' in ret:
7 years ago
print("DELEGATECALL in fallback function: Contract 0x" + k.hex() + " deployed at: ")
instance_list = contract_storage.instance_lists[k]
for i in range(1, len(instance_list.addresses)):
print("Address: " + instance_list.addresses[i] + ", balance: " + str(instance_list.balances[i]))
# contract.get_xrefs() should contain the delegateCall() target (library contract)
7 years ago
print("Referenced contracts:")
xrefs = contract.get_xrefs()
7 years ago
print ("\n".join(xrefs))
'''
from here on are many different options!
7 years ago
In this example, we'll only check one of the refernced contracts contains the initWallet() function
If it does, we save the disassembly and callgraph for further analysis
'''
for xref in xrefs:
code = homestead.eth_getCode(xref)
disassembly = Disassembly(code)
7 years ago
if contract.matches_expression("func#initWallet(address[],uint256,uint256)#"):
print ("initWallet() in referenced library contract: " + xref)
# Save list of contracts that forward calls to this library contract
cwd = os.getcwd()
with open("contracts_calling_" + xref + ".txt", "w") as f:
addresses = contract_storage.instance_lists[k].addresses
f.write("\n".join(addresses))
easm = disassembly.get_easm()
with open("library_" + xref + ".easm", "w") as f:
f.write(easm)
generate_callgraph(disassembly, os.path.join(cwd, "library_" + xref))