键盘的过滤

这几天心态崩了 就没怎么继续撸  看pwn看的心态有点崩  然后 看驱动看不下了  所以 划了一天的水。。

然后这次写的是  键盘的过滤 这次  看的是   资料是   windows黑客技术编程  

其实这个 我感觉 还是比较好理解的

首先是  一个 扩展设备   

typedef struct _DEVICE_EXTENSION
{
	PDEVICE_OBJECT pAttachDevObj;
	ULONG ulIrpInQuene;

}DEVICE_EXTENSION, *PDEVICE_EXTENSION;

第一个是  在我们 创建的设备下面的对象  第二个是irp的数量   read 加一次 我们处理过 就减一次  

然后 irp这个东西要处理的很好 要不然非常容易蓝屏  那么     这里就有一点非常尴尬的了  就是  你卸载我们的驱动 还要必须在按下一个键 才行  这个就是为了安全    因为卸载驱动的时候 有可能就是 有 派遣函数 在挂起 还没有返回  irp 找不到 处理的函数 那就gg了     

所以只有在按下一个键 然后 让那个取消的栈 然后下发 然后 让那个irp完成返回 然后就可以卸载了     因为按下那个irp 并没有经过我们绑定的设备 

所以我们 就用这个结构体 来记录 数量  至于为什么记录 栈的下一个设备 那当然是下发啊0.。。。。。  233

卸载的函数要注意  要先把 设备 把设备栈中分离 要不然 发回这个信息  还默认 有我们那个处理函数 然后才能让最后一个rip 分发 然后完成卸载 

代码如下

#include<ntddk.h>
#include <Ntddkbd.h>
#define DEV_NAME L"\\Device\\KEYBOARD_LOG_DEV_NAME"
#define SYM_NAME L"\\DosDevices\\KEYBOARD_LOG_SYM_NAME"
#define IOCTL_TEST CTL_CODE(FILE_DEVICE_KEYBOARD, 0x800, METHOD_BUFFERED, FILE_ANY_ACCESS)
typedef struct _DEVICE_EXTENSION
{
	PDEVICE_OBJECT pAttachDevObj;
	ULONG ulIrpInQuene;

}DEVICE_EXTENSION, *PDEVICE_EXTENSION;
VOID Unload(PDRIVER_OBJECT pDriverObject)
{
	KdPrint(("开始卸载!\n"));
	PDEVICE_OBJECT pDevObj = pDriverObject->DeviceObject;
	LARGE_INTEGER liDelay = { 0 };
	if (NULL == pDevObj)
	{
		return;
	}
	if (NULL == pDevObj->DeviceExtension)
	{
		return;
	}

	IoDetachDevice(((PDEVICE_EXTENSION)pDevObj->DeviceExtension)->pAttachDevObj);

	liDelay.QuadPart = -1000000;
	while (0 < ((PDEVICE_EXTENSION)pDevObj->DeviceExtension)->ulIrpInQuene)
	{
		KdPrint(("剩余挂起IRP:%d\n", ((PDEVICE_EXTENSION)pDevObj->DeviceExtension)->ulIrpInQuene));
		KeDelayExecutionThread(KernelMode, FALSE, &liDelay);
	}

	UNICODE_STRING ustrSymName;
	RtlInitUnicodeString(&ustrSymName, SYM_NAME);
	IoDeleteSymbolicLink(&ustrSymName);

	if (pDriverObject->DeviceObject)
	{
		IoDeleteDevice(pDriverObject->DeviceObject);
	}

	KdPrint(("卸载成功!\n"));
	
}
NTSTATUS CreareDriver(PDRIVER_OBJECT pDriverObject)
{
	KdPrint(("创建设备!\n"));
	NTSTATUS status;
	UNICODE_STRING S_name, D_name;
	PDEVICE_OBJECT ob = NULL;
	RtlInitUnicodeString(&S_name, SYM_NAME);
	RtlInitUnicodeString(&D_name, DEV_NAME);
	status = IoCreateDevice(pDriverObject, sizeof(DEVICE_EXTENSION), &D_name, 
		FILE_DEVICE_KEYBOARD, 0, FALSE, &ob);
	if (!NT_SUCCESS(status))
	{
		KdPrint(("创建驱动对象失败!\n"));
		return status;
	}
	status = IoCreateSymbolicLink(&S_name, &D_name);
	if (!NT_SUCCESS(status))
	{   
		KdPrint(("创建设备失败!\n"));
		return status;
	}
	KdPrint(("创建成功!\n"));
	return status;
}

