数据恢复专题:exFAT 文件系统的 FAT 表、簇位图、目录结构(12)
前言
本节将学习到 exFAT 文件系统的 FAT 表、簇位图、目录结构。
知识点总览
- exFAT 分区 FAT 表结构
- exFAT 分区 Bitmap 结构
- exFAT 分区大写字符文件结构
- exFAT 分区目录结构
exFAT 分区 FAT 表结构
FAT(File Allocation Table)即文件分配表,对于 ExFAT 文件系统来讲也是很重要的一个组成部分,ExFAT 文件系统 FAT 表的功能主要是记录不连续存储的文件的簇链,所以在 FAT 中看到数值为 0 的 FAT 项,并不能说明该 FAT 项对应的簇是可用簇。
系统是如何定位到 FAT 表的?
① 从 MBR 的分区表定位到该分区的 DBR 扇区。
② 读取 DBR 的 BPB 参数,主要读取 “ FAT 表起始扇区号” 这个参数,它在 DBR 的 50H~54H 偏移处。
③ 读取到 “FAT 表起始扇区号” 这个参数的值后,跳转到该分区的偏移扇区,这里就是 FAT 表的开始。
FAT 表的实际应用
把分区格式化为 exFAT 文件系统时,格式化程序会把分配给 FAT 表的第一个扇区清零,然后写入 0 号 FAT 项和 1 号 FAT 项,另外还会写入簇位图文件、大写字符文件及根目录所占簇对应的 FAT 项。
由上图可以看出每个 FAT 项占用 4 字节:其中 0 号 FAT 项描述介质类型,其首字节为“F8”,表示介质类型为硬盘;1 号 FAT 项写入 4 个“FF”;从 2 号 FAT 项开始对应 2 号簇,3 号 FAT 项对应 3 号簇,一直到最后一个簇。目前 2、3、4 三个 FAT 项中都是结束标志,说明簇位图文件、大写字符文件、根目录各占一个簇。
除了这 5 个 FAT 项以外,其他 FAT 项都是 0,但这并不能说这些 FAT 项对应的簇就是空簇。
exFAT 分区 Bitmap 结构
ExFAT 文件系统的 FAT 表之后就是数据区了,但数据区并不一定紧跟在 FAT 表之后,FAT 表后面可能还会有一些保留扇区,每个分区不一样,这要看实际情况。所以不能通过 Bitmap 的位置减去 FAT 表的位置直接计算分区大小。数据区的开始位置在 DBR 的 BPB 中有描述,“首簇起始扇区号”起始就是数据区的开始。数据区中第一个簇就是 2 号簇,2 号簇一般都分配给簇位图文件使用。
簇位图文件是在分区格式化时创建的,该文件不允许用户访问和修改。
上图为一个 exFAT 分区的 Bitmap。
该扇区中只有一个字节“07H”,这就是簇位图文件的内容。
簇位图文件是 ExFAT 文件系统中的一个元文件,类似于 NTFS 文件系统中的元文件$BitMap,它的作用是用来管理分区中簇的使用情况。簇位图文件中的每一个位,映射到数据区中的每一个簇。如果某个簇分配给了文件,该簇在簇位图文件中对应的位就会被填入“1”,表示该簇已经占用;如果没用使用的空簇,它们在簇位图文件中对应的位就是“0”。
exFAT 分区大写字符文件结构
大写字符文件是 exFAT 文件系统中的第二个元文件,类似于 NTFS 文件系统中的元文件$UpCase。Unicode 字母表中每一个字符在这个文件中都有一个对应的条目,用于比较、排序、计算 Hash 值等方面。
大写字符文件是在分区格式化时创建的,该文件不允许用户访问和修改。
簇位图文件结束后的下一个簇一般就分配给大写字符文件使用。
大写字符文件的大小固定为 5836 字节,约为 12 个扇区。
下图为一个大写字符文件的第一个扇区的前半部分。
从图中可以看到其内容都是 Unicode 字母表中的字符,每一个字符占用两个字节。
exFAT 分区目录结构
目录项对于 exFAT 文件系统来讲是非常重要的组成部分,其主要作用及结构特点如下:
① 分区中的每个文件和文件夹(也称为目录)都被分配多个大小为 32 字节 的目录项,用以描述文件或文件夹的属性、大小、起始簇号和时间、日期等信息,当然还会把文件名或目录名也记录在目录项中。
② 在 exFAT 文件系统中,目录也被视为特殊类型的文件,所以每个目录也与文件一样有目录项。
③ 在 exFAT 文件系统下,分区根目录下的文件及文件夹的目录项存放在根目录区中,分区子目录下的文件及文件夹的目录项存放在数据区相应的簇中。
④ exFAT 文件系统目录项的第一个字节用来描述目录项的类型,剩下的 31 字节用来记录文件的相关信息。
⑤ 根据目录项的作用和结构特点,可以把目录项分为四种类型:
- 卷标目录项
- 簇位图文件的目录项
- 大写字符文件的目录项
- 用户文件的目录项
卷标目录项
卷标就是一个分区的名字,可以在格式化分区时创建,也可以随时修改。ExFAT 文件系统把卷标当作文件,用文件目录项进行管理。系统为卷标建一个目录项,放在根目录区中。
卷标的目录项占用 32 字节,其中第一个字节是特征值,用来描述类型。
卷标目录项的特征值为“83H”,如果没有卷标或者将卷标删除,该特征值为“03H”。
没有卷标的目录项
上图为一个没有卷标的 exFAT 类型分区,其特征值为“03H”,占用 32 字节。
有卷标的目录项
接下来查看有卷标的目录项(M:):
上图为一个有卷标的 exFAT 类型分区,其特征值为“83H”,紧接着标识符后的即为卷标名,共占用 32 字节。
卷标的长度理论上为 11 字符,但实际上可以达到 15 字符。
被修改过卷标的目录项
将上图 “M:” 分区的卷标改为 expart
后从底层查看该属性。
由上图可以看出,该分区根目录的第一个目录项 “83H” 的内容被修改了。
接下来查看将 “没有卷标的目录项” 改为 “有卷标的目录项”:
将 “N:” 分区的卷标改为 newpart
后从底层查看该属性。
从根目录可以看出,该分区的第一个目录项还是 “03H”。
但是在最后一个目录项(改完卷标后没有做任何文件操作)中可以看到一条特征值为 “83H” 的目录项。
该目录项为刚刚修改的 newpart
,再次修改卷标后,只有该目录项变更值。
簇位图文件的目录项
ExFAT 文件系统格式化时会创建一个簇位图文件,并为其建一个目录项,放在根目录区中。
簇位图文件的目录项占用 32 字节,其中第一个字节是特征值,用来描述类型。簇位图文件目录项的特征值为“81H”。
ExFAT 簇位图文件目录项的含义:
字节偏移 | 字段长度(字节) | 内容及含义 |
---|---|---|
0x00 | 1 | 目录项的类型(簇位图文件目录项的特征值为“81H”) |
0x01 | 1 | 保留 |
0x02 | 18 | 保留 |
0x14 | 4 | 起始簇号 |
0x18 | 8 | 文件大小 |
簇位图文件的目录项有如下特点:
① 对于 ExFAT 格式的分区,簇位图文件起始簇号一般都为 2。
② 簇位图文件的目录项中不记录时间戳。
下图为一个示例分区的簇位图目录项:
从上图可以看出,该分区的簇位图的起始簇号为:00 00 00 02 H
簇位图的大小为:00 00 D0 12 H (53,266 字节)
故该分区 BPB 参数中的 “分区总簇数” 为 (53266 - 1) * 8 ≈ 426,120
由于最后一个字节不一定完整表示 8 个簇,为避免误差,则将字节数 - 1,算出来的结果与原总簇号最多误差 8 个簇。
大写字符文件的目录项
ExFAT 文件系统格式化时会创建一个大写字符文件文件,并为其建一个目录项,放在根目录区中。
大写字符文件的目录项占用 32 字节,其中第一个字节是特征值,用来描述类型。大写字符文件目录项的特征值为“82H”。
ExFAT 大写字符文件目录项的含义:
字节偏移 | 字段长度(字节) | 内容及含义 |
---|---|---|
0x00 | 1 | 目录项的类型(大写字符文件目录项的特征值为“82H”) |
0x01 | 3 | 保留 |
0x08 | 14 | 保留 |
0x14 | 4 | 起始簇号 |
0x18 | 8 | 文件大小 |
大写字符文件的目录项有如下特点:
① 对于 ExFAT 格式的分区,大写字符文件的目录项一般都跟在簇位图文件的目录项之后。
② 大写字符文件的目录项中不记录时间戳。
下图为一个示例分区的大写字符文件目录项:
从上图可以看出,该分区的大写字符文件的起始簇号为:00 00 00 04 H
大写字符文件的大小为:00 00 16 CC H (5,836 字节)
跳转到大写字符文件数据区(4 号簇)后查看其扇区位置:
大写字符的位置为 6,335 号扇区
根目录的数据区在大写字符后一个簇(即 5 号簇),向下跳转 5836 字节后搜索 !00
到达根目录:
根目录的位置为 6,399 扇区。
用根目录的位置(5 号簇)减去大写字符文件位置(4 号簇)可得每簇扇区数为:6399 - 6335 = 64 。
用户文件的目录项
ExFAT 文件系统中每个用户文件至少有三个目录项,这三个目录项被称为三个属性:第一个目录项称为“属性 1”,目录项首字节的特征值为“85H”;第二个目录项称为“属性 2”,目录项首字节的特征值为“C0H”;第三个目录项称为“属性 3”,目录项首字节的特征值为“C1H”。
“属性 1”目录项
“属性 1”目录项用来记录该目录项的附属目录项数、校验和、文件属性、时间戳等信息。
用户文件的“属性 1”目录项如图所示。
用户文件的“属性 1”目录项的含义
字节偏移 | 字段长度(字节) | 内容及含义 |
---|---|---|
0x00 | 1 | 目录项的类型(“属性 1”目录项的特征值为“85H”) |
0x01 | 1 | 附属目录项数 |
0x02 | 2 | 校验和 |
0x04 | 4 | 文件属性 |
0x08 | 4 | 文件创建时间 |
0x0C | 4 | 文件最后修改时间 |
0x10 | 4 | 文件最后访问时间 |
0x14 | 1 | 文件创建时间精确至 10ms |
0x15 | 3 | 保留 |
0x18 | 8 | 保留 |
①0x00 ~ 0x00:类型。该参数为目录项类型的特征值,“属性 1”目录项的特征值为“85H”。
②0x01 ~ 0x01:附属目录项数。该参数指除此目录项外,该文件还有几个目录项,当前值为 2,说明这个文件除了“属性 1”目录项外,后面还有两个目录项,起始就是“属性 2”目录项和“属性 3”目录项。
③0x02 ~ 0x03:校验和。该参数是校验算法算出来的目录项的校验和。
④0x04 ~ 0x07:文件属性。该参数描述文件的常规属性,属性具体含义见下表。
二进制值 | 属性含义 | 二进制值 | 属性含义 |
---|---|---|---|
00000000 | 读/写 | 00001000 | 卷标 |
00000001 | 只读 | 00010000 | 子目录 |
00000010 | 隐藏 | 00100000 | 存档 |
00000100 | 系统 |
⑤0x08 ~ 0x0B:文件创建时间。该参数是文件的具体创建时间,格式为 32 位的 DOS 时间,包括年、月、日、时、分、秒,具体表示方法与 FAT 文件系统一样,这里就不再重复讲述。
⑥0x0C ~ 0x0F:文件最后修改时间。该参数是文件最后一次修改时的具体时间,格式为 32 位的 DOS 时间,包括年、月、日、时、分、秒,具体表示方法跟 FAT 文件系统一样,这里就不再重复讲述。
⑦0x10 ~ 0x13:文件最后访问时间。该参数是文件最后一次访问时的具体时间,格式为 32 位的 DOS 时间,包括年、月、日,也包含时、分、秒,这一点跟 FAT 不一样,FAT 中改时间只有年、月、日,没有时、分、秒。
⑧0x14 ~ 0x14:文件创建时间,精确至 10ms。该参数是文件的具体创建时间精确到 10ms 的数值。
“属性 2”目录项
“属性 2”目录项用来记录文件是否有碎片、文件名的字符数、文件名的 Hash 值、文件的起始簇号及大小等信息。
用户文件的“属性 2”目录项如图所示。
用户文件的“属性 2”目录项的含义
字节偏移 | 字段长度(字节) | 内容及含义 |
---|---|---|
0x00 | 1 | 目录项的类型(“属性 2”目录项的特征值为“C0H”) |
0x01 | 1 | 文件碎片标志 |
0x02 | 1 | 保留 |
0x03 | 1 | 文件名字符数 N |
0x04 | 2 | 文件名 Hash 值 |
0x06 | 2 | 保留 |
0x08 | 8 | 文件大小 1 |
0x10 | 4 | 保留 |
0x14 | 4 | 起始簇号 |
0x18 | 8 | 文件大小 2 |
①0x00 ~ 0x00:类型。该参数为目录项类型的特征值,“属性 2”目录项的特征值为“C0H”。
②0x01 ~ 0x01:文件碎片标志。该参数能够反映出文件是否连续存放。如果是连续存放没有碎片,该标志为 03H;如果不是连续存放,文件有碎片,该标志就为 01H。
③0x03 ~ 0x03:文件名字符数。该参数用来说明文件名的长度,ExFAT 文件系统的文件名用 Unicode 码表示,每个字符占用两个字节。
④0x04 ~ 0x05:文件名 Hash 值。该参数是根据相应算法算出的文件名的校验值,当文件名发生改变时,Hash 值也会发生改变,但当文件移动时,该值并不改变。
⑤0x08 ~ 0x0F:文件大小 1。该参数是文件的总字节数,用 64 位记录文件大小。
⑥0x14 ~ 0x17:起始簇号。该参数描述文件的起始簇号,用 32 位记录簇的地址。
⑦0x18 ~ 0x1F:文件大小 2。该参数也是文件的总字节数,是为 NTFS 文件系统的压缩属性准备的,一般情况下与“文件大小 1”的数值保持一致。
“属性 3”目录项
“属性 3”目录项用来具体记录文件的名称。如果文件名很长,“属性 3”可以包含多个目录项,每个目录项称为一个片段,从上至下依次记录文件名的每一个字符,记录的方向刚好跟 FAT 文件系统中长文件名目录项从下至上的顺序相反。
用户文件的“属性 3”目录项的含义
字节偏移 | 字段长度(字节) | 内容及含义 |
---|---|---|
0x00 | 1 | 目录项的类型(“属性 3”目录项的特征值为“C1H”) |
0x01 | 1 | 保留 |
0x02 | 2N | 文件名 |
因为该文件名很短,所以只有一个片段,如果文件名足够长,则有多个“属性 3”(C1H)。