(十八)、驱动程序调用驱动程序

一、通过文件句柄调用驱动

0

1、ZwCreateFile

调用者代码
#include <ntddk.h>

VOID Unload(PDRIVER_OBJECT driver)
{
    DbgPrint("Driver Unload\n");
}


void CallDriverTest()
{
    HANDLE hDevice;
    UNICODE_STRING DeviceName = RTL_CONSTANT_STRING(L"\\Device\\MyDDKName");
    NTSTATUS status;
    OBJECT_ATTRIBUTES oa;
    IO_STATUS_BLOCK IoStatus;
    InitializeObjectAttributes(&oa, &DeviceName, OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, NULL, NULL);

    status = ZwCreateFile(&hDevice, 
        GENERIC_ALL,
        &oa,
        &IoStatus,
        NULL,
        FILE_ATTRIBUTE_NORMAL,
        FILE_SHARE_READ | FILE_SHARE_WRITE,
        FILE_OPEN,
        FILE_SYNCHRONOUS_IO_NONALERT,
        NULL,
        0);

    if (!NT_SUCCESS(status))
    {
        DbgPrint("设备打开失败%x\n", status);

        return;
    }
    ZwReadFile(hDevice, NULL, NULL, NULL, &IoStatus, NULL, 0, NULL, NULL);
    
    DbgPrint("读结束\n");
    ZwClose(hDevice);
}
NTSTATUS DriverEntry(PDRIVER_OBJECT driver)
{
    DbgPrint("Driver Load\n");

    CallDriverTest();
    driver->DriverUnload = Unload;
    return STATUS_SUCCESS;
}
被调用者代码
#include <ntddk.h>

KDPC dpc;
KTIMER timer;
LARGE_INTEGER timeout;

VOID Unload(PDRIVER_OBJECT driver)
{
    //IoStopTimer(driver->DeviceObject);
    UNICODE_STRING SymbolicName = RTL_CONSTANT_STRING(L"\\??\\MyDDKLink");
    KeCancelTimer(&timer);
    DbgPrint("Driver Unload\n");
    IoDeleteSymbolicLink(&SymbolicName);
    IoDeleteDevice(driver->DeviceObject);

    DbgPrint("driver unload\n");
}
VOID IoTimer(
    PDEVICE_OBJECT    pDeviceObject,
    PVOID             pContext
)
{
    DbgPrint("iO定时器\n");
}
void DpcRoutine(
    struct _KDPC* Dpc,
    PVOID DeferredContext,
    PVOID SystemArgument1,
    PVOID SystemArgument2
)
{
    PIRP Irp = (PIRP)DeferredContext;
    Irp->IoStatus.Status = STATUS_CANCELLED;
    Irp->IoStatus.Information = 0;

    IoCompleteRequest(Irp, IO_NO_INCREMENT);
    DbgPrint("Dpc Timer\n");

}

NTSTATUS DispatchRoutine(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
    Irp->IoStatus.Status = STATUS_SUCCESS;
    Irp->IoStatus.Information = 0;

    IoCompleteRequest(Irp, IO_NO_INCREMENT);
    return STATUS_SUCCESS;
}

NTSTATUS DispatchRead(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
    IoMarkIrpPending(Irp);
    timeout = RtlConvertLongToLargeInteger(-10 * 2000 * 1000);// 2s 一次//
    KeInitializeTimer(&timer);

    KeInitializeDpc(&dpc, DpcRoutine, Irp);
    KeSetTimer(&timer, timeout, &dpc);
    return STATUS_PENDING;
}

NTSTATUS DriverEntry(PDRIVER_OBJECT driver)
{
    DbgPrint("Driver Load\n");
    UNICODE_STRING SymbolicLinkName = RTL_CONSTANT_STRING(L"\\??\\MyDDKLink");
    UNICODE_STRING DeviceName = RTL_CONSTANT_STRING(L"\\Device\\MyDDKName");
    PDEVICE_OBJECT DeviceObject;
    NTSTATUS status;
    status = IoCreateDevice(driver, 0, &DeviceName, FILE_DEVICE_UNKNOWN, 0, FALSE, &DeviceObject);
    if (!NT_SUCCESS(status))
    {
        DbgPrint("设备创建失败\n");
        return status;
    }

    status = IoCreateSymbolicLink(&SymbolicLinkName, &DeviceName);
    if (!NT_SUCCESS(status))
    {
        DbgPrint("符号链接创建失败\n");

        IoDeleteDevice(DeviceObject);
        return status;
    }



    //IoInitializeTimer(DeviceObject, IoTimer, NULL);
    //IoStartTimer(DeviceObject);//启动定时器,默认1s一次//

    //timeout = RtlConvertLongToLargeInteger(-10 * 2000 * 1000);// 2s 一次//
    //KeInitializeTimer(&timer);

    //KeInitializeDpc(&dpc, DpcRoutine, NULL);
    //KeSetTimer(&timer, timeout, &dpc);

    driver->DriverUnload = Unload;
    driver->MajorFunction[IRP_MJ_CREATE] = DispatchRoutine;
    driver->MajorFunction[IRP_MJ_CLOSE] = DispatchRoutine;
    driver->MajorFunction[IRP_MJ_READ] = DispatchRead;

    DeviceObject->Flags |= DO_BUFFERED_IO;
    DeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
    //KeSetTimer(&timer, timeout, &dpc);

    return STATUS_SUCCESS;
}
 
