一口气做完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=4
,callvalue=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 = 15
, calldata
长度是3字节即可,输入:15, 0xaabbcc
即可。
有问题欢迎留言,一起探讨
本文参与区块链技术网 ,好文好收益,欢迎正在阅读的你也加入。
- 发表于 2022-10-12 15:31
- 阅读 ( 220 )
- 学分 ( 10 )
- 分类:公链
评论