NTSTATUS Read(PDEVICE_OBJECT pDevObj, PIRP pIrp, PVOID pContext)
{
	NTSTATUS status = pIrp->IoStatus.Status;
	PKEYBOARD_INPUT_DATA pKeyboardInputData = NULL;
	ULONG ulKeyCount = 0, i = 0;
	if (NT_SUCCESS(status))
	{
		pKeyboardInputData = (PKEYBOARD_INPUT_DATA)pIrp->AssociatedIrp.SystemBuffer;
		ulKeyCount = (ULONG)pIrp->IoStatus.Information / sizeof(KEYBOARD_INPUT_DATA);
		for (i = 0; i < ulKeyCount; i++)
		{
			if (KEY_MAKE == pKeyboardInputData[i].Flags)
			{
				DbgPrint("[Down][0x%X]\n", pKeyboardInputData[i].MakeCode);
			}
			else if (KEY_BREAK == pKeyboardInputData[i].Flags)
			{
				DbgPrint("[Up][0x%X]\n", pKeyboardInputData[i].MakeCode);
			}
		}

	}
	if (pIrp->PendingReturned)
	{
		IoMarkIrpPending(pIrp);
	}
	((PDEVICE_EXTENSION)pDevObj->DeviceExtension)->ulIrpInQuene--;
	status = pIrp->IoStatus.Status;
	return status;

}

NTSTATUS DriverRead(PDEVICE_OBJECT pDriverObject, PIRP pirp)
{
	KdPrint(("read开始了!\n"));
	NTSTATUS status;
	IoCopyCurrentIrpStackLocationToNext(pirp);
	IoSetCompletionRoutine(pirp, Read, pDriverObject, TRUE, TRUE, TRUE);
	((PDEVICE_EXTENSION)pDriverObject->DeviceExtension)->ulIrpInQuene++;
	status = IoCallDriver(((PDEVICE_EXTENSION)pDriverObject->DeviceExtension)->pAttachDevObj, pirp);
	KdPrint(("read结束了!\n")); 
	return status;

}
NTSTATUS AttKdClass(PDEVICE_OBJECT pDevObj)
{
	KdPrint(("开始过滤键盘驱动!\n"));
	NTSTATUS status;
	UNICODE_STRING Ob_name;
	PFILE_OBJECT pFileObj=NULL;
	PDEVICE_OBJECT AttKdClassObj = NULL, pAttachDevObj = NULL;
	RtlInitUnicodeString(&Ob_name, L"\\Device\\KeyboardClass0");
	status = IoGetDeviceObjectPointer(&Ob_name, GENERIC_READ | GENERIC_WRITE,
		&pFileObj, &AttKdClassObj);
	if (!NT_SUCCESS(status))
	{
		KdPrint(("获取对象指针失败"));
		return status;
	}
	ObReferenceObject(pFileObj);
	//加到设备栈栈顶  然后 返回 原来的栈顶
	pAttachDevObj = IoAttachDeviceToDeviceStack(pDevObj, AttKdClassObj);
	if (NULL == pAttachDevObj)
	{
		KdPrint(("附加栈顶失败!\n"));
		return STATUS_UNSUCCESSFUL;
	}
	pDevObj->Flags = pDevObj->Flags | DO_BUFFERED_IO | DO_POWER_PAGABLE;
	pDevObj->ActiveThreadCount = pDevObj->ActiveThreadCount & (~DO_DEVICE_INITIALIZING);
	((PDEVICE_EXTENSION)pDevObj->DeviceExtension)->pAttachDevObj = pAttachDevObj;
	((PDEVICE_EXTENSION)pDevObj->DeviceExtension)->ulIrpInQuene = 0;
	return status;
}
NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObject, PUNICODE_STRING pRegPath)
{
	NTSTATUS status;
	pDriverObject->DriverUnload = Unload;
	pDriverObject->MajorFunction[IRP_MJ_READ] = DriverRead;
	status=CreareDriver(pDriverObject);
	if (!NT_SUCCESS(status))
	{
		return status;
	}
	status = AttKdClass(pDriverObject->DeviceObject);
	if (!NT_SUCCESS(status))
	{
		KdPrint(("附加设备失败 :0x%X\n", status));
		return status;
	}

	KdPrint(("离开 DriverEntry!\n"));
	return STATUS_SUCCESS;
}

效果如下

猜你喜欢

转载自blog.csdn.net/qq_41071646/article/details/86530700
今日推荐