逆向工程工作流指南
工具矩阵 速查
● 实操工作流

逆向 App 与网站
可落地工作流指南

把散落的开源逆向工具,串成一条从侦察到复现、可复核的流程 —— 覆盖原生二进制、Android、iOS、Web/JS 与 Electron。

10 个章节 5 类目标 5 个工作流阶段 开源工具链

这是一份按目标类型组织的实操工作流,把散落的开源逆向工具串成"侦察 → 静态 → 动态 → 协议 → 复现"的可重复流程。默认你已经在用 REA 做统一证据与静态/受控动态分析,这里补充的是它不覆盖或覆盖较弱的环节:动态插桩、抓包改包、脱壳、JS 反混淆与补环境、符号执行。

每个场景的验收标准是同一条:能在脱离原环境的情况下,独立复现出目标的某个可观测行为,并留下可复核的证据。


1. 工具矩阵速查#

按"你在干什么"查,不按工具分类查。

我需要的动作 首选工具 仓库 备注
反编译原生二进制 Ghidra NationalSecurityAgency/ghidra 多架构、免费、可脚本化
命令行批量逆向 radare2 / rizin radareorg/radare2 · rizinorg/rizin 适合自动化与 CI
图形化 r2 前端 Cutter rizinorg/cutter rizin 官方 GUI
解析/改写 ELF·PE·Mach-O LIEF lief-project/LIEF 改二进制、加段、重签名
指令级仿真 Unicorn unicorn-engine/unicorn 算法抽取神器
反汇编引擎(自研工具用) Capstone capstone-engine/capstone 很多工具的地基
符号执行 / 约束求解 angr angr/angr 自动找输入、解校验
动态 Hook(全平台) Frida frida/frida 移动端逆向第一工具
免越狱/免 Root 利用 objection sensepost/objection Frida 的上层封装
Android Hook 框架 LSPosed LSPosed/LSPosed 需 Root/Magisk
Android Root Magisk topjohnwu/Magisk 现代 Root 标准方案
APK 反编译到 Java jadx skylot/jadx 可读性最好
APK 解包 / 重打包 Apktool iBotPeaches/Apktool 改资源、改 smali
内存脱壳 frida-dexdump hluwa/frida-dexdump 对抗加固
移动 App 自动化审计 MobSF MobSF/Mobile-Security-Framework-MobSF 静态+动态一体
iOS 砸壳导 IPA frida-ios-dump AloneMonkey/frida-ios-dump iOS 静态前置步骤
导 ObjC 头文件 class-dump nygard/class-dump 恢复类与方法签名
HTTPS 抓包 / 改包 mitmproxy mitmproxy/mitmproxy 可编程,脚本化首选
流量协议分析 Wireshark wireshark/wireshark 非 HTTP、底层协议
Web 安全扫描 OWASP ZAP zaproxy/zaproxy 开源 Burp 替代
拦截调试 HTTP(S) HTTP Toolkit httptoolkit/httptoolkit 桌面端体验好
浏览器自动化 Playwright microsoft/playwright 反检测能力优于 Selenium
浏览器自动化(CDP 直连) Puppeteer puppeteer/puppeteer 贴近 Chrome DevTools 协议
Node 端 DOM 补环境 jsdom jsdom/jsdom JS 逆向"补环境"主力
JS 格式化 / 美化 js-beautify beautifier/js-beautify 第一步永远是格式化
AST 级还原改写 Babel babel/babel 用 @babel/parser+traverse 写还原脚本
webpack 打包还原 webcrack j4k0xb/webcrack 一键拆 bundle
了解混淆手法 javascript-obfuscator javascript-obfuscator/javascript-obfuscator 知道怎么混淆才会反
Electron 资源解包 @electron/asar electron/asar 解 app.asar
自动化沙箱 CAPEv2 kevoreilly/CAPEv2 Cuckoo 的活跃分支
让 LLM 直连反编译器 GhidraMCP LaurieWired/GhidraMCP 与 REA 互补
同上(IDA) ida-pro-mcp mrexodia/ida-pro-mcp 需 IDA Pro

选用原则:能静态解决就不上动态,能动态观察就不硬猜算法。 动静结合是为了互相验证,不是二选一。


2. 通用工作流骨架:五阶段#

所有场景都套这个骨架,只是每阶段的工具不同。

阶段一 · 侦察(Recon)#

确定"这是什么、跑在哪、有多少东西要看"。产出范围清单,而不是结论。

阶段二 · 静态(Static)#

不运行目标,抽取结构。产出符号、调用关系、字符串、常量。

阶段三 · 动态(Dynamic)#

在真实运行时观察与干预。产出真实参数与返回值的观测记录。

阶段四 · 协议(Protocol)#

把"App 在做什么"翻译成"接口与数据格式"。产出可独立调用的请求模板。

阶段五 · 复现(Verify)#

这是判断"是否真懂"的唯一标准。 产出脱离原环境的可运行脚本。

不要把"能看懂"当成"已完成"。 看懂只是阶段二结束。


3. 场景 A · 原生二进制与桌面 App#

适用:macOS .app、Windows .exe/.dll、Linux ELF、命令行工具。

阶段 动作 工具 产出
侦察 架构/依赖/加固识别 file otool -L LIEF 架构、依赖清单、加载路径
静态 导入 Ghidra,跑自动分析 Ghidra、radare2 函数列表、伪代码、xref
静态 定位关键字符串与常量 Ghidra、REA search_strings 特征字符串 → 函数
动态 Hook 关键函数看真实数据 Frida、LLDB、REA observe_native_calls 入参/返回值样本
协议 抓网络与 IPC mitmproxy、Wireshark 请求模板
复现 抽取纯算法独立运行 Unicorn、pwntools 可独立运行的算法实现

关键命令

# 侦察:macOS 架构与依赖
file ./Target.app/Contents/MacOS/Target
otool -L ./Target.app/Contents/MacOS/Target
otool -hv ./Target.app/Contents/MacOS/Target   # 看 PIE / 加固标志

# 用 LIEF 列依赖与导出(Python)
python3 -c "
import lief
b = lief.MachO.parse('Target').at(0)
print([str(l.name) for l in b.libraries])
print([s.name for s in b.exported_symbols][:20])
"
// Frida:Hook 一个导出函数,打印入参与返回值
const addr = Module.findExportByName(null, 'verify_license');
Interceptor.attach(addr, {
  onEnter(args) { console.log('arg0 =', args[0].readUtf8String()); },
  onLeave(ret) { console.log('ret  =', ret.toInt32()); }
});
# 复现:用 Unicorn 跑一段抽取出来的算法
from unicorn import Uc, UC_ARCH_ARM64, UC_MODE_ARM
from unicorn.arm64_const import UC_ARM64_REG_X0
uc = Uc(UC_ARCH_ARM64, UC_MODE_ARM)
uc.mem_map(0x1000, 0x1000)
uc.mem_write(0x1000, code_bytes)
uc.emu_start(0x1000, 0x1000 + len(code_bytes))
print(hex(uc.reg_read(UC_ARM64_REG_X0)))

常见坑


4. 场景 B · Android App#

适用:APK、AAB、带加固的商业 App。

阶段 动作 工具 产出
侦察 解包看 Manifest/权限/SDK Apktool、aapt2 组件、权限、第三方 SDK 清单
静态 DEX → Java 反编译 jadx 可读源码树
静态 代码级分析/引用追踪 androguard、REA 调用链、字符串
脱壳 内存 dump 真实 DEX frida-dexdump、BlackDex 脱壳后的 DEX
动态 Hook 方法看真实参数 Frida、LSPosed 参数样本
协议 抓包 + 绕过证书固定 mitmproxy + Frida 请求模板
复现 脚本化调用 requests、Playwright 独立可运行客户端

关键命令

