讲一讲区块链逆向函数涉及到的接收参数的指令集
当你在逆向一个 EVM 字节码时,你会发现函数参数的传递和处理主要涉及到以下几种指令集和概念:
1. CALLDATALOAD
和 CALLDATASIZE
CALLDATALOAD
: 这个指令用于从交易的调用数据(calldata)中加载参数。calldata
是一个只读的、外部调用的数据区域,它存储了函数选择器(Function Selector)和所有传入的参数。CALLDATALOAD
接收一个内存偏移量作为参数,然后从该偏移量处加载一个32字节(256位)的数据到栈顶- 逆向分析中的应用: 当你看到一个
CALLDATALOAD
指令时,你需要查看它加载的偏移量0x04
偏移量通常是第一个参数的开始。这是因为前4个字节(0x00
到0x03
)是函数选择器,用于识别要调用的函数- 随后的偏移量(例如
0x24
、0x44
等)则对应后续的参数
- 逆向分析中的应用: 当你看到一个
CALLDATASIZE
: 这个指令用于获取calldata
的总大小。在逆向分析中,它通常用于进行边界检查,确保传入的参数数量和大小是正确的
2. ISZERO
和 JUMPI
ISZERO
: 这是一个判断指令,用于检查栈顶的值是否为零。在处理参数时,它通常用于检查某个参数是否为空或为0JUMPI
: 这是一个条件跳转指令。它接收两个参数:一个目标地址和一个条件。如果条件非零,程序执行流将跳转到目标地址- 逆向分析中的应用: 你会看到
ISZERO
和JUMPI
常常配合使用,用于函数签名检查。当函数签名(前4个字节)与预期的签名不匹配时,JUMPI
就会将程序跳转到错误处理代码块,如revert
或invalid jump
。这是逆向分析中识别不同函数入口点的关键
- 逆向分析中的应用: 你会看到
3. EQ
, LT
, GT
(比较指令)
EQ
: 比较栈顶的两个值是否相等LT
: 比较栈顶的第一个值是否小于第二个值GT
: 比较栈顶的第一个值是否大于第二个值- 逆向分析中的应用: 这些比较指令经常用于对传入的参数进行验证,例如检查一个数值参数是否在某个范围内,或者一个地址参数是否等于合约所有者的地址
4. MSTORE
和 MLOAD
虽然这两个指令不直接用于接收参数,但在处理和使用参数时它们是不可或缺的
MSTORE
: 将栈顶的32字节数据存储到指定的内存(Memory)位置MLOAD
: 从指定的内存位置加载32字节数据到栈顶- 逆向分析中的应用: 传入的参数通常会先从
calldata
加载到栈上,然后使用MSTORE
存储到内存中以供后续计算或处理。当你看到一个MSTORE
指令时,它通常意味着一个参数正在被复制到内存中
- 逆向分析中的应用: 传入的参数通常会先从