Communitygithub.com

binary-diff

古いバージョンのバイナリから得たシンボル情報を、新しいバージョンのバイナリへと効率的に移行するためのスキルです。LLMを使って関数ごとに比較・マッピングすることで、手動での再解析や高価なツールに頼らず、低コストで高精度なシンボル移行を実現します。

binary-diff とは?

このスキルは、主にWindowsカーネルドライバやアプリケーションのアップデート時に発生する「古いバージョンにはシンボル(PDBなど)があるが、新しいバージョンにはない」という状況を解決するために設計されています。従来の方法(手動比較、BinDiff)に比べ、LLMを使用することで、1関数あたり約10秒、約1円という非常に低コストで高精度なシンボルマッピングを実現します。その核となる仕組みは、旧バージョンと新バージョンの同一関数の逆アセンブルと擬似コードをLLMに与え、関数内部で参照されるシンボル(関数呼び出し、グローバル変数、構造体オフセットなど)の対応関係をYAML形式で出力させるというものです。この出力を解析し、IDA Proなどの解析ツールに適用することで、大量のシンボルを一括で移行できます。対応プラットフォームとしては、IDA Proをベースとし、LLM API(DeepSeek、GPT-4o、Claudeなど)と連携して動作します。エージェントは、事前に定義されたワークフロー(データ準備→一括エクスポート→LLM比較→結果適用→反復)に従い、まずは確実なアンカー(エクスポート関数など)から比較を開始し、その結果を新たなアンカーとして段階的にシンボルを広げていくことで、最終的に関数全体のシンボル移行を完了します。

対応✓Claude Code✓Codex CLI~Cursor
npx skills add https://github.com/zhaoxuya520/reverse-skill/tree/main/skills/binary-diff

お気に入りのAIに質問する

このエージェントスキルを事前に読み込んだ状態で新しいチャットを開きます。

ドキュメント

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

アクション必須(読んだらすぐ実行)

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

適用範囲

以下のシナリオに該当するタスクで本スキルを使用する:

  1. カーネル/ドライバのPDB欠落 — 旧バージョンの ntoskrnl.exe にはシンボルがあるが、新版のPDBがMicrosoftによって削除されている場合。旧版のシンボルを使って新版の非エクスポート関数のアドレスを導出する。
  2. プログラム更新後のシンボル移行 — 過去にリバースエンジニアリングしたプログラムが更新され、再度解析することなく、旧版の結果を一括移行したい場合。
  3. 保護機構の更新 — 旧版に完全なリバース結果があり、新版で同じ関数の新しいオフセットを素早く特定する必要がある場合。
  4. 「旧版にシンボルあり + 新版にシンボルなし」のバイナリ比較シナリオ全般

他のスキルとの役割分担

シナリオ使用するスキル
バイナリをゼロからリバースida-reverse/ または radare2/
旧版の結果があり、新版に移行本スキル
二つの全く異なるバイナリを比較BinDiff / Diaphora(従来ツール)

コアアドバンテージ

従来手法との比較:

手法200関数のコスト時間精度
手動でIDAを2つ開いて比較無料だが命を削る数時間高い
BinDiff自動マッチ無料速い中(構造変化が大きいと無効)
全てをAgent(CC/Codex)に任せる50~100元遅い高い
本スキル(LLM一括比較)約1元約10秒/関数高い

コア原理

旧版関数(シンボルあり)         新版同一関数(シンボルなし)
    ↓                              ↓
逆アセンブル + 疑似コードのエクスポート         逆アセンブル + 疑似コードのエクスポート
    ↓                              ↓
    └──────── LLM 構造化比較 ────────┘
                    ↓
         YAML出力(シンボルマッピングテーブル)
                    ↓
         プログラムによる解析 → 新版IDBに一括適用

ポイント:

  • prompt は固定テンプレートで、プログラム的に埋め込む
  • 入出力形式が確定しており、プログラム的に解析可能
  • LLMは「2つのコードを見比べて、対応関係を見つける」部分のみを担当
  • 時間コストとトークンコストが非常に低い

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にロード(シンボルなし)
  - 2つのバージョンで同じアンカー関数(エクスポート関数、文字列参照など)を見つける

Step 2: 一括エクスポート
  - 旧版から:アンカー関数の逆アセンブル + 疑似コード(シンボル名を含む)
  - 新版から:同じアンカー関数の逆アセンブル + 疑似コード(シンボル名なし)

Step 3: LLM比較
  - promptテンプレートにデータを埋め込む
  - LLM APIを呼び出す(推奨:deepseekは量が多く安い、超大関数はgptに切り替え)
  - 返ってきたYAMLを解析する

Step 4: 結果の適用
  - YAML内のシンボルマッピングを新版IDBに一括適用する
  - idapro_rename または IDAPythonスクリプトで一括リネーム

Step 5: 反復
  - 第一ラウンドで移行した関数が新しいアンカーになる
  - これらの関数に入り、内部の呼び出しを引き続き比較
  - 全ての目的関数をカバーするまで繰り返す

アンカー選択戦略

アンカータイプ信頼性説明
エクスポート関数最高名前は変わらず、アドレスが変わる可能性あり
文字列参照高い文字列内容は変わらず、参照位置が変わる可能性あり
定数/マジックナンバー中特徴的な値は変わらない
コードパターン中関数構造は似ているが、アドレスはすべて変わる

