---
title: 逆向工程需要更大的模型嗎？ | REA
url: https://rea.tools/zh-TW/blog/reverse-engineering-models/
---

[首頁](https://rea.tools/zh-TW/) / [部落格](https://rea.tools/zh-TW/blog/) / 模型與逆向工程

隨筆

# 逆向工程需要更大的模型嗎？

作者 N0zoM1z0 · 2026 年 10 月 13 日

要點

- **模型能力會影響 agent 能提出哪些假設。** 後來的工作解決了早期嘗試未能解決的問題。
- **熟悉的編譯器為專用模型提供了具體的學習對象。** 有些精確匹配依賴細小但可以複用的原始碼模式。
- **也要公平評估程式碼倉庫裡的知識。** 較小的模型配合良好的檢索，可能已經掌握了足以推進工作的知識。
- **訓練模型選擇下一個有價值的實驗，同時檢驗它使用的驗證器。** 回饋是否有用，取決於驗證器究竟檢查了什麼。
- **結合時間和成本，評估透過驗證的重建成果。** 這是我希望從整個 agent 工作流程中獲得的結果。

## 更強的模型改變了什麼

從 2026 年 8 月開始，我一直在探索：如果給 agent 訪問程式的能力，以及驗證自身工作的手段，它能獨立完成多少逆向工作？我的經驗主要來自遊戲重建，尤其是東方系列。隨著我更換模型，程式碼倉庫記錄了每次工作還原出的內容。

這些工作很大一部分追求精確重建：用固定版本的歷史工具鏈編譯我們維護的原始碼，檢查它能否復現目標函式。當後來的模型解決了早期工作卡住的問題，我們可以從原始碼變化中看出，是什麼促成了這次進展。

### 臨時值需要同時保持有效

TH09 中一個攻擊函式的大部分邏輯已經還原，但編譯器對臨時結果的儲存安排仍然與原版不同。剩下的問題在於：這些結果的生命週期應該多長，編譯器何時可以複用它們的儲存空間？

[GPT-6-Sol 的一次工作記錄](https://github.com/N0zoM1z0/th09/commit/de63c0f9121963f3a6b1ab5471c4878625fd3425)表明，嘗試幾種常見的原始碼寫法後，差異仍未消除。後來，[GPT-6.1-Sol 重新研究這個問題](https://github.com/N0zoM1z0/th09/commit/52929ed7c299f1a5f29cc13964e22510145fd616)，提出了一個有價值的假設：關鍵可能在於這些臨時值的生命週期。

這個函式會產生臨時結果，再把它們複製到動畫的位置資料中。在 C++ 中，臨時結果會一直存在，直到使用它的表示式執行完畢。把實際操作放進同一個表示式，就能讓這些結果同時存活，編譯器也就不能為它們全部複用同一塊儲存空間。

其中一個結果仍然與稍後用於碰撞檢查的值共享儲存。給那個值單獨的生命週期後，最後一處重疊也消失了。經過幾次有針對性的實驗，**一次乾淨的重新構建確認，整個函式都已匹配**。

我感興趣的是，發現與驗證如何共同推進工作。生命週期的假設給 agent 指明瞭新方向；編譯器的回饋又幫助它逐步調整原始碼，直到找到匹配的寫法。

### 換一種控制流結構

TH09 的另一個函式說明了，新方向為什麼重要。這次的難點是多個分支如何共享末尾的操作。[GPT-6.1-Sol 之前的工作](https://github.com/N0zoM1z0/th09/commit/f8d12d72aaf02212ee1b585a8f3f86d7ed000269)已經讓函式的一些部分匹配，但分支匯合的方式仍與原版不同。

[GPT-6-Astra 改寫了外圍的控制流圖](https://github.com/N0zoM1z0/th09/commit/da33a646221198ceb7f3df2b96e2ca0e9b2f705f)，讓主要路徑匯入共同的最終更新與返回。在這種原始碼結構下，編譯器合併分支的方式與原版一致。整個函式實現了匹配，[另一次獨立的重新構建也確認了這一結果](https://github.com/N0zoM1z0/th09/commit/5f825b28a862f8e1a6d4aea2f78a42f04c09a1c0)。

**換一種表達方式，開啟了更有價值的搜尋空間。** 這兩個例子讓我認真看待通用模型的能力：agent 可能花很長時間嘗試局部變化，才找到一種更好的整體寫法。

不過，後來的工作也繼承了之前的原始碼和失敗記錄。這些積累本身就是優勢的一部分。歷史記錄讓我們可以檢查發現及其驗證過程；要區分模型能力和繼承經驗各自帶來的幫助，還需要對照實驗。

這正是我覺得有趣的地方。有些進展來自新的表達方式，剩下的大量工作則是在熟悉的編譯器上試驗不同寫法。其中有多少需要廣泛的推理能力？又有多少可以透過反覆接觸這個編譯器和這些程式碼來學會？

## 為什麼專用模型可能做得很好？

東方系列給了我們一個具體的理由，去期待經驗積累能發揮作用。大量遊戲程式碼出自同一個作者 ZUN，因此，把反覆出現的程式設計習慣作為初始假設是合理的。程式碼倉庫也提供了實際例子：相似的迴圈和輔助函式組織方式，曾為其他遊戲的重建提供假設。

把編譯器也考慮進去，這些原始碼模式就更加具體了。在固定版本和選項下，原始碼的小變化可能穩定地產生不同的機器碼。其中一些規律藏得很深。

以 TH095 為例，**連局部變數的名字，都可能改變 VC7.1 為它安排的儲存位置**。只移動宣告並不能解決佈局問題，但先前重建的一個背景函式揭示了會影響編譯器選擇的命名模式。這為[重建 `Supervisor::LoadDat`](https://github.com/N0zoM1z0/th095/commit/26bb64bdb093a13f73abd0ee8ae7ce199ee4658f)提供了更有希望的假設。

把這個模式用於表示檔案大小的變數，不增加額外儲存就得到了所需佈局。隨後，整個函式實現了匹配。

這類細節非常具體，通用模型第一次接觸時未必知道。而針對這個編譯器訓練的專用模型，可以接觸許多類似案例，學會哪些原始碼變化值得優先嚐試。

當我們已經理解函式行為，只剩最後的匹配差異時，這個機會尤其明顯。此時的問題是：這個編譯器會把哪一種普通寫法編譯成眼前的指令？專用訓練可能讓模型更高效地提出這些寫法，而最終由目標程式決定哪些假設成立。

但這些模式必須保留適用的上下文。TH08 使用的 Visual C++ 版本早於 TH095 和 TH09。TH04 用的是另一種 DOS 時代的編譯器，其[玩家邏輯重建](https://github.com/N0zoM1z0/th04/commit/6dce0a79d5b931f0e2a08475b90e0c33d2321b98)需要不同的假設，既涉及原始碼寫法，也涉及編譯後的程式碼如何連結成可執行檔案。同一作者為我們提供了先驗，具體目標則告訴我們它是否適用。區分這些情況，也是專用模型需要學會的事。

## 這些經驗應該存在哪裡？

在決定透過訓練讓模型學會這些模式之前，我會先看看程式碼倉庫裡已有的知識。在[上一篇文章](https://rea.tools/zh-TW/blog/touhou-reconstruction/)中，我寫過：倉庫正在成為專案的工作記憶。這裡儲存著對編譯器的認識，也儲存著相關原始碼和失敗實驗，讓這些經驗有據可查。

檢索這些記錄後，agent 可以從已知結果出發，看看我們是如何得到它的，也可以避開在相同條件下已經失敗的方案。模型的參數沒有改變，工作的起點卻提高了。

重建 TH09 的敵人生成函式時，[GPT-6-Luna-max 的一次工作](https://github.com/N0zoM1z0/th09/commit/1eb843383941d00065622a9e353146c4bb96979e)從 TH08 對應的原始碼中找到了假設。之前的寫法提示了迴圈該如何組織，以及內部失敗該如何處理。TH09 自身的證據補上了遊戲特有的細節，乾淨的重新構建確認了整個函式的匹配。

**“模型不知道這個編譯器特性”和“模型不會利用它”，是兩個不同的問題。** 檢索可能解決前者，但把知識變成有價值的候選原始碼，仍然需要能力。如果候選方案失敗了，模型還得判斷這次結果對下一次嘗試意味著什麼。知道相關模式，只是這個過程的起點。

所以，在任何對照實驗中，我都會加入一個具備良好檢索能力的小型通用模型。給它相同的經驗庫，才能看清訓練究竟增加了什麼：更好的候選方案、更好的回饋後決策，還是兩者都有？

## 學習選擇下一個有價值的實驗

回饋之後如何決策，是我最想研究的部分。在 agent 驅動的重建中，模型提出解釋，再用程式來驗證。即使候選方案失敗了，結果也可能縮小剩餘的可能性，提示下一步更值得嘗試什麼。

再看前面的臨時結果例子。最終原始碼展示了成功的寫法，但得到它的過程包含更多資訊。下面的每次實驗，都幫助我們確定了還有什麼需要改變。

| 實驗 | 結果告訴了我們什麼 |
| --- | --- |
| 嘗試另一種複製結果的方式 | 複製程式碼改變了，但函式仍有差異。 |
| 直接使用回傳值 | 複製方式與原版一致，但臨時儲存佈局仍有差異。 |
| 讓臨時結果同時保持有效 | 它們得到了各自的儲存空間，但其中一個仍與稍後用於碰撞檢查的值重疊。 |
| 讓碰撞檢查的值擁有獨立儲存 | 乾淨的重新構建確認了整個函式的匹配。 |

選自前面攻擊函式的重建實驗，按每次得到的認識整理。

儲存這個過程的訓練記錄，比單獨儲存最終原始碼能教會模型更多東西。它把每個改動、觀察到的結果和下一步決策聯絡起來。無效的嘗試也值得保留：後來的 agent 可以據此知道，在這個上下文中，哪些假設已經檢驗過。

**我希望模型學會如何利用回饋。** 結果沒有變化，可能意味著該重新考慮這個改動；差異發生變化，則可能指向另一個原因。當局部修改不再提供有效資訊時，agent 應該可以重新考慮原始碼的整體表達，或者回頭檢查證據。

學會這些選擇，需要自主性。有時，更有價值的下一步是檢查另一個呼叫者，而不是再修改一次原始碼並編譯。如果強制按照固定順序改寫，就會剝奪這種選擇，也失去一部分我們希望模型學會的行為。

## 為什麼逆向工程值得用來探索強化學習

範圍明確的重建任務，為研究這些選擇提供了一個實際環境。目標和編譯器版本固定之後，許多原始碼實驗都能快速給出可重複的回饋。agent 可以編譯候選原始碼、檢查差異，再根據觀察選擇下一步。

強化學習可以利用這些回饋，訓練模型的決策過程。候選原始碼透過明確定義的檢查，就給出了一個具體成果；而嘗試的過程，讓我們可以看到實現它花了多少功夫。

已有研究支援這個方向。[LLM4Decompile](https://aclanthology.org/2024.emnlp-main.203/)研究專門用於反編譯的模型。[AutoDecompiler](https://arxiv.org/html/2606.16162v1)利用編譯和執行回饋，訓練多輪改進能力。這些研究關注的是功能還原。對於我們的工作，我會以它們為起點，研究一個相關任務：找到能復現歷史編譯器輸出的原始碼。

不過，要得到這樣一個定義明確的任務，有時得先確定函式負責哪些資源，或者設計新的方法觀察程式執行時的行為。在 TH08 中，[一次碰撞差異最終追溯到原版處理浮點計算的方式](https://github.com/N0zoM1z0/th08/commit/af9cb1d3e839b15a78b47ac1701506083cc82847)。agent 必須先弄清楚該測量什麼，才能驗證有價值的修正。

這提示了能力全面的模型的另一個作用：先把問題變得可驗證。驗證手段建立起來後，我們才可以研究，學出來的搜尋策略能走多遠。

## 當驗證器出錯時

一旦用某項檢查來訓練模型，它的覆蓋範圍就會成為學習環境的一部分。我把這種參考標準或驗證器稱為 oracle。即使它能給出可重複的答案，我們也必須知道，這個答案覆蓋了什麼。

TH08 展示了檢查範圍之外可能藏著多少問題。一些重建函式使用了錯誤的浮點常量，卻仍然透過了精確比較。比較器會先調整重定位地址，再檢查指令；但只有明確登記過的常量，才會進一步檢查地址指向的值。其他常量引用，即使值沒被檢查，也可能透過。

為了補上這個漏洞，[一次更全面的審計](https://github.com/N0zoM1z0/th08/commit/a393f400786e4cc6cbb1000af0dad3276da12c78)在已經透過檢查的函式中找到了錯誤常量。有一個計算中，重建原始碼加的是 `1.0f`，而原版加的是 `32.0f`。

**如果用舊檢查的結果作為獎勵，模型可能學會生成錯誤的重建原始碼。** 我們沒有用這個驗證器訓練 RL 模型；實際觀察到的是檢查本身的漏洞。但如果把它用作獎勵，同一個盲點也會進入學習環境。

功能測試也可能存在類似盲點。[針對 LLM 反編譯器的差分模糊測試研究](https://arxiv.org/html/2609.05370v1)發現，在已有測試之外，程式行為仍可能不同。因此，理解“測試透過”時，必須看它實際覆蓋了哪些情況；理解“指令匹配”時，也必須看它檢查了哪些位元組和資料。

在把任何一種檢查用作獎勵之前，我都會用刻意構造的錯誤來測試它。我還會把最終驗收機制放在候選原始碼可修改的範圍之外，讓模型透過正確重建來滿足檢查。否則，直接複製目標程式的位元組陣列，也可能騙過簡單的評分，卻沒有還原出有用的原始碼。

**改進模型和改進它的驗證器，屬於同一個研究問題。** 模型越擅長最佳化我們給它的回饋，我們就越需要理解回饋本身。

## 值得做的對照實驗

具備這些檢查之後，我會從一組固定的 VC7.1 任務開始比較。先為強通用模型和小型通用模型建立基線，再給小模型加入倉庫知識，觀察檢索帶來的變化。接著比較監督訓練的專用模型，以及在此基礎上進行 RL 訓練的版本，看看訓練增加了什麼。

為了讓比較有意義，每個模型都應獲得相同的目標證據和工具。專門比較訓練效果時，還要固定基礎模型和可用知識。重複實驗有助於區分可靠的搜尋策略與偶然成功的候選方案。

我還會區分兩種起點：從指令開始重建函式，以及在已有原始碼中消除最後幾處差異。專用模型可能很擅長後者，而通用模型承擔了到達這個階段的大部分工作。分別評估，才能看清這種分工。

兩類任務都需要真正未見過的測試案例。東方系列的相關遊戲會共享引擎程式碼，只留出某個遊戲，仍可能讓幾乎相同的函式進入訓練集。我會改為按相關原始碼家族留出測試集，並把它們透過驗證的答案同時排除在訓練資料和檢索庫之外。

在這些案例上，要統計的是完整、獨立驗證過的匹配成果。給每個模型相同的候選數量或編譯次數預算，可以比較搜尋品質。記錄總耗時和總成本，包括編譯，才能知道這種品質是否轉化成了高效的工作流程。訓練成本也要單獨計算。

兩種角度都重要。一個便宜的提議，如果導致大量無效編譯，整個工作流程仍可能很貴。反過來，較慢的模型如果更早找到有價值的實驗，也可能更划算。對照實驗應當反映這些成本。

只統計透過驗收的結果，也能幫助我們合理看待中間進展。TH09 的一個[錄影儲存候選方案](https://github.com/N0zoM1z0/th09/commit/ab72fd77728293fc0beacfc656ca701b0e266016)看起來很有希望，因為編譯後函式的大小符合預期，但完整比較仍發現大量差異。編譯器改變指令排列，也可能讓候選原始碼看起來更接近，卻沒有解決根本問題。這些診斷可以指導下一步，但若要獎勵“變得更接近”，我會先對照完整驗收檢查，確認這種獎勵有效。

我想看這些結果呈現出什麼規律。如果專用模型在熟悉的編譯器上表現很好，換了工具鏈後，這種優勢還在嗎？當雙方都擁有良好的檢索能力時，訓練還能增加多少價值？這些答案能幫助我們決定，每類模型最適合用在哪裡。

## 這意味著怎樣的 agent？

如果不同模型在不同階段各有所長，一種有價值的安排可能是：讓能力全面的 agent 可以呼叫專用模型。當任務變成一種熟悉的編譯器搜尋時，它可以請專用模型提出候選方案。如果結果開始說不通，通用 agent 可以回頭檢查目標證據，或者調查測量本身。

在這樣的安排中，專用模型成為 agent 隨著調查進展可以選擇的工具。agent 仍然擁有改變方向的自由，而這正是前面那些突破發生的重要條件。

這自然延續了上一篇文章中談到的工業化轉變。能夠開展更多實驗，會改變我們組織工作的方式，也讓我們有理由追問：哪些決策需要全面的判斷，哪些可以透過反覆積累某項具體技藝來改善？

目前，最強的通用模型解決了我過去沒能解決的問題，因此在我的工作流程中佔據了一席之地。正是這些成功，讓我想更仔細地研究過程：有多少依賴模型能力的廣度？又有多少可以交給專門學習這類重建的模型？

**這些程式碼倉庫讓我們有機會驗證這個問題。** 我想利用這些記錄建立對照實驗，看看我們能學到什麼。

證據與模型歸屬

[詳細證據記錄](https://github.com/morluto/rea/blob/main/website/evidence/reverse-engineering-models.md)包含歷史比較結果與實驗背景。

這些例子來自連結中的提交中記錄的歷史函式級比較。整款遊戲的執行時檢查屬於另一個里程碑。相關原始碼與匹配記錄核查於 2026 年 10 月 13 日。

TH09 中的標籤 `gpt-dots` 對應 GPT-6-Astra。`gpt-web` 會隨當時使用的模型變化，因此僅憑這個標籤無法確定某次執行的具體模型。其他引用提交中的明確模型名，提供了對應的歸屬記錄；這些歷史記錄並沒有統一的單次執行成本或投入統計。

- **TH09 臨時值生命週期：**[早期上下文檢查](https://github.com/N0zoM1z0/th09/commit/de63c0f9121963f3a6b1ab5471c4878625fd3425)與[完整的乾淨重建](https://github.com/N0zoM1z0/th09/commit/52929ed7c299f1a5f29cc13964e22510145fd616)。
- **TH09 Front 回呼：**[未匹配的診斷區域](https://github.com/N0zoM1z0/th09/commit/f8d12d72aaf02212ee1b585a8f3f86d7ed000269)、[Astra 提出的新控制流圖](https://github.com/N0zoM1z0/th09/commit/da33a646221198ceb7f3df2b96e2ca0e9b2f705f)與[透過驗收的重新編譯檢查](https://github.com/N0zoM1z0/th09/commit/5f825b28a862f8e1a6d4aea2f78a42f04c09a1c0)。
- **編譯器知識：**[TH095 識別符號分桶規律的複用](https://github.com/N0zoM1z0/th095/commit/26bb64bdb093a13f73abd0ee8ae7ce199ee4658f)、[TH04 玩家原始碼與連結順序](https://github.com/N0zoM1z0/th04/commit/6dce0a79d5b931f0e2a08475b90e0c33d2321b98)、[Luna 完成的 TH09 敵人生成函式匹配](https://github.com/N0zoM1z0/th09/commit/1eb843383941d00065622a9e353146c4bb96979e)。
- **檢查與診斷：**[TH08 浮點常量審計](https://github.com/N0zoM1z0/th08/commit/a393f400786e4cc6cbb1000af0dad3276da12c78)、[TH08 數值問題調查](https://github.com/N0zoM1z0/th08/commit/af9cb1d3e839b15a78b47ac1701506083cc82847)、[TH09 錄影儲存重建](https://github.com/N0zoM1z0/th09/commit/ab72fd77728293fc0beacfc656ca701b0e266016)。

文中提出的專用模型與 RL 對照，屬於未來實驗。專案歷史為這些想法提供了依據；本文尚未評估經過訓練的專用模型。
