Ethereum Opcodes
Ethereum 中的 opcodes 有 142 种,部分常见的 opcodes 如下所示:
00
STOP
-
-
STOP()
01
ADD
| a | b |
| a + b |
a + b
02
MUL
| a | b |
| a * b |
a * b
03
SUB
| a | b |
| a - b |
a - b
04
DIV
| a | b |
| a // b |
a // b
51
MLOAD
| offset |
| value |
value = memory[offset:offset+32]
52
MSTORE
| offset | value |
-
memory[offset:offset+32] = value
54
SLOAD
| key |
| value |
value = storage[key]
55
SSTORE
| key | value |
-
storage[key] = value
56
JUMP
| destination |
-
$pc = destination
5B
JUMPDEST
-
-
-
F3
RETURN
| offset | length |
-
return memory[offset:offset+length]
FD
REVERT
| offset | length |
-
revert(memory[offset:offset+length])
!!! info JUMPDEST 是跳转指令的 destination,跳转指令不能跳转到没有 JUMPDEST 的地方。
更多的详细 opcodes 信息可以查看 ethervm.io。
例子
以 startCTF 2021 的 StArNDBOX 一题为例讲解一下 opcodes 的题目。
本题会在部署挑战合约的时候传入 100 wei 到合约中,我们的目标是将合约的 balance 清空。题目合约的源码如下:
可以看到题目的 StArNDBoX
函数可以获取任意地址的合约并检测该合约的每个字节是否为质数,如果通过检查则使用 delegatecall
来调用目标合约。
但由于该合约中的 isPrime
函数并不是完整的质数检查函数,00
和 01
也可以通过检查,因此我们可以构造如下的字节码:
来执行 address(0x0001).call.gas(0xfbfb).value(0x0065 - 0x0001)
语句,也就是将题目合约中的 balance 转到 0x1 处,从而清空 balance 满足得到 flag 的条件。
题目
starCTF 2021
题目名称 StArNDBOX
RealWorld 2019
题目名称 Montagy
QWB 2020
题目名称 EasySandbox
题目名称 EGM
华为鲲鹏计算 2020
题目名称 boxgame
!!! note 注:题目附件相关内容可至 ctf-challenges/blockchain 仓库寻找。
参考
Last updated