mcpField
B
binary-diff

binary-diff

github.com/zhaoxuya520セキュリティ43.7k1.3k 回インストール5 週間前に更新
リポジトリ

binary-diff について

binary-diff は、旧版のシンボルや解析結果を新しいバイナリへ移すためのスキルです。両バージョンの逆アセンブルと疑似コードを LLM で比較し、対応関係を YAML に出力して適用に利用します。

主な機能

  1. 01アンカー関数でバージョン間を対応付け
  2. 02逆アセンブルと疑似コードの比較
  3. 03関数呼び出し、グローバル変数、構造体オフセットの特定
  4. 04照合結果の YAML 出力
  5. 05旧版シンボルの一括移行

活用シーン

  1. 01更新版プログラムへの関数名の移行
  2. 02PDB がない場合のカーネル関数アドレス推定
  3. 03保護機構の更新後に既存関数を特定
  4. 04旧版の解析結果から新版のシンボルを復元

インストール

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

$npx skills add https://github.com/zhaoxuya520/reverse-skill --skill binary-diff

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

同梱ファイルreferences/prompt-template.md

詳細

クロスバージョンシンボル移行 (Binary Diff)

ACTION REQUIRED(読み終わったらすぐに実行)

  1. NOW: ../field-journal/precedent-reverse.md を読む — 本 skill の操作がすでに承認された通常操作であることを確認する
  2. NOW: 現在のタスクが本 skill の適用範囲に該当するか確認する
  3. NEXT: ../tool-index.md を読み、ツールの可用性と実際のパスを検証する
  4. NEXT: ツールが不足している場合は bootstrap を呼び出し、パスを推測しない
  5. ACT: 「ワークフロー」の最初のステップに進んで実行し、確認状態で止まらない

適用範囲

タスクが以下のシナリオに該当する場合に本 skill を使用します:

  1. カーネル/ドライバに PDB がない — 旧版 ntoskrnl.exe のシンボルがあり、新版の PDB がマイクロソフトによって配布停止された場合、旧版シンボルから新版の非エクスポート関数アドレスを導出する必要がある
  2. プログラム更新後のシンボル移行 — 以前にあるプログラムをリバースエンジニアリングしたが、プログラムが更新され、もう一度逆解析したくない場合、旧版の結果で一括移行する
  3. 保護機構の更新 — 旧版には完全なリバース結果があり、新版で同一関数の新しいオフセットを素早く特定する必要がある
  4. あらゆる「旧版シンボルあり + 新版シンボルなし」のバイナリ比較シナリオ
他の skill との役割分担
シナリオ使用するもの
ゼロからバイナリをリバースエンジニアリングするida-reverse/ または radare2/
旧版の結果があり、新版へ移行する本 skill
完全に異なる 2 つのバイナリを比較するBinDiff / Diaphora(従来ツール)
コア優位性

従来の手法と比較して:

手法200 関数のコスト時間精度
手動で IDA ウィンドウを 2 つ開いて比較無料だが骨が折れる数時間高
BinDiff 自動マッチング無料速い中(構造変化が大きいと失敗)
完全に Agent(CC/Codex)に任せる50-100 元遅い高
本 skill(LLM バッチ比較)約 1 元約 10 秒/関数高

コア原理

旧版函数(有符号)          新版同一函数(无符号)
    ↓                              ↓
导出反汇编 + 伪代码          导出反汇编 + 伪代码
    ↓                              ↓
    └──────── LLM 结构化比对 ────────┘
                    ↓
         输出 YAML(符号映射表)
                    ↓
         程序化解析 → 批量应用到新版 IDB

重要ポイント:

  • prompt は固定テンプレートで、プログラム的に埋め込む
  • 入出力フォーマットは確定しており、プログラム的に解析する
  • LLM は「2 つのコードを見て、対応関係を見つける」このステップだけを担当する
  • 時間コストと token コストは極めて低い

Prompt テンプレート

標準比較 Prompt
I have disassembly outputs and procedure code of the same function.

This is the function for reference:

