mcpField
R
rev-struct

rev-struct

github.com/p4nda0s開発2.3k1.9k 回インストール25 週間前に更新
リポジトリ

rev-struct について

rev-structは、関数のメモリアクセスと呼び出し関係からデータ構造の配置を推定するリバースエンジニアリング用スキルです。IDA Pro MCPでの照会と、エクスポート済みコードの解析に対応します。

主な機能

  1. 01フィールドのオフセットとアクセス型の収集
  2. 02呼び出し元と呼び出し先の追跡
  3. 03フィールド型と構造体サイズの推定
  4. 04情報を統合した構造体分析

活用シーン

  1. 01対象関数から構造体を復元
  2. 02関数間でのフィールド受け渡しを調査

MCP 対応

IDA Pro MCPが接続されている場合はIDAを直接照会し、未接続の場合はIDA-NO-MCPのエクスポートデータを解析します。

インストール

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

$npx skills add https://github.com/p4nda0s/reverse-skills --skill rev-struct

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

詳細

rev-struct - 構造体の復元

関数とその呼び出しチェーンにおけるメモリアクセスパターンを分析し、データ構造の定義を復元します。

事前確認

利用可能な IDA アクセス方法を確認します:

オプション A — IDA Pro MCP(接続されている場合は推奨): IDA Pro MCP サーバーが接続されているか確認します(アクティブな ida-pro または同等の MCP 接続を探します)。接続されている場合は、MCP ツール経由で IDA に直接問い合わせることができ、エクスポート済みファイルは不要です。MCP を使って分析を進めてください。

オプション B — IDA-NO-MCP のエクスポートデータ: MCP が接続されていない場合は、現在のディレクトリに IDA-NO-MCP のエクスポートデータがあるか確認します:

  1. decompile/ ディレクトリが存在するか確認します
  2. その中に .c ファイルがあるか確認します

MCP とエクスポートデータのどちらも利用できない場合は、ユーザーに次のように問い合わせてください:

No IDA access method detected. Choose one of the following:

Option A — IDA Pro MCP (recommended):
  Connect the IDA Pro MCP server so Claude can query IDA directly.

Option B — IDA-NO-MCP export:
  1. Download plugin: https://github.com/P4nda0s/IDA-NO-MCP
  2. Copy INP.py to IDA plugins directory
  3. Press Ctrl-Shift-E in IDA to export
  4. Open the exported directory with Claude Code

エクスポートディレクトリの構成

./
├── decompile/              # Decompiled C code directory
│   ├── 0x401000.c          # One file per function, named by hex address
│   ├── 0x401234.c
│   └── ...
├── decompile_failed.txt    # Failed decompilation list
├── decompile_skipped.txt   # Skipped functions list
├── strings.txt             # String table (address, length, type, content)
├── imports.txt             # Import table (address:function_name)
├── exports.txt             # Export table (address:function_name)
└── memory/                 # Memory hexdump (1MB chunks)

関数ファイルの形式(decompile/*.c)

各 .c ファイルには、関数のメタデータコメントと逆コンパイルされたコードが含まれています:

/*
 * func-name: sub_401000
 * func-address: 0x401000
 * callers: 0x402000, 0x403000    // List of functions that call this function
 * callees: 0x404000, 0x405000    // List of functions called by this function
 */

int __fastcall sub_401000(int a1, int a2)
{
    // Decompiled code...
}

構造体の復元手順

ステップ 1:対象関数を読む
  1. ユーザーが指定したアドレスに基づき、decompile/<address>.c を読みます
  2. 関数のメタデータを解析し、呼び出し元と呼び出し先の一覧を抽出します
  3. 関数内のポインタ引数を特定します(構造体ポインタの可能性があります)
ステップ 2:メモリアクセスパターンを収集する

対象関数内で次のパターンを探します:

直接オフセットアクセス:

*(a1 + 0x10)           // offset 0x10
*(_DWORD *)(a1 + 8)    // offset 0x8, DWORD type
*(_QWORD *)(a1 + 0x20) // offset 0x20, QWORD type
*(_BYTE *)(a1 + 4)     // offset 0x4, BYTE type

配列アクセス:

*(a1 + 8 * i)          // array, element size 8 bytes
a1[i]                  // array access

ネストした構造体:

*(*a1 + 0x10)          // first field of struct pointed by a1 is a pointer

レコード形式:

offset=0x00, size=8, access=read/write, type=QWORD
offset=0x08, size=4, access=read, type=DWORD
...
ステップ 3:呼び出し元をたどって分析する

各呼び出し元の関数を読み、次の点を分析します:

  1. 引数の受け渡し:呼び出し時に何が渡されていますか?

    sub_401000(v1);        // v1 might be a struct pointer
    sub_401000(&v2);       // v2 is a struct
    sub_401000(malloc(64)); // struct size is ~64 bytes
    
  2. 呼び出し前後の処理:

    v1 = malloc(0x40);     // allocate 0x40 bytes
    *v1 = 0;               // offset 0x00 initialization
    *(v1 + 8) = callback;  // offset 0x08 is a function pointer
    sub_401000(v1);
    
  3. オフセットアクセスをさらに収集します

ステップ 4:呼び出し先をたどって分析する

各呼び出し先の関数を読み、次の点を分析します:

  1. 引数の使用方法:

    // In callee
    int callee(void *a1) {
        return *(a1 + 0x18);  // accesses offset 0x18
    }
    
  2. 他の関数への受け渡し:

    another_func(a1 + 0x20);  // offset 0x20 might be a nested struct
    
ステップ 5:集約して推定する
  1. すべてのオフセット情報を統合し、オフセット順に並べます
  2. 構造体のサイズを計算します:max(offset) + last_field_size
  3. フィールドの型を推定します:
    • 関数ポインタとして呼び出される → 関数ポインタ
    • strlen/printf に渡される → 文字列ポインタ
    • 定数と比較される → 列挙型/フラグ
    • インクリメント/デクリメント操作 → カウンター/インデックス
  4. 一般的なパターンを特定します:
    • オフセット 0 が関数ポインタテーブル → vtable(C++ オブジェクト)
    • next/prev ポインタ → リンクリストノード
    • refcount フィールド → 参照カウント方式のオブジェクト

出力形式

/*
 * Structure Recovery Analysis
 * Source function: <func_address>
 * Analysis scope: <number of callers/callees analyzed>
 * 
 * Functions using this struct:
 *   - 0x401000 (initialization)
 *   - 0x401100 (field access)
 *   - 0x401200 (destruction)
 */

// Estimated size: 0x48 bytes
// Confidence: High / Medium / Low

struct suggested_name {
    /* 0x00 */ void *vtable;           // vtable pointer, called: (*(*this))()
    /* 0x08 */ int refcount;           // reference count, has ++/-- operations
    /* 0x0C */ int flags;              // flags, AND with 0x1, 0x2
    /* 0x10 */ char *name;             // string, passed to strlen/printf
    /* 0x18 */ void *data;             // data pointer
    /* 0x20 */ size_t size;            // size field
    /* 0x28 */ struct node *next;      // linked list next pointer
    /* 0x30 */ struct node *prev;      // linked list prev pointer
    /* 0x38 */ callback_fn handler;    // callback function
    /* 0x40 */ void *user_data;        // user data
};

// Field access examples:
// 0x401000: *(this + 0x08) += 1;     // refcount++
// 0x401100: printf("%s", *(this + 0x10));  // print name

コメント