EXE和SYS通信(ReadFile WriteFile DO_DIRECT_IO) 直接方式
2015-07-31 17:24
429 查看
EXE部分
SYS部分
#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 __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); //写请求派遣函数
#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; }
相关文章推荐
- Deep Learning for Nature Language Processing --- 第七讲
- linux安装mysql、tomcat和jdk1.7、Android Studio
- Uediter的引用和取值
- Memcached命令:简单获取缓存value用法
- 利用HTML5分片上传超大文件
- MyEclipse10 离线图文安装SVN插件教程
- tomcat一些参数的理解
- ubuntu varnish 安装
- 目前宽带的接入方式有哪些
- markDown语法
- 原生js获取Html元素的实际宽度高度
- .Net HttpWebRequest 方式 访问服务器
- LeetCode225——Implement Stack using Queues
- hdoj 4115 Eliminate the Conflict 【2-sat 经典建图】
- appcan localStorage 本地存储
- ssh--声明事务管理
- cocos2.2版本点遮罩和scroview
- 拉普拉斯滤波实现图像增强
- Python初步
- javascript 变量