上一篇文章《FAT32文件系统详解》中作者介绍了FAT32文件系统存储数据的原理,接下来作者就介绍一下NTFS文件系统。NTFS、用过Windows系统的人都知道,它是一个很强大的文件系统,支持的功能很多,存储的原理也很复杂。目前绝大多数Windows用户都是使用NTFS文件系统,它主要以安全性和稳定性而闻名,下面是它的一些主要特点。

安全性高:NTFS支持基于文件或目录的ACL,并且支持加密文件系统(EFS)。

可恢复性:NTFS支持基于原子事务概念的文件恢复,比较符合服务器文件系统的要求。

文件压缩:NTFS支持基于文件或目录的文件压缩,可以很方便的节省磁盘空间。

磁盘配额:NTFS支持磁盘配额,可针对系统中每个用户分配磁盘资源。


分析NTFS文件系统的结构

   当用户将硬盘的一个分区格式化为NTFS分区时,就建立了一个NTFS文件系统。NTFS文件系统同FAT32文件系统一样,也是用“簇”为存储单位,一个文件总是占用一个或多个簇。

NTFS文件系统使用逻辑簇号(LCN)和虚拟簇号(VCN)对分区进行管理。

逻辑簇号:既对分区内的第一个簇到最后一个簇进行编号,NTFS使用逻辑簇号对簇进行定位。

虚拟簇号:既将文件所占用的簇从开头到尾进行编号的,虚拟簇号不要求在物理上是连续的。

NTFS文件系统一共由16个“元文件”构成,它们是在分区格式化时写入到硬盘的隐藏文件(以"$"开头),也是NTFS文件系统的系统信息。

如下表:是NTFS的16个元文件介绍

wKiom1LORnDRR2gkAAONDW1H15k691.jpg

如下:是NTFS文件系统大致的结构图

wKiom1LOSaHj-VliAADHhN92UCo824.jpg


分析NTFS文件系统的元文件

   在此,我们先复习一下前面的文章《MBR分区结构和GPT分区结构》,如果磁盘采用的是MBR分区结构的话,则硬盘的第一个扇区是MBR扇区,MBR扇区中有分区表,可以根据分区表得知分区的起始位置(也就是DBR的位置)。如果磁盘采用的是GPT的分区结构,那么磁盘的第一个扇区应该是MBR保留扇区,第二个扇区应该是GPT头,第三个扇区应该是分区表,从分区表中我就可以找到分区的起始位置(既DBR)。因此,作者后面的内容都是从分区起始位置(既DBR)开始的,而不是磁盘的0号扇区。


由于各元文件的内容太多,作者只分析工作中所用到的,如果读者感兴趣可以自行去阅读相关资料。


1、分析$Boot元文件

   $Boot元文件由分区的第一个扇区(既DBR)和后面的15个扇区(既NTLDR区域)组成,其中DBR由“跳转指令”、“OEM代号”、“BPB”、“引导程序”和“结束标志”组成,这里和FAT32文件系统的DBR一样。下图是一个NTFS文件系统完整的DBR。

wKioL1LOTPmiKKYcAAW3ngzJQaw966.jpg

下面我们分析一下DBR中的各参数

跳转指令:本身占2字节它将程序执行流程跳转到引导程序处。

OEM代号:这部分占8字节,其内容由创建该文件系统的OEM厂商具体安排。

BPB:NTFS文件系统的BPB从DBR的第12个字节开始,占用73字节,记录了有关该文件系统的重要信息,下表中的内容包含了“跳转指令”、“OEM代号”以及“BPB”的参数。

wKioL1LOTvrRGqUBAAItRorG7p4948.jpg

wKiom1LOTwqQ1eS9AAEO0jTqHW4182.jpg

引导程序:DBR的引导程序占用426字节,其负责完成将系统文件NTLDR装入,对于没有安装系统的分区是无效的。

结束标志:DBR的结束标志与MBR,EBR的结束标志相同,为“55 AA”。

分析$MFT元文件

   在NTFS文件系统中,磁盘上的所有数据都是以文件的形式存储,其中包括元文件。每个文件都有一个或多个文件记录,每个文件记录占用两个扇区(既1字节),而$MFT元文件就是专门记录每个文件的文件记录。由于NTFS文件系统是通过$MFT来确定文件在磁盘上的位置以及文件的属性,所以$MFT是非常重要的,$MFT的起始位置在DBR中有描述。$MFT的文件记录在物理上是连续的,并且从0开始编号。$MFT的前16个文件记录总是元文件的,并且顺序是固定不变的,其顺序和表1相同(第一张图片)。

分析文件记录

1、文件记录的结构

文件记录由两部分构成,一部分是文件记录头,另一部分是属性列表,最后结尾是四个“FF”。如下是一个完整的文件记录:

wKioL1LOXNeDLlNmAAUXiGhmlTE208.jpg

分析文件记录头的结构

在同一系统中,文件记录头的长度和具体偏移位置的数据含义是不变的,而属性列表是可变的,其不同的属性有着不同的含义。后文将对属性进行具体分析,先来看看文件记录头的信息。如下表:是文件记录头的相关信息解释。

wKioL1LOXnfhZ5DbAAQwgtEKj5Y171.jpg

分析文件记录属性结构

   在NTFS文件系统中所有与文件相关的数据结构均被认为是属性,包括文件的内容。文件记录是一个与文件相对应的文件属性数据库,它记录了文件的所有属性。每个文件记录中都有多个属性,他们相对独立,有各自的类型和名称。每个属性都由两部分组成,既属性头和属性体。属性头的前四个字节为属性的类型。如下是以10H属性为例的属性结构。

wKioL1LOYkfj7x_jAALaOVvizHk234.jpg

另外属性还有常驻与非常驻之分。当一个文件很小时,其所有属性体都可以存放在文件记录中,该属性就称为常驻属性。如果某个文件很大,1KB的文件记录无法记录所有属性时,则文件系统会在$MFT元文件之外的区域(也称数据流)存放该文件的其他文件记录属性,这些存放在非$MFT元文件内的记录就称为非常驻属性。

分析属性的属性头

   每个属性都有一个属性头,这个属性头包含了一些该属性的重要信息,如属性类型,属性大小,名字(并非都有)及是否为常驻属性等。

如下是常驻属性的属性头分析表:

wKiom1LOaiSDv7mOAAMuHi1uysQ810.jpg

如下是非常驻属性的属性头分析:

wKioL1LOakrTpGXRAAQN3P8LdHs770.jpg


前面说过了,属性的种类有很多,因此各属性体的含义也不同。下表是NTFS文件系统中的所有属性体的简介。

wKioL1LObq6zdmiEAANQjYT6rrM170.jpg

wKioL1LObZOiqDtVAALl7rHKs5U305.jpg

由于属性体的解释内容太多了,作者就不一一做解释了,只介绍几个工作时常用的属性,其他属性的介绍请查阅相关资料。


分析10H属性

   10H类型属性它包含文件的一些基本信息,如文件的传统属性,文件的创建时间和最后修改时间和日期,文件的硬链接数等等。如下:是一个10H类型的属性。

wKiom1LTQ8qCkFlqAAKJFS962dA232.jpg

如下:是10H类型属性的解释。

wKiom1LTQ_jz_x1eAAOeK2AhTY8449.jpg

上表中所描述的传统属性补充如下:

wKiom1LTRJyDtCYfAAE80BM6yhY262.jpgwKioL1LTRKvAhL35AAFwbF5xBJ8515.jpg


分析20H属性

   20H类型属性既属性列表,当一个文件需要好几个文件记录时,才会用到20H属性。20H属性记录了一个文件的下一个文件记录的位置。如下:是20H属性的解释。

wKiom1LTRoahX81uAAKQe4fYOWg137.jpg


分析30H属性

   30H类型属,该属性用于存储文件名 ,它总是常驻属性。最少68字节,最大578字节,可容纳最大Unicode字符的文件名长度。如下:是一个30H属性的实例。

wKioL1LTR86TGxN6AAHc6Q2nG0Q135.jpg

如下:是30H属性的解释

wKioL1LTSKLzXzoNAAMgiwCwb3Q415.jpg


分析80H属性

   80H属性是文件数据属性,该属性容纳着文件的内容,文件的大小一般指的就是未命名数据流的大小。该属性没有最大最小限制,最小情况是该属性为常驻属性。常驻属性就不做多的解释了,如下是一个非常驻的80H属性。

wKioL1LTlu-DnNWYAAH3Bub6lko574.jpg

如下:是数据“Run List”部分的解释。

wKioL1LTmE6wBqd5AAF1RE4gwEs637.jpg

wKiom1LTmHXyQbuyAAIMg_tHMd0270.jpg

其中该属性的“Run List”值为“32 0C 1B 00 00 0C”,其具体含义如下:

wKioL1LTmMLThLlFAAFKyUjzvQc402.jpg

分析90H属性

   90H属性是索引根属性,该属性是实现NTFS的B+树索引的根节点,它总是常驻属性。该属性的结构如下图:

wKiom1LTmj7QAacDAAKrVAKKAFQ597.jpg

索引根的解释如下表:

wKioL1LTmtjgr_ZbAAFfjJLLjGE858.jpg

索引头的解释如下表:

wKioL1LTmvSwkZZgAAFyF_smZh8480.jpg

索引项的解释如下表:

wKioL1LTmxKCvy_LAAOARrmR9CI263.jpg


分析A0H属性

   A0属性是索引分配属性,也是一个索引的基本结构,存储着组成索引的B+树目录索引子节点的定位信息。它总是常驻属性。如下:是一个A0H属性的实例。

wKiom1LTm_XA6SpLAAGkl4iX3kA636.jpg

根据上图A0H属性的“Run List”可以找到索引区域,偏移到索引区域所在的簇,如下图:

wKiom1LTq1PgWTPFAAWC3hXZ_J8441.jpg

标准索引头的解释如下;

wKioL1LTrCnRGNdlAAFXiQx7PuE124.jpg

wKiom1LTrEiTHqTKAAE2_ml2qHQ538.jpg

索引项的解释如下:

wKiom1LTrGTQZ5O-AAKtqSUdMI8014.jpg

至此属性分析已经介绍完毕了,下面我们来分析一下数据存储在NTFS文件系统中的具体位置。


1、定位DBR,通过DBR可以得知“$MFT”的起始簇号及簇的大小。

2、定位“$MFT”,找到“$MFT”后,在其中寻找根目录的文件记录,一般在5号文件记录。如下:

wKioL1LTn1WRvWY8AAVCbYtsEcA294.jpg

4、分析根目录中的文件记录属性,从上图中可以看出文件记录的属性一共有7个,我们可以根据前面分析过的属性进行对照可知道各属性的意思。由于是根目录,目录比较大,所以90H属性是没有内容的,重点在A0属性上。通过属性中的“Run List”定位到其数据流,如下图:是“Run List”的分析。

wKioL1LTpYej8jRpAAU_kprYh_k739.jpg

通过上图A0H属性中的分析,我们可以计算出有6个数据流,如下表:

wKioL1LTp4qDoUAYAAFIu5mtrHI697.jpg

5、分析NTFS的索引

   从上表中分许出6个数据流所对应的LCN号,现在只需要偏移到相应的簇就可以找到索引区域了。

如下图:

wKiom1LTqabQ2tQtAASYQe45QD4485.jpg

6、偏移到索引区域后发现,索引区域的索引项都有子节点,我们根据自己需要找的目标文件,找到相应的索引项并查找索引缓冲区的LCN和VCN对应关系,可得知子节点的起始簇号。如下图:

wKioL1LTr4KAoMmNAAOYbSamwCs141.jpg

7、从索引项中可以获取“$MFT”的参考号,然后进入到“$MFT”找到对应的文件记录,如下图:

wKioL1LTsFOBcVTCAANkU1R4dwY456.jpg

然后再根据80H属性中的数据流就可以找到文件真正的数据了。


由于NTFS实在是太复杂了,所以文章内容写的有限,并且有大量的截图,所以看起来很乱。就请大家多多包含,写这么多也不容易。


作者:邓奇