关于 rev-unicorn-debug
rev-unicorn-debug 是使用 Unicorn 引擎模拟代码片段和函数的逆向调试技能,面向分析原生二进制的开发者。它通过钩子模拟 JNI、系统调用和库依赖,并以迭代方式处理模拟故障。
主要功能
- 01使用原始字节映射目标文件
- 02通过钩子模拟外部依赖
- 03捕获内存访问和系统调用
- 04迭代诊断并修复模拟故障
- 05优先采用基本块级跟踪
适用场景
- 01模拟二进制中的指定函数
- 02为 JNI 或 libc 调用构建替身
- 03定位未映射内存导致的故障
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ p4nda0s/ reverse-skills --skill rev-unicorn-debug安装后在 Claude Code 中输入/rev-unicorn-debug确认已加载。
详细介绍
rev-unicorn-debug - Unicorn 仿真调试器
使用 Unicorn 引擎调试并仿真特定代码片段或函数。分析上下文依赖(JNI、系统调用、库函数),并通过钩子机制进行模拟,以完成用户的调试目标。
核心原则
- 先按原始字节加载文件——不要解析 ELF/PE/Mach-O 头。将文件作为原始字节读取,并直接映射到 Unicorn 内存中。我们只需要仿真特定函数,而不是整个二进制文件。如果原始加载失败(代码引用了特定地址处的段),再进行最少量的解析——只映射所需的段。
- 识别上下文依赖——分析目标代码中的外部调用(JNI、系统调用、libc、导入函数),并为其添加钩子,提供模拟响应。
- 广泛使用回调——利用 Unicorn 的钩子系统进行调试、跟踪、错误恢复和环境仿真。
- 迭代修复——仿真崩溃时,使用回调信息诊断并修复问题(映射缺失内存、为未处理的调用添加钩子、修正寄存器状态)。
- 尽量减少跟踪输出——优先使用块级跟踪,而不是指令级跟踪。仅在小范围目标区域内启用指令跟踪。使用计数器和摘要,而不是逐步记录日志。
环境仿真策略
仿真前,读取目标函数并识别其调用的内容。按地址为外部依赖添加钩子,并在 Python 中模拟:
| 类别 | 示例 | 仿真策略 |
|---|---|---|
| libc | malloc、free、memcpy、strlen、printf | 为地址添加钩子,并在 Python 中实现逻辑(malloc 使用递增分配器) |
| JNI | GetStringUTFChars、FindClass、GetMethodID | 在 UC 内存中构建伪造的 JNIEnv 函数表,在每个条目处写入 RET 存根,并为存根地址添加钩子 |
| 系统调用 | read、write、mmap、ioctl | 添加 UC_HOOK_INTR 钩子,按系统调用编号分发 |
| C++ 运行时 | operator new、__cxa_throw | 添加钩子并进行模拟 |
| 库调用 | pthread_mutex_lock、dlopen | 添加钩子并返回成功结果或存根 |
**钩子模式:**注册 UC_HOOK_CODE 回调。PC 命中已知导入地址时,执行 Python 模拟,然后设置 PC = LR,以跳过原始函数。
要使用的回调类型
| 回调 | 用途 |
|---|---|
UC_HOOK_CODE | 按地址拦截导入调用;指令级跟踪(谨慎使用,仅限较小范围) |
UC_HOOK_BLOCK | 块级跟踪(优先于指令跟踪) |
UC_HOOK_MEM_UNMAPPED | 自动映射缺失页面,以恢复未映射访问错误 |
UC_HOOK_MEM_READ | UC_HOOK_MEM_WRITE | 仅跟踪目标数据范围内的内存访问 |
UC_HOOK_INTR | 拦截 SVC/INT 以模拟系统调用 |
迭代调试工作流
仿真失败时,按以下循环操作:
- 运行——启动仿真,让其崩溃
- 读取回调输出——哪个地址触发了错误?类型是什么(读取/写入/取指)?
- 诊断:
- 未映射内存取指 → 缺少代码页,映射它
- 未映射内存读写 → 缺少数据段或指针未初始化,映射内存或添加钩子
- 命中导入存根 → 识别函数并添加模拟钩子
- 无限循环 → 添加带执行计数器的代码钩子,达到阈值后停止
- 修复——添加钩子 / 映射内存 / 调整寄存器
- 重新运行——重复以上步骤,直到目标函数执行完毕
Architecture Quick Reference
| Arch | Uc Const | Mode | SP | LR | Args | Return | Syscall |
|---|---|---|---|---|---|---|---|
| ARM64 | UC_ARCH_ARM64 | UC_MODE_LITTLE_ENDIAN | SP | X30 | X0-X7 | X0 | X8 + SVC #0 |
| ARM32 | UC_ARCH_ARM | UC_MODE_THUMB / UC_MODE_ARM | SP | LR | R0-R3 | R0 | R7 + SVC #0 |
| x86-64 | UC_ARCH_X86 | UC_MODE_64 | RSP | (stack) | RDI,RSI,RDX,RCX,R8,R9 | RAX | RAX + syscall |
| x86-32 | UC_ARCH_X86 | UC_MODE_32 | ESP | (stack) | (stack) | EAX | EAX + int 0x80 |
| MIPS32 | UC_ARCH_MIPS | UC_MODE_MIPS32 + UC_MODE_BIG_ENDIAN | $sp | $ra | $a0-$a3 | $v0 | $v0 + syscall |
评论
支持 Markdown