1

I do not understand why my source code is not working properly.

My source code is just a simple driver that just drops the IRP.

    #include <wdm.h>

    typedef struct
    {
        PDEVICE_OBJECT NextLayerDeviceObject;
    } DEVICE_EXTENSION, *PDEVICE_EXTENSION;

    const WCHAR next_device_name[] = L"\\Device\\KeyboardClass0";

    const char dbg_name[] = "[Test]";

    NTSTATUS IrpSkip(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
    {
        NTSTATUS ret = STATUS_SUCCESS;
        PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation(Irp);

        DbgPrint("%s IrpSkip() Start\n", dbg_name);
        DbgPrint("%s IrpSkip() - MajorFunction %d\n", dbg_name, Stack->MajorFunction);

        IoSkipCurrentIrpStackLocation(Irp);
        ret = IoCallDriver(((PDEVICE_EXTENSION)(DeviceObject->DeviceExtension))->NextLayerDeviceObject, Irp);

        DbgPrint("%s IrpSkip() End\n", dbg_name);

        return ret;
    }

    NTSTATUS Unload(IN PDRIVER_OBJECT DriverObject)
    {
        NTSTATUS ret = STATUS_SUCCESS;

        IoDetachDevice(((PDEVICE_EXTENSION)(DriverObject->DeviceObject->DeviceExtension))->NextLayerDeviceObject);
        IoDeleteDevice(DriverObject->DeviceObject);

        DbgPrint("%s Unload()...\n", dbg_name);

        return ret;
    }

    NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath)
    {
        NTSTATUS ret=STATUS_SUCCESS;
        UNICODE_STRING _next_device_name;

        DbgSetDebugFilterState(DPFLTR_DEFAULT_ID, DPFLTR_INFO_LEVEL, TRUE);

        DbgPrint("%s DriverEntry() Start\n", dbg_name);

        RtlInitUnicodeString(&_next_device_name, next_device_name);

        for (int i = 0; i < IRP_MJ_MAXIMUM_FUNCTION ; i++)
        {
            DriverObject->MajorFunction[i] = IrpSkip;
        }
        DriverObject->DriverUnload = Unload;
        //DriverObject->MajorFunction[IRP_MJ_READ] = Read;

        PDEVICE_OBJECT DeviceObject = 0;
        PDEVICE_EXTENSION DeviceExtension;

        ret = IoCreateDevice(DriverObject, sizeof(DEVICE_EXTENSION), 0, FILE_DEVICE_KEYBOARD, 0, TRUE, &DeviceObject);
        if (ret == STATUS_SUCCESS)
        {
            DbgPrint("%s DriverEntry() - IoCreateDevice() Success\n", dbg_name);
        }
        else
        {
            DbgPrint("%s DriverEntry() - IoCreateDevice() Fail\n", dbg_name);
            return ret;
        }
        DeviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension;
        DeviceObject->Flags |= (DO_BUFFERED_IO | DO_POWER_PAGABLE);
        DeviceObject->Flags &= DO_DEVICE_INITIALIZING;

        ret = IoAttachDevice(DeviceObject, &_next_device_name, &DeviceExtension->NextLayerDeviceObject);
        if (ret == STATUS_SUCCESS)
        {
            DbgPrint("%s DriverEntry() - IoAttachDevice() Success\n", dbg_name);
        }
        else
        {
            DbgPrint("%s DriverEntry() - IoAttachDevice() Fail\n", dbg_name);
            IoDeleteDevice(DriverObject->DeviceObject);
            return ret;
        }

        DbgPrint("%s DriverEntry() End\n", dbg_name);

        return ret;
    }

