エッセイ

リバースエンジニアリングに、より大きなモデルは必要か?

N0zoM1z0 著 · 2026 年 10 月 13 日

要点

  • モデルの能力によって、エージェントが見つけられる仮説は変わる。 後の作業では、それまで解決できなかった問題が解決された。
  • 使い慣れたコンパイラには、特化モデルが学べる具体的なパターンがある。 完全一致の中には、細かな、再利用可能なソースコードのパターンに依存するものもある。
  • リポジトリに蓄積した知識も、公平に比較したい。 小さなモデルでも、適切に知識を検索できれば、作業を進めるのに十分かもしれない。
  • 次の有用な実験を選ぶ力を学習させ、その検証器も確かめる。 フィードバックの価値は、検証器が実際に何を確認しているかで決まる。
  • 検証を通った再構築の成果を、時間とコストと合わせて評価する。 エージェントのワークフロー全体で測りたいのは、その結果だ。

強いモデルで何が変わったか

2026年8月から、プログラムにアクセスし、自分の作業を検証できるエージェントが、どこまでリバースエンジニアリングを進められるかを探ってきた。私の経験は主にゲーム、特に Touhou(東方)の再構築から得たものだ。モデルを変えるたびに、各セッションで何を復元できたかがリポジトリに残った。

その多くは完全一致を目指す再構築だ。バージョンを固定した当時のツールチェーンで、保守しているソースをコンパイルし、対象の関数を再現できるか確かめる。後のモデルが以前の行き詰まりを解消したとき、ソースの変更を見ると、何が進歩を可能にしたかがわかる。

一時的な値を同時に有効にしておく必要があった

TH09 のある攻撃関数は、ロジックの大部分が復元済みだった。それでも、コンパイラが一時的な結果を格納する方法は原版と違っていた。残る問題は、その結果がいつまで有効であるべきか、そして格納領域をいつ再利用できるかだった。

いくつかの通常のソースコード配置をテストした後、GPT-6-Sol セッション レコード でこの不一致が報告されました。 GPT-6.1-Sol がこの問題を再度調査したとき、これらの一時変数の存続期間に関する有用な仮説が提案されました。

この関数は一時的な結果を作り、アニメーションの位置にコピーする。C++ の一時的な結果は、それを使う式が終わるまで生存する。実際の処理を一つの式にまとめると、結果の生存期間が重なり、コンパイラはすべての結果に同じ格納領域を使い回せなくなる。

一つの結果だけは、後の衝突判定に使う値と領域を共有していた。その値に独立した生存期間を与えると、最後の重なりも解消された。いくつかの絞り込んだ実験の後、クリーンビルドで関数全体の一致が確認された。

発見とテストがどのように相互にサポートし合っていたのかに興味があります。一時オブジェクトの存続期間に関する仮説は、AI エージェントに新しい方向性を与えました。コンパイラーからのフィードバックにより、その仮説を改良して、一致するソースコードの配置を実現することができました。

別の制御フロー グラフ

2 番目の TH09 関数は、その新しい方向が重要である理由を示しています。ここでの障害は、複数のブランチが最終的な作業をどのように共有するかでした。 GPT-6.1-Sol の以前の作業 では、関数の一部が一致していましたが、分岐の結合方法は依然としてオリジナルとは異なっていました。

GPT-6-Astra が周囲の制御フロー グラフを変更しました。メイン パスは共有された最終更新と復帰につながりました。そのソース構造では、コンパイラはオリジナルと同じ方法でブランチを結合しました。完全な関数は一致しており、別のリビルド チェックでそれが確認されました。

表現を変えたことで、より有望な探索空間が開けた。 この二つの例から、汎用モデルの能力は重要だと感じる。エージェントは局所的な変更を長く試した末に、周囲の処理を表すもっとよい方法を見つけることがある。

ただし、後のセッションは、それまでのソースと失敗の記録を引き継いでいる。その蓄積も有利に働いた。履歴から発見と検証の過程は調べられるが、モデルの効果と引き継いだ経験の効果を分けるには、条件をそろえた比較が必要だ。

これが私にとってこの質問が興味深い理由です。新しい表現を見つけることである程度の進歩が得られました。残りの作業の多くには、使い慣れたコンパイラに対してさまざまなソース コードの配置をテストすることが含まれていました。このうちどの程度の範囲で幅広い推論能力が必要でしょうか?モデルはそのコンパイラーとコードを繰り返し操作することでどれだけ学習できるでしょうか?

特化モデルがうまく働く可能性は?

Touhou には、経験の蓄積が役立つと考える具体的な理由がある。多くのゲームコードを ZUN 一人が書いているため、繰り返し現れる書き方を最初の仮説にできる。実際、リポジトリには、似たループや補助関数の構成が別のゲームの仮説につながった例がある。