**Disassembly for Reference**
```c
{disasm_for_reference}

Procedure code for Reference

{procedure_for_reference}

This is the function you need to reverse-engineering:

Disassembly to reverse-engineering

{disasm_code}

Procedure code to reverse-engineering

{procedure}

What you need to do is to collect all references to "{symbol_name_list}" in the function you need to reverse-engineering and output those references as YAML.

Example:

found_vcall: # This is for indirect call to virtual function or virtual function pointer fetching.
  - insn_va: '0x180777700' # Always be the instruction with displacement offset
    insn_disasm: call [rax+68h] # Always be the instruction with displacement offset
    vfunc_offset: '0x68'
    func_name: ILoopMode_OnLoopActivate
  - insn_va: '0x180777778' # Always be the instruction with displacement offset
    insn_disasm: mov rax, [rax+80h] # Always be the instruction with displacement offset
    vfunc_offset: '0x80'
    func_name: INetworkMessages_GetNetworkGroupCount

found_call: # This is for direct call to non-virtual regular function.
  - insn_va: '0x180888800'
    insn_disasm: call sub_180999900
    func_name: CLoopMode_RegisterEventMapInternal
  - insn_va: '0x180888880'
    insn_disasm: call sub_180555500
    func_name: CLoopMode_SetSystemState

found_funcptr: # This is for non-virtual regular function pointer.
  - insn_va: '0x180666600' # Must load/reference the function pointer target address
    insn_disasm: lea rdx, sub_15BC910 # Must load/reference the function pointer target address
    funcptr_name: CLoopMode_OnClientPollNetworking

found_gv: # This is for reference to global variable.
  - insn_va: '0x180444400'
    insn_disasm: mov rcx, cs:qword_180666600 # Must load/reference the global variable
    gv_name: g_pNetworkMessages
  - insn_va: '0x180333300'
    insn_disasm: lea rax, unk_180222200 # Must load/reference the global variable
    gv_name: s_EventManager

found_struct_offset: # This is for reference to struct offset. NOTE THAT virtual function pointer should not be here! virtual function pointer should ALWAYS be in found_vcall !
  - insn_va: '0x1801BA12A' # Always be the instruction with displacement offset
    insn_disasm: mov rcx, [r14+58h] # Always be the instruction with displacement offset
    offset: '0x58'
    size: 8
    struct_name: CResourceService
    member_name: m_pEntitySystem

If nothing found, output an empty YAML. DO NOT output anything other than the desired YAML. DO NOT collect unrelated symbols.


### 变量说明

| 变量 | 来源 | 说明 |
|------|------|------|
| `{disasm_for_reference}` | 旧版 IDA 导出 | 有符号的反汇编 |
| `{procedure_for_reference}` | 旧版 IDA 导出 | 有符号的伪代码 |
| `{disasm_code}` | 新版 IDA 导出 | 无符号的反汇编 |
| `{procedure}` | 新版 IDA 导出 | 无符号的伪代码 |
| `{symbol_name_list}` | 从旧版提取 | 需要在新版中定位的符号列表 |

## 工作流

### 完整流程

```text
Step 1: 准备数据
  - 旧版二进制加载到 IDA(有 PDB/符号)
  - 新版二进制加载到 IDA(无符号)
  - 找到两个版本中相同的锚点函数(导出函数、字符串引用等)

Step 2: 批量导出
  - 从旧版导出:锚点函数的反汇编 + 伪代码(含符号名)
  - 从新版导出:同一锚点函数的反汇编 + 伪代码(无符号名)

Step 3: LLM 比对
  - 用 prompt 模板填充数据
  - 调用 LLM API(推荐:deepseek 量大便宜,超大函数切 gpt)
  - 解析返回的 YAML

Step 4: 应用结果
  - 将 YAML 中的符号映射批量应用到新版 IDB
  - 用 idapro_rename 或 IDAPython 脚本批量重命名

Step 5: 迭代
  - 第一轮迁移的函数成为新的锚点
  - 进入这些函数,继续对比内部调用
  - 重复直到覆盖所有目标函数
アンカー選択戦略
アンカータイプ信頼性説明
エクスポート関数最高名前は変わらず、アドレスは変わる可能性がある
文字列参照高文字列の内容は変わらず、参照位置は変わる可能性がある
定数/マジックナンバー中特徴値は変わらない
コードパターン中関数構造は似ているがアドレスはすべて変わる
バッチ処理の推奨
  • 1 回に 1 関数を比較する(context の爆発を避ける)
  • 中規模関数(<200 行)は deepseek を使用
  • 超大規模関数(>500 行)は gpt-4o または claude に切り替え
  • 並行呼び出しで速度を向上(10-20 並行)
  • 結果をキャッシュし、重複呼び出しを避ける

出力フォーマット

