mcpField
A
analysis

analysis

github.com/allthingsidaセキュリティ4949 回インストール3 週間前に更新
リポジトリ

analysis について

analysisは、IDAでのバイナリ調査を支援するスキルです。インポート、文字列、関数間の関係から挙動やセキュリティ上の懸念を調べ、SQLクエリ例と関連スキルへの引き継ぎ手順を提供します。

主な機能

  1. 01インポートと文字列から手掛かりを抽出
  2. 02SQLによる関数・呼び出し関係の検索
  3. 03制御フロー、呼び出し連鎖、データ参照の分析
  4. 04セキュリティ関連関数のトリアージ
  5. 05逆コンパイルや注釈スキルへの引き継ぎ

活用シーン

  1. 01バイナリの挙動の初期調査
  2. 02ネットワーク、暗号、プロセス関連コードの確認
  3. 03文字列やAPIの参照元の追跡
  4. 04高リスク関数の詳細レビュー準備

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/allthingsida/idasql-skills --skill analysis

インストール後、Claude Code で/analysisを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

agents/
openai.yaml
references/
analysis-cookbook.md
crypto-detection.md
network-detection.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を段階的に分割し、候補のセットを小さくします。

引き継ぎパターン

  1. analysis -> xrefs:シグナルのアドレスを呼び出し元/呼び出し先のグラフにマッピングします。
  2. analysis -> decompiler:リスクが最も高い関数の意味的なロジックを調べます。
  3. 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 — トリアージクエリで特定した疑わしい関数を詳しく調べます。

コメント