🦀 Android SO Dumper - 基于 Rust 的高性能 Android 原生库内存导出工具
一个用 Rust 编写的 Android 动态库(.so)内存 dump 与修复工具,专为逆向工程和安全研究设计。支持从运行中的进程内存提取加密/加壳的 SO 文件,并自动修复 ELF 结构。
- 🔓 绕过加固保护:从内存中提取被加密/加壳的 SO 文件
- 🎯 精准定位:通过解析 Android Linker 的
soinfo结构精确获取模块大小 - ⚡ 高性能:Rust 实现,零运行时依赖,体积小(~2MB)
- 🛡️ 内存安全:利用 Rust 所有权系统,防止内存泄漏和越界访问
- 🔄 自动恢复:RAII 模式自动恢复被暂停的进程
- 🔧 自动修复:集成
SoFixer和fixso,自动重建 ELF Section Header - 📱 Termux 友好:可直接在 Android 设备上编译运行
- 🎨 彩色输出:友好的命令行界面
dump_so_rs/
├── src/
│ └── main.rs # 主程序源代码
├── .gitignore # Git 忽略规则
├── Cargo.toml # Rust 项目配置文件
├── README.md # 项目文档(本文件)
├── SoFixer32 # 32位 SO 修复工具 (需自行下载)
├── SoFixer64 # 64位 SO 修复工具 (需自行下载)
├── fixso32 # 32位 fixso 工具 (需自行下载)
└── fixso64 # 64位 fixso 工具 (需自行下载)
| 文件/目录 | 说明 |
|---|---|
src/main.rs |
核心逻辑:进程挂起、内存读取、soinfo 解析、SO 修复 |
Cargo.toml |
依赖管理:clap (命令行解析)、nix (信号处理)、regex 等 |
SoFixer32/64 |
第三方 ELF 修复工具(二进制文件,需单独获取) |
fixso32/64 |
第三方轻量级修复工具(二进制文件,需单独获取) |
.gitignore |
排除 target/、修复工具等二进制文件 |
⚠️ 注意:SoFixer和fixso工具需要自行从以下项目获取:
- SoFixer: https://github.com/F8LEFT/SoFixer
- fixso: https://github.com/CodingGay/fixso
- Root 权限:必须以 root 身份运行
- readelf:用于解析 linker 符号(Termux:
pkg install binutils) - 修复工具:
fixso或SoFixer(二选一)
[dependencies]
clap = "4.5" # 命令行参数解析
anyhow = "1.0" # 错误处理
regex = "1.10" # 正则表达式
nix = "0.27" # Unix 系统调用 (信号处理)
colored = "2.1" # 终端彩色输出
libc = "0.2" # C 标准库绑定# 1. 安装依赖
pkg update && pkg upgrade
pkg install rust binutils
# 2. 克隆/创建项目
git clone <your-repo-url> dump_so_rs
cd dump_so_rs
# 3. 下载修复工具到项目根目录
# (从 GitHub Release 或自行编译)
# 确保文件名为: fixso64, fixso32, SoFixer64, SoFixer32
# 4. 编译
cargo build --release
# 5. 运行
su
./target/release/dump_so -n com.example.app -t libil2cpp.so# 1. 添加目标平台
rustup target add aarch64-linux-android
rustup target add armv7-linux-androideabi
# 2. 安装 Android NDK
# 下载: https://developer.android.com/ndk/downloads
export ANDROID_NDK_HOME=/path/to/ndk
# 3. 配置工具链 (创建 .cargo/config.toml)
[target.aarch64-linux-android]
linker = "$ANDROID_NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android30-clang"
# 4. 编译
cargo build --release --target aarch64-linux-android
# 5. 推送到手机
adb push target/aarch64-linux-android/release/dump_so /data/local/tmp/
adb shell chmod +x /data/local/tmp/dump_so# 通过进程名 dump SO
su -c "./dump_so -n com.tencent.mm -t libwechatcommon.so"
# 通过 PID dump SO
su -c "./dump_so -p 12345 -t libnative.so"
# 使用 SoFixer 而非 fixso
su -c "./dump_so -n com.example.app -t libunity.so -s"
# 指定架构(通常自动检测)
su -c "./dump_so -n com.game -t libUE4.so -a arm64"Options:
-n, --process-name <NAME> 目标进程名或包名
-p, --pid <PID> 目标进程 PID
-t, --target-so <SO_NAME> 目标 SO 文件名(必须)
-s, --use-sofixer 使用 SoFixer 修复(默认使用 fixso)
-a, --arch <ARCH> 手动指定架构 (arm/arm64)
-h, --help 显示帮助信息
-V, --version 显示版本信息
[*] Target PID: 12345
[*] Architecture: arm64
[*] Suspending process 12345
[*] Parsing linker symbols...
[*] solist offset: 0x1a3b8
[*] linker base: 0x7f8c234000
[*] solist address: 0x7f8c24e3b8
[*] Target SO: base=0x7c5e230000, end=0x7c5e263000, size=208896
[*] solist head: 0x7f8c24e3c0
[*] First soinfo next: 0x7ff1234000
[*] Found soinfo_size from linker: 204800
[*] Dumping memory...
[+] Dumped 204800 bytes to libil2cpp_dump.so
[*] Fixing SO...
[+] Fixed SO saved to: libil2cpp_0x7c5e230000_204800_fix.so
[*] Resuming process 12345
[+] Done!
kill(pid, Signal::SIGSTOP) // 发送 SIGSTOP 信号暂停进程/system/bin/linker64 (ELF)
↓ readelf -s
找到 __dl__ZL6solist 符号偏移
↓ 读取 /proc/<pid>/maps
计算 linker 加载基址
↓ 基址 + 偏移
得到 solist 链表头指针地址
struct soinfo {
char name[128]; // +0x00
void* base; // +0x10 ← 查找目标
size_t size; // +0x18 ← 提取大小
// ...
soinfo* next; // +0x28 ← 遍历链表
};File::open("/proc/<pid>/mem")
.seek(base_address)
.read_exact(size)dump.so (缺失 Section Header)
↓ fixso / SoFixer
重建 .text, .data, .dynamic 等 Section
↓
fix.so (可用 IDA/Ghidra 分析)
impl Drop for ProcessGuard {
fn drop(&mut self) {
kill(self.pid, Signal::SIGCONT)
}
}- ✅ Android 7.0+ (API 24+)
⚠️ Android 10+ 需要关闭 SELinux 或添加策略- ❌ Android 14 可能需要调整
soinfo结构偏移
不同 Android 版本的 soinfo 结构可能不同:
| Android 版本 | off_next 偏移 |
|---|---|
| 7.0 - 9.0 | 0x28 |
| 10.0 - 12.0 | 0x30 (可能) |
| 13.0+ | 需自行分析 |
如果遇到错误,请手动分析 /system/bin/linker64 的 soinfo 结构。
# 如果遇到 Permission denied
setenforce 0
# 或者添加 SELinux 规则
supolicy --live "allow untrusted_app proc_mem file read"pkg install binutils# 检查 linker 路径
ls -l /system/bin/linker64
# 手动查找符号
readelf -s /system/bin/linker64 | grep solist# 确保以 root 运行
su
whoami # 应显示 root
# 关闭 SELinux
setenforce 0# 确保修复工具有执行权限
chmod +x fixso64 SoFixer64
# 检查是否在同一目录
ls -l fixso64| 特性 | Python 版本 | Rust 版本 |
|---|---|---|
| 运行时依赖 | Python3 + Frida | 无(静态链接) |
| 体积 | ~50MB (含依赖) | ~2MB |
| 启动速度 | ~2s | ~0.1s |
| 内存安全 | ✅ 编译期保证 | |
| 交叉编译 | ❌ 困难 | ✅ 原生支持 |
| 部署难度 | 中等 | 简单(单文件) |
MIT License - 详见 LICENSE 文件
- SoFixer - https://github.com/F8LEFT/SoFixer
- fixso - https://github.com/CodingGay/fixso
- 原 Python 实现的作者
如有问题或建议,欢迎提交 Issue 或 Pull Request。
本工具仅供安全研究和学习使用,请勿用于非法用途。使用本工具所产生的一切后果由使用者自行承担。