idapython について
idapython は、SQL 経由で IDA 内の Python コードやファイルを実行する方法を説明するスキルです。IDA SDK の利用、複雑な分析、UI 操作、自作スクリプトの再利用に向けて、出力制限や分離可能な名前空間も扱います。
主な機能
- 01SQL 経由で Python コードやファイルを実行
- 02sandbox ごとに名前空間を分離・保持
- 03任意の出力バイト上限を設定
- 04Python の例外を SQL エラーとして返却
活用シーン
- 01idasql にない IDA SDK API の呼び出し
- 02複雑なアルゴリズムや独自パターン照合
- 03IDA の UI 操作の自動化
- 04既存の Python スクリプトの再利用
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ allthingsida/ idasql-skills --skill idapythonインストール後、Claude Code で/idapythonを入力して読み込まれたか確認します。
同梱ファイルagents/openai.yaml
詳細
Python 実行 SQL 関数
| 関数 | 説明 |
|---|---|
idapython_snippet(code[, sandbox]) | Python スニペットを実行し、キャプチャした出力テキストを返します |
idapython_file(path[, sandbox]) | Python ファイルを実行し、キャプチャした出力テキストを返します |
ランタイムガード
Python の実行はデフォルトで無効です。次の設定で有効にします。
PRAGMA idasql.enable_idapython = 1;
キャプチャした print の出力は、デフォルトで無制限です。実行が止まらない、または出力が非常に多いスニペットがメモリやレスポンスを使い果たさないようにするには、オプションのバイト数上限を設定します。0 にすると無制限に戻ります。
PRAGMA idasql.idapython_output_max = 65536; -- cap captured output at 64 KiB
PRAGMA idasql.idapython_output_max = 0; -- unbounded (default)
enable_idapython と idapython_output_max(およびその他のランタイム制御)の現在値を確認するには、SELECT * FROM runtime_settings WHERE scope = 'idasql' を実行します。これは、PRAGMA idasql.* のインターフェースを参照する読み取り専用のビューです。connect スキルを参照してください。
例
SELECT idapython_snippet('print("hello from idapython")');
SELECT idapython_file('C:/temp/script.py');
SELECT idapython_snippet('counter = globals().get("counter", 0) + 1; print(counter)', 'alpha');
注意事項
- pragma が有効になるまで、デフォルトで無効です
- Python の例外は SQL エラーとして伝播します
sandboxは、サンドボックスキーごとに Python のグローバル変数を分離、永続化します
2 つの Python コンテキスト(重要)
- ホスト側 Python クライアント(IDA の外部):
requests.post(.../query, data=sql)を使って、HTTP 経由で SQL を送信します。本文には 1 つのステートメント、またはセミコロン区切りのスクリプトを指定できます。すべてのレスポンスで標準のresults[]エンベロープが使われます(単一ステートメントの場合も配列になり、results[i].rowsを読み取ります)。ループ、一括更新、自動化のオーケストレーションに使用します。HTTP クライアントのパターンについては、connectスキルを参照してください。 - SQL 経由の IDAPython(IDA 内部):プロセス内で IDA SDK API に直接アクセスする必要がある場合は、
idapython_snippet()/idapython_file()を使用します。
対照例:
# Host-side Python (outside IDA): sends SQL over HTTP
import requests
requests.post("http://127.0.0.1:8080/query", data="SELECT COUNT(*) FROM funcs")
-- IDAPython (inside IDA): executes Python in IDA runtime
SELECT idapython_snippet('import idaapi; print(idaapi.get_kernel_version())');
サンドボックスの動作
サンドボックスキーごとに、分離された Python 名前空間が作成されます。
- あるサンドボックスで設定した変数は、別のサンドボックスからは参照できません
- 同じサンドボックスキーを使うと、呼び出し間で名前空間が再利用されます(状態はセッション内で保持されます)
- サンドボックスキーを指定しない場合、コードはデフォルトのグローバル名前空間で実行されます
エラーの伝播
Python スクリプトで例外が発生すると、SQL エラーとして伝播します。
-- This will return an error: "NameError: name 'undefined_var' is not defined"
SELECT idapython_snippet('print(undefined_var)');
IDAPython と SQL の使い分け
| 用途 | 最適なツール | 理由 |
|---|---|---|
| データのクエリ/フィルタリング/集計 | SQL | JOIN、CTE、GROUP BY、ウィンドウ関数など、この用途に特化しています |
| テーブルをまたいだ分析 | SQL | funcs、xrefs、strings、ctree の JOIN は SQL で自然に行えます |
| レポート作成とカウント | SQL | COUNT、SUM、AVG、GROUP_CONCAT を使えば、Python のループは不要です |
| 複雑なアルゴリズム | IDAPython | グラフアルゴリズム、カスタムパターンマッチング、ML パイプライン |
| idasql で公開されていない IDA SDK API | IDAPython | 一部の IDA SDK 機能は、SQL テーブル/関数として公開されていません |
| UI の自動化 | IDAPython | ビューを開く、カーソルを移動する、IDA のアクションを実行する |
| 既存のスクリプト | IDAPython | 既存の .py スクリプトを SQL に書き直さずに再利用できます |
一般的なルール: まず SQL を使います。ネストしたループや再帰アルゴリズム、または idasql で公開されていない IDA API が必要だと感じたら、橋渡しとして idapython_snippet() を使用します。
実用例
カスタム分析スクリプトを実行する
-- Enable Python execution first
PRAGMA idasql.enable_idapython = 1;
-- Run a script that collects custom metrics
SELECT idapython_snippet('
import idautils, idc
count = 0
for func_addr in idautils.Functions():
if idc.get_func_attr(func_addr, idc.FUNCATTR_FLAGS) & 0x4: # FUNC_LIB
count += 1
print(f"Library functions: {count}")
');
idasql 経由で公開されていない IDA SDK API にアクセスする
-- Example: get processor-specific register names
SELECT idapython_snippet('
import ida_idp
for i in range(ida_idp.ph_get_regnames().__len__()):
name = ida_idp.ph_get_regnames()[i]
if name:
print(f"{i}: {name}")
');
ブリッジパターン:Python で JSON を生成し、SQL で処理する
抽出には Python の機能を、分析には SQL の機能を使う場合:
-- Python extracts data as JSON
SELECT idapython_snippet('
import json, idautils, idc
result = []
for addr in idautils.Functions():
flags = idc.get_func_attr(addr, idc.FUNCATTR_FLAGS)
if flags & 0x4: # FUNC_LIB
result.append({"addr": addr, "name": idc.get_func_name(addr)})
print(json.dumps(result))
');
-- Then process the JSON output in SQL using json_each()
-- (copy the output from above into the query)
関連項目
- まず該当する SQL スキル(
disassembly、decompiler、types、data、xrefs、annotations、debugger)を確認してください。タスクに使える SQL のインターフェースがない場合に限り、IDAPython を使用します。 functions— SQL 関数カタログです。スクリプトを書く前に、スカラー関数やヘルパー関数がすでに存在しないか確認してください。