AsherDLL/jadx-rpc
GitHub: AsherDLL/jadx-rpc
为 LLM 智能体提供基于文件的无头 jadx 反编译会话,将昂贵的解析操作与高频查询分离,实现毫秒级代码检索响应。
Stars: 1 | Forks: 0
# jadx-rpc
为 LLM agents 提供无头模式的 [jadx](https://github.com/skylot/jadx) 会话。
目前的 jadx 有两种形态,但都不适合 autonomous agent。GUI 专为在屏幕上阅读代码的人类而构建,而将其暴露给模型的插件需要运行该 GUI。命令行工具是一个批量反编译器,运行之间没有内存记录,因此如果 agent 提出二十个问题,就要付出二十次的完整解析成本。
jadx-rpc 补充了缺失的那一部分:一个会话。打开目标文件会执行一次耗时的操作并将其写入磁盘。之后的所有操作都只是读取文件、正则扫描或单个类的反编译,并在几毫秒内得到响应。它驱动的是真正的 jadx 命令行,因此它可以在任何 jadx 能运行的地方工作,并且不需要显示器。
## 工作原理
没有 daemon 也没有 socket。Ghidra 需要这些是因为它的分析只存在于一个运行中的 JVM 内部,并会随其终止。jadx 没有这个限制,它的输出是普通文件,所以会话就是一个目录:
```
~/.local/state/jadx-rpc//
session.json what was opened and how
mapping.json every class, method and field, original and displayed names
res/ decoded resources, including AndroidManifest.xml
src/ decompiled Java, written by the optional full export
callgraph.json resolved call edges
cache/ classes decompiled on demand
renames.mapping recorded renames in Enigma format
```
命令之间没有任何程序在运行。两个 agent 可以同时查询同一个会话,因为它们只是在读取文件,并且会话在系统重启后依然存在。
## 成本开销
在包含 10761 个类的 12 MB APK 上测试,使用 jadx 1.5.6,运行在八核台式机上。你的数据将根据应用程序的大小按比例变化。
| 命令 | 耗时 | 执行的操作 |
|---|---|---|
| `open` | 12 s | 索引 19705 个类和 117352 个方法,解码每个资源 |
| `classes`, `symbols`, `members` | 0.25 s | 读取索引 |
| `entrypoints`, `manifest`, `resources` | 0.25 s | 读取解码后的资源 |
| `class` | 首次 5 s,之后瞬间完成 | 反编译一个类并将其缓存 |
| `export` | 175 s,223 MB | 反编译全部 10761 个类,以及调用图 (call graph) |
| `search`, `strings`, `callers`, `callees` | 几秒 | 需要 export 支持 |
这种拆分正是其核心所在。问题分类 (Triage)、符号查找和读取单个类的成本都很低,而唯一的耗时操作是可选的,并在后台运行。
## 安装说明
### jadx
jadx-rpc 会调用 `jadx` 启动器,因此请先安装 jadx。
```
# 任意平台,从 release zip 获取
curl -LO https://github.com/skylot/jadx/releases/download/v1.5.6/jadx-1.5.6.zip
mkdir -p /opt/jadx && unzip jadx-1.5.6.zip -d /opt/jadx
ln -s /opt/jadx/bin/jadx /opt/jadx/bin/jadx-gui ~/.local/bin/
# 或从 package manager 获取
brew install jadx # macOS
sudo pacman -S jadx # Arch
flatpak install flathub com.github.skylot.jadx # Flathub
```
jadx 需要 64 位的 Java 11 或更高版本。该 zip 压缩包同时包含了 `jadx` 和 `jadx-gui`。jadx-rpc 只使用 `jadx`,当你想自己查看相同的目标时,可以使用 GUI。
```
jadx --version # expect 1.5.6 or newer
```
如果 `jadx` 不在 PATH 中,请将 `JADX_BIN` 指向该启动器。
### jadx-rpc
```
uv tool install git+https://github.com/AsherDLL/jadx-rpc
# 或
pipx install git+https://github.com/AsherDLL/jadx-rpc
# 或包含内置的 MCP server
uv tool install "jadx-rpc[mcp] @ git+https://github.com/AsherDLL/jadx-rpc"
```
需要 Python 3.10 或更高版本。基础安装完全没有任何依赖,它所需的一切都在标准库中。
```
jadx-rpc list # expect {"ok": true, "result": {"sessions": [], "count": 0}}
```
默认情况下输出是带缩进的。以下示例使用 `--compact`,它会打印单行,因为这在页面中更易读,也更易于通过管道传输。
## 使用说明
```
$ jadx-rpc open app.apk --export
{"ok": true, "result": {"id": "1781c62d0f3b", "classes": 19705, "methods": 117352,
"elapsed_s": 12.6, "export": "running"}}
```
`--export` 会在后台开始完整的反编译。你不必等待它完成,下面的命令会立即生效。
```
$ jadx-rpc entrypoints
{"ok": true, "result": {"package": "org.fdroid.fdroid", "target_sdk": "30",
"components": [...], "exported_count": 10, ...}}
$ jadx-rpc symbols 'crypt|token|secret'
$ jadx-rpc members org.fdroid.fdroid.FDroidApp
$ jadx-rpc class org.fdroid.fdroid.FDroidApp --lines 1:80
```
一旦 `jadx-rpc status` 报告 export 已就绪:
```
$ jadx-rpc search 'javax\.crypto' --context 2
$ jadx-rpc strings '^https://'
$ jadx-rpc callers 'org.fdroid.fdroid.FDroidApp.onCreate'
```
重命名混淆符号:现在记录,并在稍后的一次遍历中统一应用:
```
$ jadx-rpc rename class com.a.b.c com.example.PaymentHandler
$ jadx-rpc rename method 'com.a.b.c.d(Ljava/lang/String;)V' verifySignature
$ jadx-rpc renames
$ jadx-rpc reload
```
`AGENTS.md` 包含完整的命令参考、每个命令的成本开销以及一个行之有效的分类排查顺序。它是专门为模型阅读而编写的,因此请将你的 agent 指向它。
## 接入 LLM
有三种方式可以调用相同的功能。请选择最适合你技术栈的一种。
### Shell agents
Claude Code、Codex、Cursor、pi 以及其他任何可以运行命令的工具。无需任何配置,该工具会输出 JSON。将参考指南提供给 agent 即可:
```
Read AGENTS.md in jadx-rpc, then triage app.apk and report every exported
component that reaches a crypto call.
```
### MCP
```
claude mcp add jadx-rpc -- jadx-rpc mcp
```
或者在客户端配置文件中:
```
{
"mcpServers": {
"jadx-rpc": {
"command": "jadx-rpc",
"args": ["mcp"],
"env": {"JADX_RPC_TARGET": "/abs/path/to/app.apk"}
}
}
}
```
共有二十个工具,每个命令对应一个。`jadx-rpc mcp --list-tools` 可以在不启动服务器的情况下打印它们,并且可以在基础安装下运行。提供服务需要额外安装 `pip install "jadx-rpc[mcp]"`。
### Python,适用于 ADK、LangChain 及同类工具
每个命令都是一个可导入的函数,它返回一个 dict,并在失败时引发 `JadxRpcError`,因此框架可以直接注册它,无需子进程,也无需 MCP 跳转。
```
from google.adk.agents import LlmAgent
import jadx_rpc
jadx_rpc.open_target("/abs/path/to/app.apk", export=True)
agent = LlmAgent(
name="apk_triage",
model="gemini-2.0-flash",
instruction=open("AGENTS.md").read(),
tools=[
jadx_rpc.entrypoints,
jadx_rpc.classes,
jadx_rpc.symbols,
jadx_rpc.members,
jadx_rpc.decompile_class,
jadx_rpc.search,
jadx_rpc.callers,
],
)
```
文档字符串和类型提示即是工具的 schema,因此无需重复描述。
## 环境变量
| 变量 | 作用 |
|---|---|
| `JADX_BIN` | jadx 启动器的路径(当它不在 PATH 中时) |
| `JADX_RPC_TARGET` | 每个命令所操作的会话,可以是路径或会话 ID |
| `JADX_RPC_STATE_DIR` | 会话的存放位置,适用于沙箱和 CI |
如果只打开了一个会话,`JADX_RPC_TARGET` 是可选的。如果打开了多个会话且未指定名称,命令将失败并列出候选会话,而不是进行猜测。
## 值得了解的限制
- 索引阶段会写入并随后删除一组中间文件,其大小大致与反编译后的应用程序相当。因此,打开一个非常大的 APK 需要同等大小的临时磁盘空间。
- 字段重命名需要 JVM descriptor,而索引中不包含此信息。请根据反编译源码中的声明来构建它。类和方法的重命名不需要任何额外内容,`members` 会打印出要传回的准确字符串。
- jadx 在大多数实际应用程序中无法反编译其中一小部分类。这是 jadx 的正常行为,其余部分的输出不受影响。
- 仅读取本地文件。jadx-rpc 不会进行获取、上传或向任何外部发送数据。
## 开发说明
```
git clone https://github.com/AsherDLL/jadx-rpc && cd jadx-rpc
uv venv && uv pip install -e . pytest
uv run pytest
```
测试套件使用 `javac` 构建了自己的测试 jar,并对其运行真实的 jadx,因此它不需要网络和 Android SDK。当缺少 `jadx` 或 `javac` 时,测试会被干净地跳过。
## 许可证
GPL-3.0-or-later。请参阅 `LICENSE`。
jadx 本身是一个独立项目,基于 Apache-2.0 许可。jadx-rpc 将其作为外部程序运行,不包含或链接其任何代码。
标签:Android, DSL, JS文件枚举, LLM工具, 云安全监控, 云资产清单, 无头模式, 逆向工具, 逆向工程, 静态分析