zzh520420
驱动牛犊
驱动牛犊
  • 注册日期2008-07-24
  • 最后登录2011-05-16
  • 粉丝0
  • 关注0
  • 积分14分
  • 威望59点
  • 贡献值1点
  • 好评度0点
  • 原创分0分
  • 专家分0分
阅读:2318回复:2

关于文件过虑驱动做透明加密解密的问题(框架是tooflat)

楼主#
更多 发布于:2008-11-25 11:38
求救!!!我的加密函数没问题,但解密有问题,网上很多做的办法是在驱动里获取打开文件时,然后通过对文件进行解密,把解密后的明文写入文件,最后就能显示出来明文。但我不想这样,我的思路是这样的,当打开一个文件时我不是直接对文件进行解密,我是想通过截获读取到的数据,然后再对它进行解密给用户,所以在硬盘中的文件还是能保持密文,但给用户看到的是明文。下面是代码,其中解密文件的代码在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;
}
wesley2005
驱动牛犊
驱动牛犊
  • 注册日期2007-06-16
  • 最后登录2011-03-29
  • 粉丝1
  • 关注0
  • 积分34分
  • 威望327点
  • 贡献值0点
  • 好评度15点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2008-12-01 17:06
Completion的context,不是原来的thread了啊
guard366
驱动牛犊
驱动牛犊
  • 注册日期2009-04-30
  • 最后登录2010-10-21
  • 粉丝0
  • 关注0
  • 积分36分
  • 威望351点
  • 贡献值1点
  • 好评度0点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2009-05-01 11:50
我是想通过截获读取到的数据,然后再对它进行解密给用户,所以在硬盘中的文件还是能保持密文,但给用户看到的是明文。

都是这种做法吧?
成熟的产品!
游客

返回顶部