驅動開發(1)基礎知識
驅動程式是作業系統和硬體通訊的橋樑,同時,驅動程式可以實現很多特殊功能,比如,虛擬光碟機(虛擬裝置),核心級hook,檔案系統透明加密(過濾驅動),修改Windows核心等等
並非所有驅動程式都必須由裝置的設計方編寫。如果裝置根據已釋出的硬體標準來設計。這時驅動程式可以由 Microsoft 編寫,裝置設計者無須提供驅動程式。
並非所有的驅動程式都與硬體關聯。某些驅動程式與任何硬體裝置根本不關聯。 例如,如果需要訪問核心,或者實現虛擬裝置,過濾裝置等等,需要通過編寫驅動程式實現。提供一個使用者模式下執行且提供使用者介面的應用程式,還需要在核心模式下執行且可以訪問核心作業系統資料的驅動程式。這個驅動程式可以稱為“軟體驅動程式”。軟體驅動程式與硬體裝置不關聯。還有個例子是一些螢幕錄影軟體通過驅動程式直接讀取螢幕,而不是從應用層呼叫API截圖,實現硬體加速。
在正式開始介紹驅動開發之前,我們需要先來了解一下基本的概念。
1。驅動程式的執行級別
以核心模式驅動程式為例,使用者模式驅動是後來才有的。
其實intel 80x86提供了四個執行級別,R0,R1,R2和R3,現代主流作業系統,Windows自然也不例外,只用了R0和R3兩個執行級別,分別為“核心模式”和“使用者模式”。應用程式執行在使用者模式,驅動程式執行在核心模式。
這也就是說,驅動程式在執行的那一刻,就是天道!驅動程式中的指令,就是天道法則!(打個比方),所以說驅動程式執行時理論上可以做任何事情,RootKit病毒和防毒軟體都是利用的驅動程式。
2。Windows驅動程式的種類
windows9x時代,是VxD驅動,從NT的第一代開始到現在的Windows 10,windows逐漸出現了三種驅動程式模型,它們分別是:
1。遺留驅動:NT驅動程式:這是基礎的驅動模型,也是本系列博文著重介紹的驅動模型。
2。WDM驅動:為了支援裝置的熱插拔(比如USB裝置),微軟推出了WDM驅動,支援電源管理和即插即用
3。WDF驅動:有人說,如果WDM是Win32,WDF就是MFC。這個比喻還是比較恰當的。WDF驅動其實就是微軟又封裝了一些更方便的核心函式,使驅動開發更加便捷。另外WDF還提供了兩套機制,一種是核心模式驅動程式,一種是使用者模式驅動程式。
3。虛擬記憶體(虛擬地址空間)
驅動程式可以訪問整個4GB的虛擬記憶體,使用者程式只允許訪問低2G。
關於虛擬記憶體的分頁原理和Windows的記憶體管理機制,這裡不再介紹,有興趣的可以查閱相關資料
4。API的處理
在Win32子系統呼叫的API,會進一步呼叫在ntdll裡的Native API,Native API進入核心,呼叫系統的服務例程,被I/O管理器生成IRP併發送到裝置棧最上層的裝置物件所在驅動程式的派遣函式中,有可能會進一步向下層的驅動程式繼續傳送(比如過濾驅動),驅動程式完成任務。
5。同步與非同步
我對同步和非同步的理解,可能不是很準確:
同步:呼叫一個介面後,一直等待到被呼叫者處理完畢,再返回
非同步:呼叫一個介面後,不等待到被呼叫者處理完畢,直接返回,處理其他東西。
同步處理是驅動開發中的重要任務。Windows是支援非同步操作的作業系統,編寫驅動程式時,如果有必要,需要進行同步處理。
6。 裝置物件和裝置堆疊
“裝置物件”為 DEVICE_OBJECT 結構的一個例項。裝置堆疊是一系列裝置形成的和棧結構類似的東西,簡單說,磁碟裝置之上可能有磁碟過濾裝置,再上面是卷裝置,再上面可能有檔案系統過濾裝置,等等,IRP總是z先發送到裝置堆疊最上面一層的裝置中。
7。符號連線
一般的,對於NT驅動而言,應用程式不直接訪問裝置,而是訪問裝置的符號連線,比如第一個磁碟卷的裝置名是
“\Device\HarddiskVolume1”
其符號連線為:核心模式下
"\??\C:"
使用者模式下:
而我們的應用程式訪問的時候都是用符號連線。
對於WDM驅動,一般不使用符號連線,而是使用裝置介面。