[IRP HOOK] 键盘过滤驱动学习

标 题: [IRP HOOK]  键盘过滤驱动学习
作 者: 0xFFFFCCCC
时 间: 2012-05-20
链 接: http://hi.baidu.com/pushad/item/0d335810261c38483a176ee8 

 

IRP HOOK 这个篇幅整整学习了大半个多月,  中间穿插了驾照考试第二科目, 然后5.1回家十多天;

真的发现,学东西是速成的, 断断续续拖拖拉拉的 今天学过几天又忘记了。

写下此篇文章作为备忘以及借用百度空间的搜索率来帮助后来的同学!

感谢 北极星2003 写的 键盘过滤驱动之IRP劫持 , 读者会发现两份代码雷同之处很多;

附上关键代码

/*************************************************
Function:       IRPHookKeyBoard
Description:    以IRP的方式HOOK键盘设备
Input:          DeviceObject 一个驱动设备指针
Output:         无
Return:         成功返回 STATUS_SUCCESSFUL 否则为其他    
*************************************************/
NTSTATUS IRPHookKeyBoard(PDEVICE_OBJECT DeviceObject)
{
// 建立新的驱动过滤对象
PDEVICE_EXTENSION pDeviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension;
UNICODE_STRING usKeyBoardSymlic;

RtlInitUnicodeString(&usKeyBoardSymlic, L"\\Device\\keyboardClass0");

// 设置新设备的标志与底层键盘设备标记相同   
// 在DriverEntry例程中创建的设备对象,并不需要必须清除DO_DEVICE_INITIALIZING标识,   
// 这是因为这个工作将会由I/O管理器自动完成。   
// 然而,如果创建了其它设备对象,则需要进行该清除工作。   
// 对DEVICE_EXTENSION结构清0

DeviceObject->Flags = DeviceObject->Flags | ( DO_BUFFERED_IO | DO_POWER_PAGABLE | DO_DIRECT_IO );
DeviceObject->Flags = DeviceObject->Flags &~ DO_DEVICE_INITIALIZING;

RtlZeroMemory(DeviceObject->DeviceExtension, sizeof(DEVICE_EXTENSION));
pDeviceExtension->bAttached = TRUE;

// 安装过滤钩子
return IoAttachDevice(DeviceObject, &usKeyBoardSymlic, &pDeviceExtension->pKeybdDevObject);
}


NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
{
NTSTATUS Status = STATUS_UNSUCCESSFUL;
PDEVICE_OBJECT pdoDeviceObj = NULL;

pGIrp = NULL;
pGDriverObject = DriverObject;
RtlInitUnicodeString(&GusMyDriverName, L"\\Device\\MykeyboardClass");
RtlInitUnicodeString(&GusSymlinkName, L"\\Device\\keyboardSymlc");

Status = IoCreateDevice(DriverObject, sizeof(DEVICE_EXTENSION), &GusMyDriverName, \
FILE_DEVICE_UNKNOWN, FILE_DEVICE_SECURE_OPEN, FALSE, &pdoDeviceObj);

if (!NT_SUCCESS(Status))
{
DbgPrint("Device Create Error\n");
goto Exit0;
}

Status = IoCreateSymbolicLink(&GusSymlinkName, &GusMyDriverName);

if (!NT_SUCCESS(Status))
{
IoDeleteDevice(pdoDeviceObj);
DbgPrint("Create R3 symbolic Error\n");
goto Exit0;
}

DriverObject->MajorFunction[IRP_MJ_CREATE] = 
DriverObject->MajorFunction[IRP_MJ_CLOSE] = KeyBoardFileDispathCreateClose;
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = KeyBoardDispathDeviceControl;
DriverObject->MajorFunction[IRP_MJ_READ] = KeyBoardDispathRead;
DriverObject->DriverUnload = UnLoad;

Status = IRPHookKeyBoard(pdoDeviceObj);
Exit0:
return Status; 
}

