驱动开发:内核遍历文件或目录
在笔者前一篇文章《内核文件读写系列函数》
简单的介绍了内核中如何对文件进行基本的读写操作,本章我们将实现内核下遍历文件或目录这一功能,该功能的实现需要依赖于ZwQueryDirectoryFile
这个内核API函数来实现,该函数可返回给定文件句柄指定的目录中文件的各种信息,此类信息会保存在PFILE_BOTH_DIR_INFORMATION
结构下,通过遍历该目录即可获取到文件的详细参数,如下将具体分析并实现遍历目录功能。
该功能也是ARK工具的最基本功能,如下图是一款通用ARK工具的文件遍历功能的实现效果;
在概述中提到过,目录遍历的核心是ZwQueryDirectoryFile()
系列函数,该函数可返回给定文件句柄指定的目录中文件的各种信息,其微软官方定义如下;
ZwQueryDirectoryFile是Windows操作系统中的一个系统调用函数,用于查询目录中的文件信息。具体而言,它可以用来枚举一个目录中的所有文件,并返回每个文件的名称、属性、时间戳等信息。
调用ZwQueryDirectoryFile函数需要指定以下参数:
- 目录句柄:表示要查询的目录的句柄,可以通过调用ZwOpenFile函数打开目录获取。
- 文件信息类:表示要返回的文件信息的类型,如文件名、文件大小、文件时间戳等。
- 文件信息缓冲区:表示存放返回文件信息的缓冲区,其大小必须足够大以容纳查询结果。
- 缓冲区大小:表示文件信息缓冲区的大小。
- 是否遍历子目录:指定是否遍历目录中的子目录。
- 文件名匹配模式:指定查询的文件名模式,支持通配符。
- 是否返回长文件名:指定是否返回长文件名。
- 函数执行成功时,将返回STATUS_SUCCESS,同时将文件信息写入文件信息缓冲区中。当返回STATUS_NO_MORE_FILES时,表示目录中没有更多的文件需要枚举。
需要注意的是,使用ZwQueryDirectoryFile函数需要具有足够的权限,并且应该对返回的文件信息进行适当的处理,以避免潜在的安全问题。
NTSYSAPI NTSTATUS ZwQueryDirectoryFile( |
该函数我们需要注意FileInformation
参数,在本例中它被设定为了PFILE_BOTH_DIR_INFORMATION
用于存储当前节点下文件或目录的一些属性,如文件名,文件时间,文件状态等,其次FileInformationClass
参数也是有多种选择的,本例中我们需要遍历文件或目录则设置成FileBothDirectoryInformation
就可以,在循环遍历文件时需要将当前目录.以及上一级目录..排除,而pDir->FileAttributes
则用于判断当前节点是文件还是目录,属性FILE_ATTRIBUTE_DIRECTORY
代表是目录,反之则是文件,实现目录文件遍历完整代码如下所示;
|
编译如上驱动程序并运行,则会输出C:\\Windows
目录下的所有文件和目录,以及创建时间和修改时间,输出效果如下图所示;
你是否会觉得很失望,为什么不是递归枚举,这里为大家解释一下,通常情况下ARK工具并不会在内核层实现目录与文件的递归操作,而是将递归过程搬到了应用层,当用户点击一个新目录时,在应用层只需要拼接新的路径再次发送给驱动程序让其重新遍历一份即可,这样不仅可以提高效率而且还降低了蓝屏的风险,显然在应用层遍历是更合理的。