(十三)、直接方式读写与其他方式读写以及IO设备控制

直接方式读写

 
0
 
0
 
#include <ntddk.h> typedef struct _DEVICE_EXTENSION { PCHAR Buffer; ULONG Length; #define MAX_FILE_LEN 4096 }DEVICE_EXTENSION,*PDEVICE_EXTENSION; VOID Unload(PDRIVER_OBJECT driver) { UNICODE_STRING SymbolicLinkName = RTL_CONSTANT_STRING(L"\\??\\MyDDK"); IoDeleteSymbolicLink(&SymbolicLinkName); IoDeleteDevice(driver->DeviceObject); DbgPrint("Driver Unload\n"); } NTSTATUS DisPatchRoutine(IN PDEVICE_OBJECT DeciceObject, IN 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_INFORMATI " , " IRP_MJ_SET_VOLUME_INFORMATION " , " IRP_MJ_DIRECTORY_CONTROL " , " IRP_MJ_FILE_SYSTEM_CONTROL " , " IRP_MJ_DEVICE_CONTROL " , " IRP_MJ_INTERNAL_DEVICE_CONTRO " , " 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 " }; PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(Irp);//IRP栈单元// DbgPrint("%s\n", irpname[stack->MajorFunction]); Irp->IoStatus.Information = 0; //返回状态// Irp->IoStatus.Status = STATUS_SUCCESS; IoCompleteRequest(Irp, IO_NO_INCREMENT);//优先级不改变// return STATUS_SUCCESS; } NTSTATUS DispatchRead(IN PDEVICE_OBJECT DeciceObject, IN PIRP Irp) { NTSTATUS status; PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(Irp); DbgPrint("读异常\n"); ULONG length; CHAR re[] = "Hello ring3"; ULONG offset; ULONG ReadLength; PDEVICE_EXTENSION pdx = DeciceObject->DeviceExtension; __try { length = stack->Parameters.Read.Length; offset = stack->Parameters.Read.ByteOffset.LowPart; DbgPrint("offect值为%x\n", offset); if (length + offset < MAX_FILE_LEN) { if (length + offset > pdx->Length) { ReadLength = pdx->Length - offset; } else { ReadLength = length; } RtlCopyMemory(Irp->AssociatedIrp.SystemBuffer, pdx->Buffer + offset, ReadLength); } else { status = STATUS_BUFFER_TOO_SMALL; ReadLength = 0; } } __except (EXCEPTION_EXECUTE_HANDLER) { status = GetExceptionCode(); DbgPrint("读异常触发,%x\n", status); } Irp->IoStatus.Information = length; Irp->IoStatus.Status = status; IoCompleteRequest(Irp, IO_NO_INCREMENT); return status; } NTSTATUS DispatchWrite(IN PDEVICE_OBJECT DeciceObject, IN PIRP Irp) { NTSTATUS status; ULONG Length; PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(Irp);//获取IRP栈单元// DbgPrint("写异常\n"); ULONG offect; ULONG WriteLength; PDEVICE_EXTENSION pdx = DeciceObject->DeviceExtension; __try { offect = stack->Parameters.Write.ByteOffset.LowPart; DbgPrint("offect值为%x\n", offect); Length = stack->Parameters.Write.Length; if (Length + offect <= MAX_FILE_LEN) { if (Length + offect > pdx->Length) { pdx->Length = Length + offect; } RtlCopyMemory(pdx->Buffer + offect, Irp->AssociatedIrp.SystemBuffer, Length); WriteLength = Length; } else { status = STATUS_BUFFER_TOO_SMALL; DbgPrint("STATUS_BUFFER_TOO_SMALL\n"); WriteLength = 0; } // stack->Parameters.Write.ByteOffset.LowPart += WriteLength; } __except (EXCEPTION_EXECUTE_HANDLER)//如果出现异常,不让操作系统接管,我们自己接管// { status = GetExceptionCode(); DbgPrint("写异常触发,%x\n",status); Length = 0; } Irp->IoStatus.Status = status; Irp->IoStatus.Information = Length; IoCompleteRequest(Irp, IO_NO_INCREMENT); return status; } NTSTATUS DisPatchQueryInfo(PDEVICE_OBJECT DeviceObject, PIRP Irp) { NTSTATUS status; ULONG Length; PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(Irp); PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension; DbgPrint("查询异常\n"); __try { Length = stack->Parameters.QueryFile.Length; if (stack->Parameters.QueryFile.FileInformationClass == FileStandardInformation && Length >= sizeof(FILE_STANDARD_INFORMATION)) { PFILE_STANDARD_INFORMATION pfsi = (PFILE_STANDARD_INFORMATION)Irp->AssociatedIrp.SystemBuffer; pfsi->EndOfFile.LowPart = pdx->Length; status = STATUS_SUCCESS; Length = sizeof(FILE_STANDARD_INFORMATION); } } __except (EXCEPTION_EXECUTE_HANDLER) { status = STATUS_BUFFER_TOO_SMALL; Length = 0; } Irp->IoStatus.Status = status; Irp->IoStatus.Information = Length; IoCompleteRequest(Irp, IO_NO_INCREMENT); return status; } NTSTATUS DriectRead(PDEVICE_OBJECT DeciceObject, PIRP Irp) { NTSTATUS status; PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(Irp); PCHAR Buffer; ULONG ByteOffset; ULONG ByteCount; PVOID Va; ULONG Len; DbgPrint("直接读写异常\n"); __try { ByteOffset = MmGetMdlByteOffset(Irp->MdlAddress);//虚拟内存首地址在第一页的偏移量 ByteCount = MmGetMdlByteCount(Irp->MdlAddress);//mdl虚拟内存的长度 Va = MmGetMdlVirtualAddress(Irp->MdlAddress);//虚拟内存起始地址// DbgPrint("ByteOffset: %x\n", ByteOffset); DbgPrint("ByteCount: %x\n", ByteCount); DbgPrint("Va: %p\n", Va); Buffer = (PCHAR)MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority); if (stack->Parameters.Read.Length <= ByteCount) { RtlCopyMemory(Buffer, "这是一段来自内核的代码\n", strlen("这是一段来自内核的代码\n")); Len = strlen("这是一段来自内核的代码\n"); status = STATUS_SUCCESS; } else { status = STATUS_UNSUCCESSFUL; Len = 0; } } __except(EXCEPTION_EXECUTE_HANDLER) { Len = 0; status = GetExceptionCode(); DbgPrint("直接读写异常触发\n"); } Irp->IoStatus.Status = STATUS_SUCCESS; Irp->IoStatus.Information = status; IoCompleteRequest(Irp, IO_NO_INCREMENT); return status; } NTSTATUS DriverEntry(PDRIVER_OBJECT driver, PUNICODE_STRING RegistryPath) { UNICODE_STRING DeviceName = RTL_CONSTANT_STRING(L"\\Device\\HelloDDK"); UNICODE_STRING SymblicLink = RTL_CONSTANT_STRING(L"\\??\\MyDDK"); NTSTATUS status; PDEVICE_OBJECT DeviceObject; driver->DriverUnload = Unload; DbgPrint("Driver Load\n"); PDEVICE_EXTENSION pdx;//设备扩展// status = IoCreateDevice(driver, sizeof(DEVICE_EXTENSION), &DeviceName, FILE_DEVICE_UNKNOWN,0, FALSE, &DeviceObject); if (!NT_SUCCESS(status)) { DbgPrint("创建设备失败\n"); return status; } status = IoCreateSymbolicLink(&SymblicLink, &DeviceName); if (!NT_SUCCESS(status)) { DbgPrint("创建符号链接失败\n"); IoDeleteDevice(DeviceObject); return status; } DeviceObject->Flags |= DO_DIRECT_IO; //缓冲区读写// 出错原因,DeviceObject写成了driver// DeviceObject->Flags &= ~DO_DEVICE_INITIALIZING; for (ULONG i = 0; i < IRP_MJ_MAXIMUM_FUNCTION + 1; i++) { driver->MajorFunction[i] = DisPatchRoutine; } driver->MajorFunction[IRP_MJ_READ] = DriectRead; //driver->MajorFunction[IRP_MJ_WRITE] = DispatchWrite; driver->MajorFunction[IRP_MJ_QUERY_INFORMATION] = DisPatchQueryInfo; pdx = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension; pdx->Buffer = (PCHAR)ExAllocatePool(PagedPool, 4096); pdx->Length = 0; return STATUS_SUCCESS; }
 