# 侦察:解包 + 看 Manifest
apktool d target.apk -o target_src
grep -E "package=|android:name=" target_src/AndroidManifest.xml | head -20
# 快速看权限与 SDK
aapt2 dump badging target.apk | head -20

# 静态:jadx 反编译(带资源)
jadx -d out_jadx --show-bad-code target.apk
// Frida:绕过常见证书固定(OkHttp / TrustManager)
Java.perform(function () {
  const X509TrustManager = Java.use('javax.net.ssl.X509TrustManager');
  const TrustManagerImpl = Java.use('com.android.org.conscrypt.TrustManagerImpl');
  TrustManagerImpl.verifyChain.implementation = function (untrusted, trusted, host, clientAuth, ocsp) {
    console.log('[+] bypass pinned chain for', host);
    return untrusted;
  };
});
# 脱壳:附加到进程,dump 内存中的 DEX
frida-dexdump -U -f com.example.app

常见坑


5. 场景 C · iOS App#

适用:.ipa、越狱设备或已砸壳的 Mach-O。

阶段 动作 工具 产出
侦察 解压 IPA,定位主二进制 unzip、REA project_apple_application_graph 可执行文件路径、嵌套 bundle
砸壳 从内存导出解密后的 Mach-O frida-ios-dump 可静态分析的主二进制
静态 导 ObjC 头文件 class-dump、Ghidra 类/方法签名
静态 Swift 符号还原 REA analyze_swift_types 类型与归属
动态 Hook ObjC 方法 / C 函数 Frida 参数样本
协议 抓包 mitmproxy + SSL Kill Switch 请求模板

关键命令

