64位内开发第二十三讲,分层过滤驱动-键盘过滤

64位内开发第二十三讲,分层过滤驱动-键盘过滤

来自: iBinary - 博客园 禁止爬虫.如果遇到此文章不是 出自 博客园 或者 腾讯云+社区. 请举报目标网站. 或者跳转至 本人博客园进行查看.
因为文章随时更改.可能今天只是写了一部分.或者有错误. 而明天就进行更改重发了.
但是爬虫爬取的文章还是之前错误的文章.会为读者造成文章有错误的假象.

一丶键盘过滤的两种方式

1.1 第一种方式 驱动对象方式绑定

第一种方式是通过 寻找键盘驱动对象. 然后遍历其下面的所有设备. 对于每一个设备创建一个过滤设备,并且附加上去.

此方式可以应用于多个键盘设备.

核心代码如下:

#include "CMain.h"
#include <ntddkbd.h>

// 声明微软未公开的ObReferenceObjectByName()函数
extern "C" NTSTATUS ObReferenceObjectByName(
    PUNICODE_STRING ObjectName,
    ULONG Attributes,
    PACCESS_STATE AccessState,
    ACCESS_MASK DesiredAccess,
    POBJECT_TYPE ObjectType,
    KPROCESSOR_MODE AccessMode,
    PVOID ParseContest,
    PVOID* Object
);

extern "C" POBJECT_TYPE * IoDriverObjectType;




VOID FilterUnload(IN PDRIVER_OBJECT pDriverObject)
{
    //跟以往卸载不通.过滤驱动卸载的时候 需要解除挂载.然后删除该设备对象
    //循环卸载
    //IoEnumerateDeviceObjectList()
    KdPrint(("[Filter]-->DriverUnload \r\n"));
    PDEVICE_OBJECT next_device = nullptr;

    if (pDriverObject->DeviceObject == nullptr)
    {
        KdPrint(("[Filter]--> Previous Driver Unload \r\n"));
        return;
    }

    next_device = pDriverObject->DeviceObject;
    while (next_device != nullptr)
    {
        PDEVICE_SAVE_INFOMATION device_save_info =
            (PDEVICE_SAVE_INFOMATION)next_device->DeviceExtension;
        if (device_save_info == nullptr)
        {
            IoDeleteDevice(next_device);
            break;
        }

        //得到记录的下一个设备.
        if (device_save_info->attach_to_device != nullptr)
        {
            //解除附加
            IoDetachDevice(device_save_info->attach_to_device);
            device_save_info->attach_to_device = nullptr;
        }
        //删除设备
        IoDeleteDevice(next_device);
        device_save_info->src_device = nullptr;
        next_device = next_device->NextDevice;
    }
    KdPrint(("[Filter]--> Perfect Driver Unload \r\n"));
}


NTSTATUS Ctrl2capPower(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP           Irp
)
{
    PDEVICE_SAVE_INFOMATION   devExt;

    devExt = (PDEVICE_SAVE_INFOMATION)DeviceObject->DeviceExtension;
    PoStartNextPowerIrp(Irp);
    IoSkipCurrentIrpStackLocation(Irp);
    return PoCallDriver(devExt->attach_to_device, Irp);
}