0
调用者对被调用者发出读请求,被调用者就会响应
 
 

二、异步

#include <ntddk.h>

VOID Unload(PDRIVER_OBJECT driver)
{
    DbgPrint("Driver Unload\n");
}


void CallDriverTest()
{
    HANDLE hDevice;
    UNICODE_STRING DeviceName = RTL_CONSTANT_STRING(L"\\Device\\MyDDKName");
    NTSTATUS status;
    OBJECT_ATTRIBUTES oa;
    IO_STATUS_BLOCK IoStatus;
    InitializeObjectAttributes(&oa, &DeviceName, OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, NULL, NULL);

    status = ZwCreateFile(&hDevice, 
        GENERIC_ALL,
        &oa,
        &IoStatus,
        NULL,
        FILE_ATTRIBUTE_NORMAL,
        FILE_SHARE_READ | FILE_SHARE_WRITE,
        FILE_OPEN,
        FILE_SYNCHRONOUS_IO_NONALERT,
        NULL,
        0);

    if (!NT_SUCCESS(status))
    {
        DbgPrint("设备打开失败%x\n", status);

        return;
    }
    ZwReadFile(hDevice, NULL, NULL, NULL, &IoStatus, NULL, 0, NULL, NULL);
    
    DbgPrint("读结束\n");
    ZwClose(hDevice);
}

VOID APCRoutine(PVOID ApcContext, PIO_STATUS_BLOCK IoStatusBlock, ULONG Reserved)
{
    PKEVENT  pEvent = (PKEVENT)ApcContext;
    KeSetEvent(pEvent, IO_NO_INCREMENT,FALSE);

}

void CallDriverTest2()
{   
    HANDLE hDevice;
    UNICODE_STRING DeviceName = RTL_CONSTANT_STRING(L"\\Device\\MyDDKName");
    NTSTATUS status;
    OBJECT_ATTRIBUTES oa;
    IO_STATUS_BLOCK IoStatus;
    KEVENT Event;
    LARGE_INTEGER offset = RtlConvertLongToLargeInteger(0);
    InitializeObjectAttributes(&oa, &DeviceName, OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, NULL, NULL);

    status = ZwCreateFile(&hDevice,
        GENERIC_ALL,
        &oa,
        &IoStatus,
        NULL,
        FILE_ATTRIBUTE_NORMAL,
        FILE_SHARE_READ | FILE_SHARE_WRITE,
        FILE_OPEN,
        0,
        NULL,
        0);

    if (!NT_SUCCESS(status))
    {
        DbgPrint("设备打开失败%x\n", status);

        return;
    }

    KeInitializeEvent(&Event, SynchronizationEvent, FALSE);
    status =  ZwReadFile(hDevice, NULL, APCRoutine, &Event, &IoStatus, NULL, 0, &offset, NULL);
    if (NT_SUCCESS(status))
    {
        if (status == STATUS_PENDING)
        {
            KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
        }
    }

    KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
    DbgPrint("读结束\n");
    ZwClose(hDevice);
}
NTSTATUS DriverEntry(PDRIVER_OBJECT driver)
{
    DbgPrint("Driver Load\n");

    //CallDriverTest();
    CallDriverTest2();
    driver->DriverUnload = Unload;
    return STATUS_SUCCESS;
}
 
0
我这个代码运行后调用者驱动会卡住..不理解
 
 

三、通过设备指针调用驱动程序

IoGetDeviceObjectPointer 

0
 

IoBuildSynchronousFsdRequest

0
0

IoGetNextIrpStackLocation

0

IoCallDriver宏

0
调用者代码
#include <ntddk.h>

VOID Unload(PDRIVER_OBJECT driver)
{
    DbgPrint("Driver Unload\n");
}


void CallDriverTest()
{
    HANDLE hDevice;
    UNICODE_STRING DeviceName = RTL_CONSTANT_STRING(L"\\Device\\MyDDKName");
    NTSTATUS status;
    OBJECT_ATTRIBUTES oa;
    IO_STATUS_BLOCK IoStatus;
    InitializeObjectAttributes(&oa, &DeviceName, OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, NULL, NULL);

    status = ZwCreateFile(&hDevice, 
        GENERIC_ALL,
        &oa,
        &IoStatus,
        NULL,
        FILE_ATTRIBUTE_NORMAL,
        FILE_SHARE_READ | FILE_SHARE_WRITE,
        FILE_OPEN,
        FILE_SYNCHRONOUS_IO_NONALERT,
        NULL,
        0);

    if (!NT_SUCCESS(status))
    {
        DbgPrint("设备打开失败%x\n", status);

        return;
    }
    ZwReadFile(hDevice, NULL, NULL, NULL, &IoStatus, NULL, 0, NULL, NULL);
    
    DbgPrint("读结束\n");
    ZwClose(hDevice);
}

VOID APCRoutine(PVOID ApcContext, PIO_STATUS_BLOCK IoStatusBlock, ULONG Reserved)
{
    PKEVENT  pEvent = (PKEVENT)ApcContext;
    KeSetEvent(pEvent, IO_NO_INCREMENT,FALSE);

}

void CallDriverTest2()
{   
    HANDLE hDevice;
    UNICODE_STRING DeviceName = RTL_CONSTANT_STRING(L"\\Device\\MyDDKName");
    NTSTATUS status;
    OBJECT_ATTRIBUTES oa;
    IO_STATUS_BLOCK IoStatus;
    KEVENT Event;
    LARGE_INTEGER offset = RtlConvertLongToLargeInteger(0);
    InitializeObjectAttributes(&oa, &DeviceName, OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, NULL, NULL);

    status = ZwCreateFile(&hDevice,
        GENERIC_ALL,
        &oa,
        &IoStatus,
        NULL,
        FILE_ATTRIBUTE_NORMAL,
        FILE_SHARE_READ | FILE_SHARE_WRITE,
        FILE_OPEN,
        0,
        NULL,
        0);

    if (!NT_SUCCESS(status))
    {
        DbgPrint("设备打开失败%x\n", status);

        return;
    }

    KeInitializeEvent(&Event, SynchronizationEvent, FALSE);
    status =  ZwReadFile(hDevice, NULL, APCRoutine, &Event, &IoStatus, NULL, 0, &offset, NULL);
    if (NT_SUCCESS(status))
    {
        if (status == STATUS_PENDING)
        {
            KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
        }
    }

    KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
    DbgPrint("读结束\n");
    ZwClose(hDevice);
}
void CallDriverTest3()
{
    HANDLE hDevice;
    UNICODE_STRING DeviceName = RTL_CONSTANT_STRING(L"\\Device\\MyDDKName");
    NTSTATUS status;
    OBJECT_ATTRIBUTES oa;
    IO_STATUS_BLOCK IoStatus;
    KEVENT Event;
    LARGE_INTEGER offset = RtlConvertLongToLargeInteger(0);
    InitializeObjectAttributes(&oa, &DeviceName, OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, NULL, NULL);

    PFILE_OBJECT FileObject;
    PDEVICE_OBJECT DeviceObject;
    status = IoGetDeviceObjectPointer(&DeviceName, FILE_ANY_ACCESS,&FileObject, &DeviceObject);
    if (!NT_SUCCESS(status))
    {
        DbgPrint("获取设备对象失败\n");
        return;
    }
    KeInitializeEvent(&Event, SynchronizationEvent, FALSE);
    PIRP Irp;
    PIO_STACK_LOCATION stack;
    Irp = IoBuildSynchronousFsdRequest(IRP_MJ_READ, DeviceObject, NULL, 0, &offset, &Event, &IoStatus);
    
    stack = IoGetNextIrpStackLocation(Irp);
    stack->FileObject = FileObject;

    status = IoCallDriver(DeviceObject, Irp);
    if (status == STATUS_PENDING)
    {
        KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
        DbgPrint("完成读操作\n");
    }

    ObDereferenceObject(FileObject);

}

NTSTATUS DriverEntry(PDRIVER_OBJECT driver)
{
    DbgPrint("Driver Load\n");

    //CallDriverTest();
    //CallDriverTest2();
    CallDriverTest3();
    driver->DriverUnload = Unload;
    return STATUS_SUCCESS;
}
 
0
 
 

四、异步

调用者
#include <ntddk.h>

VOID Unload(PDRIVER_OBJECT driver)
{
    DbgPrint("Driver Unload\n");
}


void CallDriverTest()
{
    HANDLE hDevice;
    UNICODE_STRING DeviceName = RTL_CONSTANT_STRING(L"\\Device\\MyDDKName");
    NTSTATUS status;
    OBJECT_ATTRIBUTES oa;
    IO_STATUS_BLOCK IoStatus;
    InitializeObjectAttributes(&oa, &DeviceName, OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, NULL, NULL);

    status = ZwCreateFile(&hDevice, 
        GENERIC_ALL,
        &oa,
        &IoStatus,
        NULL,
        FILE_ATTRIBUTE_NORMAL,
        FILE_SHARE_READ | FILE_SHARE_WRITE,
        FILE_OPEN,
        FILE_SYNCHRONOUS_IO_NONALERT,
        NULL,
        0);

    if (!NT_SUCCESS(status))
    {
        DbgPrint("设备打开失败%x\n", status);

        return;
    }
    ZwReadFile(hDevice, NULL, NULL, NULL, &IoStatus, NULL, 0, NULL, NULL);
    
    DbgPrint("读结束\n");
    ZwClose(hDevice);
}

