首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 組合語言

VxD 程式設計實戰:攔截虛擬機建立/銷毀事件彈出訊息框

     編輯:組合語言

VxD 事件驅動模型

虛擬裝置驅動程式(VxD)在 Ring 0 執行,透過控制訊息分派器響應 VMM(虛擬機管理器)發送的系統事件。本範例示範靜態 VxD 攔截兩個關鍵虛擬機生命週期事件:

  • Create_VM:新虛擬機建立(如啟動 DOS 視窗)
  • VM_Terminate2:虛擬機銷毀(關閉 DOS 視窗)

核心服務:Shell_Message

VxD 可透過 VxDCall SHELL_Message 在指定虛擬機顯示訊息框(類似 Ring 3 的 MessageBox):

; 參數透過暫存器傳遞
EBX = 目標虛擬機控制塊 (VMCB) 線性位址 (即 VM handle)
EAX = 訊息框旗標 (MB_OK, MB_ICONEXCLAMATION 等,定義於 shell.inc)
ECX = 訊息字串 32-bit 線性位址
EDI = 標題字串 32-bit 線性位址
ESI = 回呼函數位址 (NULL 表示不需回呼)
EDX = 回呼函數參數
; 返回:CF=0 成功,CF=1 失敗

完整原始碼 (message.asm)

.386p
include vmm.inc
include shell.inc

; 裝置宣告:名稱 MESSAGE, 版本 1.0, 控制程序 MESSAGE_Control
DECLARE_VIRTUAL_DEVICE MESSAGE, 1, 0, MESSAGE_Control, UNDEFINED_DEVICE_ID, UNDEFINED_INIT_ORDER

; 控制訊息分派表
Begin_Control_Dispatch MESSAGE
    Control_Dispatch Create_VM,      OnVMCreate
    Control_Dispatch VM_Terminate2,  OnVMClose
End_Control_Dispatch MESSAGE

; 可分頁資料段
VxD_PAGEABLE_DATA_SEG
MsgTitle    db "VxD MessageBox", 0
VMCreated   db "A VM is created", 0
VMDestroyed db "A VM is destroyed", 0
VxD_PAGEABLE_DATA_ENDS

; 可分頁代碼段
VxD_PAGEABLE_CODE_SEG

BeginProc OnVMCreate
    mov  ecx, OFFSET32 VMCreated      ; 訊息字串
    jmp  CommonCode
EndProc OnVMCreate

BeginProc OnVMClose
    mov  ecx, OFFSET32 VMDestroyed    ; 訊息字串
    jmp  CommonCode
EndProc OnVMClose

CommonCode:
    ; 取得系統虛擬機控制代碼 (EBX 目前是新建立/銷毀的 VM,非系統 VM)
    VMMCall Get_Sys_VM_Handle         ; 返回 EBX = 系統 VM handle
    mov  eax, MB_OK + MB_ICONEXCLAMATION
    mov  edi, OFFSET32 MsgTitle
    xor  esi, esi                     ; 無回呼
    xor  edx, edx
    VxDCall SHELL_Message
    ret

VxD_PAGEABLE_CODE_ENDS
end

關鍵技術點解析

1. 控制訊息分派巨集

Begin_Control_Dispatch / Control_Dispatch / End_Control_Dispatch 自動產生控制程序入口點,將 VMM 發送的訊息 ID 對應到處理函數。VMM 會在適當時機呼叫 MESSAGE_Control,由巨集生成的跳轉表分派。

2. 記憶體段屬性選擇

段類型巨集特性適用場景
可分頁代碼VxD_PAGEABLE_CODE_SEG/ENDS可被換出至磁碟非即時、非中斷處理的一般函數
鎖定代碼VXD_LOCKED_CODE_SEG/ENDS常駐記憶體中斷處理、高優先級回呼、分頁錯誤處理
可分頁資料VxD_PAGEABLE_DATA_SEG/ENDS可分頁一般變數、字串
鎖定資料VXD_LOCKED_DATA_SEG/ENDS常駐中斷服務常式需存取的資料、共享緩衝區

本範例的訊息處理非即時,故置於可分頁段。

3. 系統虛擬機與 VM Handle

  • 每個虛擬機擁有唯一的 VM Handle(實為指向 VMCB 的 32 位線性位址)。
  • Create_VM / VM_Terminate2 到達時,EBX = 觸發事件的目標 VM Handle。
  • 若要在系統虛擬機(VMID=1,Windows GUI 環境)顯示訊息框,必須呼叫 VMMCall Get_Sys_VM_Handle 取得系統 VM Handle 覆蓋 EBX。

4. VMCB (虛擬機控制塊) 結構

cb_s STRUC
    CB_VM_Status      DD ?   ; VM 狀態旗標
    CB_High_Linear    DD ?   ; 系統共享區映射基址 (對應 VM 的 V86 區域)
    CB_Client_Pointer DD ?   ; Client Register Structure 指標 (被中斷程式的暫存器影像)
    CB_VMID           DD ?   ; VM 識別碼 (系統 VM = 1)
    CB_Signature      DD ?   ; "VMcb" 簽章,用於驗證 handle 有效性
cb_s ENDS

模組定義檔 (message.def)

指定段屬性與匯出符號,確保 VxD 正確載入:

VxD MESSAGE
SEGMENTS
    _LPTEXT  CLASS 'LCODE' PRELOAD NONDISCARDABLE
    _LTEXT   CLASS 'LCODE' PRELOAD NONDISCARDABLE
    _LDATA   CLASS 'LCODE' PRELOAD NONDISCARDABLE
    _TEXT    CLASS 'LCODE' PRELOAD NONDISCARDABLE
    _DATA    CLASS 'LCODE' PRELOAD NONDISCARDABLE
    CONST    CLASS 'LCODE' PRELOAD NONDISCARDABLE
    _BSS     CLASS 'LCODE' PRELOAD NONDISCARDABLE
    _LMGTABLE CLASS 'MCODE' PRELOAD NONDISCARDABLE IOPL
    _LMSGDATA CLASS 'MCODE' PRELOAD NONDISCARDABLE IOPL
    _IMSGTABLE CLASS 'MCODE' PRELOAD DISCARDABLE IOPL
    _IMSGDATA CLASS 'MCODE' PRELOAD DISCARDABLE IOPL
    _ITEXT   CLASS 'ICODE' DISCARDABLE
    _IDATA   CLASS 'ICODE' DISCARDABLE
    _PTEXT   CLASS 'PCODE' NONDISCARDABLE
    _PMSGTABLE CLASS 'MCODE' NONDISCARDABLE IOPL
    _PMSGDATA CLASS 'MCODE' NONDISCARDABLE IOPL
    _PDATA   CLASS 'PDATA' NONDISCARDABLE SHARED
    _STEXT   CLASS 'SCODE' RESIDENT
    _SDATA   CLASS 'SCODE' RESIDENT
    _DBOSTART CLASS 'DBOCODE' PRELOAD NONDISCARDABLE CONFORMING
    _DBOCODE CLASS 'DBOCODE' PRELOAD NONDISCARDABLE CONFORMING
    _DBODATA CLASS 'DBOCODE' PRELOAD NONDISCARDABLE CONFORMING
    _16ICODE CLASS '16ICODE' PRELOAD DISCARDABLE
    _RCODE   CLASS 'RCODE'
EXPORTS
    MESSAGE_DDB @1

建置與部署

編譯連結指令

ml -coff -c -Cx -DMASM6 -DBLD_COFF -DIS_32 message.asm
link -VxD -def:message.def message.obj
  • -VxD:連結器產生 VxD 格式 (LE 可執行檔)
  • -def:指定模組定義檔

安裝步驟

  1. 將 message.vxd 複製到 C:\WINDOWS\SYSTEM\
  2. 編輯 C:\WINDOWS\SYSTEM.INI,在 [386Enh] 區段加入:
    device=message.vxd
  3. 重新開機

測試驗證

  • 開啟 MS-DOS 提示字元視窗 → 應彈出 "A VM is created"
  • 關閉該視窗 → 應彈出 "A VM is destroyed"

進階延伸方向

  1. 動態 VxD:在 .def 中加入 DYNAMIC 關鍵字,配合 CreateFile("\\.\vxdname.vxd") 從 Ring 3 載入/卸載,無需修改 SYSTEM.INI 重開機。
  2. Ring 3 通訊:實作 W32_DeviceIoControl 處理函數,配合 DeviceIoControl 實現雙向資料交換。
  3. 攔截更多事件:VM_Suspend/VM_Resume (暫停/繼續)、Destroy_VM、Device_Init 等。
  4. 硬體存取:透過 Hook_V86_Int_Chain、Set_PM_Int 攔截中斷,實現硬體監控或虛擬化。

總結

本範例展示了 VxD 開發的核心流程:裝置宣告、控制訊息分派、段屬性管理、VMM/VxD 服務呼叫、共享資料處理、建置部署。雖然 Windows 9x 已退出歷史舞台,但 VxD 架構對理解 Windows 核心設計、Ring 0 程式設計、虛擬化技術仍具極高參考價值。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved