1. 程式人生 > >面向Windows的檔案透明加解密解決方案(3)——透明加解密驅動程式一

面向Windows的檔案透明加解密解決方案(3)——透明加解密驅動程式一

.透明加解密驅動程式:

3.1.Windows檔案系統及傳統檔案過濾驅動模型

 

  Windows 作業系統是基於分層思路設計的,每層由若干個元件組成。如圖2.1.1,Windows 作業系統簡化圖所示,Windows 作業系統總體上分為使用者層和核心層,核心層的介面對使用者層的應用程式提供服務。在使用者層,應用程式各自呼叫相應的Win32 子系統,Win32 子系統將應用程式呼叫的API 介面轉化為Native API 介面。在Native API 介面中呼叫轉化為對系統服務函式的呼叫,即Native API 穿過了使用者層和核心層的介面,到達了核心層,系統服務函式通過I/O 管理器將訊息傳遞給驅動程式。執行體元件提供了大量的核心函式供驅動程式呼叫,其中I/O 管理器負責發起I/O 請求,並且管理這些請求,使來自使用者層的I/O 請求獨立於裝置,無論是對埠的讀寫、對鍵盤的訪問,還是對磁碟檔案的操作都統一為IRP(I/O Request Packages)的請求形式,IRP 被傳遞到具體裝置的驅動程式,驅動程式負責“完成”這些IRP,之後將結果返回給使用者層的應用程式。圖2.1.2即展示了使用者應用程式在一個開啟了快取機制的檔案上的讀寫流程。



    傳統的檔案過濾驅動程式位於檔案系統驅動程式之上,截獲I/O 管理器傳送給檔案系統驅動程式的IRP 包。每個檔案系統驅動程式和過濾驅動程式都有唯一的控制裝置物件CDO(Control Device Object),檔案系統過濾驅動就是通過把自己的CDO 繫結到檔案系統驅動的CDO 上來實現截獲檔案系統驅動程式的IRP 包。由於Windows 作業系統核心異常複雜在傳統的過濾驅動模型中,開發者需要自己處理一系列系統機制的問題,例如建立資料結構來儲存處理物件的上下文資訊,新建併發送IRP 來查詢某些狀態,並且需要提供機制預防IRP重入,重入是指的是當前處理的請求會產生新的請求,然後這個請求又被過濾驅動捕獲到陷入遞迴的問題。於是微軟引入了一個新的檔案過濾驅動框架——Minifilter,用以解決傳統過濾驅動開發中的難題。

3.2Minifilter模型簡介

Minifilter基於Microsoft公司對於傳統型的檔案系統過濾驅動整合的基礎上提出的過濾管理器(Filter Manager)所提供的介面,使過濾驅動的開發具有了更好的魯棒性與可移植性。

2.2.1展示了WDK中提供的示例Minifilter模型的框架示意。


Minifilter框架與Legacy Filter框架比較:

l 相容性

Minifilter模型相對Legacy Filtersfilter模型具有更好的相容性,不僅僅指在和其它Filter共處時的相容性,它更多的是對Windows後續版本的相容性。隨著Windows XP系統即將退出歷史的舞臺,

Windows NT 6.X 系列各個版本相繼釋出,在實際的公司中往往多個版本的作業系統共存,基於Minifilter框架開發的檔案透明加密系統可以實現更好地相容性並且對於使用者其他行為的干擾也是較小

  • 檔案重入

檔案重入問題類似於死鎖,指驅動在處理某IRP請求時必須發出並且等待NewIRP的執行結果,而NewIRP又被髮送給了驅動本身,最終導致驅動陷入死迴圈之中而導致使用者的請求無法正確及時處理。在WDKWindows提供了IoCreateFileSpecifyDeviceObjectHint函式來實現直接向下層裝置開啟一個檔案物件,但是這個函式的相容性較差。而Minifilter中提供了這類介面有:FltCreateFileEx),FltReadFile 和 FltWriteFile等,較好地解決了檔案重入的問題。

  • 使用者態與核心態的雙向通訊機制

傳統的驅動程式與應用程式互動方式採取共享記憶體、事件驅動的非同步/同步通訊,通訊效率較低開發難度大。Minifilter有內建支援的通訊API並且建立了通訊埠方便使用者互動資訊。

  • 上下文的安全管理

傳統的檔案透明加密驅動中需要對於機密檔案進行計數處理(也就是上下文管理),但是由於Microsoft未公佈NTFS的原始碼,無法獲取NTFSFCB的結構體,使得對於FCB的計數與控制存在著一定的困難。Filter Manager 提供了上下文(context)來了解屬於自己的物件狀態,對於檔案一般使用流上下文(StreamContext)來追蹤,並且可以把對此檔案的操

作狀態作為標誌位記錄在流上下文中。初次開啟一個檔案物件時,通常呼叫FltAllocateContext 函式申請一塊記憶體區域,然後呼叫FltSetStreamContext 將其附著在這個檔案物件上,然後在在上下文中記錄一些有用的標誌位,在其他操作中可以根據這些標誌位對檔案物件進行適當的操作,每當處理完一個context 之後要呼叫FltReleaseContext 釋放這塊記憶體空間。