VOID APCRoutine(PVOID ApcContext, PIO_STATUS_BLOCK IoStatusBlock, ULONG Reserved)
{
    PKEVENT  pEvent = (PKEVENT)ApcContext;
    KeSetEvent(pEvent, IO_NO_INCREMENT,FALSE);

}

void CallDriverTest2()
{   
    HANDLE hDevice;
    UNICODE_STRING DeviceName = RTL_CONSTANT_STRING(L"\\Device\\MyDDKName");
    NTSTATUS status;
    OBJECT_ATTRIBUTES oa;
    IO_STATUS_BLOCK IoStatus;
    KEVENT Event;
    LARGE_INTEGER offset = RtlConvertLongToLargeInteger(0);
    InitializeObjectAttributes(&oa, &DeviceName, OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, NULL, NULL);

    status = ZwCreateFile(&hDevice,
        GENERIC_ALL,
        &oa,
        &IoStatus,
        NULL,
        FILE_ATTRIBUTE_NORMAL,
        FILE_SHARE_READ | FILE_SHARE_WRITE,
        FILE_OPEN,
        0,
        NULL,
        0);

    if (!NT_SUCCESS(status))
    {
        DbgPrint("设备打开失败%x\n", status);

        return;
    }

    KeInitializeEvent(&Event, SynchronizationEvent, FALSE);
    status =  ZwReadFile(hDevice, NULL, APCRoutine, &Event, &IoStatus, NULL, 0, &offset, NULL);
    if (NT_SUCCESS(status))
    {
        if (status == STATUS_PENDING)
        {
            KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
        }
    }

    KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
    DbgPrint("读结束\n");
    ZwClose(hDevice);
}
void CallDriverTest3()
{
    HANDLE hDevice;
    UNICODE_STRING DeviceName = RTL_CONSTANT_STRING(L"\\Device\\MyDDKName");
    NTSTATUS status;
    OBJECT_ATTRIBUTES oa;
    IO_STATUS_BLOCK IoStatus;
    KEVENT Event;
    LARGE_INTEGER offset = RtlConvertLongToLargeInteger(0);
    InitializeObjectAttributes(&oa, &DeviceName, OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, NULL, NULL);

    PFILE_OBJECT FileObject;
    PDEVICE_OBJECT DeviceObject;
    status = IoGetDeviceObjectPointer(&DeviceName, FILE_ANY_ACCESS,&FileObject, &DeviceObject);
    if (!NT_SUCCESS(status))
    {
        DbgPrint("获取设备对象失败\n");
        return;
    }
    KeInitializeEvent(&Event, SynchronizationEvent, FALSE);
    PIRP Irp;
    PIO_STACK_LOCATION stack;
    Irp = IoBuildSynchronousFsdRequest(IRP_MJ_READ, DeviceObject, NULL, 0, &offset, &Event, &IoStatus);
    
    stack = IoGetNextIrpStackLocation(Irp);
    stack->FileObject = FileObject;

    status = IoCallDriver(DeviceObject, Irp);
    if (status == STATUS_PENDING)
    {
        KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
        DbgPrint("完成读操作\n");
    }

    ObDereferenceObject(FileObject);

}


void CallDriverTest4()
{
    HANDLE hDevice;
    UNICODE_STRING DeviceName = RTL_CONSTANT_STRING(L"\\Device\\MyDDKName");
    NTSTATUS status;
    OBJECT_ATTRIBUTES oa;
    IO_STATUS_BLOCK IoStatus;
    KEVENT Event;
    LARGE_INTEGER offset = RtlConvertLongToLargeInteger(0);
    InitializeObjectAttributes(&oa, &DeviceName, OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, NULL, NULL);

    PFILE_OBJECT FileObject;
    PDEVICE_OBJECT DeviceObject;
    status = IoGetDeviceObjectPointer(&DeviceName, FILE_ANY_ACCESS, &FileObject, &DeviceObject);
    if (!NT_SUCCESS(status))
    {
        DbgPrint("获取设备对象失败\n");
        return;
    }
    KeInitializeEvent(&Event, SynchronizationEvent, FALSE);
    PIRP Irp;
    PIO_STACK_LOCATION stack;
//    Irp = IoBuildSynchronousFsdRequest(IRP_MJ_READ, DeviceObject, NULL, 0, &offset, &Event, &IoStatus);
    
    Irp = IoBuildAsynchronousFsdRequest(IRP_MJ_READ, DeviceObject, NULL, 0, &offset, &IoStatus);
    Irp->UserEvent = &Event;
    stack = IoGetNextIrpStackLocation(Irp);
    stack->FileObject = FileObject;

    status = IoCallDriver(DeviceObject, Irp);
    if (status == STATUS_PENDING)
    {
        KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
        DbgPrint("完成读操作\n");
    }

    ObDereferenceObject(FileObject);

}
NTSTATUS DriverEntry(PDRIVER_OBJECT driver)
{
    DbgPrint("Driver Load\n");

    //CallDriverTest();
    //CallDriverTest2();
    //CallDriverTest3();
    CallDriverTest4();
    driver->DriverUnload = Unload;
    return STATUS_SUCCESS;
}
 
0
 
 

五、万能IRP函数

IoAllocateIrp
 
0
 
0
 
#include <ntddk.h>

VOID Unload(PDRIVER_OBJECT driver)
{
    DbgPrint("Driver Unload\n");
}


void CallDriverTest()
{
    HANDLE hDevice;
    UNICODE_STRING DeviceName = RTL_CONSTANT_STRING(L"\\Device\\MyDDKName");
    NTSTATUS status;
    OBJECT_ATTRIBUTES oa;
    IO_STATUS_BLOCK IoStatus;
    InitializeObjectAttributes(&oa, &DeviceName, OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, NULL, NULL);

    status = ZwCreateFile(&hDevice, 
        GENERIC_ALL,
        &oa,
        &IoStatus,
        NULL,
        FILE_ATTRIBUTE_NORMAL,
        FILE_SHARE_READ | FILE_SHARE_WRITE,
        FILE_OPEN,
        FILE_SYNCHRONOUS_IO_NONALERT,
        NULL,
        0);

    if (!NT_SUCCESS(status))
    {
        DbgPrint("设备打开失败%x\n", status);

        return;
    }
    ZwReadFile(hDevice, NULL, NULL, NULL, &IoStatus, NULL, 0, NULL, NULL);
    
    DbgPrint("读结束\n");
    ZwClose(hDevice);
}

VOID APCRoutine(PVOID ApcContext, PIO_STATUS_BLOCK IoStatusBlock, ULONG Reserved)
{
    PKEVENT  pEvent = (PKEVENT)ApcContext;
    KeSetEvent(pEvent, IO_NO_INCREMENT,FALSE);

}

void CallDriverTest2()
{   
    HANDLE hDevice;
    UNICODE_STRING DeviceName = RTL_CONSTANT_STRING(L"\\Device\\MyDDKName");
    NTSTATUS status;
    OBJECT_ATTRIBUTES oa;
    IO_STATUS_BLOCK IoStatus;
    KEVENT Event;
    LARGE_INTEGER offset = RtlConvertLongToLargeInteger(0);
    InitializeObjectAttributes(&oa, &DeviceName, OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, NULL, NULL);

    status = ZwCreateFile(&hDevice,
        GENERIC_ALL,
        &oa,
        &IoStatus,
        NULL,
        FILE_ATTRIBUTE_NORMAL,
        FILE_SHARE_READ | FILE_SHARE_WRITE,
        FILE_OPEN,
        0,
        NULL,
        0);

    if (!NT_SUCCESS(status))
    {
        DbgPrint("设备打开失败%x\n", status);

        return;
    }

    KeInitializeEvent(&Event, SynchronizationEvent, FALSE);
    status =  ZwReadFile(hDevice, NULL, APCRoutine, &Event, &IoStatus, NULL, 0, &offset, NULL);
    if (NT_SUCCESS(status))
    {
        if (status == STATUS_PENDING)
        {
            KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
        }
    }

    KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
    DbgPrint("读结束\n");
    ZwClose(hDevice);
}
void CallDriverTest3()
{
    HANDLE hDevice;
    UNICODE_STRING DeviceName = RTL_CONSTANT_STRING(L"\\Device\\MyDDKName");
    NTSTATUS status;
    OBJECT_ATTRIBUTES oa;
    IO_STATUS_BLOCK IoStatus;
    KEVENT Event;
    LARGE_INTEGER offset = RtlConvertLongToLargeInteger(0);
    InitializeObjectAttributes(&oa, &DeviceName, OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, NULL, NULL);

    PFILE_OBJECT FileObject;
    PDEVICE_OBJECT DeviceObject;
    status = IoGetDeviceObjectPointer(&DeviceName, FILE_ANY_ACCESS,&FileObject, &DeviceObject);
    if (!NT_SUCCESS(status))
    {
        DbgPrint("获取设备对象失败\n");
        return;
    }
    KeInitializeEvent(&Event, SynchronizationEvent, FALSE);
    PIRP Irp;
    PIO_STACK_LOCATION stack;
    Irp = IoBuildSynchronousFsdRequest(IRP_MJ_READ, DeviceObject, NULL, 0, &offset, &Event, &IoStatus);
    
    stack = IoGetNextIrpStackLocation(Irp);
    stack->FileObject = FileObject;

    status = IoCallDriver(DeviceObject, Irp);
    if (status == STATUS_PENDING)
    {
        KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
        DbgPrint("完成读操作\n");
    }

    ObDereferenceObject(FileObject);

}


void CallDriverTest4()
{
    HANDLE hDevice;
    UNICODE_STRING DeviceName = RTL_CONSTANT_STRING(L"\\Device\\MyDDKName");
    NTSTATUS status;
    OBJECT_ATTRIBUTES oa;
    IO_STATUS_BLOCK IoStatus;
    KEVENT Event;
    LARGE_INTEGER offset = RtlConvertLongToLargeInteger(0);
    InitializeObjectAttributes(&oa, &DeviceName, OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, NULL, NULL);

    PFILE_OBJECT FileObject;
    PDEVICE_OBJECT DeviceObject;
    status = IoGetDeviceObjectPointer(&DeviceName, FILE_ANY_ACCESS, &FileObject, &DeviceObject);
    if (!NT_SUCCESS(status))
    {
        DbgPrint("获取设备对象失败\n");
        return;
    }
    KeInitializeEvent(&Event, SynchronizationEvent, FALSE);
    PIRP Irp;
    PIO_STACK_LOCATION stack;
//    Irp = IoBuildSynchronousFsdRequest(IRP_MJ_READ, DeviceObject, NULL, 0, &offset, &Event, &IoStatus);
    
    Irp = IoBuildAsynchronousFsdRequest(IRP_MJ_READ, DeviceObject, NULL, 0, &offset, &IoStatus);
    Irp->UserEvent = &Event;
    stack = IoGetNextIrpStackLocation(Irp);
    stack->FileObject = FileObject;

    status = IoCallDriver(DeviceObject, Irp);
    if (status == STATUS_PENDING)
    {
        KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
        DbgPrint("完成读操作\n");
    }

    ObDereferenceObject(FileObject);

}

VOID CallDriverTest5()
{
    HANDLE hDevice;
    UNICODE_STRING DeviceName = RTL_CONSTANT_STRING(L"\\Device\\MyDDKName");
    NTSTATUS status;
    OBJECT_ATTRIBUTES oa;
    IO_STATUS_BLOCK IoStatus;
    KEVENT Event;
    LARGE_INTEGER offset = RtlConvertLongToLargeInteger(0);
    InitializeObjectAttributes(&oa, &DeviceName, OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, NULL, NULL);

    PFILE_OBJECT FileObject;
    PDEVICE_OBJECT DeviceObject;
    status = IoGetDeviceObjectPointer(&DeviceName, FILE_ANY_ACCESS, &FileObject, &DeviceObject);
    if (!NT_SUCCESS(status))
    {
        DbgPrint("获取设备对象失败\n");
        return;
    }
    KeInitializeEvent(&Event, SynchronizationEvent, FALSE);
    PIRP Irp;
    PIO_STACK_LOCATION stack;

    Irp = IoAllocateIrp(DeviceObject->StackSize, FALSE);
    if (Irp != NULL)
    {
        Irp->UserIosb = &IoStatus;
        Irp->UserEvent = &Event;
        Irp->AssociatedIrp.SystemBuffer = NULL;
        Irp->Tail.Overlay.Thread = PsGetCurrentThread();
        stack = IoGetNextIrpStackLocation(Irp);
        stack->FileObject = FileObject;
        stack->DeviceObject = DeviceObject;
        stack->MajorFunction = IRP_MJ_READ;
        stack->MinorFunction = IRP_MN_NORMAL;
        status = IoCallDriver(DeviceObject, Irp);
        if (status == STATUS_PENDING)
        {
            KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
            DbgPrint("完成读操作\n");
        }


    }


    //    Irp = IoBuildSynchronousFsdRequest(IRP_MJ_READ, DeviceObject, NULL, 0, &offset, &Event, &IoStatus);

    //Irp = IoBuildAsynchronousFsdRequest(IRP_MJ_READ, DeviceObject, NULL, 0, &offset, &IoStatus);
    //Irp->UserEvent = &Event;
    //stack = IoGetNextIrpStackLocation(Irp);
    //stack->FileObject = FileObject;



    ObDereferenceObject(FileObject);
}
NTSTATUS DriverEntry(PDRIVER_OBJECT driver)
{
    DbgPrint("Driver Load\n");

    //CallDriverTest();
    //CallDriverTest2();
    //CallDriverTest3();
    //CallDriverTest4();
    CallDriverTest5();
    driver->DriverUnload = Unload;
    return STATUS_SUCCESS;
}
 
 
0
 
 

六、对象管理器函数

NTSTATUS
ObReferenceObjectByName(
      __in PUNICODE_STRING ObjectName,
      __in ULONG Attributes,
      __in_opt PACCESS_STATE AccessState,
      __in_opt ACCESS_MASK DesiredAccess,
      __in POBJECT_TYPE ObjectType,
      __in KPROCESSOR_MODE AccessMode,
      __inout_opt PVOID ParseContext,
      __out PVOID *Object
  );
这里有很大的问题
#include <ntddk.h>

VOID Unload(PDRIVER_OBJECT driver)
{
    DbgPrint("Driver Unload\n");
}

