Taesoo Kim
Taesoo Kim
web3.py
, RemixStorage.sol
, Owner.sol
and Ballot.sol
from Remix/BrownieRef. EI §2
Ref. EI §2
Ref. EI §2
Ref. EI §2
Ref. EI §2
PUSH1 0x80
--------------------------------------------------
stack : []
memory : []
stroage: {}
stack : [0000000000000000000000000000000000000000000000000000000000000080]
memory : []
stroage: {}
Ref. EI §2
MSTORE 0x40 0x80
--------------------------------------------------
stack : [
0000000000000000000000000000000000000000000000000000000000000080,
0000000000000000000000000000000000000000000000000000000000000040
]
memory : []
stroage: {}
stack : []
memory : [
0000000000000000000000000000000000000000000000000000000000000000,
0000000000000000000000000000000000000000000000000000000000000000,
0000000000000000000000000000000000000000000000000000000000000080
]
stroage: {}
Ref. EI §2
SSTORE 0x00 0xdeadbeef
--------------------------------------------------
stack : [
00000000000000000000000000000000000000000000000000000000deadbeef,
0000000000000000000000000000000000000000000000000000000000000000
]
memory : []
stroage: {}
stack : []
memory : []
stroage: {
0000000000000000000000000000000000000000000000000000000000000000:
00000000000000000000000000000000000000000000000000000000deadbeef
}
Ref. EI §2
> web3.eth.get_code(s.address)
'0x6080604052348015600f57600080fd5b506004361060...'
> print(evm_disasm(web3.eth.get_code(s.address)))
00000: PUSH1 0x80
00002: PUSH1 0x40
00004: MSTORE
00005: CALLVALUE
00006: DUP1
00007: ISZERO
00008: PUSH1 0x0f
0000a: JUMPI
0000b: PUSH1 0x00
0000d: DUP1
0000e: REVERT
0000f: JUMPDEST
...
Ref. EI §2
Ref. EI §2
Ref. EI §2
Ref. EVM CALL
> tx.trace[118-1:118+1]
[{
'fn': "Caller.storeToStorage",
'memory': [
0x80: "6057361d00000000000000000000000000000000000000000000000000000000",
0xa0: "deadbeef00000000000000000000000000000000000000000000000000000000"],
'gasCost': 187834,
'op': "CALL",
'stack': [
"0000000000000000000000000000000000000000000000000000000000000000",<retSize>
"0000000000000000000000000000000000000000000000000000000000000080",<retOffset>
"0000000000000000000000000000000000000000000000000000000000000024",<argSize>
"0000000000000000000000000000000000000000000000000000000000000080",<argOffset>
"0000000000000000000000000000000000000000000000000000000000000000",<value>
"0000000000000000000000003194cbdc3dbcd3e11a07892e7ba5c3394048cc87",<address>
"0000000000000000000000000000000000000000000000000000000000b6c24e" <gas>
]},
Ref. EI §2
Ref. EI §2
static_gas = 0
if value == current_value
if key is warm
base_dynamic_gas = 100
else
base_dynamic_gas = 100
else if current_value == original_value
if original_value == 0
base_dynamic_gas = 20000
else
base_dynamic_gas = 2900
else
base_dynamic_gas = 100
Ref. SSTORE
Ref. EI §2
Ref. EI §2
CALLDATALOAD 0x00
--------------------------------------------------
stack : [
0000000000000000000000000000000000000000000000000000000000000000
]
memory : []
stroage: {}
stack : []
memory : [6057361d00000000000000000000000000000000000000000000000000000000]
stroage: {}
> s = Storage.deploy()
# deployment code. [] indicates the contract's code
> Storage.bytecode
'6080604052348015600f57600080fd5b5060ac8061001e6000396000f3fe[6080604052348015600f57600080fd5...]'
# +-----------------------------------------------------------
# => code that deploys the contract as a payload
# contract code
> web3.eth.get_code(s.address)
'[6080604052348015600f57600080fd5...]'
Ref. EI §2
tx.trace
in
TrasnactionReceipt()
of Brownieevm_disasm()
in pwn.py
or
evm disasm
in your console# codecopy(destOffset=0x00, offset=0x1e, size=0xac)
0011 60 PUSH1 0xac
0013 80 DUP1
0014 61 PUSH2 0x001e
0017 60 PUSH1 0x00
0019 39 CODECOPY
# return(offset=0x00, size=0xac)
001A 60 PUSH1 0x00
001C F3 *RETURN
pwn.py
code = HexBytes("0xdeadbeef")
deployer = evm_asm("""\
PUSH1 %d
DUP1
PUSH1 0x0b
PUSH1 0x00
CODECOPY
PUSH1 0x00
RETURN
""" % len(code))
tx = web3.eth.send_transaction({"from": a[0].address, "data": d + code})
tx = web3.eth.get_transaction_receipt(tx)
# what's here?!
web3.eth.get_code(tx.contractAddress)
1 gwei
back
to you when invoked