• [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
    作者:Y4ng
    出处:http://y4ng.cnblogs.com/
    文章版权属于Y4ng受法律保护。没有作者书面许可不得转载。若作者同意转载,必须以超链接形式标明文章原始出处和作者信息及本声明!
  • 相关阅读:
    “fatal error: hdf5.h: 没有那个文件或目录”解决方法
    算法狗的机器学习基础
    统计:假设检验 T检验
    各种排序和数据结构算法收藏
    知乎好书--入门神经网络和机器学习
    机器学习中的数学(1)-回归(regression)、梯度下降(gradient descent)
    第八天 T3S04
    第七天 T3S03
    第六天T3S02
    T3S01
  • 原文地址:https://www.cnblogs.com/Y4ng/p/2514720.html
Copyright © 2020-2023  润新知