您的位置:首页 > 其它

EXE和SYS通信(ReadFile WriteFile DO_DIRECT_IO) 直接方式

2017-06-14 17:14 295 查看
EXE部分

[cpp] view
plain copy

#include <stdio.h>  

#include <Windows.h>  

  

int main (void)  

{  

    char linkname[]="\\\\.\\HelloDDK";  

    HANDLE hDevice = CreateFileA(linkname,GENERIC_READ | GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);  

    if (hDevice == INVALID_HANDLE_VALUE)  

    {  

        printf("Win32 error code: %d\n",GetLastError());  

        return 1;  

    }  

  

    UCHAR buffer[10]={0};  

    ULONG ulRead=0;  

    if (ReadFile(hDevice,buffer,10,&ulRead,NULL))  

    {  

        printf("Read %d bytes:",ulRead);  

        for (int i=0;i<(int)ulRead;i++)  

        {  

            printf("%02X ",buffer[i]);  

        }  

        printf("\n");  

    }  

    getchar();  

    getchar();  

  

    ulRead=0;  

    if (WriteFile(hDevice,buffer,10,&ulRead,NULL))  

    {  

        printf("write %d bytes\n",ulRead);  

        for (int i=0;i<(int)ulRead;i++)  

        {  

            printf("%02X ",buffer[i]);  

        }  

        printf("\n");  

    }  

  

    CloseHandle(hDevice);  

  

    getchar();  

    getchar();  

    return 0;  

}  

 

SYS部分

[cpp] view
plain copy

#pragma once  

  

#include <ntddk.h>  

#define CountArray(Array)  (    sizeof(Array)   /   sizeof(Array[0])    )  

  

typedef struct _DEVICE_EXTENSION  

{  

    PDEVICE_OBJECT pDevice;                                     //设备对象  

    UNICODE_STRING ustrDeviceName;                  //设备名称  

    UNICODE_STRING ustrSymLinkName;                 //符号名称  

}DEVICE_EXTENSION,*PDEVICE_EXTENSION;  

  

  

  

#ifdef __cplusplus  

extern "C" NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING  RegistryPath);  

#endif  

  

void HelloUnload(IN PDRIVER_OBJECT DriverObject);                                                       //卸载函数  

NTSTATUS CreateDevice(PDRIVER_OBJECT PDevObj);                                                  //创建设备  

NTSTATUS HelloDDKDispatchRoutine(IN PDEVICE_OBJECT pDevObj,IN PIRP pIrp);   //派遣函数  

NTSTATUS HelloDDKRead(IN PDEVICE_OBJECT pDevObj,IN PIRP pIrP);                      //读请求派遣函数  

NTSTATUS HelloDDKWrite(IN PDEVICE_OBJECT pDevObj,IN PIRP pIrP);                     //写请求派遣函数  

 

 

[cpp] view
plain copy

#include "hello.h"  

  

NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING  RegistryPath)  

{  

        DbgPrint("Hello from!\n");  

        DriverObject->DriverUnload = HelloUnload;  

        for (int i=0;i<IRP_MJ_MAXIMUM_FUNCTION;i++)  

        {  

            DriverObject->MajorFunction[i]=HelloDDKDispatchRoutine;  

        }  

        DriverObject->MajorFunction[IRP_MJ_READ]=HelloDDKRead;           //设置读派遣函数  

        DriverObject->MajorFunction[IRP_MJ_WRITE]=HelloDDKWrite;     //设置写派遣函数  

  

  

#if DBG  

        _asm int 3  

#endif  

        //创建设备  

        CreateDevice(DriverObject);  

  

        return STATUS_SUCCESS;  

}  

  

//读派遣函数  

NTSTATUS HelloDDKRead(IN PDEVICE_OBJECT pDevObj,IN PIRP pIrP)  

{  

#if DBG  

    _asm int 3  

#endif  

  

    NTSTATUS status=STATUS_SUCCESS;  

  

    PIO_STACK_LOCATION stack=IoGetCurrentIrpStackLocation(pIrP);  

    ULONG ulReadLength=stack->Parameters.Read.Length;  

  

    ULONG mdl_length=MmGetMdlByteCount(pIrP->MdlAddress);                    //获取缓冲区的长度  

    PVOID  mdl_address=MmGetMdlVirtualAddress(pIrP->MdlAddress);     //获取缓冲区的虚拟地址  

    ULONG mdl_offset=MmGetMdlByteOffset(pIrP->MdlAddress);                   //返回缓冲区的偏移  

  

    if (mdl_length!=ulReadLength)  

    {  

        //MDL的长度应该和读长度相等,否则该操作应该设为不成功  

        pIrP->IoStatus.Information=0;  

        status=STATUS_UNSUCCESSFUL;  

    }  

    else  

    {  

        //用那个MmGetSystemAddressForMdlSafe得到在内核模式下的影射  

        PVOID kernel_address=MmGetSystemAddressForMdlSafe(pIrP->MdlAddress,NormalPagePriority);  

        DbgPrint("address0X%08X\n",kernel_address);  

        memset(kernel_address,0XAA,ulReadLength);  

        pIrP->IoStatus.Information=ulReadLength;  

    }  

  

    //完成IRP  

    pIrP->IoStatus.Status=status;                                                                    //设置完成状态  

    IoCompleteRequest(pIrP,IO_NO_INCREMENT);                                        //完成IRP  

  

    return status;  

}  

  

//写派遣函数  

NTSTATUS HelloDDKWrite(IN PDEVICE_OBJECT pDevObj,IN PIRP pIrP)  

{  

#if DBG  

    _asm int 3  

#endif  

  

    NTSTATUS status=STATUS_SUCCESS;  

  

    PIO_STACK_LOCATION stack=IoGetCurrentIrpStackLocation(pIrP);  

    ULONG ulWriteLength=stack->Parameters.Write.Length;  

  

    ULONG mdl_length=MmGetMdlByteCount(pIrP->MdlAddress);                    //获取缓冲区的长度  

    PVOID  mdl_address=MmGetMdlVirtualAddress(pIrP->MdlAddress);     //获取缓冲区的虚拟地址  

    ULONG mdl_offset=MmGetMdlByteOffset(pIrP->MdlAddress);                   //返回缓冲区的偏移  

  

    if (mdl_length!=ulWriteLength)  

    {  

        //MDL的长度应该和读长度相等,否则该操作应该设为不成功  

        pIrP->IoStatus.Information=0;  

        status=STATUS_UNSUCCESSFUL;  

    }  

    else  

    {  

        //用那个MmGetSystemAddressForMdlSafe得到在内核模式下的影射  

        PVOID kernel_address=MmGetSystemAddressForMdlSafe(pIrP->MdlAddress,NormalPagePriority);  

        DbgPrint("address0X%08X\n",kernel_address);  

        UCHAR buffer[10]={0};  

        memcpy(buffer,kernel_address,ulWriteLength);  

        for (int i=0;i<(int)ulWriteLength;i++)  

        {  

            DbgPrint("%02x\n",buffer[i]);  

        }  

        memset(kernel_address,0XAA,ulWriteLength);  

        pIrP->IoStatus.Information=ulWriteLength;  

    }  

  

  

    //完成IRP  

    pIrP->IoStatus.Status=status;                                                                    //设置完成状态  

    IoCompleteRequest(pIrP,IO_NO_INCREMENT);                                        //完成IRP  

  

    return status;  

}  

  

//卸载函数  

void HelloUnload(IN PDRIVER_OBJECT DriverObject)  

{  

        DbgPrint("Goodbye from!\n");  

        PDEVICE_OBJECT pNextObj=NULL;  

        pNextObj=DriverObject->DeviceObject;  

  

        while (pNextObj)  

        {  

            PDEVICE_EXTENSION pDevExt=(PDEVICE_EXTENSION)pNextObj->DeviceExtension;  

            //删除符号连接  

            IoDeleteSymbolicLink(&pDevExt->ustrSymLinkName);  

            //删除设备  

            IoDeleteDevice(pDevExt->pDevice);  

  

            pNextObj=pNextObj->NextDevice;  

        }  

}  

  

//创建设备  

NTSTATUS CreateDevice(PDRIVER_OBJECT pDriver_Object)  

{  

    //定义变量  

    NTSTATUS status=STATUS_SUCCESS;  

    PDEVICE_OBJECT pDevObje=NULL;  

    PDEVICE_EXTENSION pDevExt=NULL;  

  

    //初始化字符串  

    UNICODE_STRING devname;  

    UNICODE_STRING symLinkName;  

    RtlInitUnicodeString(&devname,L"\\device\\hello");  

    RtlInitUnicodeString(&symLinkName,L"\\??\\HelloDDK");  

  

    //创建设备  

    if (IoCreateDevice(pDriver_Object,sizeof(PDEVICE_EXTENSION),&devname,FILE_DEVICE_UNKNOWN,NULL,TRUE,&pDevObje)!=STATUS_SUCCESS )  

    {  

        DbgPrint("创建设备失败\n");  

        return status;  

    }  

  

    //设置读写方式  

    pDevObje->Flags |= DO_DIRECT_IO;             //直接读取设备  

    pDevExt=(PDEVICE_EXTENSION)pDevObje->DeviceExtension;  

    pDevExt->pDevice=pDevObje;  

    pDevExt->ustrDeviceName=devname;  

    pDevExt->ustrSymLinkName=symLinkName;  

  

    //创建符号连接  

    if (IoCreateSymbolicLink(&symLinkName,&devname)!=STATUS_SUCCESS )  

    {  

        DbgPrint("创建符号连接失败\n");  

        IoDeleteDevice(pDevObje);  

        return status;  

    }  

    return STATUS_SUCCESS;  

}  

  

//派遣函数  

NTSTATUS HelloDDKDispatchRoutine(IN PDEVICE_OBJECT pDevObj,IN PIRP pIrP)  

{  

#if DBG  

    _asm int 3  

#endif  

  

    PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(pIrP);  

    //建立一个字符串数组与IRP类型对应起来  

    static char* irpname[] =   

    {  

        "IRP_MJ_CREATE",  

        "IRP_MJ_CREATE_NAMED_PIPE",  

        "IRP_MJ_CLOSE",  

        "IRP_MJ_READ",  

        "IRP_MJ_WRITE",  

        "IRP_MJ_QUERY_INFORMATION",  

        "IRP_MJ_SET_INFORMATION",  

        "IRP_MJ_QUERY_EA",  

        "IRP_MJ_SET_EA",  

        "IRP_MJ_FLUSH_BUFFERS",  

        "IRP_MJ_QUERY_VOLUME_INFORMATION",  

        "IRP_MJ_SET_VOLUME_INFORMATION",  

        "IRP_MJ_DIRECTORY_CONTROL",  

        "IRP_MJ_FILE_SYSTEM_CONTROL",  

        "IRP_MJ_DEVICE_CONTROL",  

        "IRP_MJ_INTERNAL_DEVICE_CONTROL",  

        "IRP_MJ_SHUTDOWN",  

        "IRP_MJ_LOCK_CONTROL",  

        "IRP_MJ_CLEANUP",  

        "IRP_MJ_CREATE_MAILSLOT",  

        "IRP_MJ_QUERY_SECURITY",  

        "IRP_MJ_SET_SECURITY",  

        "IRP_MJ_POWER",  

        "IRP_MJ_SYSTEM_CONTROL",  

        "IRP_MJ_DEVICE_CHANGE",  

        "IRP_MJ_QUERY_QUOTA",  

        "IRP_MJ_SET_QUOTA",  

        "IRP_MJ_PNP",  

    };  

  

    UCHAR type = stack->MajorFunction;  

  

    if (type >= CountArray(irpname))  

        KdPrint(("无效的IRP类型 %X\n", type));  

    else  

        KdPrint(("%s\n", irpname[type]));  

  

  

  

  

    pIrP->IoStatus.Status=STATUS_SUCCESS;                    //设置完成状态  

    pIrP->IoStatus.Information=0;                                        //设置操作字节为0  

    IoCompleteRequest(pIrP,IO_NO_INCREMENT);            //结束IRP派遣函数,第二个参数表示不增加优先级  

    return STATUS_SUCCESS;  

}  
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: