阅读:4372回复:13
总结:关于文件夹地隐藏。
1、返回的列表中只有一项并且这一项就是需要隐藏的项同时ReturnSingleEntry又为TRUE时怎么办?
1)、Coolice采用重新调用ZwQueryDirectoryFile()的方法,不过这种方法需要考虑重入问题。 2)、VCMFC通过对根目录进行特别处理来实现隐藏,不过他没有给出代码,具体方法我也不清楚。 还有另外一种的方法,那就是重新构造IRP查询。Coolice也提到了这种方法,不过他也没有代码。OK,下面就是这种方法的代码: // // 执行隐藏操作 // bool bNeedReQuery; bool bReturnSingleEntry; bReturnSingleEntry = ((IrpStack->Flags & SL_RETURN_SINGLE_ENTRY) == SL_RETURN_SINGLE_ENTRY ); while(true) { // // 在SfHideFile()中判断是否符合上述条件,如果符合则设置bNeedReQuery为TRUE然后直接返回。 // Status = SfHideFile( &FullDirName, Irp->UserBuffer, IrpStack->Parameters.QueryFile.Length, bReturnSingleEntry, &bNeedReQuery ); if(!bNeedReQuery) { break; } // // 如果欲隐藏的文件恰好是第一项,这时候只能通过重新查询来实现隐藏。 // Status = SfReissueIrp(Irp,DeviceObject->StackSize + 2,DevExt); if(Status != STATUS_SUCCESS) { break; } } //--------------------------------------------------------------------------- // // 构造新的IRP来继续查询 // NTSTATUS SfReissueIrp( IN PIRP Irp, IN int StackSize, IN PSFILTER_DEVICE_EXTENSION DevExt ) { NTSTATUS Status; PIO_STACK_LOCATION IrpStack; PIRP NewIrp; PIO_STACK_LOCATION NextIrpStack; NewIrp = IoAllocateIrp(StackSize,false); if(NewIrp != NULL) { // // 设置同步事件 // KEVENT WaitEvent; KeInitializeEvent(&WaitEvent,SynchronizationEvent,false); // // 设置IRP // NewIrp->UserEvent = NULL; NewIrp->AssociatedIrp.SystemBuffer = Irp->AssociatedIrp.SystemBuffer; NewIrp->UserBuffer = Irp->UserBuffer; NewIrp->Tail.Overlay.Thread = PsGetCurrentThread(); NewIrp->RequestorMode = Irp->RequestorMode; NewIrp->Flags = Irp->Flags & (~IRP_ASSOCIATED_IRP); // // 设置IO堆栈 // IrpStack = IoGetCurrentIrpStackLocation(Irp); NextIrpStack = IoGetNextIrpStackLocation(NewIrp); *NextIrpStack = *IrpStack; NextIrpStack->CompletionRoutine = SfDirectoryControlCompletion; NextIrpStack->Context = &WaitEvent; // // 发送新的IRP到下层FSD // Status = IoCallDriver(DevExt->AttachedToDeviceObject,NewIrp); if(Status == STATUS_PENDING) { KeWaitForSingleObject(&WaitEvent, Executive, KernelMode, FALSE, NULL); Status = NewIrp->IoStatus.Status; } // // 释放IRP // IoFreeIrp(NewIrp); } else { Status = STATUS_INSUFFICIENT_RESOURCES; } return Status; } 2、那就是要隐藏的文件在返回缓冲中不是第一项时怎么隐藏? 我使用“隐藏”来搜索了本分论坛的贴子,在有关隐藏文件夹地讨论中,发现几乎99.9999%的FSFD Writer都使用与VCMFC相同的方法,那就是不停的Move Memory …:),实际上除了第一项需要Move以外,后面所有项地隐藏都是不需要Move的,直接更改一个ULONG值就可以了,一律Move只会对系统性能产生影响。虽然现在CPU已经是2、3、4G了(Sorry,具体是多少不清楚),不过追求最好的性能应该是一个程序员最基本的追求吧? // // 1、第一项匹配 // if(...) { } // // 2:最后一项匹配 // else if(pDirInfo->NextEntryOffset == 0) { pPrevDirInfo->NextEntryOffset = 0; } // // 3:中间项匹配 // else { // // 隐藏中间项目时不需要调整pPrevDirInfo的值 // bMustAdjustPrevDirInfo = false; pPrevDirInfo->NextEntryOffset += pDirInfo->NextEntryOffset; } // // ........ // Do something here // // // 是否需要调整pPrevDirInfo的值?(隐藏中间项目时不需要) // if(bMustAdjustPrevDirInfo) { pPrevDirInfo = pDirInfo; } pDirInfo = (PFILE_BOTH_DIR_INFORMATION)((PUCHAR)pDirInfo + pDirInfo->NextEntryOffset); 3、最最重要的一点,那就是我上面的贴出的代码是不能直接Copy & Paste & Compile的,其中道理我想你自己应该明白。 2004-1-30开始学习文件系统驱动开发,直接着手的第一个问题就是把以前通过Hook ZwQueryDirectoryFile()来实现文件夹隐藏的驱动重新使用FSFD来实现。说来惭愧,使用了8天时间才彻底搞定。 题外话:SFilter在2K上面也是可以动态加载的,使用一些Trick就可以了。如果老是只听MS的那些工程师的话,那玩驱动编程岂不是少了许多乐趣? 最后,如果你认为我的总结对你还有一个点帮助,就请up一个这个贴子 [编辑 - 2/7/04 by slwqw] [编辑 - 2/7/04 by slwqw] |
|
沙发#
发布于:2004-02-08 10:39
ding
|
|
板凳#
发布于:2004-02-09 09:20
不错,希望老兄能多一些这样的总结经验。。。。。。
|
|
|
地板#
发布于:2004-02-09 09:29
不需要重新构造一个irp,只需要把原来的irp往下传就可以了
|
|
地下室#
发布于:2004-02-09 09:37
第2点比较好。
up,up,up. |
|
|
5楼#
发布于:2004-02-09 10:03
不需要重新构造一个irp,只需要把原来的irp往下传就可以了 我试过了这种方法,结果产生了MULTIPLE_REQUEST_COMPLETION BugCheck,也就是说IRP被完成了两次。如果要解决这个问题那还得做别地处理。不如重新构造一个IRP方便,不用考虑那么多。 |
|
6楼#
发布于:2004-02-11 12:49
我以前是用move.
你的方法是不是参考rootkit的hide process ?,它也是修改其Offset,是个好方法。 |
|
7楼#
发布于:2004-02-11 12:50
其实最大的损耗不在这里,在匹配规则表的时间,那将是最大的地方。
|
|
8楼#
发布于:2004-02-11 18:06
其实最大的损耗不在这里,在匹配规则表的时间,那将是最大的地方。 同意! 假设一个目录下面存在50项,需要隐藏其中的4项,最坏情况下需要匹配“49 + 48 + 47 + 46”次,实在受不了 :( :( :( 如果待隐藏的目录或者文件中“不包含通配符”,则使用多模式字符串匹配算法,可以避免这个问题,最多只比较50次即可。 只是不使用通配符又不太现实,烦啊... |
|
9楼#
发布于:2008-08-25 19:47
感觉很抽象,略懂
|
|
10楼#
发布于:2008-08-28 20:06
MULTIPLE_REQUEST_COMPLETION
这个是完成例程的返回值没有处理正确引起的。 |
|
|
11楼#
发布于:2008-09-02 09:48
学习了
|
|
|
12楼#
发布于:2008-09-03 13:54
过几天我把我的代码贴出来,今天出差
|
|
13楼#
发布于:2009-01-21 22:29
如果一个跟目录下所有文件都要隐藏,楼主的方法不行。
实际上最简单的办法就是不用建立IRP,直接把当前的IRP做个循环多CALL几次就可以了。 |
|
|