虽然NTFS和FAT32有很大区别,但是它们的结构是有共通之处的。NTFS大概的结构如下图6-1所示。$Boot包含了引导扇区。$MFT是主文件表,是NTFS结构的核心。最后的一个扇区是$Boot引导扇区的备份,其实它不是不分区内的结构,是属于分区外的一个扇区备份,它的大小不算入分区大小,从FAT32文件系统转换成NTFS是没有后面的$Boot扇区备份的。理解NTFS文件系统结构的最关键的概念:一切东西都是文件。所以其他的元文件都是文件,不作为特殊的结构列出。和FAT32一样,数据也是以簇为单位来存储。
6.2 NTFS引导扇区
NTFS的引导扇区是元文件$Boot中的一部分。它的结构和FAT32的类似,习惯上称为DBR,大概结构如图6-2所示。其中BPB的参数含义如下表6-1。
表6-1 NTFS文件系统BPB参数含义
偏移 |
长度(字节) |
含义 |
偏移 |
长度(字节) |
含义 |
0x0B |
2 |
每扇区字节数 |
0x0D |
1 |
每簇扇区数 |
0x0E |
2 |
保留扇区 |
0x10 |
3 |
总是0 |
0x13 |
2 |
未使用 |
0x15 |
1 |
介质描述符 |
0x16 |
2 |
未用 |
0x18 |
2 |
每磁道扇区数 |
0x1A |
2 |
磁头数 |
0x1C |
4 |
隐藏扇区 |
0x20 |
4 |
未使用 |
0x24 |
4 |
总为80008000 |
0x28 |
8 |
扇区总数 |
0x30 |
8 |
$MFT起始簇号 |
0x38 |
8 |
$MFTMirr起始簇号 |
0x40 |
1 |
文件记录大小描述 |
0x41 |
3 |
未使用 |
0x44 |
1 |
索引缓冲大小 |
0x45 |
3 |
未用 |
0x48 |
8 |
卷序列号 |
0x50 |
4 |
校验和 |
|
|
|
6.3 NTFS文件记录
在NTFS文件系统中,磁盘上所有数据都是以文件的形式存在的,即使是文件系统的管理信息也是以一组文件的形式存储。每个文件都有一个文件记录,这些记录就是存放在主文件表中,即MFT。MFT是NTFS最重要部分,因为它记录着所有文件的信息。MFT在建立文件系统的时候就创建好了,它的位置是不定的,所以在引导扇区中有指向MFT的记录,这样系统就可以找得到MFT,也就能找到文件了。MFT由很多个文件记录组成,每个记录对应着不同的文件,每个记录大小由BPB参数确定,目前微软操作系统中,每个记录大小都是1KB。每个MFT记录有一定的结构:文件记录头和多个属性,如图6-3所示,文件记录头的具体含义如表6-2。
图6-3 NTFS文件记录结构
表6-2 NTFS文件记录头含义
偏移 |
长度 |
含义 |
0x00 |
4 |
MFT标志,“FILE” |
0x04 |
2 |
更新序列号(USN)的偏移 |
0x06 |
2 |
更新序列号的大小和数组 |
0x08 |
8 |
日志文件序列号 |
0x10 |
2 |
序列号 |
0x12 |
2 |
硬链接数 |
0x14 |
2 |
第一个属性的偏移地址 |
0x16 |
2 |
标志,00H表示文件被删除,01H表示文件正在使用,02H表示目录被删除,03H表示目录正在使用 |
0x18 |
4 |
文件记录的实际长度 |
0x1C |
4 |
文件记录的分配长度 |
0x20 |
8 |
基本文件记录中的文件索引号 |
0x28 |
2 |
下一个属性ID |
0x2A |
2 |
边界 |
0x2C |
4 |
文件记录参考号 |
0x30 |
2 |
更新序列号 |
0x32 |
4 |
更新数组 |
表6-3 常驻属性
偏移 |
长度 |
含义 |
0x00 |
4 |
属性类型 |
0x04 |
4 |
属性长度 |
0x08 |
1 |
是否为常驻属性(00表示常驻,01表示非常驻) |
0x09 |
1 |
属性名长度 |
0x0A |
2 |
属性名的开始偏移 |
0x0C |
2 |
压缩、加密、稀疏标志 |
0x0E |
2 |
属性ID |
0x10 |
4 |
属性体的长度(L) |
0x14 |
2 |
属性体的开始偏移 |
0x16 |
1 |
索引标志 |
0x17 |
1 |
无意义 |
0x18 |
L |
属性体 |
表6-4 非常驻属性
偏移 |
长度 |
含义 |
0x00 |
4 |
属性类型 |
0x04 |
4 |
属性长度 |
0x08 |
1 |
是否为常驻属性(00表示常驻,01表示非常驻) |
0x09 |
1 |
属性名长度 |
0x0A |
2 |
属性名的开始偏移 |
0x0C |
2 |
压缩、加密、稀疏标志 |
0x0E |
2 |
属性ID |
0x10 |
8 |
属性体的起始虚拟簇号(VCN) |
0x18 |
8 |
属性体的结束虚拟簇号 |
0x20 |
2 |
Run List偏移地址 |
0x22 |
2 |
压缩单位大小 |
0x24 |
4 |
无意义 |
0x28 |
8 |
属性体的分配大小 |
0x30 |
8 |
属性体的实际大小 |
0x38 |
8 |
属性体的初始大小 |
0x40 |
|
属性体的Run List信息 |
其中,Run List是最难理解,也是最重要的。当属性不能存放完数据,系统就会在NTFS数据区域开辟一个空间存放,这个区域是以簇为单位的。Run List就是记录这个数据区域的起始簇号和大小,一个Run List例子如图6-4所示。这个示例中,Run List的值为“31 40 00 00 04”,因为后面是00H,所以知道已经是结尾。如何解析这个Run List呢?如图6-5所示, 第一个字节是压缩字节,高位和低位相加,3+1=4,表示这个Data Run信息占用四个字节,其中高位表示起始簇号占用多少个字节,低位表示大小占用的字节数。在这里,起始簇号占用3个字节,值为40000H,大小占用1个字节,值为40H。解析后,得到这个数据流起始簇号为262144,大小为64簇。
图6-4 Run List例子
图6-5 Run List结构及含义
系统定义的属性有15个,如表6-5所示。
表6-5 NTFS文件系统属性
编号 |
名称 |
作用 |
10H |
$STANDARD_INFORMATION |
标准属性,包含文件的基本信息 |
20H |
$ATTRIBUTE_LIST |
属性列表 |
30H |
$FILE_NAME |
文件名 |
40H |
$OBJECT_ID |
对象ID |
50H |
$SECURITY_DESCRIPTOR |
安全描述符 |
60H |
$VOLUME_NAME |
简单包含卷名称 |
70H |
$VOLUME_INFORMATION |
说明卷的版本和状态 |
80H |
$DATA |
数据属性 |
90H |
$INDEX_ROOT |
索引根属性 |
A0H |
$INDEX_ALLOCATION |
索引分配属性 |
B0H |
$BITMAP |
位图属性 |
C0H |
$REPARSE_POINT |
重解析点属性 |
D0H |
$EA_INFORMATINO |
扩展属性信息属性 |
E0H |
$EA |
扩展属性 |
100H |
$LOGGED_UTILITY_STREAM |
EFS加密属性 |
在这些属性中,重要的有10H、30H、80H、90H、A0H和B0H。
10H是包含文件的一些基本信息,如文件的传统属性、文件创建时间和最后修改时间、有多少目录指向该文件等。
30H用来存储文件名,它是常驻属性。
80H就是存储文件的内容,它没有最大最小限制,如果文件内容实在太小,就存在MFT记录中,不过一般都是存储在MFT外的。
90H是根索引属性,实现NTFS的B-索引树的根节点,它是常驻属性,在根目录项比较少的情况下会使用,如果文件项多,则使用到了A0H属性。
A0H是索引分配属性,它是一个索引的基本结构,存储着组成索引的B-树目录所有子节点的定位信息,它是常驻,并且没有最大最小限制。该属性实现B-树的大目录,在后面详细讲解。
B0H是位图属性,它由一系列的位构成的虚拟簇(VCN)使用情况表,没有最大最小。在两个地方使用到该属性:索引和$MFT,索引中,每一位代表索引分配中的一个VCN;在$MFT中,每一位代表一个文件记录使用情况。其中每一位中的0代表未使用,1代表正在使用。
在所有合法属性之后,以“FFFFFFFF”表示结束。
值得一提的是,有时候一个MFT记录中会出现两个一样的属性,这是很正常的。但是特殊的情况是一个结束标志之后还有某个属性,如A0H属性,然后后面还有一个结束标志,这种情况下就以第一个结束标志为准,后面的信息都不要了,只是前面的修改留下来而已,系统并不会清除。
6.5 NTFS元文件
元文件就是一些文件系统的记录,记录卷的基本信息,它在创建文件系统的时候建立,这些元文件和一般的文件记录都是一样的。文件系统已经规定好元文件,每个元文件都有固定顺序,元文件的文件名的第一个字符都是“$”,表示该文件是隐藏的,用户无法访问和修改,元文件如表6-6所示。
表6-6 NTFS文件系统元文件
序号 |
元文件 |
功能 |
0 |
$MFT |
主文件表,是每个文件的索引 |
1 |
$MFTMirr |
主文件表的镜像(部分) |
2 |
$LogFile |
事务型日志文件 |
3 |
$Volume |
卷文件,记录卷标等信息 |
4 |
$AttrDef |
属性定义列表文件 |
5 |
$Root |
根目录文件,管理根目录 |
6 |
$Bitmap |
位图文件,记录簇使用情况 |
7 |
$Boot |
引导文件 |
8 |
$BadClus |
坏簇列表文件 |
9 |
$Quota |
早期版本使用的磁盘配额信息 |
10 |
$Secure |
安全文件 |
11 |
$Upcase |
大小写字符转换表文件 |
12 |
$Extend metadata directory |
扩展元数据目录 |
13 |
$Extend\$Reparse |
重解析点文件 |
14 |
$Extend\$UsnJrnl |
加密日志问文件 |
15 |
$Extend\$Quota |
配额管理文件 |
16 |
$Extend\$ObjId |
对象ID文件 |
还有哦,继续加油~