承接上篇 LE 格式與架構基礎,本文深入實戰:靜態與動態 VxD 的載入機制、初始化/結束控制訊息處理、函數建構慣例、呼叫慣例與位址運算,助您撰寫可正常運作的 VxD 核心模組。
INT 2Fh AX=1605hHKLM\System\CurrentControlSet\Services\VxD\key\StaticVxD=路徑SYSTEM.INI [386Enh] 區段:device=路徑(開發建議,易於 DOS 下修復)| 訊息 | 時機 | 用途 | 處理建議 |
|---|---|---|---|
Sys_Critical_Init | VMM 進入保護模式、開啟中斷前 | 搶佔中斷向量、初始化其他 VxD 依賴的服務 | 極速完成,避免硬體中斷遺失 |
Device_Init | 中斷已開啟 | 大多數初始化工作(硬體偵測、記憶體配置等) | 可執行耗時操作 |
Init_Complete | 所有 VxD 完成 Device_Init、釋放 ICODE/RCODE 前 | 極少數 VxD 需要(如最終資源檢查) | 可選處理 |
回傳值規則:EAX=0 成功;非零 = 錯誤碼 → VMM 終止載入。
System_Exit2:Windows 關機,僅剩系統 VM,CPU 仍在保護模式,Kernel32 已卸載。Sys_Critical_Exit2:中斷關閉後,準備轉實模式。Device_Reboot_Notify2 / Crit_Reboot_Notify2:重開機通知(中斷開啟/關閉)。「2」尾碼表示反初始化順序發送(先載入的後結束),保證相依服務仍可用。舊版無「2」訊息不保證順序,新版 VxD 應忽略。
; .DEF 檔
VXD MYVXD DYNAMIC ; 僅加上 DYNAMIC 關鍵字
\WINDOWS\SYSTEM\IOSUBSYS\:由 IOS 載入,需支援分層驅動,非通用。CreateFile:最通用,應用程式呼叫 CreateFile("\\.\Path\To\VxD.vxd", ..., FILE_FLAG_DELETE_ON_CLOSE, 0),關閉控制代碼即卸載。Sys_Dynamic_Device_Init:首次 CreateFile 載入時(取代靜態三階段)。Sys_Dynamic_Device_Exit:最後一個控制代碼關閉時。W32_DeviceIoControl:CreateFile 成功後首次觸發,必須處理並回傳 EAX=0;後續 DeviceIoControl 也送此訊息。除上述三訊息外,動態 VxD 仍接收所有系統控制訊息(VM 建立/銷毀、電源管理等)。
VxD_LOCKED_CODE_SEGVxD_PAGEABLE_CODE_SEG(預設最佳選擇)VxD_PAGEABLE_CODE_SEG
BeginProc MyFunction
; 函數本體
; 可加參數:BeginProc MyFunction, CCALL, PUBLIC
EndProc MyFunction
VxD_PAGEABLE_CODE_ENDS
BeginProc/EndProc 取代傳統 PROC/ENDP,支援呼叫慣例、參數聲明、堆疊框架自動建構。CCALL:C 呼叫慣例(參數由呼叫者清理堆疊),W32_DeviceIoControl 回呼必須使用。DF 與中斷旗標 IF:修改後必須恢復,不可長時間關閉中斷。| 類型 | 命名特徵 | 參數傳遞 | 回傳值 | 範例 |
|---|---|---|---|---|
| 暫存器呼叫 | 無底線開頭 | 暫存器 | 暫存器 | VMMCall Service |
| 堆疊呼叫 | 底線開頭 _Service | 堆疊(右→左) | EAX | VMMCall _Service, <arg1, arg2> |