zl程序教程

您现在的位置是:首页 >  其他

当前栏目

破解以太坊 EVM 谜题1

破解 以太 谜题 EVM
2023-06-13 09:14:41 时间

本文作者:Ethernaut CTF[1]

EVM 谜题 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

以上是 EVM 谜题 1 的操作码,我们要设法直接跳转(JUMP)到由 JUMPDEST 操作码,即程序计数器(program counter, 简称 PC,即第一列上的数字 )08 位置上,否则就 REVERT 了。

我们克隆 evm-puzzles 代码库,安装依赖后,使用npx hardhat play开始闯关:

第一题:要求我们输入发送多少金额。

谜题分析

我们需要先了解 JUMP[2]操作码是如何工作的:

JUMP 指令改变了程序计数器,从而打破了执行的线性路径,转到了部署代码[3]中的另一个点。它被用来实现函数等功能。

请注意,我们要跳转的程序计数器是一个由 JUMPDEST 操作码标记的位置。

JUMP 将从哪里获得要跳转的值?你应该有所了解,每个操作都与堆栈、内存或存储空间相互作用。在此案例中,JUMP 操作将从栈中获取第一个值(记住,堆栈的工作方式是后进先出的栈 - LIFO),并将其作为参数来确定跳转的位置。

这个特定的值是由CALLVALUE[4]操作码添加到栈的,这是 EVM 执行的第一个操作码。

CALLVALUE 操作码是做什么的?它把当前调用的 "wei" 的值(发送的金额)推到栈中。

例如,如果我们在调用这个合约时,msg.value等于1000 wei,它将把3e8(十进制中 1000 的十六进制转换)推到栈。

所以我们需要找到正确的 wei 值传递给合约,以便使CALLVALUE操作码把正确的偏移量放入栈中,使其跳转到计数器 08 的JUMPDEST

解决方案

为了解决这个问题,我们必须调用合约,将msg.value等于8,通过这样做CALLVALUE将推到 EVM 堆栈8,该堆栈将被JUMP操作码弹出。通过这样做,程序计数器将跳到由JUMPDEST代表的第 8 条指令。

因此我们只需要输入 8.

结果如下:

你可以在 EVM Codes 网站上模拟一下谜题 1 的解决方案[5]

参考文章:https://stermi.xyz/blog/evm-puzzle-1-solution

参考资料

[1]

Ethernaut CTF: https://learnblockchain.cn/people/11048

[2]

JUMP: https://www.evm.codes/#56

[3]

代码: https://www.evm.codes/about

[4]

CALLVALUE: https://www.evm.codes/#34

[5]

谜题1的解决方案: https://www.evm.codes/playground?callValue=8&unit=Wei&callData=&codeType=Bytecode&code='3456FDFDFDFD5B00'_