1. 程式人生 > >Sfilter過濾驅動框架

Sfilter過濾驅動框架

原理

Sfilter框架是基於NT驅動框架之上通過裝置棧繫結的形式繫結的,驅動自己生成一個裝置(過濾裝置物件),呼叫系統提供的繫結API,繫結到目標裝置上。並返回一個在未繫結之前目標裝置所在裝置棧的最頂層裝置。這樣發往下層的IRP或者發往上層的資料都會被過濾裝置截獲。

移動裝置連結到系統中時系統會為其生成一個檔案系統裝置,然後系統會向檔案系統裝置傳送mount IRP,檔案系統裝置接收到IRP後會動態生成卷裝置物件【碟符】

如果要監控移動裝置卷裝置物件,首先要先生成過濾裝置物件繫結到移動裝置的檔案系統裝置物件上攔截mount IRP請求,之後在該IRP內生成過濾裝置物件繫結到卷裝置物件上【兩次繫結操作】

IoRegisterFsRegistrationChange函式可註冊一個動態監控移動裝置物件插入時生成檔案系統裝置物件的回撥函式

關於固定的卷裝置物件可直接通過函式一一枚舉出來,然後依次生成過濾裝置物件繫結上去即可。

實現

函式主流程

首先建立控制裝置和符號連結用於與R3客戶端通訊。然後註冊過濾分發函式【內部對客戶端IRP和其他程序IRP分開處理】

分配一個Fastio結構體大小的記憶體,然後對其內部初始化Fastio的操作函式【內部全部返回False,不新增會有問題,只需要簡單的禁用處理即可】之後將該結構體註冊到DriverObject->FastIoDispatch中。

接下來通過IoRegisterFsRegistrationChange註冊監控檔案系統裝置建立的回撥函式。函式內判斷裝置插入時,生成過濾裝置物件繫結到對應的檔案系統裝置物件上【通過判斷系統版本使用繫結函式】用來監控mount IRP【回撥函式參1為監控到到檔案系統裝置物件,參2為bool值表示檔案系統是插入還是拔掉。函式內建立的過濾裝置物件會和檔案系統裝置物件通訊方式一樣(通過依次判斷的方式實現)】

當監控到發往檔案系統裝置上的mount IRP時就會呼叫Sfilter中指定的分發函式【IRP分發函式中的IRP_MJ_FILE_SYSTEM_CONTROL】函式內部會生成過濾裝置物件繫結到對應的卷裝置物件上【IRP->MinorFunction(次功能號)為IRP_MN_MOUNT_VOLUME(mount)時就呼叫定義的附加函式。函式內部生成了過濾裝置物件,由於卷裝置物件要等mount下發到檔案裝置物件後才能建立,所以要用IoSetCompletionRoutine為mount設定一個完成例程然後用IoCallDriver下發。之後等待例程完成然後從檔案裝置物件裝置擴充套件中拿到卷裝置物件之後作為繫結引數繫結(xp前的版本使用工作者執行緒繫結,原因是mount會提升IRQL)】

FileMon函式中通過列舉26個碟符,開啟檔案獲取FileObject->DeviceObject,通過驅動生成過濾裝置繫結到DeviceObjec上【無法監控動態載入的移動裝置】

fastio時Cache manager【快取管理】的一部分,必須為DriverObject撰寫一組函式,函式指標在driver->FastIoDispatch裡,函式內部不作處理簡單的返回False即可。

分發函式處理細節
函式中共有兩個過濾驅動裝置,根據R3客戶裝置和卷裝置的過濾裝置分別編寫處理流程。IS_MY_CONTROL_DEVICE_OBJECT巨集可判定是否為控制裝置,IS_MY_DEVICE_OBJECT巨集可判定是否為過濾裝置

然後通過sfDebug的標誌判斷過濾過程中所需要抓取的資訊【儲存在登錄檔中,DriverEntry中有從登錄檔獲取的操作】不需要抓取則會直接IoSkipCurrentIrpStackLocation放行IRP並用IoCallDriver下發。否則分配記憶體空間呼叫NLGetFullPathName獲取檔名稱,然後呼叫IoCopyCurrentIrpStackLocationToNext將當前IRP棧拷到下一層IRP棧上,建立事件後IoSetCompletionRoutine設定完成例程,並用IoCallDriver下發。等待完成例程修改事件後將檔名稱打印出來。

最後通過IRP下發結果繼續處理並完成。一般IoCallDriver下發之後就不能對IRP進行操作了【不再關心,否則藍屏】,但通過設定完成例程並讓完成例程返回STATUS_MORE_PROCESSING_REQUIRED可以通知IO管理器在底層處理完IRP後不去銷燬。而上層【即本層】呼叫IoCopyCurrentIrpStackLocationToNext拷貝棧並通過IoCallDriver下發後等待完成例程更改的事件狀態繼續執行,最後在本層結束IRP。通過該方法可在下發IRP後繼續對IRP進行處理