NTSTATUS Ctrl2capPnP(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP           Irp
)
{
    PDEVICE_SAVE_INFOMATION           devExt;
    PIO_STACK_LOCATION          irpStack;
    NTSTATUS                    status = STATUS_SUCCESS;
    KIRQL                       oldIrql;
    KEVENT                      event;

    devExt = (PDEVICE_SAVE_INFOMATION)DeviceObject->DeviceExtension;
    irpStack = IoGetCurrentIrpStackLocation(Irp);

    switch (irpStack->MinorFunction) {
    case IRP_MN_REMOVE_DEVICE:

        IoSkipCurrentIrpStackLocation(Irp);
        IoCallDriver(devExt->attach_to_device, Irp);

        IoDetachDevice(devExt->attach_to_device);
        IoDeleteDevice(DeviceObject);

        status = STATUS_SUCCESS;
        break;

    case IRP_MN_SURPRISE_REMOVAL:

        //
        // Same as a remove device, but don't call IoDetach or IoDeleteDevice.
        //
        IoSkipCurrentIrpStackLocation(Irp);
        status = IoCallDriver(devExt->attach_to_device, Irp);
        break;

    case IRP_MN_START_DEVICE:
    case IRP_MN_QUERY_REMOVE_DEVICE:
    case IRP_MN_QUERY_STOP_DEVICE:
    case IRP_MN_CANCEL_REMOVE_DEVICE:
    case IRP_MN_CANCEL_STOP_DEVICE:
    case IRP_MN_FILTER_RESOURCE_REQUIREMENTS:
    case IRP_MN_STOP_DEVICE:
    case IRP_MN_QUERY_DEVICE_RELATIONS:
    case IRP_MN_QUERY_INTERFACE:
    case IRP_MN_QUERY_CAPABILITIES:
    case IRP_MN_QUERY_DEVICE_TEXT:
    case IRP_MN_QUERY_RESOURCES:
    case IRP_MN_QUERY_RESOURCE_REQUIREMENTS:
    case IRP_MN_READ_CONFIG:
    case IRP_MN_WRITE_CONFIG:
    case IRP_MN_EJECT:
    case IRP_MN_SET_LOCK:
    case IRP_MN_QUERY_ID:
    case IRP_MN_QUERY_PNP_DEVICE_STATE:
    default:
        IoSkipCurrentIrpStackLocation(Irp);
        status = IoCallDriver(devExt->attach_to_device, Irp);
        break;
    }

    return status;
}


PDEVICE_OBJECT FilterAttach(PDEVICE_OBJECT src_device, PDEVICE_OBJECT target_device)
{
    PDEVICE_OBJECT attach_to_device = nullptr;
    NTSTATUS status = STATUS_UNSUCCESSFUL;
    status = IoAttachDeviceToDeviceStackSafe(src_device, target_device, &attach_to_device);
    if (NT_ERROR(status))
        return nullptr;
    return attach_to_device;
}

NTSTATUS FilterComplete(IN PDEVICE_OBJECT driver,
    IN PIRP pIrp)
{

    NTSTATUS ntStatus = STATUS_SUCCESS;
    //将自己完成IRP,改成由底层驱动负责
    PDEVICE_SAVE_INFOMATION pdx = (PDEVICE_SAVE_INFOMATION)driver->DeviceExtension;
    //调用底层驱动
    IoSkipCurrentIrpStackLocation(pIrp);

    ntStatus = IoCallDriver(pdx->attach_to_device, pIrp);
    return ntStatus;
}


