analysis について
analysisは、IDAでのバイナリ調査を支援するスキルです。インポート、文字列、関数間の関係から挙動やセキュリティ上の懸念を調べ、SQLクエリ例と関連スキルへの引き継ぎ手順を提供します。
主な機能
- 01インポートと文字列から手掛かりを抽出
- 02SQLによる関数・呼び出し関係の検索
- 03制御フロー、呼び出し連鎖、データ参照の分析
- 04セキュリティ関連関数のトリアージ
- 05逆コンパイルや注釈スキルへの引き継ぎ
活用シーン
- 01バイナリの挙動の初期調査
- 02ネットワーク、暗号、プロセス関連コードの確認
- 03文字列やAPIの参照元の追跡
- 04高リスク関数の詳細レビュー準備
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ allthingsida/ idasql-skills --skill analysisインストール後、Claude Code で/analysisを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
agents/openai.yamlreferences/analysis-cookbook.mdcrypto-detection.mdnetwork-detection.md詳細
追加リソース
- 暗号化/ネットワーク検出パターンについては、references/crypto-detection.md、references/network-detection.mdを参照してください。
- 高度な SQL パターン(CTE、ウィンドウ関数、バッチ分析、ページネーション)と拡張クエリクックブックについては、references/analysis-cookbook.mdを参照してください。
トリガーとなる意図
次のようなユーザープロンプトには、このスキルを使用してください。
- 「このバイナリは何をしますか?」
- 「不審な動作やセキュリティに関わる動作を探してください。」
- 「どのライブラリ/フレームワークが含まれていますか?」
- 「優先順位を付けたトリアージ計画を提示してください。」
- 「生の行データだけでなく、より高レベルの分析結果を示してください。」
- 「この逆コンパイル結果をソースと比較してください。」
- 「この関数をレビューしやすい状態にするのを手伝ってください。」
必要に応じて、関連するスキルに引き継いでください。
- 生の呼び出し元/呼び出し先の詳細が必要な場合:
xrefs - アセンブリレベルの調査が必要な場合:
disassembly - 擬似コードの意味を把握する必要がある場合:
decompiler - 編集/注釈が必要な場合:
annotations
まず実行すること(ウォームスタート手順)
広く調べてから、対象を絞ります。
-- 1) Binary orientation
SELECT * FROM binary;
-- 2) Capability hints from imports
SELECT module, name FROM imports ORDER BY module, name;
-- 3) Behavioral hints from strings
SELECT content, printf('0x%X', addr) AS addr
FROM strings
WHERE length >= 8
ORDER BY length DESC
LIMIT 40;
解釈の指針:
- 暗号化/ネットワーク/プロセス API と不審な文字列が見つかった場合、通常はそれらに関連する関数を最優先で調べます。
xrefs/disasm_callsを使って「シグナル」から「関数」へと調査を進め、次に可能性の高いホットスポットを逆コンパイルします。
失敗時の対応と復旧
- 結果が空、またはノイズが多い場合:
- パターンを絞り込み、モジュール固有のインポートを手がかりに調査します。
funcsとのJOINを追加し、サイズ/名前または呼び出し密度で絞り込みます。
- デコンパイラーで表示できない場合:
disassemblyとxrefsのパターンを使って調査を続けます。
- 複雑な分析がタイムアウトする場合:
- CTEを段階的に分割し、候補のセットを小さくします。
引き継ぎパターン
analysis->xrefs:シグナルのアドレスを呼び出し元/呼び出し先のグラフにマッピングします。analysis->decompiler:リスクが最も高い関数の意味的なロジックを調べます。analysis->annotations:コメント/名前変更として調査結果を保存し、逆コンパイル結果をレビューしやすい状態にします。
高精度なレビューへの引き継ぎ
ユーザーがソースとの並列比較を希望する場合や、関数を読みやすく「整理」するよう求めた場合は、読み取り専用のトリアージとして扱うのをやめ、annotationsに引き継いでください。
まず、次のレビュー用プローブを実行します。
SELECT decompile(0x401000);
SELECT idx, name, type FROM ctree_lvars WHERE func_addr = 0x401000 ORDER BY idx;
SELECT callee_name FROM disasm_calls WHERE func_addr = 0x401000;
次に、編集作業のためにannotationsへ引き継ぎます。関数がレビューしやすい状態になったことを示すポイントは次のとおりです。
- 型付きのシグネチャと、より明確なフィールドアクセス
- 名前が付けられたローカル変数、グローバル変数、ラベル
- 関数の先頭付近にある、見出し形式の要約コメント
- 関数が継続的なトリアージ/レビュー用の分類に属する場合のフォルダーへの配置
- 生のポインタ演算が減り、汎用的な一時変数名が少ないこと
この要約コメントは、単なる見栄えの調整ではなく、分析成果物の一部として扱ってください。
- 後で意味的な検索をするときに役立つ内容にします。
- 多くの関数にすでに注釈が付いている場合、プログラム全体の理解に役立つ内容にします。
目標ではないこと:
- ソースの構文を正確に再現すること。
qmemcpy(...)のようにデコンパイラーで安定して得られる形式でも、名前、型、コメントが正しければ問題ありません。
クイックスタートの例
「このバイナリは何をしますか?」
-- Entry points
SELECT * FROM entries;
-- Imported APIs (hints at functionality)
SELECT module, name FROM imports ORDER BY module, name;
-- Interesting strings
SELECT content FROM strings WHERE length > 10 ORDER BY length DESC LIMIT 20;
「セキュリティに関わるコードを探す」
-- Dangerous string functions
SELECT DISTINCT (SELECT name FROM funcs WHERE func_addr >= addr AND func_addr < end_addr LIMIT 1) FROM disasm_calls
WHERE callee_name IN ('strcpy', 'strcat', 'sprintf', 'gets');
-- Crypto-related
SELECT * FROM imports WHERE name LIKE '%Crypt%' OR name LIKE '%Hash%';
-- Network-related
SELECT * FROM imports WHERE name LIKE '%socket%' OR name LIKE '%connect%' OR name LIKE '%send%';
-- File likely network triage candidates under a durable folder
INSERT INTO dirtree_folders(tree, path) VALUES ('funcs', 'idasql/triage/network');
UPDATE funcs
SET folder_path = 'idasql/triage/network'
WHERE addr IN (
SELECT DISTINCT func_addr FROM disasm_calls
WHERE callee_name LIKE '%socket%' OR callee_name LIKE '%connect%' OR callee_name LIKE '%send%'
);
「特定の関数を理解する」
-- Basic info
SELECT * FROM funcs WHERE addr = 0x401000;
-- Full disassembly
SELECT disasm_func(0x401000);
-- Decompile (if Hex-Rays available)
SELECT decompile(0x401000);
-- Local variables
SELECT name, type, size FROM ctree_lvars WHERE func_addr = 0x401000;
-- What it calls
SELECT callee_name FROM disasm_calls WHERE func_addr = 0x401000;
-- What calls it
SELECT (SELECT name FROM funcs WHERE from_addr >= addr AND from_addr < end_addr LIMIT 1) FROM xrefs WHERE to_addr = 0x401000 AND is_code = 1;
「文字列のすべての使用箇所を探す」
SELECT s.content, (SELECT name FROM funcs WHERE x.from_addr >= addr AND x.from_addr < end_addr LIMIT 1) as function, printf('0x%X', x.from_addr) as location
FROM strings s
JOIN xrefs x ON s.addr = x.to_addr
WHERE s.content LIKE '%config%';
自然言語でのクエリ例
関数シグネチャのクエリ
「整数を返す関数を表示してください」
SELECT name, return_type, arg_count FROM funcs
WHERE return_is_integral = 1 LIMIT 20;
-- Or via types_func_args (typedef-aware)
SELECT DISTINCT type_name FROM types_func_args
WHERE arg_index = -1 AND is_integral_resolved = 1;
「文字列引数を4つ取る関数を表示してください」
SELECT type_name, COUNT(*) as string_args
FROM types_func_args
WHERE arg_index >= 0
AND is_ptr_resolved = 1
AND base_type_resolved IN ('char', 'wchar_t', 'CHAR', 'WCHAR')
GROUP BY type_ordinal
HAVING string_args = 4;
「ポインターを返す関数はどれですか?」
SELECT name, return_type FROM funcs
WHERE return_is_ptr = 1 ORDER BY name LIMIT 20;
「引数が多いvoid関数を探してください」
SELECT name, arg_count FROM funcs
WHERE return_is_void = 1 AND arg_count >= 4
ORDER BY arg_count DESC;
「どの呼び出し規約が使われていますか?」
SELECT calling_conv, COUNT(*) as count FROM funcs
WHERE calling_conv IS NOT NULL AND calling_conv != ''
GROUP BY calling_conv ORDER BY count DESC;
戻り値の分析
「0を返す関数はどれですか?」
SELECT DISTINCT f.name FROM funcs f
JOIN ctree_v_returns r ON r.func_addr = f.addr
WHERE r.return_num = 0;
「-1を返す関数(エラーパターン)を探してください」
SELECT DISTINCT f.name FROM funcs f
JOIN ctree_v_returns r ON r.func_addr = f.addr
WHERE r.return_num = -1;
「入力引数を返す関数」
SELECT DISTINCT f.name FROM funcs f
JOIN ctree_v_returns r ON r.func_addr = f.addr
WHERE r.returns_arg = 1;
「別の呼び出しの結果を返す関数(ラッパー)」
SELECT DISTINCT f.name FROM funcs f
JOIN ctree_v_returns r ON r.func_addr = f.addr
WHERE r.returns_call_result = 1;
「複数のreturn文を持つ関数」
SELECT f.name, COUNT(*) as return_count
FROM funcs f
JOIN ctree_v_returns r ON r.func_addr = f.addr
GROUP BY f.addr
HAVING return_count > 1
ORDER BY return_count DESC LIMIT 20;
よく使うクエリパターン
最も多く呼び出される関数を探す
SELECT f.name, COUNT(*) as callers
FROM funcs f
JOIN xrefs x ON f.addr = x.to_addr
WHERE x.is_code = 1
GROUP BY f.addr
ORDER BY callers DESC
LIMIT 10;
特定のAPIを呼び出す関数を探す
SELECT DISTINCT (SELECT name FROM funcs WHERE from_addr >= addr AND from_addr < end_addr LIMIT 1) as caller
FROM xrefs
WHERE to_addr = (SELECT addr FROM imports WHERE name = 'CreateFileW');
文字列のクロスリファレンス分析
SELECT s.content, (SELECT name FROM funcs WHERE x.from_addr >= addr AND x.from_addr < end_addr LIMIT 1) as used_by
FROM strings s
JOIN xrefs x ON s.addr = x.to_addr
WHERE s.content LIKE '%password%';
関数の複雑さ(ブロック数による)
SELECT (SELECT name FROM funcs WHERE func_addr >= addr AND func_addr < end_addr LIMIT 1) as name, COUNT(*) as block_count
FROM blocks
GROUP BY func_addr
ORDER BY block_count DESC
LIMIT 10;
リーフ関数を検索(呼び出し先なし)
SELECT f.name, f.size
FROM funcs f
LEFT JOIN disasm_calls c ON c.func_addr = f.addr
GROUP BY f.addr
HAVING COUNT(c.addr) = 0
ORDER BY f.size DESC;
呼び出しチェーンが深い関数
SELECT f.name, MAX(cc.depth) as max_depth
FROM disasm_v_call_chains cc
JOIN funcs f ON f.addr = cc.root_func
GROUP BY cc.root_func
ORDER BY max_depth DESC
LIMIT 10;
対象を絞った走査では、disasm_v_call_chains よりも call_graph テーブルを使用してください。
-- Map all functions in a call subtree
SELECT func_name, depth FROM call_graph
WHERE start = 0x401000 AND direction = 'down' AND max_depth = 5;
対象関数への呼び出しパスをトレース
-- Trace call path to an internal helper
SELECT step, func_name FROM shortest_path
WHERE from_addr = (SELECT addr FROM funcs WHERE name = 'main')
AND to_addr = (SELECT addr FROM funcs WHERE name = 'copy_user_input')
AND max_depth = 20;
呼び出し先がインポートされた API の場合は、call_graph + disasm_calls + imports を使用してください。shortest_path のエンドポイントは関数に解決される必要があります。
関数から到達可能なすべての文字列を検索
SELECT DISTINCT sr.string_value
FROM call_graph cg
JOIN string_refs sr ON sr.func_addr = cg.func_addr
WHERE cg.start = 0x401000 AND cg.direction = 'down' AND cg.max_depth = 3;
3 つの要素:関数から到達可能な文字列 + インポート
-- Three-way: strings + imports reachable from a function
SELECT 'string' as kind, sr.string_value as detail, cg.func_name as via_func
FROM call_graph cg
JOIN string_refs sr ON sr.func_addr = cg.func_addr
WHERE cg.start = 0x401000 AND cg.direction = 'down' AND cg.max_depth = 5
AND sr.string_value LIKE '%http%'
UNION ALL
SELECT 'import', i.name, cg.func_name
FROM call_graph cg
JOIN disasm_calls dc ON dc.func_addr = cg.func_addr
JOIN imports i ON dc.callee_addr = i.addr
WHERE cg.start = 0x401000 AND cg.direction = 'down' AND cg.max_depth = 5
ORDER BY kind, detail;
関連項目
xrefs— 呼び出し/データのシグナルを呼び出し元/呼び出し先のチェーンに変換します。data— 文字列、インポート、バイトパターンをトリアージの証拠として扱います。decompiler— トリアージクエリで特定した疑わしい関数を詳しく調べます。