第 46 章 区块链与智能合约逆向(EVM)
区块链世界的一切"规则"都是代码:智能合约是不可篡改的公开二进制,攻击事件(DAO、Ronin、闪电贷攻击)全是逆向的结果。本章讲 EVM 合约逆向、区块链取证、攻击面理解。
📍 知识点地图 | 主题:区块链逆向 | 前置:第9章 | 后续:— | 核心概念:EVM、Storage、代理合约、漏洞模式
46.1 为什么逆向智能合约
□ 审计: 上线前找漏洞(价值以亿计)
□ 攻击复盘: 事件后还原攻击手法
□ 取证: 追踪被盗资金
□ 分析: 匿名合约到底是什么(蜜罐/钓鱼/机器人)
□ 竞赛: 区块链 CTF(Ethernaut/Damn Vulnerable DeFi)
46.2 EVM 基础知识(逆向的前提)
EVM = 以太坊虚拟机(256 位栈机)
核心结构:
Stack(栈,最多 1024 深)
Memory(内存,临时数据)
Storage(持久存储,键值对,合约状态)
交易执行:
调用者 → 合约地址 + calldata(函数选择器+参数)
函数选择器: 前 4 字节 = keccak256("transfer(address,uint256)")[:4]
Gas 模型: 每条指令有成本(逆向时可推断热/冷路径)
字节码 vs 操作码
合约部署后是字节码(如 0x608060405234801561001057600080fd...)
操作码(opcode): 60=PUSH1 80=DUP1 54=SLOAD 55=SSTORE 01=ADD 10=EXP...
工具自动反汇编: 0x60 → PUSH1 0x80
46.3 EVM 逆向工具链
| 工具 | 用途 |
|---|---|
| Etherscan 页面 | 合约源码/字节码/反编译(在线第一站) |
| Panoramix (Etherscan) | 在线反编译为伪代码(够用) |
| Dedaub | 专业反编译(质量最好) |
| Porosity / Octopus | 反编译/框架 |
| EVM disassembler | 字节码 → 操作码文本 |
| Mythril | 符号执行找漏洞(自动) |
| Slither | 静态分析(有源码时) |
| Foundry | 测试/复现(cast 调用) |
| Rattle | 控制流图重建 |
46.4 无源码合约逆向标准流程
1. 获取字节码(Etherscan → Contract → Code)
2. 识别函数签名(4 字节选择器 ↔ 已知函数)
→ 工具: 4byte 目录(4byte.directory)查询选择器
→ 暴力: 尝试常见函数名组合计算 keccak
3. 反汇编/反编译(Panoramix/Dedaub)
4. 恢复 Storage 布局(变量 slot 位置)
5. 恢复控制流(函数入口 → 逻辑分支)
6. 验证: 用 Foundry/cast 调用合约对比行为
关键逆向目标(Storage)
Storage slot 分配规则(重要!):
uint256/地址/布尔 等静态变量 → 顺序 slot
动态数组 → slot 存长度,元素在 keccak(slot)
mapping → keccak(key . slot)
结构体 → 按 32 字节打包
代理合约 → 状态在代理,逻辑在实现(slot 0 = 实现地址)
读取: cast storage <addr> <slot>
46.5 常见智能合约漏洞(攻击面知识)
| 漏洞 | 原理 | 著名事件 |
|---|---|---|
| 重入攻击 | 外部调用期间状态未更新 | DAO 攻击(2016) |
| 整数溢出/下溢 | 0.8 之前无默认检查 | 各种 |
| 闪电贷组合 | 原子性借款+攻击 | 多次 DeFi 攻击 |
| 预言机操纵 | 价格源被操控 | 多次 |
| 权限缺陷 | owner/管理员函数未保护 | 各种 Rug Pull |
| 代理初始化缺陷 | 未锁初始化 → 抢走 owner | Parity 冻结 |
| 签名重放 | 签名未含 nonce/chainId | 多链事件 |
| 精度损失 | 除零/舍入 | 各种 |
逆向审计要点:在无源码合约里找这些模式(外部调用 CALL → 关注状态更新顺序;SLOAD/SSTORE 顺序 → 重入窗口;DELEGATECALL → 代理逻辑)。
46.6 代理合约分析(升级合约专项)
原理: 代理(Proxy)把调用 DELEGATECALL 转发给实现合约
→ 状态在代理,逻辑在实现
→ 升级 = 换实现地址
识别:
合约里大量 DELEGATECALL
fallback 函数路由所有调用
slot 0 存实现地址
逆向要点:
1. 读 slot 0 → 找到实现合约地址
2. 分开分析代理(路由)与实现(逻辑)
3. 检查实现合约的可升级性(谁控制升级 = 谁拥有资产)
46.7 区块链取证
□ 追踪资金: 交易图(Etherscan 深度追踪/GraphSense/Elliptic)
□ 地址聚类: 交易所/混币器/跨链桥关联
□ 时间线: 攻击交易 → 资金流向还原攻击链
□ 合约交互: 攻击合约分析(Flashbots 交易的 calldata 还原)
□ 链上预言机价格操纵: 对比操纵前后价格
46.8 EVM 逆向决策树
拿到合约字节码/地址
├─ 有源码? → 静态分析(Slither)+ 审计模式
├─ 无源码 → 反编译(Panoramix/Dedaub)
│ ├─ 识别函数签名(4byte 目录)
│ ├─ 恢复 storage 布局(cast storage)
│ └─ 分析关键函数逻辑(重入/权限/代理)
├─ 需要自动找漏洞? → Mythril 符号执行
├─ 需要验证行为? → Foundry cast 调用
└─ 事件分析 → 交易图 + 时间线
动手练习
- 在 Etherscan 找一个无源码合约(或从 CTF 题目获取),用 Panoramix 反编译,识别出全部函数。
- 用 4byte.directory 查询一个函数选择器,练习"选择器 ↔ 函数名"还原。
- 用 cast 读取一个合约的 storage,对照反编译结果恢复关键变量。
- 玩 Ethernaut(区块链 CTF 入门),完成 3 关,体会重入/权限/代理漏洞。
深入阅读
- 仓库:
skills/reverse-engineering/patterns*.md(计算类模式:字节-at-a-time、CVP/LLL——数学攻击通用) - 仓库:
skills/reverse-engineering/crypto-decode-tools.md(哈希/签名工具) - 仓库:
CTF-Sandbox-Orchestrator/competition-crypto-mobile/(密码学 CTF 子技能) - 外部资源:Ethernaut(OpenZeppelin)、Damn Vulnerable DeFi、4byte.directory