在NTFS中,所有存储在卷上的数据都包含在文件中,包括用来定位和获取文件的数据结构,引导程序和记录这个卷的记录(NTFS元数据)的位图,这体现了NTFS的原则:磁盘上的任何事物都为文件。在文件中存储一切使得文件系统很容易定位和维护数据,而在NTFS中,卷中所有存放的数据均在一个叫做MFT的文件记录数组中,称为主文件表(Master File Table),MFT是由高级格式化产生的。而MFT则由文件记录(File Record)数组构成。File Record的大小一般是固定的,不管簇的大小是多少,均为1KB,这个概念相当于Linux中的inode(i节点)。File Record在MFT文件记录数组中物理上是连续的,且从0开始编号。MFT仅供系统本身组织、架构文件系统使用,这在NTFS中称为元数据(metadata)。其中最基本的前16个记录是操作系统使用的非常重要的元数据文件。这些NTFS主文件表的重要的元数据文件都是以$(美元符号)开始的名字,所以是隐藏文件,在Windows 2000中不能使用dir命令(甚至加上/ah参数)像普通文件一样列出这些元数据文件。实际上File System Driver(ntfs.sys)维护了一个系统变量NTFS Protect System Files用于隐藏这些元数据。但是微软公司也提供了一个OEM TOOL,叫做NFI.EXE,用此工具可以转储NTFS主文件表的重要的元数据文件(元数据:是存储在卷上支持文件系统格式管理的数据。它不能被应用程序来访问,它只能为系统提供服务)

一. 分析$Boot文件


  我们第一步就是先找到MFT的位置,通过分区表,我们得到本分区的引导扇区所在的扇区号,就拿C盘分区来实践,通过上一节,我们得到C盘的引导扇区的扇区号是63,首先进到扇区号为63的扇区。

在这里插入图片描述


  下面我们分析一下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的分析如下:

- -
00 02 每个扇区512个字节
08 每个簇8个扇区
00 00 保留扇区为0
00 00 00 为0
00 00 不使用
F8 硬盘
00 00 为0
3F 00 每磁道63个扇区
FF 00 每柱面255个磁头
3F 00 00 00 隐藏扇区数(MBR到DBR)
00 00 00 00 不使用
80 00 80 00 不使用
C0 FF BF 03 00 00 00 00 扇区总数 62914496
00 00 00 00 00 0C 00 00 MFT的开始簇号 786432
10 00 00 00 00 00 00 00 MFTmirr的开始簇号 16
F6 00 00 00 每个MFT记录的簇数 246
01 00 00 00 每索引的簇数 1
B9 63 23 FC AA 23 FC 卷标


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

二、分析文件记录

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

在这里插入图片描述


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


  在下面的表中罗列出NTFS5中所有的元文件:

序号 元文件 功能
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文件


  每个MFT记录都对应着不同的文件,如果一个文件有很多属性或是分散成很多碎片,就很可能需要多个文件记录。这时,存放其文件记录位置的第一个记录就叫做“基文件记录”(base file record)。
  MFT中的第1个记录就是MFT自身。由于MFT文件本身的重要性,为了确保文件系统结构的可靠性,系统专门为它准备了一个镜像文件($MftMirr),也就是MFT中的第2个记录。
  第3个记录是日志文件($LogFile)。该文件是NTFS为实现可恢复性和安全性而设计的。当系统运行时,NTFS就会在日志文件中记录所有影响NTFS卷结构的操作,包括文件的创建和改变目录结构的命令,例如复制,从而在系统失败时能够恢复NTFS卷。
  第4个记录是卷文件($Volume),它包含了卷名、被格式化的卷的NTFS版本和一个标明该磁盘是否损坏的标志位(NTFS系统以此决定是否需要调用Chkdsk程序来进行修复)。
  第5个记录是属性定义表($AttrDef,attribute definition table),其中存放了卷所支持的所有文件属性,并指出它们是否可以被索引和恢复等。
  第6个记录是根目录(\),其中保存了存放于该卷根目录下所有文件和目录的索引。在访问了一个文件后,NTFS就保留该文件的MFT引用,第二次就能够直接进行对该文件的访问。
  第7个记录是位图文件($Bitmap)。NTFS卷的分配状态都存放在位图文件中,其中每一位(bit)代表卷中的一簇,标识该簇是空闲的还是已被分配了的,由于该文件可以很容易的被扩大,所以NTFS的卷可以很方便的动态的扩大,而FAT格式的文件系统由于涉及到FAT表的变化,所以不能随意的对分区大小进行调整。
  第8个记录是引导文件($Boot),它是另一个重要的系统文件,存放着Windows 2000/XP的引导程序代码。该文件必须位于特定的磁盘位置才能够正确地引导系统。该文件是在Format程序运行时创建的,这正体现了NTFS把磁盘上的所有事物都看成是文件的原则。这也意味着虽然该文件享受NTFS系统的各种安全保护,但还是可以通过普通的文件I/O操作来修改。
  第9个记录是坏簇文件($BadClus),它记录了磁盘上该卷中所有的损坏的簇号,防止系统对其进行分配使用。
  第10个记录是安全文件($Secure),它存储了整个卷的安全描述符数据库。NTFS文件和目录都有各自的安全描述符,为了节省空间,NTFS将具有相同描述符的文件和目录存放在一个公共文件中。
  第11个记录为大写文件($UpCase,upper case file),该文件包含一个大小写字符转换表。
  第12个记录是扩展元数据目录($Extended metadata directory)。
  第13个记录是重解析点文件($Extend$Reparse)。
  第14个记录是变更日志文件($Extend$UsnJrnl)。
  第15个记录是配额管理文件($Extend$Quota)。
  第16个记录是对象ID文件($Extend$ObjId)。
  第17~23记录是是系统保留记录,用于将来扩展。
  MFT的前16个元数据文件是如此重要,为了防止数据的丢失,NTFS系统在该卷文件存储部分的正中央对它们进行了备份,参见下图。


NTFS文件系统详解系列

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