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

来源:互联网 发布:邓亚萍 20亿 知乎 编辑:程序博客网 时间:2024/05/01 14:08

EXE部分

#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部分

#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 __cplusplusextern "C" NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING  RegistryPath);#endifvoid 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);//写请求派遣函数


 

 

#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#endifNTSTATUS 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;}//完成IRPpIrP->IoStatus.Status=status;//设置完成状态IoCompleteRequest(pIrP,IO_NO_INCREMENT);//完成IRPreturn status;}//写派遣函数NTSTATUS HelloDDKWrite(IN PDEVICE_OBJECT pDevObj,IN PIRP pIrP){#if DBG_asm int 3#endifNTSTATUS 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;}//完成IRPpIrP->IoStatus.Status=status;//设置完成状态IoCompleteRequest(pIrP,IO_NO_INCREMENT);//完成IRPreturn 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#endifPIO_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));elseKdPrint(("%s\n", irpname[type]));pIrP->IoStatus.Status=STATUS_SUCCESS;//设置完成状态pIrP->IoStatus.Information=0;//设置操作字节为0IoCompleteRequest(pIrP,IO_NO_INCREMENT);//结束IRP派遣函数,第二个参数表示不增加优先级return STATUS_SUCCESS;}



 

0 0
原创粉丝点击