鼠标过滤驱动
文章目录
- 概述
- 代码
- 参考资料
概述
其编写过程大体与键盘过滤驱动相似,只需要切换一下附加的目标设备以及创建的设备类型等。但在该操作后依然无法捕获到Vmware创建的win7操作系统的鼠标irp信息,于是通过在获取鼠标驱动,遍历其所有的设备进而附加,这样便可以获取到鼠标的irp信息。
代码
#include<ntifs.h>
typedef struct
{
PDEVICE_OBJECT LowerKbdDevice;
}DEVICE_EXTENTION,*PDEVICE_EXTENTION;
extern POBJECT_TYPE* IoDriverObjectType;
typedef struct _MOUSE_INPUT_DATA {
USHORT UnitId;
USHORT Flags;
union {
ULONG Buttons;
struct {
USHORT ButtonFlags;
USHORT ButtonData;
};
};
ULONG RawButtons;
LONG LastX;
LONG LastY;
ULONG ExtraInformation;
} MOUSE_INPUT_DATA, * PMOUSE_INPUT_DATA;
ULONG pendingkey = 0;
NTSTATUS NTAPI ObReferenceObjectByName(PUNICODE_STRING ObjectName,
ULONG Attributes,
PACCESS_STATE AccessState,
ACCESS_MASK DesiredAccess,
POBJECT_TYPE ObjectType,
KPROCESSOR_MODE AccessMode,
PVOID ParseContext OPTIONAL,
PVOID* Object);
VOID DriverUnload(PDRIVER_OBJECT DriverObject)
{
LARGE_INTEGER interval = { 0 };
PDEVICE_OBJECT DeviceObject = DriverObject->DeviceObject;
interval.QuadPart = -10 * 1000 * 1000;
while (DeviceObject)
{
IoDetachDevice(((PDEVICE_EXTENTION)DeviceObject->DeviceExtension)->LowerKbdDevice);
DeviceObject = DeviceObject->NextDevice;
}
//判断是否还有未处理的IRP
while (pendingkey)
{
KeDelayExecutionThread(KernelMode, FALSE, &interval);
}
DeviceObject = DriverObject->DeviceObject;
while (DeviceObject)
{
IoDeleteDevice(DeviceObject);
DeviceObject = DeviceObject->NextDevice;
}
KdPrint(("驱动卸载结束!\n"));
}
NTSTATUS ReadComplete(PDEVICE_OBJECT DeviceObject, PIRP irp, PVOID Context)
{
PMOUSE_INPUT_DATA KeyBuffer = (PMOUSE_INPUT_DATA)irp->AssociatedIrp.SystemBuffer;
int structnum = irp->IoStatus.Information / sizeof(MOUSE_INPUT_DATA);
if (irp->IoStatus.Status == STATUS_SUCCESS)
{
for (int i = 0; i < structnum; i++)
{
KdPrint(("ButtonFlags = %x\n", KeyBuffer->ButtonFlags));
}
}
//处理完成需要将标志位设置,以声明以完成此irp的返回处理
if (irp->PendingReturned)
{
IoMarkIrpPending(irp);
}
pendingkey--;
return irp->IoStatus.Status;
}
NTSTATUS DispatchPass(PDEVICE_OBJECT pDeviceObject,PIRP irp)
{
IoCopyCurrentIrpStackLocationToNext(irp);
return IoCallDriver(((PDEVICE_EXTENTION)pDeviceObject->DeviceExtension)->LowerKbdDevice, irp);
}
NTSTATUS DispatchRead(PDEVICE_OBJECT pDeviceObject, PIRP irp)
{
IoCopyCurrentIrpStackLocationToNext(irp);
IoSetCompletionRoutine(irp,ReadComplete,NULL,TRUE,TRUE,TRUE,TRUE);
pendingkey++;
return IoCallDriver(((PDEVICE_EXTENTION)pDeviceObject->DeviceExtension)->LowerKbdDevice, irp);
}
NTSTATUS MyAttachDevice(PDRIVER_OBJECT pDriverObject)
{
UNICODE_STRING kbdName = RTL_CONSTANT_STRING(L"\\Driver\\MouClass");
PDRIVER_OBJECT TargetDriverObject = NULL;
PDEVICE_OBJECT CurrentDeviceObject = NULL;
PDEVICE_OBJECT myKbdDevice = NULL;
PDEVICE_OBJECT lowDevice = NULL;
NTSTATUS status = ObReferenceObjectByName(&kbdName,OBJ_CASE_INSENSITIVE,NULL,0,*IoDriverObjectType,KernelMode,NULL,&TargetDriverObject);
if (!NT_SUCCESS(status))
{
DbgPrint("Open Mouse Driver Failed\n");
return status;
}
else
{
// 解引用
ObDereferenceObject(TargetDriverObject);
}
CurrentDeviceObject = TargetDriverObject->DeviceObject;
//循环附加到目标驱动上的所有设备栈上
while (CurrentDeviceObject)
{
NTSTATUS status = IoCreateDevice(pDriverObject, sizeof(DEVICE_EXTENTION), NULL, 0, FILE_DEVICE_MOUSE, FALSE, &myKbdDevice);
if (!NT_SUCCESS(status))
{
myKbdDevice = CurrentDeviceObject = NULL;
return status;
}
RtlZeroMemory(myKbdDevice->DeviceExtension, sizeof(DEVICE_EXTENTION));
lowDevice = IoAttachDeviceToDeviceStack(myKbdDevice, CurrentDeviceObject);
if (!lowDevice)
{
IoDeleteDevice(myKbdDevice);
myKbdDevice = NULL;
return status;
}
((PDEVICE_EXTENTION)myKbdDevice->DeviceExtension)->LowerKbdDevice = lowDevice;
myKbdDevice->Flags |= DO_BUFFERED_IO;
myKbdDevice->Flags &= ~DO_DEVICE_INITIALIZING;
CurrentDeviceObject = CurrentDeviceObject->NextDevice;
}
return STATUS_SUCCESS;
}
NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObject, PUNICODE_STRING pRegistryPath)
{
int i = 0;
NTSTATUS Status = STATUS_SUCCESS;
for (i = 0; i < IRP_MJ_MAXIMUM_FUNCTION; i++)
{
pDriverObject->MajorFunction[i] = DispatchPass;
}
pDriverObject->MajorFunction[IRP_MJ_READ] = DispatchRead;
Status = MyAttachDevice(pDriverObject);
if (!NT_SUCCESS(Status))
{
KdPrint(("AttachDevice ERROR!\n"));
}
else
{
KdPrint(("AttachDevice SUCCESS!\n"));
}
pDriverObject->DriverUnload = DriverUnload;
return Status;
}
参考资料
Revised Mouse and Keyboard Filter Driver