# 侦察:解压 IPA
unzip -o target.ipa -d ipa_out
ls ipa_out/Payload/*.app/

# 砸壳:导出解密后的 IPA
python3 frida-ios-dump/dump.py -u -o decrypted.ipa "TargetApp"
# 静态:导 ObjC 头文件
class-dump -H ipa_out/Payload/Target.app/Target -o headers/
grep -rn "isPremium\|verifyReceipt" headers/ | head
// Frida:Hook ObjC 类方法
if (ObjC.available) {
  const cls = ObjC.classes.NSString;
  Interceptor.attach(cls['- containsString:'].implementation, {
    onEnter(args) {
      const self = new ObjC.Object(args[0]);
      const other = new ObjC.Object(args[2]);
      console.log('[NSString containsString:]', self.toString(), '|', other.toString());
    }
  });
}

常见坑


6. 场景 D · 网站 / Web / JavaScript#

适用:网页接口逆向、签名算法还原、爬虫与自动化。

阶段 动作 工具 产出
侦察 资源清单、sourcemap、接口枚举 DevTools、Playwright 路由表、脚本清单
抓包 记录请求与响应 mitmproxy、HTTP Toolkit 原始请求/响应
定位 从请求参数反查生成函数 DevTools 断点、debugger 关键函数位置
反混淆 格式化、AST 还原、拆 bundle js-beautify、Babel、webcrack 可读代码
补环境 让加密函数脱离浏览器运行 jsdom、Node vm 可独立调用的算法
复现 构造完整请求 requests、Playwright 可运行客户端

关键命令

# 抓包:mitmproxy 录制为可读流
mitmproxy -p 8080 --save-stream-file flows.mitm
# 回放/导出为 HAR 供离线分析
mitmdump -nr flows.mitm --set hardump=out.har
# 反混淆:先拆 webpack bundle,再格式化
npx webcrack bundle.js -o unpacked/
npx js-beautify unpacked/*.js -o beautified/
// 用 Babel 做 AST 级还原:把 a["b"] 形式的成员访问还原为 a.b
const parser = require('@babel/parser');
const traverse = require('@babel/traverse').default;
const generate = require('@babel/generator').default;

const ast = parser.parse(source);
traverse(ast, {
  MemberExpression(path) {
    const { computed, property } = path.node;
    if (computed && property.type === 'StringLiteral' && /^[A-Za-z_$][\w$]*$/.test(property.value)) {
      path.node.computed = false;
      path.node.property = { type: 'Identifier', name: property.value };
    }
  }
});
console.log(generate(ast).code);
// 补环境:在 Node 里给出加密函数所需的最小浏览器环境
const { JSDOM } = require('jsdom');
const dom = new JSDOM('<!doctype html><html><body></body></html>', {
  url: 'https://target.example.com/',
  pretendToBeVisual: true
});
global.window = dom.window;
global.document = dom.window.document;
global.navigator = dom.window.navigator;   // 注意:navigator 可能需手动伪造字段
global.location = dom.window.location;

// 此后加载目标脚本,调用其加密函数
require('./beautified/sign.js');
console.log(global.window.sign('payload'));

常见坑


7. 场景 E · Electron 桌面应用#

Electron 应用 = 一个 Node 主进程 + 一个 Chromium 渲染进程,两条路都能逆。

阶段 动作 工具 产出
侦察 解包 app.asar @electron/asar 全部前端源码
静态 读主进程与 preload REA analyze_javascript_application IPC 通道与暴露 API
动态 开 DevTools / 连 CDP REA inspect_electron_page、capture_electron_scenario 运行时脚本与 DOM
协议 抓渲染进程网络 mitmproxy 接口

关键命令

# 解包 asar
npx @electron/asar extract app.asar ./app_unpacked
ls app_unpacked/
# 找 IPC 通道与主进程逻辑
grep -rn "ipcMain.handle\|ipcRenderer.invoke\|contextBridge" app_unpacked/ | head -20

常见坑


8. 证据沉淀:如何与 REA 对齐#

工具跑完会散落一堆日志、截图、脚本。价值不在于跑过,而在于可复核。 建议每个阶段固定产出:

阶段 必须留下的证据 对应 REA 能力
侦察 文件哈希、架构、依赖清单 inspect_binary_layout、binary_overview
静态 函数/类清单、关键字符串、xref analyze_function、search_strings、xrefs
动态 参数样本、调用栈、时间点 capture_process_scenario、observe_native_calls
协议 原始请求/响应、签名输入输出对 inspect_web_network_capture
复现 可运行脚本 + 与目标一致的输出 verify_reconstruction、compare_process_captures

三条实践建议

  1. 先建 unknown 清单再开工。 把"我还不知道什么"显式记下来(REA record_unknown),比记"我知道了什么"更能防止自欺。
  2. 动态观测要绑定环境。 同一份样本在不同版本 OS/浏览器上行为不同,记录版本号,否则复现会玄学失败。
  3. 用差分验证代替确认偏误。 改变一个输入看输出是否按预期变化(REA compare_process_captures),比"跑通了"更可信。

9. 合规边界与常见坑#

先划边界,再动手。

工程上的常见坑

症状 多半是 对策
附加进程就崩 反调试 / 完整性校验 先静态定位检测点,Hook 掉再附加
抓不到 HTTPS 证书固定 / 走 QUIC Hook 上层 API 或关闭 QUIC
反编译全是壳代码 加固 先脱壳
补环境后结果不对 检测字段未对齐 逐字段对比真实浏览器取值
复现偶尔失败 依赖时间/随机数 固定随机数做差分
改了二进制就不启动 代码签名 重新签名,或关闭硬化运行时

10. 一页速查:从零到复现#

1. 侦察   file / otool / aapt2 / unzip      → 我面对的是什么?
2. 静态   Ghidra / jadx / class-dump        → 结构长什么样?
3. 动态   Frida / LLDB / CDP                → 真实跑起来是什么样?
4. 协议   mitmproxy / Wireshark             → 它和服务器说什么?
5. 复现   Python / Node / Playwright        → 我能否独立重放?

每一步都问自己:这一步产出的证据,能不能让别人复核? 不能,就还没做完。


本指南由工作区内的 re-workflow 项目构建并部署到 Cloudflare Pages。工具清单为开源仓库,使用前请自行确认许可证与合规边界。