键盘过滤

《Windows内核安全与驱动开发》阅读笔记 -- 索引目录

键盘过滤

1.如何绑定需要过滤的设备

  键盘在底层存在一个驱动,即 \Driver\kbdclass,我们通过ObReferenceObjectByName这个非公开函数来获取这个驱动指针,

  然后遍历该驱动下面的设备对象,见到一个绑定一个,这样就最终可以实现驱动的绑定。

  下面我们使用工具DeviceTree来查看一下 这个  \Driver\kbdclass,之后我们就知道如何绑定了。

  

  现在,我们使用这个API来获取设备对象指针

  

  之后,我们就开始while()来遍历这个设备,如果存在就像之前那样来创建过滤设备来绑定该目标设备,这很好理解。

 

2. 拓展设备的应用

  其实我们之前在“端口过滤”中,我们使用数组来存储每个设备对象,这其实完全没有必要。

  我们可以直接来使用过滤设备中的拓展设备,这样我们在派遣函数中,可以直接拿到拓展设备,直接来处理即可。

  下面其拓展设备的数据结构,我们来讲解一下有关重点内容:

  

  下面对于拓展设备这很好理解,就是底层设备、目标设备、过滤设备三者直接全部存放在这里,这样做有什么好处呢?

  我们下面来看看IRP的处理,我们可以直接调用IoCallDriver将其分发到底层设备,而不用像之前那样,先For循环判断是哪个设备,然后找对应设备。

  这个逻辑要理解,可以大大减少你的代码量。

  

 

3. 无关IRP请求的处理

  过滤设备要处理各种IRP,这代码处理了四种:通用、IRP_MJ_POWER、IRP_MJ_PNP、IRP_MJ_READ(处理键盘过滤的)

  1)通用型

    这很好理解,并不需要特殊处理,直接分发给下层设备即可。

    

  2)IRP_MJ_POWER

    这个电源的派发函数,需要调用专门的处理电源的派发函数 PoStartNextPowerIrp来进行处理。

    

  3)IRP_MJ_PNP

    这个是即插即用的设备,我们需要处理MinorFuncion为 IRP_MN_REMOVE_DEVICE时的情况,

    此时就需要解除过滤设备的绑定,然后删除自己的过滤设备,这顿操作很好理解,当然,这个请求也是要派发下去的。

    

 

4. 读IRP请求的处理

  现在我们来处理过滤中的读请求,键盘输入的本质就是通过驱动的读请求向键盘设备中读取相关信息,其操作如下:

  如上图,我们现在要过滤请求,应该怎么处理呢?是直接像COM端口过滤一样直接在派发函数中过滤么?

  这当然是不行的,因为我们在派发函数中,只是获得了一个读请求,而读的信息此时还没到达键盘设备自然不能获取。

  因此我们现在要设置完成回调函数,其在派发函数中设置如下:

  

  现在我们来看看其回调函数的核心代码逻辑是什么样的:

  

  我们现在判断IRP的返回值,只有当返回成功时,才说明里面存在信息,直接从Buffer缓冲区读取就好,读取到的数据依次打印出来。

 

5. 处理的细节

  1)gC2pKeyCount 绑定处理个数

    我们在设置回调和完成回调时,依次 gC2pKeyCount++ 和 gC2pKeyCount--,为什么这么做呢?

    因此当我们卸载设备时,我们要确保这里不存在还需要处理的消息,若gC2pKeyCount不为零,则需要继续延迟等待处理。

    

   2)打开驱动对象时的驱动类型

    这里我们使用一个未导出的内部变量,注意一定要用指针类型,否则一定概率获取不到对象。(这里不清楚原因,但是确实出现过这种错误)

    

posted @ 2020-06-28 21:15  OneTrainee  阅读(945)  评论(0编辑  收藏  举报