世界初の自律型リバースエンジニア
バイナリリバースエンジニアリングのためのLLMオーケストレーション
ほとんどのタスクは線形の関係に従います。タスクが難しいほど、通常は時間がかかるものです。リバースエンジニアリング(およびバイナリ解析)は、実際の難易度は多少簡単ですが、実行時間は数時間(そして数日!)にも及ぶことがあり、関数が数百しかないバイナリであっても同様です。
Kongは、NSAグレードのリバースエンジニアリングフレームワークを使用して、機械的なレイヤーを自動化します。Kongは完全に難読化され、ストリップされたバイナリを取得し、完全な解析パイプラインを実行できます。関数のトリアージ、コールグラフコンテキストの構築、LLMガイドによる逆コンパイルによる型とシンボルの回復、そして結果をGhidraのプログラムデータベースに書き戻します。出力は、あるFUN_00401a30がparse_http_headerになり、復元された構造体、パラメータ名、呼び出し規約を持つバイナリです。
なぜこれが存在するのか
ストリップされたバイナリは、コードを読みやすくするすべてのコンテキストを失います。関数名、型情報、変数名、構造体レイアウト。そのコンテキストを回復することが、ほとんどのREタスクにおける作業の大部分であり、それは主にパターンマッチングです。すなわち、標準ライブラリ関数の認識、使用法からの型の推論、コールグラフを通じた名前の伝播です。
LLMは、まさにこの種のパターンマッチングに優れています。しかし、生の逆コンパイラ出力をLLMに渡して「これは何をするのか?」と尋ねると、平凡な結果しか得られません。モデルには呼び出しコンテキスト、クロスリファレンス情報、バイナリがどのように構造化されているかという全体像が不足しています。さらに、ほとんどの難読化されたバイナリは、リバースエンジニアリングを防ぐために極端な技術を導入しています。
Kongは、LLMに触れる前にGhidraのプログラム解析(コールグラフ、クロスリファレンス、文字列参照、データフロー)からリッチなコンテキストウィンドウを構築し、各関数が既に名前が付けられた呼び出し先から恩恵を受けるように依存関係順に解析をオーケストレーションすることで、この問題を解決します。さらに、Kongは独自の、初のエージェンティックな難読化解除パイプラインを導入しています。


