mcpField
D
decompiler

decompiler

github.com/allthingsida開発4970 回インストール3 週間前に更新
リポジトリ

decompiler について

Hex-Raysで関数を分析するスキルです。疑似コード、AST、ローカル変数、パターンビューを扱い、関数単位のクエリや関連スキルへの引き継ぎを案内します。

主な機能

  1. 01逆コンパイル済み疑似コードの確認
  2. 02ASTとローカル変数の検索
  3. 03呼び出し・分岐・ループの検索
  4. 04疑似コードコメントの編集
  5. 05逆アセンブルによる分析の補完

活用シーン

  1. 01関数の動作を理解
  2. 02呼び出しや条件のパターンを特定
  3. 03ローカル変数の意味を調査
  4. 04アセンブリレベルで結果を検証

インストール

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

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

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

同梱ファイル

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

agents/
openai.yaml
references/
ctree-manipulation.md
decompiler-views.md
decompiler-workflows.md

詳細


トリガーとなるインテント

ユーザーが次のことを求めた場合に、このスキルを使用します。

  • 「この関数を逆コンパイルして」
  • 疑似コードの理解、または AST レベルの分析
  • 逆コンパイル結果におけるローカル変数の意味の解釈
  • デコンパイラー中心のパターン抽出(戻り値/呼び出し/条件)

次にルーティングします。

  • 解釈後のコメントや名前の永続化には annotations
  • 構造体/列挙型/型の構築と適用には types
  • デコンパイラーが利用できない、または不十分な場合は disassembly

最初に実行すること(ウォームスタートの手順)

-- 1) Capability/profile probe
SELECT * FROM pragma_table_list WHERE name IN ('pseudocode', 'ctree', 'ctree_lvars');

-- 2) Pick one concrete function target
SELECT name, printf('0x%X', addr) AS addr, size
FROM funcs
ORDER BY size DESC
LIMIT 10;

-- 3) View decompiled text via primary read surface
SELECT decompile(0x401000);

解釈のガイダンス:

  • decompile(addr) は主要な表示サーフェスです。
  • pseudocode/ctree* は構造化されたクエリー/編集用サーフェスです。

グローバル制約に関する注意(重要)

デコンパイラーのテーブルには、必ず関数で制約をかけてください。

WHERE func_addr = 0x...

これを行わないと、デコンパイラーのテーブルがすべての関数を逆コンパイルし、非常に遅くなる場合があります。


失敗時の復旧

  • Hex-Rays がない/デコンパイラーのテーブルを利用できない:
    • disassembly と xrefs のワークフローにフォールバックします。
  • 行が空/不完全:
    • 対象の func_addr が存在することを確認し、逆コンパイルキャッシュを更新します(サポートされている場合は decompile(addr, 1))。
  • 変更が反映されない:
    • 必須の変更ループ(読み取り → 編集 → 更新 → 検証)を実行します。

引き継ぎパターン

  1. decompiler → ローカル型の設定と、より詳細な宣言には types。
  2. decompiler → 永続的な説明や命名には annotations。
  3. decompiler → オペコードレベルでの検証には disassembly。

デコンパイラーのテーブル(Hex-Rays が必要)

重要: 必ず func_addr でフィルターしてください。制約を指定しない場合、これらのテーブルはすべての関数を逆コンパイルするため、非常に遅くなります!

pseudocode

pseudocode テーブルは、書き込み可能なコメントを備えた、行単位の構造化された疑似コードです。疑似コードの表示には decompile(addr) を使用してください。このテーブルは、ピンポイントの編集(コメント)または構造化クエリーにのみ使用してください。

列型書き込み可能説明
func_addrINTいいえ関数アドレス
line_numINTいいえ行番号
lineTEXTいいえ疑似コードテキスト
addrINTいいえ対応するアセンブリアドレス(COLOR_ADDR アンカーから取得)
commentTEXTはいこのアドレスにおけるデコンパイラーコメント
comment_placementTEXTはいコメントの配置:semi(行内、デフォルト)、block1(行の上)

