日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 >

Windows键盘驱动结构与消息机制--转

發布時間:2025/4/5 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Windows键盘驱动结构与消息机制--转 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

https://www.douban.com/note/318793892/

本文主要介紹按鍵消息是如何傳遞到窗口并轉化為具體的按鍵消息的。

Windows系統是事件驅動的多任務系統,其中按鍵和鼠標是主要的事件。按鍵是由鍵盤驅動獲得并轉換,然后廣播給各個窗口。

整個架構的核心是csrss.exe這個進程,對于“一般”的窗口,收到的消息都是由這個任務產生的。該任務負責用CreateFile方式打開鍵盤設備并讀取信息,獲得對應的鍵碼并發送給特定的進程,csrss.exe的啟動的輸入線程為win32k!RawInputThread,具體要把鍵盤消息發送給哪個線程,以及如何發送,是由csrss來控制的。

所以,每個進程的MessageLoop實際上是從這里讀取的,于是SetWindowHook之類的函數有些是掛到各個進程里,有些實際上是掛到了csrss里,達到監控鍵盤的目的。但對于加密的控件(如網銀等),SetWindowHook不管用,但如果hook到RawInpuThread里,那么還是有可能讀到信息的。

csrss訪問的是鍵盤設備,具體這個設備是一個kbdclass設備,以下部分就是內核的代碼空間了。

因為一個系統里可能不只一個鍵盤(同理,鼠標也是),所以需要一個統一的驅動去管理所有的鍵盤設備,這個驅動就是kbdclass.sys,鍵盤設備類驅動,對應的設備名是L"\\Driver\\Kdbclass",RawInpuThread實際上訪問的是這個設備,而對于每個鍵盤,則是有各自的驅動,對于PS/2鍵盤是i8042prt.sys,對于USB鍵盤,這是另外的驅動,這些驅動稱為port驅動,是真正的設備驅動,對應的設備是KeyboadClass0、KeyboardClass1等等(有幾個鍵盤,數字就排到多少),RawInpuThread把請求發送到kbdclass,kbdclass把請求(IRP)pend到這一層,等待下層port驅動返回。

這里需要特別提出的一個函數是KeyboardClassServiceCallback,這個函數是kbdclass一層的callback,下層設備驅動的所有返回值都需要經過它。所以,如果鉤子掛到這里,那么理論上所有的輸入都可以被攔截的,已經親自測試過網銀控件的密碼會在此被泄露,但QQ不會,QQ2013會啟動失敗,估計是檢查了這個驅動。

順便說一句,早期的QQ加密沒那么恐怖,但它是啟動一個線程不停的SetWindowHook,使得自己的hook永遠在第一個,然后過濾掉所有的消息防止被人監聽。后來的QQ可能是修改IDT里的鍵盤中斷實現的。

當然病毒也可以通過filter驅動注入到kbdclass和port驅動之間,來實現監聽鍵盤,這也是一種常見的情況。

所以,一個按鍵的消息產生流程如下:

1)硬件中斷/硬件端口數據
//WinIO能模擬,或者修改IDT是在這一層
2)鍵盤Port驅動(USB or PS/2)
//Filter驅動在此
//KeyboardClassServiceCallback也在這一層被調用
3)kbdclass驅動
//處理鍵盤布局和鍵盤語言
4)Windows內核邊界(zwCreate/zwReadFile)
----------------------(系統調用)----------------------
5)Windows內核邊界(zwCreate/zwReadFile)
6)csrss.exe的win32k!RawInputThread讀取,完成scancode和vk的轉換
//SetWindowHook工作在這里(全局)
//kbd_event工作在這里
7)csrss.exe調用DispatchMessage等函數分發消息
//SetWindowHook工作在這里(進程)
//PostMessage和SendMessage在這里
8)各個進程處理消息

WinIO這個驅動比較特殊,它提供接口可以允許應用層直接寫端口,但只能寫PS/2端口,所以有些模擬按鍵程序通過WinIO來模擬按鍵。

對于標準的程序,PostMessage等函數可以完成模擬,但對于不太標準的軟件,只能用kbd_event來模擬,但有些軟件(如網銀控件)就只能在更靠近內核的區域模擬了。

同時,有一種輸入是很特殊的,就是DirectInput,這是DirectX提供的一種方法,大型游戲中很常見的用法,因為DirectInput的輸入速度很快,繞過了消息層。但對于這種軟件,在kbdclass一層甚至都無法模擬。目前還不確定DirectInput工作在哪一層,猜測可能是在kbdclass和port驅動之間,也許是一種filter驅動。對于這種輸入方法,可以WinIO來模擬,但對于USB鍵盤則沒有辦法。

Windows提供了一套API:SendInput,這個驅動發送按鍵消息時有兩種類型,一種是VK模式的,實際上跟kbd_event一樣,工作在csrss這一層,而另一種是ScanCode模式,MSDN里有這樣的描述:

Windows 2000/XP: Set the KEYEVENTF_SCANCODE flag to define keyboard input in terms of the scan code. This is useful to simulate a physical keystroke regardless of which keyboard is currently being used.

可以看出,這是能夠模擬更底層的按鍵的,理論上說是可以模擬DirectInput的按鍵的,實際測試也是這樣,但文檔中沒有說明在vista以后的版本是什么狀態,所以暫時也無法知道在WIN7里的工作情況。

轉載于:https://www.cnblogs.com/davidwang456/p/8708619.html

總結

以上是生活随笔為你收集整理的Windows键盘驱动结构与消息机制--转的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。