撰寫本系列文章目的在於提升資訊安全之實務能力,
並透過實作體悟到資訊安全領域的重要性,
本系列所有文章之內容皆有一定技術水平,
不得從事非法行為、惡意攻擊等非法活動,
「一切不合法規之行為皆受法律所約束」,
為了避免造成公司、廠商或玩家之間困擾,
所有實作不會拿已上市產品、Online Game 等等來作範例學習,
且部分具有深度、價值之內容,將會提升一定閱讀門檻(不對該技術做分析、解說),
請勿透過本系列文章所學,從事任何非法活動,請不要以身試法!!!
首先開始前要先說一下,
小弟我目前還屬於菜鳥階段,正不斷努力學習中,
若有發現錯誤或不妥之處還請不吝賜教。
歡迎大家多多留言,互相交流交流。
那就開始今天的主題吧~~
今天來講講關於 PS/2 的鍵盤過濾驅動,
簡稱為:「鍵盤監聽/側錄器」
首先,按下鍵盤按鍵後的流程大致上是這樣的:
中斷要求層級 Interrupt Request Level (IRQL):
在電腦系統中,無時無刻都在大量處理著資訊、訊息、程式...,
這個中斷要求層級就是要讓一些更重要的事情來「插隊的」,
意思就是說,當有一個優先順序較高的「中斷要求」來臨時,
它就能被優先執行,因此優先順序較低的就會被打斷,
所以你有想到什麼東西中斷層級是最高的?當然是按下電源按鈕、拔插頭...。
圖片內容取自 WIKI:https://zh.wikipedia.org/wiki/IRQL
當按下鍵盤,會產生「硬體中斷」,中斷層級很高,也是因為這樣系統才能捕捉到訊息,
所以當我們按下鍵盤,User mode 是有那麼一瞬間都停了下來,在等待鍵盤訊息的處理,
同時 IRP 訊息正在由下而上一層一層的傳遞,最終會到 User mode 應用程式中,
也就是大家打出來的文字。
所以~
要如何攔截鍵盤訊息呢?
有兩種方法:
作法一:
自己建立一個虛擬的 Device,讓這個虛擬的 Device Attach 上去 KbdClass。
作法二:
想辦法拿到鍵盤所使用的虛擬設備(KbdClass),然後 HOOK 它!
先來講第一種較腳踏實地的作法,
使用 IoCreateDevice 建立虛擬的 Device,
要怎麼知道現在有幾個虛擬的 Device?
使用 WinObj.exe
然後你就會看到:KeyboardClass0
這是在 VMWare 上的結果,若在實體機結果就不相同。
所以將建立好的虛擬 Device Attach 上去 KbdClass0,
當然,鍵盤可能很多個,所以 KbdClass0 可能不只一個,
KbdClass0、KbdClass1... ...要自己列舉,然後通通 Attach 上去!!
Attach 函數就用 IoAttachDevice。
再來,我們不應該在讀取 IRP 時做一些耗時的動作,例如更改按鍵...等,
因為這樣會耽誤 IRP 傳遞的速度,所以要在讀 IRP 這個動作完之後,
再來做一些其他操作,不然會完蛋!
大概就是設定 IoSetCompletionRoutine
最後拿到 IRP,此時就是設一個 FUNC 來做想做的事情拉~
把 IRP 讀進來放進指向 PKEYBOARD_INPUT_DATA 結構的變數中,
typedef struct _KEYBOARD_INPUT_DATA {
USHORT UnitId;
USHORT MakeCode;
USHORT Flags;
USHORT Reserved;
ULONG ExtraInformation;
} KEYBOARD_INPUT_DATA, *PKEYBOARD_INPUT_DATA;
其中的 MakeCode 就是鍵盤按鍵編號了,可以把它改成別的,也可以直接印出來...等等,
效果圖:
再來講一下第二種作法,這種作法相當簡單,實作起來也很容易,
直接想辦法拿到鍵盤所使用的虛擬設備(KbdClass0),
然後把 IRP_MJ_READ 改成自己寫好的 FUNC,
使用 ObReferenceObjectByName 拿到虛擬設備(KbdClass0),
保存一份原本的 IRP_MJ_READ FUNC Address,
然後就是:xxxDriver->MajorFunction[IRP_MJ_READ] = MyHookDispatch;
這樣應該很清楚惹吧 XD
以上所講僅限用於 PS/2 的鍵盤~
不支援 USB 鍵盤,可直接在 VMWare 中使用,因為 VMWare 預設就是跑 i8042prt。
有空再來寫一篇支援 USB 鍵盤的文章,因為 USB 鍵盤和 PS/2 差很大,
它沒有固定的 Device Name,只有 Driver Name,而且是走 kbdhid.sys,
很難搞定,難度大幅提升,要自己從 USB Driver Stack 中列舉,
所以假設有哪天忽然很閒,我應該就會再發一篇 XD,訂閱起來,文章不漏接。
好了,這篇就講到這結束了,
大家若有發現哪裡寫得不好或錯誤的地方,都留個言討論一下吧 XD
那我們下期見 o( ̄▽ ̄)ブ