
逆コンパイルされたバイナリの脆弱性を特定するためのBianryNinjaプラグインで、プログラムによるスキャンとLLMサポートの両方を備えています。
LLM支援の脆弱性調査のための Binary Ninja プラグインです。
VulnFanatic-NG はサイドバーパネルを追加し、現在のバイナリをスキャンして、疑わしいコードが実際に脆弱かどうかを LLM(デフォルトではローカルホストの OpenAI 互換モデル、または Anthropic Claude、Google Gemini、Azure OpenAI(LLM バックエンドを参照))に判断させます。主に Binary Ninja の**逆コンパイラ出力(HLIL)**を使用し、必要に応じてアセンブリにフォールバックして、確認された問題のみをコードへのクリック可能な参照付きで報告します。
スキャンは最大3つのフェーズで実行されます(フェーズ3はオプトインかつオンラインのみ)。
rules/phase1_rules.json で定義された危険な関数の呼び出し箇所を検出します — strcpy、memcpy、sprintf/フォーマット文字列、system、alloca、scanf、コマンド/exec API、弱い RNG、free/delete 系(use-after-free / double-free)、固定バッファへの信頼できない入力の読み込み(recv/read/fread/ReadFile)、SQLインジェクション(sqlite3_exec/mysql_query/PQexec)、無効化された TLS 証明書検証(SSL_CTX_set_verify/curl)、SSRF、不適切な権限管理(setuid/setresgid)、memset/bzero 系、攻撃者が制御する長さとの比較(memcmp/strncmp → 認証バイパス)。対象は C/C++、Win32、および(ベストエフォートの)Rust FFI です。対応範囲には、強化された _chk(FORTIFY)および Annex-K _s バリアントが含まれます。境界付きフォーマット出力関数(snprintf およびそのバリアント)には独自のデフォルト安全ルールがあり、正しいサイズ引数がオーバーフローとして報告されないようになっています。
呼び出し箇所は3つの方法で検出されます: 名前付きシンボルへの直接呼び出し。フォワーディングサンク / PLTスタブを経由する呼び出し(実際の呼び出し元が復元されるため、スタブ経由でのみ到達するインポートも見逃されません)。そして — vulnfanatic.scanIndirectCalls がオフでない限り — Binary Ninja が危険な関数に解決した関数ポインタまたは vtable を介してディスパッチされる間接呼び出し。各呼び出し箇所について、プロシージャ間の逆コンパイラ中心のコンテキストを構築し、トークン上限(デフォルト 100k)に収めます。
__*_chk や境界チェック付き *_s バリアントは先頭に追加の引数が付くため、フォーマット/サイズ/宛先の位置がずれます。s->buf のような構造体フィールドは s のポインタサイズではなく、そのフィールドの実際の配列サイズに解決されます。型セクションの構造体定義にもフィールドごとのバイトサイズが含まれます。0x40 であることが証明されたり、[0, 0xff] に制限される)。モデルはサイズをバッファ容量と比較する際に推測ではなくこれを真実として使用します。vulnfanatic.includeStackLayout)。if/ループ/switch 条件)。このコンテキストとルール固有のプロンプトがモデルに送信され、モデルは構造化された判定を返します。問題ではないものは破棄されます。プロンプトは強力なローカルコードモデル(例: Qwen2.5-Coder)向けに調整されており、フロー全体を分析して JSON のみを出力するよう指示します。
モデルは再現率を優先するよう指示されます。完全に証明できないものを破棄するのではなく、もっともらしいセキュリティ関連の問題を報告し、不確実性は信頼度(Confidence)で表現します。モデルは、判断の根拠となったコードスニペットをそのまま引用するスクラッチパッドに思考過程を示します(入力ソース、各ガード、サイズ/長さ、関連する型、シンク)。これは検出名に保存されるため、推論を監査できます。
各検出名には信頼度(high/medium/low)が付きます。high = コンテキストにチェーン全体が示されている。medium = 可能性が高く、リンクが1、2件推定される。low = 手動レビューに値する手がかり。これは主要な指標です(モデルの重大度推定は副次的なフィールドです)。vulnfanatic.minConfidence を設定すると、しきい値未満のものはすべて破棄されます。
デフォルトでは VulnFanatic-NG は再現率を優先します(実際の問題を捕捉)。誤検出が多すぎる場合は、次のいずれかで厳しくします。
vulnfanatic.validationPass(デフォルト オフ)— 2回目の LLM パスを実行し、フラグが立った各問題を同じコンテキストに対して再検証します(スクラッチパッドのスニペットを検証し、フローを再トレース)。判定や信頼度を修正できます。フラグが立った候補に対して LLM 呼び出しが2倍になります。
vulnfanatic.validatorModel(および validatorProvider / validatorBaseUrl / validatorApiKey)を設定すると、2回目のパスを別のモデルで実行できます。独立したモデルからのセカンドオピニオンははるかに有用です。盲点が少なく、最初の判定を鵜呑みにする可能性がはるかに低いためです(モデルは自分の答えを好む傾向があります)。良いパターンはカスケードです。アナリストとして高速なモデル(広い再現率)、バリデータとして最も強力なモデルを使用し、バリデータはフラグが立った候補に対してのみ実行されます。バリデータモデルを空白にすると、アナリストモデルで検証します。バリデータはアナリストと同等以上の能力を持つべきです。弱いモデルは誤った却下を増やすだけです。プロバイダー / ベースURL / キー / モデル以外はすべてアナリストの接続設定から継承されます。バリデータキーを空白にするとアナリストキーが再利用され、バリデータエンドポイントに到達できない場合は最初の判定が保持されます(検証の障害で検出名が失われることはありません)。vulnfanatic.minConfidence(デフォルト low)— medium/high に引き上げると、より確度の高い検出名のみを報告します。vulnfanatic.skipConstantArgCalls(デフォルト )— 引数がすべてコンパイル時定数であるオーバーフロー系の呼び出し箇所をスキップします。速度。 呼び出しごとのレイテンシのほとんどは書かれる推論によるものなので、vulnfanatic.verdictReasoning がモデルの出力量を制御します。
concise(デフォルト)— 1〜3文の簡潔な根拠。コードの逐語引用なし。full よりもはるかに高速で、精度の低下はわずかです。vulnfanatic.maxResponseTokens を下げることもできます。full — 引用スニペット付きの詳細なスクラッチパッド(最も監査しやすく、最も遅い)。none — 判定のみ。最速。推論対応バックエンド(vulnfanatic.reasoningEffort)と組み合わせると、モデルの内部思考が作業を担います。素のローカルモデルでは none は精度を失います(思考連鎖がまったくないため)。常に有効な精度サポート機能(検出名を抑制せずにモデルに情報を提供します):
_s(Annex K)と _chk(FORTIFY)バリアント、および長さ制限付き API を、サイズ引数自体が誤っていない限り安全として扱います。Scan Offline ボタンは、モデルなしでフェーズ1を実行します — phase1_rules.json の各ルールの offline ブロックで宣言された純粋にプログラム的なヒューリスティックです。危険な呼び出し箇所にフラグを立て、明らかに安全なものは除外し、ヒューリスティックな信頼度を割り当てます。
memcpy/memmove、定数文字列からの strcpy、定数フォーマットの printf、定数コマンドの system など — 支配的な引数がコンパイル時定数であり、攻撃者によって制御され得ない呼び出しです。「定数」には、Binary Ninja の値集合解析が上流で固定値に特定した値も含まれ、リテラル引数だけではありません。strlen/サイズ比較、if (len < …))がフロー上のどこか — パス上で呼び出される関数内を含む — で見つかった場合。すでに処理されている可能性があります。(変数に言及するだけで比較しない分岐はもはやカウントされず、誤った降格の原因が取り除かれます。)ヒューリスティックは、ルール内の小さな宣言的ボキャブラリ(constant_safe_args、eliminate_if_all_args_constant、format_arg_lookup、length_guard_vars、base_confidence、skip)を使用し、Python 述語によって評価されます — exec する埋め込みコードはありません。ほとんどのルールにはオフライン定義があります(オーバーフロー、フォーマット文字列、コマンド実行、scanf、パス処理、弱い RNG、弱い数値解析、権限変更、アロケーションサイズなど)。本当に意味解析が必要な2つのカテゴリだけがオフラインではスキップされ、LLM に委ねられます: free/delete 系(use-after-free / double-free。ポインタのライフタイム追跡が必要)とTLS検証(バグは SSL_VERIFY_NONE のような特定の定数値です)。オフラインサマリは、いくつのサイトがフラグ立て / 除外 / スキップ(LLM が必要)/ 失敗したかを報告するため、カウントは合計されます。これは高速なトリアージです。実際の判断 — およびスキップされたカテゴリ — には、完全な LLM スキャンを実行してください。
オフラインの検出名も、オンラインスキャンが送信するのと同じ完全なプロシージャ間コンテキストを(フラグが立ったサイトのみ)構築して保存するため、トリアージ後はオンラインの検出名と同様にファインチューニング用データとしてエクスポートできます。オフラインの速度を最大化したい場合は、vulnfanatic.offlineBuildContext で無効にします。
バイナリに実際のシンボル / 変数名があると思われる場合にのみ実行されます。rules/phase2_rules.json で定義されたセキュリティ関連関数を特定します — 認証、暗号化(弱いアルゴリズムを含む)、署名/証明書検証、セッション/トークン処理、アクセス制御、秘密/キー処理、入力検証、非定数時間の秘密比較、安全でないデシリアライゼーション — 関数名と参照される文字列で照合し、モデルが監査します。
ファームウェア堅牢化の監査で、フォールトインジェクション(電圧/クロック/EMグリッチング)およびサイドチャネル(タイミング/電力)攻撃に対するもので、ハードウェア攻撃の緩和ガイダンスに基づいています。バグを見つけるフェーズ1〜2とは異なり、フェーズ3はセキュリティ上重要な関数における欠落または違反した堅牢化コントロールを報告します — 例: デフォルトフェイル分岐、二重チェックされたセキュリティ判断、ループ後のカウンタ検証、高ハミング距離の状態定数(単純な 0/1 ではなく)、定数時間の全長シークレット比較、ランダムオフセットでのシークレットアクセス/消去、暗号化してから検証(anti-DFA)、制御フロー整合性カウンタ、ユーザーランド暗号の回避、生の鍵素材を直接扱わないこと(rules/phase3_rules.json)。
コンパイラの最適化によってソースレベルの保護が削られる可能性があるため、これらのコントロールはコンパイル済みバイナリで検証するのが最適です — まさにこれがチェックするものです。フェーズ3はLLMのみ(オンライン)、シンボルゲート、デフォルトでは無効です。New Scan タブの Phase 3 チェックボックスでスキャンごとに有効にします(オフラインモードでは実行されません)。
検出名はテーブル(ステータス、信頼度、フェーズ、CWE、関数、アドレス、タイトル)に一覧表示され、詳細ペインには説明、分析スクラッチパッド、検証ノートが表示されます。行をダブルクリックすると、バイナリビューがコードに移動します。
すべての検出名は Untriaged で始まります。行を右クリックしてステータスを設定します — Mark as Real Issue、Mark as False Positive、または Mark as Untriaged。ステータスを変更するたびに "Provide reason:" テキストボックスがポップアップします(理由は検出名とともに保存されます)。テーブルはステータスを明確に示します: Real Issues は緑/太字で上部にソートされ、False Positives はグレー/取り消し線で下部にソートされ、Untriaged はその間に信頼度の色付きで表示されます。サマリ行に件数が表示されます。
各結果タブには Export triaged (fine-tuning)… ボタンがあり、トリアージ済みの検出名(Real Issue + False Positive)のみをファインチューニング用の OpenAI チャット形式 JSONL としてエクスポートします。各サンプルは、元の system+user プロンプトと人間が修正した判定をアシスタントターゲットとしてペアにします(False Positive は is_vulnerable=false とあなたの理由を教え、Real Issue は is_vulnerable=true を強化します)。これにより、あなたのバイナリに対するモデルの精度を反復的に改善できます。
詳細ペインに表示される(およびファインチューニングプロンプトの再構築に使用される)検出名ごとのコンテキストは、デフォルトでは完全な状態で保持されます — vulnfanatic.storedContextChars で制御します(0 = 無制限。正の上限(例: 4000)を設定すると、コンテキストの忠実度を犠牲にして BNDB の肥大化を抑えられます)。
パネルはタブ形式です。最初のタブは常に New Scan で、次の項目を設定します:
<timestamp> <mode>、例: 2026-06-15 14:03:50 offline)、その後、Start Scan または Scan Offline を押します。実行ごとに独自の結果タブが開き、検出名がライブでストリーミングされます。すべてのスキャンは BNDB に保存されます。たとえば、オフラインスキャンを保持して後でオンラインスキャンを追加したり、異なるルールセットでの実行を並べて比較したりできます。データベースを再度開くと、それらはタブとして再表示されます。タブを閉じると、そのスキャンは BNDB から完全に削除されます。事故を防ぐため、Delete results forever ボタンが有効になる前に、「 の結果を永久に失うことを確認します。」 にチェックを入れる必要がある確認ダイアログがポップアップします。Export current scan… は選択中のタブを Markdown/JSON に書き出します。
開いている各バイナリは独立したパネル状態を持ちます — 独自のスキャンタブと実行中のスキャン。あるバイナリでスキャンを開始して別のバイナリに切り替えると、2番目のバイナリの結果が表示され(個別にスキャンも可能)、最初のバイナリのスキャンはバックグラウンドで実行され続け、切り替えて戻るとそのまま残っています。
このプラグインのパッケージフォルダ名は vulnfanatic_ng です(有効な Python 識別子です。Binary Ninja はプラグインフォルダ名をモジュールとしてインポートするため、VulnFanatic-NG のようなハイフン付きの名前は読み込まれません)。
(オプション)正確なトークンカウントを Binary Ninja の Python にインストールします: ``` pip install tiktoken
vulnfanatic_ng フォルダを Binary Ninja のユーザープラグイン
ディレクトリにシンボリックリンクするかコピーします:
~/Library/Application Support/Binary Ninja/plugins/~/.binaryninja/plugins/%APPDATA%\Binary Ninja\plugins\例えば、macOS の場合: ``` ln -s "$(pwd)/vulnfanatic_ng" "$HOME/Library/Application Support/Binary Ninja/plugins/vulnfanatic_ng"
Binary Ninja を再起動するか(または Reload Plugins を実行)します。右サイドバーに VF アイコンが表示されます。
設定(歯車アイコン / Edit ▸ Preferences ▸ Settings)を開き、vulnfanatic を検索してください。最低限、以下を設定します:
vulnfanatic.apiProvider は、リクエストの構成方法と認証方法を選択します。判定コントラクト(およびすべてのルールプロンプト)はプロバイダ間で同一です。
AWS Bedrock は、その OpenAI 互換エンドポイントを介して
openaiプロバイダ経由で使用できるため、専用のバックエンドは不要です。
その他の便利な設定: vulnfanatic.maxContextTokens(既定 100000)、
vulnfanatic.maxResponseTokens、vulnfanatic.temperature、
vulnfanatic.reasoningEffort(off/low/medium/high。既定 high — サポートされている場合、
モデルは回答前に考えるよう要求されます。プロバイダごとに以下へマップされます:
openai/azure は reasoning_effort、anthropic は適応的思考 + output_config.effort、
google は動的 thinkingConfig。モデルが拒否した場合は自動的に除去して再試行します)、
vulnfanatic.requestTimeoutSec、
vulnfanatic.callPathMaxDepth / vulnfanatic.callPathMaxPaths、
(コールパス上の関数の逆コンパイル済み本体を含める、
既定 on)/ (上限、既定 12)、
(パス上で呼び出される他の関数も含めます。これらは
境界/検証チェックを持つ可能性があります。既定 on)/
(上限、既定 12)、
(struct/union/enum 定義を含める。既定 on)/
(上限、既定 24)、
(呼び出し引数をその生成元/消費元まで遡って追跡し、
それらの本体を含めます。既定 on)/
(上限、既定 8)、
(呼び出し元関数に固定サイズのバッファがある場合、そのスタック変数レイアウトを
含めます。既定 on)、
(解決された関数ポインタ/vtable を経由してディスパッチされる危険な呼び出しも
一致させます。既定 on — 非常に大きなバイナリではスキャンを高速化するため off にします)、
(2 回目のダブルチェックパスを実行。既定 off)/
/ /
/ (検証パスを
別の独立したモデルで実行 — 空欄 = 分析モデルと同じモデル)/
(//。これ未満の検出結果は破棄。既定
)、(モデルがスコア付けできなかったサイトを破棄せず、
信頼度の "Unscored" 候補として報告。既定 on)、
(全引数が定数のオーバーフロー呼び出しサイトをスキップ。
既定 off)、(//。判定ごとにモデルが書く
推論の量 — 主な速度調整レバー。既定 )、
/
/ (各フェーズを有効化。Phase 3 は
オンライン専用で、通常はここではなく New Scan チェックボックスでスキャンごとに切り替えます)、
/ 、
(トークン見積もりのための tiktoken エンコーディング。tiktoken が
インストールされていない場合は文字ヒューリスティックにフォールバック)、
(オフライン検出結果用に完全なコンテキストを構築し、ファインチューニング用に
エクスポートできるようにします。既定 on)、
(コンソールへの詳細なパイプライントレース。既定 off)/
(バイナリを特定できるすべての詳細を編集し、ログを
共有可能にします — 下の を参照)、
、(HTTPS 証明書を
検証。既定 on)/ (HTTPS 用 CA バンドル —
が発生した場合は Troubleshooting を参照)、および
/ /
(これらを独自のルールファイルに指定して、
検出とプロンプトをカスタマイズします)。
セキュリティ上の注意: API キーは Binary Ninja の設定に平文で保存されます。 機密キーには環境変数による上書きを推奨します。
vulnfanatic.apiBaseUrl をリテラル値 TEST に設定すると、LLM なしで実行できます:
/tmp/vulnfanatic_ng/<binary>-<timestamp>/。これを使用して、VulnFanatic-NG がモデルに送信する正確な内容を検査・検証し、モデル時間を消費せずにルールプロンプト/コンテキストを反復調整できます。
vulnfanatic.debugLogging をオンにすると、スキャンパイプラインの詳細なステップバイステップのトレースが
(オンライン/オフラインの両方)Binary Ninja のログ/コンソールに出力されます: 各呼び出し
サイト、すべてのスキップ/除外決定、コンテキスト構築(サイズのみ)、各 LLM リクエスト
(プロバイダ/モデル/エンドポイント、リトライ、フォールバック)、各判定、および報告された各
検出結果。API キーがログに記録されることはありません。
デバッグログがオンの間、オンラインスキャンでは、確定された問題にならない候補を破棄せず、すべての候補を結果 テーブルに保持します。各候補には デバッグ専用ステータスがタグ付けされます(暗転表示され、下部にソートされます):
したがって、デバッグスキャンでは /N 合計のうち候補ごとに 1 行が表示され、サマリーは
問題数と rejected/skipped/error 数を別々に報告します。これらの行は右クリックして
Real Issue または False Positive として再トリアージできます(ファインチューニング用エクスポートの対象になります)。
(オフラインスキャンは影響を受けません — LLM を呼び出すことはありません。)
デバッグモードとは無関係に、モデルが解析不能な応答を返した場合 — 例えば
Gemma の <unused…> のような迷子トークン、JSON の代わりに散文、または 空メッセージ(role のみで
content がない場合)— クライアントは 1 回の修正リトライを行い、構造化出力フォーマットを無効にして JSON のみを
再要求します。成功した場合、スキャンの残りはそのフォーマットを無効にしたままにします。
また、クライアントは content が空のとき 推論チャネル
(reasoning_content / reasoning)も読み取るため、回答をそこに置く推論モデルでも
機能します。
空メッセージのケースは、OpenAI 互換 API(例: mlx-community/gpt-oss-20b)で提供される
GPT-OSS / o1 などの推論モデルでよく発生します: response_format=json_object が設定されていると、
harmony の「final」回答チャネルが抑制されることが多く、
サーバーは content なしで {"role": "assistant"} を返します。これらのモデルはまた、
出力予算のすべてを推論チャネルに使い切り、思考途中で切り詰められ、
JSON を一切含まない散文を返すことがあります。自動リトライはフォーマット関連のケースを回復します。
それでも続く場合は、vulnfanatic.sendJsonResponseFormat をオフにし、vulnfanatic.reasoningEffort を下げ
(思考に使う予算を減らす)、および/または vulnfanatic.maxResponseTokens を上げてください。
一方、<unused…>/意味不明な応答が続く場合は通常、
プロンプトがモデルのコンテキストウィンドウを超えている(vulnfanatic.modelContextWindow を設定し、
および/またはサーバーのコンテキスト長を上げる)、またはモデルが厳密な JSON 出力に不向きである
(Qwen2.5-Coder のようなコードモデルは Gemma よりはるかに優れた動作を示します)ことを意味します。
リコールを保持するフォールバック。 リトライ後も候補をスコアリングできない場合、
vulnfanatic.flagUnparseableResponses(既定 on) はそれをとにかく
"Unscored" 検出結果として UNKNOWN 信頼度で報告します — low とは異なる値です(
モデルは判定を生成しなかったため、低信頼度の判断ではありません)。これは下部にソートされ、
モデルの部分出力を説明として保持するため、サイトを失わず、
手動でレビューするだけです。オフにすると、代わりにそのようなサイトは破棄されます(その後は
分析エラーまたはデバッグの ERROR 行としてのみ表面化します)。
また、vulnfanatic.debugAnonymous を有効にすると、ログを共有しても安全になります:
分析対象ファイルを特定できるすべての情報を編集します — シンボル/変数名と
アドレスは実行ごとのソルト付きハッシュになります(実行内では一貫しているため、フローは
追跡可能)、ファイル名は隠され、検出結果テキストは <redacted> に置き換えられ、
LLM エンドポイントのホストはハッシュされ、逆コンパイルされたコード / プロンプト / コンテキストは
サイズのみがログに記録されます(内容は決して記録されません)。これにより、バイナリに関する
情報を開示せずに、問題を報告するためのデバッグログを送信できます。
検出結果は、誤検知ステータスを含めて、Binary Ninja
データベースに保存されます。データベースを保存すると .bndb に書き込まれ(
.bndb が既に存在する場合は即座にフラッシュされる)、再オープン後も保持されます。
スキャンは一致したすべての呼び出しサイト(上限なし)を分析するため、ローカルモデルに適しています。 ホスト型/従量課金エンドポイントの場合は、大規模な バイナリではボリュームに注意してください。
両方のルールファイルは、共通の system_prompt と output_schema、および rules のリストを含むエンベロープを共有します。
バンドルされたファイルをコピーし、関数/キーワード/プロンプトを編集して、
vulnfanatic.rulesPhase1Path / vulnfanatic.rulesPhase2Path をコピー先に指定します。
Phase 1 ルールは functions(完全一致)と name_regex でマッチし、Phase 2 ルールは name_keywords、name_regex、
string_keywords でマッチします。各ルールの prompt は {function} プレースホルダーを使用できます。
トリアージ済みエクスポートは、そのままモデルにフィードバックできるように設計されています。
複数のバイナリにわたって検出結果をトリアージし、それぞれで Export triaged
(fine-tuning)… をクリックした後(.jsonl ファイルを 1 つのフォルダに収集)、
scripts/finetune_mlx.py がそれらに対して MLX LoRA
ファインチューニングを実行します。```bash
pip install mlx-lm # Apple Silicon / macOS
python scripts/finetune_mlx.py ./exports
--model mlx-community/Qwen2.5-Coder-7B-Instruct-4bit
--adapter-path ./vf-adapters --iters 800
python scripts/finetune_mlx.py ./exports --model
--fuse --fused-path ./vf-qwen-coder-vuln
スクリプトは位置引数として**training-dataフォルダ**とベースの
**`--model`** (ローカルパスまたはMLX/HFリポジトリID) を受け取ります。その他のパラメータはオプションです:
`--adapter-path`, `--valid-split` (0.1), `--iters`, `--batch-size` (小さな分割に
収まるよう自動的にクランプされます), `--num-layers`, `--learning-rate`, `--max-seq-length`
(`0` = 最長の例に**自動調整** (上限16384)。正の値を設定すると
その値に固定されます), `--fine-tune-type` (`lora`/`dora`/`full`), `--seed`, `--fuse`/`--fused-path`,
および`--dry-run` (トレーニングせずにデータを準備してコマンドを表示します)。リテラル
`--`の後にあるものはすべて、そのまま`mlx_lm lora`に転送されます。フォルダ内のすべての
`*.jsonl`を再帰的にマージし、チャットの例を検証して**重複排除**し、MLXが期待する
`train.jsonl`/`valid.jsonl`の分割を作成してから、`python -m mlx_lm lora`
(`--fuse`付きの場合は`mlx_lm fuse`も) を起動します。
結果はOpenAI互換サーバー (`mlx_lm.server --model <path>`) で公開し、
`vulnfanatic.apiBaseUrl`をそのサーバーに向けて、チューニングしたモデルでスキャンしてください。
> VulnFanatic-NGのコンテキストは大きいため、デフォルトではスクリプトは`--max-seq-length`を
> 最長の例に**自動調整**します (切り上げ、上限**16384トークン**)。
> 長いシーケンスはトレーニングメモリを大量に消費するため、この上限に近い大きなモデルは
> 小さなMacのメモリを不足させる可能性があります。例が上限を超える場合は切り詰められます。
> エクスポートする前に、より高い`--max-seq-length`を渡すか (メモリ増加)、
> `vulnfanatic.storedContextChars`を低くしてください。トレーニングがシグナル (例: `exit -10` / SIGBUS) で
> 終了した場合はメモリ不足によるクラッシュです。`--max-seq-length`を下げるか、
> `-- --grad-checkpoint`を追加するか、より小さなモデルを使用してください。
---
## 開発とテスト
このプラグインには必須のサードパーティ依存関係はありません。純粋なモジュール
(`rules`, `tokens`, `llm`, `findings`, `settings`, `prototypes`) は、Binary Ninjaもネットワークも
必要としないオフラインのテストスイートでカバーされています。`tests/`
スイートはプロジェクトのソースリポジトリにあります (公開されたプラグインには同梱されていません)。
そこから実行してください。パッケージディレクトリからでも、すべてのモジュールの
構文チェックが可能です:```
python3 -m py_compile *.py ui/*.py
python3 -m unittest discover -s tests # from the source repository
Binary Ninja 向けモジュール(context_builder、phase1、phase2)は、Binary Ninja
なしでも問題なくインポートできます(API アクセスはガードされています)が、実際に動作させる
には実行中の Binary Ninja が必要です。
argv[1] を固定サイズの
スタックバッファに strcpy し、入力に対して system() を呼び出すもの)。
Phase 2 もテストするため、シンボル付きでコンパイルしてください。vulnfanatic.apiBaseUrl、
vulnfanatic.apiKey、vulnfanatic.model を設定します。SSL: CERTIFICATE_VERIFY_FAILED ... unable to get local issuer certificate —
HTTPS エンドポイントの証明書自体は正常ですが、Binary Ninja に同梱されている Python には
検証用の CA バンドルがありません(macOS や組み込み Python でよく発生します。AWS Bedrock、
Anthropic、Google、Azure などのホスト型エンドポイントでも発生します)。以下を優先順に
試して修正してください:
pip install certifi でインストールします。VulnFanatic-NG は自動的に検出して使用します。vulnfanatic.caBundlePath にバンドルファイル(または
ディレクトリ)を設定します — 例:python3 -m certifi が出力するパス、または
/etc/ssl/cert.pem。vulnfanatic.tlsVerify をオフにする(信頼できる内部エンドポイントまたは
自己署名のローカルサーバーにのみ使用してください — これにより証明書チェックが無効に
なります)。HTTP 400 ... tokenizer.chat_template is not set — 配信中のモデルにチャットテンプレート
がないため、/chat/completions エンドポイントがメッセージをフォーマットできません。
VulnFanatic-NG はこのエラーを検出すると、スキャンの残りを /completions エンドポイントに
自動的にフォールバックするため、スキャンは継続されます。最初の失敗リクエストを完全に
回避するには、vulnfanatic.apiMode を completions に設定します。あるいは、チャット
テンプレートを同梱したモデルを配信するか、サーバーにテンプレートを渡してサーバー側で修正
します — 例:vLLM の場合は --chat-template <template.jinja>(または -Instruct/-Chat
系のモデルバリアントを使用)。専用のチャットテンプレートは通常、フラット化された completions
プロンプトよりも良い結果をもたらします。
No JSON object found ... response looks truncated — モデルの応答が JSON の完了前に
途切れています。原因は2つあります:
vulnfanatic.maxResponseTokens を引き上げます。maxResponseTokens をいくら高く設定しても応答は数トークンで止まります。
ローカルサーバーはウィンドウが小さいことがよくあります(ollama はデフォルトで
num_ctx=2048!)。vulnfanatic.modelContextWindow をサーバーのウィンドウに合わせて
設定することで修正できます(例:ollama の num_ctx、llama.cpp の -c、vLLM の
--max-model-len)。これにより VulnFanatic-NG は送信するコンテキストを自動的に制限し、
プロンプト + 応答が収まるようにします。また、vulnfanatic.maxResponseTokens は妥当な値
(≈8192、65535 ではなく)に保ち、必要に応じてサーバーのウィンドウも引き上げてください。
小さすぎるウィンドウ(≤8k)では完全なプロシージャ間コンテキストを保持できないため、32k 以上
に設定されたモデル/サーバーを使用してください。IncompleteRead / Could not complete request ... after N attempt(s) —
サーバーはリクエストを受け付けましたが、完全な応答を送信する前に接続を閉じました。
これはほとんどの場合、モデルサーバーが生成中にクラッシュまたは停止したことを意味します:
メモリ不足(大きなコンテキスト + 長い出力)、内部/ワーカーのタイムアウト、またはプロキシに
よる接続リセットです。VulnFanatic-NG は自動的に1回再試行し、その後そのサイトをスキップ
します。実際の原因についてはモデルサーバー自身のログを確認してください。
vulnfanatic.maxContextTokens や vulnfanatic.maxResponseTokens を減らすか、サーバーに
より多くのメモリ / より大きなコンテキストウィンドウを割り当てることで、通常は解決します。
vulnfanatic.phase2ForceEnable を設定するか、vulnfanatic.phase2RequireSymbols=off
にします。シンボルゲートはヒューリスティックです。response_format=json_object を無視または拒否します。クライアント
はそれを許容し、JSON の抽出を継続します。サーバーがパラメータを完全に拒否する場合は
vulnfanatic.sendJsonResponseFormat を無効にしてください。Apache-2.0(© Martin Petran)— plugin.json を参照してください。
MAIN→ABCD→strcpy の場合、MAIN と ABCD が他で呼び出す関数も含む)。危険な値を制御する境界/検証チェックが含まれている可能性があるためです(vulnfanatic.includeCallPathSiblings。予算が許す限り追加されます)。recv/read/getenv などの入力関数)。| 設定 | 意味 |
|---|
vulnfanatic.apiProvider | 呼び出す LLM バックエンド: openai(既定)、anthropic、google、azure。下の LLM バックエンド を参照。すべてのプロバイダは Python 標準ライブラリ経由でアクセスされるため、pip install は不要です。 |
vulnfanatic.apiBaseUrl | 選択したプロバイダのエンドポイントベース(下の表を参照)。既定は http://localhost:8080/v1。リテラル値 TEST に設定すると テストモード が有効になります(下記参照)。 |
vulnfanatic.apiKey | API キー / ベアラートークン。ローカルサーバーでは空でも可。VULNFANATIC_API_KEY または OPENAI_API_KEY 環境変数で上書きされます。 |
vulnfanatic.model | 必須(テストモードを除く)。モデル識別子(azure の場合は デプロイメント名)。 |
vulnfanatic.apiMode | openai のみ: chat(既定、/chat/completions)と completions(単一のフラット化されたプロンプト — チャットテンプレートなしで提供されるベース/インストラクトモデル用)。 |
vulnfanatic.azureApiVersion | azure のみ: api-version クエリパラメータ(既定 2024-10-21)。 |
| Provider | apiBaseUrl | Auth | Notes |
|---|
openai | 例: http://localhost:8080/v1 のような自前サーバー | Authorization: Bearer | OpenAI 互換の Chat/Completions: ローカルの llama.cpp / ollama / vLLM、OpenAI、および AWS Bedrock の OpenAI 互換エンドポイント。 |
anthropic | 空欄 → https://api.anthropic.com | x-api-key + anthropic-version | Claude Messages API(POST <base>/v1/messages)。temperature は送信されません(現在の Claude モデルはこれを拒否するため)。 |
google | 空欄 → https://generativelanguage.googleapis.com | API キーを URL に含める | Gemini generateContent(<base>/v1beta/models/<model>:generateContent)。 |
azure | https://<resource>.openai.azure.com | api-key ヘッダー | Azure OpenAI。model には デプロイメント名、azureApiVersion には API バージョンを設定します。 |
vulnfanatic.callPathIncludeBodiesvulnfanatic.callPathMaxBodiesvulnfanatic.includeCallPathSiblingsvulnfanatic.callPathSiblingMaxBodiesvulnfanatic.includeDataTypesvulnfanatic.maxTypeDefsvulnfanatic.includeVariableDataflowvulnfanatic.dataflowMaxFunctionsvulnfanatic.includeStackLayoutvulnfanatic.scanIndirectCallsvulnfanatic.validationPassvulnfanatic.validatorModelvulnfanatic.validatorProvidervulnfanatic.validatorBaseUrlvulnfanatic.validatorApiKeyvulnfanatic.minConfidencelowmediumhighlowvulnfanatic.flagUnparseableResponsesUNKNOWNvulnfanatic.skipConstantArgCallsvulnfanatic.verdictReasoningconcisefullnoneconcisevulnfanatic.runPhase1vulnfanatic.runPhase2vulnfanatic.runPhase3vulnfanatic.phase2RequireSymbolsvulnfanatic.phase2ForceEnablevulnfanatic.tokenizerEncodingvulnfanatic.offlineBuildContextvulnfanatic.debugLoggingvulnfanatic.debugAnonymousvulnfanatic.sendJsonResponseFormatvulnfanatic.tlsVerifyvulnfanatic.caBundlePathCERTIFICATE_VERIFY_FAILEDvulnfanatic.rulesPhase1Pathvulnfanatic.rulesPhase2Pathvulnfanatic.rulesPhase3Path