Windows驱动 - 桌面程序与驱动交互

0x00 代码

桌面程序

#include <windows.h>

#include <stdio.h>

#define IOCTL_Device_Read_Write CTL_CODE(FILE_DEVICE_UNKNOWN, 0x999, METHOD_BUFFERED , FILE_READ_DATA | FILE_WRITE_DATA)

int main(int argc, char* grav[])

{

    char readBuffer[300] = { 0 };

    const char writeBuffer[] = "Console  WriteFile";

    size_t writeBufferLength = strlen(writeBuffer) + 1;

 

 

    char deviceIoControlWrite[] = "Console  DeviceIoControl";

    size_t deviceIoControlWriterLength = strlen(deviceIoControlWrite) + 1;

    char deviceIoControlRead[300] = { 0 };

 

 

    DWORD BytesReturned = 0;

    DWORD readNumber = 0;

    DWORD writerNumber = 0;

 

 

    printf("CreateFile\n");

    system("pause");

    HANDLE handle = CreateFile(L"\\\\.\\DataInteraction",GENERIC_READ| GENERIC_WRITE,0,NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,NULL);

    if(handle == INVALID_HANDLE_VALUE)

    {

        printf("INVALID_HANDLE_VALUE\n");

        return 0;

    }

 

 

    printf("ReadFile\n");

    system("pause");

    if (ReadFile(handle, readBuffer, 100, &readNumber, NULL))

    {

        printf("ReadFile::  %s %d\n", readBuffer, readNumber);

    }

    else

    {

        printf("ReadFile failed\n");

 

    }

 

    printf("WriteFile\n");

    system("pause");

    if (WriteFile(handle, writeBuffer, writeBufferLength, &writerNumber, NULL))

    {

        printf("WriteFile success\n");

    }

    else

    {

        printf("WriteFile failed\n");

    }

 

    printf("DeviceIoControl\n");

    system("pause");

    if (DeviceIoControl(handle, IOCTL_Device_Read_Write, deviceIoControlWrite, deviceIoControlWriterLength, deviceIoControlRead, 300, &BytesReturned, NULL))

    {

 

       printf("DeviceIoControl  Read:  %s BytesReturned:  %d\n", deviceIoControlRead, BytesReturned);

 

    }else

    {

        printf("DeviceIoControl failed\n");

    }

 

    CloseHandle(handle);

 

    system("pause");

    return 0;

 

}

 

驱动

#include <wdm.h>

 

#define IOCTL_Device_Read_Write CTL_CODE(FILE_DEVICE_UNKNOWN, 0x999, METHOD_BUFFERED , FILE_READ_DATA | FILE_WRITE_DATA)

 

 

 

//驱动卸载

VOID DriverUnload(PDRIVER_OBJECT DriverObjec)

{

 

    DbgPrint("DriverUnload");

    if (DriverObjec->DeviceObject)

    {

        DbgPrint("DriverUnload->IoDeleteDevice");

        IoDeleteDevice(DriverObjec->DeviceObject);

        UNICODE_STRING SysmbolicLinkNmae = { 0 };

        RtlInitUnicodeString(&SysmbolicLinkNmae, L"\\??\\DataInteraction");

        IoDeleteSymbolicLink(&SysmbolicLinkNmae);

 

    }

    DbgPrint("DriverUnload success");

}

 

 

NTSTATUS MyDispatchCreate(PDEVICE_OBJECT DeviceObjct,PIRP Irp)

{

    NTSTATUS status = STATUS_SUCCESS;

 

    DbgPrint("MyDispatchCreate");

 

    Irp->IoStatus.Information = 0; //返回给R3的附加信息

    Irp->IoStatus.Status = status; //irp完成状态

    IofCompleteRequest(Irp,IO_NO_INCREMENT); //当驱动程序完成给定IRP的所有处理时调用,代表IRP处理完成

 

 

    return status;

}

 

NTSTATUS MyDispatchCleanUp(PDEVICE_OBJECT DeviceObjct,PIRP Irp)

{

    NTSTATUS status = STATUS_SUCCESS;

 

    DbgPrint("MyDispatchCleanUp");

 

 

    Irp->IoStatus.Information = 0; //返回给R3的附加信息

    Irp->IoStatus.Status = status; //irp完成状态

    IofCompleteRequest(Irp,IO_NO_INCREMENT); //当驱动程序完成给定IRP的所有处理时调用,代表IRP处理完成

 

 

    return status;

}

 

 

 

NTSTATUS MyDispatchClose(PDEVICE_OBJECT DeviceObjct, PIRP Irp)

{

    NTSTATUS status = STATUS_SUCCESS;

 

    DbgPrint("MyDispatchClose");

 

    Irp->IoStatus.Information = 0; //返回给R3的附加信息

    Irp->IoStatus.Status = status; //irp完成状态

    IofCompleteRequest(Irp, IO_NO_INCREMENT); //当驱动程序完成给定IRP的所有处理时调用,代表IRP处理完成

 

 

    return status;

}

 

 

NTSTATUS MyDispatchRead(PDEVICE_OBJECT DeviceObjct, PIRP Irp)

{

    NTSTATUS status = STATUS_SUCCESS;

 

    const char str[] = "Device MyDispatchRead";

    size_t strLen = strlen(str) + 1;

 

 

    DbgPrint("MyDispatchRead");

 

    PIO_STACK_LOCATION  IrpSp= IoGetCurrentIrpStackLocation(Irp); //获取堆信息

 

    //BOOL ReadFile(HANDLE hFile,LPVOID lpBuffer,DWORD nNumberOfBytesToRead,LPDWORD lpNumberOfBytesRead,LPOVERLAPPED lpOverlapped);

    //IrpSp->Parameters.Read.Length == nNumberOfBytesToRead

    if (IrpSp->Parameters.Read.Length < strLen)

    {

        Irp->IoStatus.Information = 0; //返回给R3的附加信息 -> lpNumberOfBytesRead

 

        DbgPrint("MyDispatchRead failed");

    }

    else

    {

       

        //IrIrp->AssociatedIrp.SystemBuffer == lpBuffer

        RtlCopyMemory(Irp->AssociatedIrp.SystemBuffer, str, strLen);

 

        //返回给R3的附加信息 -> lpNumberOfBytesRead

        //修改此值会影响实际传输的数据. 修改为2,则实际只拷贝2字节

        //Irp->IoStatus.Information = strLen; 

        Irp->IoStatus.Information = 10;    //返回给R3的附加信息

 

        DbgPrint("MyDispatchRead success");

    }

 

 

    Irp->IoStatus.Status = status; //irp完成状态

    IofCompleteRequest(Irp, IO_NO_INCREMENT); //当驱动程序完成给定IRP的所有处理时调用,代表IRP处理完成

   

    return status;

}

 

 

NTSTATUS MyDispatchWrite(PDEVICE_OBJECT DeviceObjct, PIRP Irp)

{

    NTSTATUS status = STATUS_SUCCESS;

 

    DbgPrint("MyDispatchWrite");

   

    //BOOL WriteFile(HANDLE hFile,LPCVOID lpBuffer,DWORD nNumberOfBytesToWrite,LPDWORD lpNumberOfBytesWritten,LPOVERLAPPED lpOverlapped);

    char str[256] = {0};

   

 

    PIO_STACK_LOCATION  IrpSp = IoGetCurrentIrpStackLocation(Irp); //获取堆信息

 

    //IrpSp->Parameters.Read.Length == nNumberOfBytesToRead

    if (IrpSp->Parameters.Write.Length > 256)

    {

        Irp->IoStatus.Information = 0; //返回给R3的附加信息 -> lpNumberOfBytesRead

        DbgPrint("MyDispatchWrite failed");

    }

    else

    {

 

        //IrIrp->AssociatedIrp.SystemBuffer == lpBuffer

        RtlCopyMemory(str, Irp->AssociatedIrp.SystemBuffer, IrpSp->Parameters.Write.Length);

 

        DbgPrint("Device Write: %s",str);

 

        Irp->IoStatus.Information = IrpSp->Parameters.Write.Length;   //返回给R3的附加信息 -> lpNumberOfBytesRead

        DbgPrint("MyDispatchWrite success");

    }

 

 

    Irp->IoStatus.Status = status; //irp完成状态

    IofCompleteRequest(Irp, IO_NO_INCREMENT); //当驱动程序完成给定IRP的所有处理时调用,代表IRP处理完成

 

    return status;

 

}

 

 

NTSTATUS MyDispatchControl(PDEVICE_OBJECT DeviceObjct, PIRP Irp)

{

    NTSTATUS status = STATUS_SUCCESS;

 

    const char str[] = "Device MyDispatchControl";

    size_t strLen = strlen(str) + 1;

 

    PIO_STACK_LOCATION  IrpSp = IoGetCurrentIrpStackLocation(Irp); //获取堆信息

 

    DbgPrint("MyDispatchControl");

    DbgPrint("MyDispatchControl->IOCTL_Device_Read_Write:%d", IOCTL_Device_Read_Write);

    DbgPrint("MyDispatchControl->IrpSp->Parameters.DeviceIoControl.IoControlCode:%d", IrpSp->Parameters.DeviceIoControl.IoControlCode);

 

    //IrpSp->Parameters.DeviceIoControl.IoControlCode -> 用户层传入的指定代码

    switch (IrpSp->Parameters.DeviceIoControl.IoControlCode)

    {

    case IOCTL_Device_Read_Write:

 

        DbgPrint("MyDispatchControl->switch->IOCTL_Device_Read_Write");

 

        DbgPrint("Device MyDispatchControl->Write:  %s InputLenght:%d OutputLenght:%d",

            (char*)Irp->AssociatedIrp.SystemBuffer,

            IrpSp->Parameters.DeviceIoControl.InputBufferLength,

            IrpSp->Parameters.DeviceIoControl.OutputBufferLength);

 

        if (IrpSp->Parameters.DeviceIoControl.OutputBufferLength < strLen)

        {

           

            Irp->IoStatus.Information = 0; //返回给R3的附加信息

            DbgPrint("Device MyDispatchControl->Read failed");

        }

        else

        {

            RtlCopyMemory(Irp->AssociatedIrp.SystemBuffer, str, strLen);

            //Irp->IoStatus.Information = strLen;  //返回给R3的附加信息

            Irp->IoStatus.Information = 10;    //返回给R3的附加信息

            DbgPrint("Device MyDispatchControl->Read success");

           

        }

       

        break;

 

    default:

 

        DbgPrint("MyDispatchControl::switch->default");

 

        break;

    }

 

   

    Irp->IoStatus.Status = status; //irp完成状态

    IofCompleteRequest(Irp, IO_NO_INCREMENT); //当驱动程序完成给定IRP的所有处理时调用,代表IRP处理完成

 

    return status;

}

 

 

 

