📄 关于文件夹地隐藏.txt
字号:
总结:关于文件夹地隐藏。
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一个这个贴子
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -