PatchEx 是一个面向 IDA Pro 的汇编与字节补丁插件,适用于逆向分析、漏洞研究、二进制修复、CTF/AWDP 等需要精确修改和可靠回滚的场景。
- 基于 Keystone 的汇编补丁。
- 原始字节补丁,支持常见输入格式:
90 90 C39090C3\x90\x90\xC30x90, 0x90, 0xC3db 90h, 90h, 0C3h
- 就地补丁:新代码短于选区时自动填充。
- Code cave trampoline:新代码无法放入原选区时,可跳转到代码洞执行后再跳回。
- 后台扫描 code cave,支持进度显示和取消。
- ELF 可覆盖节扫描,支持
.eh_frame、.eh_frame_hdr、.gcc_except_table等元数据节。 - 补丁预览:按“机器码字节 + 对应汇编”的形式逐行展示。
- 原始选区展示:同步显示原始字节和反汇编。
- 补丁历史记录持久化到 IDB。
- Undo 前校验当前字节,避免覆盖用户或其他插件后续修改。
- 写入后读回校验,确保实际写入字节与预览一致。
Keypatch 是 IDA 中非常经典的 Keystone 汇编补丁插件,适合快速输入汇编并应用补丁。PatchEx 的定位不同:它更像一个完整的补丁工作台,强调预览、符号解析、code cave、历史记录和安全回滚。
| 对比项 | Keypatch | PatchEx |
|---|---|---|
| 主要定位 | 快速 Keystone 汇编补丁 | 带预览、历史、校验和 cave 支持的补丁工作流 |
| 汇编补丁 | 支持 | 支持 |
| 字节补丁 | 支持常见字节格式 | 支持,并显示原始字节、输入字节和最终写入字节 |
| 预览方式 | 偏编码结果展示 | 按每条指令显示“字节 + 汇编” |
| Code cave 工作流 | 不是主要功能 | 内置 cave 扫描、rel32 可达性显示和 trampoline patch |
| Cave 扫描 | 非核心能力 | 后台扫描,支持进度和取消 |
| IDA 符号支持 | 基础名称/地址支持 | 支持自动名、导入名、ELF 版本符号、本地 label、栈变量风格名称、枚举常量、结构体成员、段前缀内存操作数 |
| Undo 模型 | 偏最后一次补丁回滚 | IDB 持久化历史,记录原始字节和补丁字节,Undo 前校验 |
| 安全策略 | 用户自行确认为主 | 未解析符号拒绝汇编;写入前检查映射;写入后读回验证 |
| 大型二进制体验 | 重点在补丁动作本身 | Cave 扫描后台执行,避免 UI 长时间无响应 |
PatchEx 并不是为了在所有场景取代 Keypatch。Keypatch 仍然是紧凑、熟悉的 Keystone 汇编入口;PatchEx 更适合需要审阅字节、使用复杂 IDA 符号、寻找 code cave、保留补丁历史和安全回滚的场景。
PatchEx 会在汇编前解析常见 IDA 风格符号,包括:
- 普通名称:
main、puts、global_buf - IDA 自动名:
loc_401000、sub_401000、qword_404000 - 符号偏移表达式:
symbol+0x10、symbol-4 - 补丁文本内本地 label
- ELF 版本符号:
puts@@GLIBC_2.2.5 - 常见导入/跳板装饰名:
__imp_MessageBoxA、j_puts、_symbol - Demangled/display name 查询
- 栈变量风格名称:
var_8、arg_10 - 混合内存表达式:
[global_buf+rax*4+8] - 枚举常量表达式:
PROT_READ | PROT_WRITE - 结构体成员偏移:
my_struct.field - IDA 段前缀内存操作数:
mov rcx, cs:qword_147CAC8E8mov cs:qword_147CB1490, 0mov word ptr cs:lpServiceName, axmov rax, gs:58h
-
在 IDA 使用的 Python 环境中安装 Keystone:
pip install -r requirements.txt
-
将整个
patchex目录复制到 IDA 插件目录:<IDA>/plugins/patchex/ -
重启 IDA。
-
在反汇编窗口中选中需要修改的指令或字节,然后使用:
右键 -> PatchEx -> PatchEx -- Patch Selection...或快捷键:
Ctrl+Shift+P
- 在 IDA 中选中要替换的指令或字节。
- 打开 PatchEx。
- 查看顶部的原始字节和反汇编。
- 在 ASM 或 Bytes 页面输入补丁内容。
- 检查 Patch Preview 中的最终写入结果。
- 如果可以就地写入,直接 Patch;如果需要 cave,先扫描并选择 cave。
- 在 History 页面查看或撤销已记录补丁。
- 未解析符号会导致汇编失败,PatchEx 不会带着未知符号继续尝试写入。
- Undo 前会检查当前字节是否仍然等于 PatchEx 当初写入的字节。
- 大型二进制的 cave 扫描在后台执行,可以取消。
- 独立 NOP Fill 功能未暴露;如需写入 NOP,请使用 Bytes 页面明确输入字节。