一、NtQueryDirectoryFile函数功能(NT系列函数)

NtQueryDirectoryFile函数:在一个给定的文件句柄,该函数返回该文件句柄指定目录下的不同文件的各种信息。

根据传入的文件句柄参数fileHandle,返回句柄所表示的目录中的不同文件的信息。

NTSTATUS ZwQueryDirectoryFile(
_In_      HANDLE FileHandle,
_In_opt_  HANDLE Event,
_In_opt_  PIO_APC_ROUTINE ApcRoutine,
_In_opt_  PVOID ApcContext,
_Out_     PIO_STATUS_BLOCK IoStatusBlock,
_Out_     PVOID FileInformation,
_In_      ULONG Length,
_In_      FILE_INFORMATION_CLASS FileInformationClass,
_In_      BOOLEAN ReturnSingleEntry,
_In_opt_  PUNICODE_STRING FileName,
_In_      BOOLEAN RestartScan
);

下面就简单说几个重要的参数:

1.FileHandle [in]文件句柄

ZwCreateFile或者ZwOpenFile返回的句柄。

A handle returned by ZwCreateFile or ZwOpenFile for the file object that represents the directory for which information is being requested. The file object must have been opened for asynchronous I/O if the caller specifies a non-NULL value for Event or ApcRoutine.

7.FileInformation [out]

FileInformation是一个指向一个缓冲区的指针。该缓冲区存储关于文件的信息。信息的结构由FileInformationClassparameter定义。就由最后一个参数FileInformationClass决定。所以要先判断这个参数的值是什么呀。

A pointer to a buffer that receives the desired information about the file. The structure of the information returned in the buffer is defined by the FileInformationClassparameter.

8.Length [in] 长度,代表缓冲区的size,以字节大小记录。

The size, in bytes, of the buffer pointed to by FileInformation. The caller should set this parameter according to the given FileInformationClass.

9.FileInformationClass [in]文件信息类

返回的关于在一个目录中的文件的信息类型。它的取值是下表中的一个。

The type of information to be returned about files in the directory. One of the following.

Value Meaning

FileBothDirectoryInformation

Return a FILE_BOTH_DIR_INFORMATION structure for each file.

FileDirectoryInformation

Return a FILE_DIRECTORY_INFORMATION structure for each file.

FileFullDirectoryInformation

Return a FILE_FULL_DIR_INFORMATION structure for each file.

FileIdBothDirectoryInformation

Return a FILE_ID_BOTH_DIR_INFORMATION structure for each file.

FileIdFullDirectoryInformation

Return a FILE_ID_FULL_DIR_INFORMATION structure for each file.

FileNamesInformation

Return a FILE_NAMES_INFORMATION structure for each file.

FileObjectIdInformation

Return a FILE_OBJECTID_INFORMATION structure for each file. This information class is valid only for NTFS volumes on Windows 2000 and later versions of Windows.

FileReparsePointInformation

Return a single FILE_REPARSE_POINT_INFORMATION structure for the directory.

ReturnSingleEntry [in]

Set to TRUE if only a single entry should be returned, FALSE otherwise. If this parameter is TRUEZwQueryDirectoryFile returns only the first entry that is found.

FileName [in, optional]

An optional pointer to a caller-allocated Unicode string containing the name of a file (or multiple files, if wildcards are used) within the directory specified by FileHandle. This parameter is optional and can be NULL.

If FileName is not NULL, only files whose names match the FileName string are included in the directory scan. If FileName is NULL, all files are included.

The FileName is used as a search expression and is captured on the very first call to ZwQueryDirectoryFile for a given handle. Subsequent calls toZwQueryDirectoryFile will use the search expression set in the first call. The FileName parameter passed to subsequent calls will be ignored.

RestartScan [in]

Set to TRUE if the scan is to start at the first entry in the directory. Set to FALSE if resuming the scan from a previous call.

When the ZwQueryDirectoryFile routine is called for a particular handle, the RestartScan parameter is treated as if it were set to TRUE, regardless of its value. On subsequent ZwQueryDirectoryFile calls, the value of the RestartScan parameter is honored.

