鼠标过滤驱动

文章目录

概述

其编写过程大体与键盘过滤驱动相似,只需要切换一下附加的目标设备以及创建的设备类型等。但在该操作后依然无法捕获到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

相关推荐
五仁火烧19 分钟前
生产环境中配置了接口3000后,不能启动,改成8080后就可以
linux·网络·安全·vue
专业开发者23 分钟前
借助安全返场方案提升智慧建筑能效的新机遇
物联网·安全
Ankie Wan1 小时前
windows技巧:要将 Windows 资源管理器的默认查看方式设置为详细信息
windows·windows11·效率提升·文件夹·windows技巧·详细信息
菩提小狗1 小时前
Sqlmap双击运行脚本,双击直接打开。
前端·笔记·安全·web安全
●VON2 小时前
跨模态暗流:多模态安全攻防全景解析
人工智能·学习·安全·von
ayaya_mana3 小时前
VS Code 远程开发:SSH连接与远程资源管理器的配置
linux·ide·windows·vscode·远程资源管理
廋到被风吹走3 小时前
【Spring】Spring Boot 配置管理深度指南:Profile、类型安全与加密
spring boot·安全·spring
龙潜月七3 小时前
做一个背单词的脚本
数据库·windows·c#·aigc·程序那些事
王火火(DDoS CC防护)3 小时前
多域名业务如何做好DDoS安全防护?
安全·ddos防御·ddos攻击
ohoy4 小时前
RedisTemplate 使用之List
数据结构·windows·list