RealMode_Init。可檢測硬體、讀取 CMOS/BIOS、決定是否繼續載入、預留物理頁面。完成後段被丟棄。Init 代碼/數據段釋放,不可再訪問。任何階段返回 Carry Flag = 1 即可中止載入。
Simulate_Int/Simulate_IO 模擬中斷/I/O。Allocate_Phys_Memory 為設備預留物理頁 (如 DMA 緩衝區)。RM_INIT_STRUCT 告知 VMM:實例數、物理頁陣列、配置數據指針。VxD 不像 DLL 導出符號,而是通過 **服務號** 註冊:
// 定義服務 (汇编巨集)
BeginProc MyService, Service
mov eax, [esp+4] ; 參數1
; ... 處理
clc ; 成功
ret
EndProc MyService
// 服務表
VxD_Service_Table MyVxD_Services = {
{ SERVICE_ID_MYVXD, MyService }, // 服務號由 VMM 分配
{ 0, 0 }
};
// 其他 VxD 調用
mov eax, SERVICE_ID_MYVXD
mov ebx, 參數
int 20h
; 返回: CF=0 EAX=結果 / CF=1 EAX=錯誤碼
| 約定 | 服務名 | 參數傳遞 | 返回值 | 保存寄存器 |
|---|---|---|---|---|
| Register-based | 無前綴 | 通用寄存器 (EAX,EBX,ECX,EDX,ESI,EDI) | EAX (或 EDX:EAX) | 除返回值外全保存 |
| C-based | 以下劃線 _ 開頭 | 堆疊 (32bit 各參數) | EAX (或 EDX:EAX) | EBX, ESI, EDI, EBP, DS, ES, FS, GS |
異步服務 (Async_Service):可在中斷上下文調用,**必須可重入**,**不可呼叫非異步服務/阻塞 VMM 服務**。
Hook_V86_Int_Chain / Hook_PM_Fault:攔截 V86/保護模式中斷/異常。Simulate_IO / Hook_IO:攔截 IN/OUT 指令 (端口虛擬化)。PageHook:監控特定線性地址頁的讀/寫/執行 (實現斷點、影子記憶體、Copy-on-Write)。在 DDB 中填入 API_Entry_Table 指針,表項格式:
API_ENTRY MyAPIs[] = {
{ "OpenDevice", OpenDevice_Proc },
{ "CloseDevice", CloseDevice_Proc },
{ 0, 0 }
};
Ring 3 應用透過 VxDCall(0, ServiceID, ...) (需 vwin32.vxd 支援) 或 DeviceIoControl (配合 CreateFile("\\\\.\\VXDNAME")) 調用。
SYMFILE LOAD MYVXD.NMS (由 VToolsD 生成)。BPX MyVxD_Control — 所有控制消息入口。BPIO PORT — I/O 埠訪問斷點 (硬體斷點)。BPM ADDRESS — 記憶體讀寫斷點 (頁級)。BPEX INT_NUM — 中斷入口斷點。VM 指令查看/切換當前 VM;THREAD 查看執行緒。DR (寄存器)、D (記憶體)、U (反組譯)、G (運行)、P (單步過 Call)、T (單步進 Call)。CreateFile("\\\\.\\MYVXD", 0, 0, NULL, OPEN_EXISTING, FILE_FLAG_DELETE_ON_CLOSE, NULL) → VMM 載入 VxD,返回偽句柄;CloseHandle → 卸載。[Version]
Signature="$CHICAGO$"
Class=System
[DefaultInstall]
CopyFiles=VxD_Files
AddReg=VxD_Reg
[VxD_Files]
MYVXD.386
[VxD_Reg]
HKR,,DevLoader,,*vxd
HKR,,NTMPDriver,,MYVXD.386
HKLM,System\CurrentControlSet\Services\VxD\MYVXD,StaticVxD,,MYVXD.386
VxD 開發是對 x86 體系結構、Windows 內核調度、即時系統編程的綜合考驗。掌握初始化序列、服務機制、回調約束、調試技巧,即能駕馭 Ring 0 的無限權力。再次強調:**現代開發請轉向 WDF/KMDF/UMDF**,VxD 僅作歷史參考。