2.hook  NtQueryDirectoryFile()实现对文件的隐藏

 #include "ntddk.h"

 #pragma pack(1)
typedef struct ServiceDescriptorEntry {
unsigned int *ServiceTableBase;
unsigned int *ServiceCounterTableBase;
unsigned int NumberOfServices;
unsigned char *ParamTableBase;
} ServiceDescriptorTableEntry_t, *PServiceDescriptorTableEntry_t; typedef struct _FILE_BOTH_DIR_INFORMATION {
ULONG NextEntryOffset;
ULONG FileIndex;
LARGE_INTEGER CreationTime;
LARGE_INTEGER LastAccessTime;
LARGE_INTEGER LastWriteTime;
LARGE_INTEGER ChangeTime;
LARGE_INTEGER EndOfFile;
LARGE_INTEGER AllocationSize;
ULONG FileAttributes;
ULONG FileNameLength;
ULONG EaSize;
CCHAR ShortNameLength;
WCHAR ShortName[];
WCHAR FileName[];
} FILE_BOTH_DIR_INFORMATION, *PFILE_BOTH_DIR_INFORMATION; // Our System Call Table
PVOID* NewSystemCallTable; // Our Memory Descriptor List
PMDL pMyMDL; #define HOOK_INDEX(function2hook) *(PULONG)((PUCHAR)function2hook+1) #define HOOK(functionName, newPointer2Function, oldPointer2Function ) \
oldPointer2Function = (PVOID) InterlockedExchange( (PLONG) &NewSystemCallTable[HOOK_INDEX(functionName)], (LONG) newPointer2Function) #define UNHOOK(functionName, oldPointer2Function) \
InterlockedExchange( (PLONG) &NewSystemCallTable[HOOK_INDEX(functionName)], (LONG) oldPointer2Function) NTSYSAPI
NTSTATUS
NTAPI ZwQueryDirectoryFile(
IN HANDLE FileHandle,
IN HANDLE Event OPTIONAL,
IN PIO_APC_ROUTINE ApcRoutine OPTIONAL,
IN PVOID ApcContext OPTIONAL,
OUT PIO_STATUS_BLOCK IoStatusBlock,
OUT PVOID FileInformation,
IN ULONG Length,
IN FILE_INFORMATION_CLASS FileInformationClass,
IN BOOLEAN ReturnSingleEntry,
IN PUNICODE_STRING FileName OPTIONAL,
IN BOOLEAN RestartScan
); typedef NTSTATUS (__stdcall* ZWQUERYDIRECTORYFILE)(
__in HANDLE FileHandle,
__in_opt HANDLE Event OPTIONAL,
__in_opt PIO_APC_ROUTINE ApcRoutine OPTIONAL,
__in_opt PVOID ApcContext OPTIONAL,
__out PIO_STATUS_BLOCK IoStatusBlock,
__out PVOID FileInformation,
__in ULONG Length,
__in FILE_INFORMATION_CLASS FileInformationClass,
__in BOOLEAN ReturnSingleEntry,
__in PUNICODE_STRING FileName OPTIONAL,
__in BOOLEAN RestartScan
); int ZwQueryDirectoryFileIndex;//作为ZwQueryDirectoryFileIndex在ssdt索引地址中的相对路径。 NTSTATUS __stdcall NewNtQueryDirectoryFile(
__in HANDLE FileHandle,
__in_opt HANDLE Event ,
__in_opt PIO_APC_ROUTINE ApcRoutine,
__in_opt PVOID ApcContext OPTIONAL,
__out PIO_STATUS_BLOCK IoStatusBlock,
__out PVOID FileInformation,
__in ULONG Length,
__in FILE_INFORMATION_CLASS FileInformationClass,
__in BOOLEAN ReturnSingleEntry,
__in PUNICODE_STRING FileName,
__in BOOLEAN RestartScan
)
{
NTSTATUS status;
ANSI_STRING ansiFileName,ansiDirName,HideDirFile;
UNICODE_STRING uniFileName;
ZWQUERYDIRECTORYFILE OldZwQueryDirectoryFile;
int ;
//测试C盘中的123.txt是否可以被隐藏。
RtlInitAnsiString(&HideDirFile,"123.txt");
KdPrint(("hide: NewZwQueryDirectoryFile called.")); if(MmIsAddressValidEx(OriginalServiceDescriptorTable->ServiceTable[ZwQueryDirectoryFileIndex]))//判断函数的地址是否有效
{
OldZwQueryDirectoryFile=OriginalServiceDescriptorTable->ServiceTable[ZwQueryDirectoryFileIndex];
}
else
OldZwQueryDirectoryFile=KeServiceDescriptorTable->ServiceTable[ZwQueryDirectoryFileIndex]; status = OldZwQueryDirectoryFile (
FileHandle,
Event,
ApcRoutine,
ApcContext,
IoStatusBlock,
FileInformation,
Length,
FileInformationClass,
ReturnSingleEntry,
FileName,
RestartScan);
if()
//这部分是隐藏文件的核心部分
if(NT_SUCCESS(status)&&FileInformationClass==FileBothDirectoryInformation)
{
PFILE_BOTH_DIR_INFORMATION pFileInfo;
PFILE_BOTH_DIR_INFORMATION pLastFileInfo;
BOOLEAN bLastOne=FALSE;
pFileInfo = (PFILE_BOTH_DIR_INFORMATION)FileInformation;
pLastFileInfo = NULL;
do
{
bLastOne = !( pFileInfo->NextEntryOffset );
RtlInitUnicodeString(&uniFileName,pFileInfo->FileName); RtlUnicodeStringToAnsiString(&ansiFileName,&uniFileName,TRUE);
RtlUnicodeStringToAnsiString(&ansiDirName,&uniFileName,TRUE); if( RtlCompareMemory(ansiFileName.Buffer,HideDirFile.Buffer,HideDirFile.Length ) == HideDirFile.Length)
{
if(bLastOne)
{
pLastFileInfo->NextEntryOffset = ;
break;
}
else //指针往后移动
{
int iPos = ((ULONG)pFileInfo) - (ULONG)FileInformation;
int iLeft = (DWORD)Length - iPos - pFileInfo->NextEntryOffset;
RtlCopyMemory( (PVOID)pFileInfo, (PVOID)( (char *)pFileInfo + pFileInfo->NextEntryOffset ), (DWORD)iLeft );
continue;
}
}
pLastFileInfo = pFileInfo;
pFileInfo = (PFILE_BOTH_DIR_INFORMATION)((char *)pFileInfo + pFileInfo->NextEntryOffset);
}while(!bLastOne);
RtlFreeAnsiString(&ansiDirName);
RtlFreeAnsiString(&ansiFileName);
}
goto _FunctionRet; _FunctionRet: return status;
161
}

