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

VxD 程式設計入門指南:架構、初始化、控制訊息與段管理完整解析

     編輯:組合語言

VxD 兩大類型:靜態與動態

特性靜態 VxD動態 VxD
載入時機系統開機 (由 VMM 載入)執行期隨需載入 (CreateFile, VxDCall)
載入觸發1. INT 2Fh/1605h 呼叫
2. 登錄鍵值 StaticVxD
3. SYSTEM.INI [386Enh] device=
1. 放入 \SYSTEM\IOSUBSYS (IO 子系統)
2. VxDCall VxD 動態載入服務
3. Ring 3 CreateFile("\\.\vxdname.vxd")
初始化訊息Sys_Critical_Init → Device_Init → Init_CompleteSys_Dynamic_Device_Init (僅此一項)
卸載訊息System_Exit2 → Sys_Critical_Exit2Sys_Dynamic_Device_Exit
轉換方法—在 .def 加入 VxD NAME DYNAMIC

靜態 VxD 初始化序列詳解

  1. Sys_Critical_Init:VMM 進入保護模式、開啟中斷前發送。用途:搶佔中斷向量、為後載入 VxD 提供服務。中斷尚未開啟,執行必須極快。
  2. Device_Init:中斷已開啟,大多數 VxD 在此完成主要初始化(配置記憶體、掛鉤中斷、建立執行緒等)。
  3. Init_Complete:所有 VxD 的 Device_Init 完成、初始化段 (ICODE/RCODE) 即將釋放前發送。極少數 VxD 需處理。

初始化失敗必須設定 Carry Flag 並返回錯誤碼,VMM 將中止該 VxD 載入。

卸載序列與「2」後綴意義

卸載順序與初始化順序相反(後載入先卸載),確保依賴關係安全:

  • System_Exit2:Windows 關機,僅剩系統 VM,CPU 仍在保護模式,Kernel32.dll 已卸載。
  • Sys_Critical_Exit2:所有 VxD 處理完 System_Exit2、中斷關閉後發送。準備切換回實模式。

舊版 System_Exit/Sys_Critical_Exit 不保證反初始化順序,可能導致依賴服務已卸載而崩潰。新版 VxD 必須使用帶「2」的版本。

常見系統控制訊息分類

類別訊息說明
虛擬機管理Create_VM新 VM 建立 (EBX = 新 VM handle)
VM_Critical_InitVM 關鍵初始化
VM_Suspend / VM_ResumeVM 暫停/繼續 (切換焦點時)
Close_VM_NotifyVM 即將關閉通知
Destroy_VMVM 銷毀完成
VM_Terminate / VM_Terminate2VM 終止 (Terminate2 為新版)
...其他:電源管理、除錯、檔案系統等

VxD 應選擇性處理感興趣的訊息,忽略其他。

函數定義與段管理

段宣告巨集

; 代碼段
VXD_LOCKED_CODE_SEG     ; 鎖定代碼段 (常駐)
VXD_PAGEABLE_CODE_SEG   ; 可分頁代碼段 (可換出)
VXD_STATIC_CODE_SEG     ; 靜態代碼段 (初始化後丟棄)

; 資料段
VXD_LOCKED_DATA_SEG
VXD_PAGEABLE_DATA_SEG
VXD_STATIC_DATA_SEG

原則:中斷處理、高優先級回呼、分頁錯誤處理 → 鎖定段;一般功能 → 可分頁段。

函數定義巨集

BeginProc MyFunction
    ; 函數主體
EndProc MyFunction
  • 自動處理堆疊框架、暫存器保存、符號匯出
  • 支援參數:BeginProc MyFunc, HIGH_PRIORITY 等屬性
  • 優於傳統 PROC/ENDP,提供更完整的 VxD 運行期支援

VxD 程式設計約定

暫存器使用規範

  • 可自由使用:EAX, ECX, EDX, EBX, ESI, EDI, EBP, ESP, 旗標暫存器
  • 嚴禁修改:CS, SS(除非極度確定後果)
  • 可修改但必須恢復:DS, ES, FS, GS
  • 方向旗標 (DF) 與中斷旗標 (IF) 修改後必須恢復
  • 不得長時間關閉中斷 (CLI)

參數傳遞慣例

類型呼叫方式參數傳遞返回值命名慣例
暫存器呼叫VMMCall / VxDCall暫存器 (EAX, EBX, ECX, EDX, ESI, EDI, EBP...)暫存器 (通常 EAX, 旗標 CF)無前綴 (如 Get_Sys_VM_Handle)
堆疊呼叫VMMCall _Service堆疊 (右至左 push)EAX底線前綴 (如 _HeapAllocate)

巨集語法:

VMMCall ServiceName           ; 暫存器呼叫
VMMCall _StackService,   ; 堆疊呼叫,參數用角括號包圍

位址運算:OFFSET32

早期 MASM 版本 offset 在 VxD 產生錯誤位址,故引入 OFFSET32 巨集(等同 offset flat:)。現代 MASM 6.14+ 已修正,但為相容性建議仍使用 OFFSET32。

動態 VxD 載入機制詳解

Ring 3 透過 CreateFile 載入

.data
VxDName db "\\.\MyDynamic.vxd", 0

.code
invoke CreateFile, addr VxDName, 0, 0, 0, 0, FILE_FLAG_DELETE_ON_CLOSE, 0
mov hDevice, eax
; ... 使用 DeviceIoControl 通訊 ...
invoke CloseHandle, hDevice  ; FILE_FLAG_DELETE_ON_CLOSE 觸發卸載
  • 路徑格式:\\.\VxD完整路徑名
  • FILE_FLAG_DELETE_ON_CLOSE:關閉控制代碼時自動卸載 VxD

動態 VxD 必須處理的訊息

  • W32_DeviceIoControl:首次 CreateFile 觸發,返回 EAX=0 表示成功;後續 DeviceIoControl 也發送此訊息。
  • 初始化:Sys_Dynamic_Device_Init
  • 卸載:Sys_Dynamic_Device_Exit

動態 VxD 載入後,享有與靜態 VxD 相同的權限(除初始化/卸載訊息不同)。

開發建議與最佳實務

  1. 開發階段用 SYSTEM.INI 載入:出錯可在 DOS 模式下編輯恢復;登錄載入失敗無法進入系統。
  2. 善用可分頁段:減少鎖定記憶體壓力,提升系統效能。
  3. 共享資料段需明確宣告:.def 中 CLASS 'LCODE' ... SHARED 或連結器 /SECTION:.bss,S。
  4. 中斷處理極簡原則:ISR 僅做必要硬體操作,其餘延遲至執行緒/工作項處理。
  5. 驗證 VM Handle:使用 CB_Signature == "VMcb" 確認有效性。
  6. 除錯工具:WDEB386 (串口核心除錯器)、SoftICE (已停止更新但傳奇級工具)。

總結

VxD 是 Windows 9x 核心擴充機制,直接運行於 Ring 0,擁有最高權限。掌握其初始化/卸載序列、控制訊息分派、段屬性管理、暫存器呼叫慣例、動態載入機制,是進行 9x 核心層開發、逆向工程、安全研究的基石。雖然 NT 內核採用 WDM/KMDF 架構,但 VxD 的許多設計哲學(分層、服務導向、動態載入)在現代驅動模型中仍有回響。

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