注意
檔名稱只有在建立檔案時是可靠的,所以獲取檔名稱操作只能在Create分發函式中做。

過濾驅動IRP處理方式有三種:
1.通過IoCopyCurrentIrpStackLocationToNext+完成例程+IoCallDriver等待處理完成
2.通過IoSkipCurrentirpStackLocation+IoCallDriver忽略直接下發。下層裝置拿到的棧和當前棧一樣【該函式會將棧指標++操作,IoCallDriver會對棧指標–操作】
3.通過IoGetCurrentirpStackLocation獲取當前棧然後設定irp的IoStatus中的Status【成功STATUS_SUCCESS或失敗STATUS_ACCESS_DENIED】和Information【操作位元組數】最後通過IoCompleteRequest結束IRP停止下發

繫結API:
IoAttachDevice()
IoAttachDeviceToDeviceStackSafe(2000 SP4以及XP以上)
IoAttachDeviceToDeviceStack()

PDEVICE_OBJECT //返回該函式繫結前最頂層的裝置物件
IoAttachDeviceToDeviceStack(
IN PDEVICE_OBJECT  SourceDevice,//指定裝置物件
IN PDEVICE_OBJECT  TargetDevice //目標裝置物件
);//該函式將指定裝置物件繫結到目標裝置物件上,使用時注意儲存原頂層裝置物件用於處理後下發

基於Sfilter的HIPS放行規則

IRP過濾函式規則
FilterCreate:該函式內攔截檔案的建立和開啟,而且要在該檔案內獲取檔案的全路徑
FilterRead:主防中不攔截,加解密時需要攔截
FilterWrite:函式內攔截修改,加解密時需要攔截
FileterSetInfo:函式內攔截刪除和重新命名
FilterClose:讀關閉一般不攔截
FilterClean:函式內攔截寫關閉【重新掃描檔案防止多次寫入,Sfilter無法判斷讀關閉或寫關閉】

其他規則
放行核心請求:通過Irp->RequestorMode==KernelMode識別
放行本程序請求:通過FilterDeviceloctrl中使用PsGetCurrentProcessId獲取PID識別
放行系統程序請求:通過DriverEntry中使用PsGetCurrentProcessId獲取PID識別【DriverEntry運行於系統上下文】
IRQL大於APC級別:KeGetCurrentIrql()>APC_LEVEL

放行使用IoSkipXXX+IoCallDriver方式即可

其他

Deubug除錯過濾驅動時可使用以下命令:
!devobj 檢視裝置物件資訊
!drvobj 檢視驅動物件資訊
!devstack 檢視裝置棧
!devnode 0 1 系統裝置樹

程式碼

//

相關推薦

Sfilter過濾驅動框架

原理 Sfilter框架是基於NT驅動框架之上通過裝置棧繫結的形式繫結的,驅動自己生成一個裝置(過濾裝置物件),呼叫系統提供的繫結API,繫結到目標裝置上。並返回一個在未繫結之前目標裝置所在裝置棧的最頂層裝置。這樣發往下層的IRP或者發往上層的資料都會被過濾裝

一個簡單的檔案系統過濾驅動框架

 很多人認為檔案系統過濾驅動很複雜,其實也有一定道理,因為需要有很多細節需要考慮到,這是一個簡單的檔案系統過濾驅動,拋去了大部分細節,留下了一個簡單的框架,其實這樣檔案系統過濾驅動就變得蠻簡單的,很多介面可以不用實現,只要知道大致流程,其它都將會很清晰。#define DBG

整理一份我對Windows檔案系統過濾驅動sFilter工程程式碼的詳細說明(精華僑)

標 題: 【分享】整理一份我對Windows檔案系統過濾驅動的sFilter工程程式碼的詳細說明 作 者: tianhz 時 間: 2012-06-19,18:32:07 鏈 接: http://bbs.pediy.com/showthread.php?t=1523

linux設備驅動之misc驅動框架源碼分析(一)

