0x41337/AndKittyInjector
GitHub: 0x41337/AndKittyInjector
一个基于 Rust 重写的 Android ptrace 共享库注入器,支持多架构、隐蔽注入与远程系统调用。
Stars: 0 | Forks: 0
# AndKittyInjector (Rust 移植版)
基于 ptrace 的 Android 共享库注入器 —— [AndKittyInjector](https://github.com/MJx0/AndKittyInjector) 的完全 Rust 重写版本。
## 功能
- [x] 通过 `dlopen` / `android_dlopen_ext` 进行原生注入
- [x] 基于 memfd 的 dlopen(绕过 SELinux / 文件系统限制)
- [x] 单次调用注入多个库
- [x] 自动启动目标应用并注入 (`--launch`)
- [x] 监听应用启动并注入 (`--watch`)
- [x] 对 `dlopen` 设置硬件断点 (`--bp`)
- [x] 延迟注入 (`--delay`)
- [x] 远程 syscall (mmap, munmap, memfd_create, fcntl)
- [x] 在 `/proc/pid/maps` 中隐藏库(匿名重映射)
- [x] 在 linker 的 `solist`/`sonext` 中隐藏库(取消链接 soinfo)
- [x] 注入后随机化 ELF 头
- [x] 在入口点执行后卸载库 (`--free`)
- [x] JNI 环境:查找 `JavaVM` 并调用 `JNI_OnLoad`
- [x] ARM64, ARM32, x86_64, x86 ABIs
- [x] 硬件断点(ARM DBR, x86 DR)
- [x] LinkerScanner —— 通过解析 ELF 动态发现 soinfo 偏移量
- [ ] 通过 NativeBridge(libhoudini / libndk_translation)进行模拟注入
## 环境要求
### 构建要求
| 工具 | 版本 |
|---|---|
| Rust | 1.85+ (edition 2021) |
| Android NDK | r27+(推荐) |
| `cargo-ndk` | 4.x |
### Rust 目标平台
```
rustup target add aarch64-linux-android \
armv7-linux-androideabi \
x86_64-linux-android \
i686-linux-android
```
### 环境变量
```
export ANDROID_NDK_HOME=$HOME/android-sdk/ndk/
```
## 构建
```
cd andkitty-injector
# Host binary (语法检查,在 Android 上不可用)
cargo build
# 所有 4 个 Android ABI
ANDROID_NDK_HOME=$HOME/android-sdk/ndk/ \
cargo ndk -t arm64-v8a -t armeabi-v7a -t x86_64 -t x86 build --release
```
Release 二进制文件位于:
```
target//release/andkitty-injector
```
交叉编译的二进制文件最低目标版本为 **Android API 21**。
## 使用方法
```
AndKittyInjector 5.2.1
Usage: andkitty-injector --package --libs ... [OPTIONS]
Options:
--package Target package name to inject into
--libs ... Libraries path to be injected
--launch Launch process and inject
--watch Monitor process start then inject
--bp Inject after native dlopen breakpoint hit
--delay Delay injection in microseconds
--timeout Timeout for ptrace remote calls in milliseconds
--memfd Use memfd dlopen
--free Unload library after entry point execution
--hide Remove soinfo from solist/sonext, remap library
to anonymous memory and randomize ELF header
-h, --help Print help
-V, --version Print version
```
### 示例
```
# 启动应用并通过 memfd 注入库,延迟 1 秒
./andkitty-injector \
--package com.target.package \
--libs /data/local/tmp/libexample.so \
--memfd --launch --delay 1000000
# 注入到运行中的进程
./andkitty-injector \
--package com.target.package \
--libs /data/local/tmp/libhack.so
# 注入并从 linker + maps 中隐藏
./andkitty-injector \
--package com.target.package \
--libs lib.so \
--hide
# 带 breakpoint 注入(在 dlopen 之后立即注入)
./andkitty-injector \
--package com.target.package \
--libs lib.so --bp
```
### 目标库入口点
如果找到该符号,注入器将调用 `JNI_OnLoad(JavaVM *vm, void *key)`。
密钥为 `1337` —— 在运行 payload 之前请先进行验证:
```
extern "C" jint JNIEXPORT JNI_OnLoad(JavaVM *vm, void *key) {
if (key != (void *)1337)
return JNI_VERSION_1_6;
// Payload runs here
std::thread(worker).detach();
return JNI_VERSION_1_6;
}
```
## 架构
```
src/
├── main.rs Entry point, inject_direct / inject_watch dispatch
├── cli.rs Clap argument parser
├── error.rs InjectError enum (thiserror)
├── types.rs InjectConfig, InjectInfo, Arch
├── trace/
│ └── ptrace.rs TraceManager: attach/seize, regs, remote_call,
│ remote_syscall, HW breakpoints (all 4 ABIs)
├── mem/
│ └── ops.rs ProcMap parser, read_process_maps
├── elf/
│ ├── scanner.rs ELF validation, local & remote symbol resolution
│ └── linker.rs LinkerScanner, RemoteSymbols, soinfo linked list
├── injector/
│ ├── config.rs InjectContext
│ ├── syscall.rs RemoteSyscall (mmap, munmap, memfd_create, seal)
│ ├── inject.rs Injector: legacy dlopen + memfd android_dlopen_ext
│ ├── hide.rs Hide library from linker + remap + randomize
│ ├── jni.rs Find JavaVM, call JNI_OnLoad
│ ├── breakpoint.rs wait_for_breakpoint (HW bp)
│ └── emu_inject.rs [stub] NativeBridge emulated injection
├── nb/
│ └── mod.rs [stub] NativeBridge scanner
└── utils/
├── app.rs android_launch_app / android_stop_app via am
├── logcat.rs am_proc_start detection via logcat pipe
└── inotify.rs Process directory monitoring via inotify
```
## 工作原理
1. **附加 (Attach)** —— 通过 `PTRACE_SEIZE` (SDK 21+) 或 `PTRACE_ATTACH` 附加到目标进程。
2. **解析符号** —— 匹配本地和远程的 `/proc/pid/maps`,使用 `goblin` 解析本地 `.so` 文件,从而在远程进程中找到 `dlopen`、`dlerror` 和 `android_dlopen_ext`。
3. **分配缓冲区** —— 预留栈空间,或 `mmap` 一个远程缓冲区(使用 `--memfd` 时)。
4. **注入** —— 写入库路径(或创建一个 memfd 并写入 ELF),然后通过 ptrace 操纵寄存器远程调用 `dlopen` / `android_dlopen_ext`。
5. **注入后处理**(可选):
- **查找 `JavaVM`** —— 在 `libart.so` 中解析并调用 `JNI_GetCreatedJavaVMs`。
- **调用 `JNI_OnLoad`** —— 如果同时找到了 `JavaVM` 和 `JNI_OnLoad`。
- **隐藏** —— 遍历 linker 的 `soinfo` 链表,取消该条目的链接,对所有的段进行 `munmap` + 匿名 `mmap`,并随机化 ELF 头。
- **卸载** —— 远程调用 `dlclose`。
## 状态
| 功能 | 状态 |
|---|---|
| 原生注入 (dlopen) | ✅ |
| memfd 注入 | ✅ |
| 多库支持 | ✅ |
| 启动 + 监听 | ✅ |
| 断点注入 | ✅ |
| 从 solist 隐藏 | ✅ |
| 从 /maps 隐藏 | ✅ |
| 随机化 ELF 头 | ✅ |
| 查找 JavaVM + JNI_OnLoad | ✅ |
| 远程 syscall | ✅ |
| LinkerScanner | ✅ |
| 模拟器注入 (NativeBridge) | 🔧 计划中 |
| 模拟 soinfo 隐藏 | 🔧 计划中 |
## 已测试
- Android 5.0–16 (API 21–36) —— *计划中*
- ABI: arm64-v8a, armeabi-v7a, x86_64, x86
## 致谢
- 原始 C++ 项目:[MJx0/AndKittyInjector](https://github.com/MJx0/AndKittyInjector)
- [KittyMemoryEx](https://github.com/MJx0/KittyMemoryEx)
- [arminject](https://github.com/evilsocket/arminject)
- Riru hide 实现
标签:Android, DSL, Rust, SSH蜜罐, 云资产清单, 动态注入, 可视化界面, 目录枚举, 移动安全, 网络流量审计, 进程注入, 逆向工程, 通知系统