|
|
Author: sinister# n$ U. O& G# f, V
Email: [email]sinister@whitecell.org[/email]
$ ?' Q( t% U; @# f! dHomepage:[url]http://www.whitecell.org[/url] ) n) e4 `' `# W6 Q w
Date: 2007-02-26
4 M. Q/ p, ~7 A: X6 B
: C V' p( R$ P* Q7 o4 s+ n& E" g7 {4 {4 f9 G5 X: Q: _: l) T
/*******************************************************************
3 }/ S" [+ [9 o/ }8 \8 l I- |1 b* R7 c/ U
这个键盘过滤驱动是一个定时锁定计算机程序的功能部分,以前 lgx
: A$ L: M) ?3 F0 l2 @写过一个 linux 版,现在我们需要实现一个 windows 版。这部分的
' y$ x/ t& ~9 L, W! n+ b功能要求如下:
! _# t* x3 a$ K. b4 `; V( _5 m9 |# \) J
1、强制锁定键盘/鼠标。+ P% n+ m: o3 p1 ]& o- |9 h
2、可动态加/解锁
+ T( g2 o9 H: {. K( ^8 b7 L3、兼容所有 NT 系列的操作系统。
% x4 h$ p3 V2 O3 _) S
+ ]% h, Q/ {5 k4 o4 g( J# Q就这个需求而言,能马上能想到的就有7,8种方案,这些方案可以说都能够实
, p K ^9 c8 f b3 B现,但如何更合理,更稳定、更彻底的实现,如何尽量少的消耗系统资源,如/ J7 O# ^2 r! e# Q3 X8 ?
何保证其兼容性,等一系列问题不得不让我们去重新评估这几种方法。首先在
" C9 P6 W) \, N: I6 k) e上层实现,一是怕被饶过,二是怕调用频繁影响系统性能。在底层实现,一是
6 X6 r) ~6 L7 y% B( K0 H5 x0 D怕考虑不周有兼容性问题,二是怕过多使用未公开方法导致系统不稳定。下面& g* [1 ], |0 L
就来看一下我想到的几种实现方法:
' c9 s% f3 R! @; q7 E. K, e6 B; }# K' h7 N' z
1、全局键盘/鼠标钩子5 `5 h6 `4 ~6 M3 p
2、BlockInput() API
; `- t8 i8 [: {- S, g' v: Y# v; l3、使用 setupapi 进行控制
/ I" O3 I# D1 l* W0 ~$ N4、全局键盘/鼠标钩子+远线程插入 WINLOGON 进程屏蔽 CTRL+AL+DEL# w1 D3 J5 |3 E# e9 s* E5 X7 V' V
5、拦截 win23k!RawInputThread() 函数
' E5 _% O6 Q2 v% ]! s) W6、修改 DDK 中自带的 kbfilter 的键盘(Port Driver)过滤驱动6 C% X( [. D9 w8 ^4 i# a/ \$ _
7、拦截 kdbclass 驱动的 driver dispatch routine2 ?: a3 P; j- p$ W
8、实现一个 PS/2 与 USB 键盘过滤驱动" \, p. P; q5 u7 b1 N
5 L( m: S0 ^6 X& f* ]8 a4 p7 Q3 w5 A- x7 k0 [
我们先看一下以上这些方案的实用性与通用性。第1,2套方案不在考虑
) O: N' \7 k2 z T" }: r之内了,因为有办法解锁,屏蔽不了 CTRL+ALT+DEL 组合键。第3套方
, ]& w7 q% `. }- X0 j6 l/ F案经过我的测试使用 Keyboard 的 CLASSID 不是什么环境都好使,存在
" \, q* S& s2 H& }! d9 J" Z5 {' X兼容性的问题。第4套方案系统效率会大大降低,而且存在很多不稳定因7 m; Y$ B! O5 m- f) }) [$ q9 Z
素,对于全局钩子这种东西我一直很排斥。第5套方案,同样存在兼容性
# R' Q$ j& f" G9 R1 j问题和不稳定因素。第6套方案看似完美,但无法实现动态卸载,无法卸2 x" F5 V3 T; g/ c. S3 S* v
载就意味着你需要一个开关来控制是否锁定,这样还要与应用层通讯,我
) r- S8 j7 R: w" }/ J0 G" o的目的是不让应用层与驱动有任何交互。且使用 WDM 形式这种安装起来# H' m$ f# l9 u5 ^ J, R9 X3 Z; Q
也很麻烦,要么 INF 要么自己 setupapi,这都不是我想看到的,还有如
4 B) r0 [" D9 J7 g' ^1 Q A) y$ Q. w果仅为实现这么一个功能,就让一个核心驱动一直存在系统中的话,我有
' F/ I/ L/ a$ ^障碍。第7套方案看似实现起来很简单,其实有很多问题。如仅是拦截
9 {6 F: E( A- |5 D* VIRP_MJ_READ 并粗暴的返回拒绝后,系统无法恢复到初始状态。且对于 + p( i) c( h6 X: }( T7 k& z% D- E) }
USB 键盘存在兼容性问题。那么最后只有自己实现一个 PS/2 与 USB 键
) n- ]+ ?. Y% _! Y4 e: `盘过滤驱动了,既然要实现这么一个驱动,那么就必须能实现到第6套方& k" T! T2 E8 ]3 e
案的全部功能且不存在它所带来的问题,否则就没有什么意义了。
$ A/ w; \! R: C. a* \
2 B- }- @# U3 `% P0 Q7 R
% Q5 n( S1 {& E3 J0 d6 n6 ]1 o& Y( ^& y( S我们都知道实现一个可直接使用 SERVICE API 来动态装载的 KMD 键盘过
: G# E! @+ k% c; y' f滤驱动,首先需要先 ATTACH 到 \\Device\\KeyboardClass0 设备上再进1 V' ^- K7 f( Q/ S S$ o! W8 Y
行按键过滤。但如果仅 ATTACH 这个设备的话,会存在很多问题,那就是
7 o7 |3 w! q- u3 F; h只能过滤到 PS/2 键盘,而对于使用 USB 键盘的机器毫无作用。现在越
5 R* W5 ?& Q0 N/ q! T来越多的品牌机都预配的是 USB 键盘(如:DELL)。大家可能会想,从; y2 M, k. H3 [/ G* R" |
KeyboardClass0 一直到 N 都 ATTACH 不就可以了么?总有一个是 USB
! k$ k3 K$ i4 {/ l1 I键盘设备,经过实践这是不可行的,只要是 USB 键盘设备的话,在使用3 l$ j( w" p8 ~( W5 t6 K( F
IoGetDeviceObjectPointer() 函数从设备名得到设备对象都会获取失败,& X1 y9 a6 Z$ @
我还曾尝试使用 USB 键盘设备名来转换,还是一样失败。还有一个问题
- W4 s& N; \) G7 N& p6 M就是 USB 键盘设备不是都有名称的,即使有它的名称也都是动态生成的/ h7 F }6 c$ R& i$ d2 h
而不是固定的。那么这就带来了一个问题,既然系统提供的函数无法使
* f) Z; q& ^% @) ^& x用,且我们又是为了动态安装/卸载,使用的是 KMD 类型驱动,无法通3 u$ { y, ?& t8 Q$ u: C8 y; n5 e
过 AddDevice 例程来获得 USB 键盘的设备对象进行挂接。那么如何来
# J5 G; }' @* `) R. O屏蔽 USB 键盘按键?要达到这个目的只有自己分析下 USB 协议栈,通
) U" i# `$ P5 a4 L过使用 DriverTree 观察发现,所有 USB 外设都挂在了 \Driver\hidusb
$ Z* R/ e% l) a' P& q上面,USB 键盘驱动名为 \Driver\kbdhid,而它则是 \Driver\kbdhid 5 } t3 U0 {' \. s3 Z4 x
的一个 FilterDriver,且这个 \Driver\kbdhid 没有设备名称,也就意
& G" L' w' ?% j# \味着,我们无法 IoGetDeviceObjectPointer() 得到设备对象并 ATTACH。
4 z# x% I8 d& h4 E经过对多个系统多台使用 USB 键盘机器的分析,可以确定让我使用它们
$ |) |% J+ v$ G! p$ a1 T' ]" l' ~来作为得到 USB 键盘设备的依据。(这里仅是对 USB 键盘设备很功利
7 G; o7 u# H% n- I% z; y的分析,如果想了解 WINDOWS 的 USB 设备栈如何组建,请阅读 tiamo5 q) Q: \+ s* w8 h* e$ y; L9 \+ i B
的 《Windows 的 USB 体系结构》。在此向所有公开研究成果的人致
7 X# t; r) @$ k4 Z敬!)有了这些依据,下面就没什么好说的了,自己遍历 USB 设备栈,+ m/ |: z( F: z$ y" N7 k
根据驱动名称获得 USB 设备对象,然后 ATTACH,过滤按键。具体流程9 u$ K6 p0 G2 d! K$ y' C
见下面代码。
( M. ^$ W) | m/ k6 l% P
/ j, {5 `- l( f+ i7 V; [/ U7 T0 O这里有必要说下动态卸载,我尝试了两种方式,一种是在 UNLOAD 例程7 F: [3 ^+ A3 ]5 Z1 F
里直接取消 IRP,这种方法在 W2K 系统下,无论是 PS/2 还是 USB 键+ d& C5 I' Z8 y l* {
盘都可以很好的实现。但在 XP/2003 系统上则无法成功,在 XP/2003
4 T' Z( l; f7 \' A: U L$ l2 `上暂时使用一个 IRP 计数器,在 UNLOAD 例程里判断如果还有一个没有
$ a6 v+ P2 Q5 r1 d完成的 IRP 则等待,这样的话,需要在 UNLOAD 后用户按下任意键才可. e9 j! C7 E$ _" ~+ Y& B! J
继续,虽然能够安全卸载但还需要一次用户介入。考虑实现的仅是一个
3 H# E7 t9 F( ^锁定功能,这样也算是能够忍受了。以后考虑在驱动中直接模拟用户按
5 ?; S6 y# Y) x* l5 Z& b# q键来实现,当然这种按键要有通用性和兼容性,支持 PS/2 与 USB 键盘。 ]; s2 ~% a- X/ R0 t
# [- e3 r& e6 M2 Y+ \+ }
1 V6 P( Y" ]2 l完成了上述工作后看起来好象完美了,其实不然,当你屏蔽了当前使用; T( f3 t0 H$ [/ M/ e" j
的键盘时别忘了还可以再插入一个 USB 键盘,而后续插入的这个键盘是+ v3 k1 l$ Y5 Q
可以被识别的。这就需要我们处理 IRP_MJ_PNP 选项,对其中我们有兴趣& W! x% o( C0 _0 n% w
的 IRP_MN_XXX 做相应处理,可以处理 IRP_MN_START_DEVICE,在这时我0 Y, G7 m3 Q1 y0 Q
们动态挂接。还可以处理其他的 IRP,索性返回错误,让识别失效。但我
9 ]4 M" W( r6 x( b* {: p' l0 w们的驱动是 KMD 类型,只要加上一句对 DriverObject->DriverExtension
- Y" \+ B$ i, u/ W% E/ Q1 ]->AddDevice 的赋值操作则无法直接使用 SERVICE API 来动态加载了。$ P1 S/ F- k1 ^! k5 s: x/ ~
如何保持 KMD 又可以获得 PNP 的处理权呢?这可能要直接对 PnpManager
1 b9 d' }8 H: [: T进行操作了。这个问题有待大家来完善了。
8 ?8 E" k+ k/ y8 a( M( p
) K9 }# l8 R9 N! u: \2 ^) }5 G: ^
( b0 H8 i% e2 R+ a要问为什么把文章插在代码当中,那可能是我觉得,既然把全部代码都贴出0 k. x1 F, K3 Q: O$ K3 |
来了,写文章就不如直接看代码来的真切。我这里所写也仅仅是对这些天的! v& M. }* P( y- W; ]
分析做个记录而已。我更愿意把它看做是一段注释。
3 @0 J* j. T! r
' ]$ _, _$ e L7 u+ J0 U2 j最后在此代码中要
, F' b; \, ~1 C5 Y9 w1 t4 j& r& b
感谢:PolyMeta,他在放假前提醒我 USB 键盘的不同。- ?* P& Q6 G& t* l
& E y% O; E# R8 v1 l
感谢:lgx,过节前给我找了些事,以至于没有让我觉得过节那么无聊。
& c. t. g$ I/ p+ ^- p
$ g" G6 b* _/ s感谢:齐佳佳,过节请我吃好吃的。
" k6 \+ S8 l8 j0 I8 G- p z- ^ o( a* O% q
, B# Y# J P4 v7 ] e
******************************************************************/8 ]& _9 ?6 Z6 ]
# Q5 ~' b3 e, _# C; n4 Q; r/ q% x' g9 M- X
/*****************************************************************
+ n( M- n6 {) \$ n" E 文件名 : WssLockKey.c
* `( R) N/ o; B% { 描述 : 键盘过滤驱动
% I. ~- E9 o/ x4 D3 H 作者 : sinister
2 y9 ]4 {7 q3 _ 最后修改日期 : 2007-02-260 q8 w! ?; r- U( {" D1 M
*****************************************************************/
# l p# m; N% N" c/ W- o. |" M: m' S, m8 j3 t
+ P+ R- o# m: B" k2 n0 M8 {$ V2 P
#include "WssLockKey.h"9 v2 Q& u% c9 d) e6 N' X" a% m
1 X: V! ?3 p) B/ b: {3 H4 i
NTSTATUS& Q8 H; ^) F0 P# g6 c" J
DriverEntry( IN PDRIVER_OBJECT KeyDriverObject,
# E- v" s3 d9 j9 o' n IN PUNICODE_STRING RegistryPath )
3 K! d/ Q3 H3 @( W# G! I W{2 O' \4 j1 y( i1 v V0 h
UNICODE_STRING KeyDeviceName; & k/ S( {/ P4 j" `% ?6 K$ {* c
PDRIVER_OBJECT KeyDriver; ' T- D- E3 Z @. I. C
PDEVICE_OBJECT UsbDeviceObject;6 V% H6 N0 E8 m, u/ }6 @
NTSTATUS ntStatus; " v+ P/ u5 H6 U/ Z: o' ~
ULONG i;
4 G- k2 [" Y* {, F! G1 }/ D5 V: Y8 k( R% s0 ]' Z* d! Q% `
//3 t/ _# X4 u7 v d
// 保存设备名,调试使用/ p2 x6 ^+ q) ] m5 N
//
9 |1 d% y. {# s- z5 e' N WCHAR szDeviceName[MAXLEN + MAXLEN] =2 G! v$ ?" R* B+ g6 I7 L
{% V. x7 M6 v2 j
0* u5 `: K- V L( S2 D4 s. s
};2 O8 A' X1 R' S
6 [ y$ q3 \( f0 ]: |: F! k KeyDriverObject->DriverUnload = KeyDriverUnload;
# L5 A" B4 T7 I* M1 A5 I* n& @
: Z* q: [' _& x) ^! ~- g" R0 D //
" k& E, \. Y7 c) A6 {. v$ j4 t // 先尝试获得 USB 键盘设备对象,如果成功则挂接 USB 键盘
8 U2 F4 L( a) n' q# V' @ O /// h9 a/ x9 E S3 E7 k, j% I) d
// 注意:因为 USB 键盘设备名不固定,且即使得到名称也无法
/ c( `6 g9 a6 h9 M$ D // 使用 IoGetDeviceObjectPointer() 函数根据设备名称得到其
# s" M; @8 v) y/ ?8 [* h // 设备对象,所以这里我们只能自己枚举 USB 设备栈,并得到
4 _; e! g1 a" d: s |, P, W // USB 键盘设备来进行挂接; O' ^) w1 m0 Z' o
//
: @$ Q8 ]' c# [( Q" a; x ntStatus = GetUsbKeybordDevice( &UsbDeviceObject );
0 x$ C5 q- x# P" r. |" f, \ if ( NT_SUCCESS( ntStatus ) && UsbDeviceObject != NULL )
( q8 d/ h( {/ a; p3 g/ L0 [8 X; N {
1 [- S6 c8 g% G! b //
6 d7 ^# s% g* [. k // 调试使用,USB 键盘设备 kbdhid 没有设备名只有驱动名; B6 w3 a9 W: `8 O5 C
// 所以这里打印为空
' k0 d* R" v) |1 D, P X o- g7 i //+ y) I4 ]0 \( i) V" q/ t6 |/ A# S
RtlInitUnicodeString( &KeyDeviceName, szDeviceName ); // USB KEYBOARD
; l7 E% p" n, `+ v DbgPrint( "KeyDeviceName:%S\n", KeyDeviceName.Buffer );. k' k% {1 f; ^" B
+ ?% Y' R2 { w7 c8 m% ^; N+ Q
//
8 l: ~) }, D! l" c! t0 b* E* R _ // 挂接 USB 键盘设备
4 ^) h/ P9 w, T /// V% x7 ~( p0 k+ e6 u
ntStatus = AttachUSBKeyboardDevice( UsbDeviceObject, KeyDriverObject );
z' Z7 e* e' H if ( !NT_SUCCESS( ntStatus ) )
6 u$ U4 f/ J$ [4 X- t {
( [8 \: \7 |& o DbgPrint( "Attach USB Keyboard Device to failed!\n" );: m. v7 `* G% b, j" y
return STATUS_INSUFFICIENT_RESOURCES;
! @1 J, N* l' v! q; r# m }
, w* ?' v0 V) l1 d0 V Y6 k }
5 i ~% V- q7 P else
5 r1 N. M1 c2 A& r% y3 ~ {
( F- B0 V5 f2 ^4 ~. Q //
; W! Q; C$ Y/ I6 L; T // 如果没有 USB 键盘,则尝试挂接 PS/2 键盘设备
/ r9 P+ B: c1 @1 }( G0 W$ @ // 5 ~3 f; K+ ]3 w! x
RtlInitUnicodeString( &KeyDeviceName, PS2KEYBOARDNAME );
) [1 @$ v( k* @, t, ]9 l& y5 s% K: @
ntStatus = AttachPS2KeyboardDevice( &KeyDeviceName,
* g& G" A h5 D KeyDriverObject,
0 N9 ~! T' {& q7 s &KeyDriver );
9 A6 x/ O! a2 V h6 p4 R if ( !NT_SUCCESS( ntStatus ) || KeyDriver == NULL )
* D- l4 t) h o4 S+ ~ m/ z9 i {( s" X2 T6 P, f9 I6 g3 T
DbgPrint( "Attach PS2 Keyboard Device to failed!\n" );4 I9 \+ G5 s2 A
return STATUS_INSUFFICIENT_RESOURCES;
/ ?9 H n9 r2 l$ ~0 h4 h: x* W }
K( C- L2 U9 _) x }
, r& q: p0 _3 Y( }' b$ {6 j0 a
1 e, r9 q! @* K8 Z7 }2 ?8 Q1 N //; |- T4 R+ _$ U5 ]/ q$ m) Q
// 这里没有过滤其他例程,仅处理了按键操作。这样处理会禁止
+ }5 e b3 |" k // 休眠。因在锁定时不允许休眠,所以也就无须处理其他例程
6 _( a) R+ w6 A //
: i. s! j. S% A3 b2 {! I9 d" [ KeyDriverObject->MajorFunction[IRP_MJ_READ] = KeyReadPassThrough;
0 f0 k c; u' j! g
( J% }/ W+ N4 N( x/ r$ j return STATUS_SUCCESS;
1 a* ^( p/ w0 N4 I5 U}
0 \5 L: W8 C; F8 s
6 [# K( W0 n6 L) f @/////////////////////////////////////////////////////////////////
( `% Z0 t& T- {3 s" g: S) j0 g3 ?// 函数类型 : 系统函数
/ j. ~3 y: A/ L* t// 函数模块 : 键盘过滤模块
) _, c) }3 ~) L" d4 t' S////////////////////////////////////////////////////////////////
) Z& i* w6 L+ _0 y7 v/ O; T& J- ]" L// 功能 : 尝试取消队列里的异步 IRP,如果失败则等待用户按键,
' w# c$ R$ e" [2 q// 卸载键盘过滤驱动
6 A0 t5 K3 a8 H2 E$ q9 u! Z// 注意 : 取消 IRP 操作在 2000 系统上可以成功,在 XP / 2003 上
# x5 J; \, D3 d1 a* Y4 d R// 则需要等待用户按键,以后有待完善 u& w. [; ]5 _5 z( v
/////////////////////////////////////////////////////////////////: S* v. M$ l- S# w1 `3 V6 m2 C
// 作者 : sinister- o/ Y3 I4 H* G) w
// 发布版本 : 1.00.00! g# r0 p3 I8 f: `2 W$ v! z! u4 y( N
// 发布日期 : 2005.12.27% L% g2 B: ]( P5 C; I
/////////////////////////////////////////////////////////////////' [6 N+ {0 R. \" V
// 重 大 修 改 历 史
9 u. @$ ~, X+ f////////////////////////////////////////////////////////////////
$ ]/ e: K: P) ^ X2 e// 修改者 :
- O+ z2 a- o+ k2 R// 修改日期 :% o7 f M1 u8 U" Z2 p
// 修改内容 :
: ?1 E r' _( t4 T: B C/////////////////////////////////////////////////////////////////1 C4 b1 F9 K$ ?1 x _% y; t
$ z1 T* w/ m$ G
VOID0 @; j9 J' F) j# O
KeyDriverUnload( PDRIVER_OBJECT KeyDriver )! |4 U2 ?9 k/ G& w2 y: t4 @
{* h- `) I7 \+ K6 `* S9 x4 h) Q% G
PDEVICE_OBJECT KeyFilterDevice ;
6 ~5 c: ?" _* F+ h) |6 G$ T7 E PDEVICE_OBJECT KeyDevice ;2 C: V) P) O4 B% K+ [
PDEVICE_EXTENSION KeyExtension; ( U, Q; A7 j% _+ ]" H; s2 v; m w
PIRP Irp;1 P6 I; `8 o5 t& u0 b
NTSTATUS ntStatus;9 }/ y! r( p0 v9 Z3 @+ v9 |
! R, U' h i6 H8 l! i KeyFilterDevice = KeyDriver->DeviceObject; * {( @: Q, u- X } H6 M7 O' p
KeyExtension = ( PDEVICE_EXTENSION ) KeyFilterDevice->DeviceExtension;
, A8 c) X3 f. h3 ^ T KeyDevice = KeyExtension->TargetDevice; ( p+ i* n& k# Q8 \& e7 K( f
# `! a% I8 s1 Q IoDetachDevice( KeyDevice ); 6 Q- ]: ?9 U. X
. I: O' N+ ~5 p4 g% F+ Q, P! o
//0 X' p3 e2 m7 Y1 P' e% P$ ]
// 如果还有 IRP 未完成,且当前 IRP 有效则尝试取消这个 IRP# \4 U9 R& n: J6 a* G1 E- Y+ y! g' b
//
0 k o# i7 k& }( h if ( KeyExtension->IrpsInProgress > 0 && KeyDevice->CurrentIrp != NULL )
7 x3 L& W% [) E/ K: n" p; K {
) }6 {7 F& N/ Y; Z$ c2 X if ( CancelKeyboardIrp( KeyDevice->CurrentIrp ) )0 j$ h2 b- }3 `5 q. ^6 X* c3 b2 w
{2 ?+ `" F6 ~; ~
//
& C% r% d% a1 [' s" X // 成功则直接退出删除键盘过滤设备( [" v6 [3 V" _) T0 O
//( `/ g+ ^" s/ U
DbgPrint( "CancelKeyboardIrp() is ok\n" );
8 H- `' B) M7 o$ P goto __End;
: f' J: e1 a2 Y }3 `* ]1 P% l; \+ s# r6 ^0 o6 I3 y
}
& p1 D' E3 D, j& D# x+ y$ t8 O( {, T/ s! J: T# H
//: z7 G; k, W7 @9 E9 g4 [, \# F
// 如果取消失败,则一直等待按键- [8 m; i& O5 K T
//
8 H0 q& K0 f, A" W while ( KeyExtension->IrpsInProgress > 0 )
, @- k& J6 u2 e" ~: X, j( ` {
+ D2 k# b% h z. g* a; O DbgPrint( "Irp Count:%d\n", KeyExtension->IrpsInProgress );2 I5 ]) | |& u4 ~' k
}8 I1 d$ |) O0 o& `
: ^+ V8 {( d. O. L __End:
* q! }2 B( B) j# D) Z# p IoDeleteDevice( KeyFilterDevice ); 6 V* h& r& ?0 _, G
5 R- w3 ?0 k9 B+ \6 r
return ;) P" q/ Z; ?$ l" v5 r4 i
} 6 X3 L8 e3 ~: p7 N0 G# u
$ ~- E2 B+ |1 p* \8 t* [ `/////////////////////////////////////////////////////////////////; \4 U: w- a' c. N3 f, h& F" P6 P
// 函数类型 : 自定义工具函数3 f. f% N, ~" n9 z: ]
// 函数模块 : 键盘过滤模块9 J& C( U- E. T+ f; i+ d+ v
/////////////////////////////////////////////////////////////////3 @1 ]" g, a# H% x
// 功能 : 取消 IRP 操作+ x% x1 H9 }$ l+ \# Q g. z7 I! i
// 注意 : 这个函数仅是为配合在 UNLOAD 例程使用,其他例程中不能
3 p% }! y+ v) I" i/ O( u+ c$ P// 使用此方法来取消 IRP6 ?( J% Z1 P+ P7 H* }# t
/////////////////////////////////////////////////////////////////
+ @% c% M2 W1 w7 G! m// 作者 : sinister
/ J$ U/ _& p- h; \// 发布版本 : 1.00.00
8 Z R+ k. }7 E4 V; ], Y) e// 发布日期 : 2007.02.20; @% [& S$ m, w% L: Z
/////////////////////////////////////////////////////////////////
( y% K+ M3 c) n1 P- x% U0 W// 重 大 修 改 历 史$ G' O, ~$ G4 V5 I& [8 a4 T! m0 Y) R
/////////////////////////////////////////////////////////////////5 N( y" \5 n) L% v
// 修改者 : ( L2 \% u; u' m% A( H/ ]& h
// 修改日期 :
& G1 W1 A, w$ r2 g: S8 D2 w// 修改内容 :
0 ^! d3 N$ n! ^: m7 m, W9 @/////////////////////////////////////////////////////////////////
' `0 Q+ X: G2 b# K- y) w4 p# }, P1 p
BOOLEAN# G, W* o! q, d" y
CancelKeyboardIrp( IN PIRP Irp )
+ @' _( l8 q5 \ k{
2 C. N' ~& [2 }& }* S, g if ( Irp == NULL )# U0 A1 K3 Z4 w- V' e4 j
{
( L1 G0 O, k# e9 X% o DbgPrint( "CancelKeyboardIrp: Irp error\n" );: W& w* |; i8 `1 i& F
return FALSE;
4 r, K5 Q. L' ?- E' Z }
9 T3 Y3 W; R# P) F- ]0 W6 F" u+ e& O# [
& }9 v% R ^% [8 N" ? J" @ //( f" r, Y- m- T( t* W6 B
// 这里有些判断应该不是必须的,比如对 CancelRoutine 字段,' E+ Q4 ~4 | v. c. w. \ j8 B
// 因为 IoCancelIrp() 函数中有判断了。但只有偏执狂才能生存 :)。
; x# X$ K3 ~; n3 K // 小波说 低智、偏执、思想贫乏是最不可容忍的。我这一行代码就占; c/ r( o4 e+ o$ R
// 了两条 :D,不知 xiaonvwu 看过后会作何感想?:DDD7 T, F3 g0 _ k) E+ M3 Y
//9 x0 ?0 e `, ^& z1 W
/ E$ K" t! Y' f _2 H' M G }
//
8 h+ s1 F; W0 I3 S& u // 如果正在取消或没有取消例程则直接返回 FALSE" x" f3 g" x/ i( I. J# I# w
//8 e! N$ R2 Z- Q" \0 g5 V
if ( Irp->Cancel || Irp->CancelRoutine == NULL )
$ T3 I5 o3 [$ u. [6 o5 I D {
4 Q0 }& z: Q8 u$ I- f! T t' } DbgPrint( "Can't Cancel the irp\n" );
. g8 o8 @: }1 `% T) p, k! z return FALSE;
; n4 z) g% F4 C. @ }" z2 ~$ G5 Y; G; v; A7 s. Y% M) m
1 {, S- p3 G+ N* A. ]8 F% J
if ( FALSE == IoCancelIrp( Irp ) )" z+ i% F. q& K4 B) }# I. X4 x
{% V; J6 R, m: k9 X' B" o' d- [
DbgPrint( "IoCancelIrp() to failed\n" );8 H& Q! {; v0 M/ z) [! F4 j
return FALSE;, \: F" p9 z+ G+ z" R
} a( f) C6 q" U
, E3 j0 ]! S' {" F% I& T; \ //$ X, `$ f& B: S( F/ k
// 取消后重设此例程为空
/ u0 i' e; f$ k7 z! h* i //
! m7 ?4 a0 \$ y) I IoSetCancelRoutine( Irp, NULL );( l: Y! o3 ?" R" @
% s3 S& q2 L: e1 `, f& _8 ` return TRUE;
; q. R+ p' P) L( Z f2 T1 o}1 `+ A9 J5 T! d" p" r# H! ^
2 S) [) T* L. |, \- R' r8 E
/////////////////////////////////////////////////////////////////
4 c& F8 z) c, q% n& J* Q+ Q3 W: K// 函数类型 : 自定义工具函数
% M& Q1 O9 o& ]2 \// 函数模块 : 设备栈信息模块
1 Z3 ]2 N" q6 F: ^- d( W8 B* s/////////////////////////////////////////////////////////////////
) H/ p- y' [, L' A* ^. C& p; ?3 l// 功能 : 遍历 DEVICE_OBJECT 中 AttachedDevice 域,找到 USB 键盘3 [7 D4 y1 l& Z% d- \* {* I
// 设备上名为 kbdhid 的过滤驱动(Upper Filter Driver)
* j+ ?. J# l6 O" @/ X. y// 注意 :
' ^, I6 [' Z- e6 b) l' M/////////////////////////////////////////////////////////////////& Q" ]$ R- s' t8 t! m" u. m7 @
// 作者 : sinister
: u& I1 n+ K( [% k) ?' }: b// 发布版本 : 1.00.00
4 q6 s' h9 s3 ~8 D// 发布日期 : 2005.06.02
?5 B9 x' K/ S% K% I/////////////////////////////////////////////////////////////////
/ u/ O8 @7 R# n5 |. G/ C: O// 重 大 修 改 历 史# w. n6 [1 u# E) n }" C& D4 ?
/////////////////////////////////////////////////////////////////7 v9 N: R3 e4 q+ T6 e
// 修改者 : sinister
# J( Q6 ?! M/ K2 _; |- [$ h// 修改日期 : 2007.2.12" P9 O. c) S+ J U2 q
// 修改内容 : 为匹配 USB 键盘驱动做了相应的修改( z" l; w# A$ r, c
/////////////////////////////////////////////////////////////////
, w) X$ T) }7 Y' c2 i+ F/ q6 G
9 M4 m3 o" c9 C+ e' gBOOLEAN' e8 F% w' A8 f2 B+ P
GetAttachedDeviceInfo( IN PDEVICE_OBJECT DevObj )
6 T$ x4 c# p6 o8 R4 f7 U( A{
$ O. k' |* r- q: h/ A& C% z PDEVICE_OBJECT DeviceObject;
7 R5 V: l* H# u$ U2 G/ S BOOLEAN bFound = FALSE;8 c$ Y: m% v* R
$ q: e4 S0 y5 E6 I9 Z1 Y if ( DevObj == NULL )6 U# P" G' x. \* `
{
# N% \! t7 t# ^2 ] DbgPrint( "DevObj is NULL!\n" );2 H: V) e5 Y3 s2 l$ t6 |# M. {
return FALSE;
: Q' n) z6 `$ w3 ~" h }
( q6 h) U4 x+ j3 m7 o$ u' Y$ \( y
' t8 B2 K# e/ y; P0 h& M. M9 b7 l DeviceObject = DevObj->AttachedDevice;
$ Q2 h0 g+ o. J2 H g/ S+ Q( n
8 e: S- u0 P) i+ k/ P1 Z& X4 E while ( DeviceObject )
) F! ~* S" u0 y6 `) O8 j% ] {
- c- n9 Z5 d. y* i2 b3 L //
0 j! D+ M* I! \1 y8 G+ \$ ` // 一些 OBJECT 的名称都存在分页区,虽然大部分时候不会被交换出去,但
& w, ?" n6 `$ L, b8 N# z# A! l // 有一次足够了。这算是经验之谈
4 F# Q; I. n- ^8 H //
. A% U0 S3 o. C% v# w if ( MmIsAddressValid( DeviceObject->DriverObject->DriverName.Buffer ) )
. L6 P4 A8 q4 m. E! Z {4 {- v0 U/ c# m. z5 m$ ^
DbgPrint( "Attached Driver Name:%S,Attached Driver Address:0x%x,Attached DeviceAddress:0x%x\n",
# |+ u( y5 e/ u1 Z; H' D DeviceObject->DriverObject->DriverName.Buffer,
; h5 a: u; t U+ C! Z2 n0 r DeviceObject->DriverObject,
) D6 t+ B* r; N3 O v6 Y DeviceObject );
- j. ~9 P6 w( R# o
$ n: o0 |4 L& o% ? { //
; Z V( y0 E$ x: a5 H // 找到 USB 键盘驱动的 kbdhid 设备了么?找到了就不继续了! R. r+ E9 W, F" D+ C# K# N
//
) W4 X6 ]+ m5 n, n; a if ( _wcsnicmp( DeviceObject->DriverObject->DriverName.Buffer,( U z' M% x5 O: r" R: I8 ]
KDBDEVICENAME,
# b9 j5 \9 |4 S7 J& ^0 h( D wcslen( KDBDEVICENAME ) ) == 0 )# O- L3 U4 \) @
{
y# o) F5 q$ ~ `+ G" j DbgPrint( "Found kbdhid Device\n" );
6 _+ G) b* s: c c* g4 V bFound = TRUE;
8 C7 S/ I4 R/ U' U; D- v/ P, S break;
6 p2 J. ~8 Z7 Y }$ w; G% r1 j2 a3 @! k0 P4 M, V( j2 x! R
}
$ X. z, c7 A6 {7 {/ n( F; |" S8 r
8 z# Y) e3 u( T1 r' l! m$ H DeviceObject = DeviceObject->AttachedDevice;1 Q$ X8 B# G7 J6 L5 e
}
7 D3 ?* f( H" R" p
) A" N5 Y% T: H" X7 P return bFound;9 _& f3 Z4 w9 Y3 J+ ]) j( j
}
# x' @, H' F) t; C# g& p
" ?' C1 Q) ~ S/////////////////////////////////////////////////////////////////" A# F3 q! ~2 f
// 函数类型 : 自定义工具函数) o! Z( g& `! ~3 a$ `5 e
// 函数模块 : 设备栈信息模块5 X$ `# a1 ?9 T
/////////////////////////////////////////////////////////////////
, {: o5 \& s0 D; I; ?// 功能 : 从 DEVICE_OBJECT 中得到设备与驱动名称并打印地址
, \3 D/ m" E8 k( S// 注意 : 函数功能只是打印信息,不同环境使用中应该会做修改
; {) [ X* n! N1 J. ?' z///////////////////////////////////////////////////////////////// [0 s4 Q" U9 I5 b7 k' L/ S
// 作者 : sinister- R( r0 @0 {+ d& b/ y9 e" z
// 发布版本 : 1.00.00
2 _! n+ j; H9 g) m// 发布日期 : 2006.05.02
7 W" B, i& t: Y, a7 q1 p/////////////////////////////////////////////////////////////////" _- l4 q2 U/ _3 |
// 重 大 修 改 历 史
P1 @- F* Z) D/////////////////////////////////////////////////////////////////
, B. Y h4 w- V, o) l8 e1 F// 修改者 : sinister
. a$ Y: U. L5 a$ V// 修改日期 : 2007.2.12# f1 s; [4 N" `/ i1 l/ ]
// 修改内容 : 打印出 USB 键盘驱动的设备名称,仅作调试使用6 R/ u% _/ N7 | ^- t. ~0 ?" ^# r
/////////////////////////////////////////////////////////////////% E# W0 l; @3 O" n8 U
) X; b8 n5 {% v6 w+ O
VOID$ F; m6 F9 O; H
GetDeviceObjectInfo( IN PDEVICE_OBJECT DevObj )* k( {0 B& |/ T
{
' R! g& P# k& j6 S8 Q POBJECT_HEADER ObjectHeader; d" o! M9 L! V0 V- f( d
POBJECT_HEADER_NAME_INFO ObjectNameInfo;
. \# k( Y9 z' `' K8 L( r+ ~6 F- x7 V8 \/ Y9 e; I7 M
if ( DevObj == NULL )% `" _( ]# R, W( E
{" `- D2 ~/ E1 K7 d% q' |. x
DbgPrint( "DevObj is NULL!\n" );* T) b7 ?& c1 j8 P/ ~
return; M3 m _& c8 L8 s% p: x
}
8 s2 \/ _0 n0 \2 t1 J. }8 r
9 n5 _4 v) d- T+ J //
% C: W6 r, v; B" C/ ?, A; [7 M0 S // 得到对象头4 H& U* I3 G/ Q
//
. A+ s9 }7 w7 e% ?" `: d9 G9 a% i" t- i ObjectHeader = OBJECT_TO_OBJECT_HEADER( DevObj );' a9 E+ l) c: `2 q( H0 j$ ~6 T
3 K! ]0 B2 H, j7 }" j" Z7 w if ( ObjectHeader )
; m1 X' W3 t2 `0 d: l5 b; u# O {
3 R! R% R9 B7 e2 k: v; ` //( O' t1 A. D# E2 J% r, U4 x" v
// 查询设备名称并打印
# f8 e4 L; f2 g' Z //
( I) M6 D1 Y8 ]* D3 Z y' u2 o2 O- G ObjectNameInfo = OBJECT_HEADER_TO_NAME_INFO( ObjectHeader );
/ J# F# e$ r& l, e/ W
& R+ w2 I5 W! `! R" r6 v$ K2 F if ( ObjectNameInfo && ObjectNameInfo->Name.Buffer )
`5 j8 d# r8 F7 V. U {. S! j+ q) R, u# S5 m. R+ ]7 E
DbgPrint( "Device Name:%S - Device Address:0x%x\n",
; A3 O9 b1 B/ z ObjectNameInfo->Name.Buffer,
% r+ N! j; P4 R8 z$ o3 C* w DevObj );
2 o$ v" h: y, V
9 b! D1 o/ N3 P/ L6 M$ Z //0 M( U% |' ^) Q( ]+ H
// 复制 USB 键盘设备名到一个全局 BUFFER 里,为调试时显示0 y) ]; y' v8 C
// 用,没有实际的功能用途$ i1 @5 I: W) y4 U8 [
//0 I$ g" Z8 P. F; |
RtlZeroMemory( szUsbDeviceName, sizeof( szUsbDeviceName ) );
# z' T7 V. d& f" c7 J7 L0 _/ K
7 h# _ i2 k% R4 ~+ V2 ] wcsncpy( szUsbDeviceName,
- z# @7 `: w, f5 c ObjectNameInfo->Name.Buffer,
- a! t: m% \7 e$ N% c ObjectNameInfo->Name.Length / sizeof( WCHAR ) );
R" s9 l z! o4 @0 B- D }6 L. |4 D) p) g% C8 N
: S* O7 \8 E; x4 f% F# c0 T
//3 {. J) e P3 h
// 对于没有名称的设备,则打印 NULL
2 @9 Q8 W* O- I0 d; M- |3 W' [ //6 E! W' X$ |; A7 x/ K- z
else if ( DevObj->DriverObject )
2 P5 I% h' {1 x+ g {# g+ G- P$ S+ T. z+ W' |. N: k
DbgPrint( "Driver Name:%S - Device Name:%S - Driver Address:0x%x - Device Address:0x%x\n"," l, d: W6 p2 k. y1 f& w1 s
DevObj->DriverObject->DriverName.Buffer,
5 \- g7 [. Q- W' G+ t1 F1 a M L"NULL",
4 L# M: g- s1 M. q* c+ V DevObj->DriverObject,0 c6 h2 @( m4 ~3 h N1 ^* e
DevObj );
; W' B+ a6 K' L% ]% z) P# z- O }: v. r/ G2 z1 m' P B! A0 ^
}
2 T v( s+ [ q# \5 p. Y}3 x# u$ y% F) H
% K% r( ]& J* g/ u4 @
/////////////////////////////////////////////////////////////////
+ P. _5 y- |+ s% f6 L// 函数类型 : 自定义工具函数
( S' h' W5 u9 E7 v. }// 函数模块 : 键盘过滤模块
; V/ d# b3 K6 I/////////////////////////////////////////////////////////////////
4 ^# q3 d7 `5 i, J+ U% z/ K( L// 功能 : 得到 USB 驱动 hidusb 的驱动对象,并遍历以上所有设备/ d N" J! ?) h+ E1 r
// 对象,过滤出 USB 键盘设备,将其设备对象返回
3 I/ w# W4 `, d// 注意 : & P4 ^* m0 {4 @" A/ O
/////////////////////////////////////////////////////////////////) i3 r* e5 h+ Z5 F0 j* s
// 作者 : sinister
% ]6 p3 I, n" b// 发布版本 : 1.00.00* w J, h* t" Q3 A, p) O1 s
// 发布日期 : 2007.02.13
2 ^! t* Z- f$ _2 [4 B4 m/////////////////////////////////////////////////////////////////) L* w# @9 D4 _% Z3 H& F
// 重 大 修 改 历 史
! g. u/ f0 G. O% ]/ n: S' F- v+ g/////////////////////////////////////////////////////////////////
* P" h% G( U8 ~0 H// 修改者 :
7 k4 c' A9 ^" b x// 修改日期 :
% l/ s" A! E5 w! }- i$ i* Q5 W// 修改内容 : % @3 X0 \2 E, z9 l$ U
/////////////////////////////////////////////////////////////////
% b; A0 o, `, Z, S7 J% @7 Z+ ^, _
' L8 U) ^ a7 w% G, J, NNTSTATUS
$ x# A( D7 _, z) j. z' iGetUsbKeybordDevice( OUT PDEVICE_OBJECT* UsbDeviceObject )
+ p1 l7 x1 H3 z) @{ ]/ g1 y+ Z$ Y3 S6 u+ A' Y: _
UNICODE_STRING DriverName;
& @. V' C9 ]! q8 b# \+ ]; T0 [6 f PDRIVER_OBJECT DriverObject = NULL; \' s% o, |+ N+ H. c" H
PDEVICE_OBJECT DeviceObject = NULL;
, @( C9 ^' W0 }) ]: I+ f. p( [9 b5 q BOOLEAN bFound = FALSE;' l# b! x$ {, C+ a
# R% w* f/ x% ^+ `. @ RtlInitUnicodeString( &DriverName, USBKEYBOARDNAME );
Y3 E. k6 B' s5 s' U2 Q9 d7 Q! }1 _
# w: k) a( t$ \1 }( ], g9 e ObReferenceObjectByName( &DriverName,7 @4 N% C$ R% S7 n1 T
OBJ_CASE_INSENSITIVE,
( e+ T& t8 x. U! s" F1 z; z1 E: b NULL,9 m# s, [! ~. J: N9 x
0,8 m5 g1 c- }8 v- c9 C
( POBJECT_TYPE ) IoDriverObjectType,
* d0 q3 X6 G6 p3 V1 A7 f; R KernelMode,
9 ^( }/ f" `6 A- N& v NULL,. @# c& _1 @0 L' o/ y
&DriverObject );
7 k- l L3 m5 b9 r1 K, }0 ]
' M$ F1 x3 N" U0 g4 b6 J+ ] if ( DriverObject == NULL )2 Z% f- T U# L3 j; f
{$ z% d% D; k9 j, n) O; \
DbgPrint( "Not found USB Keyboard Device hidusb!\n" );8 x! s+ }9 H8 h
return STATUS_UNSUCCESSFUL;4 p0 u$ y" f/ E: m; I- l
}
/ O& U' c( ^ `( {. U2 l
. x! \9 F/ Z8 \- j) s- t# ? DeviceObject = DriverObject->DeviceObject;
) B4 _" @3 t8 H
0 f- j' g7 Z* q/ Y while ( DeviceObject )3 j8 X1 b$ W1 X2 P$ X1 e6 v
{: A9 d, V7 N2 e2 w- W X
GetDeviceObjectInfo( DeviceObject );" n" r! o$ z4 a% V
! G% T% q; @; j# w, \
if ( DeviceObject->AttachedDevice )& {7 H2 Z+ t2 C0 S# Y8 P) D
{
+ U; d$ c4 }% ^. p0 p //
5 l' C; x& m2 C: _9 l // 查找 USB 键盘设备4 t' i; W; m7 L$ }9 f" p
//3 ^& N" n* l! g6 [ ^6 q
if ( GetAttachedDeviceInfo( DeviceObject ) )
, ?% R( f! u9 M' ~, v { S9 `3 j5 V+ x! i% P4 r" q
bFound = TRUE;; P" d8 q. a5 }, j: I! i6 @" \
goto __End;
# j1 b/ A/ x4 `" {) m4 r1 M4 Y }2 f9 r1 t6 [7 w- N4 d; ?/ _8 A
}
- D% ~9 C+ j+ o) s3 r6 v5 a. z8 [3 y- q0 O) d7 n ]3 i- s- m. K
DeviceObject = DeviceObject->NextDevice;
% B* z/ v6 Z8 }: n2 y0 L }
3 l9 A `8 i C4 R
$ A' Z8 L& i3 Z+ {) [ __End:
1 c; ^/ G6 A$ L, p$ d7 r' T B
& F# A7 Y$ l6 e% t# S: x* l if ( bFound )* \* y: F5 q! R$ p+ N8 C* q
{4 @3 g# v% W- n
//- e1 N" b% {& H6 Y
// 找到则返回 USB 键盘设备对象
0 W: i. K- A/ A, h6 F //
) Y# r3 ]/ V* w5 K; s *UsbDeviceObject = DeviceObject;
1 d* E% ~* x6 b4 m$ ~ }
5 Q8 ]0 X' j; G' q: b: n- N1 U$ H else0 P# U" q, o5 `2 F8 s
{7 I/ Z+ |# }/ s& L) n
*UsbDeviceObject = NULL;
B$ ~ p% `; P' J; \ }
" X- F% ?" u! }# W
0 z* W% C5 Z- R5 E return STATUS_SUCCESS;3 _# \/ P' F0 P; C" `7 N
}& M# [7 V4 C8 ^$ Y
# B( _- N" e8 u" Y: ^ q" G/////////////////////////////////////////////////////////////////( F( B6 k4 @3 g. M( y9 a
// 函数类型 : 自定义工具函数 ?. Y6 V0 N8 A! R
// 函数模块 : 键盘过滤模块
, Q9 V* s8 n# c! D h0 O////////////////////////////////////////////////////////////////
+ }0 R' g- { a2 y// 功能 : 创建过滤设备将其附加到需要跟踪的设备上,保存设备相关9 I$ g& [1 l9 u7 ]# Y
// 信息,返回附加后的驱动对象
, _. |' L7 W# Y4 k8 a8 x* e4 \// 注意 : 此函数仅挂接 USB 键盘设备% W5 ?3 {0 Z4 @7 v
/////////////////////////////////////////////////////////////////
/ l* ? a" F6 Y: K$ d// 作者 : sinister
; w# h/ S! I- e) q& G4 X d* W' D// 发布版本 : 1.00.00
9 i' Y, h' |' [8 z; ~// 发布日期 : 2005.12.270 j8 ]: h; ], q5 b& I" `0 A
/////////////////////////////////////////////////////////////////( y+ B# l$ ~) X o2 Y% P, y3 v
// 重 大 修 改 历 史0 S1 y8 q- ~$ F9 r
////////////////////////////////////////////////////////////////; S5 n! g3 z, m, d
// 修改者 :
- ^: s' O3 H. m' q) }/ b/ N// 修改日期 :5 J9 T* v) ^ ?3 T2 o9 {
// 修改内容 :' W1 i/ r9 P; H) }. K
/////////////////////////////////////////////////////////////////1 ]" o! `( P; f$ S% |, b; f
, ^6 [- _, W- @1 C
NTSTATUS2 k1 h6 Q2 M- N1 ], F& ?
AttachUSBKeyboardDevice( IN PDEVICE_OBJECT UsbDeviceObject,
$ K; w$ {5 ^: z* u( U9 P IN PDRIVER_OBJECT DriverObject )
% Y9 q8 c$ x @! F0 {( S, M{
; L/ z$ t# {" r. ?$ V. k! |4 A PDEVICE_OBJECT DeviceObject; 5 J6 J6 i6 _ f: h h
PDEVICE_OBJECT TargetDevice; ! ^: a0 O( \# d' k+ v2 Y% ?% `
PDEVICE_EXTENSION DevExt;( C$ I7 m0 l; n+ P
NTSTATUS ntStatus;
7 ]3 B) E) n( y: R. h4 {' p! m7 ]' O" Z. w
//4 N' I4 }4 L" `! }4 ^$ g3 Y: j8 F
// 创建过滤设备对象) b& Q2 I9 x8 e$ R; {3 Y; P( o1 m
//
) f" t( ~: j( A, x3 c ntStatus = IoCreateDevice( DriverObject,
8 K- [; b# m/ ?4 |/ d& w. u sizeof( DEVICE_EXTENSION ),
, b' ?# b) p: R4 P* w NULL,% w% p6 o( z/ M# G6 q
FILE_DEVICE_UNKNOWN,8 I) s% q Q: ]/ W7 D
0,( _% U/ [+ d% i2 @3 o
FALSE,* e" T; u9 S. z. P, d3 g/ i6 U/ d
&DeviceObject ); 0 I' D% h# u7 p- t1 {: x
4 J* w2 i& M+ g: ^; }. k
if ( !NT_SUCCESS( ntStatus ) )
9 P, k5 S- T+ S, f' } {; i& D. o2 E- F
DbgPrint( "IoCreateDevice() 0x%x!\n", ntStatus );# j* n0 u& e" ~
return ntStatus;/ o% O' |) q, M1 D
} ; w2 s- O( w5 D, W$ {0 U* w
9 I2 j, J4 M1 ]9 G' L/ V3 [# R1 ~ DevExt = ( PDEVICE_EXTENSION ) DeviceObject->DeviceExtension;
^3 o; |/ Q6 }& M' J1 Q& B5 S9 p, s" b$ |
//
7 h1 L& f: ]" p0 s, X // 初始化自旋锁
0 g) o4 A t$ C+ l //& d/ ?" X; F4 D7 A( F
KeInitializeSpinLock( &DevExt->SpinLock );" A) ~ P4 u- u( Q* f" f; L0 |
4 F" S( G5 r- B6 p( j" j$ L6 }0 T! O
//. b, T: U; f: g9 O; g" Y
// 初始化 IRP 计数器1 ~: h7 \4 D; ?
//* \- k/ k. F- ?% E& H
DevExt->IrpsInProgress = 0;
. J+ d. E8 {5 J7 q& C/ J7 {# d: W# H- n) V& h
//, w5 O! l( Y; K' h' {4 ?
// 将过滤设备对象附加在目标设备对象之上,并返回附加后的原设备对象$ z5 Z8 p, ?+ m4 m0 G* u
//
4 X& N/ m$ `" g6 f- P7 |) p$ F/ F1 v! c" m0 W
TargetDevice = IoAttachDeviceToDeviceStack( DeviceObject, UsbDeviceObject ); / @& D! ~2 b' U$ W
if ( !TargetDevice )
2 p0 L. e$ L; w% N4 |" w& M: ` {
. T* G( {+ X: a! |; P IoDeleteDevice( DeviceObject ); $ K. O2 e; x' P
DbgPrint( "IoAttachDeviceToDeviceStack() 0x%x!\n", ntStatus );
; ]6 L8 g: r) g- ~/ G return STATUS_INSUFFICIENT_RESOURCES;" c: \" J- u4 V) \% Q/ [. ?2 v
} - C& D7 x# a& L! U
- Q7 g- h$ {6 m. s A2 M //
9 l0 j6 J1 Y% Z+ g* x3 D& H z // 保存过滤设备信息
3 W c" x0 ]* r5 f) a //0 Y& R) K3 t# s1 b7 g
DevExt->DeviceObject = DeviceObject;
) \6 Y! {% H& s" i DevExt->TargetDevice = TargetDevice;% b. z! X& R% @+ O
- n" W$ n6 u3 c9 e( L2 `' @ //
+ z! x* [2 ?, Q. s' b8 h. e! u // 设置过滤设备相关信息与标志/ w; \+ \+ q) d' @, z( Z5 k
//
3 y6 h* x( \7 _) d6 l$ k DeviceObject->Flags |= ( DO_BUFFERED_IO | DO_POWER_PAGABLE );
, @. A, @2 g7 | DeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
; J8 m _) m8 @; k0 v" `& O) ~; Y) u* `8 G" j( @" T
/ i* E. I" J+ i* Y& N; Q return STATUS_SUCCESS;6 C8 |! x: G+ O& O
}2 J; g+ x- G% q0 w4 m; y: U3 p- ?
+ g4 D v T) D* E5 ^9 w
/////////////////////////////////////////////////////////////////* _5 s! z7 s f- V) w$ @/ t
// 函数类型 : 自定义工具函数
! `) [7 ?: ?6 g: h: I/ Y7 {: Q9 U// 函数模块 : 键盘过滤模块
, ~0 G/ y. o9 q! S& s+ N B1 O0 _1 Q1 t7 y////////////////////////////////////////////////////////////////9 t) H+ @* P; {0 g
// 功能 : 创建过滤设备将其附加到需要跟踪的设备上,保存设备相关
1 `8 p( O" ?, {" }6 L3 S J: t// 信息,返回附加后的驱动对象7 y. E/ Z1 n. J) c& R7 ~* ]
// 注意 : 此函数仅挂接 PS/2 键盘设备
: P O1 ?( d4 A Q' V' l5 X0 t/////////////////////////////////////////////////////////////////
6 ^) M$ [& j3 X2 S' K8 H// 作者 : sinister
. |# p& [" M4 j7 x// 发布版本 : 1.00.00
! G4 P z, J! e+ B* A1 s6 j; K0 F// 发布日期 : 2005.12.27
7 c) M. Z8 ~- @ u" w* u/////////////////////////////////////////////////////////////////4 M8 i% T8 n# c. k/ F) t( @
// 重 大 修 改 历 史
2 m3 G/ {* [1 D* |3 a/ R////////////////////////////////////////////////////////////////+ ~/ i) x7 N3 _
// 修改者 :' s7 \' _, A5 Y& }3 z B
// 修改日期 :
! A6 ~" j- z8 m5 K w8 i// 修改内容 :; J+ t9 o& q' A, o/ o
/////////////////////////////////////////////////////////////////
- V0 V) Z" D5 s
0 r. l4 O2 c# d3 k2 | ]1 BNTSTATUS8 L; f' P0 g8 W; f/ V2 U
AttachPS2KeyboardDevice( IN UNICODE_STRING* DeviceName, // 需要跟踪的设备名* g' O% M; M6 }' h6 q
IN PDRIVER_OBJECT DriverObject, // 过滤驱动也就是本驱动的驱动对象
) J# V0 q% \4 n: M5 u OUT PDRIVER_OBJECT* FilterDriverObject ) // 返回附加后的驱动对象7 [; O5 e$ X' w }3 Y& K
{6 H% d/ X# k/ `. t: {
PDEVICE_OBJECT DeviceObject; / b/ f2 _5 c% _- S' D( U1 y4 R
PDEVICE_OBJECT FilterDeviceObject;0 q7 |$ Q$ G' m0 R3 z
PDEVICE_OBJECT TargetDevice;
; n3 u3 T; R# }' j PFILE_OBJECT FileObject;
& Q* c" x9 Z: Z% n: I" Y9 l PDEVICE_EXTENSION DevExt;5 W6 @+ D2 g0 \( X: P6 F7 Z! o
( \4 H9 T, M7 K
NTSTATUS ntStatus; 3 A$ Q' o4 i" M
; X: O6 \0 D2 H! Q2 b Y/ y
/// u9 b9 h5 _2 v/ J ~0 j4 ]; g
// 根据设备名称找到需要附加的设备对象7 i7 O/ }, w$ [9 ]. w5 Y0 w
//0 q9 q& w i0 h" }9 ]
ntStatus = IoGetDeviceObjectPointer( DeviceName,) \& I2 e6 s* [
FILE_ALL_ACCESS,
# y: j" D2 A! x- w &FileObject,8 k% b, U- s6 x. N
&DeviceObject ); : I! s2 ^8 n5 b1 L5 x& B1 C
( U5 Z* l, w9 z
if ( !NT_SUCCESS( ntStatus ) )
0 U X: q) S0 E0 F4 A j {: k4 ~; C1 \1 y
DbgPrint( "IoGetDeviceObjectPointer() 0x%x\n", ntStatus );3 U& T* T& F1 R3 Y" ]
return ntStatus;
) o' e5 _2 y. P } 4 o. y2 E/ M* z) X$ i# F, R8 e
1 J/ j& m! u0 t5 ~ //
, e! K2 d4 J) a: d1 k2 x, ]$ X // 创建过滤设备对象
. R# k) D' z6 q( Q; [ //
& y" u- U4 S+ P4 j3 C ntStatus = IoCreateDevice( DriverObject,7 i0 A- Q" I; Y! V2 O( h
sizeof( DEVICE_EXTENSION ),
- S/ l. i6 r% x NULL,
8 H2 Z) J* T# c! B% P1 h FILE_DEVICE_KEYBOARD,
/ p0 a2 X& X+ n. E3 _; N 0, C y6 T6 P# Q* _8 l
FALSE,
2 L' D! K$ ?- K3 ~, D &FilterDeviceObject ); ; k& d5 E* I' W' |3 Z
3 z* A$ H& `3 F1 u$ [0 @6 ?9 P$ L
if ( !NT_SUCCESS( ntStatus ) )
- @) l# O; L, Q9 a% x {# P9 T, r# t8 P4 M
ObDereferenceObject( FileObject );
2 B5 Q/ i; Q. m1 p! j2 ~# @ DbgPrint( "IoCreateDevice() 0x%x!\n", ntStatus );
3 R9 q" d* T6 l, y* z# A$ i, \0 } return ntStatus;
+ w$ W. b9 q1 V# j } ) \4 a1 T, K6 h. Y, L+ B
' K0 U* M4 q( @3 C //
% }0 N3 A! u Q // 得到设备扩展结构,以便下面保存过滤设备信息6 z; N3 m- S: h. [$ F) J
//
. o6 D+ p" I% c; \- w6 v DevExt = ( PDEVICE_EXTENSION ) FilterDeviceObject->DeviceExtension;6 Q. r2 s7 v( U1 P* _4 C
2 R/ D4 `. ^# |! W
' m ~( t5 Z) r8 G4 [3 w //7 |# U/ A% S4 I' N
// 初始化自旋锁
! [8 D1 W8 G, Z/ d //- I8 |1 ~& E0 ^# J
KeInitializeSpinLock( &DevExt->SpinLock );8 S% v3 D8 N, Z6 Y6 M
6 r, `5 U: X/ L5 f( i
//
) v8 c X( K# X h+ U. M // 初始化 IRP 计数器4 Z! E6 z" l& I: ]( G, b& J
//
1 \0 d7 e% h# ~% L3 E DevExt->IrpsInProgress = 0;" Q% t4 I; r) u/ `& T, G2 s
+ ^7 a! E. \1 N" F1 G( w A
//% w! ?7 d3 q) ~
// 将过滤设备对象附加在目标设备对象之上,并返回附加后的原设备对象" _) ^) | S8 ?4 p1 N r' E' `) y
//
# G8 p: b0 d2 f TargetDevice = IoAttachDeviceToDeviceStack( FilterDeviceObject,* V3 I4 |; K; e h: f' k7 [' `+ s
DeviceObject );
( ^8 S/ E9 c4 M w' } if ( !TargetDevice )
1 C" r7 f. i5 c: ^' G1 W {1 [6 q" d0 y! e5 v& p
ObDereferenceObject( FileObject );
& T7 [- }8 y6 e5 c. f8 }9 A IoDeleteDevice( FilterDeviceObject ); 3 j+ P$ N+ S/ _. n6 e- F0 E
DbgPrint( "IoAttachDeviceToDeviceStack() 0x%x!\n", ntStatus );
& L! i5 R9 }( J2 ^ return STATUS_INSUFFICIENT_RESOURCES;' S; Z1 W* F* \5 {$ P2 o
}
/ Q$ [5 s8 z# D( z9 D( K% ~
( _& Q5 s4 V! L" _, R //
( \) ^6 Y1 Q) K3 d, }9 F: M // 保存过滤设备信息
3 \+ Q, b2 V% K% [5 s //. u4 g2 L- ~# x" U
DevExt->DeviceObject = FilterDeviceObject;
6 c* M/ x; ~, k* Z1 t* F DevExt->TargetDevice = TargetDevice;
. {( E' l$ }$ D, r5 o: s1 J% ?. w DevExt->pFilterFileObject = FileObject;
. I9 W5 @5 H( b9 z6 F2 h) ?7 U* m6 y, v; e. g# ?0 V
//
) `1 j- e9 r7 j" g* @, f( Q, O6 E // 设置过滤设备相关信息与标志 ~+ e5 \4 W2 B3 c/ j0 N" ?9 |
//
% C p" P1 [2 c! R( z FilterDeviceObject->DeviceType = TargetDevice->DeviceType; * {% J/ P" J, ^, q& r6 m
FilterDeviceObject->Characteristics = TargetDevice->Characteristics;
" R# S2 ?- r; |' n! j- D; \$ c FilterDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
1 k2 W0 E0 T6 l# h FilterDeviceObject->Flags |= ( TargetDevice->Flags & ( DO_DIRECT_IO |* t1 g4 B' T9 _5 C% I/ k
DO_BUFFERED_IO ) ); , r" ?0 a- ? C4 m: l z
$ k$ L @6 a% F, z; ^
//
; O% F& D8 C4 x3 r5 } // 返回附加后的驱动对象; J6 D& ~2 W0 Q& D9 Z4 _5 M
//& i( u7 l1 B5 A. ?# K& j2 U
*FilterDriverObject = TargetDevice->DriverObject;; C% S* w7 q/ T
+ c* `7 d& ]4 Y7 S; C% _
ObDereferenceObject( FileObject ); ; \ X0 }* Y& D4 z5 c! ?
- G( P9 \) u" ]1 R- j: j
return STATUS_SUCCESS;8 W: Y1 A" b4 r# l, P4 T
}7 y* R7 b& I7 l2 _ X# H$ _3 r% ]
; K6 i! e. m6 o4 O. D( M G/////////////////////////////////////////////////////////////////
i8 u. O1 x: ]- Y% O// 函数类型 : 自定义工具函数8 {, Q0 F- _9 t' M
// 函数模块 : 键盘过滤模块9 w1 d/ ]1 x1 ~
////////////////////////////////////////////////////////////////
; T/ M: u3 e" {$ j+ o7 T. c; D// 功能 : 键盘过滤驱动的 IRP_MJ_READ 派遣例程,所有按键将触发
6 d) x2 r o4 V* l$ M, z// 这个 IRP 的完成9 \! I& q$ j4 I7 d% F- Q
// 注意 : ' ~ o3 p0 A7 o( Z; X5 e7 D
/////////////////////////////////////////////////////////////////" _) l. A( q5 x1 d! ^! k% p# M% C
// 作者 : sinister
* ^ N: H7 p8 ^/ n2 j// 发布版本 : 1.00.00
3 f. X) U9 F6 H u// 发布日期 : 2007.2.15' b$ \ R9 d, G! M6 @" T% {4 e
/////////////////////////////////////////////////////////////////' `5 ^6 V( z5 e
// 重 大 修 改 历 史( k3 t& Q0 o+ T
////////////////////////////////////////////////////////////////$ K2 }( S7 c$ c9 j t. A1 @' R1 L
// 修改者 :" o' {4 m& R( Z1 {, C8 W
// 修改日期 :& o) |/ s' x* x; P' Q' g: N# m
// 修改内容 :
* t8 ^# O3 j6 B& m4 h5 Q/////////////////////////////////////////////////////////////////
: H) R' P! d, a R$ x* Q# T
/ p" O1 l7 g- w4 R6 Z0 i& b$ aNTSTATUS
: K) F: Y2 |0 d% z& jKeyReadPassThrough( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp )6 c" W" e* |- i3 m
{0 w1 T) ?& y l8 ~2 C W
NTSTATUS status;
& s7 q2 m) k2 d/ } C KIRQL IrqLevel;
- J+ C" l1 I: t3 @, V' J W$ c b
% { F( k3 p- Z& R+ X PDEVICE_OBJECT pDeviceObject;
3 o' T8 ^* B$ F0 N5 m% O PDEVICE_EXTENSION KeyExtension = ( PDEVICE_EXTENSION )1 ^; Z5 `1 {" n- O
DeviceObject->DeviceExtension; 9 j0 C6 H: @$ G. M) }* Q
* C I# N: H' X
1 W4 B& j+ S8 z) J' n8 s; j IoCopyCurrentIrpStackLocationToNext( Irp );3 f- h2 F; ?' T" _
* J* y c) a, k3 I1 h; \
//$ @0 H" }$ c H0 Q3 u' Q
// 将 IRP 计数器加一,为支持 SMP 使用自旋锁
3 B. M" K9 _' M: Z: ?/ b; _. W //
) j4 ?; V1 Y- o KeAcquireSpinLock( &KeyExtension->SpinLock, &IrqLevel );
$ L: A8 t1 V! _( i2 { InterlockedIncrement( &KeyExtension->IrpsInProgress ); C2 A G1 y6 j' H1 U
KeReleaseSpinLock( &KeyExtension->SpinLock, IrqLevel );
& k# `( s- i4 J
) o) z8 q1 T6 A" }0 m x IoSetCompletionRoutine( Irp,0 [; I9 Z. | u) K7 U3 x: i
KeyReadCompletion,
, H; |6 k, q" u( D DeviceObject," [4 s$ A1 Y M: f4 h. M
TRUE,
" R; j* G9 o) M4 ? TRUE," v/ }% V6 l7 O+ B
TRUE );
( G+ P4 w* U6 l/ J0 B; h; J% ]% @8 Y; X
return IoCallDriver( KeyExtension->TargetDevice, Irp );+ k! s! A0 n9 C5 m6 t4 x' w2 ^2 \
} 1 ]7 F* Q4 G) a7 K
% l, @! u3 | R3 x
/////////////////////////////////////////////////////////////////
- N: c, G6 N+ D' n, A// 函数类型 :系统回调函数
( b' ]6 S8 v: f0 W4 c// 函数模块 : 键盘过滤模块
1 G5 y4 Z" ?& x+ e////////////////////////////////////////////////////////////////0 q+ C# ] h6 `3 j' Q& S. }
// 功能 : 获得键盘按键,用无效扫描码替换,以达到屏蔽键盘的目的
4 @1 W2 j4 K, Z) `; ]// 注意 :
( a2 x) _& R* g; i/////////////////////////////////////////////////////////////////
1 L- P9 p/ [7 ]! u; u' O" b5 t7 o// 作者 : sinister: z5 }. O: h6 n
// 发布版本 : 1.00.00
* s9 `; {6 ^, Z# b- ?// 发布日期 : 2007.2.12
( k+ q. o M1 Y+ s( B/////////////////////////////////////////////////////////////////
, [% q _, g9 U// 重 大 修 改 历 史. I% {: X3 u% B7 K
////////////////////////////////////////////////////////////////) }1 A& N% T8 h) d2 ~
// 修改者 :
+ y( |& z w; i// 修改日期 :. D( N1 P% V' f- C# z
// 修改内容 :; E' N$ O/ p# h& I9 B% T" c. f
/////////////////////////////////////////////////////////////////; j) a6 {5 n5 M3 A
% g7 q0 B& w, y- _, |5 vNTSTATUS0 w% [# ^2 E3 l8 u* `; ^0 B
KeyReadCompletion( IN PDEVICE_OBJECT DeviceObject,
9 a/ m) p3 y) @) l IN PIRP Irp,
2 \, w$ w% P4 _0 @5 s IN PVOID Context )& X* n7 `# S& `2 l! ]/ u
{
! I; q9 f# M, M, t PIO_STACK_LOCATION IrpSp;
% f! C9 O8 G8 h4 o PKEYBOARD_INPUT_DATA KeyData;
9 |4 K; @/ c9 S PDEVICE_EXTENSION KeyExtension = ( PDEVICE_EXTENSION )
# B, S2 N, m: P, _1 k DeviceObject->DeviceExtension; % _% N+ y. U8 a- A
int numKeys, i;
* E% i1 [5 t& [+ b% S* F; C/ C( t KIRQL IrqLevel;
) O0 w# n% p/ s d1 X" h
2 J7 E4 A0 K" ~# X, X3 Q- m5 Y IrpSp = IoGetCurrentIrpStackLocation( Irp );
# i& N" H% R2 I9 r$ g9 }# {2 Z S8 C* }
2 h n0 V+ ?- d3 C6 m1 U1 B6 ~/ q/ e
if ( Irp->IoStatus.Status != STATUS_SUCCESS )
9 q& K' z6 j: _/ T. O {
+ _: ?% Z% Q% V w/ n% ] DbgPrint( "ntStatus:0x%x", Irp->IoStatus.Status );
, t3 ]7 f7 f3 v goto __RoutineEnd;
5 N2 ~% Z5 Z: g$ C& L }8 i2 z& j+ J# _: @4 \' e
- w; X2 C0 J# {+ D! ?
//
7 a3 K% ?, K( {! f6 p# { // 系统在 SystemBuffer 中保存按键信息
$ x, Q2 T* k. P- i9 J //8 y$ y% ~# d. V, `! P1 Q
KeyData = Irp->AssociatedIrp.SystemBuffer;
* Y. ~* f. l+ [7 z2 Y if ( KeyData == NULL )& X2 r5 e" Y) |5 `# |' H& J
{ c; f1 A2 N9 c7 |) O4 W
DbgPrint( "KeyData is NULL\n" );
1 u# ~7 N. x0 F9 a9 i) i8 i goto __RoutineEnd;' r/ {9 t( u/ j* a$ f6 s! M
}
- m4 q; U4 a3 |7 O" R _4 J0 c1 O( a4 i; M9 b6 M6 a: R
//* b; A2 \$ u7 S1 B1 l# r
// 得到按键数! T6 y5 A9 G$ i: i( K
//
/ ~3 L8 K- U; d8 c2 V numKeys = Irp->IoStatus.Information / sizeof( KEYBOARD_INPUT_DATA );
2 k u- E* n+ v0 I2 t! ?4 w$ K if ( numKeys < 0 )
0 C4 i' I0 o6 B5 I {* M3 K: q3 x+ ^% K; Y0 U
DbgPrint( "numKeys less zero\n" );
# x3 p9 p# g5 Y. s: R goto __RoutineEnd;
! B, H+ x( |5 D( Z }5 J2 t" a" L7 J( j' S
) I( G T( X. P2 K t8 b: U+ ^ //
- ]# ?( G- m. Z" l* l0 F7 n# D. V // 使用 0 无效扫描码替换,屏蔽所有按键
9 |& B q% h8 L //7 D, ~1 x6 x- u9 P4 B W3 g
for ( i = 0; i < numKeys; i++ )( a- S7 M e0 x9 b0 h
{
; B1 h4 g1 J2 M; L1 K DbgPrint( "KeyDwon: 0x%x\n", KeyData[i].MakeCode );# E5 _( o Y: z! i5 x, v l5 U8 I1 V
KeyData[i].MakeCode = 0x00;
; \$ C- l# `" W }
, f: D9 T' p1 C3 s6 S0 H3 b" E; L \% X9 J: i
& P. U& ?( j: h1 q __RoutineEnd :
! b3 j* `% D) k+ ^- c' ?
V. b; F' }6 E5 ^8 w4 _2 v) v if ( Irp->PendingReturned )9 T; h6 X, j+ ^6 b- x# I
{
?! j7 B) O) J, G q' m! u0 g IoMarkIrpPending( Irp );7 P, p5 _# H# n% ]
}
; }' o1 Q" H) @6 y" H8 [5 r
4 ]( h2 j, i6 F2 x$ A //$ f- K' g2 M6 P
// 将 IRP 计数器减一,为支持 SMP 使用自旋锁- s: s0 J: q8 }8 o d
//
: ?3 t+ A3 |& v0 n KeAcquireSpinLock( &KeyExtension->SpinLock, &IrqLevel );7 r+ o) `8 E/ ]2 n# F& r
InterlockedDecrement( &KeyExtension->IrpsInProgress );; ?8 p8 v" V7 a! y \4 g
KeReleaseSpinLock( &KeyExtension->SpinLock, IrqLevel );
3 a3 n% z: a: l
% Y9 e- y/ h/ k7 f& _ return Irp->IoStatus.Status ;
( B9 Z" C" O0 K+ O; }# `0 j} . p* ]0 Q4 c O+ u: {
* \9 h y3 @3 c3 o& e
+ d7 t0 Z; D6 C
/***************************************************************** d$ X. O1 e! g1 d( F8 {
文件名 : WssLockKey.h+ q% r% U0 d6 X/ u1 e
描述 : 键盘过滤驱动
; n; u( ^8 X. j; I, J) W 作者 : sinister+ z! }- B+ B# q: K, y' T R# ?
最后修改日期 : 2007-02-26
5 a- r; Z: y1 Y8 j. p4 d4 P1 E*****************************************************************/
* h7 m& u% x! K4 T. O( d/ n3 j2 z+ J! L, U; K8 j
#ifndef __WSS_LOCKKEY_H_% _0 Y1 ]+ m Q8 F7 b/ \- O$ @
#define __WSS_LOCKKEY_H_) i L- ~2 N$ }1 i# v
1 T6 R* }6 ?2 t+ M. V
#include "ntddk.h"
0 I" P7 p3 T2 o! _4 r#include "ntddkbd.h"
9 \$ p) p8 S8 }0 J#include "string.h"
# x# Q* i& e/ @#include ; I% e. o' I" u W* y- r
( G4 L( I( A5 ] U3 ]
#define MAXLEN 2560 B5 }, y* _3 F% G" }/ p0 k
3 ?2 Z$ R8 e. n7 }
#define KDBDEVICENAME L"\\Driver\\kbdhid"- e3 I0 u f) k5 Y% ]6 U( ?
#define USBKEYBOARDNAME L"\\Driver\\hidusb" 0 X' y- o* l" Y
#define PS2KEYBOARDNAME L"\\Device\\KeyboardClass0"3 p) d- l# K& ` X( ]! N. W
; P) A& C( \' }( i7 R0 U
typedef struct _OBJECT_CREATE_INFORMATION
! L2 R4 U5 k- R! a- `{/ W3 v0 M9 v: a- S6 H4 |
ULONG Attributes;
! F5 ^7 b, G6 I' S HANDLE RootDirectory;# V) x h% r' ?" Y$ l: [2 f
PVOID ParseContext;
0 p& J# b! q3 A0 y6 O! I1 B KPROCESSOR_MODE ProbeMode;0 T" z6 k% D, r7 i, P7 M: S
ULONG PagedPoolCharge;: j( V7 x9 T. N. b3 v0 v$ g) {. D
ULONG NonPagedPoolCharge;& P: p8 ^ z+ @6 h
ULONG SecurityDescriptorCharge;9 \, a# O3 c: B
PSECURITY_DESCRIPTOR SecurityDescriptor;
0 l' I" I/ s$ y PSECURITY_QUALITY_OF_SERVICE SecurityQos;
: D3 z; } t0 p* h0 i6 }7 `1 [, D SECURITY_QUALITY_OF_SERVICE SecurityQualityOfService;# D* @ N( l) L1 N8 u$ ~" ]1 m
} OBJECT_CREATE_INFORMATION, * POBJECT_CREATE_INFORMATION;
' c, i6 p9 n) ^ E
1 r7 D! W8 E( g( Y# dtypedef struct _OBJECT_HEADER
" X6 B# b; ^) Z1 F* K{8 u( j! p& Y" I
LONG PointerCount;, L# k9 y" H0 f/ ^
union9 }6 q( D: C% h1 h. `: [) L
{5 R: ]. B" n T: C
LONG HandleCount;$ R+ ^% c! N% w0 o
PSINGLE_LIST_ENTRY SEntry;
5 Y7 }/ F/ {! v4 i! I };
, W. Q3 e! L- @. d9 N( L$ H POBJECT_TYPE Type;7 J3 M, J5 Y3 G& y9 \4 d- X
UCHAR NameInfoOffset;9 j6 ]; E* _4 B2 {3 v: O
UCHAR HandleInfoOffset;+ E* q& Y, P9 c3 v& Z& Z/ E: Z% I! d
UCHAR QuotaInfoOffset;$ w3 ]& c6 t$ r' P, o1 {& s. b
UCHAR Flags;; H2 ?7 ?- @! _# [$ [ c8 ~" C0 p
union
$ m- t# X, E3 k1 ^ {* |7 P5 t# J% E
POBJECT_CREATE_INFORMATION ObjectCreateInfo;, Z3 ~, w3 d0 ^4 f1 V k
PVOID QuotaBlockCharged;5 T. P7 R& g: r+ G$ T, p) d9 {
};2 z3 v1 p w4 }0 ?4 d, N
h" O* S; [) ?5 J1 i. P PSECURITY_DESCRIPTOR SecurityDescriptor;! L Z* y7 n; q9 Y; R; M
QUAD Body;$ A+ o3 m O) k4 O+ s/ A2 r5 d
} OBJECT_HEADER, * POBJECT_HEADER;
6 T# ^% G0 C+ j7 Y. [
9 O+ m6 _: a' E% X9 X! S {! S( v#define NUMBER_HASH_BUCKETS 37- x. `& z4 |5 X& d; V
. ]% P4 p3 f; x! i" `
typedef struct _OBJECT_DIRECTORY) _; R) A9 x; {6 I! H3 ^
{% E& z& K" m' r% {3 G+ X7 p2 @# l
struct _OBJECT_DIRECTORY_ENTRY* HashBuckets[NUMBER_HASH_BUCKETS];% E' O2 b: t3 A% p& e6 X
struct _OBJECT_DIRECTORY_ENTRY** LookupBucket;0 Q% i7 ?! q- |% E3 g0 J
BOOLEAN LookupFound;7 x5 {3 r5 s, |4 T% _% H
USHORT SymbolicLinkUsageCount;
( H5 s& E: ~# w% U4 j( e struct _DEVICE_MAP* DeviceMap;/ j0 n4 W4 i ?, z1 i
} OBJECT_DIRECTORY, * POBJECT_DIRECTORY;
9 b* X; Y3 i& d+ D* ~* I
1 B/ F, O+ X3 b* x( f: f& Stypedef struct _OBJECT_HEADER_NAME_INFO& ]) U, P; O7 t
{: G/ W: {3 F% H% |% [
POBJECT_DIRECTORY Directory;/ E: S: r$ x! I- |; h
UNICODE_STRING Name;
3 m1 B8 L {2 w( u ULONG Reserved; @9 c% u3 w* d( w' m# }+ C
#if DBG
) ?, }, F: T" q% H, S$ P" ` ULONG Reserved2 ;! }. V4 D1 k/ F a B
LONG DbgDereferenceCount ;
7 \' l& p" N1 j# o! }/ Y" w c4 O* p#endif
+ b v- `* a% k P9 @: J7 Z} OBJECT_HEADER_NAME_INFO, * POBJECT_HEADER_NAME_INFO;
: p1 W. U3 T) d$ r' ?7 `" A) ]3 I- z6 t* L5 Q
#define OBJECT_TO_OBJECT_HEADER( o ) \
0 l4 s' K& J* ?6 \7 g CONTAINING_RECORD( (o), OBJECT_HEADER, Body )$ |) O3 Z+ h3 x. {. R
8 S, }% h0 X8 H0 Y#define OBJECT_HEADER_TO_NAME_INFO( oh ) ((POBJECT_HEADER_NAME_INFO) \
* B( @- _8 @& I ((oh)->NameInfoOffset == 0 ? NULL : ((PCHAR)(oh) - (oh)->NameInfoOffset)))
0 g; j( t# t" C9 _) t* Z% S3 W$ D3 _# M9 U- b6 n7 {7 n( W
typedef struct _DEVICE_EXTENSION4 w0 y* b0 X7 J& D# W& \
{
9 n; D8 Z& Z3 o4 a) e) O5 e PDEVICE_OBJECT DeviceObject;
1 `0 s$ f0 L' p4 d- u- E PDEVICE_OBJECT TargetDevice;
7 c0 n1 a" R6 d, e5 o PFILE_OBJECT pFilterFileObject;
" \5 H+ H! s# p) m6 F2 C/ x ULONG DeviceExtensionFlags;
0 |* e, d' z$ ?$ d, m4 |' |6 B LONG IrpsInProgress;
: s3 z( C" b- u- c- c3 O% T5 N, f. R KSPIN_LOCK SpinLock;
$ w z) z4 a7 L$ F}DEVICE_EXTENSION, * PDEVICE_EXTENSION;
( l& w' [/ K) Y ]" S3 G& @6 }! H
: _# w) @: [ ]4 mVOID . w' i$ Y; h0 ]& ]% V/ p7 I2 o" r
KeyDriverUnload( PDRIVER_OBJECT KeyDriver );
+ ~4 c0 I# s& G% u5 u! x& V% z# }
BOOLEAN. k2 {7 K4 O$ i$ H" a- J
CancelKeyboardIrp( IN PIRP Irp );, P0 Q# d, C0 ^2 k
+ p$ s! J' H+ e* P: I- d! H. S" \extern POBJECT_TYPE* IoDriverObjectType;, m. l% {' A( E+ s2 [, m g9 D
! W* ?- O w' H9 t' V6 lNTSYSAPI% K' |+ t) R4 I% O/ D: i
NTSTATUS- ~ k5 ]( a; Y- W$ G7 C* m
NTAPI ObReferenceObjectByName( IN PUNICODE_STRING ObjectName, y% G& T% V) g1 x
IN ULONG Attributes,
8 Y H. q* ^) c IN PACCESS_STATE AccessState OPTIONAL,9 {* O+ i8 o$ y- |7 K; A4 O
IN ACCESS_MASK DesiredAccess OPTIONAL,
0 Z8 e9 s; X. Y% K IN POBJECT_TYPE ObjectType,4 c' b& N7 ?+ P( e& |+ p
IN KPROCESSOR_MODE AccessMode,
' h! |9 W5 v' E7 Q% d+ _# X IN OUT PVOID ParseContext OPTIONAL,
) T/ s1 w& H3 ^2 D* Q OUT PVOID* Object ); f8 u5 X" Q" c- J
* F) {2 I9 ?3 ^& J& q+ z$ k6 r
NTSTATUS
" { r8 h8 O+ _/ C4 ~" f3 ?GetUsbKeybordDevice( OUT PDEVICE_OBJECT* UsbDeviceObject );
4 } `7 j% W0 T5 \& y1 [; ^ b* R: `: r
BOOLEAN
4 [2 l6 O$ R. |) G9 b% N0 XGetAttachedDeviceInfo( IN PDEVICE_OBJECT DevObj );( O( \% E2 N9 \& a
s, j, H/ R, M3 q- B8 L0 @7 D3 [VOID
; ?, N' }$ ^4 D9 f+ o" MGetDeviceObjectInfo( IN PDEVICE_OBJECT DevObj );! X* {9 E% h! g# Y+ E9 _
: ]4 M e/ G0 b+ j$ BNTSTATUS 2 h+ y) S$ t% J5 Z+ a$ w! D
AttachUSBKeyboardDevice( IN PDEVICE_OBJECT UsbDeviceObject,3 q" V, u4 u: i7 B; L
IN PDRIVER_OBJECT DriverObject );
! H0 c5 @7 z6 R9 h' S1 U) |8 P2 |" v0 j
NTSTATUS
5 P5 b7 Z8 s4 Z% u U: M/ Q* rAttachPS2KeyboardDevice( IN UNICODE_STRING* DeviceName,- B+ e" h+ g# V; _: ~
IN PDRIVER_OBJECT DriverObject,
w! }8 v1 O% I4 Y- Z OUT PDRIVER_OBJECT* FilterDriverObject );, B2 }. G9 l7 m+ p1 n1 w( ]& c" I
" D! `! b5 f7 B" M; mNTSTATUS 6 K: t# I( N9 O6 F' D/ Y
KeyReadCompletion( IN PDEVICE_OBJECT DeviceObject,) p( Q: @7 |. _; e1 x6 E3 \0 d; X6 l
IN PIRP Irp,
4 N5 X# M/ @( z3 g$ L IN PVOID Context );- y$ T: k. X# Q" g2 e7 g% Z
NTSTATUS $ l% R7 {1 q8 Z6 Y1 @0 s
KeyReadPassThrough( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp );
1 K+ p7 q$ ^! M" Z0 N& W9 o4 @1 u( w- A7 T3 ^+ Z8 Z
WCHAR szUsbDeviceName[MAXLEN];* S) t" t4 T; `& u; G! S
8 |$ B! y+ {9 X) h
#endif
6 {0 p2 L, n- C+ V7 e3 d: @4 r7 F$ @9 V9 y
* ^* h# d- V( Z# G% j- L
, j; ~8 w2 Q2 P W6 S& @3 c% r
, o2 i/ \) z! u9 G5 C% z F9 E* N% a
" @3 A6 W& z* |
WSS(Whitecell Security Systems),一个非营利性民间技术组织,致力于各种系统安全技术的研究。坚持传统的hacker精神,追求技术的精纯。: | Y; j* @; c
WSS 主页:[url]http://www.whitecell.org/[/url]
% e5 ~# b& v8 w' s2 ?WSS 论坛:[url]http://www.whitecell.org/forums/[/url] |
|