最近在做键盘过滤驱动,《寒江独钓》第四章的例子。本来想实现内核捕获按键信息后通过事件同步机制发送给应用层的程序。内核程序中CreateDeviceFun中先绑定Kbdclass设备,然后建立过滤驱动的设备栈,得到设备扩展。代码如下:
#define KBD_DRIVER_NAME L"\\Driver\\Kbdclass"
#define KBD_FILTER_DEV_NAME L"\\Device\\KbdFilterDevice"
#define KBD_FILTER_DEV_LINK L"\\??\\KbdFilterSymlink"
//创建键盘过滤设备
NTSTATUS CreateDeviceFun(IN PDRIVER_OBJECT pDriverObject ,IN PUNICODE_STRING pRegistryPath)
{
NTSTATUS ntStatus = 0 ;
UNICODE_STRING kbdDriverName ;
UNICODE_STRING kbdFilterDevName ;
UNICODE_STRING kbdFilterDevLink ;
PKEY_BOARD_DEV_EXT pDevExt ;
PDEVICE_OBJECT pFilterDeviceObject = NULL ;
PDEVICE_OBJECT pTargetDeviceObject = NULL ;
PDEVICE_OBJECT pLowerDeviceObject = NULL ;
PDRIVER_OBJECT kbdDriverObject = NULL ;
KdPrint(("CreateDeviceFun: Create keyboard device now.\n")) ;
//打开Driver-->Kbdclass驱动对象
RtlInitUnicodeString(&kbdDriverName ,KBD_DRIVER_NAME) ;
ntStatus = ObReferenceObjectByName(&kbdDriverName ,OBJ_CASE_INSENSITIVE ,NULL ,0 ,
IoDriverObjectType ,KernelMode ,NULL ,&kbdDriverObject) ;
if (!NT_SUCCESS(ntStatus))
{
KdPrint(("CreateDeviceFun: Open Kbdclass driver error.\n")) ;
return(ntStatus) ;
}
else
{
//调用ObReferenceObjectByName会导致驱动对象的引用计数增加
//必须调用相对应的解引用函数ObDereferenceObject
ObDereferenceObject(pDriverObject) ;
}
//这是设备链的第一个设备,位于设备栈的顶层
pTargetDeviceObject = kbdDriverObject->DeviceObject ;
//遍历设备链
while (pTargetDeviceObject)
{
//生成一个过滤设备
ntStatus = IoCreateDevice(pDriverObject ,sizeof(KEY_BOARD_DEV_EXT) ,NULL ,
pTargetDeviceObject->DeviceType ,pTargetDeviceObject->Characteristics ,
FALSE ,OUT &pFilterDeviceObject) ;
if (!NT_SUCCESS(ntStatus))
{
KdPrint(("CreateDeviceFun: Create filter device error.\n")) ;
return(ntStatus) ;
}
//绑定之后得到的下一个设备
pLowerDeviceObject = IoAttachDeviceToDeviceStack(pFilterDeviceObject ,
pTargetDeviceObject) ;
if (!pLowerDeviceObject)
{
KdPrint(("CreateDeviceFun: Attach device error.\n")) ;
//绑定失败后删除已建立的设备对象
IoDeleteDevice(pFilterDeviceObject) ;
pFilterDeviceObject = NULL ;
return(ntStatus) ;
}
//得到设备扩展对象
pDevExt = (PKEY_BOARD_DEV_EXT)(pFilterDeviceObject->DeviceExtension) ;
//对得到的设备扩展对象进行设置
SetDeviceExtension(pDevExt,kbdFilterDevName,kbdFilterDevLink,pFilterDeviceObject ,
pTargetDeviceObject ,pLowerDeviceObject) ;
//保持与被绑定的设备类型一致
pFilterDeviceObject->DeviceType = pLowerDeviceObject->DeviceType ;
pFilterDeviceObject->Characteristics = pLowerDeviceObject->Characteristics ;
pFilterDeviceObject->StackSize = pLowerDeviceObject->StackSize+1 ;
pFilterDeviceObject->Flags |= pLowerDeviceObject->Flags &
(DO_BUFFERED_IO | DO_DIRECT_IO | DO_POWER_PAGABLE) ;
//移动到下一个设备,继续遍历
pTargetDeviceObject = pTargetDeviceObject->NextDevice ;
}
return ntStatus ;
}
我想在此基础上新建过滤驱动的符号链接。需要添加的代码如下:
//创建虚拟过滤设备的链接
RtlInitUnicodeString(&kbdFilterDevLink ,KBD_FILTER_DEV_LINK) ;
ntStatus = IoCreateSymbolicLink(&kbdFilterDevLink ,&kbdFilterDevName) ;
if (!NT_SUCCESS(ntStatus))
{
KdPrint(("CreateDeviceFun: Could not create Symlink error.\n")) ;
return ntStatus ;
}
但我发现原函数中IoCreateDevice函数调用的第三个参数为NULL,如下:
//生成一个过滤设备
ntStatus = IoCreateDevice(pDriverObject ,sizeof(KEY_BOARD_DEV_EXT) ,NULL ,
pTargetDeviceObject->DeviceType ,pTargetDeviceObject->Characteristics ,
FALSE ,OUT &pFilterDeviceObject) ;
而不是许多书上写的这样:
//生成一个过滤设备
RtlInitUnicodeString(&kbdFilterDevName ,KBD_FILTER_DEV_NAME) ;
ntStatus = IoCreateDevice(pDriverObject ,sizeof(KEY_BOARD_DEV_EXT) ,&kbdFilterDevName ,
pTargetDeviceObject->DeviceType ,pTargetDeviceObject->Characteristics ,
FALSE ,OUT &pFilterDeviceObject) ;
请问应该怎么向CreateDeviceFun函数中插入新建符号链接的部分,新建符号链接的第二个设备名称地址参数应该填什么??求大家帮忙,最近刚学习内核编程,感激不尽。
[课程]FART 脱壳王!加量不加价!FART作者讲授!