鼠标过滤驱动

文章目录

概述

其编写过程大体与键盘过滤驱动相似,只需要切换一下附加的目标设备以及创建的设备类型等。但在该操作后依然无法捕获到Vmware创建的win7操作系统的鼠标irp信息,于是通过在获取鼠标驱动,遍历其所有的设备进而附加,这样便可以获取到鼠标的irp信息。

代码

c 复制代码
#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

相关推荐
C+++Python1 小时前
详细介绍一下Java泛型的通配符
java·windows·python
能喵烧香1 小时前
深度解析:Linux 与 Windows 超级权限账户的本质差异
linux·windows
皮皮蟹虾饺5 小时前
DNS协议指南:从报文格式到安全加密与 K8s 实战
安全·容器·kubernetes
caimouse5 小时前
Reactos 第 7 章 视窗报文 — 7.5 视窗报文的发送
windows
HavenlonLabs8 小时前
重塑链上未来的隐形基石:长期主义下的生态演进
大数据·人工智能·安全·区块链
IT 行者9 小时前
GitHub Spec Kit 实战(六):/speckit.implement 怎么用、怎么审、怎么发现 spec 阶段的遗漏——五部曲收官
java·驱动开发·github·ai编程·claude
callJJ9 小时前
Volta + Claude Code 在 Windows 上的路径 Bug 复盘
windows·bug
其实防守也摸鱼10 小时前
软件安全与漏洞--Windows底层原理与软件逆向工程基础
linux·网络·数据库·算法·安全·安全架构·软件安全与漏洞
女神下凡10 小时前
这是 Cursor(Composer) 的五种核心交互模式
服务器·人工智能·windows·vscode·microsoft
techdashen10 小时前
从 Windows 的 ping.exe 入手:动态库、调用约定与 Rust FFI
开发语言·windows·rust