mcpField
D
data

data

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

data について

IDAデータベース内の文字列、バイトパターンなどの生データをSQLで調べる分析スキルです。データの一致箇所をコード参照と結び付け、追加分析やデバッグへ引き継ぐ作業を支援します。

主な機能

  1. 01キャッシュ済みバイナリ文字列の検索
  2. 02バイト列とオペコードパターンの検出
  3. 03文字列参照と関数の結合
  4. 04範囲を指定したバイト読み取り
  5. 05分析引き継ぎのガイダンス

活用シーン

  1. 01バイナリ内の指標や定数の調査
  2. 02特定文字列を参照する関数の特定
  3. 03オペコードパターンの効率的な検索
  4. 04データ分析結果のトリアージやデバッグへの引き継ぎ

インストール

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

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

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

同梱ファイルagents/openai.yaml

詳細


トリガーとなる意図

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

  • 文字列/バイト列/パターンをすばやく検索する
  • 文字列の根拠をコードの使用箇所に対応付ける
  • 生データレベルの指標(IOC、定数、シグネチャ)を調査する

次のスキルに引き継ぎます。

  • 一致したアドレスから関連情報を展開する場合は xrefs
  • データシグナルからトリアージを統合する場合は analysis
  • 調査結果に基づいてパッチやブレークポイントの操作を行う場合は debugger

最初に行うこと(ウォームスタート手順)

-- 1) Validate string availability
SELECT COUNT(*) AS strings FROM strings;

-- 2) Sample high-value strings
SELECT content, printf('0x%X', addr) AS addr
FROM strings
WHERE length >= 8
ORDER BY length DESC
LIMIT 40;

-- 3) If expected strings are missing, rebuild once
SELECT rebuild_strings();

解釈のガイダンス:

  • 文字列は動作を知る手がかりとして最もすばやく得られることが多いため、実行コンテキストを調べるにはすぐに xrefs に切り替えます。
  • オペコード/パターンを探す場合は、命令をすべてスキャンするより byte_search テーブルを優先します。

失敗と復旧

  • 文字列が見つからない、または件数が予想外に少ない場合:
    • rebuild_strings() を実行し、COUNT(*) FROM strings で件数を確認します。
  • 誤検出が多すぎる場合:
    • 条件をより具体的にします(LIKE、正規表現に似たパターンの絞り込み、モジュール/関数の結合フィルター)。
  • バイトパターン検索の範囲が広すぎる場合:
    • 範囲を限定するか、一致したバイトアドレスを funcs に結合します。
  • 文字列の内容ではなく、名前付き関数、ラベル、構造体、メンバーが必要な場合:
    • strings や byte_search ではなく、grep を使用します。

引き継ぎパターン

  1. data -> xrefs で、データのヒットをコードパス/関数に変換します。
  2. data -> analysis で、リスクスコアリングとキャンペーンレベルの分析情報を得ます。
  3. data -> debugger で、実用的なパッチ/ウォッチポイントの設定を行います。

strings

バイナリ内で見つかった文字列リテラルです。IDA は設定可能な文字列リストをキャッシュとして保持します。

列型説明
addrINT文字列アドレス
lengthINT文字列の長さ
typeINT文字列の型(生のエンコーディングビット)
type_nameTEXT型名:ascii、utf16、utf32
widthINT文字幅(0=1バイト、1=2バイト、2=4バイト)
width_nameTEXT文字幅の名前:1-byte、2-byte、4-byte
layoutINT文字列のレイアウト(0=null 終端、1-3=Pascal 形式)
layout_nameTEXTレイアウト名:termchr、pascal1、pascal2、pascal4
encodingINTエンコーディングインデックス(0=デフォルト)
contentTEXT文字列の内容(実際のテキスト。value や text ではありません)

文字列型のエンコーディング: IDA は文字列型を32ビット値として保存します。

  • ビット0-1:幅(0=1B/ASCII、1=2B/UTF-16、2=4B/UTF-32)
  • ビット2-7:レイアウト(0=TERMCHR、1=PASCAL1、2=PASCAL2、3=PASCAL4)
  • ビット8-15:term1(最初の終端文字)
  • ビット16-23:term2(2番目の終端文字)
  • ビット24-31:エンコーディングインデックス
