Change class name ETHCode -> ETHContract

pull/2/head
Bernhard Mueller 7 years ago
parent 4923f2db9d
commit e611a961e3
  1. 21
      README.md
  2. 6
      contractstorage.py
  3. 9
      ether/ethcontract.py
  4. 10
      ether/util.py

@ -57,23 +57,28 @@ $ mythril --search "code[PUSH1 0x50,POP]"
$ mythril --search "func[changeMultisig(address)] and code[PUSH1 0x50,POP]"
```
### Tracing code in the EVM
### Other commands
You can also disassemble and trace code using the '-d' and '-t' flags, respectively. When tracing, the code is run in the PyEthereum virtual machine with the (optional) input data passed via the '--data' flag.
```
$ ./mythril -d -a "0x3665f2bf19ee5e207645f3e635bf0f4961d661c0"
PUSH1 0x60
PUSH1 0x40
MSTORE
CALLDATASIZE
ISZERO
PUSH2 0x00ac
JUMPI
(...)
$ ./mythril -t -a "0x3665f2bf19ee5e207645f3e635bf0f4961d661c0"
vm storage={'storage': {}, 'nonce': '0', 'balance': '0', 'code': '0x'} gas=b'21000' stack=[] address=b'6e\xf2\xbf\x19\xee^ vE\xf3\xe65\xbf\x0fIa\xd6a\xc0' depth=0 steps=0 inst=96 pushvalue=96 pc=b'0' op=PUSH1
vm op=PUSH1 gas=b'20997' stack=[b'96'] depth=0 steps=1 inst=96 pushvalue=64 pc=b'2'
vm op=MSTORE gas=b'20994' stack=[b'96', b'64'] depth=0 steps=2 inst=82 pc=b'4'
```
## Custom static / dynamic analysis
Do note however that the disassembly / debugging functionality is currently quite bare-bones. If you are planning to do manual analysis, I recommend using [remix](https://remix.ethereum.org/) and [etherscan](https://etherscan.io).
## Custom scripts
By combining modules of Mythril and [PyEthereum](https://github.com/ethereum/pyethereum) you can perform more complex static/dynamic analysis tasks.
-- TODO --
-- TODO: Add example(s) --
## Credit

@ -1,5 +1,5 @@
from rpc.client import EthJsonRpc
from ether.ethcontract import ETHCode, InstanceList
from ether.ethcontract import ETHContract, InstanceList
from ethereum import utils
import hashlib
import re
@ -50,7 +50,7 @@ class ContractStorage(persistent.Persistent):
# skip contracts with zero balance (disable with --sync-all)
continue
code = ETHCode(contract_code)
code = ETHContract(contract_code)
m = hashlib.md5()
m.update(contract_code.encode('UTF-8'))
@ -94,4 +94,4 @@ class ContractStorage(persistent.Persistent):
m = self.instance_lists[contract_hash]
callback_func(contract_hash.hex(), self.contracts[k].code, m.addresses, m.balances)
callback_func(contract_hash.hex(), self.contracts[k], m.addresses, m.balances)

@ -3,13 +3,20 @@ import re
import persistent
class ETHCode(persistent.Persistent):
class ETHContract(persistent.Persistent):
def __init__(self, code = ""):
self.code = code
def get_xrefs(self):
disassembly = asm.disassemble(util.safe_decode(self.code))
print(disassembly)
def matches_expression(self, expression):
disassembly = asm.disassemble(util.safe_decode(self.code))

@ -1,5 +1,8 @@
from rpc.client import EthJsonRpc
import codecs
from ethereum.abi import encode_abi, encode_int
from ethereum.utils import zpad
from ethereum.abi import method_id
def safe_decode(hex_encoded_string):
@ -25,6 +28,13 @@ def bytecode_from_blockchain(creation_tx_hash, rpc_host='127.0.0.1', rpc_port=85
raise RuntimeError("Transaction trace didn't return any bytecode")
def encode_calldata(func_name, arg_types, args):
mid = method_id(func_name, arg_types)
function_selector = zpad(encode_int(mid), 4)
args = encode_abi(arg_types, args)
return function_selector + args
def raw_bytes_to_file(filename, bytestring):
with open(filename, 'wb') as f:
f.write(bytestring)

Loading…
Cancel
Save