对驱动型键盘记录程序Klog的修改

原创 2007年09月28日 12:56:00

 对驱动型键盘记录程序Klog的修改    vocanicy 2007/09/27

  Windows上的各种软件都做过,就是没接触做驱动,真是惭愧。最近下载了Clandestiny写的驱动型键盘记录程序的源码,在学习的过程中发现了几点问题。这些问题经过小的改动就可以解决,我相信是作者有意留在源码中的。
  本人初次接触驱动程序开发,下面这些小的改动,也让我欣赏了很多次Windows的蓝屏。在这我说说修改的思路。

1、内存泄漏
  Klog的OnReadCompletion IRP完成处理函数中获取按键信息KEY_DATA,然后为其分配4K内存,并加入键盘记录的链表。Klog另外有一个专门负责将链表中的记录写入文件的线程。但是这个线程将键盘记录取出后,并没有将其内存释放,导致内存泄漏。

由于OnReadCompletion的IRQL为DISPATCH_LEVEL,原程序中使用ExAllocatePool分配NonPagedPool内存。这里我将其替换成ExAllocatePoolWithTag后,就可以在PoolTag工具中看到Tag内存的分配情况。每次按键之后,内存都重新分配,但是原内存并未释放。
KEY_DATA* kData = (KEY_DATA*)ExAllocatePoolWithTag(NonPagedPool, sizeof(KEY_DATA), (ULONG)'GOLK');

解决方法:在线程将按键记录从链表中取出写入文件后,调用ExFreePool(kData)将其释放。


2、内存碎片
  第1点中提到的OnReadCompletion的IRQL为DISPATCH_LEVEL,因此原程序中使用ExAllocatePool分配NonPagedPool内存。DDK的文档中有说明使用ExAllocatePool分配的内存是以PAGE_SIZE对齐的。Windows中的PAGE_SIZE大小一般为4K。也就是说每按一个键,KLog都将分配4K的NonPagedPool内存,而实际上每个按键记录KEY_DATA结构只需要2个字节。更重要的是DDK文档中提到NonPagedPool内存为稀有资源(scarce resource)。这可以说是非常巨大的浪费。(如果没有修改第一点提到的内存泄漏,这个程序不知道能运行多长时间。4K×击键次数)
注:原程序中的这个缺点,作者是有提到的。

解决方法:在驱动的DriverEntry中预先分配好内存,并自己建立一个内存队列。这样可以避免频繁分配释放内存。下面是我写的键盘循环队列的结构。这里用到一个小技巧,使结构大小对齐到PAGE_SIZE。

#define HDR_SIZE        (sizeof(KSEMAPHORE) + sizeof(KSPIN_LOCK) + sizeof(int) * 2)
#define KEY_QUEUE_COUNT        ((PAGE_SIZE - HDR_SIZE) / sizeof(KEY_DATA))
struct KEY_QUEUE
{
        KSEMAPHORE KeySem;
        KSPIN_LOCK KeyLock;
       
        int Start;      // 队列头
        int End;        // 队列尾
       
        KEY_DATA Data[KEY_QUEUE_COUNT];
};

typedef KEY_QUEUE* PKEY_QUEUE;


3、驱动卸载
  Klog中为了截获键盘的按键信息,为IRP_MJ_READ操作的IRP设置了OnReadCompletion完成处理。OnReadCompletion需要等到某个按键按下之后才被调用。原KLog程序的Unload函数中设置一个等待循环,等到所有的IRP处理完成之后才退出。这就造成了一个问题。如果驱动卸载时,没有按键操作,系统将被挂起直到某个按键被按下。
注:这个缺点作者在注释中也有说明,因为驱动一般情况下不会被卸载,这个问题就显得不重要了。

解决方法:我的解决方法是在IoSetCompletionRoutine的同时,为IRP再调用IoSetCancelRoutine指定一个取消处理函数。在驱动卸载时,对Pending的IRP调用IoCancelIrp,迫使IRP立刻返回。

使用WINIO进行驱动层的键盘记录

突然对QQ的安全机制起了兴趣.. 想来利用检测键盘状态来做键盘记录应该很容易.安全软件也不能认为这种需求为非法.那QQ怎么防类似记录呢. 做个实验. 随便写个程序,每帧都去读取键...
  • ainn_pp
  • ainn_pp
  • 2013年05月29日 17:32
  • 2107

VB 加载winIO,实现驱动级键盘模拟

最近用VB做外挂,模拟鼠标实现自动化操作。发现驱动级模拟,一直存在问题。今天终于解决了,记录下. ---------------------------------------------------...
  • renminzdb
  • renminzdb
  • 2015年11月21日 15:42
  • 4196

Python自制键盘记录木马!

声明 我开发这个程序只有一个目的:学习。绝不会用于其他用途!我发布这个程序也只有一个目的:分享学习经验。鉴于其并没有任何反查杀功能,危害较小,故公开源码,以供新手学习之用。...
  • u012216571
  • u012216571
  • 2015年03月09日 21:45
  • 3477

键盘记录程序代码

键盘记录程序 ------------------------------------------------------------------------------- 主程序: 就...
  • xiaocaiju
  • xiaocaiju
  • 2012年06月14日 17:21
  • 2375

C#编写的键盘记录程序备忘

http://www.cnblogs.com/gardenforu/archive/2011/04/20/2021734.html 众所周知的原因,C#并不是很适合编写这类特殊的程序。但还是和大家分...
  • gardenforu
  • gardenforu
  • 2011年04月20日 17:31
  • 467

初试Hook与键盘记录程序

初试Hook与键盘记录程序 最近开始接触hook程序,在此基础之上制作了一个键盘记录小程序,并将所遇到的问题记录下来和大家分享。一:基本概念 1.钩子(hook) 是windows消息处理...
  • shirelyme
  • shirelyme
  • 2015年03月06日 18:49
  • 369

驱动级键盘记录 自己改的,比较低层,是个好的学习样本

  • 2011年05月26日 17:35
  • 124KB
  • 下载

VC 驱动级键盘记录Hook源码.zip

  • 2014年06月03日 23:03
  • 23KB
  • 下载

键盘记录小程序cpp文件

  • 2012年11月29日 11:36
  • 13KB
  • 下载

VB 键盘记录 程序代码

  • 2011年03月22日 22:41
  • 2KB
  • 下载
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:对驱动型键盘记录程序Klog的修改
举报原因:
原因补充:

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