-
-
[原创]关于键盘驱动过滤蓝屏的问题
-
发表于:
2017-2-17 15:34
5128
-
好多人学习驱动的时候都会看《寒江独钓》或《windows内核安全》这两本书(其实这两本书差不多)。开始看这两本书的时候,看目录就会感觉自己被吓到了,觉得这些技术简直就是牛叉啊。但是实质看内容的时候,我就感叹,这些代码都是各路拼接的啊,这一点我好失望,而且许多基础的知识点介绍的并不是那么清楚。
今天我所说的这个例子,是书中键盘过滤那章的第一个程序。由于本人系统是win10,WDK10无法编写XP的驱动,我没在XP实验过,听说这个例子的源代码编译后在XP可以直接跑起来,没任何问题。在win7环境下实验的小伙伴,肯定会出现我这些问题。(程序的源码请各位自行寻找,这里我只说问题)。
首先第一个问题。直接编译的小伙伴会发现在win7系统中,安装完驱动就会退出,不会蓝屏。这里问题其实很简单,程序在开始的时候会声明IoDriverObjectType这个全局的变量。只要将代码改成
extern POBJECT_TYPE *IoDriverObjectType;
就可以了。接下来ObReferenceObjectByName这个函数对应的参数也要改成*IoDriverObjectType。
第二个问题就很坑了,我找了好久才找到。驱动成功运行后,卸载的时候就会蓝屏。开始的时候我一直认为是卸载例程函数里哪里错了。但是实际调试的时候,发现卸载函数很正常的运行完了,并没有在卸载的过程中崩溃。
其实原因很简单,是ObDereferenceObject这个函数参数的问题。我们在使用ObReferenceObjectByName函数的时候,所获取的设备是会被增加引用计数的。而ObDereferenceObject这个函数,则是用来平衡引用计数的。书中并没有对这些进行解释。我认为,程序打开了Kbdclass的设备,这是永久性的设备,而ObDereferenceObject 是把一个永久性的对象的引用记数减少到0。代码中ObDereferenceObject的参数是DriverObject,这明显是个错误的,这就会导致程序卸载的时候,导致引用计数不正确,就会蓝屏。只要将参数换成我们打开KbdDriverObject就好了。
ObDereferenceObject(KbdDriverObject);
这两本书的许多代码部分解释的不是很清楚,还是需要好好的学习才行。
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!