其中,指针类型变量强化转换为ULONG型变量。

(ULONG)pFileInfo ;//即把地址转化为ULONG型变量。

(ULONG) FileInformation;

那么int  iPos=((ULONG)pFileInfo)- (ULONG) FileInformation;

得到的就是地址偏移值。

int  iLeft=(DWORD)Length-iPos-pFileInfo->NextEntryOffset;

3.上述代码,采用WDK编译。然后再整合到MFC开发的用户界面程序中。

4.在Vmware虚拟机中,操作系统是Windows XP,做测试。

5.发现在点击XX.exe之后,C盘中的123.txt就消失不见。说明对123.txt的文件隐藏成功。

hook NtQueryDirectoryFile实现文件隐藏的更多相关文章

  1. Inline Hook NtQueryDirectoryFile

    Inline Hook NtQueryDirectoryFile 首先声明这个是菜鸟—我的学习日记,不是什么高深文章,高手们慎看. 都总是发一些已经过时的文章真不好意思,几个月以来沉迷于游戏也是时候反 ...

  2. 默默的发现在网上找到的hook NtQueryDirectoryFile......

    默默的发现在网上找到的hook  NtQueryDirectoryFile...... hook  NtQueryDirectoryFile是为了实现文件隐藏,然后就发现在网上发现的代码版本似乎同一个 ...

  3. tp5.1入口文件隐藏

    修改.htaccess文件 <IfModule mod_rewrite.c> Options +FollowSymlinks -Multiviews RewriteEngine On Re ...

  4. Webshell清除-解决驱动级文件隐藏挂马

    Webshell清除-解决驱动级文件隐藏挂马

  5. FlashFXP链接到服务器上,如果www目录下的文件隐藏

    FlashFXP链接到服务器上,如果www目录下的文件隐藏,那么请按照如下设置,就可以显示隐藏的文件了 [站点]->[站点管理器]->选项,然后按照如下设置:

  6. mac 如何让文件隐藏

    1.首先,要确保知道目标文件或文件夹的名称,你不把这个名称正确地输入到终端中,Mac也无能为力啊... 2.打开终端,输入chflags hidden 3.在上述代码的后面加上该文件夹的路径,但是注意 ...

  7. 如何把.rar文件隐藏在一个图片内

    首先假设我们要隐藏的.rar文件叫a.rar,图片叫a.jpg.先把他俩放到同一个目录下,然后通过“cmd”进入windows命令行,进入目标目录下,使用以下命令进行隐藏: copy/B  a.jpg ...

  8. Ring3下Hook NtQueryDirectoryFile隐藏文件

    NTSTATUS WINAPI Hook_NtQueryDirectoryFile(IN HANDLE FileHandle,IN HANDLE Event OPTIONAL,IN PIO_APC_R ...

  9. API HOOK和PE文件的关系

    api hook技术的难点,并不在于hook技术,而在于对PE结构的学习和理解.如何修改api函数的入口地址?这就需要学习pe可执行文件(.exe,.dll等)如何被系统映射到进程空间中,这需要学习p ...

随机推荐

  1. Microsoft Office 2013 (64位) 免费完整版(安装 + 激活)

    Microsoft Office 2013(Office 15)是微软的新一代Office办公软件,全面采用Metro界面.Microsoft Office 2013官方下载(Office2013专业 ...

  2. 实现一个scnprinf

    #include <stdio.h> #include <stdarg.h> /* 该函数ret = min(size, 实际写入长度) - 1,即ret永远小于size * ...

  3. Linq:从List列表中查询数据(Where查询)

    获取List<Customer> customerList的函数见:http://www.cnblogs.com/yf2011/p/3369927.html 输出List中Berlin城市 ...

  4. LOJ2823 「BalticOI 2014 Day 1」三个朋友

    题意 给定一个字符串 S,先将字符串 S 复制一次(变成双倍快乐),得到字符串 T,然后在 T 中插入一个字符,得到字符串 U. 给出字符串 U,重新构造出字符串 S. 所有字符串只包含大写英文字母. ...

  5. 十八、python沉淀之路--生成器

    一.生成器 生成器总结:语法上和函数类似:生成器函数和常规函数几乎是一样的.他们都是使用def语句进行定义,差别在于生成器使用yield语句返回一个值,而常规函数使用return语句返回一个值.自动实 ...

  6. jenkins 重置密码

      说明 最近在折腾jenkins,配置用户权限时点错了,选择了安全矩阵后没有添加用户,就保存配置了,然后就报错了,提示没有Overall/Read权限.还有另外一个问题,用户的密码忘记了怎么办? 一 ...

  7. numpy之初识ndarray

    Numpy ndarray numpy的最重要特点就是其N维数组对象(ndarray). ndarray的可以对整块数据执行数学运算,语法与标量元素的元素的运算一致. 如: import numpy ...

  8. java代码从键盘输入n的值,计算1+1/2+1/3+...+1/n的值,,

    总结:谢谢陈勇老师.很棒的指导.超有爱. 总是不思考++++如内存的分析.堆和栈.堆内存里对象,字符串,栈里基本数据类型 来龙去脉,属性方法的调用,都不是很理解.... package com.c2; ...

  9. 类的特殊成员方法,类的起源type, metaclass

    1.__doc__表示类的描述信息 2. __module__ 和  __class__  __module__ 表示当前操作的对象在那个模块 __class__     表示当前操作的对象的类是什么 ...

  10. virsh使用qemu+tcp访问远程libvirtd

    因为ssh的不能访问 所以使用tcp进行对远程libvirtd进行连接访问,例如 virsh -c qemu+tcp://example.com/system 修改文件vim /etc/sysconf ...