阅读:1702回复:3
toaster filter改造磁盘过滤驱动中,数据读取问题
程序要实现全volum的加密操作,以toaster filter驱动为起点进行。在网上找到一段代码,测试使用floppydisk做加密成功,但是再调试volum的时候bugcheck了。问题出再RtlCopyBytes(TempBuffer, Buffer , StoreUserMdl->ByteCount);
这行,会出现读的时候内存无效。 现有几点不明白。 1、if ((( StoreUserMdl)->MdlFlags & (MDL_PAGES_LOCKED)))这个判断好像与理解的不符合,难道已经锁定就再锁定一次?这个地方如果用调试版内核会出现Assertion failed: (MemoryDescriptorList->MdlFlags & MDL_MAPPED_TO_SYSTEM_VA) == 0 2、读跟写的是否锁定内存判断不一样,怎么会这样,我改成一样就会出问题。 3、各位大侠都提到不能在原有mdl上进行操作,本驱动已经是文件系统之下了,是不是也要遵循这个规则。 4、disk/volum过滤驱动中的内存是不是肯定用mdl描述,即都是DIRECTIO。 NTSTATUS FilterIoCompletion( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context ) { PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension; // PDEVICE_EXTENSION physicalDisk = deviceExtension->PhysicalDevice->DeviceExtension; PIO_STACK_LOCATION irpStack = IoGetCurrentIrpStackLocation (Irp); // PDISK_PERFORMANCE partitionCounters = &deviceExtension->DiskCounters; // PDISK_PERFORMANCE diskCounters = &physicalDisk->DiskCounters; PMDL StoreUserMdl; PCHAR Buffer; PCHAR TempBuffer; BOOLEAN BufferFlag = FALSE; UNREFERENCED_PARAMETER ( Context ); if ( irpStack->MajorFunction == IRP_MJ_READ ) { StoreUserMdl = Irp->MdlAddress; /*DebugPrint(("READ D - %d P - %d S - %ld\n", deviceExtension -> DiskNumber, deviceExtension ->LastPartitionNumber, (ULONG)(irpStack->Parameters.Read.ByteOffset.LowPart>>9)));*/ while(StoreUserMdl != NULL) { if ((( StoreUserMdl)->MdlFlags & (MDL_PAGES_LOCKED))) //if (!(StoreUserMdl->MdlFlags & (MDL_MAPPED_TO_SYSTEM_VA | MDL_SOURCE_IS_NONPAGED_POOL))) { Buffer = MmMapLockedPages(StoreUserMdl, KernelMode); BufferFlag = TRUE; } else { Buffer = (PCHAR)StoreUserMdl->MappedSystemVa + StoreUserMdl->ByteOffset; BufferFlag = FALSE; } TempBuffer = ExAllocatePool(NonPagedPool, StoreUserMdl->ByteCount); if(TempBuffer == NULL) { DebugPrint(("*******Unable to allocate the memory\n" )); return STATUS_UNSUCCESSFUL; } RtlCopyBytes(TempBuffer, Buffer , StoreUserMdl->ByteCount); if(DecryptBlock(TempBuffer, StoreUserMdl->ByteCount) == FALSE) { ExFreePool(TempBuffer); return STATUS_UNSUCCESSFUL; } RtlCopyBytes(Buffer, TempBuffer, StoreUserMdl->ByteCount); ExFreePool(TempBuffer); if (BufferFlag == TRUE) { MmUnmapLockedPages ( Buffer, StoreUserMdl ); } DebugPrint(("Read Sector %d Decrypted %s\n", (ULONG) (irpStack->Parameters.Read.ByteOffset.LowPart>>9), BufferFlag?"(buffer)":" ")); StoreUserMdl = StoreUserMdl -> Next; }// end of while } else // ------ Write Request ----- // { StoreUserMdl = Irp -> MdlAddress; while ( StoreUserMdl != NULL ) { if (!((StoreUserMdl)->MdlFlags & (MDL_MAPPED_TO_SYSTEM_VA | MDL_SOURCE_IS_NONPAGED_POOL))) { Buffer = MmMapLockedPages ( StoreUserMdl, KernelMode ); BufferFlag = TRUE; } else { Buffer = (PCHAR)StoreUserMdl->MappedSystemVa + StoreUserMdl->ByteOffset; BufferFlag = FALSE; } TempBuffer = ExAllocatePool(NonPagedPool, StoreUserMdl->ByteCount); if(TempBuffer == NULL) { DebugPrint(("Write - Unable to allocate the memory\n")); return STATUS_UNSUCCESSFUL; } RtlCopyBytes(TempBuffer, Buffer, StoreUserMdl->ByteCount ); if(DecryptBlock(TempBuffer, StoreUserMdl->ByteCount) == FALSE) { ExFreePool(TempBuffer); return STATUS_UNSUCCESSFUL; } RtlCopyBytes ( Buffer, TempBuffer ,StoreUserMdl->ByteCount ); ExFreePool ( TempBuffer ); if ( BufferFlag == TRUE ) { MmUnmapLockedPages ( Buffer, StoreUserMdl ); } DebugPrint(("Write Complete Sector %d Decrypted %s\n", (ULONG)(irpStack->Parameters.Read.ByteOffset.LowPart>>9 ), BufferFlag?"(buffer)":" ")); StoreUserMdl = StoreUserMdl->Next; } } if ( Irp->PendingReturned ) { IoMarkIrpPending ( Irp ); } return STATUS_SUCCESS; } |
|
最新喜欢:![]() |
沙发#
发布于:2007-01-12 16:39
几天了,望达人指点。如果需要付费,可以商量。
|
|
板凳#
发布于:2007-01-13 22:08
应该在write irp下发之前就对数据加密,在read irp下发之后解密。
访问mdl指向的内存的内容可以直接通过MmGetSystemAddressForMdl(Safe),如果是upper filter的话。 lower filter怎么处理,我就不清楚了,可能会有不同。 disk/volume read write的内存肯定是mdl描述的。 |
|
地板#
发布于:2007-01-13 22:31
程序是一个volum upper filter。
我是在write irp下发之前加密,write和read 的完成历程中对数据进行解密,这样就可以保证所谓的对系统来说均为明文数据? |
|