NTSTATUS
keyboard(
    PDEVICE_OBJECT DeviceObject,
    PIRP Irp,
    PVOID Context
)
{
    KdBreakPoint();
    PIO_STACK_LOCATION irp_stack = nullptr;
    PKEYBOARD_INPUT_DATA key_data_ptr = nullptr;
    ULONG number_keys = 0;
    irp_stack = IoGetCurrentIrpStackLocation(Irp);
    if (NT_SUCCESS(Irp->IoStatus.Status))
    {
        //获取Irp中的数据.
        key_data_ptr = (PKEYBOARD_INPUT_DATA)Irp->AssociatedIrp.SystemBuffer;
        number_keys = Irp->IoStatus.Information / sizeof(KEYBOARD_INPUT_DATA);
        for (int i = 0; i < number_keys; i++)
        {
            KdPrint(
                ("The Code is [%x] key State = [%s] \r\n",
                    key_data_ptr[i].MakeCode, key_data_ptr[i].Flags ? "up" : "down")
            );
        }
    }

    //处理pending位传播
    if (Irp->PendingReturned)
    {
        IoMarkIrpPending(Irp);
    }
    return Irp->IoStatus.Status;
}
NTSTATUS FilterRead(IN PDEVICE_OBJECT driver,
    IN PIRP pIrp)
{
    NTSTATUS status = STATUS_SUCCESS;
    if (pIrp->CurrentLocation == 1)
    {
        status = STATUS_INVALID_DEVICE_REQUEST;
        pIrp->IoStatus.Status = status;
        pIrp->IoStatus.Information = 0;
        IoCompleteRequest(pIrp, IO_NO_INCREMENT);
        return status;
    }

    IoCopyCurrentIrpStackLocationToNext(pIrp);
    //设置一个完成例程,用来进行过滤.当底层按键返回的时候则会触发完成例程.
    IoSetCompletionRoutine(
        pIrp,
        keyboard,
        driver,
        TRUE,
        TRUE,
        TRUE);


    //调用底层驱动
    PDEVICE_SAVE_INFOMATION pdx = (PDEVICE_SAVE_INFOMATION)driver->DeviceExtension;
    return IoCallDriver(pdx->attach_to_device, pIrp);
}

PDRIVER_OBJECT GetKeyBoardDriverObjByDriverName(WCHAR* driver_name)
{
    NTSTATUS status = STATUS_UNSUCCESSFUL;
    PDRIVER_OBJECT keyboard_driver = nullptr;
    UNICODE_STRING ucd_kbd_driver_name = { 0 };
    status = RtlUnicodeStringInit(&ucd_kbd_driver_name, driver_name);
    if (NT_ERROR(status))
    {
        return nullptr;
    }
    //通过驱动名寻找其驱动对象. 然后寻找驱动对象里面记录的设备.找到所属的设备进行绑定.
    status = ObReferenceObjectByName(
        &ucd_kbd_driver_name,
        OBJ_CASE_INSENSITIVE,
        NULL,
        0,
        *IoDriverObjectType,
        KernelMode,
        NULL,
        (PVOID*)&keyboard_driver);
    if (NT_ERROR(status))
    {
        return nullptr;
    }
    else
    {
        ObDereferenceObject(keyboard_driver);
        return keyboard_driver;
    }
    return keyboard_driver;
}

PDEVICE_OBJECT CreateDevice(
    PDRIVER_OBJECT driver,
    PDEVICE_OBJECT target_device)
{
    NTSTATUS status = STATUS_UNSUCCESSFUL;
    PDEVICE_OBJECT filter_device = nullptr;
    status = IoCreateDevice(driver,
        sizeof(DEVICE_SAVE_INFOMATION),
        NULL,
        target_device->DeviceType,
        target_device->Characteristics,
        FALSE,
        &filter_device);
    if (NT_ERROR(status))
    {
        return nullptr;
    }

    return filter_device;
}

PDEVICE_OBJECT AttachToDevice(
    PDEVICE_OBJECT filter_device,
    PDEVICE_OBJECT target_device)
{
    PDEVICE_OBJECT stack_low_device = nullptr;
    NTSTATUS status = STATUS_UNSUCCESSFUL;
    status = IoAttachDeviceToDeviceStackSafe(
        filter_device,
        target_device,
        &stack_low_device);
    if (NT_ERROR(status))
    {
        return nullptr;
    }
    return stack_low_device;
}

void InitDeviceExtension(
    PDEVICE_OBJECT filter_device,
    PDEVICE_OBJECT target_device,
    PDEVICE_OBJECT stack_low_device)
{
    PDEVICE_SAVE_INFOMATION save_info = (PDEVICE_SAVE_INFOMATION)filter_device->DeviceExtension;
    save_info->src_device = filter_device;
    save_info->target_next_device = target_device;
    save_info->attach_to_device = stack_low_device;
}

NTSTATUS InitAttach(PDRIVER_OBJECT keyboard_driver, PDRIVER_OBJECT driver)
{
    NTSTATUS status = STATUS_UNSUCCESSFUL;
    PDEVICE_OBJECT target_device = nullptr;
    PDEVICE_OBJECT filter_device = nullptr;
    PDEVICE_OBJECT stack_low_device = nullptr;
    //循环遍历驱动对象里面的设备.并且创建相同过滤设备进行绑定.
    KdBreakPoint();
    target_device = keyboard_driver->DeviceObject;
    while (target_device)
    {
        //创建过滤设备
        filter_device = CreateDevice(driver, target_device);
        if (filter_device == nullptr)
        {
            return STATUS_UNSUCCESSFUL;
        }
        else
        {
            //进行绑定
            stack_low_device = AttachToDevice(filter_device, target_device);
            if (stack_low_device == nullptr)
            {
                if (filter_device != nullptr)
                {
                    IoDeleteDevice(filter_device);
                }
                filter_device = nullptr;
                return status;
            }


            //记录相应的设备.
            InitDeviceExtension(filter_device, target_device, stack_low_device);
            //初始化过滤设备的属性
            filter_device->DeviceType = stack_low_device->DeviceType;
            filter_device->Characteristics = stack_low_device->Characteristics;
            filter_device->StackSize = stack_low_device->StackSize + 1;
            filter_device->Flags |= stack_low_device->Flags & (DO_BUFFERED_IO | DO_DIRECT_IO | DO_POWER_PAGABLE);
        }
        target_device = target_device->NextDevice;
    }
}

NTSTATUS DriverEntry(PDRIVER_OBJECT driver, PUNICODE_STRING regpath)
{
    //1.设置驱动的卸载以及派遣函数
    driver->DriverUnload = FilterUnload;
    for (int i = 0; i < IRP_MJ_MAXIMUM_FUNCTION; i++)
    {
        driver->MajorFunction[i] = FilterComplete;

    }
    driver->MajorFunction[IRP_MJ_READ] = FilterRead;
    driver->MajorFunction[IRP_MJ_POWER] = Ctrl2capPower;
    driver->MajorFunction[IRP_MJ_PNP] = Ctrl2capPnP;

    //1.寻找目标设备的驱动对象
    KdBreakPoint();
    PDRIVER_OBJECT keyboard_driver = nullptr;
    keyboard_driver = GetKeyBoardDriverObjByDriverName(L"\\Driver\\Kbdclass");
    if (keyboard_driver == nullptr)
    {
        return STATUS_UNSUCCESSFUL;
    }
    //2.进行绑定
    return InitAttach(keyboard_driver, driver);
}

1.2 第二种方式,直接设备类型绑定.

此方式可以使用Winobj来查看一下你想绑定的键盘设备. 代码还是使用 上一节所用.

在Winobj如下界面则可以看到键盘驱动有多少了.

只需要微微改动即可.

#include "CMain.h"
#include <ntddkbd.h>

PDEVICE_OBJECT GetAttachDeviceByName(
    IN wchar_t* attach_device_name,
    OUT PFILE_OBJECT* fileobj)
{
    NTSTATUS status = STATUS_UNSUCCESSFUL;
    UNICODE_STRING ucd_attach_device_name = { 0 };
    PDEVICE_OBJECT target_next_device = nullptr;
    if (attach_device_name == nullptr)
        return nullptr;

    status = RtlUnicodeStringInit(&ucd_attach_device_name, attach_device_name);
    if (NT_ERROR(status))
        return nullptr;

    status = IoGetDeviceObjectPointer(&ucd_attach_device_name,
        FILE_ALL_ACCESS,
        fileobj,
        &target_next_device);
    if (NT_ERROR(status))
    {
        KdPrint(("[Filter]--->IoGetDeviceObjectPointer Error\r\n"));
        return nullptr;
    }

    return target_next_device;
}

