本节摘要:聚合层的价值在广度,本节把广度铺开。第一部分过反编译引擎层:REA 驱动本地已装的 Hopper、Ghidra、IDA 取伪代码——引擎是你自己的,REA 只做调度与统一输出,双引擎互证是聚合层独有的玩法(IDA 为商业软件,使用需自行取得授权,本书不演示其细节)。之后逐类过对象:Electron 与 JS 应用(源码形态的分析,asar 包是典型入口)、Go 与 Rust 二进制(免装工具链的静态分析:符号、版本、字符串)、WASM 与 EVM 字节码(编译目标不同、分析方法同源)、APK 与固件(容器与镜像类的拆包前置)、pcap 与 HAR(观察类对象:分析的是行为记录不是程序本身)。每类给一个使用场景与命令形态示意,并配「怎么复核」的具体动作;最后一张决策图加一张总表把对象类型、分析什么、复核工具钉在一起。
REA 的反编译能力来自本地引擎:装了 Hopper 就能调 Hopper,开着 Ghidra 就能取 Ghidra 的伪代码,IDA 同理(商业软件,授权自行解决)。调度关系记一句话:引擎是你的,REA 只是派活与收口。
| 引擎 | 平台与定位 | 授权口径 |
|---|---|---|
| Ghidra | 跨平台,NSA 开源,本书第 01 章主角 | Apache-2.0,免费 |
| Hopper | macOS 为主的反汇编 / 反编译器 | 商业授权 |
| IDA | 老牌全功能逆向套件 | 商业授权(有免费版,功能受限) |
一句授权提醒再强调:聚合层只是「派活」,引擎的授权责任不转移——驱动 IDA 就要有 IDA 的授权,商业授权的边界以厂商条款为准。
对同一段代码让 REA 用不同引擎各取一次伪代码、互相印证,是聚合层独有的玩法:两个引擎对同个函数给出结构一致的伪 C,置信度立涨;不一致的地方,正好是你该亲自下场看的裂缝。复核动作:挑结论里最关键的一个函数,在 Ghidra(第 1.2 节流程)里自己走一遍反编译,比对结构。
互证的分工逻辑值得点破:不同引擎的分析器启发式不同——函数边界、类型推断、跳转表识别各有取舍。分歧不代表谁错,而是「这段代码对启发式不友好」,恰是需要人工判断的高价值位置。把「引擎分歧清单」单独记下来,是聚合层工作流里最容易被忽视、又最值钱的产出。
场景:拿到一个 Electron 打包的桌面工具,想知道它有没有偷偷上报数据。这类对象本质是 JS 源码或近源码形态(asar 归档),方法回到源码侧——但不必从头学:《语义代码检索》第 1 章《为什么 grep 不够》的符号检索思路照用,REA 把「解包、定位入口、追网络调用」串成一问。
典型提问顺序给一个模板:先问「程序的入口文件与主进程代码在哪」,再问「哪些模块发起网络请求、目标域名是什么」,最后问「上传的数据里包含哪些本地信息」。三问下来,一个 Electron 应用的数据面基本摊开。
# bash —— 分析 Electron 应用(命令形态示意,以官方文档为准) npx rea analyze ./tool.app --focus network --question "它向外发送哪些数据"
要点:JS 侧的结论同样要复核——打开解包产物亲自看那段 fetch / WebSocket 调用;混淆过的 JS,交给模型读时注明「混淆样本」,让它在结论里声明置信度。第 03~04 章的幻觉纪律在源码形态下一样生效。
JS 对象还有个免费优势:改动可验证。想确认「删掉这段上报代码后行为是否变化」,在解包产物里改完重打包(Electron 官方工具链支持)再跑一遍即可——这是二进制对象做不到的实验闭环,别浪费。
场景:客户环境里一个无源码的 Go 运维工具,要快速确认「它读哪些文件、连哪些地址」。Go/Rust 二进制自带运行时与符号痕迹(即便 stripped 也常残留版本串与函数名模式),REA 不要求你先装 Go / Rust 工具链即可做符号恢复与字符串分析——5.1 节的 hello-go 已示范过。
复核动作沿用第 02 章:r2 打开、izz 看字符串(URL、路径、版本串都在这)、ii 看导入。聚合层给的清单与这两条命令的输出对得上,结论可用。经验提示:Go 二进制的函数表很长(运行时全在里面),先问「业务入口与网络相关函数」这类聚焦问题,别上来就要全量清单。
Go/Rust 对象的另一个高价值问题是版本与构建信息:两族二进制常嵌着编译器版本、模块路径、构建标签,聚合层能直接给出「什么版本的工具链编出来的」。这类信息看着不起眼,在漏洞研究里常用来对照已知缺陷版本段——属于「问一句、值一句」的典型问题。
三类的共同点:都不是机器码,是某种字节码——分析方法同源(先反编译回可读形态再分析),目标不同。
| 对象 | 场景 | 分析什么 |
|---|---|---|
| WASM | 浏览器里的加密 / 授权逻辑模块 | 把 wasm 反编译回近似 C / 文本格式,找算法逻辑 |
| EVM 字节码 | 智能合约审计(自有或公开合约) | 函数选择器、存储读写、外部调用与权限检查 |
| APK | 自家应用的组件盘点、公开样本的行为理解 | 拆包看清单与 dex,与 Ghidra / 反编译器接力 |
# bash —— 字节码对象分析(命令形态示意,以官方文档为准) npx rea analyze ./module.wasm --question "其中的校验算法是什么" npx rea analyze ./contract.bin --question "列出合约的函数与权限检查"
纪律照旧:EVM 与 APK 的结论要落到可指认的证据(指令片段、清单条目),公开 CTF 与自家对象优先。WASM 的复核有个便宜技巧:把 wasm 转成文本格式(官方工具链或聚合层自带),模型说的每个函数名都能在文本里搜到。
EVM 对象的两条专属提醒:合约字节码要区分部署时与运行时(两者不同,拿错版本分析半天白费,以链上数据与官方文档为准);复核重点放在「谁能调用」而不是「调用什么」——权限检查缺失是模型最容易漏看的部分。
最后一类换了个性质:前面分析的都是程序,这两样分析的是记录。 固件是「一堆程序的容器」,pcap / HAR 是「一次行为的留痕」。
观察类对象还有一个纪律要单独强调:记录文件本身就是敏感数据。 抓包里可能有内网地址、账号令牌,HAR 里有会话凭据——这些文件的保管等级应当不低于样本本身,分享结论前先脱敏。
pcap 与 HAR 的分工顺带说清:pcap 是链路层起的全量包记录(含重传、乱序、非 HTTP 流量),HAR 是浏览器侧的请求响应记录(结构化、带请求头响应头)。看程序行为优先 HAR(可读性好),看有没有「夹带私货」的流量优先 pcap(覆盖全)。对象决定视角,两份都该留。
# bash —— 观察类对象(命令形态示意,以官方文档为准) npx rea analyze ./capture.pcap --question "对外通信的目标与内容摘要"
两类对象的复核姿势不同:固件的结论复核靠「把组件单独拿出来过工具」,pcap 的结论复核靠「回到原始抓包文件看那几条记录」——分析记录的结论,最终仍要以记录本身为证。
拿到陌生对象,先问形态再选入口。速记口诀一行:程序问引擎,源码问文本,记录问流量;容器先拆包,字节码先转译。
(文字流程图)对象是—— 原生二进制 ──▶ 引擎取伪代码(Ghidra 免费起步) JS / Electron ──▶ 解包后按源码分析 Go / Rust ──▶ 免工具链静态分析 + izz 复核 WASM / EVM / APK ──▶ 转可读格式再分析 固件 / pcap / HAR ──▶ 先拆容器或读记录,再回到程序分析
| 对象 | 分析什么 | REA 的角色 | 复核工具 |
|---|---|---|---|
| 原生二进制 | 伪代码与行为 | 调度本地引擎 | Ghidra / r2(第 01~02 章) |
| Electron/JS | 源码逻辑 | 解包与串联 | 解包产物 + 符号检索(《语义代码检索》第 1 章) |
| Go/Rust | 符号、字符串、结构 | 免工具链静态分析 | r2 的 izz / ii |
| WASM/EVM | 字节码逻辑 | 反编译回可读形态 | 文本格式逐段核对 |
| APK | 组件与行为 | 拆包与定位 | dex 工具链 + Ghidra |
| 固件 | 容器内容盘点 | 镜像拆解 | 对具体组件回到 Ghidra / r2 |
| pcap/HAR | 历史行为 | 流量与请求解读 | 原始抓包文件 |
总表按行念一遍就是本章的地图:每类对象一句话定位、一个复核出口。建议把这张表抄进自己的工作笔记,遇到新对象先对表再动手——比每次现场回忆可靠。
最后给一个自检问题收束本章实操:随手挑一个你手头的对象,能否十秒内说出它的形态、该走的入口、复核用的工具?说得出,本章就到手了;说不出,回决策图再走一遍。
用法心得一句:先用 REA 回答「这是什么、值不值得挖」,再用第 01~04 章的工具深挖。 广度归聚合层,深度归地基。
节奏上给一条「快慢结合」的工作流:快通道(REA)负责分诊与广度,一天能过几十个对象;慢通道(Ghidra / r2 工程化)只接收快通道筛出的重点,一个对象可能吃一天。两条通道之间用文件交接——快通道的结论连同证据落 JSON(字段沿用第 2.2 节约定),慢通道拿着 JSON 直接开工。这个「分诊台加手术室」的分工,是聚合层在本章语境下最正当的用法。
什么都能问、什么都答得快,这时最需要的是什么?是知道哪些答案可信。下一节拆 REA 的证据与局限输出设计,顺手学会一件更通用的事:怎么判断一个开源项目的真实成熟度。