NTFS文件系统详解

  • Post author:
  • Post category:其他




NTFS (New Technology File System),是 Windows NT 环境的文件系统。新技术文件系统是Windows NT家族(如,Windows 2000、Windows XP、Windows Vista、Windows 7和 windows 8.1)等的限制级专用的文件系统(操作系统所在的盘符的文件系统必须格式化为NTFS的文件系统,4096簇环境下)。NTFS取代了老式的FAT文件系统。

NTFS对FAT和HPFS作了若干改进,例如,支持元数据,并且使用了高级数据结构,以便于改善性能、可靠性和磁盘空间利用率,并提供了若干附加扩展功能。NTFS文件系统拥有以下特点:

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

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

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

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



一、分析NTFS文件系统的结构


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

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

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

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

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

NTFS的16个元文件介绍:

序号 元文件 功能
0 $MFT 主文件表本身,是每个文件的索引
1 $MFTMirr 主文件表的部分镜像
2 $LogFile 事务型日志文件
3 $Volume 卷文件,记录卷标等信息
4 $AttrDef 属性定义列表文件
5 $Root 根目录文件,管理根目录
6 $Bitmap 位图文件,记录了分区中簇的使用情况
7 $Boot 引导文件,记录了用于系统引导的数据情况
8 $BadClus 坏簇列表文件
9 $Quota(NTFS4) 在早期的Windows NT系统中此文件为磁盘配额信息
10 $Secure 安全文件
11 $UpCase 大小写字符转换表文件
12 $Extend metadata directory 扩展元数据目录
13 $Extend\$Reparse 重解析点文件
14 $Extend\$UsnJrnl 加密日志文件
15 $Extend\$Quota 配额管理文件
16 $Extend\$ObjId 对象ID文件



二、分析$Boot文件

在这里插入图片描述


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


  • EB 52 90(跳转指令)

    本身占2字节它将程序执行流程跳转到引导程序处。“EB 52 90”清楚地指明了OS引导代码的偏移位置。jump 52H加上跳转指令所需的位移量,即开始于0×55。


  • 4E 54 46 53 20 20 20 20(OEM代号)

    这部分占8字节,其内容由创建该文件系统的OEM厂商具体安排,本例为“NTFS”。


  • BPB

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

偏移(offset) 长度(字节) 含义

00-02H

3

跳转指令EB 52 90
03-0AH 8 文件系统的ASIIC码,表示形式NTFS
0B-0CH 2 每个扇区内的字节总数,一般为00 02H

0DH

1

簇大小
0E-0FH 2 保留扇区
10-12H 3 总为0
13H 1 不使用
14-15H 2 介质描述,硬盘为F8
16-17H 2 总为0

18-19H

2

每磁头扇区数

1A-1BH

2

每柱面磁头数

1C-1FH

4

隐含扇区(从MBR到DBR的扇区总数)
20-23H 4 不使用
24-27H 4 不使用,总为80 00 80 00

28-2FH

8

扇区总数,即分区大小

30-37H

8

$MFT的开始簇号

38-3FH

8

$MFTmirr的开始簇号
40-43H 4 每个MFT记录的簇数
44-47H 4 每索引的簇数
48-4FH 8 分区的逻辑序列号


对照上表,对BPB的分析如下:

02 00 每个扇区512个字节
08 每个簇8个扇区
00 00 保留扇区为 0
00 00 00 为 0
00 00 不使用
F8 硬盘
00 00 为0
00 3F 每磁道63个扇区
00 FF 每柱面255个磁头
00 00 00 3F 隐藏扇区数(MBR到DBR)
00 00 00 00 不使用
80 00 80 00 不使用
00 00 00 00 04 FF D5 E5 扇区总数 83875301
00 00 00 00 00 0C 00 00 MFT的开始簇号 786432
00 00 00 00 00 00 00 10 MFTmirr的开始簇号 16
00 00 00 F6 每个MFT记录的簇数
00 00 00 01 每索引的簇数
B6 FC 23 AA FC 23 63 B9 分区的逻辑序列号


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



三、分析$MFT元文件


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



四、分析文件记录



1. MFT偏移地址计算


根据上面BPB的数据可以得到条件

说明 数值
MBR开始扇区 63
每个扇区内的字节总数 512
簇大小 8
每个MFT记录的簇数 1
MFT的开始簇号 786432


每个MFT字节总数 = 簇大小 * 每个扇区内的字节总数


= 8 * 512 = 4096


MBR开始扇区字节总数 = MBR起始扇区 * 每个扇区内的字节总数


= 63 * 512 = 32256