NTKERNELAPI
NTSTATUS
ObReferenceObjectByName(
    __in PUNICODE_STRING ObjectName,
    __in ULONG Attributes,
    __in_opt PACCESS_STATE AccessState,
    __in_opt ACCESS_MASK DesiredAccess,
    __in POBJECT_TYPE ObjectType,
    __in KPROCESSOR_MODE AccessMode,
    __inout_opt PVOID ParseContext,
    __out PVOID* Object
);
extern POBJECT_TYPE IoDeviceObjectType;
void CallDriverTest()
{
    HANDLE hDevice;
    UNICODE_STRING DeviceName = RTL_CONSTANT_STRING(L"\\Device\\MyDDKName");
    NTSTATUS status;
    OBJECT_ATTRIBUTES oa;
    IO_STATUS_BLOCK IoStatus;
    InitializeObjectAttributes(&oa, &DeviceName, OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, NULL, NULL);

    status = ZwCreateFile(&hDevice, 
        GENERIC_ALL,
        &oa,
        &IoStatus,
        NULL,
        FILE_ATTRIBUTE_NORMAL,
        FILE_SHARE_READ | FILE_SHARE_WRITE,
        FILE_OPEN,
        FILE_SYNCHRONOUS_IO_NONALERT,
        NULL,
        0);

    if (!NT_SUCCESS(status))
    {
        DbgPrint("设备打开失败%x\n", status);

        return;
    }
    ZwReadFile(hDevice, NULL, NULL, NULL, &IoStatus, NULL, 0, NULL, NULL);
    
    DbgPrint("读结束\n");
    ZwClose(hDevice);
}

VOID APCRoutine(PVOID ApcContext, PIO_STATUS_BLOCK IoStatusBlock, ULONG Reserved)
{
    PKEVENT  pEvent = (PKEVENT)ApcContext;
    KeSetEvent(pEvent, IO_NO_INCREMENT,FALSE);

}

void CallDriverTest2()
{   
    HANDLE hDevice;
    UNICODE_STRING DeviceName = RTL_CONSTANT_STRING(L"\\Device\\MyDDKName");
    NTSTATUS status;
    OBJECT_ATTRIBUTES oa;
    IO_STATUS_BLOCK IoStatus;
    KEVENT Event;
    LARGE_INTEGER offset = RtlConvertLongToLargeInteger(0);
    InitializeObjectAttributes(&oa, &DeviceName, OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, NULL, NULL);

    status = ZwCreateFile(&hDevice,
        GENERIC_ALL,
        &oa,
        &IoStatus,
        NULL,
        FILE_ATTRIBUTE_NORMAL,
        FILE_SHARE_READ | FILE_SHARE_WRITE,
        FILE_OPEN,
        0,
        NULL,
        0);

    if (!NT_SUCCESS(status))
    {
        DbgPrint("设备打开失败%x\n", status);

        return;
    }

    KeInitializeEvent(&Event, SynchronizationEvent, FALSE);
    status =  ZwReadFile(hDevice, NULL, APCRoutine, &Event, &IoStatus, NULL, 0, &offset, NULL);
    if (NT_SUCCESS(status))
    {
        if (status == STATUS_PENDING)
        {
            KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
        }
    }

    KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
    DbgPrint("读结束\n");
    ZwClose(hDevice);
}
void CallDriverTest3()
{
    HANDLE hDevice;
    UNICODE_STRING DeviceName = RTL_CONSTANT_STRING(L"\\Device\\MyDDKName");
    NTSTATUS status;
    OBJECT_ATTRIBUTES oa;
    IO_STATUS_BLOCK IoStatus;
    KEVENT Event;
    LARGE_INTEGER offset = RtlConvertLongToLargeInteger(0);
    InitializeObjectAttributes(&oa, &DeviceName, OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, NULL, NULL);

    PFILE_OBJECT FileObject;
    PDEVICE_OBJECT DeviceObject;
    status = IoGetDeviceObjectPointer(&DeviceName, FILE_ANY_ACCESS,&FileObject, &DeviceObject);
    if (!NT_SUCCESS(status))
    {
        DbgPrint("获取设备对象失败\n");
        return;
    }
    KeInitializeEvent(&Event, SynchronizationEvent, FALSE);
    PIRP Irp;
    PIO_STACK_LOCATION stack;
    Irp = IoBuildSynchronousFsdRequest(IRP_MJ_READ, DeviceObject, NULL, 0, &offset, &Event, &IoStatus);
    
    stack = IoGetNextIrpStackLocation(Irp);
    stack->FileObject = FileObject;

    status = IoCallDriver(DeviceObject, Irp);
    if (status == STATUS_PENDING)
    {
        KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
        DbgPrint("完成读操作\n");
    }

    ObDereferenceObject(FileObject);

}


