Skip to content

About

ARM64 Android dynamic debugging tool: ptrace injection, LuaJIT + Dobby hooking, ChaCha20-encrypted local socket, memory read/write/search, hardware breakpoints and disassembly, without suspending the target process.\面向 ARM64 Android 的动态调试工具:ptrace 注入、LuaJIT + Dobby 插桩、ChaCha20 加密本地通信、内存读写/搜索/修改、硬件断点与反汇编,全程不挂起目标进程。

Resources

Stars

0 stars

Watchers

0 watching

Forks

 
 

Repository files navigation

Universal Debug Tool(通用动态调试工具)

面向 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):hookfunc inline hook、hookCPU 寄存器级插桩、call 主动调用、内存读写辅助。
    • 硬件断点(root):对目标进程所有线程下断,命中后回传寄存器、PC 与堆栈,地址可点击跳转内存页。
    • 反汇编(capstone)与汇编写入(asmjit):内存页内可直接修改指令,例如输入 ~A8 nop、~A8 cset w0, ne。
  • 原生悬浮窗 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、断点服务)

技术实现

Socket 连接方案

  • 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 之间转发。

LuaJIT 交互 Dobby

  • 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 模式),基于 Linux perf_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 / 寄存器 / 堆栈地址均可点击跳转内存页。

已知问题

  1. 断点堆栈结果可能不准:目前只做 native 帧回溯(PC + LR),JNI 调用场景无法还原 Java 调用帧,且依赖目标函数的帧指针与寄存器状态,结果仅供参考。
  2. 部分内核/机型上硬件断点采样到的个别寄存器可能为 0(PERF_SAMPLE_REGS_USER 的内核行为差异);代码已追加 PERF_SAMPLE_REGS_INTR 兜底,仍以真机表现为准。
  3. 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)在本项目开发过程中协助编写代码。

免责声明

  1. 内存分类定义 MemToolTypes.h 提取自 AlguiMemTool.h(作者 ByteCat,MIT License);为尊重作者意愿,提取时保留了原始版权声明与作者信息。
  2. 本工具仅限用于合法用途(如学习研究、对自己拥有权限的程序进行调试等),禁止用于任何非法活动;使用者需自行承担使用本工具产生的全部法律责任。
  3. 本人不一定会对该项目进行维护,如有需求者,请自行下载源码修改并编译。
  4. 本工具仅在作者本人的机型(Android 16)上验证通过,不保证在不同 Android 版本、不同机型上的兼容程度。
  5. 本 README 由 AI 对项目进行分析后编写并优化,不保证内容与实际实现完全一致,可能存在描述不准确或过度夸大之处。

About

ARM64 Android dynamic debugging tool: ptrace injection, LuaJIT + Dobby hooking, ChaCha20-encrypted local socket, memory read/write/search, hardware breakpoints and disassembly, without suspending the target process.\面向 ARM64 Android 的动态调试工具:ptrace 注入、LuaJIT + Dobby 插桩、ChaCha20 加密本地通信、内存读写/搜索/修改、硬件断点与反汇编,全程不挂起目标进程。

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages