前言

现在,你已经学会了简单的修复 MBR,迈出了数据恢复的第一步。接下来,我们将了解到 FAT32 格式的分区是如何工作的。

你可以在 https://winhex.im0o.top/ 中查看所有例题文件

知识点总览

  • FAT32 分区构成
  • 实例:导出损坏分区 FAT32 中的文件
  • 实例:恢复 FAT32 分区(手动填写 FAT32 分区的 DBR)
  • EBR 的组成

FAT32 分区的构成

​ FAT32 文件系统是从微软 Windows 95 系统的 OSR2 版本开始使用的,它能够支持大于 32MB 小于 32GB 的分区。虽然第三方的格式化程序可以把超过 32GB 的分区格式化为 FAT32,但微软自身的系统不允许将大于 32GB 的分区格式化为 FAT32 文件系统。

​ FAT32 文件系统由保留扇区(包含 DBR 以及其备份等),FAT 表 1,FAT 表 2,数据区四个部分组成,下图为其结构示意图:

fat32Jiegou

DBR 及其保留扇区

​ FAT32 文件系统的 DBR 开始于其第一个扇区,由 5 个部分组成,分别为跳转指令、OEM 代号、BPB、引导程序和结束标志,下图为一个完整的 FAT32 文件系统的 DBR。

fat32dbr

  1. 跳转指令

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

    当前 DBR 中的EB 58代表汇编语言中的JMP 58。需注意,该指令本身占用了 2 字节,计算跳转目标地址时应该以该指令的下一字节为基准,所以执行下一条指令应该位于5A处,紧接着跳转指令的是一条空指令 NOP(90H)。

    由此跳转指令中第二个字节内容可以知道 OEM 代号与 BPB 参数的大小,FAT32 分区即为 90 开始向下 5 行+8 个字节(如下图中选中部分)。

    BPB

  2. OEM 代号

    这部分占 8 个字节,其内容有创建该文件系统的 OEM 厂商具体安排。当前 DBR 中的 OEM 代号为MSDOS5.0

  3. BPB

    FAT32 的 BPB 从 DBR 的第 12(0BH偏移处)个字节开始,占用 79 字节,记录了有关该文件系统的重要信息,其中各个参数的含义为:

    | 字节偏移 | 字段长度(字节) | 对应图中参数 | 字段内容及含义 |
    | ———— | :———————: | :—————————————————-: | ——————————- |
    | 0x0B | 2 | 00 02 | 每扇区字节数 |
    | 0x0D | 1 | 20 | 每簇扇区数 |
    | 0x0E | 2 | 26 00 | DOS 保留扇区数 |
    | 0x10 | 1 | 02 | FAT 表个数 |
    | 0x11 | 2 | 00 00 | 未用 |
    | 0x13 | 2 | 00 00 | 未用 |
    | 0x15 | 1 | F8 | 介质描述符(16 进制) |
    | 0x16 | 2 | 00 00 | 未用 |
    | 0x18 | 2 | 3F 00 | 每磁道扇区数 |
    | 0x1A | 2 | FF 00 | 磁头数 |
    | 0x1C | 4 | 00 30 60 03 | 隐藏扇区 |
    | 0x20 | 4 | 00 48 20 02 | 该分区的扇区总数 |
    | 0x24 | 4 | 01 22 00 00 | 每 FAT 扇区数 |
    | 0x28 | 2 | 00 00 | 标记 |
    | 0x2A | 2 | 00 00 | 版本 |
    | 0x2C | 4 | 02 00 00 00 | 根目录首簇号 |
    | 0x30 | 2 | 01 00 | 文件系统信息扇区号 |
    | 0x32 | 2 | 06 00 | DBR 备份扇区号 |
    | 0x34 | 12 | 00 00 00 00 00 00 00 00 00 00 00 00 | 保留 |
    | 0x40 | 1 | 80 | BIOS 驱动器号 |
    | 0x41 | 1 | 00 | 未用 |
    | 0x42 | 1 | 29 | 扩展引导标记 |
    | 0x43 | 4 | 26 68 E5 DE | 卷序列号 |
    | 0x47 | 11 | 20 20 20 20 20 20 20 20 20 20 20 | 卷标 |
    | 0x52 | 8 | 46 41 54 33 32 20 20 20 | 文件系统类型 |

    下面对这些参数做详细分析:

    1. 0BH~0CH:每扇区字节数

      记录每个逻辑扇区的大小,一般为 512 字节,但 512 不是固定值,该值可以由程序定义,合法值包括 512、1024、2048 和 4096 字节

    2. 0DH:每簇扇区数

      每簇扇区数记录着文件系统的簇大小,即由多少个扇区组成一个簇1

      FAT32 最大支持 128 扇区的簇。

      在 FAT32 文件系统中所有的簇从 2 开始编号,每个簇都有一个自己的地址编号,并且所有的簇都位于数据区内,在数据区之前是没有簇的。

    3. 0EH~0FH:DBR 保留扇区数

      DBR 保留扇区数指 DBR 本身占用的扇区以及其后保留扇区的总和,也就是说 DBR 到 FAT1 之间的扇区总数,也可以说是 FAT1 的相对地址(相对于 DBR)。

    4. 10H:FAT 表个数

      FAT 个数描述了该文件系统中有几个 FAT 表,一般在 FAT32 文件系统中有 2 个 FAT 表,即 FAT1 和 FAT2,FAT2 是 FAT1 的备份。

    5. 11H~12H:未用

    6. 13H~14H:未用

    7. 15H:介质描述符

      介质描述符是描述磁盘介质的参数,根据磁盘性质的不同,取不同的值2

    8. 16H~17H:未用

    9. 18H~19H:每磁道扇区数

      这是逻辑 C/H/S 中的一个参数,其值一般为 63。

    10. 1AH~1BH:磁头数

      这也是逻辑 C/H/S 中的一个参数,其值一般为 255。

    11. 1CH~1FH:隐藏扇区数

      隐藏扇区数是指本分区之前使用的扇区数,该值与分区表中描述的该分区的起始扇区号一致。对于主分区来讲,是 MBR 到该分区 DBR 之间的扇区数;对于扩展分区中的逻辑分区而言,是其 EBR 到 DBR 之间的扇区数3

    12. 20H~23H:扇区总数

      扇区总数是指分区的总扇区数,也就是说 FAT32 分区的大小。

    13. 24H~27H:每 FAT 扇区数

      这四个字节用来记录 FAT32 分区中每个 FAT 表占用的扇区数。

    14. 28H~29H:标志

      这两个字节用于表示 FAT2 是否可用,当其二进制最高位置为 1 时,表示只有 FAT1 可用,否则 FAT2 也可用。

    15. 2AH~2BH:版本

      这两个字节通常为 0。

    16. 2CH~2FH:根目录首簇号

      分区在格式化 FAT32 文件系统时,格式化程序会在数据区中指派一个簇作为 FAT32 根目录区的开始,并把该簇号记录在 BPB 中。通常斗士把数据区的第一个簇分配给根目录使用,也就是 2 号簇。

    17. 30H~31H:文件系统信息扇区号

      FAT32 文件系统在 DBR 的保留扇区安排了一个文件系统信息扇区,用以记录数据区中空闲簇的数量及下一个空闲簇的簇号,该扇区一般在分区的 1 号扇区,即紧跟 DBR 后的一个扇区。

    18. 32H~33H:DBR 备份扇区号

      FAT32 文件系统在 DBR 保留扇区中安排了一个 DBR 的备份,一般在 6 号扇区,也就是第 7 个扇区。该备份与原 DBR 的内容一摸一样,如果原 DBR 遭到破坏,可以用备份扇区修复。

    19. 34H~3FH:保留

    20. 40H:BIOS 驱动器号

      这是 BIOS 的 INT 13H 所描述的设备号码,一般把硬盘定义为 8xH。

    21. 41H:未用

    22. 42H:扩展引导标记

      扩展引导标记用来确认后面的三个参数是否有效,一般值为 29H。

    23. 43H~46H:卷序列号

      卷序列号是格式化程序在创建系统是生成的一组 4 个字节的随机数值。

    24. 47H~51H:卷标

      卷标是由用户在创建文件系统时指定的一个卷的名称,但这是旧系统所记录的位置,现在的系统已经不再使用这个位置记录卷标,而是由一个目录项管理卷标。

    25. 52H~59H:文件系统类型

      BPB 的最后一个参数,直接用 ASCII 码记录当前分区的文件系统类型。

  4. 引导程序

    FAT32 的 DBR 引导程序占用 420 字节(5AH~1FDH)),在 Windows 98 之前的系统之下,这段代码负责完成 DOS 三个系统的装入,在 Windows 2000 之后的系统中,其负责完成将系统文件 NTLDR 装入,对于一个没有安装操作系统的分区来讲,这段程序没啥用处…

  5. 结束标志

    DBR 的结束标志与 MBR、EBR 的结束标志相同,都是55 AA

FAT 表

FAT(File Allocation Table)即文件分配表,对于 FAT 文件系统来讲是非常重要的一个组成部分,其主要作用及特点如下:

  1. FAT 文件系统一般有 2 个 FAT 表,FAT1 是活动 FAT,FAT2 是备份。
  2. FAT1 的大小与 FAT2 相同,因此我们可以通过算出 FAT1 的大小在 FAT2 处跳转这么多到达数据区。
  3. FAT 表是由 FAT 表项构成的,我们把 FAT 表项简称为 FAT 项,每个 FAT 项的大小有 32 位(4 字节)。
  4. 每个 FAT 项都有一个固定的编号,这个编号从 0 开始。也就是说,第一个 FAT 项为 0 号 FAT 项,第二个 FAT 项为 1 号 FAT 项,以此类推。
  5. FAT 表的前两个 FAT 项有专门的用途:0 号 FAT 项用于存放分区所在的介质类型,例如硬盘的类型为“F8”,那么硬盘上分区的 FAT 表第一个 FAT 项就以“F8”开始;1 号 FAT 项则用来存储文件系统的肮脏标志,表明文件系统被非法卸载或者磁盘表面存在错误。
  6. 分区中每一个簇的适应情况都会映射到 FAT 表中的唯一一个 FAT 项。因为 0 号 FAT 项和 1 号 FAT 项和 1 号 FAT 项有特殊用途,无法与数据区中的簇形成映射,因此,数据区中的第一个簇的编号对应 FAT 表中的 2 号 FAT 项,以此类推。

总的来说,FAT 表是用来表示分区使用情况的一个部分,我们可以通过 FAT 表来计算 FAT 分区的大小。

fat1

上图为FAT32文件系统中的FAT1

数据区

  1. 数据区的位置

    FAT32 的数据区在文件系统中的具体位置是紧跟在 FAT2 之后的。

    以下为详细流程:

    ① 系统通过读取 MBR 中分区表的信息定位到该分区的 DBR 扇区;

    ② 读取 DBR 的0EH~0FH偏移处,得到DBR 保留扇区数的值为 38;

    ③ 读取 DBR 的24H~27H偏移处,得到FAT 表大小的值为 8705;

    ④ 用DBR保留扇区数+2*FAT表大小,结果等于 17448,从 DBR 向后跳转 17448 扇区,这里就是数据区的开始。

  2. 数据区的内容

    FAT32 文件系统数据区的内容主要由三个部分组成:根目录、子目录和文件内容。在数据中是以1为单位来管理这段空间的。

    FAT32数据区根目录
  3. 目录项

    在 FAT32 文件系统下,分区根目录下的文件及文件夹的目录项存放在根目录区中,分区子目录下的文件及文件夹的目录项存放在子目录区中,根目录区和子目录区都在数据区中。

    1)短文件名目录项

    上图是一条文件目录项,目录项占 32 字节,从 Winhex 中看(默认)是两行数据。

    让我们来分析下这条目录项的含义:

    | 字节偏移 | 字段长度(字节) | 字段内容及含义 |
    | ———— | :———————: | ——————————————————————————— |
    | 0x00 | 8 | 主文件名 |
    | 0x08 | 3 | 文件的扩展名 |
    | 0x0B | 1 | 文件属性
    (读写/只读/隐藏/系统/卷标/子目录/存档) |
    | 0x0C | 1 | 未用 |
    | 0x0D | 1 | 文件创建时间精确到 10ms 的值 |
    | 0x0E | 2 | 文件创建时间,包括时、分、秒 |
    | 0x10 | 2 | 文件创建日期,包括年、月、日 |
    | 0x12 | 2 | 文件最近访问日期,包括年、月、日 |
    | 0x14 | 2 | 文件起始簇号高位(高位簇) |
    | 0x16 | 2 | 文件修改时间,包括时、分、秒 |
    | 0x18 | 2 | 文件修改日期,包括年、月、日 |
    | 0x1A | 2 | 文件起始簇号的低位(低位簇) |
    | 0x1C | 4 | 文件大小(字节) |

    1. 00H~07H:主文件名共占8字节,如果文件名(不包含扩展名)用不完 8 字节,后面用空格填充4。图中主文件名为IM0O

      另外该位置的第一个字节也用来表示目录项的分配状态,当该字节是00时,表示该目录项从未使用过;当该字节是E5时,表示该目录项曾经使用过,但目前已经被删除。

    2. 08H~0AH:文件的扩展名

      文件的扩展名共占3字节,文件夹没有扩展名,如果是文件夹的目录项,该位置会被空格填充。图中的扩展名为JPG

    3. 0BH:文件属性5

      文件属性占 1 字节(8bit),可以用来表示文件的各种属性。

    \<\<返回目录项类型

    2)长文件名目录项

    上图为一个长文件名文件的目录项,图中长文件的文件名为System Volume Info...

    示例文件名SHUJUHUIFU.txt

    在 Windows 95 开始,文件名”8.3“格式的限制被打破了,文件名可以超过 8 个字符,并且可以使用中文了,扩展名也可以超过 3 字节,这种格式的文件名就称为长文件名。

    在 Windows 95 以上的系统中,长文件名实际存储着两个名字,一个短文件名和一个长文件名。当创建一个长文件名时,其对应的短文件名有以下 3 个处理原则。

    • 系统取长文件名的前 6 个字符加上~1形成短文件名,其扩展名不变;

    图中取前六个字符SHUJUH

    • 如果已存在这个名字的文件,则符号~后的数字自动增加;

    例如:SHUJUH~1TXTSHUJUH~2TXT

    • 如果有 DOS 和 Windows 3.x 非法的字符,则以下划线_替代。
    • 每个长文件名目录项也占用 32 字节,一个目录项作为长文件名目录项使用时,其属性字节值为 0FH,能够存储 13 个字符,如果文件名很长,一个长文件名就需要多个目录项,这些目录项按倒序排列在其短文件名目录项之前。

    如图中标明的顺序

    | 字节偏移 | 字段长度(字节) | 字段内容及含义 |
    | ———— | :———————: | ————————————————— |
    | 0x00 | 1 | 序列号 |
    | 0x01 | 10 | 文件名的第 1~5 个 Unicode 码字符 |
    | 0x0B | 1 | 长文件名目录项的属性标志 |
    | 0x0C | 1 | 保留未用 |
    | 0x0D | 1 | 短文件名校验 |
    | 0x0E | 12 | 文件名的第 6~11 个 Unicode 码字符 |
    | 0x1A | 2 | 始终为 0 |
    | 0x1C | 2 | 文件名的第 12~13 个 Unicode 码字符 |


      1. 序列号(00)

      序列号占 1 字节,该参数用来描述长文件名目录项的排序。

      在这个字节的 8 位中,0~4 这 5 位用来描述长文件名目录项的顺序号,从 1 开始编号。6 位(也就是说第 7 位)如果“1”表明该目录项是最后一项。如果文件删除,该字节也会改为E5

      1. 文件名的第 1~5 个 Unicode 码字符

      该参数长度为 10 字节(因为 Unicode 编码储存字符时每个字符占用 2 字节)。

      如果文件名已经记录完,但该参数的空间中还有未用的字节,就会在文件名最后一个字节填充 2 个字节的00,随后未用的字节用FF填充。

      1. 长文件名目录项的属性标志

      该参数长度为 1 字节,是属性字节。当属性的只读位、隐藏位、系统位、卷标位全为 1,其它全为 0 是,改制就为 16 进制的0FH,表示该目录项为长文件名记录项。

      1. 未用

      该字节不使用。

      1. 短文件名校验和

      该参数长度为 1 字节,是个校验和,长文件名目录项通过这个校验和将其与相应的短文件名目录项关联起来。校验和的数值是使用短文件名计算得到,同 文件的长文件名目录项的校验和必须是相 向的。校验和的计算方法是依次将短文件名的各个字符对应的二进制值相加,在每一步相加前要先将二进制的结果值依次向右移动一位,最右边的位循环移动到最左边,然后再加上下一个字符所对应的二进制值,直到把最后一个字符加完,结果就是校验和的数值。

      1. 文件名的第 6~11 个字符

      同[2.]

    ③ 号长文件名目录项的首字节为42H,换算为二进制等于01000010,其 0~4 位的值为00010,说明这是第二个长文件名目录项,6 位上的值是1,说明这是最后一项长文件名目录项。

    ②、③ 两条长文件名目录项的结构一样,以倒序的方式排列在其短文件名目录项之前,完整地记录了文件名shujuhuifu.txt

    \<\<返回目录项类型

    3).目录项和..目录项

    子目录所在的文件目录项区域中,总有两个特殊的目录,它们就是...

    使用 DOS 命令dir可以看到这两个目录

    .表示当前目录

    ..表示上级目录

    在 winhex 中查看.目录与..目录的目录项:

    其中 0x00H~0x1FH 为.目录的目录项,0x20H~0x3FH 为..目录的目录项

    图为两个目录项的在模板管理器中的效果

    从这两个目录项的实际数据可以得知:

    1. .目录项所描述的起始簇号是子目录本身所在的簇号。
    2. ..目录项所描述的起始簇号是上级目录的起始簇号,如果上级目录是根目录,则该值为0
    3. 所有目录的文件大小都是0

    \<\<返回目录项类型

    4)卷标目录项

    卷标就是一个分区的名字,可以在格式化分区时创建,也可以随时修改。

    ① 对于 FAT 格式的分区,卷标的长度最多为 11 字节,若果卷标为中文,则最多支持 5 个字符。

    ② 卷标的目录项中不记录簇号和大小。

    ③ 卷标的目录项中不记录创建时间和最后访问时间,只记录修改时间。

    \<\<返回目录项类型

实例:导出损坏分区 FAT32 中的文件

  1. 导入题目FAT32-19123.vhd后用 Winhex 打开

题库/FAT32-191203

fat32.png

  1. 填写结束标志,跳转到 FAT32 分区

首先填写 MBR 主引导记录所缺失的结束标志55 AA。接着查看分区表中的第一个分区,并跳转到该分区。

image.png

从残留的 DBR 中,可以看出该分区为 FAT32,其每簇扇区数为32

  1. 向下搜索!00

使用快捷键Ctrl+Alt+x向下搜索 16 进制数值!00(非零),可以搜索到根目录。

在根目录中发现需要找到的文件,查看其高位簇,低位簇(位置)和大小,导出文件即可

box.png在 3 号簇,大小为 3,752 字节

box.txt在 4 号簇,大小为 283 字节

跳转到对应位置后选中对应大小,右键>>编辑>>复制选快>>至新文件

导出文件步骤(gif有录制时有点问题)

在本题中有一道附加题,即恢复分区2。

实例:恢复 FAT32 分区(手动填写 FAT32 分区的 DBR)

  1. 导入题目FAT32-191226.vhd后用 Winhex 打开

题库/FAT32-191226

  1. 填写结束标志55 AA,向下搜索非 0,确定分区类型与 DBR 位置

打开虚拟磁盘后,我们发现 MBR 的分区表结束标志被清空,首先,填写结束标志55 AA

保存后重新加载虚拟磁盘,点选到 00 处,向下搜索非零。

根据 FAT32 分区的特征:RRaA,可以判断处该扇区前一个扇区为 FAT32 分区的 DBR。

  1. 计算 FAT32 分区所必须的数值

    1. 计算 FAT32 分区保留区大小

      在 FAT32 分区头部有一部分区域为保留区,在填写 DBR 时我们需要填写保留区大小值,所以我们需要计算保留区的大小。

      • 向下搜索F8FF

      F8FF为 FAT 文件系统中FAT 表的标识,我们通过找到FAT 表的位置后将FAT 表位置减去DBR 位置得到保留区大小

      • 复制 FAT 表位置 2086

      • 复制 DBR 位置 2048

      • FAT 表位置减去DBR 位置得到保留区大小38

    2. 计算 FAT32 分区 FAT 表大小

      填写 DBR 时还需要填写FAT表的大小,那么如何计算 FAT 表的大小呢?

      • 记录 FAT1 的位置2086,向下搜索F8FF

        FAT1 与 FAT2 的标识符均为 F8FF,用FAT2 的位置减去FAT1 的位置即可得到FAT 表的大小

      • 记录 FAT2 的位置27687

      • FAT2 的位置减去FAT1 的位置得到FAT 表的大小25601

    3. 计算 FAT32 分区每簇扇区数

      • 跳转到数据区

        FAT2向后跳转FAT 表大小即可达到数据区

      • 记录数据区的位置:53288,该位置为根目录(数据区中的首个扇区)

      • 点击空余处,向下搜索非 0,搜索到下一簇的目录,位置为53416

      • 相邻的子目录的位置减去根目录的位置得到每簇扇区数128

    4. 计算 FAT32 分区大小

      得到以上参数后我们就可以计算最后需要填写到 DBR 内的参数——分区大小

      (FAT表大小-1)x128x每簇扇区数+保留区大小即可得到该分区的大小。

      需注意,这个大小会比分区时的分区大小稍小一点,不过不影响分区中的文件(除非你用满了整个分区)

      • 通过计算,我们得到该FAT 分区的大小419430438扇区
  2. 填写 DBR

    1. 填写跳转指令EB 58 90

      在 DBR 扇区起始处填写 FAT32 分区的跳转指令

    2. 填写每扇区字节数 512

      0x0B处(2 字节)填写每扇区字节数,默认为 512

    3. 填写每簇扇区数128

      0x0D处(1 字节)填写每簇扇区数,本题为128

    4. 填写保留区大小38

      0x0E处(2 字节)填写保留区大小,本题为38

    5. 填写FAT 表个数2

      0x10处(4 字节)填写 FAT 表个数,默认为2

    6. 填写磁盘介质F8

      0x15处(1 字节)填写磁盘介质,默认为F8

    7. 填写分区位置2048

      0x1C处(4 字节)填写分区位置,本题为2048

    8. 填写分区大小419430438

      0x20处(4 字节)填写分区大小,本题为419430438

    9. 填写FAT 表大小25601

      0x24处(4 字节)填写 FAT 表大小,本题为25601

    10. 填写根目录首簇号2

      0x2C处(4 字节)填写根目录首簇号,默认为2

    11. 填写文件系统标识FAT32(ASCII)

      0x52处填写文件系统标识,在 ASCII 栏处直接填写FAT32即可

    12. 填写结束标志55 AA

      在扇区结尾处填写55 AA结束标志

    • 下图为填写 FAT32 文件系统 DBR 全过程。

    • 至此,你已经恢复了分区 1
  3. 从 DBR 向后跳转分区大小,恢复分区 2

    • 恢复分区 2 的步骤与分区 1 相同

EBR 的组成

在上篇文章中我们了解到了扩展分区的结构,以及其在整个磁盘中的作用。本节我们将了解 EBR 具体的组成。

image-20211206091143875

可以看到,EBR 中含有与 MBR 主引导记录中相似的分区表,通常最多有两个分区表项。

第一个分区表项类同与 MBR 主引导记录中的分区表格式,不过需要注意的是:扩展分区中的逻辑分区无法成为活动分区。

第二个分区表项用来链接下一个 EBR 扇区,下图为一个扩展分区的结构

image-20211206091355096

从上图中可以看出,逻辑分区后无扩展分区的情况时,逻辑分区前的扩展分区无第二个分区表项

分区表项 1 的作用同等于 MBR 中的分区表项,所以在这里我们查看分区表项 2

所谓扩展分区,严格地讲它不是一个实际意义的分区,它仅仅是一个指向下一个用来定义分区的参数的指针,这种指针结构形成一个单向链表。

扩展分区的分区表项 2 是用来指向下一个 EBR 的位置与大小。

下图为一个磁盘的 EBR 结构。

扩展分区的结构分析

需要注意的是:EBR 中的位置参数均是以 EBR1(扩展分区的首位置)相对偏移的位置。

图床 404 部分图片丢失无法找回 博客已根据现有图片进行部分内容修改 部分无法找回的图片丢失


  1. 分区中的簇:文档
  2. 磁盘介质描述符:文档
  3. 不过该值不严谨,填写时可以直接填其绝对位置
  4. 空格在 16 进制中的数值为20H
  5. FAT32 目录项的文件属性:文档