フィルターの動作:

  • WHERE func_addr = X:最高のパフォーマンスです。1つの関数の疑似コードだけを反復処理します。
  • WHERE addr = X:対象 EA を含む関数だけを逆コンパイルし、その EA に一致する行を返します。
  • WHERE line_num = N:関数を走査し、その行インデックスに該当する行を返します。関数間で行を対応付ける必要がある場合にのみ使用してください。

コメントの配置: semi(; の後)、block1(独立した行の上)、block2、curly1、curly2、brace1、brace2、colon、case、else、do、asm、try。認識されない配置文字列は、警告なしで semi に変換されます。

-- VIEWING: Use decompile() function, NOT the pseudocode table
SELECT decompile(0x401000);

-- COMMENTING: Use pseudocode table to add/edit/delete comments
UPDATE pseudocode SET comment_placement = 'semi',
                      comment = 'buffer overflow here'
WHERE func_addr = 0x401000 AND addr = 0x401020;

-- Add block comment (appears on own line above the statement)
UPDATE pseudocode SET comment_placement = 'block1', comment = 'vulnerable call'
WHERE func_addr = 0x401000 AND addr = 0x401020;

-- Delete comments at a resolved unique anchor
UPDATE pseudocode SET comment = NULL
WHERE func_addr = 0x401000 AND addr = 0x401020;

関数コメントそのものは pseudocode に含まれません。

  • 通常の関数コメントには UPDATE funcs SET comment = ... WHERE addr = ... を使用します。
  • 繰り返し表示される関数コメントには UPDATE funcs SET rpt_comment = ... WHERE addr = ... を使用します。
pseudocode_orphan_comments

現在の関数の逆コンパイル結果に紐付かなくなった、永続化済みの Hex-Rays コメントです。古いコメントの確認や削除に使用します。

列型書き込み可能説明
func_addrINTいいえ関数アドレス
func_nameTEXTいいえトリアージ用の現在の関数名
addrINTいいえ保存された孤立コメントの EA
comment_placementTEXTいいえ保存された treeloc_t.itp の配置
orphan_commentTEXT削除のみ保存された孤立コメントのテキスト

ルール:

  • UPDATE ... SET orphan_comment = NULL または '' を指定すると、その孤立コメントが削除されます。
  • 空でない値の書き込みは拒否されます。
pseudocode_v_orphan_comment_groups

グループ化された読み取り専用の孤立コメント用トリアージサーフェスです。孤立コメントを含む関数ごとに1行あります。

列:func_addr、func_name、orphan_count、orphan_comments_json

コメントアンカーの解決(重要)

見出し形式の逆コンパイラ注釈を書く前に、この手順に従ってください。

ルール:

  • addr == func_addr と決めつけないでください。
  • 最初に表示される擬似コードの行は addr = 0 であることが多く、書き込み先として適切ではありません。
  • 1 つの addr が複数の行({、文、})に対応することがあります。ブレース以外の一意なアンカーを優先してください。
  • 関数に対するコメントを付ける場合は、pseudocode ではなく funcs.comment / funcs.rpt_comment を更新してください。
-- Resolve the first attachable non-brace row near function start
SELECT line_num, addr, line
FROM pseudocode
WHERE func_addr = 0x401000
  AND addr != 0
  AND TRIM(line) NOT IN ('{', '}')
  AND addr IN (
    SELECT addr
    FROM pseudocode
    WHERE func_addr = 0x401000 AND addr != 0
    GROUP BY addr
    HAVING COUNT(*) = 1
  )
ORDER BY line_num
LIMIT 1;

-- Write a heading-style summary using the resolved addr
UPDATE pseudocode
SET comment_placement = 'block1',
    comment = 'One-paragraph summary of the function.'
WHERE func_addr = 0x401000
  AND addr = (
    SELECT addr
    FROM pseudocode
    WHERE func_addr = 0x401000
      AND addr != 0
      AND TRIM(line) NOT IN ('{', '}')
      AND addr IN (
        SELECT addr
        FROM pseudocode
        WHERE func_addr = 0x401000 AND addr != 0
        GROUP BY addr
        HAVING COUNT(*) = 1
      )
    ORDER BY line_num
    LIMIT 1
  );
ctree