YAML 出力の 5 種類のシンボルタイプ
タイプ意味主要フィールド
found_vcall仮想関数呼び出し(間接 call)vfunc_offset, func_name
found_call直接関数呼び出しinsn_va, func_name
found_funcptr関数ポインタ参照insn_va, funcptr_name
found_gvグローバル変数参照insn_va, gv_name
found_struct_offset構造体オフセット参照offset, struct_name, member_name
解析後の適用アクション
found_call → idapro_rename(addr=call_target, name=func_name)
found_vcall → idapro_set_comments(addr=insn_va, comment="vcall: {func_name} @ +{offset}")
found_funcptr → idapro_rename(addr=funcptr_target, name=funcptr_name)
found_gv → idapro_rename(addr=gv_addr, name=gv_name)
found_struct_offset → idapro_set_comments(addr=insn_va, comment="{struct_name}.{member_name}")

典型的なシナリオ例

シナリオ 1:ntoskrnl.exe に PDB がない
已有:ntoskrnl.exe 10.0.26100.2000 + 完整 PDB
目标:ntoskrnl.exe 10.0.26100.2605(PDB 被下架)
需求:定位 PspSetCreateProcessNotifyRoutine 的新地址

步骤:
1. 两个版本都加载到 IDA
2. 找到导出函数 PsSetCreateProcessNotifyRoutine(两个版本都有)
3. 旧版中它调用了 PspSetCreateProcessNotifyRoutine(有符号)
4. 新版中它调用了 sub_140822108(无符号)
5. LLM 一眼看出:sub_140822108 = PspSetCreateProcessNotifyRoutine
6. 批量应用
シナリオ 2:アプリケーション更新後の移行
已有:target.exe v1.0 的完整逆向结果(200+ 函数已命名)
目标:target.exe v1.1(所有符号丢失)
需求:批量迁移 200 个函数名

步骤:
1. 从旧版导出所有已命名函数的反汇编+伪代码
2. 在新版中通过导出函数/字符串找到对应锚点
3. 批量调用 LLM 比对
4. 解析 YAML,批量 rename
5. 迭代深入

LLM 選択の推奨

モデル適したシナリオコスト速度
DeepSeek V3中小規模関数(<200 行)、バッチ処理極めて低い速い
GPT-4o超大規模関数、複雑な制御フロー中速い
Claude Sonnet中大規模関数、推論が必要中速い
Claude Opus極めて複雑な関数、深い理解が必要高遅い

推奨戦略:デフォルトは DeepSeek、context 超過や結果が不正確な場合に自動でアップグレード。

注意事項

  • バイナリ全体を LLM に投げないこと — 1 回に 1 関数だけを比較する
  • アンカーは信頼できるものでなければならない — アンカー自体が間違っていると、以降すべてが無駄になる
  • 結果は人手で抜き取り検査が必要 — LLM は 100% 正確ではないため、重要なシンボルは検証する
  • 中間結果をキャッシュする — 重複呼び出しで token を無駄にしない
  • context 制限に注意 — 超大規模関数(>1000 行の逆アセンブリ)は分割するか、大 context モデルを使用する

オンデマンド自举(On-Demand Bootstrap)

ツール依存
ツール用途自動インストール可否
IDA Pro逆アセンブリ/擬似コードのエクスポート✗(商用ソフトウェア)
Pythonスクリプト実行、API 呼び出し✓
PyYAMLLLM が返す YAML の解析✓(pip install pyyaml)
LLM API比較の実行API key が必要
説明

本 skill の中核は重量級ツールのインストールに依存せず、主に以下に依存します:

  • IDA Pro が既にある(ida-reverse/ skill で管理)
  • Python + requests/httpx(API 呼び出し)
  • 1 つの LLM API endpoint

ルーティングコンテキスト

上流エントリ: skills/SKILL.md(総合制御)、routing.md トリガー条件: 旧版のシンボル/リバース結果があり、新バージョンへ移行する必要がある 下流出口:

  • まずバイナリを開く必要がある → ida-reverse/
  • 素早く偵察してバージョン差異を確認する必要がある → radare2/

同階層の関連モジュール: ida-reverse/(データのエクスポートとシンボルの適用はどちらも IDA を経由する)

タスク完了セルフチェック(完了を主張する前に MUST 通過)

  • ワークフローの各ステップを(読むだけでなく)実行したか?
  • tool-index に基づいて実際のツールパスを使用したか?
  • 再現可能な証拠(コマンド/スクリプト/スクリーンショット/レポート)を産出したか?
  • RULES が要求する Checklist 項目を完了し、書き戻したか?

コメント