开发键盘过滤驱动实现模拟按键过程中遇到的问题

原创 2006年11月24日 17:34:00

如何动态御载键盘过滤驱动

     最近写个键盘过滤驱动,遇到的问题是动态御载后再有按键操作就会蓝屏,看了些资料终于明白了原因,写出来供大家参考,免得后来的朋友再重复这个郁闷的过程。

     要做到动态御载键盘过滤驱动,明白其工作运行的原理是很重要的。首先必须要知道键盘过滤驱动是工作在异步模式下的,这一点很重要。为了得到一个按键操作,首先需要发送一个IRP_MJ_READ到驱动的设备栈,驱动收到这个irp会做什么样的处理呢?它会一直保持这个irp为pending未确定状态,因为其实现在一直没有按键操作,直到一个键被真正的按下,驱动此时就会立刻完成这个irp,并将刚按下的键的相关数据做为该irp的返回值。在该irp带着对应的数据返回后,操作系统将这些值传递给对应的事件系统来处理,然后做什么呢??系统紧接着又会立刻发送一个IRP_MJ_READ请求,等待下次的按键操作,重复以上的步骤。也就是说,任何时候设备栈底都会有一个键盘的IRP_MJ_READ请求处于pending未确定状态。这意味着只有在该irp完成返回,并却新的irp请求还未发送到的时候才会有一个很短暂的时间。由此我们想到,我们按照一般的方式动态御载键盘过滤驱动的时候,基本都是有IRP_MJ_READ请求处于pending未确定状态,而我们却御载了驱动,以后按键的时候需要处理这个irp却找不到对应的驱动当然会蓝屏。

     以上分析了动态御载键盘过滤驱动蓝屏的原因,分析到了中间存在一个短暂的时间栈底是没有irp的,那么让我们想办法来解决它。

     网上一份e文资料显示,只有使用IoAttachDevice挂接/Device/KeyboardClass0(or others)才可以动态御载,而加载到UpperFilters的却不能。以下是该段的原文:

     This problem occurs in most of the keyloggers based on the sysinternals Ctrl2cap model, which has been widely adopted and adapted. It applies to the earlier versions of the filter, which manually attach to /Device/KeyboardClass0 (or others) using IoAttachDevice. (If you install your filter by adding it to the UpperFilters value of HKCR/CCS/Control/Class/{4D36E96B-E325-11CE-BFC1-08002BE10318} key as more recent versions of Ctrl2cap do, you just can't unload: your filter is wedged into the stack for as long as the system is running and can't get out. But if you wedge by IoAttachDevice, unloading is still possible in theory.)。


    让我们再深入分析下蓝屏的原因,栈底有irp为什么我们的驱动御载就会有问题呢?这是由于IRM_MJ_READ是异步的,对于异步的请求,基本上我们会关心这个异步请求的结果,如何得到完成后的数据呢?大家一定想到了,设置完成例程。对,就是这样,由于我们给IRP_MJ_READ设置了完成例程,该irp完成后会调用我们的完成例程,使我们有处理返回数据的机会。在这样的情况下,我们动态御载了键盘过滤驱动,也就是说完成例程已经被我们御载掉了,而以后的再次按键在完成这个irp后会调用这个根本已经不存在了的东东,结果蓝屏就可想而知了。

    那是否是不设置完成例程就不会有问题了呢?答案是肯定的。可是没有完成例程我们就没有办法处理到返回的数据,也就在很大程度上失去了键盘过滤驱动的作用了。如何做到既能设置完成例程来处理数据又可以实现动态的御载呢?这里我们这样想,当有IRP_MJ_READ到来的时候,我不为这个irp设置完成例程,也不将该irp向下传递,而是创建一个我自己的irp,并参考前面的IRP_MJ_READ做对应的设置,然后为我自己的这个irp设置完成例程后将我的irp向下传递,并设置原来的IRP_MJ_READ为pending状态。当有按键操作时,我的irp返回触发为它设置的完成例程,在这里取得返回的数据填充前面的IRP_MJ_READ后将该IRP_MJ_READ完成返回。相当于我们使用了一个代理,而这一切都是透明的。到这里我们实现了完成例程,也就是有了处理数据的机会。下面该说到重点了,那就是这样处理后又如何实现动态的御载呢?

    假设现在我们收到御载的请求,让我们看看当前所有的irp处于何种状态:
