学習ノート--第四章Hook配布関数フィルタキーボード入力


転載は出典を明記してください.http://blog.csdn.net/lup7in/article/details/7015497
最近windowsカーネルのプログラミングを勉強していますが、以下は「寒江独釣」の第四章hook配布関数フィルタキーボード入力のソースコードです.本には完全なコードが提供されていません.この部分のコードをデバッグして完成しました.
#include  
#include 
#define NTSTRSAFE_LIB
#include 


extern POBJECT_TYPE IoDriverObjectType;




#define KBD_DRIVER_NAME L"\\Driver\\Kbdclass"


//        
#define DELAY_ONE_MICROSECOND (-10)
#define DELAY_ONE_MILLISECOND (DELAY_ONE_MICROSECOND * 1000)
#define DELAY_ONE_SECOND (DELAY_ONE_MILLISECOND * 1000)


//         
#define S_SHIFT 0x01//shift 
#define S_CAPS  0x02//     
#define S_NUM   0x04//     


ULONG gC2pKeyCount = 0;


unsigned char 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
};


//           
PDRIVER_DISPATCH OldMajorFunction[IRP_MJ_MAXIMUM_FUNCTION+1];


//                                
NTSTATUS ObReferenceObjectByName(
PUNICODE_STRING ObjectName,
ULONG Attributes,
PACCESS_STATE AccessState,
ACCESS_MASK DesiredAccess,
POBJECT_TYPE ObjectType,
KPROCESSOR_MODE AccessMode,
PVOID ParseContext,
PVOID *Object
);


PDRIVER_OBJECT pKbdDriverObject = NULL;
UNICODE_STRING uniNtNameString;


//         
NTSTATUS OpenKbdDriver()
{
NTSTATUS status;
RtlInitUnicodeString(&uniNtNameString,KBD_DRIVER_NAME);
status = ObReferenceObjectByName(&uniNtNameString,OBJ_CASE_INSENSITIVE,NULL,0,IoDriverObjectType,KernelMode,NULL,&pKbdDriverObject);
if(NT_SUCCESS(status))
{
ObDereferenceObject(pKbdDriverObject);
DbgPrint("open the kbd driver success!");
}
else
{
DbgPrint("open the kbd driver fail!");
}
return status;
}