MFT的开始位置的字节总数 = MBR开始扇区字节总数 + MFT的开始簇号 * 每个MFT字节总数


= 32256 + 786432 * 4096 = 3221257728




3221257728

转换为十六进制,即得到MFT开始位置偏移地址

C0007E00



2. 文件记录的结构


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

查看文件记录格式,如下是一个完整的文件记录:

在这里插入图片描述


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

偏移(offset) 长度(字节) 描述
0x0 4 固定值,一定是“FILE”
0x4 2 更新序列号的偏移
0x6 2 更新序列号与更新数组以字为单位大小(S)
0x8 8 日志文件序列号(每次记录被修改,都将导致该序列号加1)
0x10 2 序列号(记录本文件记录被重复使用的次数,每次文件删除时加1,跳过0值,如果为0,则保持为0)
0x12 2 硬连接数,只出现在基本文件记录中,目录所含项数要使用到它
0x14 2 第一个属性流的偏移地址
0x16 2 标志字节,1表示记录使用中,2表示记录为目录
0x18 4 文件记录实际大小(填充到8字节,即以8字节为边界)
0x1C 4 文件记录分配大小(填充到8字节,即以8字节为边界)
0x20 8 所对应的基本文件记录的文件参考号(扩展文件记录中使用,基本文件记录中为0,在基本文件记录的属性列表0x20属性存储中扩展文件记录的相关信息)
0x28 2 下一个自由ID号,当增加新的属性时,将该值分配给新属性,然后该值增加,如果MFT记录重新使用,则将它置0,第一个实例总是0。
0x2A 2 边界,windows xp中使用,也就是本记录使用的两个扇区的最后两个字节的值
0x2C 4 windows xp中使用,本MFT记录号
2 更新序号
2S-2 更新序列数组


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

在这里插入图片描述


属性有


常驻





非常驻


之分。

当一个文件很小时,其所有属性体都可以存放在文件记录中,该属性就称为

常驻属性



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



3. 属性的属性头分析


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

常驻属性

等。



常驻属性


的属性头分析表:

偏移(offset) 长度(字节) 常用值 含义

00-03

4

属性类型

04-07

4

属性的长度,8的整数倍


(整个属性长度)



08

1

00

是否为常驻属性,00表示为常驻属性

09

1

00

属性名的长度,00表示没有属性名

0A-0B

2

18 00

属性值的开始偏移
0C-0D 2 00 标志,如压缩、加密、稀疏等
0E-0F 2 00 标识

10-13

4

Length

属性长度
14-15 2 18 属性体开始位置
16 1 索引标志
17 1 填充

18

Length

属性体开始




非常驻属性


的属性头分析表:

偏移(offset) 长度(字节) 常用值 含义

00-03

4

属性类型

04-07

4

属性的长度,8的整数倍


(整个属性长度)



08

1

01

是否为常驻属性,01表示为非常驻属性
09 1 00 属性名的长度,00表示没有属性名
0A-0B 2 属性值的开始偏移
0C-0D 2 标志,如压缩、加密、稀疏等
0E-0F 2 属性ID
10-17 8 起始虚拟簇号VCN
18-1F 8 结束虚拟簇号VCN
20-21 2 40 Data Run的偏移地址
22-23 2 压缩单位大小,2的N次方
24-27 4 不使用
28-2F 8 属性分配大小
30-37 8 属性实际大小
38-3F 8 属性原始大小
40 Data Run信息



4. 属性的属性体分析


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