void CallDriverTest4()
{
    HANDLE hDevice;
    UNICODE_STRING DeviceName = RTL_CONSTANT_STRING(L"\\Device\\MyDDKName");
    NTSTATUS status;
    OBJECT_ATTRIBUTES oa;
    IO_STATUS_BLOCK IoStatus;
    KEVENT Event;
    LARGE_INTEGER offset = RtlConvertLongToLargeInteger(0);
    InitializeObjectAttributes(&oa, &DeviceName, OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, NULL, NULL);

    PFILE_OBJECT FileObject;
    PDEVICE_OBJECT DeviceObject;
    status = IoGetDeviceObjectPointer(&DeviceName, FILE_ANY_ACCESS, &FileObject, &DeviceObject);
    if (!NT_SUCCESS(status))
    {
        DbgPrint("获取设备对象失败\n");
        return;
    }
    KeInitializeEvent(&Event, SynchronizationEvent, FALSE);
    PIRP Irp;
    PIO_STACK_LOCATION stack;
//    Irp = IoBuildSynchronousFsdRequest(IRP_MJ_READ, DeviceObject, NULL, 0, &offset, &Event, &IoStatus);
    
    Irp = IoBuildAsynchronousFsdRequest(IRP_MJ_READ, DeviceObject, NULL, 0, &offset, &IoStatus);
    Irp->UserEvent = &Event;
    stack = IoGetNextIrpStackLocation(Irp);
    stack->FileObject = FileObject;

    status = IoCallDriver(DeviceObject, Irp);
    if (status == STATUS_PENDING)
    {
        KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
        DbgPrint("完成读操作\n");
    }

    ObDereferenceObject(FileObject);

}

VOID CallDriverTest5()
{
    HANDLE hDevice;
    UNICODE_STRING DeviceName = RTL_CONSTANT_STRING(L"\\Device\\MyDDKName");
    NTSTATUS status;
    OBJECT_ATTRIBUTES oa;
    IO_STATUS_BLOCK IoStatus;
    KEVENT Event;
    LARGE_INTEGER offset = RtlConvertLongToLargeInteger(0);
    InitializeObjectAttributes(&oa, &DeviceName, OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, NULL, NULL);

    PFILE_OBJECT FileObject;
    PDEVICE_OBJECT DeviceObject;
    status = IoGetDeviceObjectPointer(&DeviceName, FILE_ANY_ACCESS, &FileObject, &DeviceObject);
    if (!NT_SUCCESS(status))
    {
        DbgPrint("获取设备对象失败\n");
        return;
    }
    KeInitializeEvent(&Event, SynchronizationEvent, FALSE);
    PIRP Irp;
    PIO_STACK_LOCATION stack;

    Irp = IoAllocateIrp(DeviceObject->StackSize, FALSE);
    if (Irp != NULL)
    {
        Irp->UserIosb = &IoStatus;
        Irp->UserEvent = &Event;
        Irp->AssociatedIrp.SystemBuffer = NULL;
        Irp->Tail.Overlay.Thread = PsGetCurrentThread();
        stack = IoGetNextIrpStackLocation(Irp);
        stack->FileObject = FileObject;
        stack->DeviceObject = DeviceObject;
        stack->MajorFunction = IRP_MJ_READ;
        stack->MinorFunction = IRP_MN_NORMAL;
        status = IoCallDriver(DeviceObject, Irp);
        if (status == STATUS_PENDING)
        {
            KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
            DbgPrint("完成读操作\n");
        }


    }


    //    Irp = IoBuildSynchronousFsdRequest(IRP_MJ_READ, DeviceObject, NULL, 0, &offset, &Event, &IoStatus);

    //Irp = IoBuildAsynchronousFsdRequest(IRP_MJ_READ, DeviceObject, NULL, 0, &offset, &IoStatus);
    //Irp->UserEvent = &Event;
    //stack = IoGetNextIrpStackLocation(Irp);
    //stack->FileObject = FileObject;



    ObDereferenceObject(FileObject);
}


void MyGetDeviceObject()
{
    NTSTATUS status;
    UNICODE_STRING DeviceName = RTL_CONSTANT_STRING(L"\\??\\MyDDKLink");
    PDEVICE_OBJECT DeviceObject;
    //OBJECT_ATTRIBUTES oa;
    status = ObReferenceObjectByName(&DeviceName,OBJ_CASE_INSENSITIVE, NULL, FILE_ANY_ACCESS,IoDeviceObjectType, KernelMode, NULL, (PVOID * )&DeviceObject);
    if (NT_SUCCESS(status))
    {
        DbgPrint("设备对象获取成功  %p\n",DeviceObject);
        ObReferenceObject(DeviceObject);
    }
    else
    {
        DbgPrint("设备对象获取失败  %p\n", status);
    }


}
NTSTATUS DriverEntry(PDRIVER_OBJECT driver)
{
    DbgPrint("Driver Load\n");

    //CallDriverTest();
    //CallDriverTest2();
    //CallDriverTest3();
    //CallDriverTest4();
    //CallDriverTest5();
    MyGetDeviceObject();
    driver->DriverUnload = Unload;
    return STATUS_SUCCESS;
}
 
 
 
0
 
他一直在报c0000024错误,在网上的说法也各不相同,有的说必须用ZwOpenFile调用,也有的人说是其他原因,捣鼓了好久,把自己整傻了...
posted @ 2022-04-12 16:55  TLSN  阅读(298)  评论(1编辑  收藏  举报