trailofbits / manticore

Symbolic execution tool
https://blog.trailofbits.com/2017/04/27/manticore-symbolic-execution-for-humans/
GNU Affero General Public License v3.0
3.69k stars 472 forks source link

ethereum.ABI incorrectly (de)serializes certain types #1219

Open stephan-tolksdorf opened 6 years ago

stephan-tolksdorf commented 6 years ago

The current implementation of ethereum.ABI does not properly differentiate between 'dynamic' and 'static' types. In particular, it incorrectly treats fixed-size arrays of non-dynamic elements as dynamic types and it treats tuples with a dynamic element as non-dynamic types.

Fixing this completely requires adding new grammar rules to the YACC grammar in abitypes.py and making the corresponding changes to abi.py.

This a simple example where the invalid serialization leads to wrong results:

from manticore.ethereum import ManticoreEVM, ABI
from manticore.core.smtlib.visitors import to_constant

m = ManticoreEVM(procs=4) # initiate the blockchain
source_code = '''
pragma solidity ^0.4.24;
contract Trivial {
    function f(uint a) public returns (uint) {
        return a;
    }
    function f1(uint[1] a) public returns (uint) {
        return a[0];
    }
}
'''
creator_account = m.create_account(balance=1000)
contract = m.solidity_create_contract(source_code, owner=creator_account)

# Correctly prints 123.
contract.f(123)
print(ABI.deserialize('uint', to_constant(m.world.transactions[-1].return_data)))

# Incorrectly prints 32 (the offset of the data of the incorrectly dynamically encoded
# array from the start of the encoded arguments).
contract.f1([123])
print(ABI.deserialize('uint', to_constant(m.world.transactions[-1].return_data)))
offlinemark commented 6 years ago

thanks for filing this 👍