コンパイラを含めると、これらのソース パターンがより具体的になります。特定のバージョンとオプションのセットでは、ソースに小さな変更を加えると、マシンコードに再現性のある差異が生じる可能性があります。これらの違いの中には、驚くほどわかりにくいものもあります。

たとえば、TH095 では、ローカル変数の名前であっても、VC7.1 がそれを格納する場所に影響を与える可能性があります。その宣言を移動してもストレージ レイアウトは解決されませんでした。ただし、以前のバックグラウンド関数では、コンパイラの選択に影響を与える名前付けパターンが明らかになっていました。これは、Supervisor::LoadDat を再構築するためのより有望な仮説を示唆しました。

そのパターンをファイルサイズの変数に使うと、格納領域を増やさずに必要な配置が得られた。続いて関数全体が一致した。

これは非常に具体的な詳細であり、汎用 AI モデルが最初に問題に遭遇したときには認識できない可能性があります。このコンパイラに特化したモデルは、そのようなケースを多数確認し、どのソース コードのバリエーションが最初にテストする価値があるかを学習できます。

動作を理解したうえで最後の差分を詰める場面では、この可能性が特にはっきりする。問うのは、このコンパイラがどの通常の書き方を観測された命令に変換するかだ。特化した学習によって候補を効率よく出せるかもしれないが、どの仮説が正しいかは対象のプログラムが決める。

ただし、パターンには適用条件を残す必要がある。TH08 は TH095 や TH09 より古い Visual C++ を使う。TH04 は DOS 時代の別のコンパイラを使い、プレイヤーのコードの再構築では、書き方や実行ファイルへのリンク順序について別の仮説が必要だった。同じ作者であることは手がかりになるが、適用できるかは各対象で確かめる。その区別も特化モデルが学ぶべきことだ。

その経験はどこに蓄積すべきか?

モデルの学習でこうしたパターンを覚えさせる前に、まずリポジトリに保存している知識を見たい。前のエッセイでは、リポジトリがプロジェクトの作業記憶になっていると書いた。そこにはコンパイラから学んだことと、それを裏付けるソースや失敗した実験が残っている。

そのレコードを取得することで、エージェントは既知の結果から開始し、どのようにしてその結果に到達したかを検査できます。また、同じコンテキストですでに失敗した代替案を回避することもできます。モデルのトレーニング済みパラメーターを変更することなく、開始点が改善されます。

TH09 の敵生成関数を再構築したGPT-6-Luna-max のセッションは、TH08 の関連するソースから仮説を得た。以前のコードが、ループの構成と失敗時の処理の手がかりになった。TH09 自体の証拠でゲーム固有の細部を補い、クリーンビルドで関数全体の一致を確認した。

「モデルがそのコンパイラの癖を知らない」と「知っていても使えない」は別の問題だ。 検索で前者を解決できても、知識を有用な候補にするには能力がいる。候補が失敗すれば、その結果が次の試みに何を意味するかも判断しなければならない。関連するパターンを知るのは、出発点にすぎない。

だから比較には、知識を適切に検索できる小さな汎用モデルも加えたい。同じ経験のライブラリを与えれば、学習が何を加えるかを調べられる。候補を作る力なのか、フィードバック後の判断なのか、それとも両方なのか。

次の有用な実験を選ぶ力を学ぶ

私が最も研究したいのは、フィードバック後の判断だ。エージェントによる再構築では、モデルが説明を提案し、プログラムに照らして検証する。候補が失敗しても、可能性を絞り、次の有用な実験を考える材料になる。

一時的な結果の例をもう一度考えてみましょう。最終的なソースには、機能した配置が示されていますが、そのソースへのルートにはさらに多くの情報が含まれています。以下の各実験は、まだ変更する必要があるものを特定するのに役立ちました。

実験 その結果が私たちに教えてくれたこと
別の方法で結果をコピーしてみてください コピーのコードは変わったが、関数にはまだ差分がある。
戻り値を直接使用する コピーは元のパターンに従いますが、一時ストレージは依然として異なります。
一時的な結果を同時に有効にしておく これらは別々のストレージを取得しますが、1 つは、後で衝突チェックに使用される値と依然として重複します。
衝突判定の値を独立させる ソースからクリーンに再コンパイルすると、完全に一致していることが確認されます。

上記の攻撃関数の再構築から選択した実験を、教えられた内容ごとにグループ化しました。

