鼠标过滤驱动

文章目录

概述

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

相关推荐
HackTwoHub18 分钟前
REA逆向一切!渗透逆向新利器、MCP 驱动全栈逆向方案,解析原生二进制、EXE、APK,高效挖掘程序底层漏洞
网络·安全·web安全·网络安全·系统安全
小趴菜一只19 分钟前
SIEM-wazuh安装过程
运维·windows·安全·网络安全
MOONICK28 分钟前
COM 组件技术(三)
c++·windows
Source.Liu36 分钟前
【A11】客户端登录流程笔记
windows·rust
看着博客敲代码42 分钟前
searchsploit illegal option -- - 与 Exploit-DB 本地漏洞检索排查
安全·网络安全·系统安全
EasyGBS1 小时前
社区、校园安防难统一?国标GB28181公网平台EasyGBS视频系统,打破安全监管难题!
深度学习·安全·自动化
pt10431 小时前
Cisco设备网络安全系列-3:远程访问虚拟专用网、站点间虚拟专用网与Cisco SD-WAN安全
网络·安全
clz13145211 小时前
Dify的Windows平台部署:从Docker安装到Dify运行
windows·docker·容器
Xudde.1 小时前
DC-6 靶机渗透测试(Vulnhub Writeup)
笔记·学习·安全·web安全
Patrick在香港1 小时前
你写的「比较 token」函数,正在用 36 纳秒泄露密码:时序攻击实测
python·安全·标准库·时序攻击·常量时间