shazow / whatsabi

Extract the ABI (and resolve proxies, and get other metadata) from Ethereum bytecode, even without source code.
https://shazow.github.io/whatsabi/
MIT License
1.04k stars 71 forks source link

disasm: Detect init code #23

Closed shazow closed 1 year ago

shazow commented 1 year ago

Test case code: 60806040526000805534801561001457600080fd5b50610178806100246000396000f300608060405260043610610062576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806329e46078146100675780634e148ce11461009a57806368e5c066146100cd578063a87d942c146100e4575b600080fd5b34801561007357600080fd5b50610098600480360381019080803563ffffffff16906020019092919050505061010f565b005b3480156100a657600080fd5b506100cb600480360381019080803563ffffffff169060200190929190505050610122565b005b3480156100d957600080fd5b506100e2610135565b005b3480156100f057600080fd5b506100f9610143565b6040518082815260200191505060405180910390f35b8060020263ffffffff1660008190555050565b8060010263ffffffff1660008190555050565b600160005401600081905550565b600080549050905600a165627a7a72305820946aaa67044121e8026c839756e8dc0bcd00731a5c7239ace3524046974de6720029

Now returns selectors: "0x29e46078" "0x4e148ce1" "0x68e5c066" "0xa87d942c"

We also tack on the init code as a separate sub-program onto the program object.

TODO:

CC: #19 @taryax

Taryax commented 1 year ago

Thanks for the quick fix. However, it seems disasm returns correct selectors but the JUMPDEST offsets are shifted. Making abiFromBytecode return an empty set by disqualifying every selector candidate. Do you have the same behavior ?

Not sure about the best solution, either modify the BytecodeIter code to be correct or to apply an "init_offset" to every p.dests offset

shazow commented 1 year ago

Great point, I forgot to adjust that. I originally wrote the code assuming input comes from getCode rather than piped in compiled contracts, so I need to update some assumptions.

shazow commented 1 year ago

Immutable case still fails, but otherwise we have the CALLVALUE ... ISZERO thing passing and init code offset passing.

shazow commented 1 year ago

Okay, this isn't perfect, since I'm not sure we could reliably detect non-static init code without dynamic analysis, but the examples we have so far are passing now!