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