-- Find error messages
SELECT content, printf('0x%X', addr) as addr FROM strings WHERE content LIKE '%error%';

-- ASCII strings only
SELECT * FROM strings WHERE type_name = 'ascii';

-- UTF-16 strings (common in Windows)
SELECT * FROM strings WHERE type_name = 'utf16';

-- Count strings by type
SELECT type_name, layout_name, COUNT(*) as count
FROM strings GROUP BY type_name, layout_name ORDER BY count DESC;

重要: 新しい解析(exe/dll)では、文字列が自動的に構築されます。既存のデータベース(i64/idb)では、文字列はすでに保存されています。文字列が予想外に0件の場合は、SELECT rebuild_strings() を一度実行してリストを再構築します。詳しくは、以下の「文字列リストのサーフェス」セクションを参照してください。


文字列参照(明示的な結合パターン)

strings + xrefs + funcs を直接使用します。これが標準的なパターンです。

-- Find call sites/functions referencing error-like strings
SELECT
    s.content as string_value,
    printf('0x%X', x.from_addr) as ref_addr,
    (SELECT name FROM funcs WHERE x.from_addr >= addr AND x.from_addr < end_addr LIMIT 1) as func_name
FROM strings s
JOIN xrefs x ON x.to_addr = s.addr
WHERE s.content LIKE '%error%' OR s.content LIKE '%fail%'
ORDER BY func_name, ref_addr;

-- Functions with most string references
SELECT
    (SELECT name FROM funcs WHERE x.from_addr >= addr AND x.from_addr < end_addr LIMIT 1) as func_name,
    COUNT(*) as string_refs
FROM strings s
JOIN xrefs x ON x.to_addr = s.addr
GROUP BY func_name
ORDER BY string_refs DESC
LIMIT 10;

bytes Table — Reads, Patches, and Bounded Windows