Kongは、ほとんどのGhidraで逆コンパイル可能なバイナリで動作します(現時点では、今後さらに追加予定)。
| C | C++ | Go | Rust | |
|---|---|---|---|---|
| x86 | 高い | 高い | 中程度 | 中程度 |
| x86-64 | 高い | 高い | 中程度 | 中程度 |
| ARM (32ビット) | 高い | 高い | 中程度 | 低い |
| AArch64 | 高い | 高い | 中程度 | 低い |
| MIPS | 中程度 | 中程度 | 低い | 低い |
| PowerPC | 中程度 | 中程度 | 低い | 低い |
高い: Kongは確実に逆コンパイル、難読化解除、名前・型・構造の回復を行います。
中程度: 逆コンパイルは使用可能ですが、ノイズが多いです。部分的な回復と低い信頼度スコアが予想されます。
低い: 逆コンパイルに大きなギャップがあり、結果は不完全、ノイズが多い、または読めないままになります。
注: バイナリサイズは関数数、LLMコスト、完了時間に正の相関があります。ただし、バイナリサイズは信頼度には負の相関があるため、より大きなバイナリを分析する際はこの点に留意してください。
Kongは、トリアージ、並列解析、後処理を調整するスーパーバイザーによってオーケストレーションされる5フェーズのパイプラインを使用します。
┌──────────────────────┐
│ トリアージ │
│ 列挙、分類、 │
│ コールグラフ構築、 │
│ シグネチャマッチング │
└──────────┬───────────┘
│
▼
┌────────────────┼────────────────┐
│ │ │
▼ ▼ ▼
┌──────────────┐ ┌──────────────┐ ┌──────────────┐
│ 解析 │ │ 解析 │ │ ... │
│ (リーフ関数) │ │ (次の層) │ │ │
└──────┬───────┘ └──────┬───────┘ └──────┬───────┘
│ │ │
└────────┬───────┴────────────────┘
│
▼
┌──────────────────────┐
│ クリーンアップ │
│ 正規化、重複排除 │
└──────────┬───────────┘
│
▼
┌──────────────────────┐
│ 合成 │
│ 名前統一、構造体構築、│
│ 難読化解除 │
└──────────┬───────────┘
│
▼
┌──────────────────────┐
│ エクスポート │
│ analysis.json + │
│ Ghidra書き戻し │
└──────────────────────┘
トリアージは、バイナリ内のすべての関数を列挙し、サイズ(些細 / 小 / 中 / 大)で分類し、コールグラフを構築し、ソース言語を検出し、既知の標準ライブラリおよび暗号関数に対するシグネチャマッチングを実行します。シグネチャで一致した関数は解決済みとしてマークされ、LLM解析をスキップします。
解析は、ワークキューを使用してコールグラフからボトムアップ順に関数を処理します。各関数について、KongはGhidraのプログラムデータベース(逆コンパイル、クロスリファレンス、文字列参照、既に解析された呼び出し先のシグネチャ)からコンテキストウィンドウを構築し、逆コンパイラ出力を正規化し、LLMに送信して名前、型、パラメータの回復を行います。関数の逆コンパイルで難読化が検出された場合、Kongは解析を生成する前に、シンボリックツールアクセスを使用したエージェンティック難読化解除パスを実行します。結果は即座にGhidraに書き戻され、下流の呼び出し元が更新された名前を参照できるようにします。
クリーンアップは、解析中に蓄積された提案から構造体型を統一し、解析パス中に適用に失敗した関数シグネチャを再試行します。
合成は、解析されたすべての関数にわたってグローバルなビューを取ります。単一のLLM呼び出しで、最も接続の多い関数をレビューし、命名規則を統一し、フィールドアクセスパターンから構造体定義を合成し、より広いコンテキストで一貫性のないように見える名前を洗練します。
エクスポートは、最終的なanalysis.jsonを書き込み、回復されたすべての名前、型、シグネチャをGhidraプログラムデータベースに適用します。
# 1. Kongをインストール
uv pip install kong-re
# 2. APIキーを設定
export ANTHROPIC_API_KEY="sk-ant-..."
# または
export OPENAI_API_KEY="sk-..."
# 3. セットアップウィザードを実行(初回のみ)
kong setup
# 4. バイナリを解析
kong analyze ./path/to/stripped_binary
セットアップウィザードでは、使用するLLMプロバイダを選択し、デフォルトを設定します。KongはGhidraとJDKのインストールを自動検出し、バイナリをインプロセスのGhidraインスタンスにロードし、完全なパイプラインを実行します。
git clone https://github.com/amruth-sn/kong.git
cd kong
uv sync
uv run kong setup
uv run kong analyze ./path/to/stripped_binary
| 変数 | 必須 | 説明 |
|---|---|---|
ANTHROPIC_API_KEY | 少なくとも1つ | Anthropic APIキー (Claude) |
OPENAI_API_KEY | 少なくとも1つ | OpenAI APIキー (GPT-4o) |
GHIDRA_INSTALL_DIR | いいえ | Ghidraインストールへのパス(設定されていない場合は自動検出) |
JAVA_HOME | いいえ | JDKへのパス(設定されていない場合は自動検出) |
KONG_CONFIG_DIR | いいえ | 設定ディレクトリの上書き(デフォルト: ~/.config/kong) |
# セットアップウィザードを実行
kong setup
# ストリップされたバイナリを解析(設定済みのデフォルトプロバイダを使用)
kong analyze ./binary
# 特定のプロバイダで解析
kong analyze ./binary --provider openai
# モデルを上書き
kong analyze ./binary --provider openai --model gpt-4o-mini
# 解析を実行せずにバイナリメタデータを表示
kong info ./binary
# 解析出力を正解ソースコードに対して評価
kong eval ./analysis.json ./source.c
結果は出力ディレクトリ(デフォルト: ./kong_output_{binary_name}/)に書き込まれます:
kong_output_{binary_name}/
├── analysis.json # 回復されたすべての関数名、型、パラメータ
└── events.log # パイプライン実行トレース
Kongは、ストリップされたliblzma.so.5.4.1から完全なXZバックドア (CVE-2024-3094) キルチェーンを自律的に再構築し、5つのコアインプラント関数すべてを90-95%の信頼度で15分、$6.63で特定しました。
完全なケーススタディと再現手順については、BENCHMARKS.md を参照してください。
kong/
├── __main__.py # CLIエントリポイント (click)
├── config.py # KongConfig, LLMProvider, LLMConfig
├── db.py # SQLite設定ストア (~/.config/kong/)
├── banner.py # ASCIIバナー、APIキーヘルパー
├── agent/
│ ├── supervisor.py # パイプラインオーケストレーター
│ ├── triage.py # 関数列挙 + 分類
│ ├── analyzer.py # LLMガイドによる関数解析
│ ├── queue.py # コールグラフからのBFSワークキュー
│ ├── signatures.py # 既知関数のシグネチャマッチング
│ ├── prompts.py # システムプロンプト + 出力スキーマ
│ ├── events.py # パイプライントレース用のフェーズ/イベントタイプ
│ └── models.py # FunctionResult dataclass
├── ghidra/
│ ├── client.py # インプロセスGhidraClient (PyGhidra/JPype)
│ ├── types.py # FunctionInfo, BinaryInfo, XRef, など
│ └── environment.py # Ghidra/JDK自動検出
├── llm/
│ ├── client.py # AnthropicClient
│ ├── openai_client.py # OpenAIClient
│ ├── usage.py # TokenUsage, コスト追跡, 価格設定レジストリ
│ └── limits.py # モデル固有の制限 + レートリミッター
├── normalizer/
│ └── syntactic.py # 逆コンパイラ出力の正規化
├── synthesis/
│ └── semantic.py # グローバルな名前統一 + 構造体合成
├── evals/
│ ├── harness.py # 正解抽出 + スコアリング
│ └── metrics.py # symbol_accuracy, type_accuracy
├── export/
│ └── source.py # analysis.json + Ghidra書き戻し
├── signatures/
│ ├── stdlib.json # C標準ライブラリシグネチャ
│ └── crypto.json # 暗号関数シグネチャ
└── tui/
└── app.py # Textual TUI
KongはApache License 2.0の下でライセンスされています。Kongは無料のオープンソースプロジェクトです。
このライセンスはGhidraライセンスと互換性があり、商用利用を許可します。
問題や機能リクエストはGitHub Issuesで歓迎します。
KeygraphHQのShannonプロジェクトに大きな拍手を。このプロジェクトは、このプロジェクトへのインスピレーションを与えました。私のモチベーションは、Shannonがウェブベースのペネトレーションテスティングツールに使用しているのと同じ種類のパイプラインを再現し、バイナリ解析と逆コンパイルに適応させることでした。
猿を恐れよ。
Kong: 世界初のAIリバースエンジニア