逆コンパイルされたコードの完全な抽象構文木です。

ColumnTypeDescription
func_addrINT関数アドレス
item_idINT一意なノード ID
is_exprINT1=式、0=文
opINT生の数値オペコード
op_nameTEXTノードの型(cot_call、cit_if など)
addrINTバイナリ内のアドレス
parent_idINT親ノード ID
depthINT木の深さ
x_id, y_id, z_idINT子ノード ID
cond_idINT条件の子ノード ID(if/while/for)
then_idINTthen 分岐の子ノード ID(if)
else_idINTelse 分岐の子ノード ID(if)
body_idINT本体の子ノード ID(ループ)
init_idINT初期化の子ノード ID(for)
step_idINTステップの子ノード ID(for)
var_idxINTローカル変数のインデックス
obj_addrINT対象のアドレス
num_valueINT数値リテラル
str_valueTEXT文字列リテラル
helper_nameTEXTヘルパー関数名(cot_helper)
member_offsetINTメンバーのオフセット(cot_memptr/cot_memref)
var_nameTEXT変数名
var_is_stkINT1=変数はスタック変数
var_is_regINT1=変数はレジスター変数
var_is_argINT1=変数は関数の引数
obj_nameTEXTシンボル名
label_numINTノードがラベルを定義する場合のラベル番号
goto_label_numINTcit_goto ノードの対象ラベル番号
ctree_lvars

逆コンパイルで取得したローカル変数です。

ColumnTypeDescription
func_addrINT関数アドレス
idxINT変数のインデックス
nameTEXT変数名
typeTEXT型文字列
commentTEXT宣言の横に表示されるローカル変数のコメント
sizeINTサイズ(バイト単位)
is_argINT1=関数の引数
is_resultINT1=関数の戻り値を保持
is_stk_varINT1=スタック変数
is_reg_varINT1=レジスター変数
stkoffINTスタックオフセット
mregINTマイクロコードのレジスター番号(レジスター変数)

変更時の指針:

  • 決定的に書き込むには、idx ベースの更新を優先してください。
  • type にはスカラー、ポインター、配列型を指定できます。たとえば、スタック上のワイド文字列や固定バッファには SET type = 'WCHAR[6]' または '_BYTE[392]' を使用します(型はローカル変数のスタックスロットに収まる必要があります)。
  • comment の更新は Hex-Rays のローカル変数コメント(lv.cmt)に反映され、decompile(...) の出力に表示されます。
ctree_labels

逆コンパイラの制御フローラベルです。UPDATE(name)をサポートし、cfunc_t のラベル機能を反映します。

ColumnTypeRWDescription
func_addrINTR関数アドレス
label_numINTRラベル番号(LABEL_<n>)
nameTEXTRW現在のラベル名
item_idINTRこのラベルの基になる ctree 項目 ID
item_addrINTRラベルを持つ ctree 項目のアドレス
is_user_definedINTR1=名前が既定の LABEL_<n> と異なる
ctree_call_args

簡単にクエリできるように、呼び出し引数をフラット化したものです。

ColumnTypeDescription
func_addrINT関数アドレス
call_item_idINT呼び出しノード ID
call_addrINT呼び出しサイト EA
call_obj_nameTEXT呼び出し先オブジェクト名
call_helper_nameTEXT呼び出し先ヘルパー名
arg_idxINT引数インデックス(0 始まり)
arg_item_idINT引数式アイテム ID
arg_opTEXT引数の型
arg_var_idxINT引数が変数の場合のローカル変数インデックス
arg_var_nameTEXT該当する場合の変数名
arg_var_is_stkINT1=引数の変数がスタック変数
arg_var_is_argINT1=引数の変数自体が関数引数
arg_obj_addrINT引数がグローバルオブジェクトの場合のオブジェクトアドレス
arg_obj_nameTEXT引数がグローバルオブジェクトの場合のオブジェクト名
arg_num_valueINT数値
arg_str_valueTEXT文字列

デコンパイラビュー

よくあるパターン向けの事前定義済みビューです(常に func_addr でフィルターしてください)。

