驅動筆記15 鍵盤過濾驅動學習筆記

2021-07-11 14:02:18 字數 2885 閱讀 9096

鍵盤過濾驅動對於分層驅動的學習是乙個很好的例子,它相對檔案過濾驅動來說較為簡單,也更容易理解。

並不是所有的驅動都需要直接訪問硬體的,事實上幾乎所有的硬體裝置都存在著驅動程式鏈,最底層的驅動程式可以直接訪問硬體,並對上層提供透明服務,最上層的驅動程式只要對接收到的資料進行過濾、格式化等處理即可,這樣大大減少了開發的難度。

我這次學習的物件是klog,但我將它的**進行了精簡,這樣使得它的工作流程更容易被看清楚。

首先看driverentry例程:

ntstatus

driverentry(

inpdriver_object 

pdriverobject,

inpunicode_string 

registrypath )

pdriverobject

->majorfunction[irp_mj_read] 

= dispatchread;

pdriverobject

->driverunload 

= unload;

// 開啟記錄

hookkeyboard(pdriverobject);

// 設定device_extersion

pkeyboarddeviceextension

=(pdevice_extension)pdriverobject

->deviceobject

->deviceextension;

returnstatus_success; }

很容易看懂,我就不多說了,其中dispatchpassdown僅僅將接收到的irp**給下一層裝置,**就不貼了。下面我們先來看其中的重頭戲之一:hookkeyboard。

ntstatus

hookkeyboard(

inpdriver_object 

pdriverobject )

pkeyboarddeviceobject

->flags

|= (do_buffered_io |do_power_pagable);

pkeyboarddeviceobject

->flags

&=~do_device_initializing;

// 設定device_extension

rtlzeromemory(pkeyboarddeviceobject

->deviceextension,

sizeof(device_extension));

pkeyboarddeviceextension

=(pdevice_extension)pkeyboarddeviceobject

->deviceextension;

// 繫結到裝置

rtlinitansistring(

&ntnamestring,ntnamebuffer);

rtlansistringtounicodest

ring(

&ukeyboarddevicename,

&ntnamestring,true);

ioattachdevice(pkeyboarddeviceobject,

&ukeyboarddevicename,

&pkeyboarddeviceextension

->pkeyboarddevice);

rtlfreeunicodestring(

&ukeyboarddevicename);

returnstatus_success; }

首先iocreatedevice不用多說了,在任何乙個驅動程式中都會見到,關鍵是下面的flags設定和ioattachdevice。我們建立了裝置之後,需要將其加入到鍵盤的驅動程式鏈中,這個具體轉化為**就是將我們的裝置attatch到"\\device\\keyboardclass0"中(當然不一定非得是這個裝置,掛這個裝置的主要目的是為了能夠動態解除安裝我們的驅動,因此不能掛接更上層的裝置)。

為了得到按鍵操作的資訊,我們傳送乙個irp_mj_read到驅動的裝置棧,由於此時還不一定有按鍵產生,於是驅動程式把這個irp標記為pending狀態,一旦有按鍵產生,則馬上把這個irp完成,所以我們需要在irp_mj_read的處理例程中設定乙個完成例程。(因為我們工作的非同步模式下)

ntstatus

dispatchread(

inpdevice_object 

pdeviceobject,

inpirp 

pirp

)

在這個完成例程onreadcompletion中,我們就可以獲取按鍵的資訊了,**如下所示:

ntstatus

onreadcompletion(

inpdevice_object 

pdeviceobject,

inpirp 

pirp,

inpvoid 

context )

} if(pirp

->pendingreturned)

return pirp

->iostatus.status; }

不過這裡我們獲取到是只是按鍵的掃瞄碼,如果想知道直觀的按鍵資訊,還需要寫個函式進行處理,這裡我就給省略了。雖然這個程式比起rootkit.com上面那個klog簡單的多,使得它的流程更加清楚,也更容易理解,但它不實用。

一旦涉及到執行緒和檔案操作就變得麻煩多了,關於這點可以通過klog的**看出來,其實也不難,就是需要考慮的東西較多而已。

最後說一下,這個程式還有乙個bug,就是在解除安裝的時候再有按鍵就會bsod,因為在我們解除安裝驅動的時候,還有很多irp處於pending狀態,當我們被解除安裝後,再有按鍵操作,irp返回後卻找不到對應的驅動,就會造成藍屏的後果。

關於這個問題,網上有很多文章都介紹了介紹的辦法,我也沒有實驗過,就不廢話了。

驅動筆記(3)

併發 多個執行單元同時被執行 竟態 併發的執行單元對共享資源 硬體資源或全域性變數等 的共享訪問 通過semaphore機制和spin lock機制實現 獲取訊號量不成功 該阻塞或者睡眠 1.定義訊號量 struct semaphore sem 2.初始化訊號量 void sema init str...

LINUX SPI驅動筆記

spi匯流排由miso 序列資料輸入 mosi 序列資料輸出 sck 序列移位時鐘 cs 使能訊號 4個訊號線組成 linux下spi驅動開發 首先明確spi驅動層次,如下圖 我們以上面的這個圖為思路 spi bus spi匯流排對應的匯流排型別為spi bus type,在核心的drivers s...

linux裝置驅動筆記

雖然並不做linux有關的東西,但是記錄下點點滴滴,以備不時之需 驅動程式的編譯 make 驅動程式按模組安裝 inmod ko 執行這個命令之前首先要獲得root許可權,否則會報錯,1 operation not permmitt 檢視模組安裝情況 lsmod 解除安裝相關模組 rmmod 安裝或...