Content
**English** | [English](README_en.md)
# ReconBridge — Universal Reverse Analysis KernelSU Module
A universal reverse analysis backend running on Android (KernelSU root) devices. The mobile side only provides atomic capabilities (package pulling / file reading / listing so / injecting hooks), while all intelligence (function localization, hook generation, result analysis) is done on the PC side (Claude Code + MCP).
> 📌 **One-page quick start for AI agents / new sessions: [`AGENTS_QUICKSTART.md`](AGENTS_QUICKSTART.md)** — All MCP tool signatures, M5 usage, typical workflows, and high-frequency pitfalls; read one and you're ready to go.
> Progress: **M1 / M2 / M3 / M4 / M5 all completed and verified on real devices** (Xiaomi SM8750 / Android 16 / KernelSU + ZygiskNext + LSPosed).
> - **M5**: Universal Java tracing + real-time tampering (LSPosed module, `trace_java` / `patch_java`) — see [`m5/README.md`](m5/README.md), [`m5/JAVA_HOOK_PROTOCOL.md`](m5/JAVA_HOOK_PROTOCOL.md).
---
> ## ⚠️ Disclaimer
>
> This project is **for authorized security research and educational use only**. You are responsible for having proper authorization for any device/app you analyze.
---
## Quick Start
### PC Side (One-click MCP Tool Installation)
Supports two AI clients: **Claude Code** (write `~/.claude.json`) and **ChatGPT Codex** (write `~/.codex/config.toml`). Default `both` = **auto-detection**: only register with the installed client (Claude checks `~/.claude.json`/`~/.claude/`, Codex checks `~/.codex/`), and skip the one that's not installed; **if neither is detected, only install the tool body, without writing any configuration** (wait for you to install the client and re-run registration, or use `--target` to force writing). Also requires `adb` (Android platform-tools, for connecting to real devices).
**Recommended: one-line online installation (Windows, no cloning or Python required)**
```powershell
irm https://github.com/lm060719/reconbridge/releases/latest/download/install.ps1 | iex
```
Automatically download and extract MCP exe, register with client user-level configuration, and lay down a `reconbridge` skill (automatically load workflow for reverse tasks):
- **Claude Code** → `~/.claude.json` `mcpServers.reconbridge` + skill to `~/.claude/skills/`
- **ChatGPT Codex** → `~/.codex/config.toml` `[mcp_servers.reconbridge]` + skill to `~/.codex/skills/`
Restart the corresponding client to use.
> exe includes MCP server and core dependencies (including androguard); jadx / Ghidra are optional decompilation tools, extracted to `%LOCALAPPDATA%\ReconBridge\tools\` for automatic detection (`toolchain_status` check).
> **Force installation of only one** (skip detection): set `$env:RB_TARGET="codex"` (or `"claude"`) and re-run — even if the directory doesn't exist, it will be created. **WiFi transmission**: set `$env:RB_TRANSPORT="wifi"`.
**Update**: re-run the above installation command to overwrite the exe and re-register, keeping `work\` (package pulling/dump data) and `tools\`.
**Uninstall**:
```powershell
irm https://github.com/lm060719/reconbridge/releases/latest/download/uninstall.ps1 | iex
```
Unregister reconbridge from both clients and delete the installation directory (default keep `work\`/`tools\` data; delete data together with `$env:RB_PURGE="1"`; uninstall only one with `$env:RB_TARGET="codex"`). Equivalent to exe self-unregistration: `reconbridge-mcp.exe --unregister [--target codex]`.
**Local Console (optional, graphical connection selection / status viewing)**
```powershell
reconbridge-mcp --serve # one-click installation adds it to PATH — new terminal to use; browser automatically opens to 127.0.0.1:9000
# if command not found (PATH not applied or not added), use full path:
# %LOCALAPPDATA%\ReconBridge\reconbridge-mcp\reconbridge-mcp.exe --serve
# source installation: python -m reconbridge_mcp --serve
```
Web interface for adb / wifi selection, one-click connection, daemon status, and read-only monitoring (active hooks / recent event flow / dumped files), eliminating the need for command-line environment variable settings and token copying. Only bound to `127.0.0.1` (localhost). `--port N` for port changes, `--no-open` to disable automatic browser opening.
**adb or wifi? Pitfalls of listening addresses**
- **adb (USB, default)**: automatically read token, establish USB tunnel,免 configuration, most secure (daemon only bound to localhost). Cost: when connected, device-side listening address **pinned to `127.0.0.1`** (with tunnel), and requires adb shell root.
- **wifi (LAN direct connection)**: device-side daemon needs to bind to **LAN IP**. In **device WebUI "Network Settings" → "Listening Address"**, fill in `auto` (automatically bind `wlan0` LAN IP) and save, or use `rbctl setbind auto` on device; then connect with `http://<device IP>:<port>` + token (IP / port / token all displayed in device WebUI).
- ⚠️ **Switching from adb to wifi**: `bind` has been pinned to `127.0.0.1`, and the computer cannot connect — change "Listening Address" back to `auto`. To fix wifi, avoid using adb mode (which will re-pin to `127.0.0.1`).
**Running from source (developers / Linux / macOS, Python 3.10+ required)**
```powershell
# Windows
git clone https://github.com/lm060719/reconbridge.git
cd reconbridge
./install.ps1 # create venv → install dependencies → register reconbridge + lay down skill (default Claude + Codex)
./install.ps1 -Target codex # install only Codex (or -Transport wifi)
```
```bash
# Linux / macOS
git clone https://github.com/lm060719/reconbridge.git
cd reconbridge
./install.sh # default both; install only Codex: ./install.sh adb codex
```
Restart the corresponding client: in Claude Code, `claude mcp list` / `/mcp` should show `reconbridge` (25 tools), and Codex's `~/.codex/config.toml` should have `[mcp_servers.reconbridge]`; both ends will have a `reconbridge` skill (automatically load workflow and pit list for reverse tasks).
### Device Side (刷入 KernelSU Module)
Device needs to be rooted (KernelSU), and ZygiskNext installed (required for M3/M4 dynamic hooking).
```powershell
./build.ps1 # compile arm64-v8a with NDK (see below)
./pack.ps1 # package dist/ReconBridge-M1.zip
```
In KernelSU Manager → Module → Install from local `dist/ReconBridge-M1.zip` → Restart.
> Pre-compiled binaries are included in the repository (`module/bin`, `module/zygisk`, `module/system/lib64`); if you don't want to compile yourself, simply run `./pack.ps1` to package, or use the zip from [Releases](../../releases).
After installation, tell Claude Code "Connect to device and check status" to start. See detailed documentation below.
## Milestone Overview
| Milestone | Content | Documentation |
|--------|------|------|
| **M1** | Static transmission layer: KernelSU module + C++ HTTP daemon + WebUI + static interface | this document (below) |
| **M2** | PC-side MCP Server: M1 interface + local decompilation chain (jadx / DexKit→androguard / Ghidra / Hermes) encapsulated as Claude Code tool | [`pc/README.md`](pc/README.md) |
| **M3** | Universal dynamic hooking executor: Zygisk injection + data-driven ShadowHook + SSE/WS hit streaming | [`m3/README.md`](m3/README.md) · protocol [`m3/HOOK_PROTOCOL.md`](m3/HOOK_PROTOCOL.md) |
| **M4** | Reinforcement/anti-debugging enhancement: universal memory dex dump (`/dump_dex`) + anti-detection hook configuration template | [`m4/README.md`](m4/README.md) |
Build all products: `./build.ps1` → `./pack.ps1` (generate `dist/ReconBridge-M1.zip`).
> Device-side note: Windows adb transmission to `/data/...` path requires `export MSYS_NO_PATHCONV=1 MSYS2_ARG_CONV_EXCL='*'`.
## M1 — Static Transmission Layer
KernelSU module skeleton + C++ HTTP daemon + WebUI port switch + static interface.
### Directory Structure
```
reverse module/
├─ src/
│ ├─ daemon.cpp # C++17 daemon source code
│ └─ third_party/
│ ├─ httplib.h # cpp-httplib 0.18.3 (single header)
│ └─ json.hpp # nlohmann/json 3.11.3 (single header)
├─ module/ # contents of zip to be flashed (zip root = this directory)
│ ├─ module.prop
│ ├─ customize.sh # installation script (architecture check / permissions)
│ ├─ service.sh # late_start to start daemon
│ ├─ rbctl # control script (enable/disable/info…)
│ ├─ bin/reconbridge_daemon # compiled product (arm64-v8a)
│ └─ webroot/index.html # KernelSU WebUI
├─ CMakeLists.txt # cmake build (optional)
├─ build.ps1 # direct build with NDK clang++ (recommended, no cmake)
├─ pack.ps1 # package into flashable zip
└─ README.md
```
### I. Compilation
Requires Android NDK (this project uses r27c). Automatically detected in `%LOCALAPPDATA%\Android\Sdk\ndk\`.
```powershell
# method A (recommended, no cmake): direct NDK clang++ build
./build.ps1
# method B: cmake + ninja
cmake -B build -G Ninja `
-DCMAKE_TOOLCHAIN_FILE=$env:ANDROID_NDK_HOME/build/cmake/android.toolchain.cmake `
-DANDROID_ABI=arm64-v8a -DANDROID_PLATFORM=android-26 -DCMAKE_BUILD_TYPE=MinSizeRel
cmake --build build
```
Product: `module/bin/reconbridge_daemon` (AArch64 PIE ELF, ~900 KB, statically linked libc++).
### II. Packaging and Flashing
```powershell
./pack.ps1
# generate dist/ReconBridge-M1.zip
```
### III. Flashing
- KernelSU Manager → Module → Install from local → select `ReconBridge-M1.zip` → **Restart**.
- or `adb`:
```
adb push dist/ReconBridge-M1.zip /data/local/tmp/
adb shell su -c "ksud module install /data/local/tmp/ReconBridge-M1.zip"
adb reboot
```
### IV. Enable Port
After restart, port is **closed by default**. In KernelSU Manager → Module → ReconBridge, open WebUI:
1. Open "Port Switch".
2. Note the **Access URL** (e.g., `http://192.168.x.x:8787`) and **token** displayed on the page.
3. Remember to close the switch when done.
> WebUI only writes `config.conf`, and daemon reloads configuration on change.
### V. Verification (PC side, same Wi-Fi)
Set `IP`/`TOKEN`/`PKG` to actual values:
```bash
# 1) alive
curl -H "X-Token: TOKEN" http://IP:8787/health
# 2) list packages
curl -H "X-Token: TOKEN" "http://IP:8787/packages"
# 3) list all apk paths for a package (including splits)
curl -H "X-Token: TOKEN" "http://IP:8787/apk?pkg=PKG"
# 4) pull a single apk (streaming, equivalent to adb pull, no adb auth required)
# after getting the actual path from the previous step:
curl -H "X-Token: TOKEN" "http://IP:8787/apk?pkg=PKG&path=/data/app/.../base.apk" -o base.apk
# 5) pull native so
curl -H "X-Token: TOKEN" "http://IP:8787/libs?pkg=PKG"
curl -H "X-Token: TOKEN" "http://IP:8787/libs?pkg=PKG&path=/data/app/.../lib/arm64/libfoo.so" -o libfoo.so
# 6) read arbitrary file
curl -H "X-Token: TOKEN" "http://IP:8787/file?path=/system/build.prop"
# 7) procfs
curl -H "X-Token: TOKEN" "http://IP:8787/proc?pid=1&what=status"
# 8) whitelisted shell
curl -H "X-Token: TOKEN" -X POST "http://IP:8787/shell" \
-d '{"argv":["getprop","ro.product.model"]}'
```
**M1 verification criteria**: on PC, use curl with token to pull any App's complete APK (including splits) and native so to local, equivalent to `adb pull` but without adb auth.
## Static Interface List
| Method | Path | Description |
|------|------|------|
| GET | `/health` | alive detection (name/version/pid/uptime) |
| GET | `/packages` | list installed packages (package name / versionCode / path / is system app) |
| GET | `/apk?pkg=` | list all apk paths for a package (base + splits); add `&path=` for single file streaming |
| GET | `/file?path=` | root read arbitrary file (absolute path) |
| GET | `/libs?pkg=` | list native `.so` in package's lib directory; add `&path=` to download single file |
| GET | `/proc?pid=&what=maps\|status\|cmdline` | forward procfs |
| POST | `/shell` | whitelisted command execution, body: `{"argv":[...]}` or `{"cmd":"..."}` |
Authentication: one of three — request header `X-Token: <token>`, `Authorization: Bearer <token>`, or query parameter `?token=<token>`.
`/shell` whitelist: `id whoami getprop uname ls cat stat du df md5sum sha1sum sha256sum pm cmd dumpsys ps getenforce settings wc head tail ip netstat pgrep mount readlink basename dirname find date`. No `sh -c`, direct `execvp`, reject outside whitelist.
## Security Notes
- Port is **closed by default**, only opened manually by user in WebUI, and closed when done; restarts to closed state.
- All interfaces use token authentication; token generated randomly (16-byte hex) on startup.
- Default bind to `wlan0`'s LAN IP (`bind=auto`), not `0.0.0.0`; fallback to `0.0.0.0` and alert if not detected. Listening address can be changed in **WebUI "Network Settings" → "Listening Address"** (`auto` / `0.0.0.0` / specific IP / `127.0.0.1`). Note that adb mode connection will automatically set it to `127.0.0.1`.
- Device side only acts as a transport, without any specific App logic (compliant with `ndde.md` design principles).
## Runtime Files
`/data/adb/reconbridge/`:
- `config.conf` — `enabled` / `port` / `bind` / `token`
- `daemon.log` — daemon logs
## Known Limitations (M1)
- `/packages` "version" takes `versionCode` (`pm` single call, fast); `versionName` requires `dumpsys`, not included in M1.
- `/libs` only lists **落地** `.so`; if app `extractNativeLibs=false`, so is inside apk `lib/arm64-v8a/`, please use `/apk` to pull package and then extract locally (interface will prompt in `note`).
- `/shell` command string splits by whitespace, no quotes; complex commands use `argv` array form.
MCP Config
Below is the configuration for this MCP Server. You can copy it directly to Cursor or other MCP clients.
mcp.json
Connection Info
You Might Also Like
No recommendations available