关于 debugger
debugger 是用于 IDA 调试工作流的技能,面向需要管理断点、观察点和字节补丁的分析人员。它提供断点与补丁清单、写入和恢复流程,以及基于分析结果设置断点的示例。
主要功能
- 01创建、更新和删除断点
- 02管理条件断点与硬件观察点
- 03读取并修改映射字节
- 04查看补丁并恢复原始字节
- 05依据调用点批量设置断点
适用场景
- 01在安全敏感 API 的调用处设置断点
- 02监视结构字段的写入
- 03记录并检查二进制补丁
- 04撤销补丁或验证修改结果
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ allthingsida/ idasql-skills --skill debugger安装后在 Claude Code 中输入/debugger确认已加载。
附带文件agents/openai.yaml
详细介绍
触发意图
当用户要求执行以下操作时,使用此技能:
- 添加/移除/修改断点
- 修补字节或还原补丁
- 创建补丁清单和调试操作计划
- 实施由分析结果驱动的断点/监视点工作流
转到:
- 先使用
analysis/xrefs选择有意义的目标 - 使用
disassembly获取操作码级别的补丁上下文 - 使用
annotations记录补丁的理由和结果
首先执行(预热序列)
-- 1) Current breakpoint inventory
SELECT printf('0x%X', addr) AS addr, type_name, enabled
FROM breakpoints
ORDER BY addr;
-- 2) Current patch inventory (fast: backed by IDA's patch list)
SELECT printf('0x%X', addr) AS addr, original_value, value AS patched_value
FROM bytes WHERE is_patched = 1
ORDER BY addr
LIMIT 50;
-- 3) Validate target bytes before patch
SELECT addr, value, original_value, is_patched
FROM bytes
WHERE addr = 0x401000;
说明:
- 添加更多插桩之前,先确认现有插桩。
- 修改之前,始终先记录当前/原始字节状态的快照。
故障与恢复
- 断点插入/更新失败:
- 验证地址是否存在,以及硬件断点的大小/类型是否兼容。
- 补丁验证不匹配:
- 重新读取
bytes(以及WHERE is_patched = 1),然后使用准确地址重试。
- 重新读取
- 补丁产生意外副作用:
- 使用
DELETE FROM bytes WHERE addr = ...还原,并重新评估目标指令上下文。
- 使用
交接模式
debugger->disassembly,验证补丁位置周围的指令语义。debugger->xrefs,评估已修补/已断开调用路径的影响范围。debugger->annotations,留下持久的分析记录。
breakpoints
调试器断点。支持完整的 CRUD(SELECT、INSERT、UPDATE、DELETE)。即使没有活动的调试器会话,断点也会保留在 IDB 中。folder_path 是 IDA 断点 group 的文件夹形式名称;更新任一字段都会更新同一底层断点分组。
| 列 | 类型 | RW | 说明 |
|---|---|---|---|
addr | INT | R | 断点地址 |
enabled | INT | RW | 1=启用,0=禁用 |
type | INT | RW | 断点类型(1=hw_write,2=hw_read,3=hw_rdwr,4=software,8=hw_exec) |
type_name | TEXT | R | 类型名称(software、hardware_write 等) |
size | INT | RW | 断点大小(用于硬件断点) |
flags | INT | RW | 断点标志 |
pass_count | INT | RW | 触发前的通过次数 |
condition | TEXT | RW | 条件表达式 |
loc_type | INT | R | 位置类型代码 |
loc_type_name | TEXT | R | 位置类型(absolute、relative、symbolic、source) |
module | TEXT | R | 模块路径(相对断点) |
symbol | TEXT | R | 符号名称(符号断点) |
offset | INT | R | 偏移量(相对/符号) |
source_file | TEXT | R | 源文件(源代码断点) |
source_line | INT | R | 源代码行号 |
is_hardware | INT | R | 1=硬件断点 |
is_active | INT | R | 1=当前处于活动状态 |
group | TEXT | RW | 断点组名称 |
bptid | INT | R | 断点 ID |
folder_path | TEXT | RW | 断点组文件夹的别名;NULL 表示根目录 |
full_path | TEXT | R | 可用时的完整断点树路径 |
-- List all breakpoints
SELECT printf('0x%08X', addr) as addr, type_name, enabled, condition
FROM breakpoints;
-- Add software breakpoint
INSERT INTO breakpoints (addr) VALUES (0x401000);
-- Add hardware write watchpoint
INSERT INTO breakpoints (addr, type, size) VALUES (0x402000, 1, 4);
-- Add conditional breakpoint (at a different address than the plain one above)
INSERT INTO breakpoints (addr, condition) VALUES (0x401330, 'eax == 0');
-- Move breakpoint into/out of an IDA breakpoint folder
UPDATE breakpoints SET folder_path = 'idasql/breakpoints/network' WHERE addr = 0x401000;
UPDATE breakpoints SET folder_path = NULL WHERE addr = 0x401000;
-- Disable a breakpoint
UPDATE breakpoints SET enabled = 0 WHERE addr = 0x401000;
-- Delete a breakpoint
DELETE FROM breakpoints WHERE addr = 0x401000;
-- Find which functions have breakpoints
SELECT b.addr, f.name, b.type_name, b.enabled
FROM breakpoints b
JOIN funcs f ON b.addr >= f.addr AND b.addr < f.end_addr;
bytes(字节修补)
纯映射字节的程序视图,支持补丁。此表中每个映射字节地址对应一行;IDA 项目元数据(如大小/类型)属于 heads。
| 列 | 类型 | RW | 说明 |
|---|---|---|---|
addr | INT | R | 字节地址 |
value | INT | RW | 当前字节值(UPDATE 修补 1 个字节) |
word | INT | RW | 2 字节小端值(UPDATE 修补 2 个字节) |
dword | INT | RW | 4 字节小端值(UPDATE 修补 4 个字节) |
qword | INT | RW | 8 字节小端值(UPDATE 修补 8 个字节) |
original_value | INT | R | 修补前的原始字节值 |
is_patched | INT | R | 若字节与原始值不同则为 1(WHERE is_patched = 1 可快速枚举补丁) |
fpos | INT | R | 物理/输入文件偏移量(不可用时为 NULL) |
使用 DELETE FROM bytes WHERE addr = ...(或 WHERE is_patched = 1)还原补丁。
-- Read one address
SELECT addr, value, original_value, is_patched
FROM bytes WHERE addr = 0x401000;
-- Read a byte range, including item-tail bytes
SELECT addr, value
FROM bytes
WHERE addr >= 0x401000 AND addr < 0x401010
ORDER BY addr;
-- Get item metadata separately
SELECT addr, size, type, flags, disasm
FROM heads
WHERE addr = 0x401000;
-- Patch via table update (single byte, or width columns word/dword/qword)
UPDATE bytes SET value = 0x90 WHERE addr = 0x401000;
UPDATE bytes SET dword = 0x90909090 WHERE addr = 0x401000; -- little-endian
-- Inspect patch inventory (fast: backed by IDA's patch list)
SELECT printf('0x%X', addr) AS addr, original_value, value AS patched_value
FROM bytes WHERE is_patched = 1 ORDER BY addr LIMIT 20;
-- Persist once done
SELECT save_database();
bytes — 修补(写入接口)
所有字节修补都通过可写的 bytes 表完成。
| 列 | RW | 含义 |
|---|---|---|
value | RW | 当前字节;UPDATE 修补 1 个字节 |
word / dword / qword | RW | UPDATE 以小端序修补 2/4/8 个字节 |
original_value | R | 原始(修补前)字节 |
is_patched | R | 若已修补则为 1;WHERE is_patched = 1 可快速枚举修补项 |
SELECT printf('0x%X', addr) AS addr,
printf('0x%02X', original_value) AS old,
printf('0x%02X', value) AS new
FROM bytes WHERE is_patched = 1
ORDER BY addr;
通过 bytes 表访问字节
所有字节读取和修补都通过 bytes 表进行。有界读取
形式记录在 data 中;本技能聚焦于修补
工作流。load_file_bytes(...) 会将文件的字节写入 IDB 中
指定的范围;如果修补内容已存在于文件中,请使用此函数。
| 函数 / 形式 | 描述 |
|---|---|
SELECT hex(blob_concat(value)) FROM (SELECT value FROM bytes WHERE start_addr = X AND n = N ORDER BY addr) | 将 N 个字节读取为大写十六进制 |
SELECT blob_concat(value) FROM (SELECT value FROM bytes WHERE start_addr = X AND n = N ORDER BY addr) | 将 N 个字节读取为 BLOB |
load_file_bytes(path, file_offset, addr, size[, patchable]) | 将文件中的字节写入 IDB 的目标范围 |
-- Read 16 bytes as hex
SELECT hex(blob_concat(value))
FROM (SELECT value FROM bytes WHERE start_addr = 0x401000 AND n = 16 ORDER BY addr);
-- Patch one byte (example: NOP) and a 4-byte little-endian value
UPDATE bytes SET value = 0x90 WHERE addr = 0x401000;
UPDATE bytes SET dword = 0x90909090 WHERE addr = 0x401000;
-- Verify current vs original
SELECT value AS current, original_value AS original
FROM bytes WHERE addr = 0x401000;
-- Revert patch (one byte, or every patch)
DELETE FROM bytes WHERE addr = 0x401000;
DELETE FROM bytes WHERE is_patched = 1;
-- Persist patches explicitly
SELECT save_database();
基于分析的断点工作流
在安全敏感 API 的所有调用者处设置断点
使用 disasm_calls 查找每个调用点并批量插入断点:
-- Breakpoint on every call to VirtualAlloc (or similar)
INSERT INTO breakpoints (addr)
SELECT addr FROM disasm_calls WHERE callee_name LIKE '%VirtualAlloc%';
-- Verify
SELECT printf('0x%08X', addr) AS addr, type_name, enabled
FROM breakpoints;
在通过类型分析发现的结构体字段上设置监视点
恢复结构体后,在特定字段偏移处设置硬件监视点:
-- Hardware write watchpoint on a 4-byte field (e.g., config.flags at base+0x10)
-- First, find where the struct base is stored (requires manual analysis)
INSERT INTO breakpoints (addr, type, size) VALUES (0x402010, 1, 4);
-- type=1 is hardware_write, size=4 for DWORD field
根据反编译分析设置条件断点
设置仅在满足特定条件时才会触发的断点:
-- Break when first argument (rcx on x64 fastcall) equals a specific enum value
INSERT INTO breakpoints (addr, condition)
VALUES (0x401000, 'rcx == 3');
-- Break on error return
INSERT INTO breakpoints (addr, condition)
VALUES (0x401050, 'rax == 0xFFFFFFFF');
修补工作流
将反调试检查替换为 NOP
查找并中和 IsDebuggerPresent 检查:
-- Find calls to IsDebuggerPresent
SELECT dc.addr, (SELECT name FROM funcs WHERE dc.func_addr >= addr AND dc.func_addr < end_addr LIMIT 1) AS func_name,
disasm_at(dc.addr, 2) AS context
FROM disasm_calls dc
WHERE dc.callee_name LIKE '%IsDebuggerPresent%';
-- Patch the conditional jump after the check (example: jnz → nop nop)
-- First inspect the instruction after the call
SELECT disasm_at(0x401030, 3);
-- Then patch (adjust addresses based on actual binary)
UPDATE bytes SET value = 0x90 WHERE addr = 0x401035;
UPDATE bytes SET value = 0x90 WHERE addr = 0x401036;
清点所有修补项并生成报告
-- Full patch report: what was changed and where
SELECT printf('0x%X', addr) AS addr,
(SELECT name FROM funcs WHERE addr >= addr AND addr < end_addr LIMIT 1) AS func_name,
printf('0x%02X', original_value) AS original,
printf('0x%02X', value) AS patched,
disasm_at(addr) AS context
FROM bytes WHERE is_patched = 1
ORDER BY addr;
性能说明
| 表 | 大小 | 约束条件 | 说明 |
|---|---|---|---|
breakpoints | 较小(通常 <100) | 无需约束 | 始终很快 |
bytes | 所有已映射字节 | addr | 关键 — 限定为单个地址或紧凑范围 |
bytes WHERE is_patched = 1 | 较小(修补数量) | is_patched = 1 | 很快 — 通过 IDA 的修补列表仅遍历已修补位置 |
breakpoints表很小 — 全表扫描没有问题。bytes表会为每个已映射字节生成一行。使用WHERE addr = X或紧凑的addr范围。bytes WHERE is_patched = 1仅遍历已修补位置 — 始终很快。
另请参阅
disassembly— 修补点周围的指令上下文(disasm_at、操作数语义)。annotations— 修改前通过注释 / 书签记录修补理由。data— 字节读取形式的权威说明(表与标量的区分)。
评论
支持 Markdown