32 lines
2.8 KiB
Markdown
32 lines
2.8 KiB
Markdown
### 讲一讲区块链逆向函数涉及到的接收参数的指令集
|
|
|
|
当你在逆向一个 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`**: 这是一个判断指令,用于检查栈顶的值是否为零。在处理参数时,它通常用于检查某个参数是否为空或为0
|
|
- **`JUMPI`**: 这是一个条件跳转指令。它接收两个参数:一个目标地址和一个条件。如果条件非零,程序执行流将跳转到目标地址
|
|
- **逆向分析中的应用**: 你会看到 `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` 指令时,它通常意味着一个参数正在被复制到内存中 |