NTFS文件系统实现了多文件流特性,NTFS环境一个文件默认使用的是未命名的文件流,同时可创建其他命名的文件流,windows资源管理器默认不显示出文件的命名文件流,这些命名的文件流在功能上和默认使用的未命名文件流一致,甚至可以用来启动程序。本文将带你了解NTFS多文件流的实现原理。
我们先介绍一下NTFS文件流的基本特性,大家可以到这里下载我开发的用来创建文件流的工具FileStreams.exe,这个是开源的控制台程序,支持创建、枚举、读写、执行文件流功能。我们首先在F:\test文件夹(NTFS)创建1.txt文件,文件内容为1
然后,我们再用FileStream创建几个命名的文件流:
这几个新建的文件流没有数据,我们使用FileStream.exe写点数据进去:
在test2文件流里面写入test2data数据,因为写入的是unicode,所以可以看到test2的文件流大小是18个字节。
在testExe文件流,我们把FileStream.exe写入到文件流中。
下面我们使用FileStream.exe的dump功能dmp出文件流数据来验证一下:
可以看到test2data和MZ头。
最后我们再使用FileStream的launch功能来执行一下testExe这个文件流。
可以看到文件流执行成功,输出和默认执行FileStream一致。
OK,在了解了NTFS文件流特性以后,我在来介绍NTFS文件流的实现原理。在NTFS下,像文件大小,文件创建时间,文件修改时间,文件名,文件内容等被组织成属性来存放,NTFS定义了一序列的文件属性:
属性 | 描述 |
$STANDARD_INFORMATION(10) | 标准属性,包含文件长度创建时间等。 |
$FILE_NAME (30) | 文件名属性,包含文件名 |
$DATA(80) | 文件数据 |
…… | …… |
详细说明可以搜索NTFS3G,这些属性统一组织在NTFS的MFT(Master File Table)上,每个MFT大小1024个字节,MFT的$DATA属性即是前面提到的文件流,通常来说包含多个不同名字的$DATA属性即说明该文件存在多个文件流,下图是winhex打开1.txt定位到1.txt的MFT,我们实际看一下NTFS是如何组织的:
可以看到文件流test2的数据是直接存放在MFT上,因为test2的数据小,而testExe的数据则没有明显看出来,因为testExe数据比较大,MFT里面存放的是簇信息。