ViewPurpose
ctree_v_calls呼び出し先情報を含む関数呼び出し
ctree_v_indirect_calls呼び出しサイトの型付けに使う間接/動的呼び出しサイト
ctree_v_loopsfor/while/do ループ
ctree_v_ifsif 文
ctree_v_comparisonsオペランドを含む比較
ctree_v_signed_ops符号付き比較/算術演算
ctree_v_assignmentsオペランドを含む代入
ctree_v_derefsポインターの間接参照
ctree_v_returns値の詳細を含む return 文
ctree_v_calls_in_loopsループ内の呼び出し(再帰的)
ctree_v_calls_in_ifsif 分岐内の呼び出し(再帰的)
ctree_v_leaf_funcs外部への呼び出しがない関数
ctree_v_call_chains深さ 10 までの呼び出しチェーンのパス

型テーブルとビュー

types、types_members、types_enum_values、types_func_args のスキーマ、型ビュー、型 CRUD の例については、types スキルを参照してください。


SQL 関数 — デコンパイル

decompile() と pseudocode テーブルの使い分け:

  • 擬似コードを読む/表示する -> 常に SELECT decompile(addr) から始めます。行ごとのプレフィックス付きで、関数全体をひとつのテキストブロックとして返します。
  • ローカル変数の宣言ヒント -> 宣言行にはコンパクトなローカル変数インデックスのヒント([lv:N])が含まれるため、名前変更操作では UPDATE ctree_lvars ... WHERE func_addr = ... AND idx = N を安全に対象指定できます。
  • 編集後に最新の出力が必要 -> SELECT decompile(addr, 1) を使って再デコンパイルを強制します。
  • 構造化された行へのアクセス、またはコメントの CRUD が必要 -> pseudocode テーブルをクエリ/更新します。
関数説明
decompile(addr)推奨 -- 行プレフィックス付きの完全な擬似コード
decompile(addr, 1)同じ出力ですが、再デコンパイルを強制します
call_arg_addrs(call_addr)永続化された引数ローダーのアドレスを JSON として読み取ります
set_union_selection(func_addr, addr, path)EA におけるユニオン選択パスを設定/解除します
set_union_selection_item(func_addr, item_id, path)ctree.item_id によってユニオン選択パスを設定/解除します
set_union_selection_addr_arg(func_addr, addr, arg_idx, path[, callee])推奨 呼び出し引数の対象指定ヘルパー
call_arg_item(func_addr, addr, arg_idx[, callee])呼び出し引数の座標を明示的な arg_item_id に解決します
ctree_item_at(func_addr, addr[, op_name[, nth]])一般的な式の座標を明示的な ctree.item_id に解決します
set_union_selection_addr_expr(func_addr, addr, path[, op_name[, nth]])一般的な式の座標を使ってユニオン選択を設定/解除します
get_union_selection(func_addr, addr)EA におけるユニオン選択パスの JSON を読み取ります
get_union_selection_item(func_addr, item_id)ctree.item_id によってユニオン選択パスの JSON を読み取ります
get_union_selection_addr_arg(func_addr, addr, arg_idx[, callee])呼び出し引数の座標を使ってユニオン選択の JSON を読み取ります
get_union_selection_addr_expr(func_addr, addr[, op_name[, nth]])一般的な式の座標を使ってユニオン選択の JSON を読み取ります
set_numform(func_addr, addr, opnum, spec)EA とオペランドインデックスを直接指定して numform を設定/解除します
get_numform(func_addr, addr, opnum)EA とオペランドインデックスを直接指定して numform の JSON を読み取ります
set_numform_item(func_addr, item_id, opnum, spec)明示的な ctree アイテム ID を指定して numform を設定/解除します
get_numform_item(func_addr, item_id, opnum)明示的な ctree アイテム ID を指定して numform の JSON を読み取ります
set_numform_addr_arg(func_addr, addr, arg_idx, opnum, spec[, callee])呼び出し引数の座標を使って numform を設定/解除します
get_numform_addr_arg(func_addr, addr, arg_idx, opnum[, callee])呼び出し引数の座標を使って numform の JSON を読み取ります
set_numform_addr_expr(func_addr, addr, opnum, spec[, op_name[, nth]])一般的な式の座標を使って numform を設定/解除します
get_numform_addr_expr(func_addr, addr, opnum[, op_name[, nth]])一般的な式の座標を使って numform の JSON を読み取ります

