Ethereum Opcodes

Ethereum 中的 opcodes 有 142 种,部分常见的 opcodes 如下所示:

Uint8
Mnomonic
Stack Input
Stack Output
Expression

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 函数并不是完整的质数检查函数,0001 也可以通过检查,因此我们可以构造如下的字节码:

来执行 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