linux驅動開發misc設備驅動 1、misc設備驅動框架源碼部分是由內核開發者實現提供的,主要是創建misc類和為驅動開發者提供misc_register函數,來進行創建misc設備。 這部分的源碼在/drvier/char/misc.c裏,代碼如下:/* * linux/drivers/c

linux設備驅動之misc驅動框架源碼分析(二)

linux驅動開發misc設備驅動1、misc_open函數分析 該函數在driver/char/misc.c中,misc.c是驅動框架實現的,這裏面的misc_Open函數是misc驅動框架為應用層提供的一個打開misc設備的一個接口。 1、首先我們要知道在misc.c中的misc_init函數

linux驅動摸索 --驅動框架初始化(結合韋東山視頻教程)

boa kernel cde targe 一個 自動 comm argv ops 一.驅動框架 初始化:insmod 加載 1.確定主設備號: 分為靜態和動態分配,其中LED_GPIO_SIZE 表示支持的次設備號數目,一般默認為1. 相關

I2C子系統驅動框架及應用 (轉)

sent cal fcm tran 中一 table same print style I2C子系統驅動框架: 應用程序層(app層) ——————————————————————————————————– i2c driver層: 從設備驅動層(TS Senso

Lind.DDD敏捷領域驅動框架~介紹

原創 bbb dnn art pdh dtd 刪除 too nim Lind.DDD敏捷領域驅動框架~介紹 qq 2589406800 qq1399494644 qq2128543647 qq2890083872 qq3235634116 qq3381945576 q

SPI驅動框架-1(DM8127 Linux2.6.37為例)

orm span remove mac 設備 single 隊列 drive for 一、驅動程序結構 1、platform_device 文件:/arch/arm/mach-omap2/device.c static struct omap2_mcspi_platfor

5.4.1.何謂驅動框架

特殊 1.2 調用 解釋 所有 出接口 如果 標準化 開發工程師 本節主要解釋了什麽是驅動框架,為什麽需要驅動框架,基於驅動框架寫驅動有什麽優勢等問題。 5.4.1.1、驅動是誰寫的 (1)驅動開發工程師 (2)內核維護者 5.4.1.2、驅動編程協作要求 (1)接口標準化

5.7.5.framebuffer驅動框架總覽

這就是我 write lcd 是什麽 sun 設備 詳細 png 定義 參考http://www.cnblogs.com/EaIE099/p/5175979.html 本節對內核的framebuffer驅動框架做整體介紹,各部分涉及哪些文件,每個文件是誰寫的,具體功能是什麽

5.7.6.framebuffer驅動框架分析1

iop 之間 write ioctl 程序 硬件 struct 於平 完成 http://www.mamicode.com/info-detail-1209620.html 5.7.6.1、fbmem_init函數[driver/video/fbmem.c] (1)#ifd

linux驅動開發(三) 字符設備驅動框架(自動創建設備節點)

The module __line__ mage fail goto div on() sys 代碼如下 #include <linux/init.h> #include <linux/module.h> #include <linux/ke

46.Linux-分析rc紅外遙控平臺驅動框架,修改內核的NEC解碼函數BUG(1)

進入 checksum 開始 紅外遙控 中斷函數 height clas margin 復習 內核版本 : Linux 3.10.14 rc紅外接收類型: GPIO 類型的NEC紅外編碼 本章內容 1) rc體系結構分析 2)

clk子系統 - 驅動框架

clk子系統負責為整個系統硬體提供時鐘訊號,這個要和linux的時鐘系統區別開來;現在的ASoC上包含許多clk模組,比如晶振,pll,divider等,那麼clk子系統就把這些模組抽象出來,並形成一個驅動框架,這樣對於其他驅動開發人員來說,只需要呼叫通用的介面就能操作各自裝置的

linux音訊子系統 - 驅動框架

音訊相關術語 PCM(Pulse Code Modulation) 脈衝編碼調製,對連續變化的模擬訊號進行抽樣、量化和編碼,在驅動中一般音訊流裝置都稱為pcm裝置 I2S I2S是對PCM格式的資料進行規範化,可以說是PCM的子集,I2S只有左右兩通道資料 T

linux裝置驅動模型 - 驅動框架

linux驅動模型框架如圖所示: 1. kernfs 驅動最終是提供給使用者層使用,那麼其中的介面就是通過kernfs檔案系統來註冊,kernfs是一個通用的核心虛擬檔案系統 2. sysfs/kobject sysfs是裝置驅動檔案系統,裝置之間的各種關係會在在/

linux 裝置驅動 nand驅動框架

nand 裝置驅動(一)架構 使用mini2440 - nand 1. nand硬體 1.1 資源 LDATD0~7資料線和地址線是複用的,都是8位 既可以傳輸資料(命令或者資料), 也可以傳送地址訊號 訊號說明: CLE: 命令鎖存, 高表示cmd ALE: 地址鎖存, 高表示地址

驅動框架理解

概述 API在某個標頭檔案中定義,被封裝在某個DLL中,而這個DLL會進一步被封裝在ntdll.dll中(它裡面的API叫native api),比如,ReadFile在ntdll.dll中就對應著ntReadFile;然後這個API會通過sysenter的方式進入核心層。 那麼,比如對於Cre

linux--framebuffer驅動框架

一:framebuffer? 幀緩衝(一螢幕資料)(簡稱fb),核心中虛擬出的裝置,嚮應用層提供一個統一標準的顯示介面(frambuffer)。 容許應用層在圖形模式下直接對顯示緩衝區進行讀寫操作。 framebuffer用來操作物理視訊記憶體的位置,換頁機制等操作。 使用frame