[寒江独钓] IRP HOOK 键盘过滤之替换原键盘分发函数

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

作 者: 0xFFFFCCCC

时 间: 2012-05-20

链 接: http://hi.baidu.com/pushad/item/0a78c3ba0812e6afeaba9399 

MajorFunction.h
#ifndef _MAJORFUNCTION_HEADERS_
#define _MAJORFUNCTION_HEADERS_

#include <ntddk.h>

#define DELAY_ONE_MILLISECOND           1000000


extern POBJECT_TYPE *IoDriverObjectType;

extern NTSTATUS ObReferenceObjectByName(     
                                 IN PUNICODE_STRING ObjectPath,     
                                 IN ULONG Attributes,     
                                 IN PACCESS_STATE PassedAccessState OPTIONAL,     
                                 IN ACCESS_MASK DesiredAccess OPTIONAL,     
                                 IN POBJECT_TYPE ObjectType,     
                                 IN KPROCESSOR_MODE AccessMode,     
                                 IN OUT PVOID ParseContext OPTIONAL,     
                                 OUT PVOID *ObjectPtr);  
    

PDRIVER_DISPATCH OldMajorFunction[IRP_MJ_MAXIMUM_FUNCTION+1];

#endif

#include "MajorFunction.h"

// 原键盘驱动分发统一处理
NTSTATUS OldKeyBoardDispath(PDEVICE_OBJECT DeviceObject, PIRP pIrp)
{
    NTSTATUS Status = STATUS_UNSUCCESSFUL;
    PIO_STACK_LOCATION irpStack = NULL;

    irpStack = IoGetCurrentIrpStackLocation(pIrp);

    Status = OldMajorFunction[irpStack->MajorFunction](DeviceObject, pIrp);

    DbgPrint("IRP_MJ_FUNCTIOIN complete successful!\n");

    return Status;
}

// HOOK 函数, 替换键盘原来的MajorFunction
NTSTATUS MajorFunctionHook(PDRIVER_OBJECT DriverObject)
{
    NTSTATUS Status = STATUS_UNSUCCESSFUL;
    PDRIVER_OBJECT KeyBoardDriverObject = NULL;
    UNICODE_STRING KeyBoardDriverName;
    PFILE_OBJECT pFileObject = NULL;
    int nIndex = 0;

    RtlInitUnicodeString(&KeyBoardDriverName, L"\\Driver\\Kbdclass");

    Status = ObReferenceObjectByName(&KeyBoardDriverName, OBJ_CASE_INSENSITIVE,\
        NULL, 0, IoDriverObjectType, KernelMode, NULL, &KeyBoardDriverObject);

    if (!NT_SUCCESS(Status))
    {
        DbgPrint("in MajorFunctionHook Get ObReferenceObjectByName by KeyBoardDriverObject Error\n");
        goto Exit0;
    }

    //保存及设置新键盘的MajorFunction
    for(nIndex = 0; nIndex < IRP_MJ_MAXIMUM_FUNCTION; nIndex++)
    {
        OldMajorFunction[nIndex] = KeyBoardDriverObject->MajorFunction[nIndex];
        InterlockedExchangePointer(&KeyBoardDriverObject->MajorFunction[nIndex], DriverObject->MajorFunction[nIndex]);
    }

    DbgPrint("IRP_MJ_FUNCTION Hook Successful!\n");

    // 解除引用
    ObDereferenceObject(KeyBoardDriverObject);
Exit0:
    return Status;
}

// 卸载函数
NTSTATUS UnLoadDriver(PDRIVER_OBJECT DriverObject)
{
    NTSTATUS Status = STATUS_UNSUCCESSFUL;
    int nIndex = 0;
    PDRIVER_OBJECT KeyBoardDriverObject = NULL;
    UNICODE_STRING KeyBoardName;
    LARGE_INTEGER Delay;

    RtlInitUnicodeString(&KeyBoardName, L"\\Driver\\Kbdclass");

    Status = ObReferenceObjectByName(&KeyBoardName, OBJ_CASE_INSENSITIVE, NULL, 0, *IoDriverObjectType,\
        KernelMode, NULL, &KeyBoardDriverObject);

    if (!NT_SUCCESS(Status))
    {
        DbgPrint("UnloadDriver Get Keyboard Driver Object Error\n");
        goto Exit0;
    }


    // 交换原来的分发函数
    
    for (nIndex; nIndex < IRP_MJ_MAXIMUM_FUNCTION; nIndex++)
    {
        InterlockedExchangePointer(&KeyBoardDriverObject->MajorFunction[nIndex], OldMajorFunction[nIndex]);
    }

    DbgPrint("Change MajorFunction Successful!\n");

    Delay = RtlConvertLongToLargeInteger(5* DELAY_ONE_MILLISECOND);
    
    // 延时等待完成
    KeDelayExecutionThread(KernelMode, FALSE, &Delay);

    ObReferenceObject(KeyBoardDriverObject);
Exit0:
    return Status;
}


NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegisterPath)
{
    NTSTATUS Status = STATUS_UNSUCCESSFUL;
    int nIndex = 0;

    // 设置新的键盘分发函数
    for (nIndex; nIndex < IRP_MJ_MAXIMUM_FUNCTION; nIndex++)
    {
        DriverObject->MajorFunction[nIndex] = OldKeyBoardDispath;
    }

    DriverObject->DriverUnload = UnLoadDriver;

    Status = MajorFunctionHook(DriverObject);

    return Status;
}
posted @ 2012-05-23 14:15  Y4ng  阅读(2026)  评论(0编辑  收藏  举报