対象指定のガイダンス:

  • 繰り返し呼び出される関数や呼び出し箇所の引数には、*_addr_arg ヘルパーを使用します。
  • 呼び出し式以外の式や、代入側での構造体/ユニオンへの格納には、ctree_item_at(..., op_name, nth) と *_addr_expr ヘルパーを使用します。

SQL 関数 — 変更

applied_types、parse_decls()、および names/funcs 経由での名前の書き込みについては、types スキルを参照してください。

関数メタデータの SQL 書き込みには、次の方法を推奨します。

  • UPDATE funcs SET name = '...', prototype = '...', comment = '...', rpt_comment = '...' WHERE addr = ...
  • prototype は applied_types の動作に対応し、デコンパイラーのキャッシュを無効化します。
  • comment/rpt_comment は get_func_cmt()/set_func_cmt() に対応します。

パフォーマンスルール

テーブルアーキテクチャ主な制約備考
pseudocodeキャッシュfunc_addr関数ごとに遅延キャッシュされ、クエリ後に解放されます
pseudocode_orphan_commentsキャッシュfunc_addr孤立行はクエリのスコープ内に限定されます。書き込みは削除のみ可能です
pseudocode_v_orphan_comment_groupsキャッシュfunc_addrグループ化された孤立行のトリアージはクエリのスコープ内に限定されます。まずは広い範囲を LIMIT で絞り込んでください
ctreeジェネレーターfunc_addr遅延ストリーミングで、結果全体をメモリ上に展開せず、LIMIT を尊重します
ctree_lvarsキャッシュfunc_addr関数ごとに遅延キャッシュされ、クエリ後に解放されます
ctree_call_argsジェネレーターfunc_addr遅延ストリーミングで、LIMIT を尊重します

重要なルール:

  • すべてのデコンパイラーテーブルで func_addr 制約が必要です。 指定しないと、すべての関数がデコンパイルされます。
  • ジェネレーターテーブル(ctree、ctree_call_args)は行を遅延ストリーミングし、LIMIT に達すると停止します。
  • デコンパイラービュー(ctree_v_calls、ctree_v_indirect_calls、ctree_v_loops など)は func_addr 制約を引き継ぎます。常にフィルターを指定してください。
  • Hex-Rays cfunc キャッシュ: decompile(addr) は内部でキャッシュされます。decompile(addr, 1) は完全な再デコンパイルを強制します。ミューテーションの効果を確認する必要がある場合にのみ使用してください。

コストモデル:

decompile(addr)          -> ~50-200ms first call, ~0ms cached
decompile(addr, 1)       -> ~50-200ms always (forces re-decompile)
ctree WHERE func_addr=X  -> one decompilation + streaming rows
ctree (no constraint)    -> one decompilation per row in funcs

追加リソース

  • 詳細なワークフロー(機能の確認、ミューテーションループ、呼び出しサイトの型付け、ローカル型のシード設定、フォールバックパターン、完全な実例)については、references/decompiler-workflows.md を参照してください。
  • 詳細なビューのスキーマ(ctree_v_indirect_calls、ctree_v_returns)については、references/decompiler-views.md を参照してください。
  • ctree ノードの種類、操作パターン、高度な CTE については、references/ctree-manipulation.md を参照してください。

関連項目

  • data — デコンパイルされたコードが参照する生バイト列と文字列の内容(バイト単位の読み取りおよび WHERE start_addr = X AND n = N による範囲を限定したウィンドウ読み取り用の bytes テーブル、16 進数出力用の hex(blob_concat(value)))。
  • disassembly — 同じ関数の命令レベルの正解情報(disasm_func、instructions、disasm_calls)。
  • xrefs — デコンパイルされた関数の呼び出し元と呼び出し先。擬似コードからコールグラフへ移動できます。
  • types — 適用されたプロトタイプが ctree の形状を決定します。applied_types / funcs.prototype を使って型を付け直し、キャストや間接呼び出しを整理してください。

コメント