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

69 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:
print("DELEGATECALL in fallback function: Contract 0x" + k.hex())
# contract.get_xrefs() should contain the delegateCall() target (library contract)
xrefs = contract.get_xrefs()
'''
from here on are many different options!
- trace functions in the referenced library contracts and look for SSTORE operations
- deploy the contract on testrpc or testnet and trigger functions using RPC
--> see class mythril.rpc.client.EthJsonRpc
For this example, we'll simply check if the library contract 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)
# if contract.matches_expression("func#initWallet(address[],uint256,uint256)#"):
if contract.matches_expression("code#PUSH#"):
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))