谁笨论坛

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

网盘分享动态:
资迅
资迅
生活
生活
娱乐
娱乐
互动
互动
芒果辅助 无事卡盟 麻婆云
绝地求生等各种稳定低价辅助点我
仟图网苞图网千库网在线解析
低价辅助卡盟值得你的信赖☞点我查看详情我要租此广告位我要租此广告位
查看: 37|回复: 0

[☆交流] 第二篇:键盘过滤驱动

[复制链接]

已分享文件:0个

网盘今日赚:积分

发表于 6 天前 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转谁笨论坛

您需要 登录 才可以下载或查看,没有帐号?注册[Register]

x
第二篇:键盘过滤驱动

前言:接着上一篇的基础,这一张我们将讲述如何去写一个基础的键盘过滤驱动,但是这个键盘过滤驱动是不完善的,因为这里会有一个BUG 这个BUG是我们在卸载键盘过滤驱动时候会出现荡机的现象,怎么解决呢?我可以提供一个思路,写个定时器,至于在哪里写?这个百度可以查一下,对于聪明的人,一般都不会是什么太大的问题!(前提是你的驱动掌握的还算可以!)

这一篇我就不默写了 直接拿自己写好的文档 给大家讲吧 (如有雷同,恭喜你,你碰到我传说中的师傅了) 文章最后面还是会附上源码 有问题的话希望大家直接指出来 因为完全纯属个人理解 下面会有一张键盘扫描码的图片 这张表格可以在微软官网找到具体在哪我也忘记了

直接进入正题
No.1
驱动层
(1)先注册自己的调度函数,处理特定的IRP消息,因为这个IRP数据包里包含了很多功能(也就是我们的自定义函数功能) 所以我们用个for循环来接收这些数据“IRP_MJ_MAXIMUM_FUNCTION”这个函数代表的是IRP主要功能的数量
        for (i = 0; i < IRP_MJ_MAXIMUM_FUNCTION; i++)
        {
                //我们将自定义调度函数注册到我们的驱动程序对象 "MajorFunction[i]"主要功能成员
                DriverObject->MajorFunction[i] = DispatchPass;// DispatchPass保存了IRP的数量
        }

(2)我们只是将这个指针传递给这个MajorFunction[i],数组并执行这个代码,我们的调度传递函数将处理所有这些主要功能,但假设我们处理一些读或写操作我们需要分配用于处理此类IRP的专用函数(也就是上节讲的自定义功能函数),所以我们使用这个函数来完成所有这些IRP请求
在这种情况下,我们只对我们的读的请求感兴趣,所以我们使用自定义“DispatchRead”函数来完成读的操作
DriverObject->MajorFunction[IRP_MJ_READ] = DispatchRead;

(3)注册我们的调度功能后接下来我们应该将我们的驱动程序附加到键盘类0设备上
status = MyAttachDevice(DriverObject);

(4)创建我们自己的设备,我们可以通过调用Iocreatedevice创建我们自己的设备
NTSTATUS MyAttachDevice(PDRIVER_OBJECT DrvierObject)

(5)第1参数是驱动对象的句柄,2参数是我们的设备扩展的大小,3我们设备的名字,4设备类型,5设备特性设置为安全打开,6是指示我们的驱动程序是否专门打开,7 参数是收到的设备对象变量新设备对象名字
status = IoCreateDevice(DrvierObject, sizeof(DEVICE_EXTENSION), NULL, FILE_DEVICE_KEYBOARD, 0, FALSE, &myKbdDevice);

(6)因为我们应该在这个函数之外使用我们的设备对象,所以我们需要将此变量定义为全局变量,所以在这种情况下,您可以定义自己的扩展,设备扩展名为自定义扩展
PDEVICE_OBJECT myKbdDevice = NULL;

(7)因为这是一个基础键盘过滤,所以我们定义了一个非常简单的扩展
typedef struct {
        PDEVICE_OBJECT LowerKbdDevice;
}DEVICE_EXTENSION, *PDEVICE_EXTENSION;

(8)接下来我们应该分配新创建的设备标志
myKbdDevice->Flags |= DO_BUFFERED_IO;

(9)这将表明我们的驱动即将开始
myKbdDevice->Flags &= ~DO_DEVICE_INITIALIZING;

(10)接下来我们需要初始化我们的设备扩展结构。
RtlZeroMemory(myKbdDevice->DeviceExtension, sizeof(DEVICE_EXTENSION));

(11)完成初始化后,让我的设备连接到其他设备,让我的设备附加到键盘类零设备上
所以第一个参数是我们的源设备,在这种情况”源设备“指的就是我们新创建的对象名叫myKbdDevice设备,
接下来是以Unicode目标命名的设备,最后一个参数是将接收附加设备的变量,
回到我们身边正如您在这里可以看到较低的LowerKbdDevice设备,这个附加设备实际上是较低的设备。
这个较低的设备是我们实际连接到的设备,但在某些情况下是你所关注的目标设备连接不等于较低的设备,因为我们有多个设备在这个设备堆栈中
status = IoAttachDevice(myKbdDevice, &TargetDevice, &((PDEVICE_EXTENSION)myKbdDevice->DeviceExtension)->LowerKbdDevice);

(12)如果操作失败 删除我们刚创建的设备       
     if (!NT_SUCCESS(status))
        {
                IoDeleteDevice(myKbdDevice);
                return  status;
        }
       
(13)自定义IRP功能函数,因为DispatchPass这个函数中保存着IRP数据包功能的数量,也可以叫做自定义IRP数据包的功能,
(什么叫自定义IRP数据包的功能?IRP本身就是个数据包,这个数据包中包含着各种各样的请求类型,这些请求可以是读的请求,
也可以是写的请求,或者打开文件的请求等等)
NTSTATUS DispatchPass(PDEVICE_OBJECT DeviceObject, PIRP Irp)

(14)自定义专用读取操作的“DispatchRead”函数来完成读的操作
NTSTATUS DispatchRead(PDEVICE_OBJECT DeviceObject, PIRP Irp)

(15)编写卸载功能,第一件事是分离我们附加在这个键盘0类设备上的驱动程序,
这次的目标设备不是”TargetDevice”而是“LowerKbdDevice”
VOID DriverUnload(PDRIVER_OBJECT DriverObject)
{
        PDEVICE_OBJECT DeviceObject = DriverObject->DeviceObject;
        IoDetachDevice(((PDEVICE_EXTENSION)DeviceObject->DeviceExtension)->LowerKbdDevice);
        IoDeleteDevice(myKbdDevice);
        KdPrint(("Unload Our Driver \r\n"));
}

总结:
为了将我们的驱动程序附加到特定设备,首先我们需要创建我们自己的设备,
然后找出我们想要附加的目标设备,调用Ioattachdevice函数来附加我们的驱动程序到目标设备,
如果我们想卸载我们的驱动程序,我们应该调用Iodetachdevice来分离我的设备,然后在删除我们的设备

最后说一句,我看了很多的教程,以及文档,如果以后你看到有人写注释写的跟我一样详细,不用猜那个肯定是我写的,因为厉害点的大佬不会这么去写注释,本人比较菜

按键扫描码.gif

Source.zip

859 Bytes, 下载次数: 1, 下载积分: 笨币 -1 枚

您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

QQ|小黑屋|手机版|Archiver|谁笨论坛

GMT+8, 2019-6-17 12:56 , Processed in 0.114899 second(s), 40 queries .

Powered by Discuz! X3.4 Licensed

© 2001-2060 Comsenz Inc.

快速回复 返回顶部 返回列表