面向 ARM64 Android 的本地动态调试工具:运行期调试(函数插桩、硬件断点、主动调用、内存读写、搜索、修改)不挂起目标进程;注入阶段通过 ptrace 会短暂挂起目标进程,注入完成后恢复。整个工具被打包成一个 Android APK,注入与调试能力依赖设备 root。
- 进程管理:root 下按 PID / 包名枚举进程,支持刷新列表。
- 动态注入:基于 ptrace 将 agent.so(集成 LuaJIT 与 Dobby)注入目标进程;注入器负责 ELF 解析、远程内存分配、dlopen 等。
- 加密通信:GUI 与 agent 之间通过本地 Unix socket 通信,负载使用 ChaCha20 加密,双向独立密钥流。
- 内存查看与修改
- 解析
/proc/<pid>/maps与/proc/<pid>/mem,按 GG 风格对内存页分类(code app、code system、anonymous、java heap、cpp heap、stack、ashmem 等)。 - 连续 / 分页两种浏览模式,支持内存类型多选筛选、数值类型切换(dword、float、utf8、utf16、hex 等)。
- 单条内存修改、偏移跳转、地址保存页、链接库基址跳转。
- 内存搜索:精确搜索、模糊搜索、改善搜索结果,内存类型可多选(精确 / 范围搜索基于 MemorySearch 引擎,多线程扫描)。
- 解析
- 动态调试
- LuaJIT 脚本引擎(FFI):
hookfuncinline hook、hookCPU寄存器级插桩、call主动调用、内存读写辅助。 - 硬件断点(root):对目标进程所有线程下断,命中后回传寄存器、PC 与堆栈,地址可点击跳转内存页。
- 反汇编(capstone)与汇编写入(asmjit):内存页内可直接修改指令,例如输入
~A8 nop、~A8 cset w0, ne。
- LuaJIT 脚本引擎(FFI):
- 原生悬浮窗 GUI:基于 Android View 的可拖动气泡 + 全屏面板(选项 / 搜索 / 保存 / 内存 / 断点 / 脚本六个 Tab),支持拖动、Tab 切换、深色模式显示;不依赖 ImGui 渲染。
- Android Studio 工程,执行
assembleDebug可一次性构建原生悬浮窗(Kotlin + JNI)、agent.so、注入器并打包为一个 APK。 - 使用注入、断点、socket relay 等功能需要 root 权限。
- Kotlin 原生悬浮窗 UI:
app/src/main/java/com/Alive/Trace/overlay(气泡、面板、各功能页、JNI 桥)。 app/src/main/cpp下主要分三部分:
| 目录 | 说明 |
|---|---|
backend |
后端复用层:内存搜索(memorysearch)、断点客户端(BpService)、socket 客户端、反汇编(capstone)、汇编写入(asmjit);由 overlay_bridge.cpp 通过 JNI 暴露给悬浮窗 |
agent |
SO 端:注入目标进程,内置 LuaJIT、Dobby、xDL、socket 服务端与内存工具 |
injector |
注入器:ptrace 注入、ELF 解析、root 服务(密钥生成、socket relay、断点服务) |
- agent 作为 Unix 域 socket 服务端,监听抽象命名空间(
sun_path[0] = '\0'),不落地 socket 文件,从而规避 SELinux 对/data/local/tmp下 socket 文件的限制。 - 加密密钥由注入器(root)预先生成到
/data/local/tmp/universal_debug_tool_key.bin(32 字节 key + 12 字节 nonce),agent 直接复用,避免注入后因权限不足而无法生成。 - 消息格式为 4 字节大端长度 + ChaCha20 密文;两个方向使用独立 nonce 与消息计数器,防止重放与串流。
- GUI 端优先直连 socket;若被 SELinux 拦截,则回退到 root relay:通过 su 启动注入器的 relay 模式,在 stdin/stdout 与 socket 之间转发。
- agent 维护一个持久 LuaJIT 状态(含 FFI),脚本通过加密 socket 以
lua <script>消息执行,输出回传 GUI 日志框。 - 主要 API:
getBase:使用 xDL(xdl_iterate_phdr)遍历目标进程已加载的 so,返回基址。hookfunc/removehook:封装 DobbyHook,返回跳板地址与成功标志;脚本通过 FFI 将跳板转成函数指针以调用原函数。hookCPU:封装 DobbyInstrument,回调中提供寄存器上下文(lightuserdata)与函数地址。call:把 Lua 闭包排队执行,优先在目标进程主线程(泵为eglSwapBuffers渲染循环或ALooper_pollOnce主线程 Looper);若均不可用,则由独立兜底线程执行(每 20ms 刷新,此时不在目标主线程)。read*/write*:内存读写辅助函数。
- hook 回调与脚本执行共用递归互斥锁,避免回调中再次执行 Lua 造成死锁。
- 搜索引擎运行在应用进程内(MemorySearch,MIT):应用进程非 root,无法直接 open 目标进程
/proc/<pid>/mem,因此通过新增的 MemSu 后端(su+dd管道)读写目标内存,maps枚举同样走 su,不占用 agent socket 通道。 - 精确 / 范围搜索已接入该引擎(多线程并行扫描);模糊搜索与"改善"仍为旧实现。
- 断点服务以 root 运行(注入器
--bp模式),基于 Linuxperf_event_open硬件断点(PERF_TYPE_BREAKPOINT),由内核直接编程 CPU 调试寄存器。 - 周期性重扫目标进程全部线程并统一挂断点,且不设置 sigtrap 位:目标进程不会停顿、不会被 ptrace、也不会收到 SIGTRAP。
- 命中时通过
PERF_SAMPLE_REGS_USER采集寄存器(跳过regs_user_abi字段),连同 PC、线程 ID、堆栈链一并回传。 - 与 GUI 通过管道协议通信(stdin:set / clear / clearall / list / ping / quit;stdout:OK / ERR / INFO / HIT)。GUI 断点页展示寄存器网格、PC 汇编与堆栈链,PC / 寄存器 / 堆栈地址均可点击跳转内存页。
- 断点堆栈结果可能不准:目前只做 native 帧回溯(PC + LR),JNI 调用场景无法还原 Java 调用帧,且依赖目标函数的帧指针与寄存器状态,结果仅供参考。
- 部分内核/机型上硬件断点采样到的个别寄存器可能为 0(
PERF_SAMPLE_REGS_USER的内核行为差异);代码已追加PERF_SAMPLE_REGS_INTR兜底,仍以真机表现为准。 - Android 10+ 会对后台应用的剪贴板读写做限制:默认直接写剪贴板,若 ROM 禁止,可在「选项」页开启「兼容复制」。
- 模糊搜索与"改善"仍为旧实现(单块 su 读取 + 单线程扫描),尚未接入 MemorySearch 引擎。
| 库 | 用途 | 改动情况 | 许可证 |
|---|---|---|---|
| asmjit | AArch64 汇编文本写入 | 未改源码,仅新增封装层(Disasm/AsmWrite.h);CMake 只编译 core/support/arm 子集 | Zlib |
| capstone | 反汇编 | 未改源码 | BSD-3-Clause |
| xDL | so 遍历、基址解析 | 未改源码 | MIT |
| LuaJIT | 脚本引擎 | 未改源码 | MIT |
| Dobby | inline hook | 未改源码,使用预编译 libdobby.a,经 LuaEngine 薄封装 |
Apache-2.0 |
| AndroidInject | ptrace 注入器基础 | 未改源码 | 上游未确认,详见上游仓库 |
| MemorySearch | 内存读写 / 搜索 | 剔除 Keystone 依赖(write_assembly,避免引入 GPL);新增 su 后端适配器 MemSu;maps 读取改为 su 管道;源码位于 backend/jni/memsearch |
MIT |
本项目自身代码以 Apache License 2.0 发布(见 LICENSE),项目内集成的第三方开源库保留其原有许可证,详见上文"参考库与改动说明"。
感谢以下开源项目及其作者:asmjit、capstone、xDL、LuaJIT、Dobby、AndroidInject、MemorySearch。
特别感谢 AlguiMemTool.h 的作者 ByteCat(MIT License):本项目内存分类规则(MemToolTypes.h)基于该库提取,使用过程中保留了原始版权声明与注释。
特别感谢 MemorySearch 的作者 Aboy-g(MIT License):本项目内存搜索引擎基于该库,已剔除其 Keystone 依赖并保留原始 LICENSE。
特别感谢 Codex(OpenAI)在本项目开发过程中协助编写代码。
- 内存分类定义
MemToolTypes.h提取自 AlguiMemTool.h(作者 ByteCat,MIT License);为尊重作者意愿,提取时保留了原始版权声明与作者信息。 - 本工具仅限用于合法用途(如学习研究、对自己拥有权限的程序进行调试等),禁止用于任何非法活动;使用者需自行承担使用本工具产生的全部法律责任。
- 本人不一定会对该项目进行维护,如有需求者,请自行下载源码修改并编译。
- 本工具仅在作者本人的机型(Android 16)上验证通过,不保证在不同 Android 版本、不同机型上的兼容程度。
- 本 README 由 AI 对项目进行分析后编写并优化,不保证内容与实际实现完全一致,可能存在描述不准确或过度夸大之处。