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 のフォルダー形式の表記です。どちらを更新しても、同じブレークポイントグループが更新されます。
| Column | Type | RW | Description |
|---|---|---|---|
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 | 利用可能な場合のブレークポイントの完全な dirtree パス |
-- 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(バイトパッチ適用)
パッチに対応した、マップ済みバイトのプログラムビューです。このテーブルはマップ済みのバイトアドレスごとに1行あります。サイズやタイプなどの IDA アイテムメタデータは heads に属します。
| Column | Type | RW | Description |
|---|---|---|---|
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 バイトを大文字の 16 進数として読み取ります |
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 | 重要 — 1 つのアドレスまたは狭い範囲に絞り込んでください |
bytes WHERE is_patched = 1 | 小規模(パッチ数分) | is_patched = 1 | 高速 — IDA のパッチリストを使って、パッチ適用済みの箇所のみを反復します |
breakpointsテーブルは小規模なので、全件スキャンしても問題ありません。bytesテーブルはマッピング済みのバイトごとに 1 行を出力します。WHERE addr = Xまたは狭いaddr範囲を使用してください。bytes WHERE is_patched = 1はパッチ適用済みの箇所のみを反復するため、常に高速です。
関連項目
disassembly— パッチ箇所周辺の命令コンテキスト(disasm_at、オペランドの意味)。annotations— 変更する前に、コメント/ブックマークでパッチの理由を記録します。data— バイト読み取り形式の正式な定義(テーブルとスカラーの区別)。