属性类型(即属性偏移00H-03H处的十六进制数据) 属性类型名 属性描述
10H 00H 00H 00H $STANDARD_INFORMATION 标准信息:包括一些基本文件属性,如只读、系统、存挡,时间属性,如文件的创建时间和最后修改时间;有多少目录指向该文件( 即其硬链接数)
20H 00H 00H 00H $ATTRIBUTE_LIST 属性列表,当一个文件需要多个MFT文件记录时,用来描述文件的属性列表
30H 00H 00H 00H $FILE_NAME 文件名,用Unicode字符表示的文件名,由于MS DOS不能识别长文件名, 所以NTFS系统会自动生成一个8.3文件名
40H 00H 00H 00H $VOLUME_VERSION 在早期的NTFS v1.2中为卷版本
40H 00H 00H 00H $OBJECT_ID 对象ID:一个具有64个字节的标识符,其中最低的16个字节对卷来说是惟一的(链接跟踪服务为外壳快捷方式即OLE链接源文件赋予对象ID,NTFS提供的API是直接通过这些对象的ID而不是文件名来打开文件的)
50H 00H 00H 00H $SECURITY_DESCRIPTOR 安全描述符:这是为向后兼容而保留的,主要用于保护文件以防止没有授权的访问,但Windows 2000、Windows XP中巳将安全描述符存放在$Secure元数据中,以便于共享(早期的NTFS将其与文件目录一起存放,不便于共享)
60H 00H 00H 00H $VOLUME_NAME 卷名(卷标识):该属性仅存在于$Volume元数据中
70H 00H 00H 00H $VOLUME_INFORMATION 卷信息,该属性仅存在于$Volume元数据中
80H 00 ll 00H 00H $DATA 文件数据:该属性为文件的数据内容
90H 00H 00H 00H $INDEX_ROOT 索引根
A0H 00H 00H 00H $INDEX_ALLOCATlON 索引分配
B0H 00H 00H 00H $BITMAP 位图
C0H 00H 00H 00H $SYMBOLIC_LINK 在早期的NTFS v1.2中为符号链接
C0H 00H 00H 00H $REPARSE_POINT 重解析点
D0H 00H 00H 00H $EA_INFORMATION 扩充属性信息
E0H 的H 00H 00H $EA 扩允属住
F0H 00H 00H 00H $PROPERTY_SET 早期的NTFS v1.2中才有
00H 10H 00H 00H $LOGGED_UTILITY_STREAM EFS加密屈性:该属性主要用于存储实现EFS加密的有关加密信息,如合法用户列表、解码密钥等


接下来来看几个重要的属性:


  • 10H属性

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

偏移(offset) 长度(字节) 操作系统 描述
标准属性头(已经分析过)
0x00 8 C TIME 文件创建时间
0x08 8 A TIME 文件修改时间
0x10 8 M TIME MFT变化时间
0x18 8 R TIME 文件访问时间
0x20 4 文件属性(按照DOS术语来称呼,都是文件属性)
0x24 4 文件所允许的最大版本号(0表示未使用)
0x28 4 文件的版本号(最在版本号为0,则他为0)
0x2C 4 类ID(一个双向的类索引)
0x30 4 2K 所有者ID(表示文件的所有者,是文件配额$QUOTA中$O和$Q索引的关键字,为0表示未使用磁盘配额)
0x34 4 2K 安全ID是文件$SECURE中$SII和$SDS数据流的关键字,注意不要与安全标识相混淆
0x38 8 2K 本文件所占用的字节数,它是文件所有流占用的总字节数,为0表示未使用磁盘配额
0x40 8 2K 更新系列号(USN),是到文件$USNJRNL的一个直接的索引,为0表示USN日志未使用


如下是一个10H属性偏移0×20处属性体的解释:

标志 描述 标志 描述
0001H 只读文件 0200H 稀疏文件
0002H 隐含文件 0400H 重点解析文件
0004H 系统文件 0800H 压缩文件
0020H 存档文件 1000H 脱机文件
0040H 设备文件 2000H 未编入文件
0080H 常规文件 4000H 加密文件
0100H 临时文件

  • 20H属性

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

    如下是20H属性偏移0×20处属性体的解释。

偏移(offset) 长度(字节) 描述
标准属性头(已经分析过)
0x00 4 类型
0x04 2 记录长度
0x06 1 属性名长度(N,为0表示没有属性名)
0x07 1 属性名偏移(如果没有属性名,则指向属性内容)
0x08 8 起始VCN(属性常驻时为0)
0x10 8 属性的基本文件记录中的文件参考号(所有MFT的文件都有一个文件索引号,引用到这个文件参考号,等价于引用这个文件记录,这个参考号在文件记录头中有定义)
0x18 2 属性ID(每个属性都有一个唯一的ID号)
0x1A 2N Unicode属性名(如果有属性名)

  • 30H属性

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

偏移(offset) 长度(字节) 描述
标准属性头(已经分析过)
0x00 8 父目录的文件参考号(即父目录的基本文件记录号,分为两部分,前6个字节48位为父目录的文件记录号,此处为0x05,即根目录,所以$MFT的父目录为根目录,后2个字节为序列号)
0x08 8 文件创建时间
0x10 8 文件修改时间
0x18 8 最后一次MFT更新时间
0x20 8 最后一次访问时间
0x28 8 文件分配大小
0x30 8 文件实际大小
0x38 4 标志,如目录、压缩、隐藏等
0x3C 4 用于EAS和重解析点
0x40 1 以字符计的文件名长度,每字符占用字节数由下一字节命名空间确定,一个字节长度,所以文件名最长255字节。
0x41 1 文件名命名空间
0x42 2L 以Unicode方式表示的文件名

  • 80H属性

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

在这里插入图片描述