一括処理の提案

  • 1回の比較は1関数のみ(コンテキスト爆発を避ける)
  • 中規模関数(<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を解析し、一括でリネーム
5. 反復して深堀り

LLM選択の提案

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

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

注意事項

  • バイナリ全体をLLMに渡さない — 一度に比較するのは1関数のみ
  • アンカーは信頼できるものでなければならない — アンカー自体が間違っていると、以降全て無駄になる
  • 結果は人間がスポットチェックする — LLMは100%正確ではないため、重要なシンボルは検証すること
  • 中間結果をキャッシュする — 重複呼び出しでトークンを無駄にしない
  • コンテキスト制限に注意 — 超大関数(>1000行の逆アセンブル)は分割するか、大コンテキストモデルを使うこと

オンデマンドブートストラップ

ツール依存関係

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

説明

本スキルの中核は重量ツールのインストールに依存せず、以下に依存する:

  • IDA Proが既にある(ida-reverse/ スキルで管理)
  • Python + requests/httpx(API呼び出し)
  • LLM APIエンドポイント

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

上流エントリ: skills/SKILL.md(全体制御)、routing.md トリガー条件: 旧版のシンボル/リバース結果が存在し、新版に移行する必要がある場合 下流出口:

  • バイナリを開く必要がある場合 → ida-reverse/
  • バージョン差分を素早く偵察・確認する必要がある場合 → radare2/

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

タスク完了セルフチェック(完了宣言前にMUST合格)

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

Individual skills in this repo

This repo contains 20 individual skills — each has its own dedicated page.

api-security

Use for authorized security assessment of REST, GraphQL, WebSocket, or SOAP APIs, including discovery, authentication, authorization, rate-limit, and CI/CD testing.

apk-reverse

在 CLI 环境下做 Android APK 逆向时使用。适用于 APK 解包、Java 反编译、smali 修改、重打包、Frida 动态 Hook,以及按需切换到 so/native 分析。优先使用本机已安装的 jadx、apktool、frida、adb、ida-reverse、radare2。

attack-chain

Use for authorized multi-stage attack-path planning and orchestration when a task spans reconnaissance, initial access, privilege escalation, lateral movement, or impact assessment. Route single-stage tasks directly to their specialist skill.

binary-ninja-reverse

Use for authorized binary analysis in Binary Ninja, including HLIL/MLIL/LLIL inspection, strings/imports/exports, cross-references, types, patch review, Python API automation, and optional Binary Ninja MCP or localhost HTTP integration.

browser-automation

|

browser-extension-reverse

Use for authorized reverse engineering of browser extensions (Chrome/Firefox) including manifest analysis, background workers, and extension-based credential or traffic logic recovery.

case-review

Reviews a reverse-skill case package for scope readiness, Evidence to Finding to Path traceability, work item coverage, timeline references, and optional artifact hash integrity before report handoff.

cloud-k8s

Use for authorized cloud, container, and Kubernetes security assessment including metadata SSRF, IAM misconfig, container escape paths, and cluster RBAC review.

code-audit

Use for authorized source-code security review and SAST workflows including Semgrep, CodeQL patterns, dangerous API hunting, and fix verification.

ctf-sandbox

Thin PRIMARY for CTF / AWD / 靶场 multi-type orchestration. Hands off to the sidecar CTF-Sandbox-Orchestrator. Use when the user says CTF, AWD, 靶场, or 比赛题 and no more specific pwn/APK/IDA route already won.

database-security

Use for authorized database security assessment covering PostgreSQL/MySQL/MSSQL/Mongo/Redis exposure, authz, UDF/command paths, and misconfiguration review.

diagram-generator

generate, refine, validate, and render diagrams from natural language, notes, code snippets, schemas, tables, or existing diagram source. use for flowcharts, swimlanes, sequence diagrams, state diagrams, er diagrams, class diagrams, architecture/c4-style diagrams, dependency graphs, gantt charts, mind maps, user journeys, sankey-style flows, org charts, network graphs, and other visual models. supports mermaid by default, graphviz dot for complex graph layout, plantuml for uml-heavy engineering diagrams, and svg output when direct markup is more reliable.

digital-forensics

Use for authorized digital forensics including memory dumps, disk timelines, PCAP investigation, artifact triage, and IR evidence preservation.

docs-generator

|

dotnet-reverse

.NET / C# 二进制逆向。当目标是 .NET assembly(PE 头含 CLR、.exe/.dll 托管程序)、C# 编译产物(含 NativeAOT)、红队 Sharp* 工具(Rubeus / SharpHound / SharpHound 等)、.NET 混淆程序(ConfuserEx / SmartAssembly / Babel / Eazfuscator)、.NET loader / info-stealer / 套壳 malware 时使用。优先用 dnSpyEx + de4dot,需要 AI 直接操作时联动 dnSpy MCP。不用于纯 native 二进制(走 reverse-engineering / ida-reverse)。

edr-bypass-re

|

email-security

Use for authorized email security review including phishing analysis, header authentication (SPF/DKIM/DMARC), BEC patterns, and mailbox token abuse research.

firmware-pentest

|

ghidra-reverse

Use for free/open reverse engineering with Ghidra (headless or GUI), including decompile, cross-refs, and optional Ghidra MCP workflows when IDA is unavailable.

go-rust-reverse

Use for reverse engineering stripped Go and Rust binaries including runtime recognition, pclntab/moduel data recovery, panic strings, and idiomatic decompilation recovery.

関連スキル