关于 android-reverse-engineering
面向 Android APK、XAPK、JAR 和 AAR 的逆向分析技能,从静态反编译与调用链追踪入手,并在需要时再进行动态分析。适合需要梳理应用结构、网络调用和 API 的分析工作。
主要功能
- 01使用 jadx 与 Fernflower/Vineflower 反编译
- 02分析应用结构与调用链
- 03搜索并记录 API 端点
- 04依赖检查与安装脚本
- 05按静态分析结果决定动态分析
适用场景
- 01检查 Android 应用的网络栈与请求流程
- 02提取接口方法、路径和认证信息
- 03判断何时需要分析 native 代码
- 04为运行时分析准备代码调用链
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ credittone/ android-reverse-engineering-skill --skill android-reverse-engineering安装后在 Claude Code 中输入/android-reverse-engineering确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/api-extraction-patterns.mdcall-flow-analysis.mddynamic-analysis.mdfernflower-usage.mdjadx-usage.mdnative-analysis.mdsetup-guide.mdscripts/bypass_frida_svc_detect.jsbypass_root_detect.jscheck-deps.ps1check-deps.shdecompile.ps1decompile.shdump_dex.jsdump_so.jsfind-api-calls.ps1find-api-calls.shhook_artmethod_register.jshook_encryption_algo.jsinstall-dep.ps1install-dep.shjni_method_trace.jskeystore_dump.jsssl_log.js详细介绍
Android 逆向工程
使用 jadx 和 Fernflower/Vineflower 反编译 Android APK、XAPK、JAR 和 AAR 文件,追踪应用代码和库中的调用流程,生成所提取 API 的结构化文档,并且仅在静态初步分析表明有必要时才升级到运行时分析。支持两种反编译引擎:jadx 适用于广泛的 Android 场景,Fernflower/Vineflower 则能为复杂的 Java 代码提供更高质量的输出。
核心原则
不要一开始就使用 Frida、抓包或 SO 分析。先使用 JADX,并确定:
- 使用的网络栈
- 请求构造器或拦截器链
- 签名或加密逻辑似乎在哪里执行
- 相关逻辑在 Java 中是否可见,还是交由原生代码处理
仅在静态分析无法解决问题或无法弥补信息缺口时,才使用动态分析进行确认或补充。
何时建议使用 IDA MCP
IDA MCP 提供针对 .so 文件的静态二进制分析(反汇编、反编译、交叉引用)。不要盲目建议使用它——请先检查以下条件:
在用户要求以下内容时,建议使用 IDA MCP:
- 查找特定 SO 中的函数偏移量或导出项
- 将已知的原生函数反编译为 C 伪代码
- 追踪指向某个字符串、符号或地址的交叉引用
- 检查某个 SO 是否导入了加密或网络库
- 分析未经过混淆的 SO(使用标准编译器,函数边界清晰可辨)
以下情况不要建议使用 IDA MCP:
- SO 使用了控制流平坦化或类似的重度混淆——伪代码将难以阅读。请改用 Frida 脚本。
- SO 中的所有字符串都经过加密——静态搜索无法找到内容。请使用
jni_method_trace.js捕获运行时解密过程。 - 用户需要运行时值(密钥、令牌、参数、解密后的数据)——IDA 只能显示静态代码。
- 尚未确定目标 SO——建议先使用
jni_method_trace.js找出处理相关逻辑的 SO。 - 用户需要计算或生成签名、密文或令牌——这需要运行时执行,而非静态分析。
**建议前先快速检查:**对该 SO 使用 survey_binary。如果输出中只有少数几个体积庞大的函数(每个 > 10 KB),而不是许多小函数,则该二进制文件经过了混淆——请跳过 IDA,改为建议使用 Frida。
先决条件
此技能需要安装 Java JDK 17+ 和 jadx。Fernflower/Vineflower、dex2jar 和 rizin 是可选项,但建议安装,以提升反编译质量并分析原生 .so 文件。运行依赖检查器以进行验证:
bash skills/android-reverse-engineering/scripts/check-deps.sh
在 Windows 上(PowerShell):
& "skills/android-reverse-engineering/scripts/check-deps.ps1"
如果缺少任何依赖项,请按照 skills/android-reverse-engineering/references/setup-guide.md 中的安装说明进行操作。
工作流
阶段 1:验证并安装依赖项
在反编译之前,请确认所需工具均已就绪,并安装任何缺失的工具。
操作:运行依赖项检查脚本。
bash skills/android-reverse-engineering/scripts/check-deps.sh
在 Windows 上(PowerShell):
& "skills/android-reverse-engineering/scripts/check-deps.ps1"
输出包含机器可读的行:
INSTALL_REQUIRED:<dep>— 必须在继续之前安装INSTALL_OPTIONAL:<dep>— 建议安装,但不会阻止后续操作
如果缺少必需的依赖项(退出代码为 1),请自动安装:
bash skills/android-reverse-engineering/scripts/install-dep.sh <dep>
在 Windows 上(PowerShell):
& "skills/android-reverse-engineering/scripts/install-dep.ps1" <dep>
安装脚本会检测操作系统和包管理器,然后:
- 尽可能在不使用 sudo 的情况下安装(下载到
~/.local/share/,并在~/.local/bin/中创建符号链接) - 必要时使用 sudo 和系统包管理器(apt、dnf、pacman)
- 如果需要 sudo 但无法使用,或用户拒绝使用,脚本会输出确切的手动命令并以代码 2 退出 — 将这些说明展示给用户
Windows 说明:
- PowerShell 安装脚本会优先选择
winget,其次是scoop,最后是choco - 如果没有可用的包管理器,则会改为下载到
%USERPROFILE%\.local\share\ check-deps.ps1和decompile.ps1会从用户环境刷新 PATH,因此通常无需重启终端即可找到新安装的工具
对于可选依赖项,请询问用户是否要安装。建议安装 Vineflower 和 dex2jar,以获得最佳效果。如果可能需要检查 JNI 或 .so 文件,建议安装 Rizin。
安装完成后,重新运行 check-deps.sh,确认所有依赖项均已就绪。在所有必需依赖项均正常之前,请勿继续阶段 2。
阶段 2:反编译
使用反编译包装脚本处理目标文件。该脚本支持三个引擎:jadx、fernflower 和 both。
操作:选择引擎并运行反编译脚本。该脚本可处理 APK、XAPK、JAR 和 AAR 文件。
bash skills/android-reverse-engineering/scripts/decompile.sh [OPTIONS] <file>
在 Windows(PowerShell)上:
& "skills/android-reverse-engineering/scripts/decompile.ps1" [OPTIONS] <file>
对于 XAPK 文件(包含多个 APK 的 ZIP 包,由 APKPure 等应用商店使用):脚本会自动解压归档文件,识别其中的所有 APK 文件(base 和 split APK),并将每个 APK 反编译到单独的子目录中。XAPK 清单会复制到输出目录,供参考。
对于 拆分/捆绑 APK 包装器:如果外层 APK 生成的 Java 文件很少,但其资源中包含 base.apk 和 split_config.*.apk 文件,反编译脚本会自动检测到外层 APK 只是一个轻量包装器,重新反编译 base.apk 到 <output>/base/,跳过仅包含配置的拆分包,并报告实际源码位置。
选项:
-o <dir>— 自定义输出目录(默认:<filename>-decompiled)--deobf— 当可读性比运行时类保真度更重要时,启用名称反混淆--no-res— 跳过资源,只反编译代码(速度更快)--engine ENGINE—jadx(默认)、fernflower或both
引擎选择策略:
| 情况 | 引擎 |
|---|---|
| 对任意 APK 进行首次处理 | jadx(速度最快,可处理资源;默认保留原始运行时类名) |
| 分析 JAR/AAR 库 | fernflower(生成的 Java 代码更好) |
| jadx 输出包含警告/损坏代码 | both(逐个比较并选择最佳结果) |
| 复杂的 lambda、泛型、流 | fernflower |
| 快速浏览大型 APK | jadx --no-res |
| 需要 Frida/JNI/unidbg/运行时类名 | 不带 --deobf 的 jadx |
| 只需提高严重混淆代码的可读性 | jadx --deobf |
使用 --engine both 时,输出分别写入 <output>/jadx/ 和 <output>/fernflower/,并在末尾显示比较摘要,其中列出文件数量和 jadx 警告数量。对于 jadx 有警告的类,请查看 Fernflower 输出,以获取更好的代码。
使用 Fernflower 处理 APK 文件时,脚本会自动使用 dex2jar 作为中间步骤。要使其正常工作,必须安装 dex2jar。
完整的 CLI 参考请参阅 skills/android-reverse-engineering/references/jadx-usage.md 和 skills/android-reverse-engineering/references/fernflower-usage.md。
阶段 3:分析结构
浏览反编译后的输出,了解应用的架构。
操作:
-
读取
<output>/resources/AndroidManifest.xml中的 AndroidManifest.xml:- 识别主启动 Activity
- 列出所有 Activity、Service、BroadcastReceiver、ContentProvider
- 记录权限(尤其是
INTERNET、ACCESS_NETWORK_STATE) - 查找应用类(
<application>上的android:name)
-
查看
<output>/sources/下的包结构:- 识别主应用包及子包
- 区分应用代码和第三方库
- 查找名为
api、network、data、repository、service、retrofit、http的包——API 调用通常位于这些包中
-
识别架构模式:
- MVP:查找
Presenter类 - MVVM:查找
ViewModel类以及LiveData/StateFlow - Clean Architecture:查找
domain、data、presentation包 - 这有助于确定后续阶段中网络调用的查找位置
- MVP:查找
阶段 4:跟踪调用流程
从面向用户的入口点沿执行路径向下追踪到网络调用。
操作:
-
从入口点开始:阅读阶段 3 中确定的主 Activity 或 Application 类。
-
跟踪初始化链:
Application.onCreate()通常会设置 HTTP 客户端、基础 URL 和 DI 框架。先阅读此处。 -
跟踪用户操作:从 Activity 开始,依次跟踪:
onCreate()→ 视图设置 → 点击监听器- 点击处理程序 → ViewModel/Presenter 方法
- ViewModel → Repository → API 服务接口
- API 服务 → 实际 HTTP 调用
-
梳理 DI 绑定(如果使用了 Dagger/Hilt):查找
@Module类,了解为哪些接口提供了哪些实现。 -
处理混淆代码:类名被混淆时,使用字符串字面量和库 API 调用作为锚点。Retrofit 注解和 URL 字符串不会被混淆。
-
优先使用符合运行时的 Hook/仿真名称:如果下一步可能涉及 Frida、JNI
FindClass、unidbg 或运行时类加载,首次运行 jadx 时不要使用--deobf。--deobf可以生成便于源码导航的可读别名,但无法保证这些别名在运行时存在。
详细技巧和 grep 命令请参阅 skills/android-reverse-engineering/references/call-flow-analysis.md。
阶段 5:提取并记录 API
查找所有 API 端点并编写结构化文档。
操作:运行 API 搜索脚本进行全面搜索。
bash skills/android-reverse-engineering/scripts/find-api-calls.sh <output>/sources/
在 Windows(PowerShell)上:
& "skills/android-reverse-engineering/scripts/find-api-calls.ps1" <output>/sources/
定向搜索:
# Only Retrofit
bash skills/android-reverse-engineering/scripts/find-api-calls.sh <output>/sources/ --retrofit
# Only hardcoded URLs
bash skills/android-reverse-engineering/scripts/find-api-calls.sh <output>/sources/ --urls
# Only auth patterns
bash skills/android-reverse-engineering/scripts/find-api-calls.sh <output>/sources/ --auth
在 Windows(PowerShell)上:
# Only Retrofit
& "skills/android-reverse-engineering/scripts/find-api-calls.ps1" <output>/sources/ -Retrofit
# Only hardcoded URLs
& "skills/android-reverse-engineering/scripts/find-api-calls.ps1" <output>/sources/ -Urls
# Only auth patterns
& "skills/android-reverse-engineering/scripts/find-api-calls.ps1" <output>/sources/ -Auth
然后,针对每个发现的端点,阅读其周边源码并提取:
- HTTP 方法和路径
- 基础 URL
- 路径参数、查询参数、请求体
- 请求头(尤其是身份验证)
- 响应类型
- 调用位置(阶段 4 中的调用链)
使用以下格式记录每个端点:
### `METHOD /path`
- **Source**: `com.example.api.ApiService` (ApiService.java:42)
- **Base URL**: `https://api.example.com/v1`
- **Path params**: `id` (String)
- **Query params**: `page` (int), `limit` (int)
- **Headers**: `Authorization: Bearer <token>`
- **Request body**: `{ "email": "string", "password": "string" }`
- **Response**: `ApiResponse<User>`
- **Called from**: `LoginActivity → LoginViewModel → UserRepository → ApiService`
有关特定库的搜索模式和完整文档模板,请参阅 skills/android-reverse-engineering/references/api-extraction-patterns.md。
阶段 6:动态分析
仅当静态分析不足,或用户明确要求进行 Frida Hook、数据包捕获、SSL Pinning 调查或签名追踪等运行时工作时,才使用此阶段。
典型的升级分析情形:
- 请求参数通过间接方式组装,难以通过静态分析还原
- Java 代码调用
native方法进行签名、令牌生成或加密 - 应用使用自定义网络栈,静态搜索无法揭示最终请求
- 用户需要运行时值的证据,而不仅仅是代码路径
建议顺序:
- Hook 最接近最终出站请求的 Java 请求构建器、拦截器、回调或请求对象
- 检查请求 URL、请求头、请求体,以及任何与签名相关的输入和输出
- 之后再判断是否需要绕过 SSL Pinning 或检查原生代码
请参阅:
skills/android-reverse-engineering/references/dynamic-analysis.mdskills/android-reverse-engineering/references/native-analysis.md
阶段 7:原生代码与签名分析
如果签名或加密操作交由 JNI 或 .so 代码处理:
- 在反编译后的 Java 代码中查找
native声明 - 查找匹配的
System.loadLibrary调用,并确定目标 SO - 判断 SO 使用的是静态 JNI 导出还是动态注册
- 在尝试深入逆向之前,优先通过运行时 Hook 确认函数的输入和输出
- 只有在用户明确需要离线复现或深入还原算法时,才使用 unidbg 或进行进一步逆向
重点回答以下问题:
- 签名是在 Java 代码还是原生代码中生成的?
- 签名函数的确切输入是什么?
- 哪些输入是稳定常量,哪些是时间戳、Cookie、设备 ID 或请求正文等运行时值?
- 可以通过调用应用来重放算法,还是必须重新实现?
.so 分析的首选 CLI 工具:
- 优先使用
rizin/rz-bin(如果可用) - 如果 rizin 不可用,则使用
readelf、nm、objdump和strings
推荐的 .so 命令集:
# Basic file identity
file libfoo.so
# ELF metadata, imports/exports, sections
rz-bin -I libfoo.so
rz-bin -s libfoo.so
rz-bin -i libfoo.so
rz-bin -E libfoo.so
# Fast string triage
rz-strings -a libfoo.so | rg 'http|https|Java_|JNI_OnLoad|RegisterNatives|encrypt|sign|ssl|socket'
# Function list and disassembly
rizin -qc "aaa; afl; q" libfoo.so
rizin -qc "aaa; pdf @ sym.JNI_OnLoad; q" libfoo.so
rizin -qc "aaa; pdr @ sym.JNI_OnLoad; q" libfoo.so
没有 rizin 时的备用方案:
readelf -d libfoo.so
readelf -Ws libfoo.so
nm -D libfoo.so | rg 'Java_|JNI_OnLoad|RegisterNatives'
objdump -T libfoo.so
objdump -d libfoo.so > libfoo.objdump.asm
strings -a libfoo.so | rg 'http|https|Java_|JNI_OnLoad|RegisterNatives|encrypt|sign|ssl|socket'
默认 .so 工作流:
- 使用
file和rz-bin -I确定架构和链接库 - 检查导出项和导入项,查找
JNI_OnLoad、Java_*以及加密或套接字 API - 搜索字符串,查找 URL、主机名、日志标签和注册线索
- 首先检查
JNI_OnLoad,然后查找RegisterNatives的目标 - 只有在了解 Java 侧调用路径后,才深入逆向函数
输出
工作流结束时,请交付:
- 反编译源码,存放在输出目录中
- 架构摘要——应用结构、主要程序包和使用的模式
- API 文档——按上述格式列出所有发现的端点
- 调用流程图——从 UI 到网络的关键路径(尤其是身份验证和主要功能)
- 运行时发现——适用时,注明 Hook 点、观察到的请求字段,以及选择该点的原因
- 签名评估——说明签名基于 Java 实现、由原生代码处理,还是目标请求无需签名
参考资料
skills/android-reverse-engineering/references/setup-guide.md— 安装 Java、jadx、Fernflower/Vineflower、dex2jar 和可选工具skills/android-reverse-engineering/references/jadx-usage.md— jadx CLI 选项和工作流skills/android-reverse-engineering/references/fernflower-usage.md— Fernflower/Vineflower CLI 选项、适用场景和 APK 工作流skills/android-reverse-engineering/references/api-extraction-patterns.md— 特定库的搜索模式和文档模板skills/android-reverse-engineering/references/call-flow-analysis.md— 跟踪反编译代码调用流程的技术skills/android-reverse-engineering/references/dynamic-analysis.md— Frida、运行时请求拦截、SSL Pinning 初步排查和数据包捕获工作流skills/android-reverse-engineering/references/native-analysis.md— JNI/SO 检查、原生签名分析,以及何时升级使用 unidbg