阅读:16990回复:60
闲暇时写的透明加解密过滤驱动,只支持流加密
仅供大家参考
需要注意的问题: 1、文件名获取方式不够完善 2、不能加密整个根目录,否则该分区不能mount 3、错误处理不够完善 4、未作充分测试,如果问题,概不负责 |
|
|
沙发#
发布于:2005-03-17 21:52
感觉你的错误有一些,比如
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 DBG if (DevExt->DriveLetter != DEBUG_VOLUME) { IoSkipCurrentIrpStackLocation(Irp); return IoCallDriver(DevExt->AttachedToDeviceObject, Irp); } #endif if (!(Irp->Flags & (IRP_NOCACHE | IRP_PAGING_IO | IRP_SYNCHRONOUS_PAGING_IO))) { IoSkipCurrentIrpStackLocation(Irp); return IoCallDriver(DevExt->AttachedToDeviceObject, Irp); } 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 (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, //错误,改为IrpSp->Parameters.Read.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; } 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; } 2 解密你考虑太多了,没有用,浪费资源。 3 你为何不能加密根目录,是因为你的代码加密判定不完善,所以修改了根目录区。 4 文件名获取参考filemon,很好的例子 5 不需要加ExReleaseFastMutex,这个影响你的性能。 以上我的个人看法,不一定对。 |
|
板凳#
发布于:2005-03-18 11:53
|
|
地板#
发布于:2005-03-18 17:31
ExReleaseFastMutex会提高它的irpl级别。对共享的可能会有影响,系统会管理好的
你不需要这个东西啊the generic table |
|
地下室#
发布于:2005-03-19 12:50
ExReleaseFastMutex会提高它的irpl级别。对共享的可能会有影响,系统会管理好的 晕,第一次听到这种说法 |
|
5楼#
发布于:2005-03-19 13:46
不好意思,让你见笑了,哈哈,说错了
是需要在Callers of ExReleaseFastMutex must be running at IRQL = APC_LEVEL. 这个级别。 不过真的这个没有必要使用。你不信就算了。你没有必要处理the generic table 。 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); } 根本需要的 你能说说你的理由吗,我比较菜,虚心接受你的意见的 |
|
6楼#
发布于:2005-03-20 02:35
文件系统完全头疼
不过那个IrpSp.Parameter.Read跟Write的问题 其实..不算是问题 实际上他们位于同一个偏移量 运行上是不会有问题的 最多... 只是源代码的阅读一级上.会有歧义... 呵呵 吹毛求疵了 |
|
7楼#
发布于:2005-03-21 14:10
不好意思,让你见笑了,哈哈,说错了 ExReleaseFastMutex releases ownership of the given fast mutex and reenables the delivery of APCs to the current thread. 不使用FastMutex,如何保证GenericTable中内容的正确,共享资源不需要同步吗?? |
|
8楼#
发布于:2005-04-02 14:10
[quote]不好意思,让你见笑了,哈哈,说错了 ExReleaseFastMutex releases ownership of the given fast mutex and reenables the delivery of APCs to the current thread. 不使用FastMutex,如何保证GenericTable中内容的正确,共享资源不需要同步吗?? [/quote] 在win 2000 professiona 下 加载-->死机[没有蓝屏,可能是死锁] |
|
|
9楼#
发布于:2005-04-07 15:56
可以给出测试程序么?我想跟踪一下,但不清楚怎么调用。谢谢!
|
|
10楼#
发布于:2005-04-07 19:09
可以给出测试程序么?我想跟踪一下,但不清楚怎么调用。谢谢! 另外,为什么我编译的时候出现 LIBCD.lib(wincrt0.obj) : error LNK2001: unresolved external symbol _WinMain@16 这样的错误啊?? 请各位大佬指点一下啊 :mad: |
|
11楼#
发布于:2005-04-08 15:26
用ddk编译,编译类型
TARGETTYPE=DRIVER DRIVERTYPE=FS |
|
12楼#
发布于:2005-04-15 10:12
抛两块砖:
1.读文件的时候在完成例程中处理用户缓冲区,这是十分危险的,因为完成例程运行在随机线程上下文中,这个问题我亲身经历过。 2.在当前根目录下面创建一个隐藏目录保存加密相关信息,然后过滤掉用户模式访问,如果将过滤范围扩大到整个根目录,则自己创建的目录也在加解密范围内了,而你在Create例程当中会以内核模式调用NtCreateFile,NtWriteFile和NtReadFile访问自己创建的目录,这样是不是会造成IRP重入? [编辑 - 4/15/05 by joshua_yu] |
|
13楼#
发布于:2005-04-15 13:27
我也提个问题哈,怎样以免修改根目录区呢?还有就是什么是根目录区啊?
|
|
14楼#
发布于:2005-04-23 21:24
我的系统为winxp,在inf中start = 0,type = 2,在DriverEntry中说无法找到文件\\systemroot\\xefs.dat,我的xefs.dat放在c:\\windows目录下,当我把inf中start =3然后手工启动能成功。为什么?是否start = 0 时 对象管理器还没有建立\\systemroot目录。
|
|
15楼#
发布于:2005-04-26 11:29
抛两块砖: |
|
16楼#
发布于:2005-05-07 15:39
我发现这个程序和容易导致内核堆栈的溢出,局部变量占用空间太多
kd> !thread THREAD ffb71800 Cid 0418.041c Teb: 7ffde000 Win32Thread: e1a05a70 RUNNING on processor 0 IRP List: 80d6f9a8: (0006,0190) Flags: 00000884 Mdl: 00000000 ffb71008: (0006,0190) Flags: 00000884 Mdl: 00000000 Not impersonating DeviceMap e1a9c9a0 Owning Process ffb74570 Wait Start TickCount 20348 Elapsed Ticks: 0 Context Switch Count 1583 LargeStack UserTime 00:00:00.0031 KernelTime 00:00:01.0000 Start Address kernel32!BaseProcessStartThunk (0x77e5eb41) Win32 Start Address Unknown_Module_4ad00000 (0x4ad0a596) Stack Init f94c2000 Current f94bfac8 Base f94c2000 Limit f94bf000 Call 0 Priority 8 BasePriority 8 PriorityDecrement 0 DecrementCount 16 ChildEBP RetAddr Args to Child 80539d2c 805236a5 00000003 00000000 0000007f nt!RtlpBreakWithStatusInstruction (FPO: [1,0,0]) 80539d78 80523dea 00000003 00000000 00000000 nt!KiBugCheckDebugBreak+0x19 (FPO: [Non-Fpo]) 8053a140 804fd1bb 0000007f 00000008 80042000 nt!KeBugCheck2+0x43c (FPO: [Non-Fpo]) 8053a160 804d7b8f 0000007f 00000008 80042000 nt!KeBugCheckEx+0x19 (FPO: [Non-Fpo]) 8053a160 80537ab1 0000007f 00000008 80042000 nt!KiTrap08+0x52 (FPO: TaskGate 28:0) ////堆栈已经溢出!!!!!!!!!!!! f94bf04c 8052034c 00000000 0000001c 73725346 nt!ExAllocatePoolWithTag+0x11 (FPO: [Non-Fpo]) f94bf064 805203bd ffbb7e78 f94bf0a0 f938905e nt!FsRtlpPostStackOverflow+0x13 (FPO: [Non-Fpo]) f94bf078 f9388f6b ffbb7e78 f94bf0a0 f938905e nt!FsRtlPostStackOverflow+0x13 (FPO: [3,0,0]) f94bf0cc f93046fc ffbb7e78 80d5e5a8 e18451b8 Fastfat!FatPostStackOverflowRead+0x179 (FPO: [Non-Fpo]) (CONV: stdcall) [n:\\winddk\\2600\\src\\filesys\\fastfat\\read.c @ 380] f94bf140 804ed04f ffba0750 80d5e5a8 ffb6e550 Fastfat!FatFsdRead+0x373 (FPO: [Non-Fpo]) (CONV: stdcall) [n:\\winddk\\2600\\src\\filesys\\fastfat\\read.c @ 238] f94bf150 f991e0e9 80e45170 ffb6e550 00000001 nt!IopfCallDriver+0x31 (FPO: [0,0,1]) f94bf9c8 804ed04f ffbda248 80d5e5a8 00000000 efs!SfRead+0x2b5 (FPO: [Non-Fpo]) (CONV: stdcall) [i:\\winddk\\2600\\src\\filesys\\filter\\sfilter\\efs.c @ 2578] f94bf9d8 804e98bb 00000000 80eb4440 00000000 nt!IopfCallDriver+0x31 (FPO: [0,0,1]) f94bf9ec 804e98db ffbda248 80eb4403 80eb4458 nt!IopPageReadInternal+0xf2 (FPO: [Non-Fpo]) f94bfa0c 804e9972 80e45170 80eb4478 80eb4458 nt!IoPageRead+0x19 (FPO: [Non-Fpo]) f94bfa7c 804efd12 80eb4440 cb240000 c032c900 nt!MiDispatchFault+0x270 (FPO: [Non-Fpo]) f94bfacc 804d8a5b 00000000 cb240000 00000000 nt!MmAccessFault+0x5b7 (FPO: [Non-Fpo]) f94bfacc 80573c30 00000000 cb240000 00000000 nt!KiTrap0E+0xb8 (FPO: [0,0] TrapFrame @ f94bfae4) f94bfba4 f931c470 80e45170 f94bfbf4 00000200 nt!CcMapData+0xef (FPO: [Non-Fpo]) f94bfbfc f931deaf ffba63a8 e18451b8 00000000 Fastfat!FatReadDirectoryFile+0x6b8 (FPO: [Non-Fpo]) (CONV: stdcall) [n:\\winddk\\2600\\src\\filesys\\fastfat\\cachesup.c @ 386] f94bfd30 f932b35b ffba63a8 e18451b8 f94bfeac Fastfat!FatLocateDirent+0x777 (FPO: [Non-Fpo]) (CONV: stdcall) [n:\\winddk\\2600\\src\\filesys\\fastfat\\dirsup.c @ 1235] f94c0048 f93187e4 ffba63a8 80d6f9a8 80d6f9b8 Fastfat!FatCommonCreate+0x2ab5 (FPO: [Non-Fpo]) (CONV: stdcall) [n:\\winddk\\2600\\src\\filesys\\fastfat\\create.c @ 1363] f94c00b4 804ed04f ffba0750 80d6f9a8 ffb6e550 Fastfat!FatFsdCreate+0x154 (FPO: [Non-Fpo]) (CONV: stdcall) [n:\\winddk\\2600\\src\\filesys\\fastfat\\create.c @ 296] f94c00c4 f99234c8 00000000 00000001 00000000 nt!IopfCallDriver+0x31 (FPO: [0,0,1]) f94c0950 804ed04f ffbda248 80d6f9a8 80d6f9a8 efs!SfCreate+0x2e3 (FPO: [Non-Fpo]) (CONV: stdcall) [i:\\winddk\\2600\\src\\filesys\\filter\\sfilter\\efs.c @ 2233] f94c0960 80575663 ffb6f568 ffbbef3c f94c0b08 nt!IopfCallDriver+0x31 (FPO: [0,0,1]) f94c0a44 8057169c ffb6f580 00000000 ffbbee98 nt!IopParseDevice+0xa17 f94c0ac8 80573d6b 00000000 f94c0b08 00000240 nt!ObpLookupObjectName+0x56a (FPO: [Non-Fpo]) f94c0b1c 80575a10 00000000 00000000 8064f000 nt!ObOpenObjectByName+0xe9 (FPO: [Non-Fpo]) f94c0b98 80575ac1 f94c0d38 00100001 f94c0d18 nt!IopCreateFile+0x407 (FPO: [Non-Fpo]) f94c0be0 80579f0d f94c0d38 00100001 f94c0d18 nt!IoCreateFile+0x36 (FPO: [Non-Fpo]) f94c0c20 804d5e91 f94c0d38 00100001 f94c0d18 nt!NtCreateFile+0x2e (FPO: [Non-Fpo]) f94c0c20 8050c15b f94c0d38 00100001 f94c0d18 nt!KiSystemService+0xc4 (FPO: [0,0] TrapFrame @ f94c0c54) f94c0cc4 f99211b9 f94c0d38 00100001 f94c0d18 nt!ZwCreateFile+0x11 (FPO: [11,0,0]) f94c113c f991d8b8 ffbda248 e107e694 f94c1173 efs!SfIsEncryptFlagExist+0x21b (FPO: [Non-Fpo]) (CONV: stdcall) [i:\\winddk\\2600\\src\\filesys\\filter\\sfilter\\efs.c @ 8122] f94c1178 f99236ea f94c19cc 00000001 00000001 efs!SfPostCreateWorker+0x92 (FPO: [Non-Fpo]) (CONV: stdcall) [i:\\winddk\\2600\\src\\filesys\\filter\\sfilter\\efs.c @ 2349] f94c1a08 804ed04f ffbda248 ffb71008 ffb71008 efs!SfCreate+0x505 (FPO: [Non-Fpo]) (CONV: stdcall) [i:\\winddk\\2600\\src\\filesys\\filter\\sfilter\\efs.c @ 2309] f94c1a18 80575663 ffb6f568 ffbb331c f94c1bc0 nt!IopfCallDriver+0x31 (FPO: [0,0,1]) f94c1afc 8057169c ffb6f580 00000000 ffbb3278 nt!IopParseDevice+0xa17 f94c1b80 80573d6b 00000000 f94c1bc0 00000040 nt!ObpLookupObjectName+0x56a (FPO: [Non-Fpo]) [编辑 - 5/7/05 by robin12] |
|
17楼#
发布于:2005-05-08 11:51
FILE_CONTEXT 结构太大了,特别是Name,应该改为动态分配,在我的64位环境下编译报错, :o
|
|
18楼#
发布于:2005-05-09 09:48
我的系统为winxp,在inf中start = 0,type = 2,在DriverEntry中说无法找到文件\\systemroot\\xefs.dat,我的xefs.dat放在c:\\windows目录下,当我把inf中start =3然后手工启动能成功。为什么?是否start = 0 时 对象管理器还没有建立\\systemroot目录。 start=0这个时候就是认不出systemroot的,因为这个时候还没有文件系统 start=1之后的应该都可以了 |
|
19楼#
发布于:2005-05-09 10:21
下面是SfDirectoryControl的片断,请教一下
Status = SfForwardIrpSyncronously(DevExt->AttachedToDeviceObject, Irp); while (TRUE) { if (!NT_SUCCESS(Status)) break; Length = IrpSp->Parameters.QueryDirectory.Length; NewLength = Length; CurPos = 0; DirInfo = (PFILE_BOTH_DIR_INFORMATION) Irp->UserBuffer; PreDirInfo = DirInfo; // // There is no entry, so just complete the request // if (Length == 0) break; // // Sanity check // if ((!DirInfo) || (DirInfo->NextEntryOffset > Length)) break; do { Offset = DirInfo->NextEntryOffset; 注SF_ENCRYPT_INFO_DIR为L\"System Encrypt Information\",如果DirInfo->FileName为SF_ENCRYPT_INFO_DIR的一部分如Syste,比较也成功 if ((DirInfo->FileNameLength > 0) && (_wcsnicmp(DirInfo->FileName, SF_ENCRYPT_INFO_DIR, DirInfo->FileNameLength / sizeof(WCHAR)) == 0)) { if (0 == Offset) // The last one { PreDirInfo->NextEntryOffset = 0; NewLength = CurPos; } else { if (PreDirInfo != DirInfo) PreDirInfo->NextEntryOffset += DirInfo->NextEntryOffset; else // The first one RtlMoveMemory((PUCHAR) DirInfo, (PUCHAR) DirInfo + Offset, Length - CurPos - Offset); NewLength -= Offset; } break; } CurPos += Offset; PreDirInfo = DirInfo; DirInfo = (PFILE_BOTH_DIR_INFORMATION) ((PUCHAR) DirInfo + Offset); } while (0 != Offset); if (0 == NewLength) // All entry is filtered { Status = SfForwardIrpSyncronously(DevExt->AttachedToDeviceObject, Irp); // // If no entry returned, just complete the request, // else we must continue to filter // if (0 == Irp->IoStatus.Information) break; } else { Irp->IoStatus.Information = NewLength; break; } // continue to filter } IoCompleteRequest(Irp, IO_NO_INCREMENT); return Status; 1、对于last one,即if (0 == Offset) // The last one,如果有多个entry,好像刚刚好去掉最后一个,但是如果是only one,那就会对irp不做修改的,又发到底下去,回来后还不是同样处理,这个我想不太明白 2、对中间的,把nextentryoffset修改了,但为什么NewLength也减了呢?实际上UserBuffer的长度没有变啊,想想如果我调ZwQueryDirectoryFile,根据IoStatusBlock的Information作为判断条件(之一)来遍历FileInformation,启不是把最后的entry的信息给丢了? 3、然后是对first one的处理,暂不谈又是first又是last的情况,RtlMoveMemory((PUCHAR) DirInfo, (PUCHAR) DirInfo + Offset, Length - CurPos - Offset);为什么把CurPos也算上呢? 最主要的,就是把irp再发下去的做法,能解释一下吗?早上有点晕,就不再想了 :D :P 把irp在发下去一次,有些明白了,就是那这次的结果丢弃,再查一遍,如果有继续丢,直到底下说没有了没有了 :D [编辑 - 5/9/05 by arthurtu] |
|
上一页
下一页