其中,Run List是最难理解,也是最重要的。当属性不能存放完数据,系统就会在NTFS数据区域开辟一个空间存放,这个区域是以簇为单位的。Run List就是记录这个数据区域的起始簇号和大小,一个Run List例子上所示。这个示例中,Run List的值为“32 CC 26 00 00 0C”,因为后面是00H,所以知道已经是结尾。如何解析这个Run List呢? 第一个字节是压缩字节,高位和低位相加,3 + 2 = 5,表示这个Data Run信息占用五个字节,其中高位表示起始簇号占用多少个字节,低位表示大小占用的字节数。在这里,起始簇号占用3个字节,值为0C 00 00,大小占用2个字节,值为26 CC。解析后,得到这个数据流起始簇号为C0000,大小为9932簇。

在这里插入图片描述


  • 90H属性

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

在这里插入图片描述


索引根结构表:

偏移(offset) 长度(字节) 描述
标准属性头(已经分析过)
0x00 4 属性类型
0x04 4 排序规则
0x08 4 索引项分配大小(字节数)
0x0C 1 每索引记录的簇数
0x0D 3 填充(到8字节)


索引头结构表:

偏移(offset) 长度(字节) 描述
标准属性头(已经分析过)
0x00 4 第一个索引项的偏移
0x04 4 索引项的总大小
0x08 4 索引项的分配大小
0x0C 1 标志
0x0D 3 填充(到8字节)


索引项结构表:

偏移(offset) 长度(字节) 描述
0x00 8 文件的MFT参考号
0x08 2 索引项大小
0x0A 2 文件名偏移
0x0C 2 索引标志
0x0E 2 填充(到8字节)
0x10 8 父目录的MFT文件参考号
0x18 8 文件创建时间
0x20 8 最后修改时间
0x28 8 文件记录最后修改时间
0x30 8 最后访问时间
0x38 8 文件分配大小
0x40 8 文件实际大小
0x48 8 文件标志
0x50 1 文件名长度(F)
0x51 1 文件名命名空间
0x52 2F 文件名
2F+0x52 P 填充(到8字节)
P+2F+0x52 8 子节点索引缓存的VCN

  • A0H属性

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

在这里插入图片描述


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

起始簇:18265

簇大小:3

起始扇区号 = 该分区的其实扇区 + 簇号 * 每个簇的扇区数 也就是

64 + 18265 * 8 = 146124

在这里插入图片描述



上面的偏移0x28,还要加上0x18 = 0×40

起始簇:18265

簇大小:3

起始扇区号 = 该分区的起始扇区 + 簇号 * 每个簇的扇区数

也就是

64 + 18265 * 8 = 146124

标准索引头的解释如下:

偏移(offset) 长度(字节) 描述
0x00 4 总是“INDX”
0x04 2 更新序列号的偏移
0x06 2 更新序列号与更新数组以字为单位的大小(S)
0x08 8 日志文件序列号
0x10 8 本索引缓存在索引分配中的VCN
0x18 4 索引项的偏移
0x1C 4 索引项大小
0x20 4 索引项分配大小
0x24 1 如果不是叶节点,置1,表示还有子节点
0x25 3 用0填充
0x28 2 更新序列
0x2A 2S-2 更新序列数组


索引项的解释如下:

偏移(offset) 长度(字节) 描述
0x00 8 文件的MFT参考号
0x08 2 索引项大小
0x0A 2 文件名偏移
0x0C 2 索引标志
0x0E 2 填充(到8字节)
0x10 8 父目录的MFT文件参考号
0x18 8 文件创建时间
0x20 8 最后修改时间
0x28 8 文件记录最后修改时间
0x30 8 最后访问时间
0x38 8 文件分配大小
0x40 8 文件实际大小
0x48 8 文件标志
0x50 1 文件名长度(F)
0x51 1 文件名命名空间
0x52 2F 文件名
2F+0x52 P 填充(到8字节)
P+2F+0x52 8 子节点索引缓存的VCN


到此一些常用属性基本介绍的差不多了。



五、遍历分区文件列表的思路


1. 定位DBR,通过DBR可得到“$MFT”的起始簇号及簇大小;

2. 定位并找到“MFT”后,在其中寻找根目录的文件记录,一般在5号文件记录;

3. 在90H属性中得到B+树索引的根节点文件信息,重点在A0属性上。通过属性中的“Run List”定位到其数据流;

4. 从“Run List”定位到起始簇后,再分析索引项可以得到文件名等信息;

5. 从索引项中可以获取“MFT”的参考号;

6. 进入到“MFT”的参考号;

7. 进入到“MFT”找到对应的文件记录;

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




NTFS文件系统详解系列



版权声明:本文为tianjin_ren原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。