// 键盘事件完成函数
// IRP = DISPATCH_LEVEL !!!
NTSTATUS OnReadCompletion(PDEVICE_OBJECT DeviceObject, PIRP pIrp, PVOID Context)
{
PKEYBOARD_INPUT_DATA pKeyBoardData  = NULL;
PDEVICE_EXTENSION pDeviceExtension  = NULL;

pDeviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension;

if (STATUS_SUCCESS == pIrp->IoStatus.Status)
{
pKeyBoardData = (PKEYBOARD_INPUT_DATA)pIrp->AssociatedIrp.SystemBuffer;

_try
{
// 按键数据处理
if (pKeyBoardData->Flags == KEY_MAKE)
{
//DbgPrint("Scan code 0x%2x Press\n", pKeyBoardData->MakeCode);
}
else if(pKeyBoardData->Flags == KEY_BREAK)
{
DbgPrint("%s %0x  ", ExplainKeyBoardCode[pKeyBoardData->MakeCode], pKeyBoardData->MakeCode);
if (pKeyBoardData->MakeCode == 0x1c)
{
DbgPrint("\n");
}
//DbgPrint("0x%2x", pKeyBoardData->MakeCode);
}
}
_except(EXCEPTION_CONTINUE_EXECUTION)
{
DbgPrint("completion error %x\n",  GetExceptionCode());
}

}

// 必须设置panding 状态,以方便底层设备处理键盘read事件
 if (pIrp->PendingReturned == TRUE)
 {
 IoMarkIrpPending(pIrp);
 }

return pIrp->IoStatus.Status;
}


NTSTATUS KeyBoardDispathRead(PDEVICE_OBJECT DeviceObject, PIRP pIrp)
{
PDEVICE_EXTENSION pDeviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension;

pGIrp = pIrp;
IoCopyCurrentIrpStackLocationToNext(pIrp);
IoSetCompletionRoutine(pIrp, OnReadCompletion, DeviceObject, TRUE, TRUE, TRUE);

return IoCallDriver(pDeviceExtension->pKeybdDevObject, pIrp);
}

// 卸载函数
NTSTATUS UnLoad(PDRIVER_OBJECT DriverObject)
{
PDEVICE_EXTENSION DeviceExtension = NULL;
KTIMER kTimer;
LARGE_INTEGER timeout;

DeviceExtension = (PDEVICE_EXTENSION)((pGDriverObject->DeviceObject)->DeviceExtension);

if (DeviceExtension->bAttached)
{
IoDetachDevice(DeviceExtension->pKeybdDevObject);
DeviceExtension->bAttached = FALSE;
}

if (NULL != pGIrp)
{
IoCancelIrp(pGIrp);
}

IoDeleteSymbolicLink(&GusSymlinkName);
IoDeleteDevice(pGDriverObject->DeviceObject);

return STATUS_SUCCESS;
}


/*IRP HOOK 键盘过滤 包含的关键头文件*/

typedef struct _DEVICE_EXTENSION {   
PDEVICE_OBJECT pKeybdDevObject ;   
ULONG           uIrpPenddingCount ;   
BOOLEAN         bAttached ;   
} DEVICE_EXTENSION, *PDEVICE_EXTENSION ;   


typedef struct _KEYBOARD_INPUT_DATA {
USHORT UnitId;
USHORT MakeCode;
USHORT Flags;
USHORT Reserved;
ULONG ExtraInformation;
} KEYBOARD_INPUT_DATA, *PKEYBOARD_INPUT_DATA;

const char ExplainKeyBoardCode[][12] = 
{
"",
"Esc",
"1", "2", "3", "4", "5", "6", "7", "8", "9", "0",
"-", "=", "Backspace", "Tab", 
"q", "w", "e", "r", "t", "y", "u", "i", "o", "p",
"[", "]", "Enter", "Left Ctrl",
"a", "s", "d", "f", "g", "h", "j", "k", "l", 
";", "'", "who2", "Left Shift", "\\", 
"z", "x", "c", "v", "b", "n", "m",
",", ".", "/", "Right Shift", 
"*", "Left Alt", "Space", "CapsLock", /*0x3A*/
"F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9", "F10", /*"F11", "F12",*/
"NumLock", "who3", /*0x46*/
"7", "8", "9", "-", "4", "5", "6", "+", "1", "2", "3", "0", ".",
"", "", "", "F11", "F12"

};


UNICODE_STRING GusMyDriverName;
UNICODE_STRING GusSymlinkName;
PDRIVER_OBJECT pGDriverObject;
PIRP pGIrp;

本文代码下载 http://115.com/file/bec4ops2#KeyBoardIRP.rar
posted @ 2012-05-23 14:08  Y4ng  阅读(3602)  评论(0编辑  收藏  举报