前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >64位内开发第二十三讲,分层过滤驱动-键盘过滤

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

作者头像
IBinary
发布2022-09-23 12:38:52
6510
发布2022-09-23 12:38:52
举报
文章被收录于专栏:逆向技术逆向技术逆向技术

目录

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 便于说明键盘过滤是怎么一回事. 并不保证运行后不会蓝屏.因为并没有做同步等相关处理. 也可能会有其他问题.

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2022-08-21,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 64位内开发第二十三讲,分层过滤驱动-键盘过滤
    • 一丶键盘过滤的两种方式
      • 1.1 第一种方式 驱动对象方式绑定
      • 1.2 第二种方式,直接设备类型绑定.
      • 1.3 效果
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档