すべてのバイトアクセスは bytes テーブル経由で行います。 非表示の start_addr と n 入力列は、範囲を限定した読み取りに使用します。一括で16進数を取得する場合は hex(blob_concat(value)、一括で BLOB を取得する場合は blob_concat(value) を使います。

形式SQL
1 バイトを読み取るSELECT value FROM bytes WHERE addr = 0x401000
N バイトを16進数で読み取る(大文字、スペースなし)SELECT hex(blob_concat(value)) FROM (SELECT value FROM bytes WHERE start_addr = 0x401000 AND n = 16 ORDER BY addr)
N バイトを BLOB で読み取るSELECT blob_concat(value) FROM (SELECT value FROM bytes WHERE start_addr = 0x401000 AND n = 16 ORDER BY addr)
範囲を読み取るSELECT value FROM bytes WHERE addr >= 0x401000 AND addr < 0x401010 ORDER BY addr

非表示の start_addr と n 列では、X から始まる連続した N バイトを正確に要求します。 これらは表示される addr 列とは意図的に分けられているため、 addr に対する述語(結合、複合 WHERE)は SQLite によって適用可能な状態に保たれます。 範囲を限定した読み取りでは、マップされていないアドレスはスキップされません。マップされた領域を超える行では、 その位置で get_byte() が返す値が報告されます。

blob_concat(value) は行の値を1つの BLOB に連結する組み込み集約関数です。hex() は SQLite に組み込まれた、BLOB を16進数に変換する関数です(大文字)。

範囲の上限を指定しない場合の注意点

上限や LIMIT を指定せずに WHERE addr > X を実行すると、X からイメージの末尾まで、マップされたすべてのバイトを走査します。行数は数百万に達し、処理に数秒かかります。必ず次のいずれかを指定して読み取り範囲を制限してください。

  • WHERE start_addr = X AND n = N(範囲を限定した読み取り形式)
  • AND addr < B(上下限を指定した範囲)
  • 外側の LIMIT N

このテーブルには呼び出しごとの上限がありません。制約の組み合わせで範囲を限定すれば、任意に大きなウィンドウを扱えます。

IDA のアイテムサイズ/型のメタデータが必要な場合は heads を使用してください。


Binary Search Table

生のバイト列やオペコードを検索するには byte_search を使用します。WHERE pattern = ... が必須です。matched_hex は出力列であり、検索入力ではありません。

列型説明
addrINT一致したアドレス
matched_hexTEXT一致したバイト列を16進数のテキストで表示したもの
matched_bytesBLOB生のバイト列としての一致データ
sizeINTバイト単位の一致サイズ
patternHIDDEN TEXT必須の IDA バイトパターン入力
start_addrHIDDEN INT任意の包含下限
end_addrHIDDEN INT任意の排他的上限
max_resultsHIDDEN INT任意の生成件数上限

パターン構文(IDA ネイティブ):

  • "48 8B 05" - 完全一致のバイト列(16進数、スペース区切り)
  • "48 ? 05" または "48 ?? 05" - ? = 任意の1バイトに一致するワイルドカード(バイト全体のみ)
  • "(01 02 03)" - 選択肢(一致対象のバイトのいずれかに一致)

注: バイトパターンではニブル単位のワイルドカードと正規表現はサポートされていません。

例:

-- Find all matches for a pattern
SELECT addr, matched_hex, size
FROM byte_search
WHERE pattern = '48 8B ? 00'
LIMIT 10;

-- First match only
SELECT printf('0x%llX', addr) AS addr
FROM byte_search
WHERE pattern = 'CC CC CC'
ORDER BY addr
LIMIT 1;

-- Search with alternatives
SELECT addr, matched_hex
FROM byte_search
WHERE pattern = 'E8 (01 02 03 04)'
LIMIT 20;

最適化パターン:特定の命令を使用する関数を検索する

「RDTSC 命令を使用する関数はいくつあるか?」に効率よく回答するには:

-- Count unique functions containing RDTSC (opcode: 0F 31)
SELECT COUNT(DISTINCT f.addr) as count
FROM byte_search b
JOIN funcs f ON b.addr >= f.addr AND b.addr < f.end_addr
WHERE b.pattern = '0F 31';

-- List those functions with names
SELECT DISTINCT
    f.addr as func_addr,
    f.name as func_name
FROM byte_search b
JOIN funcs f ON b.addr >= f.addr AND b.addr < f.end_addr
WHERE b.pattern = '0F 31';

これは、すべての逆アセンブリ行を走査するよりもはるかに高速です。理由は次のとおりです。

  • byte_search は IDA ネイティブのバイナリ検索を使用します。
  • 包含結合では、すべての命令を走査する代わりに、コンパクトな funcs テーブルを使用します。

適切な検索方法を選ぶ

  • 関数、ラベル、構造体、列挙型、メンバーなどの名前付きエンティティには grep を使用します。
  • バイナリ内の文字列リテラルを検索する場合は strings を使用します。
  • 検索対象が生のバイト列またはオペコードのパターンの場合は byte_search を使用します。

SQL サーフェス — 文字列リスト

IDA は文字列のキャッシュ済みリストを管理します。rebuild_strings() を使って文字列を検出してキャッシュし、現在の件数には COUNT(*) FROM strings を、行単位の分析には strings を使用します。

サーフェス説明
rebuild_strings()ASCII + UTF-16、最小長 5(デフォルト)で再構築します
rebuild_strings(minlen)最小長を指定して再構築します
rebuild_strings(minlen, types)長さとタイプマスクを指定して再構築します
SELECT COUNT(*) FROM strings現在の文字列リストの件数(行をマテリアライズせずに最適化して取得)

タイプマスクの値:

  • 1 = ASCII のみ(STRTYPE_C)
  • 2 = UTF-16 のみ(STRTYPE_C_16)
  • 4 = UTF-32 のみ(STRTYPE_C_32)
  • 3 = ASCII + UTF-16(デフォルト)
  • 7 = すべてのタイプ
-- Check current string count
SELECT COUNT(*) AS strings FROM strings;

-- Rebuild with defaults (ASCII + UTF-16, minlen 5)
SELECT rebuild_strings();

-- Rebuild with shorter minimum length
SELECT rebuild_strings(4);

-- Rebuild with specific types
SELECT rebuild_strings(5, 1);   -- ASCII only
SELECT rebuild_strings(5, 7);   -- All types (ASCII + UTF-16 + UTF-32)

-- Typical workflow: rebuild then query
SELECT rebuild_strings();
SELECT * FROM strings WHERE content LIKE '%error%';

重要 — 文字列クエリでのエージェントの動作: ユーザーが文字列について質問した場合(例:「文字列を表示して」「このバイナリにはどんな文字列がある?」):

  1. まず SELECT rebuild_strings() を実行して、文字列が検出されていることを確認します
  2. 次に strings テーブルにクエリします

rebuild_strings() 関数は、適切なデフォルト値(ASCII + UTF-16、最小長 5)を使用して IDA の文字列検出を設定し、文字列リストを再構築します。これにより、データベースに事前の文字列分析結果がない場合でも、ユーザーが結果を取得できます。


パフォーマンスに関するルール

テーブル/関数アーキテクチャ備考
COUNT(*) FROM stringsキャッシュ済みテーブル件数のパス現在の文字列リスト件数を O(1) で取得
stringsクエリ単位スキャンごとに IDA のライブ文字列リストからマテリアライズします(永続化された vtable キャッシュはありません)。IDA の strlist がすでに構築されているため高速です。rebuild_strings() は IDA の基盤となる文字列リストを再生成します
byte_searchネイティブのバイナリ検索テーブルinstructions テーブルを反復処理するよりもはるかに高速です
bytes WHERE addr = XポイントルックアップO(1)。仮想テーブルのインデックスを使用します
bytes WHERE start_addr = X AND n = N非表示の start_addr と n を使った範囲指定の読み取りO(N)。仮想テーブルのインデックスを使用します
bytes WHERE addr >= A AND addr < B範囲スキャンO(範囲)。仮想テーブルのインデックスを使用します
bytes WHERE addr > X(上限なし)範囲スキャン避けてください — イメージの末尾まで、マッピングされたすべてのバイトを走査します。範囲を指定した形式を使用してください

主なルール:

  • 新しいデータベースで最初の文字列クエリを実行する前、または新しい文字列が作成される可能性のあるコード/データの変更後には、必ず rebuild_strings() を呼び出してください。
  • byte_search は IDA のネイティブなバイナリ検索エンジンを使用します。「オペコード X を含む関数を検索する」場合は、instructions テーブルをスキャンするのではなく、該当結果を包含関係に基づいて funcs に結合してください。
  • strings テーブルは、キャッシュ済み文字列リストのスナップショットです。最初のクエリ後に IDA の分析で新しい文字列が作成された場合は、もう一度 rebuild_strings() を呼び出してください。
  • 文字列を関数と相互参照する場合は、strings + xrefs + funcs の JOIN パターンが標準です。IDA の xref インデックスにより、JOIN は高速に実行されます。

高度なデータパターン(CTE)

セキュリティ関連文字列のトリアージ

脅威を迅速に評価するため、文字列をセキュリティ上の関連性に基づいて分類します。

-- Categorize strings by security relevance
SELECT rebuild_strings();

WITH categorized AS (
    SELECT addr, content,
        CASE
            WHEN content LIKE '%password%' OR content LIKE '%passwd%' OR content LIKE '%secret%'
                THEN 'credential'
            WHEN content LIKE '%http://%' OR content LIKE '%https://%' OR content LIKE '%ftp://%'
                THEN 'url'
            WHEN content LIKE '%error%' OR content LIKE '%fail%' OR content LIKE '%exception%'
                THEN 'error'
            WHEN content LIKE '%debug%' OR content LIKE '%trace%' OR content LIKE '%assert%'
                THEN 'debug'
            WHEN content LIKE '%.exe%' OR content LIKE '%.dll%' OR content LIKE '%.sys%'
                THEN 'file_path'
            WHEN content LIKE '%HKEY_%' OR content LIKE '%SOFTWARE\\%'
                THEN 'registry'
            ELSE 'other'
        END AS category
    FROM strings
    WHERE length >= 5
)
SELECT category, COUNT(*) AS count,
       GROUP_CONCAT(SUBSTR(content, 1, 60), ' | ') AS samples
FROM categorized
WHERE category != 'other'
GROUP BY category
ORDER BY count DESC;
文字列参照と関数サイズを組み合わせて疑わしさをスコアリングする

セキュリティ関連文字列を参照し、かつサイズが大きい関数は、優先度の高い調査対象です。

-- Suspicious functions: reference interesting strings AND are non-trivial
WITH interesting_strings AS (
    SELECT addr, content FROM strings
    WHERE content LIKE '%password%' OR content LIKE '%encrypt%'
       OR content LIKE '%decrypt%' OR content LIKE '%http%'
       OR content LIKE '%socket%' OR content LIKE '%connect%'
),
string_funcs AS (
    SELECT DISTINCT (SELECT addr FROM funcs WHERE x.from_addr >= addr AND x.from_addr < end_addr LIMIT 1) AS func_addr,
           s.content AS matched_string
    FROM interesting_strings s
    JOIN xrefs x ON x.to_addr = s.addr
    WHERE (SELECT addr FROM funcs WHERE x.from_addr >= addr AND x.from_addr < end_addr LIMIT 1) IS NOT NULL
)
SELECT (SELECT name FROM funcs WHERE sf.func_addr >= addr AND sf.func_addr < end_addr LIMIT 1) AS func_name,
       printf('0x%X', sf.func_addr) AS addr,
       f.size AS func_size,
       GROUP_CONCAT(sf.matched_string, ' | ') AS strings_referenced
FROM string_funcs sf
JOIN funcs f ON f.addr = sf.func_addr
GROUP BY sf.func_addr
ORDER BY f.size DESC
LIMIT 20;
暗号関連とネットワーク関連の両方の文字列を参照する関数を検索する

カテゴリをまたいで相関させ、データ流出や C2 通信を特定します。

-- Functions touching both crypto and network strings
WITH crypto_refs AS (
    SELECT DISTINCT (SELECT addr FROM funcs WHERE x.from_addr >= addr AND x.from_addr < end_addr LIMIT 1) AS func_addr
    FROM strings s JOIN xrefs x ON x.to_addr = s.addr
    WHERE s.content LIKE '%crypt%' OR s.content LIKE '%aes%'
       OR s.content LIKE '%cipher%' OR s.content LIKE '%hash%'
),
network_refs AS (
    SELECT DISTINCT (SELECT addr FROM funcs WHERE x.from_addr >= addr AND x.from_addr < end_addr LIMIT 1) AS func_addr
    FROM strings s JOIN xrefs x ON x.to_addr = s.addr
    WHERE s.content LIKE '%socket%' OR s.content LIKE '%connect%'
       OR s.content LIKE '%send%' OR s.content LIKE '%recv%'
       OR s.content LIKE '%http%'
)
SELECT (SELECT name FROM funcs WHERE c.func_addr >= addr AND c.func_addr < end_addr LIMIT 1) AS func_name,
       printf('0x%X', c.func_addr) AS addr
FROM crypto_refs c
JOIN network_refs n ON n.func_addr = c.func_addr;

関連項目

  • disassembly — 文字列/バイト列がコード内のどこで参照されているか(オペランドを対象にした読み取り)。
  • xrefs — 対象アドレスへのデータ参照。データのヒットから、それを使用する対象へたどるための標準的な方法です。
  • debugger — バイトのパッチ適用には bytes テーブルを使用します。このスキルは読み取りの形式を扱います。
  • analysis — トリアージの手掛かりとしての文字列/インポート。

コメント