程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> 關於C++ >> 使用Windows虛擬設備驅動程序(VxD)之2

使用Windows虛擬設備驅動程序(VxD)之2

編輯:關於C++

八、VxD初始化

VMM初始化一個VxD時做下列工作:

1、裝載實模式初始化段並調用實模式初始化過程。該過程可以完成阻止裝載VxD,阻止啟動Windows,指定設備實例數據和在內存中選擇頁面給

設備專用的工作。

2、裝載VxD其它段到32位平坦內存模式的保護模式內存,並丟棄實模式初始化段。

3、發送Sys_Critical_Init消息到設備控制過程。禁止硬件中斷,所以VxD應該盡可能地用較少的時間完成自身初始化。

4、發送Device_Init消息到設備控制過程。允許硬件中斷,所以必須准備讓VxD管理來自設備的中斷。

5、發送Init_Complete消息到設備控制過程。

6、丟棄初始化代碼和數據段,釋放其它被使用的內存。VxD不能在處理完Init_Complete消息以後試圖存取這些段中的過程和數據。

在初始化過程中的任何時刻,VxD都可以設置進位標志返回到VMM以阻止裝載VxD。部分VMM服務,例如初始化信息服務只在初始化過程中有效。

九、實模式初始化

任何靜態設備驅動程序都可以提供實模式初始化過程以在Windows切換到保護模式之前執行初始化任務。VMM裝載VxD時調用該過程,該過程檢查

有關的Windows環境,包括注冊表和初始化文件中的有關設置以判斷是否應該裝載該VxD。該過程也可以給Windows返回信息以為每個虛擬機的實

例指定物理內存頁保留給設備專用和數據項地址。要獲得關於實模式初始化的更多信息,請參閱相關資料。

十、VxD服務

VxD可以提供服務功能(函數或過程——譯者注)給VMM和其它VxD使用。這些服務讓其它VxD可以直接訪問該VxD的特征,允許測試和修改該VxD的功能和能力。

VxD不能和Windows DLL一樣引出函數,代之的是VMM通過INT 20H提供到VxD服務的動態鏈接,該中斷處理過程使用服務編號判斷支持服務的

VxD,該中斷處理過程也使用服務編號查詢在VxD服務表中的服務地址。

下面的內容講述怎樣在VxD中定義服務,聲明VxD服務表以及從一個VxD向另一個VxD中引入服務。

1、定義服務

VxD使用BeginProc和EndProc宏以及Service和Async_Service選項定義服務。宏標記服務過程代碼的開始和結束,選項標識該過程是一個服務。

下面的實例給出了VSAMPLED_Get_Version服務的定義:

BeginProc VSAMPLED_Get_Version, Service

mov ax, 030Ah

clc

ret

EndProc VSAMPLED_Get_Version

Async_Service選項標識該服務可以被異步調用,也就是說在處理中斷的過程中調用。異步服務必須是可重入的,而且不能調用VMM和不是異步服

務的VxD服務。

VMM和標准VxD對服務使用兩種調用約定:基於寄存器的調用約定和基於32位C語言的調用約定。這兩種調用約定有不同的服務名格式,參數傳遞

和返回值方法以及寄存器保護。

對於基於寄存器的服務,服務名不應該以下劃線(_)開頭,所有的參數通過寄存器傳遞,結果也通過寄存器返回,服務保護所有不顯式用於返回

值的寄存器。

對於基於C語言的服務,服務名必須以下劃線(_)開頭,所有的參數通過堆棧中的32位值傳遞,結果(如果存在)通過EAX寄存器(32位值)

或者EAX和EDX寄存器(64位值)返回,服務保護EBX、ES、FS和GS寄存器以及ESI和EDI寄存器,只有標志寄存器和EAX、EBX、EDX寄存器被修改。

2、聲明服務

VxD使用Begin_Service_Table和End_Service_Table宏聲明服務。宏標記包含服務名和可選的包含服務的段名的列表的開始和結束。聲明必須建

立在進行VxD定義的文件中(也就是說在包含Declare_Virtual_Device宏的文件中),而且必須先進行設備指定符號的定義。下面的實例給出了

一個實例VxD——VSAMPLED的服務表聲明:

Create_VSAMPLED_Service_Table equ 1

Begin_Service_Table VSAMPLED

VSAMPELD_Service VSAMPLED_Get_Version, Local

VSAMPLED_Service VSAMPLED_Service_1

VSAMPLED_Service VSAMPLED_Service_2, VxD_ICODE

End_Service_Table VSAMPLED

上例中,Create_VSAMPLED_Service_Table符號在緊接服務表聲明之前定義,指定Begin_Service_Table宏為VSAMPLED創建服務表。聲明開始以

後,VSAMPLED_Service宏定義實際服務,這個宏是Begin_Service_Table宏創建的,只在服務表聲明中有效。每個服務名必須與服務定義名,也就

是BeginProc宏給出的名字完全符合。

當聲明服務時,如果一個服務定義在包含服務表聲明的文件中,必須在服務名後使用LOCAL選項,也就是說如果不使用LOCAL選項,服務表自動聲

明一個服務是外部服務。上例中,VSAMPLED_Get_Version服務定義在包含服務表聲明的文件中。

與之相似,如果一個服務不是定義在VxD_CODE段中,必須在服務名後注明段名。上例中,VSAMPLED_Service_2服務定義在VxD_ICODE段中。

服務聲明的順序是很重要的。VxD中第一個被聲明的服務必須是Get_Version服務(該服務清除進位標志並在AX寄存器中返回VxD版本號),任何加入VxD的新服務必須定義在服務表的末尾(或者定義在服務表中顯式保留的空間中)。由於VMM依靠服務在服務表中的順序正確鏈接

服務,在服務表中間插入一個新服務需要VxD使用的所有VxD服務被重建。

為了方便,服務表聲明應該放在一個包含文件中,使得其它VxD可以通過包含該文件引入服務而不需要重新聲明。

3、引入服務

一個VxD可以通過包含另一個VxD的服務表聲明引入另一個VxD的服務,在這種情況下,設備指定符號的定義不能先於該服務表聲明(參見上一節

的講述)。例如:VSAMPLED.INC文件包含VSAMPLED服務的服務表聲明,一個包含該文件的VxD可以調用這些服務。VxD使用VMMcall宏調用VMM服

務,使用VxDcall宏調用VxD服務。

由於計算機配置不同,一個VxD可能會在Windows啟動時裝載失敗,這說明使用其它VxD提供的服務的VxD必須檢驗其它VxD服務在調用它們之前

是否有效。為了檢驗服務,調用服務的VxD必須嘗試調用提供服務的VxD的Get_Version功能,如果VxD沒有裝載,VMM會設置進位標志並在AX寄

存器中返回0。

十一、VxD API過程

一個VxD提供V86模式和保護模式API過程以允許在一個虛擬機中運行的應用程序和其它軟件訪問該VxD的特征。如果要使這些可選的過程有效,

VxD必須將它們定義為Declare_Virtual_Device宏的參數,如果沒有定義,VMM認為該VxD沒有API過程。

在一個虛擬機中運行的應用程序或者其它軟件通過設置BX寄存器為VxD標識並調用獲取設備入口地址功能(INT 2FH 1684H功能)獲取特定的虛

擬機的API過程的入口地址,VMM返回該地址使得應用程序可以間接調用該API過程。

當一個應用程序調用該入口地址時,VMM保存該應用程序的寄存器並調用VxD相應的API過程,保存當前虛擬機的句柄到BX寄存器中並保存

Client_Reg_Struc結構地址到EBP寄存器中。API過程必須檢測客戶寄存器的值(使用Client_Reg_Struc結構)以判斷運行的API調用。

按照常規,大多數API過程使用AH寄存器指定主功能號,使用AL寄存器指定次功能號,其它客戶寄存器用於附加參數。API過程通過修改客戶寄

存器返回值,API過程可以修改EAX、EBX、ECX、EDX、ESI和EDI寄存器。

下面的實例給出了一個實例API過程——VSAMPLED_API_Get_Version:

BeginProc VSAMPLED_API_Get_Version

movzx eax, [ebp.Client_AX] ;取功能號

or eax, eax

jnz Undefined

Get_Version:

mov [ebp.Client_AX], 030AH ;在客戶寄存器AX中返回值

and [ebp.Client_Flags], NOT CF_Mask ;清除進位標志

ret

Undefined:

or [ebp.Client_Flags], CF_Mask ;設置進位標志

ret

EndProc VSAMPLED_API_Get_Version

十二、VxD INT 2FH功能

VxD可以通過為INT 2FH中斷安裝回調過程提供INT 2FH功能。INT 2FH功能允許在一個虛擬機中運行的應用程序和其它軟件在VxD不提供API過

程的情況下訪問VxD,例如,標准虛擬顯示設備支持與Windows顯示驅動程序通信的INT 2FH功能集合。

Windows安裝自己的INT 2FH中斷處理程序支持各種功能,以允許MS-DOS 設備驅動程序和TSR在Windows啟動或者虛擬機運行過程中執行特定動作。要獲得有關這些功能的更多信息,請參閱有關資料。

十三、建立一個VxD

應該通過進行下列步驟來建立一個VxD:

1、創建VxD源文件並用32位平坦模式匯編器MASM.EXE(MASM 6.11以上——譯者注)匯編源文件。

2、創建模塊定義文件(DEF文件)並用32位平坦模式連接器LINK.EXE連接目標文件。按照常規,結果可執行文件應該有與VxD相同的文件名,文

件擴展名為VXD。

3、用MAPSYM.EXE為可執行文件創建調試信息。

VxD並不與Windows動態鏈接庫兼容,基於Windows的應用程序並不能直接裝載和使用VxD,然而,基於Win32的應用程序可以通過使用CreateFile

和DeviceIoControl函數裝載動態裝載的VxD和與之相互作用。VxD模塊定義文件有以下格式:

LIBRARY VSAMPLED

DESCRIPTION 'VSAMPLED Device (Version 4.0)'

EXETYPE DEV386

SEGMENTS

_LTEXT PRELOAD NONDISCARDABLE

_LDATA PRELOAD NONDISCARDABLE

_ITEXT CLASS 'ICODE' DISCARDABLE

_IDATA CLASS 'ICODE' DISCARDABLE

_TEXT CLASS 'PCODE' NONDISCARDABLE

_DATA CLASS 'PCODE' NONDISCARDABLE

EXPORTS

VSAMPLED_DDB @1

LIBRARY語句必須指定一個與在已知設備描述塊(DDB)中相同的VxD名字,EXPORT語句必須指定一個DDB的名字,在任何情況下,DDB引出序號都是1。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved