Challenge:
Our fourth challenge is located in /puzzles/puzzle_4.json. Challenge 4 contains the following:
{
"code": "34381856FDFDFDFDFDFD5B00",
"askForValue": true,
"askForData": false
}
Hint 1:
The corresponding EVM opcodes are:
CALLVALUE
CODESIZE
XOR
JUMP
REVERT
REVERT
REVERT
REVERT
REVERT
REVERT
JUMPDEST
STOP
Hint 2:
CALLVALUE takes the value of the current call in wei
and places it on top of the stack.
CODESIZE takes the size of the code
and places it on the top of the stack.
XOR performs a bitwise xor on the top 2
values on the stack and pushes the result
to the top of the stack.
How can we JUMP over the 6 REVERT
opcodes and land on the JUMPDEST?
Hint 3:
The CODESIZE is 12 or c in Hex
1 2 3 4 5 6 7 8 9 a b c
34 38 18 56 FD FD FD FD FD FD 5B 00
Hint 4:
X ^ 0x0C = JUMPDEST offset
Solve for X
Hint 5:
CALLVALUE //Offset 0
CODESIZE //Offset 1
XOR //Offset 2
JUMP //Offset 3
REVERT //Offset 4
REVERT //Offset 5
REVERT //Offset 6
REVERT //Offset 7
REVERT //Offset 8
REVERT //Offset 9
JUMPDEST //Offset a
STOP //Offset b
Solution:
To solve this level, we just need to pass in a value of 6
wei. This way CALLVALUE places 6 on the top of the stack.
CODESIZE will then push 'c' to the top of the stack.
XOR will perform 6 ^ 'c' and push 'a' to the top of the stack
and JUMP performs a valid jump over the REVERT calls to JUMPDEST.
Challenge:
Our third challenge is located in /puzzles/puzzle_3.json. Challenge 3 contains the following:
{
"code": "3656FDFD5B00",
"askForValue": false,
"askForData": true
}
Hint 1:
The corresponding EVM opcodes are:
CALLDATASIZE
JUMP
REVERT
REVERT
JUMPDEST
STOP
Hint 2:
CALLDATASIZE takes size of the calldata
and places it on top of the stack.
How can we JUMP over the 2 REVERT
opcodes and land on the JUMPDEST?
Hint 3:
CALLDATASIZE //Offset 0
JUMP //Offset 1
REVERT //Offset 2
REVERT //Offset 3
JUMPDEST //Offset 4
STOP //Offset 5
Solution:
To solve this level, we just need to pass in a 4 bytes of call data.
(i.e. 0xaaaaaaaa) This way CALLDATASIZE places 4 on the top of the stack.
JUMP then performs a valid jump over the REVERT calls to JUMPDEST.
Challenge:
Our second challenge is located in /puzzles/puzzle_2.json. Challenge 2 contains the following:
{
"code": "34380356FDFD5B00FDFD",
"askForValue": true,
"askForData": false
}
Hint 1:
The corresponding EVM opcodes are:
CALLVALUE
CODESIZE
SUB
JUMP
REVERT
REVERT
JUMPDEST
STOP
REVERT
REVERT
Hint 2:
CALLVALUE takes the value of the current call in wei
and places it on top of the stack.
CODESIZE takes the size of the code
and places it on the top of the stack.
SUB subtracts the second value on the stack
from the value on the top of the stack.
How can we JUMP over the 2 REVERT
opcodes and land on the JUMPDEST?
Hint 3:
The CODESIZE is 10 or a in Hex
1 2 3 4 5 6 7 8 9 a
34 38 03 56 FD FD 5B 00 FD FD
Hint 4:
CALLVALUE //Offset 0
CODESIZE //Offset 1
SUB //Offset 2
JUMP //Offset 3
REVERT //Offset 4
REVERT //Offset 5
JUMPDEST //Offset 6
STOP //Offset 7
REVERT //Offset 8
REVERT //Offset 9
Solution:
To solve this level, we just need to pass in a value of 4
wei. This way CALLVALUE places 4 on the top of the stack.
CODESIZE will then push 'a' to the top of the stack.
SUB will subtract 4 from 'a' and push 6 to the top of the stack
and JUMP performs a valid jump over the REVERT calls to JUMPDEST.
Setting up the environment:
- First things first, clone the EVM puzzles repo. This contains all of the challenges we’ll be going through to improve our understanding of EVM byetecode.
- Get familiar with the tools we’ll be using by reading through the hardhat docs and playing around with evm.codes
- Optional: Read and walkthrough 1st portion of noxx’s EVM series
Challenge:
Our first challenge is located in /puzzles/puzzle_1.json. Challenge 1 contains the following:
{
"code": "3456FDFDFDFDFDFD5B00",
"askForValue": true,
"askForData": false
}
Hint 1:
The "code" section contains EVM bytecode.
Try converting that to opcodes.
(one way is to drop the bytecode into evm.codes)
Hint 2:
The corresponding EVM opcodes are:
CALLVALUE
JUMP
REVERT
REVERT
REVERT
REVERT
REVERT
REVERT
JUMPDEST
STOP
The goal of this challenge is to not cause a revert.
Hint 3:
CALLVALUE takes the value of the current call in wei
and places it on top of the stack.
JUMP takes the value on the top of the stack and moves
the program counter to the offset of that value.
How can we JUMP over the 6 REVERT
opcodes and land on the JUMPDEST?
Hint 4:
Each of the opcodes are 1 byte in size
Hint 5:
CALLVALUE //Offset 0
JUMP //Offset 1
REVERT //Offset 2
REVERT //Offset 3
REVERT //Offset 4
REVERT //Offset 5
REVERT //Offset 6
REVERT //Offset 7
JUMPDEST //Offset 8
STOP
Solution:
To solve this level, we just need to pass in a value of 8
wei, so that CALLVALUE places 8 on the top of the stack
and JUMP performs a valid jump over the REVERT calls to JUMPDEST.