鼠标过滤驱动

文章目录

概述

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

相关推荐
唐宋元明清21881 天前
.NET Win32磁盘动态卷/跨区卷触发“函数不正确”问题排查
windows·c#·存储
用户962377954484 天前
VulnHub DC-3 靶机渗透测试笔记
安全
叶落阁主5 天前
Tailscale 完全指南:从入门到私有 DERP 部署
运维·安全·远程工作
用户962377954487 天前
DVWA 靶场实验报告 (High Level)
安全
数据智能老司机7 天前
用于进攻性网络安全的智能体 AI——在 n8n 中构建你的第一个 AI 工作流
人工智能·安全·agent
数据智能老司机7 天前
用于进攻性网络安全的智能体 AI——智能体 AI 入门
人工智能·安全·agent
用户962377954487 天前
DVWA 靶场实验报告 (Medium Level)
安全
red1giant_star7 天前
S2-067 漏洞复现:Struts2 S2-067 文件上传路径穿越漏洞
安全
用户962377954488 天前
DVWA Weak Session IDs High 的 Cookie dvwaSession 为什么刷新不出来?
安全
阿白的白日梦8 天前
winget基础管理---更新/修改源为国内源
windows