一口气做完EVM Puzzle

EVM Puzzle 10道题

Puzzle 1

00      34      CALLVALUE
01      56      JUMP
02      FD      REVERT
03      FD      REVERT
04      FD      REVERT
05      FD      REVERT
06      FD      REVERT
07      FD      REVERT
08      5B      JUMPDEST     // <----跳转到这里
09      00      STOP

callvalue就是需要跳转的地址08,所以输入8即可

Puzzle 2

00      34      CALLVALUE
01      38      CODESIZE
02      03      SUB
03      56      JUMP
04      FD      REVERT
05      FD      REVERT
06      5B      JUMPDEST
07      00      STOP
08      FD      REVERT
09      FD      REVERT

codesize是10个字节,跳转地址是06,所以10 - callvalue = 6 ,输入4即可

Puzzle 3

00      36      CALLDATASIZE
01      56      JUMP
02      FD      REVERT
03      FD      REVERT
04      5B      JUMPDEST
05      00      STOP

跳转的地址是04,所以calldatasize必须是4,所以calldata长度需要达到4个字节,输入aabbccdd即可

Puzzle 4

00      34      CALLVALUE
01      38      CODESIZE
02      18      XOR
03      56      JUMP
04      FD      REVERT
05      FD      REVERT
06      FD      REVERT
07      FD      REVERT
08      FD      REVERT
09      FD      REVERT
0A      5B      JUMPDEST
0B      00      STOP

需要跳转的地址是0a, codesize = 0c,所以callvalue ^ 0c = 0a, 输入6即可

Puzzle 5

00      34          CALLVALUE
01      80          DUP1
02      02          MUL
03      610100      PUSH2 0100
06      14          EQ
07      600C        PUSH1 0C
09      57          JUMPI
0A      FD          REVERT
0B      FD          REVERT
0C      5B          JUMPDEST
0D      00          STOP
0E      FD          REVERT
0F      FD          REVERT

跳转条件要求callvalue *callvalue = 0x100 ,输入16即可

Puzzle 6

00      6000      PUSH1 00
02      35        CALLDATALOAD
03      56        JUMP
04      FD        REVERT
05      FD        REVERT
06      FD        REVERT
07      FD        REVERT
08      FD        REVERT
09      FD        REVERT
0A      5B        JUMPDEST
0B      00        STOP

跳转的地址是0a,CALLDATALOAD载入的是输入的前32字节。所以输入 0x000000000000000000000000000000000000000000000000000000000000000a即可

Puzzle 7

00      36        CALLDATASIZE
01      6000      PUSH1 00
03      80        DUP1
04      37        CALLDATACOPY
05      36        CALLDATASIZE
06      6000      PUSH1 00
08      6000      PUSH1 00
0A      F0        CREATE         //<---这里合约部署
0B      3B        EXTCODESIZE
0C      6001      PUSH1 01
0E      14        EQ
0F      6013      PUSH1 13
11      57        JUMPI
12      FD        REVERT
13      5B        JUMPDEST
14      00        STOP

要求部署合约的长度等于1。 涉及到合约的部署,一般合约简单是(参考 https://learnblockchain.cn/article/4867 里的MagicNumber 一节) :

/* 构造 开始*/
PUSH1 code_length
PUSH1 code_offset
PUSH1 memory_pos
CODECOPY
// memory[memory_pos:memory_pos+code_length] = 
// address(this).code[code_offset:code_offset+code_length]
PUSH1 code_length
PUSH1 memory_pos
RETURN
// return memory[memory_pos:memory_pos+code_length]
/* 构造结束 */
/* 执行开始,返回42 = 2A */
PUSH1 value
PUSH1 memory_pos
MSTORE
// memory[memory_pos:memory_pos+32] = value
PUSH1 value_length
PUSH1 memory_pos
RETURN
// return memory[memory_pos:memory_pos+value_length]
/* 执行结束 */

所以我们只需要让code_length=1即可,内容就一个简单的STOP指令

PUSH1   01   // 60 01
PUSH1   0c   // 60 0c
PUSH1   40   // 60 40
CODECOPY     // 39
PUSH1   01   // 60 01
PUSH1   40   // 60 40
RETURN       // f3
STOP         // 00
0x6001600c60403960016040f300

输入0x6001600c60403960016040f300即可

Puzzle 8

00      36        CALLDATASIZE
01      6000      PUSH1 00
03      80        DUP1
04      37        CALLDATACOPY
05      36        CALLDATASIZE
06      6000      PUSH1 00
08      6000      PUSH1 00
0A      F0        CREATE
0B      6000      PUSH1 00
0D      80        DUP1
0E      80        DUP1
0F      80        DUP1
10      80        DUP1
11      94        SWAP5
12      5A        GAS
13      F1        CALL
14      6000      PUSH1 00
16      14        EQ
17      601B      PUSH1 1B
19      57        JUMPI
1A      FD        REVERT
1B      5B        JUMPDEST
1C      00        STOP

同上,要求合约执行失败,所以把上面合约的最后一个STOP指令换成REVERT即可

0x6001600c60403960016040f3fd

Puzzle 9

00      36        CALLDATASIZE
01      6003      PUSH1 03
03      10        LT
04      6009      PUSH1 09
06      57        JUMPI
07      FD        REVERT
08      FD        REVERT
09      5B        JUMPDEST
0A      34        CALLVALUE
0B      36        CALLDATASIZE
0C      02        MUL
0D      6008      PUSH1 08
0F      14        EQ
10      6014      PUSH1 14
12      57        JUMPI
13      FD        REVERT
14      5B        JUMPDEST
15      00        STOP

前面三行,要求calldatasize > 3,后面要求callvalue * calldatasize == 8 ,所以我们可以让calldatasize=4callvalue=2。输入2, 0xaabbccdd即可

Puzzle 10

00      38          CODESIZE
01      34          CALLVALUE
02      90          SWAP1
03      11          GT
04      6008        PUSH1 08
06      57          JUMPI
07      FD          REVERT
08      5B          JUMPDEST
09      36          CALLDATASIZE
0A      610003      PUSH2 0003
0D      90          SWAP1
0E      06          MOD
0F      15          ISZERO
10      34          CALLVALUE
11      600A        PUSH1 0A
13      01          ADD
14      57          JUMPI
15      FD          REVERT
16      FD          REVERT
17      FD          REVERT
18      FD          REVERT
19      5B          JUMPDEST
1A      00          STOP

codesize==0x1B,要求callvalue < 0x1B,后面要求calldatasize % 3 ==0,接着要求callvalue + 0xa == 0x19 所以callvalue = 15calldata长度是3字节即可,输入:15, 0xaabbcc即可。


有问题欢迎留言,一起探讨

本文参与区块链技术网 ,好文好收益,欢迎正在阅读的你也加入。

  • 发表于 2022-10-12 15:31
  • 阅读 ( 220 )
  • 学分 ( 10 )
  • 分类:公链

评论