VOID FilterUnload(IN PDRIVER_OBJECT pDriverObject)
{
    //跟以往卸载不通.过滤驱动卸载的时候 需要解除挂载.然后删除该设备对象
    //循环卸载
    //IoEnumerateDeviceObjectList()
    KdPrint(("[Filter]-->DriverUnload \r\n"));
    PDEVICE_OBJECT next_device = nullptr;

    if (pDriverObject->DeviceObject == nullptr)
    {
        KdPrint(("[Filter]--> Previous Driver Unload \r\n"));
        return;
    }

    next_device = pDriverObject->DeviceObject;
    while (next_device != nullptr)
    {
        PDEVICE_SAVE_INFOMATION device_save_info =
            (PDEVICE_SAVE_INFOMATION)next_device->DeviceExtension;
        if (device_save_info == nullptr)
        {
            IoDeleteDevice(next_device);
            break;
        }

        //得到记录的下一个设备.
        if (device_save_info->attach_to_device != nullptr)
        {
            //解除附加
            IoDetachDevice(device_save_info->attach_to_device);
            device_save_info->attach_to_device = nullptr;
        }
        if (device_save_info->target_next_fileobj != nullptr)
        {
            //解除引用
            ObDereferenceObject(device_save_info->target_next_fileobj);
            device_save_info->target_next_fileobj = nullptr;
            device_save_info->target_next_device = nullptr;
        }
        //删除设备
        IoDeleteDevice(next_device);
        device_save_info->src_device = nullptr;
        next_device = next_device->NextDevice;
    }
    KdPrint(("[Filter]--> Perfect Driver Unload \r\n"));
}

PDEVICE_OBJECT CreateFilterDevice(PDRIVER_OBJECT driver)
{
    UNICODE_STRING ucd_filter_device_name = { 0 };
    NTSTATUS status = STATUS_UNSUCCESSFUL;
    PDEVICE_OBJECT filter_device = nullptr;
    if (driver == nullptr)
        return nullptr;
    //创建设备
    status = IoCreateDevice(
        driver,
        sizeof(DEVICE_SAVE_INFOMATION),
        nullptr,
        FILE_DEVICE_KEYBOARD,
        0,
        FALSE,
        &filter_device);
    if (NT_ERROR(status))
        return nullptr;
    //初始化驱动
    filter_device->Flags |= (DO_BUFFERED_IO | DO_POWER_PAGABLE);
    filter_device->Flags &= ~DO_DEVICE_INITIALIZING;
    return filter_device;
}
PDEVICE_OBJECT FilterAttach(PDEVICE_OBJECT src_device, PDEVICE_OBJECT target_device)
{
    PDEVICE_OBJECT attach_to_device = nullptr;
    NTSTATUS status = STATUS_UNSUCCESSFUL;

    status = IoAttachDeviceToDeviceStackSafe(src_device, target_device, &attach_to_device);
    if (NT_ERROR(status))
        return nullptr;

    return attach_to_device;
}

NTSTATUS FilterComplete(IN PDEVICE_OBJECT driver,
    IN PIRP pIrp)
{
    NTSTATUS ntStatus = STATUS_SUCCESS;
    //将自己完成IRP,改成由底层驱动负责
    PDEVICE_SAVE_INFOMATION pdx = (PDEVICE_SAVE_INFOMATION)driver->DeviceExtension;
    //调用底层驱动
    IoSkipCurrentIrpStackLocation(pIrp);
    ntStatus = IoCallDriver(pdx->attach_to_device, pIrp);
    return ntStatus;
}

NTSTATUS Ctrl2capPower(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP           Irp
)
{
    PDEVICE_SAVE_INFOMATION   devExt;

    devExt = (PDEVICE_SAVE_INFOMATION)DeviceObject->DeviceExtension;
    PoStartNextPowerIrp(Irp);
    IoSkipCurrentIrpStackLocation(Irp);
    return PoCallDriver(devExt->attach_to_device, Irp);
}

NTSTATUS Ctrl2capPnP(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP           Irp
)
{
    PDEVICE_SAVE_INFOMATION           devExt;
    PIO_STACK_LOCATION          irpStack;
    NTSTATUS                    status = STATUS_SUCCESS;
    KIRQL                       oldIrql;
    KEVENT                      event;

    devExt = (PDEVICE_SAVE_INFOMATION)DeviceObject->DeviceExtension;
    irpStack = IoGetCurrentIrpStackLocation(Irp);

    switch (irpStack->MinorFunction) {
    case IRP_MN_REMOVE_DEVICE:

        IoSkipCurrentIrpStackLocation(Irp);
        IoCallDriver(devExt->attach_to_device, Irp);

        IoDetachDevice(devExt->attach_to_device);
        IoDeleteDevice(DeviceObject);

        status = STATUS_SUCCESS;
        break;

    case IRP_MN_SURPRISE_REMOVAL:

        //
        // Same as a remove device, but don't call IoDetach or IoDeleteDevice.
        //
        IoSkipCurrentIrpStackLocation(Irp);
        status = IoCallDriver(devExt->attach_to_device, Irp);
        break;

    case IRP_MN_START_DEVICE:
    case IRP_MN_QUERY_REMOVE_DEVICE:
    case IRP_MN_QUERY_STOP_DEVICE:
    case IRP_MN_CANCEL_REMOVE_DEVICE:
    case IRP_MN_CANCEL_STOP_DEVICE:
    case IRP_MN_FILTER_RESOURCE_REQUIREMENTS:
    case IRP_MN_STOP_DEVICE:
    case IRP_MN_QUERY_DEVICE_RELATIONS:
    case IRP_MN_QUERY_INTERFACE:
    case IRP_MN_QUERY_CAPABILITIES:
    case IRP_MN_QUERY_DEVICE_TEXT:
    case IRP_MN_QUERY_RESOURCES:
    case IRP_MN_QUERY_RESOURCE_REQUIREMENTS:
    case IRP_MN_READ_CONFIG:
    case IRP_MN_WRITE_CONFIG:
    case IRP_MN_EJECT:
    case IRP_MN_SET_LOCK:
    case IRP_MN_QUERY_ID:
    case IRP_MN_QUERY_PNP_DEVICE_STATE:
    default:
        IoSkipCurrentIrpStackLocation(Irp);
        status = IoCallDriver(devExt->attach_to_device, Irp);
        break;
    }

    return status;
}

NTSTATUS Ctrl2capReadComplete(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp,
    IN PVOID Context
)
{
    PIO_STACK_LOCATION        IrpSp = nullptr;
    PKEYBOARD_INPUT_DATA      key_data_ptr = nullptr;
    ULONG                       numKeys,i = 0;
    IrpSp = IoGetCurrentIrpStackLocation(Irp);
    if (NT_SUCCESS(Irp->IoStatus.Status)) {
        key_data_ptr = (PKEYBOARD_INPUT_DATA)Irp->AssociatedIrp.SystemBuffer;
        numKeys = Irp->IoStatus.Information / sizeof(KEYBOARD_INPUT_DATA);

        for (i = 0; i < numKeys; i++) {

            KdPrint(
                ("The Code is [%x] key State = [%s] \r\n",
                    key_data_ptr[i].MakeCode, key_data_ptr[i].Flags ? "up" : "down")
            );

            //替换按键
            if (key_data_ptr[i].MakeCode == 0x1f) {

                key_data_ptr[i].MakeCode = 0x20;
            }
        }
    }

    //传播pending
    if (Irp->PendingReturned) {

        IoMarkIrpPending(Irp);
    }
    return Irp->IoStatus.Status;
}