//驱动入口

NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject,PUNICODE_STRING RegistryPath)

{

    NTSTATUS status = STATUS_SUCCESS;

 

    DbgPrint("DriverEntry");

 

    //驱动卸载

    DriverObject->DriverUnload = DriverUnload;

 

    //创建设备

    PDEVICE_OBJECT DeviceObjet = NULL;

    UNICODE_STRING DeviceName = { 0 };

    RtlInitUnicodeString(&DeviceName,L"\\Device\\DataInteraction");

    status = IoCreateDevice(DriverObject,400,&DeviceName,FILE_DEVICE_UNKNOWN,0,TRUE,&DeviceObjet);

    if (!NT_SUCCESS(status))

    {

        DbgPrint("DriverEntry->IoCreateDevice failed");

        return status;

    }

    DeviceObjet->Flags |= DO_BUFFERED_IO//未设置此标志,Irp->AssociatedIrp.SystemBufferNULL,注意是|= 不要直接=,会消除其它标志位

 

    //创建符号链接

    UNICODE_STRING SysmbolicLinkNmae = { 0 };

    RtlInitUnicodeString(&SysmbolicLinkNmae, L"\\??\\DataInteraction");

    status = IoCreateSymbolicLink(&SysmbolicLinkNmae,&DeviceName);

    if (!NT_SUCCESS(status))

    {

        DbgPrint("DriverEntry->IoCreateSymbolicLink failed");

        IoDeleteDevice(DeviceObjet);

        return status;

    }

 

   

    //设备回调

//https:docs.microsoft.com/en-us/windows-hardware/drivers/ddi/wdm/nc-wdm-driver_dispatch

    DriverObject->MajorFunction[IRP_MJ_CREATE] = MyDispatchCreate; //CreateFile

    DriverObject->MajorFunction[IRP_MJ_CLEANUP] = MyDispatchCleanUp;  //CloseHandle

    DriverObject->MajorFunction[IRP_MJ_CLOSE] = MyDispatchClose;  //CloseHandle

    DriverObject->MajorFunction[IRP_MJ_READ] = MyDispatchRead; //ReadFile

    DriverObject->MajorFunction[IRP_MJ_WRITE] = MyDispatchWrite;  //WriteFile

//https://docs.microsoft.com/en-us/windows-hardware/drivers/kernel/defining-i-o-control-codes

    DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = MyDispatchControl;    //CustomCode

   

 

    DbgPrint("DriverEntry Success");

   

    return status;

}

 

0x01 汇总

1 回调

DriverObject->MajorFunction定义了IRP回调,通过索引定位不同的回调函数

 

2 IRP

PIO_STACK_LOCATION  IrpSp= IoGetCurrentIrpStackLocation(Irp)获取I/O堆栈中与IRP相关联的条目

在不同回调中, 可以使用IrpSp不同的成员来明确操作.具体使用见文档:

https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/wdm/nc-wdm-driver_dispatch

 

2 创建(CreateFile)

调用 DriverObject->MajorFunction[IRP_MJ_CREATE]

 

3 读取(ReadFile)

调用 DriverObject->MajorFunction[IRP_MJ_ READ]

 

4 写入(WriteFile)

调用 DriverObject->MajorFunction[IRP_MJ_ WRITE]

 

5 自定义(DeviceIoControl)

调用 DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL]

IrpSp->Parameters.DeviceIoControl.IoControlCodeDeviceIoControl的第二个参数

 

6 关闭(CloseHandle)

先调用 DriverObject->MajorFunction[IRP_MJ_CLEANUP]

在调用 DriverObject->MajorFunction[IRP_MJ_CLOSE]

 

 

7设备缓冲区

IoCreateDevice第二个参数指定缓冲区大小

同时修改DeviceObjet->Flags,使其或上DO_BUFFERED_IO,如果未设置此标志则Irp->AssociatedIrp.SystemBufferNULL,注意是|= 不要直接=,否则会消除其它标志位

 

0x02文档

驱动派遣回调:  点击IRP查看详细的IPR和IrpSp参数说明

https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/wdm/nc-wdm-driver_dispatch

定义I/O控制代码: 自定义控制代码,回调详情看上述文档中的IRP_MJ_DEVICE_CONTROL

https://docs.microsoft.com/en-us/windows-hardware/drivers/kernel/defining-i-o-control-codes

https://docs.microsoft.com/en-us/windows/win32/api/ioapiset/nf-ioapiset-deviceiocontrol

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值