How can I modfy mouse_input_data in irp

61 Views Asked by At

I want to modify the flags field in MOUSE_INPUT_DATA which is provided by Irp, but every I set flags to 3, it gives me a blue screen. So how can I change the value of MOUSE_INPUT_DATA correctly?

Here is the code, if I delete the line input[i].Flags= 3; everything works fine, so I guess the MOUSE_INPUT_DATA I received here is only for monitoring purposes? what functions must I call before modifying them?

#include "ntddk.h"
#include "ntddmou.h"

extern POBJECT_TYPE* IoDriverObjectType;
NTKERNELAPI NTSTATUS ObReferenceObjectByName(
    IN PUNICODE_STRING ObjectName,
    IN ULONG Attributes,
    IN PACCESS_STATE AccessState,
    IN PACCESS_MASK DesiredAccess,
    IN POBJECT_TYPE ObjectType,
    IN KPROCESSOR_MODE AccessMode,
    IN PVOID ParseConext,
    OUT PVOID* Object);

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

ULONG pendingKey = 0;

VOID Unload(IN PDRIVER_OBJECT DriverObject)
{
    LARGE_INTEGER interval = { 0 };
    PDEVICE_OBJECT DeviceObject = DriverObject->DeviceObject;
    interval.QuadPart = -10 * 1000 * 1000;

    KdPrint(("Unloading"));
    while (DeviceObject) {
        IoDetachDevice(((PDEVICE_EXTENSION)DeviceObject->DeviceExtension)->LowerDevice);
        DeviceObject = DeviceObject->NextDevice;
    }
    KdPrint(("detached"));
    while (pendingKey) {
        KeDelayExecutionThread(KernelMode, FALSE, &interval);
    }

    DeviceObject = DriverObject->DeviceObject;
    while (DeviceObject) 
    {
        IoDeleteDevice(DeviceObject);
        DeviceObject = DeviceObject->NextDevice;
    }
    KdPrint(("Unloaded"));
}

NTSTATUS DispatchPass(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
    IoCopyCurrentIrpStackLocationToNext(Irp);
    return IoCallDriver(((PDEVICE_EXTENSION)DeviceObject->DeviceExtension)->LowerDevice, Irp);
}

NTSTATUS ReadComplete(PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID Context)
{
    PMOUSE_INPUT_DATA input = (PMOUSE_INPUT_DATA)Irp->AssociatedIrp.SystemBuffer;
    int structnum = Irp->IoStatus.Information / sizeof(MOUSE_INPUT_DATA);

    if (NT_SUCCESS(Irp->IoStatus.Status))
    {
        for (int i = 0; i < structnum; i++)
        {
            input[i].Flags= 3;
            KdPrint(("flag:%d, state:%d, x:%d, y:%d",input[i].Flags, input[i].ButtonFlags, input[i].LastX, input[i].LastY));
        }
    }

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

}

NTSTATUS DispatchRead(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
    IoCopyCurrentIrpStackLocationToNext(Irp);

    IoSetCompletionRoutine(Irp, ReadComplete, NULL, TRUE, TRUE, TRUE);

    return IoCallDriver(((PDEVICE_EXTENSION)DeviceObject->DeviceExtension)->LowerDevice, Irp);
}

NTSTATUS AttachMouseDevice(PDRIVER_OBJECT DriverObject)
{
    UNICODE_STRING MCName = RTL_CONSTANT_STRING(L"\\Driver\\mouclass");
    PDRIVER_OBJECT targetDriverObject = NULL;
    PDEVICE_OBJECT currentDeviceObject = NULL, myDeviceObject = NULL;
    NTSTATUS status = ObReferenceObjectByName(&MCName, OBJ_CASE_INSENSITIVE, NULL, 0, *IoDriverObjectType, KernelMode, NULL, (PVOID*)&targetDriverObject);
    if (!NT_SUCCESS(status))
    {
        KdPrint(("ObReferenceObjectByName failed Error:%d", status));
        return status;
    }

    ObDereferenceObject(targetDriverObject);
    currentDeviceObject = targetDriverObject->DeviceObject;

    while (currentDeviceObject)
    {
        status = IoCreateDevice(DriverObject, sizeof(DEVICE_EXTENSION), NULL, FILE_DEVICE_MOUSE, 0, FALSE, &myDeviceObject);
        RtlZeroMemory(myDeviceObject->DeviceExtension, sizeof(DEVICE_EXTENSION));

        status = IoAttachDeviceToDeviceStackSafe(myDeviceObject, currentDeviceObject, &((PDEVICE_EXTENSION)myDeviceObject->DeviceExtension)->LowerDevice);
        if (!NT_SUCCESS(status))
        {
            KdPrint(("IoAttachDeviceToDeviceStackSafe failed"));
            IoDeleteDevice(myDeviceObject);     //此处应删除的是之前创建的所有设备,而不是只删除当前创建的设备
            return status;
        }

        myDeviceObject->Flags |= DO_BUFFERED_IO;
        myDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;

        currentDeviceObject = currentDeviceObject->NextDevice;
    }

    return STATUS_SUCCESS;
}

NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath)
{
    NTSTATUS status;
    DriverObject->DriverUnload = Unload;

    for (int i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++) {
        DriverObject->MajorFunction[i] = DispatchPass;
    }

    DriverObject->MajorFunction[IRP_MJ_READ] = DispatchRead;

    status = AttachMouseDevice(DriverObject);
    if (!NT_SUCCESS(status))
        DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, "attaching mouse device failed\r\n");
    else
        DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, "attaching mouse device succeeds\r\n");
    return status;
}

and also, when I unload the driver, blue screen appears. What did I do wrong ?

0

There are 0 best solutions below