reverse-skills-max: initial public release (restored, redacted, hardened)
This commit is contained in:
146
vendor-new/rev-skills/.claude/skills/re-radare2/SKILL.md
Normal file
146
vendor-new/rev-skills/.claude/skills/re-radare2/SKILL.md
Normal file
@@ -0,0 +1,146 @@
|
||||
---
|
||||
name: re-radare2
|
||||
description: >
|
||||
rizin/radare2 工作流:命令行分析、pdf、V 模式。
|
||||
触发词:radare2、rizin、rz、r2
|
||||
capabilities: [decompilation]
|
||||
---
|
||||
|
||||
# rizin/radare2 命令行分析
|
||||
|
||||
## 何时使用 / 何时不用
|
||||
|
||||
- 用:命令行/脚本化分析;内存 <4GB 或远程环境(GUI 反编译器跑不动);快速反汇编与交叉引用;`pdf`/`V` 模式探索;固件/批量样本脚本化分析
|
||||
- 用:无 GUI 的 SSH/CI 环境(rz 纯终端,`-q -c` 一行批处理)
|
||||
- 不用:需要成熟 GUI 反编译与类型传播(走 [[re-ghidra]])
|
||||
- 不用:只需初勘结论([[re-triage]])
|
||||
- 不用:Windows 用户态调试为主([[re-x64dbg]] / [[re-windbg]] 更顺手;rz 调试器在 Windows 上能力有限)
|
||||
|
||||
## 工具准备
|
||||
|
||||
参考 [[re-analyze/platform-tips]]——命令行工具适配远程/低内存环境;平台分支的 Wine/QEMU 用户态仿真经验同样适用。
|
||||
|
||||
### rizin(radare2 的活跃分支)
|
||||
|
||||
- macOS: `brew install rizin`
|
||||
- Arch: `pacman -S rizin`
|
||||
- Fedora/RHEL(EPEL 8+): `dnf install rizin`(Fedora 当前受支持版本与 EPEL 8/9/10 均有包);已 EOL 的 Fedora 先查发行版仓库,无包再用官方 release 或 `rz-pm`
|
||||
- Debian/Ubuntu: **仓库无 rizin 包,`apt install rizin` 会失败**——改用官方 release 二进制(GitHub rizinorg/rizin releases:static tar.xz / Windows zip / macOS pkg)或 `rz-pm`
|
||||
- Kali: `apt install rizin`(Kali 自有仓库有包,前提是使用 Kali 官方源)
|
||||
- Windows: 官方 release zip 解压即用(`rz-bin.exe`)
|
||||
- 验证: `rizin -v`、`rz-bin -V`
|
||||
- 说明: 发行版包状态随时间变化,安装前先查目标发行版仓库;成功与否一律以 `rizin -v` 为准。其他技能需要 rizin 安装步骤时引用本处矩阵,不各自复制发行版命令。
|
||||
|
||||
### radare2 兼容层(旧命令体系)
|
||||
|
||||
- Linux: `apt install radare2` / `dnf install radare2` / `pacman -S radare2`
|
||||
- macOS: `brew install radare2`
|
||||
- Windows: `choco install radare2`
|
||||
- 验证: `r2 -v`
|
||||
- 注意: rz 与 r2 命令基本兼容(`pdf`/`axt`/`V` 相同),但插件名与个别命令有差异(下文标注)
|
||||
|
||||
### rz-ghidra 反编译插件
|
||||
|
||||
- 全平台: `rz-pm -ci rz-ghidra`(rizin 包管理,需网络与编译工具链)
|
||||
- 验证: rizin 内 `pdg @ main` 能输出伪 C
|
||||
|
||||
## 操作步骤
|
||||
|
||||
1. **`rizin -A` 全自动分析**:
|
||||
```sh
|
||||
rizin -A sample
|
||||
```
|
||||
等待分析完成提示(大文件按 `p` 分页观察)。`-A` 等同 `aaa`(全量自动分析: 函数/交叉引用/字符串引用)。只做浅层时用 `-a x86` 等按需参数。退出: `q`。
|
||||
- 无参数直接进交互模式后补分析: `aaa`;轻量版 `aa`(函数+字符串引用,大文件首选)
|
||||
- 函数列表: `afl`;单函数信息: `afi @ main`;手工定义函数: `af @ 0x401000`
|
||||
|
||||
2. **`pdf` 反汇编函数**:
|
||||
```
|
||||
[0x00001040]> pdf @ sym.main
|
||||
```
|
||||
- 无符号(stripped)时先找入口: `izz~entry` 或 `af @ 0x401000` 手工定义函数后再 `pdf @ 0x401000`
|
||||
- `pdf` = print disassembly function;`pd 20` = 打印 20 条指令;`pdr` 打印带引用
|
||||
- 混入分析噪声时用 `pdf @ <addr> | grep call` 过滤调用
|
||||
- 重命名: `afn 新名字 @ 地址`;注释: `CCu 注释 @ 地址`
|
||||
|
||||
3. **`axt` 交叉引用**:
|
||||
```
|
||||
[0x00001040]> axt @ 0x403000 # 谁引用 0x403000
|
||||
[0x00001040]> axf @ sym.main # main 引用了谁
|
||||
```
|
||||
字符串引用: `izz` 列出全部字符串,`axt @ str.<名称>` 找引用点(字符串已被自动命名)。
|
||||
- 定位链: `izz` 找关键字符串 → `axt @ str.xxx` → 跳到引用函数 `s <地址>` → `pdf`——与 [[re-ida]] 的 Alt+T→x→F5 同思路
|
||||
|
||||
4. **可视化 `V` 模式**:
|
||||
```
|
||||
[0x00001040]> V
|
||||
```
|
||||
- `p` 切换视图(反汇编/十六进制/图形)
|
||||
- `s` 后跟地址/符号跳转(`s sym.main`);`f` 定义函数;`d` 反汇编切换
|
||||
- 图形视图(函数流程): `V` 内按 `p` 到 graph 视图,方向键导航——梳理控制流用
|
||||
- 退出 V: `q`;退出 rizin: 再 `q`
|
||||
|
||||
5. **脚本与 rz-ghidra 反编译**:
|
||||
```sh
|
||||
# 一行命令批处理
|
||||
rizin -q -c 'aaa; pdf @ sym.main; axt @ 0x403000; quit' sample
|
||||
```
|
||||
```sh
|
||||
# 反编译
|
||||
rz-pm -ci rz-ghidra
|
||||
rizin -c 'aaa; pdg @ sym.check' sample
|
||||
```
|
||||
`pdg` = Ghidra 风格伪 C 输出;无插件时退回 `pdf` + 人工还原。
|
||||
- 脚本文件: `rizin -i script.r2 sample`(或交互内 `. script.r2`);脚本里每条命令一行,`quit` 结尾
|
||||
|
||||
6. **调试模式(rz 内置调试器)**:
|
||||
```sh
|
||||
rizin -d ./sample # 以调试模式启动
|
||||
rizin -d -p 1234 # attach pid
|
||||
```
|
||||
```
|
||||
[0x7f...]> db 0x401000 # 断点(db = debugger breakpoint,与 r2 相同)
|
||||
[0x7f...]> dc # 继续(continue)
|
||||
[0x7f...]> ds / dso # 单步 / 步过
|
||||
[0x7f...]> dr eax=0 # 改寄存器(绕过校验常用)
|
||||
[0x7f...]> px @ rsp # 看栈内容
|
||||
[0x7f...]> drr # 全部寄存器
|
||||
```
|
||||
- 断点表: `db`(无参数列出);删断点: `db- 地址`;条件断点: `db 地址:条件`(如 `db 0x401000:eax==1`)
|
||||
- 调试与 gdb 的差异见 [[gotchas]];gdb 系流程见 [[re-gdb]]
|
||||
|
||||
7. **搜索与内存操作**:
|
||||
```
|
||||
[0x00001040]> /x 5548 # 十六进制搜索
|
||||
[0x00001040]> /v 0xdeadbeef # 32 位值搜索(小端)
|
||||
[0x00001040]> /w "password" # 字符串搜索
|
||||
[0x00001040]> /r sym.check # 引用搜索(找谁引用了符号)
|
||||
[0x00001040]> wx 9090 @ 0x401000 # 写字节(NOP 补丁)
|
||||
[0x00001040]> px 32 @ 0x401000 # 读 32 字节
|
||||
```
|
||||
- 文件信息: `rz-bin -I sample`(架构/入口/段)、`rz-bin -z sample`(字符串)、`rz-bin -i sample`(导入)——等价 r2 的 `rabin2 -I/-z/-i`
|
||||
|
||||
8. **项目与导出**:
|
||||
```
|
||||
[0x00001040]> Ps project_name # 保存项目(含分析结果与标注)
|
||||
[0x00001040]> Po project_name # 打开项目
|
||||
[0x00001040]> Pj > out.json # 导出 JSON 项目(供脚本二次处理)
|
||||
```
|
||||
- 分析标注(重命名/注释)随项目持久化——下次 `Po` 直接续用
|
||||
|
||||
## 跨域联合
|
||||
|
||||
- [[re-binary-core]]:工作流第 5 步低内存/命令行替代方案(`RE_DECOMPILER=radare2`)
|
||||
- [[re-firmware]]:固件 ELF 批量脚本化分析(无 GUI 环境)
|
||||
- [[re-ctf]]:CTF 题命令行快攻
|
||||
- 与 [[re-format-elf]] 衔接读结构;需要 GUI 反编译时转 [[re-ghidra]]
|
||||
- 动态调试场景与 [[re-gdb]] 互补(gdb 生态/插件更全,rz 内置调试器轻量)
|
||||
|
||||
## 常见坑与陷阱
|
||||
|
||||
- **未 `-A` 前信息少**:不开分析则无函数边界/无交叉引用——先 `-A`(或 `aaa`),再看符号
|
||||
- **大文件分析慢**:全量 `aaa` 在超大固件上极慢——用 `aa`(轻量)或 `aa~` 限制,或只对目标段 `af @ addr` 手工分析
|
||||
- **命令体系 r2/rz 差异**:网上教程多为 radare2(r2),rizin(rz)大体兼容但插件安装(`r2pm`→`rz-pm`)、个别命令名不同——先 `rz?` 查帮助再执行
|
||||
- `pdf` 依赖函数边界——无符号时 `af` 先定义,否则输出为空或错位
|
||||
- 管道输出带颜色/分页符会污染脚本解析——批处理用 `e scr.color=0` 去色(`-2` 只关 stderr 告警,不去色)
|
||||
- 版本差异、调试器与 PIE 地址坑见 [[gotchas]]
|
||||
@@ -0,0 +1,115 @@
|
||||
# rizin/radare2 命令速查与操作序列
|
||||
|
||||
rizin(rz)与 radare2(r2)命令体系同源:交互提示符 `[0x...]>`,命令 = 短字母 + 参数 + `@ 地址` 作用域。批处理用 `-q -c 'cmd1; cmd2; quit'`(`-q` 静默模式去掉提示符输出)。下文命令以 rizin 现行语法为准,r2 差异处标注。官方文档: rizin.re/book(Rizin Book)。
|
||||
|
||||
## 命令族速查
|
||||
|
||||
### 启动与分析
|
||||
|
||||
- `rizin [-A] [-d] [-q -c '...'] sample`:`-A`=自动分析、`-d`=调试模式、`-q`=静默、`-c`=执行命令后退出
|
||||
- `aaa` 全量分析(函数/引用/字符串);`aa` 轻量(函数+字符串引用,大文件首选);`aac` 只做调用图
|
||||
- `afl` 函数列表;`afi @ 函数` 函数详情;`af @ 地址` 手工定义函数;`afn 名 @ 地址` 重命名
|
||||
- `s 地址/符号` 跳转(seek);`f 名 @ 地址` 定义标记(flag)
|
||||
- `iI` 文件信息;`iS` 段列表;`ie` 入口点;`il` 链接库
|
||||
|
||||
### 反汇编
|
||||
|
||||
- `pdf @ 函数` 函数反汇编;`pd N` N 条指令;`pdr` 带引用反汇编;`pdc` 伪 C(内置轻量反编译)
|
||||
- `pdg @ 函数` Ghidra 风格伪 C(需 rz-ghidra 插件)
|
||||
- `p=` 熵/可打印字符/字符分布条(Rizin Book: entropy/printable/chars bars)——高熵段提示加密/压缩数据
|
||||
- `e asm.pseudo=true` 伪汇编模式(寄存器名简化,可读性提升)
|
||||
|
||||
### 交叉引用与字符串
|
||||
|
||||
- `axt @ 地址/符号` 谁引用它(to);`axf @ 地址` 它引用了谁(from);`axg` 引用图
|
||||
- `izz` 全部字符串(含数据段);`iz` 当前段字符串;`izz~关键字` 过滤
|
||||
- 字符串自动命名 `str.xxx`——`axt @ str.xxx` 直接找引用点
|
||||
|
||||
### 搜索
|
||||
|
||||
- `/x 十六进制` 字节搜索;`/v 值` 按位宽值搜索(`/v4` 指定 4 字节);`/w 字符串` 文本搜索
|
||||
- `/r 符号` 引用搜索(找指针指向目标);`/a 汇编指令` 按指令搜索(如 `/a jmp`)
|
||||
- 命中结果进 `hit0_...` 标记,用 `s hit0_0` 逐个跳转
|
||||
|
||||
### 内存与补丁
|
||||
|
||||
- `px N` 十六进制读(`pxw` 按字、`pxr` 带引用标注——找指针);`p8 N` 裸字节输出
|
||||
- `wx 字节串 @ 地址` 写十六进制;`wv 值 @ 地址` 写值;`wa 汇编 @ 地址` 汇编写入(如 `wa nop @ 0x401000`)
|
||||
- 补丁存盘: `Ps 项目名` 保存项目(标注随项目);`zo`/`zr` 撤销/重做(写操作前先确认 undo 可用)
|
||||
|
||||
### 调试(rz 内置)
|
||||
|
||||
- 启动: `rizin -d sample`;attach: `rizin -d -p PID`
|
||||
- `db 地址` 断点;`db` 列表;`db- 地址` 删除;`db 地址:eax==1` 条件断点
|
||||
- `dc` 继续;`ds` 单步;`dso` 步过;`dcu 地址` 运行到地址
|
||||
- `dr` 寄存器;`dr eax=0` 改寄存器;`drr` 全部寄存器(含标志位)
|
||||
- `px @ rsp` 看栈;`dbt` 回溯(backtrace);`dt 类型 @ 地址` 按类型转储
|
||||
- `dm` 内存映射(看模块基址——PIE 目标重定位后地址变化,见 gotchas)
|
||||
|
||||
### 项目与文件工具
|
||||
|
||||
- `Ps 名` 保存项目 / `Po 名` 打开 / `Pj > out.json` JSON 导出
|
||||
- `rz-bin -I/-z/-i/-E/-l sample`:信息/字符串/导入/导出/链接库(r2 对应 `rabin2`)
|
||||
- `rz-pm -ci rz-ghidra` 安装插件;`rz-pm -l` 列出
|
||||
|
||||
## 常用操作序列(组合套路)
|
||||
|
||||
### 1. 定位校验/授权比较点(字符串 → 引用 → 反汇编)
|
||||
|
||||
```
|
||||
rizin -A sample
|
||||
izz~fail|错误|invalid # 找提示字符串
|
||||
axt @ str.<提示串> # 谁引用
|
||||
s <引用地址>; pdf # 向上看比较指令与调用链
|
||||
```
|
||||
|
||||
### 2. 无符号(stripped)目标恢复主逻辑
|
||||
|
||||
```
|
||||
rizin -A sample
|
||||
ie # 入口地址
|
||||
s <入口>; af # 定义入口函数
|
||||
afl # 看函数列表(找大函数=主逻辑候选)
|
||||
pdf @ <大函数> # 逐函数分析,afn 重命名
|
||||
```
|
||||
|
||||
### 3. 绕过校验(调试模式改寄存器/补丁)
|
||||
|
||||
```
|
||||
rizin -d sample
|
||||
db 0x401000:eax==0 # 条件断点命中比较点
|
||||
dc # 跑到断点
|
||||
dr eax=0 # 改返回/比较值
|
||||
dc # 继续,观察是否绕过
|
||||
# 持久化方案: wa / wx 打补丁 → Ps 保存项目
|
||||
```
|
||||
|
||||
### 4. 批量分析一批样本(脚本文件)
|
||||
|
||||
```
|
||||
# analyze.r2: aaa; afl; pdf @ main; quit
|
||||
for f in samples/*; do rizin -q -i analyze.r2 "$f" > "$f.out"; done
|
||||
```
|
||||
|
||||
### 5. 解密循环定位(写断点看写入)
|
||||
|
||||
```
|
||||
/w 可疑字节模式 # 或 axt 定位解密函数
|
||||
db <解密循环写地址> # 对写入点下断
|
||||
dc; px @ <地址> # 命中后看解密输出
|
||||
```
|
||||
|
||||
## 实现教训(内化)
|
||||
|
||||
- 一切命令都可用 `@ 地址` 指定作用域——批处理时把地址写进命令,别依赖 seek 状态
|
||||
- 输出进管道/文件前先 `e scr.color=0` 去色(`-2` 只关 stderr 告警,不去色),颜色 ANSI 码会污染解析
|
||||
- `izz` vs `iz`:找全库字符串用 `izz`;`izz~xxx` 过滤是定位提示串最快的路
|
||||
- `pdf` 之前先确认函数边界(`af`/`afl`)——无边界时 pdf 输出错位
|
||||
- 大文件全量 `aaa` 慢:先 `aa` 拿函数列表,重点函数 `af @ 地址` 补全
|
||||
- 项目 `Ps` 是标注持久化唯一正路(重命名/注释/断点全保存),别依赖终端历史
|
||||
|
||||
## 使用注意
|
||||
|
||||
- 全部在沙箱内执行([[re-analyze/platform-tips]] 最高原则);`rizin -d` 调试属于动态执行
|
||||
- 分析结论对照 [[re-triage]] 初勘值入档,写 [[re-analyze/analysis-contract]]
|
||||
- 带壳目标先 [[re-anti-analysis]] 脱壳再分析;批量任务注意 `-q` 静默与退出码
|
||||
@@ -0,0 +1,37 @@
|
||||
# rizin/radare2 工具特有坑与边界
|
||||
|
||||
## r2 / rz 差异(迁移雷达)
|
||||
|
||||
- **项目分叉**:rizin 是 radare2 的分叉(2021 起,r2 5.x 时代),两者命令大体兼容但独立演进——r2 教程/博客的命令先 `rz? 命令名` 确认存在再执行
|
||||
- **插件体系不同**:`r2pm`(r2)vs `rz-pm`(rz),插件不通用;rz-ghidra 是 rz 的反编译插件,r2 对应 `r2ghidra`(r2pm 安装)
|
||||
- **二进制名不同**:`r2`/`rabin2`(r2)vs `rizin`/`rz-bin`(rz);`rz-bin` 参数与 `rabin2` 基本对齐(`-I/-z/-i/-E/-l`)
|
||||
- **个别命令名差异**:rz 0.7+ 字符串命令 `izz`/`iz` 保留;但部分分析命令改名(如 r2 的 `axt` 系在 rz 全量保留,`axg` 输出格式不同)——以本技能 commands.md 的现行语法为准
|
||||
- **版本节奏**:radare2 当前主线 6.2.x;Rizin 当前主线 0.9.x(以官方 Releases 最新为准,不锁定 patch 号)——2021 年分叉后独立演进,命令/API/插件 ABI 不得按共同版本经验推断,执行前用 `r2 -v` / `rizin -v` 核验。Rizin 0.9 起默认启用新分析器(RzAnalysis 2.0 风格行为,个别命令输出有变),大版本升级后先跑一遍验证命令
|
||||
|
||||
## 分析相关坑
|
||||
|
||||
- **未分析先看 = 空数据**:不开 `-A`/`aaa` 就没有函数边界与交叉引用——`pdf`/`axt` 输出空或错位是常态,先分析
|
||||
- **`aaa` 全量在超大文件上极慢**(固件几十 MB 可达分钟级):先用 `aa` 或 `aa~`,只对重点段 `af @ 地址`;分析中途可 Ctrl+C,已分析部分保留
|
||||
- **`pdf` 依赖函数边界**:stripped 目标必须 `af @ 地址` 先定义;无边界时输出可能只打印一条指令或错位
|
||||
- **字符串搜索用 `izz` 不是 `iz`**:`iz` 只看当前段,`.rodata` 外字符串(`.data` 解密后)会漏——全量用 `izz`
|
||||
- **PIE/ASLR 地址漂移**:`-A` 分析得到的地址在调试运行后变化(加载基址不同)——调试会话用 `dm` 看真实基址,断点下符号名或按 `dm` 结果换算;静态分析阶段地址是文件映像地址,别拿去和调试内存地址直接比
|
||||
|
||||
## 调试器坑(rz 内置 vs gdb)
|
||||
|
||||
- **命令体系不是 gdb**:gdb 的 `b`/`c`/`si` 对应 rz 的 `db`/`dc`/`ds`——从 [[re-gdb]] 切过来先别顺手打 `b main`
|
||||
- **条件断点语法是 `db 地址:条件`**(冒号),不是 gdb 的 `b ... if ...`
|
||||
- **attach 受权限与 YAMA 限制**:Linux 上 `ptrace` 限制(`/proc/sys/kernel/yama/ptrace_scope`)会让 `rizin -d -p` 失败——临时放开或换 gdb + 同权限启动
|
||||
- **内置调试器能力有限**:无内核态调试、对多线程/信号处理不如 gdb 成熟——复杂调试场景直接转 [[re-gdb]]
|
||||
- **调试目标带反调试**:`ptrace` 检测类反调试会干扰——静态分析定位检测点(`/a` 搜 `ptrace` 调用)后处理,见 [[re-anti-analysis]]
|
||||
|
||||
## 输出与批处理坑
|
||||
|
||||
- **颜色/分页污染管道**:命令输出经管道/重定向时带 ANSI 颜色与交互提示——加 `-q` 静默、`e scr.color=0` 关色、必要时 `e scr.interactive=false`
|
||||
- **批处理不回显错误**:`-c 'cmd; quit'` 里命令出错只打印到 stderr——用 `-e bin.cache=true` 或脚本文件 `-i` 便于排错;检查退出码
|
||||
- **大输出刷屏**:`pdf` 在超大函数上输出几千行——`pdf @ 函数 | less` 或 `pd 50` 分段看
|
||||
- **`Po` 打开旧项目版本不匹配**:rz 版本升级后旧项目可能加载失败——项目文件与版本强绑定,升级后重建分析
|
||||
|
||||
## 使用注意
|
||||
|
||||
- 全部在沙箱内执行([[re-analyze/platform-tips]] 最高原则);`rizin -d` 调试属动态执行默认沙箱
|
||||
- 命令细节以目标版本实际行为为准(`rz -v` 查版本);不同版本差异优先查 Rizin Book
|
||||
Reference in New Issue
Block a user