この順序を維持したトレーニング記録は、最終的なソースだけよりも多くのことを教えることができます。提案された各変更を観察された結果と次の決定に結び付けます。効果のないバリエーションを維持することも重要です。バリエーションは、後のエージェントに、そのコンテキストでどの仮説がすでにテストされているかを伝えます。

モデルにはフィードバックの使い方を学んでほしい。 結果が変わらなければ、その変更を考え直す理由になる。差分が変われば、別の原因が見えてくるかもしれない。局所的な編集から情報が得られなくなったら、全体の書き方を見直したり、証拠を再確認したりできるべきだ。

これらの選択を行うことを学ぶには自主性が必要です。場合によっては、別の編集をコンパイルするのではなく、別の呼び出し元を検査することが次のステップとして役立つ場合があります。必要な書き換えを厳密に繰り返すと、モデルに学習させたい動作の一部とともに、その選択肢が削除されてしまいます。

リバースエンジニアリングが強化学習にとって興味深い理由

範囲を定めた再構築は、こうした判断を研究するための実用的な環境になる。対象とコンパイラのバージョンを固定すれば、多くのソースの実験で素早く再現可能なフィードバックを得られる。エージェントは候補をコンパイルし、差分を調べ、次の行動を選べる。

強化学習なら、得られたフィードバックからこの判断を学習できるかもしれない。定義された検証を通った候補は具体的な成果になり、試行の記録から、そこに至るまでの労力も調べられる。

この方向を支える研究はすでにある。LLM4Decompileは逆コンパイルに特化したモデルを研究している。AutoDecompilerはコンパイルと実行のフィードバックを使って複数ターンの改善を学習する。両者が扱うのは機能の復元だ。私はそこを出発点に、当時のコンパイラの出力に一致するソースを探すという関連した課題を研究したい。

ただし、このように明確に定義されたタスクに到達するには、まず関数が所有するリソースを確立するか、実行中のプログラムの状態や振る舞いを観測する新しい方法を考案する必要があるかもしれません。たとえば、TH08 では、衝突の違いにより、元のプログラムでの浮動小数点計算の処理方法が問題になりました。エージェントが有用な補正をテストする前に、何を測定するかを決定する必要がありました。

ここから、幅広い能力を持つモデルのもう一つの役割が見える。まず問題を検証可能にすることだ。検証方法ができて初めて、学習した探索方針がどこまで進めるかを調べられる。

検証器が間違っていたら

その検証を使って学習すると、検証範囲も学習環境の一部になる。私はこうした参照基準や検証器を oracle と呼んでいる。答えが再現可能でも、それが何を確認した答えなのかを理解する必要がある。

TH08 では、検証範囲の外に問題が隠れていた。誤った浮動小数点定数を使っていても、完全一致の比較を通る関数があった。比較器は命令を確認する前に再配置されたアドレスを調整するが、そのアドレスが指す値まで確認するのは、検証対象として明示的に登録された場合だけだった。ほかの定数への参照は、値を調べずに通ってしまう可能性があった。

このギャップに対処するために、広範な監査により、すでに検証に合格した関数内に不正な定数が見つかりました。ある計算では、再構成されたソース コードでは 1.0f が追加されましたが、元のコードでは 32.0f が追加されました。

古い検証結果で報酬を与えれば、モデルは誤った再構築を学習してしまうかもしれない。 この検証器で RL モデルを訓練したわけではない。観測したのは検証そのものの不具合だ。ただ、それを報酬に使えば、同じ盲点が学習環境に入ることになる。

機能テストにも同様の盲点がある可能性があります。 LLM デコンパイラで差分ファジングを使用した研究では、提供されたテスト以外の動作の違いが見つかりました。したがって、合格したテストを、実行されるケースの観点から理解する必要があります。同様に、命令の一致は、検証されるバイトとデータの観点から理解する必要があります。

どちらの種類の検証チェックも報酬として使用する前に、意図的に間違った結果でテストします。また、最終的な承認は、AI エージェントが編集できるソース コードとは別にしておきます。モデルはプログラムを正しく再構築することで検証に合格する必要があります。そうしないと、ターゲットからバイト配列をコピーするだけで、有用なソース コードを回復せずに、単純なスコアリング システムを騙してしまう可能性があります。

学習するモデルの改善と、その検証器の改善は同じ研究課題だ。 モデルが与えられたフィードバックを上手に最適化するほど、そのフィードバックを理解することも重要になる。

実行する価値のある比較

これらのチェックを実施したら、固定の VC7.1 タスク ファミリで比較を開始します。まず、強力な汎用 AI モデルと小規模な AI モデルのベースラインを確立します。リポジトリの知識をより小さなモデルに追加すると、取得によってどのような変化が生じるのかがわかります。そこから、教師付き特殊化と RL でトレーニングされたバージョンを使用して、トレーニングによって追加される内容を検証できるようになります。