0
 

其他方式读写

又称Neither读写,这种方式很少被用到
派遣函数直接读写应用程序提供的缓冲区,这是很危险的,如果在驱动读写这块地址时发生了进程切换,即驱动程序访问了错误的内存地址,将会触发蓝屏,不建议使用
 
Flag设为0
#include <ntddk.h> typedef struct _DEVICE_EXTENSION { PCHAR Buffer; ULONG Length; #define MAX_FILE_LEN 4096 }DEVICE_EXTENSION,*PDEVICE_EXTENSION; VOID Unload(PDRIVER_OBJECT driver) { UNICODE_STRING SymbolicLinkName = RTL_CONSTANT_STRING(L"\\??\\MyDDK"); IoDeleteSymbolicLink(&SymbolicLinkName); IoDeleteDevice(driver->DeviceObject); DbgPrint("Driver Unload\n"); } NTSTATUS DisPatchRoutine(IN PDEVICE_OBJECT DeciceObject, IN 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_INFORMATI " , " IRP_MJ_SET_VOLUME_INFORMATION " , " IRP_MJ_DIRECTORY_CONTROL " , " IRP_MJ_FILE_SYSTEM_CONTROL " , " IRP_MJ_DEVICE_CONTROL " , " IRP_MJ_INTERNAL_DEVICE_CONTRO " , " 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 " }; PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(Irp);//IRP栈单元// DbgPrint("%s\n", irpname[stack->MajorFunction]); Irp->IoStatus.Information = 0; //返回状态// Irp->IoStatus.Status = STATUS_SUCCESS; IoCompleteRequest(Irp, IO_NO_INCREMENT);//优先级不改变// return STATUS_SUCCESS; } NTSTATUS DispatchRead(IN PDEVICE_OBJECT DeciceObject, IN PIRP Irp) { NTSTATUS status; PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(Irp); DbgPrint("读异常\n"); ULONG length; CHAR re[] = "Hello ring3"; ULONG offset; ULONG ReadLength; PDEVICE_EXTENSION pdx = DeciceObject->DeviceExtension; __try { length = stack->Parameters.Read.Length; offset = stack->Parameters.Read.ByteOffset.LowPart; DbgPrint("offect值为%x\n", offset); if (length + offset < MAX_FILE_LEN) { if (length + offset > pdx->Length) { ReadLength = pdx->Length - offset; } else { ReadLength = length; } RtlCopyMemory(Irp->AssociatedIrp.SystemBuffer, pdx->Buffer + offset, ReadLength); } else { status = STATUS_BUFFER_TOO_SMALL; ReadLength = 0; } } __except (EXCEPTION_EXECUTE_HANDLER) { status = GetExceptionCode(); DbgPrint("读异常触发,%x\n", status); } Irp->IoStatus.Information = length; Irp->IoStatus.Status = status; IoCompleteRequest(Irp, IO_NO_INCREMENT); return status; } NTSTATUS DispatchWrite(IN PDEVICE_OBJECT DeciceObject, IN PIRP Irp) { NTSTATUS status; ULONG Length; PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(Irp);//获取IRP栈单元// DbgPrint("写异常\n"); ULONG offect; ULONG WriteLength; PDEVICE_EXTENSION pdx = DeciceObject->DeviceExtension; __try { offect = stack->Parameters.Write.ByteOffset.LowPart; DbgPrint("offect值为%x\n", offect); Length = stack->Parameters.Write.Length; if (Length + offect <= MAX_FILE_LEN) { if (Length + offect > pdx->Length) { pdx->Length = Length + offect; } RtlCopyMemory(pdx->Buffer + offect, Irp->AssociatedIrp.SystemBuffer, Length); WriteLength = Length; } else { status = STATUS_BUFFER_TOO_SMALL; DbgPrint("STATUS_BUFFER_TOO_SMALL\n"); WriteLength = 0; } // stack->Parameters.Write.ByteOffset.LowPart += WriteLength; } __except (EXCEPTION_EXECUTE_HANDLER)//如果出现异常,不让操作系统接管,我们自己接管// { status = GetExceptionCode(); DbgPrint("写异常触发,%x\n",status); Length = 0; } Irp->IoStatus.Status = status; Irp->IoStatus.Information = Length; IoCompleteRequest(Irp, IO_NO_INCREMENT); return status; } NTSTATUS DisPatchQueryInfo(PDEVICE_OBJECT DeviceObject, PIRP Irp) { NTSTATUS status; ULONG Length; PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(Irp); PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension; DbgPrint("查询异常\n"); __try { Length = stack->Parameters.QueryFile.Length; if (stack->Parameters.QueryFile.FileInformationClass == FileStandardInformation && Length >= sizeof(FILE_STANDARD_INFORMATION)) { PFILE_STANDARD_INFORMATION pfsi = (PFILE_STANDARD_INFORMATION)Irp->AssociatedIrp.SystemBuffer; pfsi->EndOfFile.LowPart = pdx->Length; status = STATUS_SUCCESS; Length = sizeof(FILE_STANDARD_INFORMATION); } } __except (EXCEPTION_EXECUTE_HANDLER) { status = STATUS_BUFFER_TOO_SMALL; Length = 0; } Irp->IoStatus.Status = status; Irp->IoStatus.Information = Length; IoCompleteRequest(Irp, IO_NO_INCREMENT); return status; } NTSTATUS DriectRead(PDEVICE_OBJECT DeciceObject, PIRP Irp) { NTSTATUS status; PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(Irp); PCHAR Buffer; ULONG ByteOffset; ULONG ByteCount; PVOID Va; ULONG Len; DbgPrint("直接读写异常\n"); __try { ByteOffset = MmGetMdlByteOffset(Irp->MdlAddress);//虚拟内存首地址在第一页的偏移量 ByteCount = MmGetMdlByteCount(Irp->MdlAddress);//mdl虚拟内存的长度 Va = MmGetMdlVirtualAddress(Irp->MdlAddress);//虚拟内存起始地址// DbgPrint("ByteOffset: %x\n", ByteOffset); DbgPrint("ByteCount: %x\n", ByteCount); DbgPrint("Va: %p\n", Va); Buffer = (PCHAR)MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority); if (stack->Parameters.Read.Length <= ByteCount) { RtlCopyMemory(Buffer, "这是一段来自内核的代码\n", strlen("这是一段来自内核的代码\n")); Len = strlen("这是一段来自内核的代码\n"); status = STATUS_SUCCESS; } else { status = STATUS_UNSUCCESSFUL; Len = 0; } } __except(EXCEPTION_EXECUTE_HANDLER) { Len = 0; status = GetExceptionCode(); DbgPrint("直接读写异常触发\n"); } Irp->IoStatus.Status = STATUS_SUCCESS; Irp->IoStatus.Information = status; IoCompleteRequest(Irp, IO_NO_INCREMENT); return status; } NTSTATUS NeitherRead(PDEVICE_OBJECT DeviceObject, PIRP Irp) { NTSTATUS status; ULONG Length; PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(Irp); __try { ProbeForWrite(Irp->UserBuffer, stack->Parameters.Read.Length, 4); RtlCopyMemory(Irp->UserBuffer, "这是来着内核的一句话", strlen("这是来着内核的一句话")); status = STATUS_SUCCESS; Length = strlen("这是来着内核的一句话"); } __except(EXCEPTION_EXECUTE_HANDLER) { status = GetExceptionCode(); Length = 0; } Irp->IoStatus.Status = STATUS_SUCCESS; Irp->IoStatus.Information = Length; IoCompleteRequest(Irp, IO_NO_INCREMENT); return status; } NTSTATUS DriverEntry(PDRIVER_OBJECT driver, PUNICODE_STRING RegistryPath) { UNICODE_STRING DeviceName = RTL_CONSTANT_STRING(L"\\Device\\HelloDDK"); UNICODE_STRING SymblicLink = RTL_CONSTANT_STRING(L"\\??\\MyDDK"); NTSTATUS status; PDEVICE_OBJECT DeviceObject; driver->DriverUnload = Unload; DbgPrint("Driver Load\n"); PDEVICE_EXTENSION pdx;//设备扩展// status = IoCreateDevice(driver, sizeof(DEVICE_EXTENSION), &DeviceName, FILE_DEVICE_UNKNOWN,0, FALSE, &DeviceObject); if (!NT_SUCCESS(status)) { DbgPrint("创建设备失败\n"); return status; } status = IoCreateSymbolicLink(&SymblicLink, &DeviceName); if (!NT_SUCCESS(status)) { DbgPrint("创建符号链接失败\n"); IoDeleteDevice(DeviceObject); return status; } DeviceObject->Flags |= 0; //缓冲区读写// 出错原因,DeviceObject写成了driver// DeviceObject->Flags &= ~DO_DEVICE_INITIALIZING; for (ULONG i = 0; i < IRP_MJ_MAXIMUM_FUNCTION + 1; i++) { driver->MajorFunction[i] = DisPatchRoutine; } driver->MajorFunction[IRP_MJ_READ] = NeitherRead; //driver->MajorFunction[IRP_MJ_WRITE] = DispatchWrite; driver->MajorFunction[IRP_MJ_QUERY_INFORMATION] = DisPatchQueryInfo; pdx = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension; pdx->Buffer = (PCHAR)ExAllocatePool(PagedPool, 4096); pdx->Length = 0; return STATUS_SUCCESS; }
 
0
 

IO设备控制

这个方法以前写过好多次了
交互
0
 
0
 

__EOF__

本文作者_TLSN
本文链接https://www.cnblogs.com/lordtianqiyi/articles/16100950.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   TLSN  阅读(142)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 25岁的心里话
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示