NTSTATUS FilterRead(IN PDEVICE_OBJECT device,
    IN PIRP pIrp)
{

    NTSTATUS ntStatus = STATUS_UNSUCCESSFUL;
    IoCopyCurrentIrpStackLocationToNext(pIrp);
    IoSetCompletionRoutine(
        pIrp, 
        Ctrl2capReadComplete,
        device,
        TRUE,
        TRUE, 
        TRUE);
    PDEVICE_SAVE_INFOMATION pdx = (PDEVICE_SAVE_INFOMATION)device->DeviceExtension;

    return IoCallDriver(pdx->attach_to_device,pIrp);
}

NTSTATUS DriverEntry(PDRIVER_OBJECT driver, PUNICODE_STRING regpath)
{
    //1.设置驱动的卸载以及派遣函数
    driver->DriverUnload = FilterUnload;
    for (int i = 0; i < IRP_MJ_MAXIMUM_FUNCTION; i++)
    {
        driver->MajorFunction[i] = FilterComplete;

    }
    driver->MajorFunction[IRP_MJ_READ] = FilterRead;
    driver->MajorFunction[IRP_MJ_POWER] = Ctrl2capPower;
    driver->MajorFunction[IRP_MJ_PNP] = Ctrl2capPnP;

    //2.寻找目标设备.也就是我们想要Attah的设备
    PDEVICE_OBJECT target_device = nullptr;
    PFILE_OBJECT   target_fileobj = nullptr;
    PDEVICE_OBJECT src_device = nullptr;
    PDEVICE_OBJECT attach_to_device = nullptr;
    KdBreakPoint();
    target_device = GetAttachDeviceByName(L"\\Device\\KeyboardClass0", &target_fileobj);
    if (target_device == nullptr)
    {
        KdPrint(("[Filter]--> GetAttachDeviceByName Fail \r\n"));
        return STATUS_UNSUCCESSFUL;
    }
    KdPrint(("[Filter]--> Mount Target Device = [%p] \r\n", target_device));
    //3.创建设备,以及设置设备扩展
    src_device = CreateFilterDevice(driver);
    if (src_device == nullptr)
    {

        KdPrint(("[Filter]--> CreateFilterDevice Fail \r\n"));
        if (target_fileobj != nullptr)
        {
            ObReferenceObject(target_fileobj);
            target_fileobj = nullptr;
        }
        return STATUS_UNSUCCESSFUL;
    }
    KdPrint(("[Filter]--> Filter Device = [%p] \r\n", src_device));

    //4.Attach到目标设备
    attach_to_device = FilterAttach(src_device, target_device);
    if (attach_to_device == nullptr)
    {
        KdPrint(("[Filter]--> FilterAttach Fail \r\n"));
        if (target_fileobj != nullptr)
        {
            ObReferenceObject(target_fileobj);
            target_fileobj = nullptr;
        }
        return STATUS_UNSUCCESSFUL;
    }
    KdPrint(("[Filter]--> Attach Device = [%p] \r\n", attach_to_device));
    //5.记录一下信息
    PDEVICE_SAVE_INFOMATION device_save_info_ptr =
        (PDEVICE_SAVE_INFOMATION)src_device->DeviceExtension;
    device_save_info_ptr->src_device = src_device;              //记录我们的设备
    device_save_info_ptr->target_next_device = target_device;   //记录我们要挂载的目标设备
    device_save_info_ptr->target_next_fileobj = target_fileobj; //记录文件对象
    device_save_info_ptr->attach_to_device = attach_to_device;  //记录下一层设备
    return STATUS_SUCCESS;
}

1.3 效果

第一种方式 只是进行了打印输出。
第二种方式 是把s键替换成了d键 所以此时如果按下s 那么将会被替换成d
注意:
代码只是一个demo 便于说明键盘过滤是怎么一回事. 并不保证运行后不会蓝屏.因为并没有做同步等相关处理.
也可能会有其他问题.

posted @ 2022-08-21 13:25  iBinary  阅读(691)  评论(0编辑  收藏  举报