(1)一个我们保存的原本的IRP_MJ_READ处于pending,注意它并没向下传递,也未设置完成例程。
(2)一个我们自己构造的irp处于栈底,并注意我们为自己的这个irp设置了完成例程。
基本就这2个irp,由于我们自己的irp有完成例程,所以直接御载会出现和上面一样的情况,导致蓝屏。如何处理呢?这里注意到是我们自己构造的irp,所以我们可以将其取消,这样并不会有太大的影响。可是取消后栈底本来该有的IRP_MJ_READ就没有了,注意到(1),我们不是还有原来的IRP_MJ_READ吗?对,就是将原来的这个IRP_MJ_READ向下传递,这里千万注意,我们自己的驱动马上要御载,所以我们传递原来的IRP_MJ_READ的时候不要给它设置完成例程。向下传递后御载我们的驱动。哈哈,成功!!!

 

   当然,这里还有更简单的办法,使用计数器也可以实现,还简单的多:)
 

如何在 ListView 上加上按鍵過濾的功能

http://ysl-paradise.blogspot.com/2008/12/listview.html   How to add type filter functionality for yo...
  • zhjp4295216
  • zhjp4295216
  • 2010年12月09日 19:38
  • 667

Windows内核安全编程__键盘过滤之内核级Hook(一)

Hook分发函数 前一篇文章讲述了进行键盘过滤,截取用户输入的方法。本篇文章开始更加深入地讨论键盘的过滤与反过滤对抗。无论是过滤还是饭过滤,原理都是过滤,取胜的关键在于谁第一个得到信息。 ...
  • jmjljmyy
  • jmjljmyy
  • 2013年03月15日 14:11
  • 598

fedora 16安装错误

http://huaonline.iteye.com/blog/1351659 Fedora 16安装时提示“安装引导程序出错,系统可能无法引导” 博客分类: linux ...
  • gdujian0119
  • gdujian0119
  • 2012年03月16日 16:52
  • 4

开发过程中遇到问题该怎么办?

开发过程中遇到问题了怎么办日常开发过程中,总会遇到问题,那么遇到问题该怎么办呢?   首先我们把问题分成大的两类:业务问题、技术问题。一、业务问题这类问题一般跟你的需求和设计相关。大致分下列情况:1、...
  • shijing266
  • shijing266
  • 2017年05月05日 16:42
  • 1669

解决网页开发过程中遇到的问题以及思路

1:js中的运算问题 js中变量的声明:如果在 var 语句中没有初始化变量,变量自动取 JavaScript值 undefined。尽管并不安全,但声明语句中忽略 var 关键字是合法的 Ja...
  • huangwwu11
  • huangwwu11
  • 2013年07月18日 16:41
  • 1733

开发键盘过滤驱动实现模拟按键过程中遇到的问题

如何动态御载键盘过滤驱动     最近写个键盘过滤驱动,遇到的问题是动态御载后再有按键操作就会蓝屏,看了些资料终于明白了原因,写出来供大家参考,免得后来的朋友再重复这个郁闷的过程。     要做到动态...
  • rageliu
  • rageliu
  • 2006年11月24日 17:34
  • 4814

最强 Android Studio 使用小技巧和快捷键

转载此处:http://www.open-open.com/lib/view/open1458715872710.html 写在前面 本文翻译自 Android Studio Ti...
  • huningjun
  • huningjun
  • 2016年09月06日 15:36
  • 10191

开发过程中遇到问题解决方法

自定义cell 时获取到的width 总是320: https://my.oschina.net/ioslighter/blog/390880 dyld: Library not load...
  • u013410274
  • u013410274
  • 2017年04月25日 09:46
  • 229

自己开发过程中遇到的问题及解决办法

1. myeclipse+hibernate+junit 在进行测试时出现invalid project specified对话框原因:你的工程可能是复制过来的。而你改名字时前面的一个空格没去掉。2....
  • tianhandigeng
  • tianhandigeng
  • 2010年07月20日 09:01
  • 2000

Source Insight入门教程

Source Insight入门教程 转载自:http://www.cnblogs.com/olvo/archive/2012/05/04/2483424.html   进入到T...
  • it1988888
  • it1988888
  • 2012年09月28日 00:01
  • 41283
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:开发键盘过滤驱动实现模拟按键过程中遇到的问题
举报原因:
原因补充:

(最多只允许输入30个字)