static int kb_status = S_NUM;
//              
//2011/11/10
void _stdcall print_keystroke(UCHAR sch,USHORT Flags)
{
UCHAR ch = 0;
int off = 0;
//kb_status = S_NUM;
//DbgPrint("%x
",sch); // if(Flags == KEY_MAKE/*(sch & 0x80) == 0*/) { switch(sch) { case 0x3A: kb_status ^= S_CAPS; break; case 0x2A: case 0x36: kb_status |= S_SHIFT; break; case 0x45: kb_status ^= S_NUM; break; } } else if(Flags == KEY_BREAK) // { if(sch == 0x2A || sch == 0x36) kb_status &= ~S_SHIFT; } if(kb_status & S_CAPS) { off = 84 * 1; } if(kb_status & S_SHIFT) { off = 84 * 2; } if((kb_status & S_SHIFT) && (kb_status & S_CAPS)) { off = 84 * 3; } //DbgPrint("%d
",off); if((sch < 0x47) || ((sch >= 0x47 && sch < 0x54) && (kb_status & S_NUM))) { ch = asciiTbl[off + sch]; } if(Flags == KEY_MAKE){ if(ch >= 0x20 && ch < 0x7F) { DbgPrint("%C
",ch); } } } NTSTATUS c2pReadComplete( PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID Context ) { PIO_STACK_LOCATION IrpSp; ULONG buf_len = 0; //systembuffer KEYBOARD_INPUT_DATA PUCHAR buf = NULL; size_t i; ULONG numKeys = 0; PKEYBOARD_INPUT_DATA KeyData = NULL; IrpSp = IoGetCurrentIrpStackLocation(Irp); // if(NT_SUCCESS(Irp->IoStatus.Status)) { // buf = Irp->AssociatedIrp.SystemBuffer; KeyData = (PKEYBOARD_INPUT_DATA)buf; // buf_len = Irp->IoStatus.Information; numKeys = buf_len / sizeof(KEYBOARD_INPUT_DATA); for(i = 0;i < numKeys;i++) { // //DbgPrint("numKeys:%d",numKeys); //DbgPrint("ScanCode:%x",KeyData->MakeCode); //DbgPrint("%s
",KeyData->Flags ? "UP" : "DOWN"); print_keystroke((UCHAR)KeyData->MakeCode,KeyData->Flags); // ctrl // CAPS_LOCK // ctrl // //if(KeyData->MakeCode == LCONTROL) //{ // KeyData->MakeCode = CAPS_LOCK; //} } // // //for(i = 0;i < buf_len;i++) //{ // DbgPrint("ctrl2cap:%2x\r
",buf[i]); //} } gC2pKeyCount--; //DbgPrint("count:%d",gC2pKeyCount); if(Irp->PendingReturned) { IoMarkIrpPending(Irp); } return Irp->IoStatus.Status; } // NTSTATUS MyDispatchFunction ( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ) { PUCHAR buf = NULL; ULONG buf_len = 0; ULONG i; PIO_STACK_LOCATION irpsp = IoGetCurrentIrpStackLocation(Irp); // hook if(irpsp->MajorFunction == IRP_MJ_READ) { irpsp->Control = SL_INVOKE_ON_SUCCESS | SL_INVOKE_ON_ERROR | SL_INVOKE_ON_CANCEL; // , irpsp->Context = irpsp->CompletionRoutine; irpsp->CompletionRoutine = (PIO_COMPLETION_ROUTINE)c2pReadComplete; //DbgPrint(" .../n"); gC2pKeyCount++; //DbgPrint("count:%d",gC2pKeyCount); // , return OldMajorFunction[irpsp->MajorFunction](DeviceObject,Irp); } else { return OldMajorFunction[irpsp->MajorFunction](DeviceObject,Irp); } } // VOID ReplaceDispatch() { ULONG i; for(i = 0;i < IRP_MJ_MAXIMUM_FUNCTION + 1;i++) { // OldMajorFunction[i] = pKbdDriverObject->MajorFunction[i]; // InterlockedExchangePointer(&pKbdDriverObject->MajorFunction[i],MyDispatchFunction); DbgPrint("replace successful!"); } } // VOID ReSetDispatchFunction() { ULONG i; for(i = 0;i < IRP_MJ_MAXIMUM_FUNCTION + 1;i++) { InterlockedExchangePointer(&pKbdDriverObject->MajorFunction[i],OldMajorFunction[i]); DbgPrint("reset dispatch function success!"); } } // //2011/11/19 VOID HookDispatchUnload(IN PDRIVER_OBJECT DriverObject) { PDEVICE_OBJECT DeviceObject; PRKTHREAD pCurrentThread; LARGE_INTEGER lDelay; lDelay = RtlConvertLongToLargeInteger(100 * DELAY_ONE_MILLISECOND); pCurrentThread = KeGetCurrentThread(); // KeSetPriorityThread(pCurrentThread,LOW_REALTIME_PRIORITY); UNREFERENCED_PARAMETER(DriverObject); KdPrint(("DriverEntry unLoading...
")); // ReSetDispatchFunction(); while(gC2pKeyCount) { KeDelayExecutionThread(KernelMode,FALSE,&lDelay); } KdPrint(("DriverEntry unLoad OK!
")); } // NTSTATUS DriverEntry( PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath ) { NTSTATUS status; DriverObject->DriverUnload = HookDispatchUnload; // status = OpenKbdDriver(); if(NT_SUCCESS(status)) { // ReplaceDispatch(); } return status; }