Below are the results from WinDbg

    [Test] DriverEntry() Start
    [Test] DriverEntry() - IoCreateDevice() Success
    [Test] IrpSkip() Start
    [Test] IrpSkip() - MajorFunction 2
    [Test] IrpSkip() End
    [Test] DriverEntry() - IoAttachDevice() Success
    [Test] DriverEntry() End
    [Test] IrpSkip() Start
    [Test] IrpSkip() - MajorFunction 3
    [Test] IrpSkip() End

    *** Fatal System Error: 0x0000000a
                           (0x00000000,0x00000002,0x00000001,0x82E41C24)

    Break instruction exception - code 80000003 (first chance)

    A fatal system error has occurred.
    Debugger entered on first try; Bugcheck callbacks have not been invoked.

    A fatal system error has occurred.

    nt!RtlpBreakWithStatusInstruction:
    82e83110 cc              int     3
    0: kd> k
     # ChildEBP RetAddr  
    00 82f30634 82ee7083 nt!RtlpBreakWithStatusInstruction
    01 82f30684 82ee7b81 nt!KiBugCheckDebugBreak+0x1c
    02 82f30a48 82e495cb nt!KeBugCheck2+0x68b
    03 82f30a48 82e41c24 nt!KiTrap0E+0x2cf
    04 82f30ae4 8fba3588 nt!memmove+0x124
    05 82f30b14 8fb8fb74 kbdclass!KeyboardClassServiceCallback+0xe0
    06 82f30b78 82e801b5 i8042prt!I8042KeyboardIsrDpc+0x18c
    07 82f30bd4 82e80018 nt!KiExecuteAllDpcs+0xf9
    08 82f30c20 82e7fe38 nt!KiRetireDpcList+0xd5
    09 82f30c24 00000000 nt!KiIdleLoop+0x38

It seems that CallBack is not working properly.

I do not know where the problem occurred.

I just dropped the IRP and I do not know why this is happening.

I have been searching for driver 's books and internet for two days but have not found the cause.

When the blue screen comes up, the message 'iRQL_NOT_LESS_OR_EQUAL' appears.

Help plz.

P.S. I do not speak English well. And that's the first question. I hope you understand if my question is strange.

SlayerBae
  • 67
  • 11
  • Perhaps it would be useful to add a debug statement to record the return value from `IoCallDriver` ? – Harry Johnston Mar 16 '17 at 21:03
  • IoCallDriver() return 0x103 (STATUS_PENDING) – SlayerBae Mar 17 '17 at 00:23
  • This is as expected. After STATUS_PENDING occurs, it is assumed that the CallBack function registered by KeyboardClass0 is executed. This is no problem. – SlayerBae Mar 17 '17 at 00:24
  • 2
    Have you checked what the I/O buffering flags are on `KeyboardClass0`, as per [this article](https://msdn.microsoft.com/en-us/windows/hardware/drivers/ifs/propagating-the-do-buffered-io-and-do-direct-io-flags)? – Harry Johnston Mar 17 '17 at 00:40
  • Oh, my... I made a miserable mistake. I changed the order of the two. DeviceObject->Flags |= (DO_BUFFERED_IO | DO_POWER_PAGABLE); DeviceObject->Flags &= DO_DEVICE_INITIALIZING; I thought the order did not matter. Thank you for your reply. – SlayerBae Mar 17 '17 at 01:07
  • 2
    I *think* the order is correct in the posted code, but it should be `&= ~DO_DEVICE_INITIALIZING` as per [this example](https://msdn.microsoft.com/en-us/library/windows/hardware/dn614010(v=vs.85).aspx)? That is, you're supposed to be *clearing* the flag, not *setting* it. – Harry Johnston Mar 17 '17 at 01:36
  • by call `DeviceObject->Flags &= DO_DEVICE_INITIALIZING` you clear `DO_BUFFERED_IO` flag. as result system not use `Irp->AssociatedIrp.SystemBuffer` - it == 0. but `KeyboardClassServiceCallback` assume that it not zero and crashed exactly when he try copy data (`memmove`) to this buffer. `memmove(Irp->AssociatedIrp.SystemBuffer, ` crashed when address 0 is accessed on dispatch_level(2) – RbMm Mar 17 '17 at 13:26

0 Answers0