阅读:2318回复:2
关于文件过虑驱动做透明加密解密的问题(框架是tooflat)
求救!!!我的加密函数没问题,但解密有问题,网上很多做的办法是在驱动里获取打开文件时,然后通过对文件进行解密,把解密后的明文写入文件,最后就能显示出来明文。但我不想这样,我的思路是这样的,当打开一个文件时我不是直接对文件进行解密,我是想通过截获读取到的数据,然后再对它进行解密给用户,所以在硬盘中的文件还是能保持密文,但给用户看到的是明文。下面是代码,其中解密文件的代码在SfReadCompletion,我是想在读取完毕后,直接对IRP里的数据进行解密,但为什么显示出来都是没有变化呢?
NTSTATUS SfRead( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ) { PSFILTER_DEVICE_EXTENSION DevExt = (PSFILTER_DEVICE_EXTENSION) DeviceObject->DeviceExtension; PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp); PFILE_OBJECT FileObject = IrpSp->FileObject; PREAD_WRITE_COMPLETION_CONTEXT CompletionCtx = NULL; PVOID OldBuffer = NULL; PVOID MyBuffer = NULL; ULONG Length = 0; FILE_CONTEXT FileCtx; PFILE_CONTEXT FileCtxPtr = NULL; NTSTATUS Status = STATUS_SUCCESS; PAGED_CODE(); // // Sfilter doesn't allow handles to its control device object to be created, // therefore, no other operation should be able to come through. // ASSERT(!IS_MY_CONTROL_DEVICE_OBJECT(DeviceObject)); ASSERT(IS_MY_DEVICE_OBJECT(DeviceObject)); // // We only care about volume filter device object // if (!DevExt->StorageStackDeviceObject) { IoSkipCurrentIrpStackLocation(Irp); return IoCallDriver(DevExt->AttachedToDeviceObject, Irp); } #if 0 if (DevExt->DriveLetter != DEBUG_VOLUME) { IoSkipCurrentIrpStackLocation(Irp); return IoCallDriver(DevExt->AttachedToDeviceObject, Irp); } #endif #if 0 //有下面这些时,就通不过,所以注释了它 if (!(Irp->Flags & (IRP_NOCACHE | IRP_PAGING_IO | IRP_SYNCHRONOUS_PAGING_IO))) { IoSkipCurrentIrpStackLocation(Irp); return IoCallDriver(DevExt->AttachedToDeviceObject, Irp); } #endif ExAcquireFastMutex(&DevExt->FsCtxTableMutex); FileCtx.FsContext = FileObject->FsContext; FileCtxPtr = RtlLookupElementGenericTable(&DevExt->FsCtxTable, &FileCtx); ExReleaseFastMutex(&DevExt->FsCtxTableMutex); if (!FileCtxPtr || !FileCtxPtr->DecryptOnRead) { IoSkipCurrentIrpStackLocation(Irp); return IoCallDriver(DevExt->AttachedToDeviceObject, Irp); } do { #if 1 if (Irp->MdlAddress) OldBuffer = MmGetSystemAddressForMdl(Irp->MdlAddress); else OldBuffer = Irp->UserBuffer; if (!OldBuffer) { KdPrint(("sfilter!SfRead: STATUS_INVALID_PARAMETER\n")); Status = STATUS_INVALID_PARAMETER; break; } Length = IrpSp->Parameters.Write.Length; CompletionCtx = ExAllocateFromNPagedLookasideList(&gReadWriteCompletionCtxLookAsideList); if (!CompletionCtx) { KdPrint(("sfilter!SfRead: STATUS_INSUFFICIENT_RESOURCES\n")); Status = STATUS_INSUFFICIENT_RESOURCES; break; } MyBuffer = ExAllocatePoolWithTag(NonPagedPool, IrpSp->Parameters.Write.Length, SFLT_POOL_TAG); if (!MyBuffer) { KdPrint(("sfilter!SfRead: STATUS_INSUFFICIENT_RESOURCES\n")); ExFreePool(CompletionCtx); Status = STATUS_INSUFFICIENT_RESOURCES; break; } CompletionCtx->OldMdl = Irp->MdlAddress; CompletionCtx->OldUserBuffer = Irp->UserBuffer; CompletionCtx->OldSystemBuffer = Irp->AssociatedIrp.SystemBuffer; CompletionCtx->OldBuffer = OldBuffer; CompletionCtx->MyBuffer = MyBuffer; CompletionCtx->Length = Length; Irp->MdlAddress = IoAllocateMdl(MyBuffer, IrpSp->Parameters.Write.Length, FALSE, TRUE, NULL); if (!Irp->MdlAddress) { KdPrint(("sfilter!SfRead: STATUS_INSUFFICIENT_RESOURCES\n")); Irp->MdlAddress = CompletionCtx->OldMdl; ExFreePool(CompletionCtx); ExFreePool(MyBuffer); Status = STATUS_INSUFFICIENT_RESOURCES; break; } #endif KdPrint(("sfilter!SfRead: Decrypt %ws\n", FileCtxPtr->Name)); MmBuildMdlForNonPagedPool(Irp->MdlAddress); Irp->UserBuffer = MmGetMdlVirtualAddress(Irp->MdlAddress); IoCopyCurrentIrpStackLocationToNext(Irp); IoSetCompletionRoutine(Irp, SfReadCompletion, CompletionCtx, TRUE, TRUE,TRUE); return IoCallDriver(DevExt->AttachedToDeviceObject, Irp); } while (FALSE); Irp->IoStatus.Status = Status; IoCompleteRequest(Irp, IO_NO_INCREMENT); return Status; } NTSTATUS SfReadCompletion( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context ) { PREAD_WRITE_COMPLETION_CONTEXT CompletionCtx = (PREAD_WRITE_COMPLETION_CONTEXT) Context; ULONG Offset = 0; UNREFERENCED_PARAMETER(DeviceObject); if (Irp->PendingReturned) IoMarkIrpPending(Irp); IoFreeMdl(Irp->MdlAddress); #if 1 Irp->MdlAddress = CompletionCtx->OldMdl; Irp->UserBuffer = CompletionCtx->OldUserBuffer; Irp->AssociatedIrp.SystemBuffer = CompletionCtx->OldSystemBuffer; // decrypt for (Offset = 0; Offset < CompletionCtx->Length; Offset++) { ((PUCHAR) Irp->UserBuffer)[Offset]=~((PUCHAR) Irp->UserBuffer)[Offset]; } ExFreePoolWithTag(CompletionCtx->MyBuffer, SFLT_POOL_TAG); #endif ExFreeToNPagedLookasideList(&gReadWriteCompletionCtxLookAsideList, CompletionCtx); return STATUS_SUCCESS; } |
|
沙发#
发布于:2008-12-01 17:06
Completion的context,不是原来的thread了啊
|
|
板凳#
发布于:2009-05-01 11:50
我是想通过截获读取到的数据,然后再对它进行解密给用户,所以在硬盘中的文件还是能保持密文,但给用户看到的是明文。
都是这种做法吧? |
|
|