系列的最後一篇:DLL開發完成後怎麼安全測試、常見崩潰怎麼排查,以及測試通過後如何打包成玩家能直接使用的發布版本。
建立獨立的測試環境
永遠在和正式遊戲目錄分開的資料夾測試:
C:\MapleTest\ ← 測試環境(只在這裡測)
├── MapleStory.exe
├── dinput8.dll ← 剛編譯的登入器
├── config.ini ← 開啟Debug選項
└── *.wz
還在除錯階段的DLL可能讓遊戲行為異常,直接在正式目錄測試可能損壞設定或影響帳號資料。
設定檔開啟Debug模式,能看到即時日誌:
[Debug]
ShowConsole = true
VerboseLog = true
開啟後遊戲啟動會跳出一個控制台視窗,顯示如下訊息,方便確認執行到哪一步:
[MainMain] Waiting for Themida depack...
[MainMain] Themida depack complete.
[Config] Server: 127.0.0.1:8484
[Hook] Hook_CreateMutexA installed
[Client] Resolution set to 1280x720
常見崩潰排查
遊戲載入DLL時立刻崩潰(點擊exe後視窗一閃就消失):先確認是Release/x86編譯而非Debug/x64;確認控制台日誌有沒有出現「Failed to load original dinput8.dll」(代表Proxy找不到真正的系統DLL);確認使用的exe版本MD5和登入器支援的版本一致。
卡在載入畫面不動:最常見原因是 WaitForThemida() 的等待條件永遠不成立。可以加入超時保護和診斷輸出:
while (*(BYTE*)CHECK_ADDR != 0x55) {
Sleep(100);
elapsed += 100;
if (elapsed > 10000) {
std::cout << "[Error] Themida wait timeout. Current byte: 0x"
<< std::hex << (int)*(BYTE*)CHECK_ADDR << std::endl;
break;
}
}
特定操作後崩潰(能進遊戲,但登入/選角/進地圖時崩潰):用動態除錯工具在崩潰當下查看Call Stack,找到第一個屬於我們DLL的函式。
除錯工具
| 工具 | 用途 |
|---|---|
| x64dbg(選x32版本) | 動態除錯:設中斷點、查暫存器、追蹤崩潰時的Call Stack |
| Cheat Engine | 記憶體驗證:確認寫入的值是否真的到達目標地址 |
| Process Monitor | 檔案系統追蹤:確認config.ini是否被正確讀取、WZ載入順序 |
| std::cout 日誌 | 最快速的手段:在關鍵位置印出執行進度,確認卡在哪一步 |
附加x64dbg到已執行中的遊戲時,Themida可能偵測到偵錯器並讓遊戲崩潰,可以搭配 ScyllaHide 外掛隱藏偵錯器的存在。
Access Violation 診斷思路
最常見的崩潰代碼是 0xC0000005(存取不存在或無權限的記憶體):
1. 確認崩潰地址是否在exe的.text section有效範圍內
2. 若Hook安裝後立刻崩潰 → 檢查JMP的相對偏移是否算錯
3. 若呼叫Trampoline時崩潰 → 檢查被覆蓋的原始指令是否被完整複製(有沒有截斷多byte指令)
4. 若普通Memory::Write後崩潰 → 確認目標地址在記憶體中確實存在且已解壓縮
測試清單
基礎功能:DLL成功載入/視窗以正確解析度出現/連到私服而非官方伺服器
登入流程:UI元素位置正確/帳密輸入正常/登入按鈕可點擊
選角流程:角色名稱等級顯示正確/角色位置平均分布
遊戲內:HUD位置正確/角色可正常移動攻擊/NPC對話視窗正常
穩定性:運行10分鐘無崩潰/換地圖3次無崩潰/開背包裝備視窗無崩潰
打包發布
Release x86 編譯設定
工具列切換為 Release + x86——誤用x64編譯的話,遊戲會報錯「不是有效的Win32應用程式」直接拒絕載入。
Runtime Library 務必選對:Project Properties → C/C++ → Code Generation → Runtime Library,選 Multi-threaded (/MT) 靜態連結CRT,不要選 /MD。靜態連結讓玩家不需要另外安裝Visual C++ Redistributable,DLL能完全自給自足。
打包內容
MapleEzorsia-v2_vX.X.zip
├── dinput8.dll ← 編譯好的登入器(Release x86)
├── config.ini ← 預設設定檔(IP填私服位址)
└── README.txt ← 安裝說明
不包含:MapleStory.exe(版權問題,玩家自行取得)、.pdb 除錯符號檔(避免暴露原始碼細節)、自訂WZ資源(另外打包或提供下載連結)。
給玩家的README重點:把 dinput8.dll 和 config.ini 放進遊戲資料夾(和MapleStory.exe同一層)、用記事本打開config.ini修改ServerIP為私服位址、直接雙擊MapleStory.exe啟動(不需要另外的啟動器)。
版本管理
建議用語意化版本(v2.1.3 = Major.Minor.Patch)。不是所有更新都需要重新逆向找地址:
| 變更 | 需要重新逆向? |
|---|---|
| 私服更換IP | 不需要(只改ini) |
| 解析度bug修正 | 不需要(改程式邏輯,地址不變) |
| 私服升級exe版本 | 需要(所有地址可能整批改變) |
可以在DLL啟動時驗證exe的MD5,版本不符就顯示錯誤退出,避免玩家誤用錯誤版本的exe:
if (!VerifyGameVersion()) {
MessageBoxA(NULL, "Incompatible MapleStory.exe version.", "Version Mismatch", MB_ICONERROR);
ExitProcess(1);
}
系列回顧
到這裡,登入器原始碼開發系列的核心內容全部完成:
DLL劫持原理與環境建置 → 專案結構與編譯首個DLL → 記憶體操作與Hook技術
→ Client.cpp解析度與UI修正 → 進階功能與設定系統 → 測試除錯與打包發布
已經足夠讓你理解、修改、並發布一個完整的DLL登入器。如果還想繼續深入 MapleStory 引擎內部的型別系統(ZXString、ZRef、防作弊安全型別等),屬於更進階、寫自訂Hook才需要的選讀內容,不在這個系列的範圍內,有興趣可以自行從 MapleEzorsia-v2 原始碼裡的 MapleClientCollectionTypes 資料夾開始研究。
想回顧整個登入器主題的其他路線,可以回到 登入器教學總覽。