これらの比較を有益なものにするために、各モデルは同じターゲットの証拠とツールを受け取ります。トレーニング固有の比較の場合、基本モデルと利用可能な知識も固定したままにします。試行を繰り返すことは、信頼できる検索戦略と偶然成功した候補ソリューションを区別するのに役立ちます。

二つの出発点も分けたい。命令から関数を再構築する場合と、保守しているソースの最後の差分を詰める場合だ。特化モデルが後者に優れていても、そこまでの作業の多くは汎用モデルが担っているかもしれない。別々に測れば、その分担が見える。

どちらのタスクも、トレーニングと取得から除外されたテスト例が必要です。関連する Touhou ゲームはエンジン コードを共有します。トレーニングから 1 つのゲームを除外しても、トレーニング セットにほぼ同じ機能が残る可能性があります。代わりに、関連するソース コードのグループ全体を除外し、検証済みの回答をトレーニング データと検索ライブラリの両方から除外します。

測る成果は、関数全体が独立した検証を通って一致したことだ。候補数やコンパイル回数の予算をそろえれば探索の質を比べられる。コンパイルを含む総時間と総費用を測れば、それが効率的なワークフローにつながるかがわかる。学習費用は別に計上したい。

どちらの測定値も重要です。安価な提案により、有用な情報を提供しないコンパイルが増加すると、ワークフローが高価になる可能性があります。逆に、有用な実験がすぐに見つかった場合、遅いモデルの方が経済的になる可能性があります。比較にはこれらのコストも含める必要があります。

受け入れられた結果をカウントすることで、中間の進捗状況も把握できます。 1 つの TH09 再生保存候補は、コンパイルされた関数が予想どおりのサイズを持っていたため有望に見えましたが、完全な比較では依然として大きな違いが見つかりました。コンパイラが命令を配置する方法を変更すると、根本的な問題が解決されずに、候補がより近くに見える可能性もあります。このような診断は次の実験を導くことができますが、私は「近づく」ことに対する報酬を完全な受け入れチェックと照らし合わせて検証します。

結果全体にどんな傾向があるかを知りたい。特化モデルが使い慣れたコンパイラで優れていても、ツールチェーンを変えた後にその強みは残るだろうか。両方が十分に知識を検索できるとき、学習はどれだけ価値を加えるのか。答えは、各モデルをどこで使うべきかを考える助けになる。

どんなエージェントが必要なのか?

モデルが段階ごとに違う強みを持つなら、汎用エージェントが特化モデルを呼び出せる構成が役立つかもしれない。問題が慣れたコンパイラでの探索になったら、特化モデルに候補を求める。結果が納得できなくなったら、汎用エージェントが対象の証拠や測定そのものを調べ直す。

この構成では、特化モデルは調査の進み方に応じて選べる道具になる。エージェントには、以前の突破口を可能にした方向転換の自由が残る。

これは、前回のエッセイで説明した産業の変化から自然に生じます。さらに多くの実験を実行できるようになると、作業の組織化の方法が変わります。また、どの決定には広範な判断が必要なのか、どの決定は特定の技術での繰り返しの経験によって改善されるのかを尋ねる理由も得られます。

今のところ、未解決のまま残されていた問題を解決することで、最強の汎用 AI モデルが私のワークフローにその地位を獲得しました。これらの成功により、私はこの作業をさらに詳しく調べてみたいと思うようになりました。どの程度がモデルの範囲に依存しているのか、また、この特定の種類の再構成でトレーニングされたモデルでどの程度の処理が可能でしょうか?

リポジトリは、質問をテストする方法を提供します。その記録を使用して比較を構築し、何が分かるかを確認したいと思います。

証拠とモデルの帰属

詳しい証拠の記録には、比較結果と実験の背景をまとめている。

この例では、リンクされたコミットに記録された関数レベルの比較の履歴について説明します。ゲーム全体のランタイム チェックは別のマイルストーンです。ソースと一致する記録は 2026 年 10 月 13 日に確認されました。

TH09 ラベル gpt-dots は GPT-6-Astra を意味します。 gpt-web に関連付けられたモデルは時間の経過とともに変化したため、ラベルだけでは特定の実行で使用されたモデルを識別できません。他の引用されたコミット内の明示的なモデル名は、記録された帰属を示します。これらの履歴には、実行ごとのコストや労力の一貫した測定値は含まれていません。

特化モデルと RL の比較は、これから行いたい実験だ。プロジェクトの履歴がその動機になっているが、このエッセイで学習済みの特化モデルを評価したわけではない。

トップ