5

I’d like to know what is preventing me to write an assembly code who knows the contract address and call some arbitrary functions, even if declared “internal” via a simple JUMP.

In theory I can: 1) discover what is the location to jump to analyzing the bytecode and using some accessible address as baseaddress; 2) write my own assembly code which loads the needed parameters into the stack; 3) make a JUMP to the location discovered at (1).

What is the mechanism that should prevent me to do that?

(I understand that the various “call” type opcodes jump to the initial location of the called code, but apparently the JUMP and JUMPI instructions have no such limitation. Reading yellow paper sections 9.4.2 and 9.4.3 AND the Geth implementation apparently do not contradict the possibility to jump to an arbitrary absolute address, but for an unclear definition of “permitted jump range” which apparently simply requires that a JUMPDEST opcode be present in the location where the EVM jumps. And this is easy to find in the attacked contract opcode. Some further analysis is required and previous answer to similar questions is to much rough and straight and do not give evidences)

5

You can not jump in on arbitrary location of the called contract. You can only call it via CALL/CALLCODE/DELEGATECALL. When you use the CALL opcode for instance, you can only provide the input for the call, but the program counter is starting at 0 at the destination. The first thing that is executed at the destination (if the bytecode has been generated by the solidity compiler) is matching the first 4 bytes of the input data (function signature) with a location of a public function. Since internal functions are not part of this "switch", you'll not be able to call them.

See Solidity Assembly or Ethereum Yellow Paper.

call(g, a, v, in, insize, out, outsize)     

call contract at address a with input mem[in..(in+insize)) providing g gas 
and v wei and output area mem[out..(out+outsize))
returning 0 on error (eg. out of gas) and 1 on success

Additional Info: See "How to separate functions in evm bytecode?" for an example of the function selection bytecode.

For a deep dive, you can look at geth's implementation. Entry points are:

  • Thank you for the answer! I appreciate it. At the moment I do not understand any formal evidence of that. JUMP and JUMPI can be used in any stand alone assembly and they have as argument absolute addresses. The function D defined in yellow paper (9.4.2) which should compute the valid jump addresses), if I understand, asks for the presence of the JUMPDEST instruction in the place where you jump, but this do not prevent me to search for those codes and to jump there. Can you add any more detailed explaination about this? – Rick Park Jan 28 at 21:21
  • 1
    JUMP works only within your own contract. For your own bytecode, you can construct whatever you want. You could manually construct some bytecode without the solidity compiler. But if you wish to call an existing contract JUMP opcode will not help you, because you can only CALL/CALLCODE/DELEGATECALL the target contract and the execution at the target will start at program counter (PC) = 0 – ivicaa Jan 28 at 21:24
  • Thank you. Could you please give me a reference for this? Of course I think you are right (or ethereum did fail immediately), but I’d like to understand a formal demonstration/declaration or whatever. – Rick Park Jan 28 at 23:52
  • (I mean: about the “jump works only within your own contract”) – Rick Park Jan 29 at 0:26
  • See Yellow Paper (link in the answer) section 9, or more specific 9.4.3. This is the ultimate reference. – ivicaa Jan 29 at 6:15

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.