破解以太坊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操作码是如何工作的:
JUMP指令改变了程序计数器,从而打破了执行的线性路径,转到了部署代码中的另一个点。它被用来实现函数等功能。
请注意,我们要跳转的程序计数器是一个由JUMPDEST操作码标记的位置。
JUMP将从哪里获得要跳转的值?你应该有所了解,每个操作都与堆栈、内存或存储空间相互作用。在此案例中,JUMP操作将从栈中获取第一个值(记住,堆栈的工作方式是后进先出的栈 - LIFO),并将其作为参数来确定跳转的位置。
这个特定的值是由CALLVALUE操作码添加到栈的,这是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的解决方案。
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!