xrefs について
xrefs は、IDA のクロスリファレンス、呼び出し関係、構造体メンバーへの参照を調べる SQL スキルです。バイナリ解析向けに便利なビュー、コールグラフ探索、最短経路検索と、効率的な絞り込み方法を提供します。
主な機能
- 01コードとデータのクロスリファレンスを検索
- 02呼び出し元と呼び出し先を確認
- 03コールグラフ探索と最短経路検索
- 04構造体メンバーへの参照を検索
- 05インデックス付き条件で検索を絞り込み
活用シーン
- 01関数を呼び出すコードの特定
- 02関数呼び出し依存関係の追跡
- 03文字列やインポートへの参照の特定
- 04構造体メンバーの読み書き箇所の分析
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ allthingsida/ idasql-skills --skill xrefsインストール後、Claude Code で/xrefsを入力して読み込まれたか確認します。
同梱ファイルagents/openai.yaml
詳細
トリガーインテント
ユーザーから次のように尋ねられた場合に、このスキルを使用します。
- 「これは誰が呼び出しますか?」/「これは何を呼び出しますか?」
- 「この文字列/インポートはどこで参照されていますか?」
- 「呼び出しグラフの依存関係を表示してください。」
次のツールにルーティングします。
- 関係を分析する前に、名前/パターンで候補エンティティを検索するには
grep - より広いトリアージのコンテキストを得るには
analysis - グラフを絞り込んだ後の意味的な解釈には
decompiler - 命令レベルで呼び出し箇所を検証するには
disassembly
最初に行うこと(ウォームスタート手順)
-- 1) Core relation volume
SELECT COUNT(*) AS xref_count FROM xrefs;
-- 2) Top imports (dependency hints)
SELECT module, COUNT(*) AS import_count
FROM imports
GROUP BY module
ORDER BY import_count DESC;
-- 3) Most called functions
SELECT printf('0x%X', to_addr) AS callee, COUNT(*) AS callers
FROM xrefs
WHERE is_code = 1
GROUP BY to_addr
ORDER BY callers DESC
LIMIT 20;
解釈のガイダンス:
- 関係の件数を使って、コストの高い詳細分析を行う前にホットスポットの優先順位を付けます。
- 高速に応答するには、インデックス付きのフィルター(
to_addr/from_addr)を優先します。
失敗と復旧
- 全件スキャンのクエリが遅すぎる場合:
to_addr = Xまたはfrom_addr = Xの制約を追加します。
- 名前でターゲットを解決できない場合:
namesテーブルまたは明示的な EA リテラルを使って、先にアドレスを解決/確認します。
- 結果が少ない場合:
imports、strings、またはdisasm_callsの結合を使って調査対象を切り替えます。
- 構造体/共用体の FIELD への参照を探している場合:
struct_member_xrefs(type_name/type_ordinal/member_idで絞り込み)を使います。 フィールド名でinstructions.disasm/instruction_operands.textをLIKEスキャンしないでください。 このテーブルが置き換えるのは、処理が遅くクラッシュを招きやすいパターンです。
- ターゲットが静的構造体またはディスパッチテーブル内にある場合:
- 最新のバイナリでは、文字列/データのターゲットはコードではなく、登録テーブルや vtable から参照されていることがよくあります。この場合、
xrefs WHERE to_addr = Xでは.rdataの行だけが返されることがあります。 テーブルの先頭までたどり、次にテーブル自体のアドレスを使って xrefs を再検索します。-- 1) ターゲットを含む項目の先頭を検索 SELECT addr FROM heads WHERE addr <= 0x140027D50 ORDER BY addr DESC LIMIT 1; -- 2) テーブルの先頭への xrefs(コード側の参照元) SELECT * FROM xrefs WHERE to_addr = <head> AND is_code = 1;
- 最新のバイナリでは、文字列/データのターゲットはコードではなく、登録テーブルや vtable から参照されていることがよくあります。この場合、
引き継ぎパターン
xrefs->decompilerで有力候補の関数の意味を調べます。xrefs->analysisでキャンペーンレベルの統合分析を行います。xrefs->annotationsで関係の調査結果を保存します。
xrefs
相互参照。コードの関係を理解するための最も重要なテーブルです。
| 列 | 型 | 説明 |
|---|---|---|
from_addr | INT | 参照元アドレス(誰が参照しているか) |
to_addr | INT | 参照先アドレス(何が参照されているか) |
type | INT | xref のタイプコード(以下を参照。通常フローのコードではありません) |
is_code | INT | 1=コード xref(呼び出し/ジャンプ)、0=データ xref |
from_func | INT | 事前計算済みの、参照元を含む関数のアドレス(関数内にない場合は NULL) |
意味:このインターフェースで公開されるのは実際の参照のみです。通常のフォールスルーフローのエッジ(fl_F:各命令が次の命令を「参照」するもの)は、全件スキャンと to_addr/from_addr/from_func の高速パスの両方で除外されます。これは IDA の Ctrl-X ビューおよび他の xsql ツールと一致します。そのため、件数に含まれるのは呼び出し/ジャンプ/データ参照であり、命令の隣接関係ではありません。
-- Who calls function at 0x401000?
SELECT printf('0x%X', from_addr) as caller FROM xrefs WHERE to_addr = 0x401000 AND is_code = 1;
-- What does function at 0x401000 reference?
SELECT printf('0x%X', to_addr) as target FROM xrefs WHERE from_addr >= 0x401000 AND from_addr < 0x401100;
struct_member_xrefs
特定の構造体/共用体メンバーへの相互参照(Issue 11)です。メンバーの IDA tid を解決し、相互参照を直接列挙します。instructions.disasm/instruction_operands.text に対する LIKE スキャンの代わりに使用してください。type_ordinal、type_name、または member_id によるフィルターが必須です(フィルターなしのクエリはエラーになります)。埋め込みメンバーは再帰的に展開され、ドット区切りの member_path が設定されます。
| 列 | 型 | 説明 |
|---|---|---|
type_ordinal / type_name | INT/TEXT | クエリ対象の(最上位)型 |
member_index | INT | 直近の親型におけるリーフのインデックス |
member_name / member_path | TEXT | リーフ名/ドット区切りのパス(payload.leaf.data) |
member_offset / member_offset_bits | INT | クエリ対象の型内での累積オフセット |
member_id | INT | メンバー tid(フィルターキーとしても使用) |
xref_from | INT | 参照元アドレス |
xref_to | INT | メンバー tid(== member_id) |
xref_type | INT | 生の IDA 相互参照型コード |
xref_kind | TEXT | read / write / offset / call / jump / flow |
function_addr / function_name | INT/TEXT | 所属関数(該当なしの場合は NULL) |
operand_index | INT | メンバーを参照するオペランド(可能な範囲で特定。NULL の場合あり) |
instruction_text | TEXT | xref_from にある逆アセンブル行(命令でない場合は NULL) |
access_offset / access_size | INT | アクセスのサブオフセット/幅(可能な範囲で特定。NULL の場合あり) |
-- Who writes _EH3_EXCEPTION_REGISTRATION.TryLevel?
SELECT member_path, xref_kind, function_name, instruction_text
FROM struct_member_xrefs
WHERE type_name = '_EH3_EXCEPTION_REGISTRATION' AND member_name = 'TryLevel';
-- All member references for a type (incl. nested), grouped by member
SELECT member_path, count(*) AS refs FROM struct_member_xrefs
WHERE type_ordinal = (SELECT ordinal FROM types WHERE name = 'db_entry_t')
GROUP BY member_path;
imports
外部ライブラリからインポートされた関数です。
| 列 | 型 | 説明 |
|---|---|---|
addr | INT | インポートアドレス(IAT エントリ) |
name | TEXT | インポート名 |
module | TEXT | モジュール/DLL 名 |
ordinal | INT | インポート序数 |
folder_path | TEXT | 書き込み可能なインポートフォルダーパス |
full_path | TEXT | 完全なインポート dirtree パス |
-- Imports from kernel32.dll
SELECT name FROM imports WHERE module LIKE '%kernel32%';
-- Organize network-related imports
UPDATE imports
SET folder_path = 'idasql/imports/network'
WHERE name LIKE '%socket%' OR name LIKE '%connect%' OR name LIKE '%send%';
便利なビュー
callers
各関数を呼び出す関数です。呼び出し元の名前は、funcs テーブルと names テーブルからビューによって解決されます。
| 列 | 型 | 説明 |
|---|---|---|
func_addr | INT | 対象関数のアドレス |
caller_addr | INT | 相互参照元のアドレス |
caller_name | TEXT | 呼び出し元の関数名 |
caller_func_addr | INT | 呼び出し元関数の開始アドレス(from_func 由来) |
基になるクエリ:
SELECT x.to_addr as func_addr, x.from_addr as caller_addr,
COALESCE((SELECT name FROM names WHERE addr = x.from_func LIMIT 1), printf('sub_%X', x.from_func)) as caller_name,
x.from_func as caller_func_addr
FROM xrefs x WHERE x.is_code = 1 AND x.from_func != 0
-- Who calls function at 0x401000?
SELECT caller_name, printf('0x%X', caller_addr) as from_addr
FROM callers WHERE func_addr = 0x401000;
-- Most called functions
SELECT printf('0x%X', func_addr) as addr, COUNT(*) as callers
FROM callers GROUP BY func_addr ORDER BY callers DESC LIMIT 10;
callees
各関数が呼び出す関数です。callers ビューの逆です。関数単位で効率よくグループ化するため、from_func を使用します。
| 列 | 型 | 説明 |
|---|---|---|
func_addr | INT | 呼び出し元関数のアドレス(from_func 由来) |
func_name | TEXT | 呼び出し元関数の名前 |
callee_addr | INT | 呼び出し先のアドレス |
callee_name | TEXT | 呼び出し先の関数/シンボル名 |
-- What does main call?
SELECT callee_name, printf('0x%X', callee_addr) as addr
FROM callees WHERE func_name LIKE '%main%';
-- Functions making most calls
SELECT func_name, COUNT(*) as call_count
FROM callees GROUP BY func_addr ORDER BY call_count DESC LIMIT 10;
string_refs
文字列の相互参照と所属関数の情報を事前に結合したビューです。
| 列 | 型 | 説明 |
|---|---|---|
string_addr | INT | 文字列のアドレス |
string_value | TEXT | 文字列の内容 |
string_length | INT | 文字列の長さ |
ref_addr | INT | 参照命令のアドレス |
func_addr | INT | 所属関数のアドレス |
func_name | TEXT | 所属関数の名前 |
-- Strings referenced by a specific function
SELECT string_value, func_name FROM string_refs WHERE func_addr = 0x401000;
-- Find functions referencing password-related strings
SELECT string_value, func_name FROM string_refs WHERE string_value LIKE '%password%';
-- Most referenced strings
SELECT string_value, COUNT(*) as ref_count
FROM string_refs GROUP BY string_addr ORDER BY ref_count DESC LIMIT 10;
data_refs
データ(コード以外)の相互参照と所属関数の情報をキャッシュしたテーブルです。 プログラム全体の集計に対応しています。
| 列 | 型 | 説明 |
|---|---|---|
from_addr | INT | 参照元アドレス |
to_addr | INT | 対象データのアドレス |
from_func_addr | INT | 所属関数のアドレス |
from_func_name | TEXT | 所属関数の名前 |
ref_type | INT | 相互参照型コード |
-- Data references from a specific function
SELECT * FROM data_refs WHERE from_func_addr = 0x401000;
-- Functions with most data references
SELECT from_func_name, COUNT(*) as data_ref_count
FROM data_refs GROUP BY from_func_addr ORDER BY data_ref_count DESC LIMIT 10;
call_graph
BFS による呼び出しグラフの探索を行うテーブル値関数です。探索を制御するために HIDDEN パラメーターを使用します。
| 列 | 型 | 説明 |
|---|---|---|
func_addr | INT | グラフ内の関数アドレス |
func_name | TEXT | 関数名 |
depth | INT | 開始点からの BFS の深さ |
parent_addr | INT | 探索における親関数のアドレス |
start | INT | HIDDEN — 開始関数のアドレス |
direction | TEXT | HIDDEN — 'down'(呼び出し先)、'up'(呼び出し元)、または 'both' |
max_depth | INT | HIDDEN — 探索の最大深度 |
3 つすべての非表示パラメーターに対して、必ず WHERE 条件を指定してください。
-- Forward call tree from main
SELECT func_name, depth FROM call_graph
WHERE start = (SELECT addr FROM funcs WHERE name = 'main')
AND direction = 'down' AND max_depth = 5;
-- All transitive callers
SELECT func_name, depth FROM call_graph
WHERE start = 0x405000 AND direction = 'up' AND max_depth = 10;
-- Bidirectional exploration
SELECT func_name, depth FROM call_graph
WHERE start = 0x401000 AND direction = 'both' AND max_depth = 3;
-- Join with string_refs to find strings reachable from a function
SELECT DISTINCT sr.string_value, sr.func_name
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;
-- Imported APIs reachable from a function's call tree
SELECT DISTINCT i.module, i.name as api
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 i.module, i.name;
パフォーマンス:訪問済みセットを使用する BFS です。O(到達可能な関数数)。非表示パラメーターは必ず制約してください。 宛先がインポートである場合は、このパターンを使用してください。
shortest_path
2 つの関数間の最短呼び出しパスを検索するテーブル値関数です。双方向 BFS を使用します。
| 列 | 型 | 説明 |
|---|---|---|
step | INT | パス内のステップ番号(0 = ソース) |
func_addr | INT | このステップの関数アドレス |
func_name | TEXT | このステップの関数名 |
from_addr | INT | HIDDEN — ソース関数のアドレス |
to_addr | INT | HIDDEN — 宛先関数のアドレス |
max_depth | INT | HIDDEN — 検索の最大深度 |
3 つすべての非表示パラメーターに対して、必ず WHERE 条件を指定してください。
両端点は関数として解決できる必要があります。imports のインポート済み API アドレスは、shortest_path の端点として使用できません。
-- Find shortest call path between two functions
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 = 'target_func')
AND max_depth = 20;
-- Check reachability between two functions
SELECT COUNT(*) > 0 as reachable FROM shortest_path
WHERE from_addr = 0x401000 AND to_addr = 0x405000 AND max_depth = 20;
-- Annotate path steps with call count and string refs
SELECT sp.step, sp.func_name,
(SELECT COUNT(*) FROM disasm_calls dc WHERE dc.func_addr = sp.func_addr) as calls_made,
(SELECT COUNT(*) FROM string_refs sr WHERE sr.func_addr = sp.func_addr) as strings_used
FROM shortest_path sp
WHERE sp.from_addr = 0x401000 AND sp.to_addr = 0x405000 AND sp.max_depth = 20
ORDER BY sp.step;
パフォーマンス:双方向 BFS。b は分岐係数、d はパスの長さです。最大深度内にパスが存在しない場合、空の結果セットを返します。
テーブル優先の相互参照クエリ
-- Incoming references to an address
SELECT from_addr, to_addr, type, is_code, from_func
FROM xrefs
WHERE to_addr = 0x401000;
-- Exact outgoing references from an item address
SELECT from_addr, to_addr, type, is_code, from_func
FROM xrefs
WHERE from_addr = 0x401000;
-- Outgoing references from anywhere inside a function
SELECT from_addr, to_addr, type, is_code, from_func
FROM xrefs
WHERE from_func = 0x401000;
grep
関係の分析を行う前に、grep を使用して内部シンボル、型、メンバーを解決してください。呼び出し先がインポート済み API としてのみ存在する可能性がある場合は、imports を使用してください。
標準的な使用方法は ../grep/SKILL.md に記載されています。
標準スキーマと所有者の対応付けについては、../connect/references/schema-catalog.md(grep)を参照してください。
-- Resolve internal functions with grep
SELECT name, kind, addr
FROM grep
WHERE pattern = 'main%' AND kind = 'function'
ORDER BY name;
-- Resolve imported APIs with imports
SELECT module, name, addr
FROM imports
WHERE name LIKE 'CreateFile%'
ORDER BY module, name;
-- Then pivot into callers/callees/xrefs
SELECT caller_name, printf('0x%X', caller_addr) AS from_addr
FROM callers
WHERE func_addr = (
SELECT addr
FROM imports
WHERE name = 'CreateFileW'
ORDER BY name
LIMIT 1
);
パフォーマンス規則
制約のプッシュダウン
xrefs テーブルには、効率的な IDA SDK API を使用する最適化済みフィルターがあります。
| フィルター | コスト | 動作 |
|---|---|---|
to_addr = X | 0.5 | O(X への xref 数)— IDA の xref インデックスを使用するため高速 |
from_addr = X | 0.5 | O(X からの xref 数)— IDA の xref インデックスを使用するため高速 |
from_func = X | 1.0 | O(X の呼び出し先数)— XrefsFromFuncIterator を使用 |
to_addr / from_addr / from_func に等価フィルターがない | — | 関数エントリーポイントへの xref のみを対象とするキャッシュにフォールバックします。インポート/データ/非関数を網羅できないため、これに依存しないでください |
to_addr、from_addr、または from_func で xrefs を必ずフィルタリングしてください。制約のないスキャンは避けてください。
-- FAST: xrefs to a specific target
SELECT * FROM xrefs WHERE to_addr = 0x401000;
-- FAST: xrefs from a specific source
SELECT * FROM xrefs WHERE from_addr = 0x401000;
-- FAST: all xrefs originating from a function
SELECT * FROM xrefs WHERE from_func = 0x401000;
-- INCOMPLETE/avoid: unconstrained scan falls back to a function-entry cache
SELECT * FROM xrefs WHERE is_code = 1;
一般的な Xref パターン
最も多く呼び出される関数を検索する
SELECT f.name, COUNT(*) as caller_count
FROM funcs f
JOIN xrefs x ON f.addr = x.to_addr
WHERE x.is_code = 1
GROUP BY f.addr
ORDER BY caller_count 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%';
インポート依存関係マップ
-- Which modules does each function depend on?
SELECT f.name as func_name, i.module, COUNT(*) as api_count
FROM funcs f
JOIN disasm_calls dc ON dc.func_addr = f.addr
JOIN imports i ON dc.callee_addr = i.addr
GROUP BY f.addr, i.module
ORDER BY f.name, api_count DESC;
データセクションの参照
-- Functions referencing data sections
SELECT
f.name,
s.name as segment,
COUNT(*) as data_refs
FROM funcs f
JOIN xrefs x ON x.from_addr BETWEEN f.addr AND f.end_addr
JOIN segments s ON x.to_addr BETWEEN s.start_addr AND s.end_addr
WHERE s.class = 'DATA' AND x.is_code = 0
GROUP BY f.addr, s.name
ORDER BY data_refs DESC
LIMIT 20;
高度な Xref パターン(CTE と再帰クエリ)
手動の CTE より
call_graphを優先してください。call_graphテーブルは、訪問済みセットを使用する C++ の BFS を利用します。正確な BFS 深度を得られ、ひし形の呼び出しグラフで重複展開が発生せず、早期終了も可能です。
変更前(再帰 CTE — 訪問済みの追跡なし。ひし形グラフでは指数関数的に増加):
WITH RECURSIVE call_chain(root, current_func, depth) AS (
SELECT 0x401000, callee_addr, 1
FROM disasm_calls WHERE func_addr = 0x401000
UNION ALL
SELECT cc.root, dc.callee_addr, cc.depth + 1
FROM call_chain cc
JOIN disasm_calls dc ON dc.func_addr = cc.current_func
WHERE cc.depth < 10
)
SELECT DISTINCT current_func, MIN(depth) FROM call_chain GROUP BY current_func;
変更後(call_graph テーブル — 訪問済みセットを使用する C++ の BFS。深度が正確):
SELECT func_addr, func_name, depth FROM call_graph
WHERE start = 0x401000 AND direction = 'down' AND max_depth = 10;
再帰呼び出しグラフ — 前方探索
注記: 対象を絞った探索では、訪問済みを追跡する C++ の BFS を使用する
call_graphテーブルを優先してください。各ステップで呼び出し先のプロパティによるフィルタリングを行うなど、カスタムの結合ロジックが必要な場合に限り、再帰 CTE を使用してください。
開始関数から到達可能なすべての関数を検索します(深度 5 まで):
-- Preferred: use call_graph table
SELECT func_name, depth FROM call_graph
WHERE start = (SELECT addr FROM funcs WHERE name = 'main')
AND direction = 'down' AND max_depth = 5;
-- Manual CTE (when custom filtering is needed at each step):
WITH RECURSIVE cg AS (
SELECT addr as func_addr, name, 0 as depth
FROM funcs WHERE name = 'main'
UNION ALL
SELECT f.addr, f.name, cg.depth + 1
FROM cg
JOIN disasm_calls dc ON dc.func_addr = cg.func_addr
JOIN funcs f ON f.addr = dc.callee_addr
WHERE cg.depth < 5
AND dc.callee_addr != 0
)
SELECT DISTINCT func_addr, name, MIN(depth) as min_depth
FROM cg
GROUP BY func_addr
ORDER BY min_depth, name;
再帰的なコールグラフ — 逆方向(これを呼び出しているのは?)
注記: 対象を絞ってたどる場合は、
direction = 'up'を指定したcall_graphテーブルを優先してください。カスタムの結合ロジックが必要な場合にのみ、再帰 CTE を使用してください。
呼び出し元を深さ 5 まで遡ってたどります:
-- Preferred: use call_graph table
SELECT func_name, depth FROM call_graph
WHERE start = 0x401000 AND direction = 'up' AND max_depth = 5;
-- Manual CTE (when custom filtering is needed at each step):
WITH RECURSIVE callers_cte AS (
SELECT DISTINCT dc.func_addr, 1 as depth
FROM disasm_calls dc
WHERE dc.callee_addr = 0x401000
UNION ALL
SELECT DISTINCT dc.func_addr, c.depth + 1
FROM callers_cte c
JOIN disasm_calls dc ON dc.callee_addr = c.func_addr
WHERE c.depth < 5
)
SELECT (SELECT name FROM funcs WHERE func_addr >= addr AND func_addr < end_addr LIMIT 1) as caller, MIN(depth) as distance
FROM callers_cte
GROUP BY func_addr
ORDER BY distance, caller;
CTE:malloc を呼び出し、かつ NULL をチェックする関数
WITH malloc_callers AS (
SELECT DISTINCT func_addr
FROM disasm_calls
WHERE callee_name LIKE '%malloc%'
),
null_checkers AS (
SELECT DISTINCT func_addr
FROM ctree_v_comparisons
WHERE rhs_num = 0 AND op_name = 'cot_eq'
)
SELECT f.name
FROM funcs f
JOIN malloc_callers m ON f.addr = m.func_addr
JOIN null_checkers n ON f.addr = n.func_addr;
CTE:解放されていないメモリ割り当て(リークの可能性)
WITH allocators AS (
SELECT func_addr, COUNT(*) as alloc_count
FROM disasm_calls
WHERE callee_name LIKE '%alloc%' OR callee_name LIKE '%malloc%'
GROUP BY func_addr
),
freers AS (
SELECT func_addr, COUNT(*) as free_count
FROM disasm_calls
WHERE callee_name LIKE '%free%'
GROUP BY func_addr
)
SELECT f.name,
COALESCE(a.alloc_count, 0) as allocations,
COALESCE(r.free_count, 0) as frees
FROM funcs f
LEFT JOIN allocators a ON f.addr = a.func_addr
LEFT JOIN freers r ON f.addr = r.func_addr
WHERE a.alloc_count > 0 AND COALESCE(r.free_count, 0) = 0
ORDER BY allocations DESC;
EXISTS:文字列参照が 1 つ以上ある関数
存在チェックでは、JOIN + DISTINCT より効率的です:
SELECT f.name
FROM funcs f
WHERE EXISTS (
SELECT 1 FROM xrefs x
JOIN strings s ON x.to_addr = s.addr
WHERE x.from_addr BETWEEN f.addr AND f.end_addr
);
EXISTS:リーフ関数(呼び出し先がない関数)
SELECT f.name, f.size
FROM funcs f
WHERE NOT EXISTS (
SELECT 1 FROM disasm_calls dc
WHERE dc.func_addr = f.addr
)
ORDER BY f.size DESC;
関連項目
disassembly— 呼び出し箇所のコンテキスト(disasm_at、disasm_calls、オペランドレベルの読み取り)。data—to_addrの背後にある文字列/データの参照先。xrefs が.rdataのみの行を返す場合に使用する標準的なピボットです。decompiler— 呼び出し元コードのロジックと、呼び出し先の型を使った間接呼び出しの解決。