最近在研究FAT32 格式,研究的目标是一个256MB容量的虚拟硬盘。
最开始发现资料和手上的结果多有出入无法对的上。经过两天的研究恍然大悟:对不上是因为这个硬盘在FAT前面还有分区信息,就是说对于一个硬盘来说要先读取分区的划分信息,比如第一个分区是FAT32,第二个分区是NTFS……..之后再根据不同的分区类型解析出文件内容。
目前主流分区有2种:一种是传统的 MBR;另外一种是比较新的 GPT。这次实验的硬盘是GPT 分区。
硬盘整体数据分布如下,解析是从左到右的顺序:
布局分布【参考1】
为了方便查看数据,使用 WinHex 这个磁盘工具。
1.使用WinHex进行查看,打开硬盘:
2.可以看到这个U盘上有“Start Sectors” 、“Partition 1(e:)”和“Partition gap”三块内容。对于OS来说 Partition 1 就是展现给用户的 e盘。
3.具体分析
3.1 Start Sectors 对应着LBA 0-33,使用WinHex 自带模板分析
分析结果如下:
这是一个保护性的“假MBR”,作用是防止不识别GPT分区的格式意外破坏分区。0x0-0x1FF偏移(在LBA0中):提供了一个 Partition 的数组, EDK2示例代码会检查这里确定是“假MBR”;0x200-0x258 偏移(在LBA1中):给出第一个分区信息表的入口(Partition Entry LBA),一般为2,意思是这个信息表入口在 LBA 2 上;0x400-0x4A0偏移(在 LBA2中):给出第一个分区的入口(Starting LBA),这里可以看到第一个分区从 LBA 2048(D)开始
3.2 选中第一个分区,可以看到它位于 0x100000处(也就是 LBA 2048 处)。同样的继续使用内置模板进行查看获得基本信息
从上面我们可以看到,从这个位置开始 Reserved 了6190(D)个扇区,因此可以知道第一个FAT在LBA:2048+6190=8238(D)。查看 LBA 8238 (D)这个位置 ,看到的就是 FAT 表。下图框出来的就是每一个文件项。第一个簇标记为 0xFFFFFFF8,第二个簇为0xFFFFFFFFF(0号FAT项为肮脏标志;1号FAT项是一个结束标志,通常簇号是从2开始就是这个原因)。其余的0xFFFFFF0F表示这个簇对应的是目录或者文件的结尾。之前我们的讨论都是以扇区为单位的,等到了研究文件时,通常需要以簇为单位,二者之间的换算关系是 Sector Per cluster 参数给出的。例如,这个值为4,就表示1个Cluster 由4个Sector 组成。
3.3 上面的概念不太容易理解,直接跳到数据区来进行查看。数据区的开始在:2048+6190+1001+1001=10240 扇区的位置:
可以隐约看到右侧ASCII字符就是我们FAT32分区上的根目录(下图是切换到D: 的示意图,注意物理硬盘和分区上的扇区不同,本文都是以物理硬盘的扇区号为准):
我们知道 EFI 目录下有 BOOT 目录,其中有 BOOTX64.EFI 这个文件。我们下面的目标就是获得这个文件的内容。首先,移动光标到前面的 EFI 目录字样处
从菜单上选择模板 :
查看目录信息 如下:
目录EFI 的数据在数据区起始扇区号+(簇号-2)*(扇区数/簇)
6号簇的绝对LBA就是 10240+(6-2)*4==10256扇区
上面可以看到 BOOT 这个目录,再使用模板解析BOOT目录的数据
可以看到 BOOT 目录的数据位于9号簇,对应的绝对扇区是10240+(9-2)*4==10268
再查看这个扇区
这里就能看到 BOOTX64.EFI 文件了,再用模板解析 BOOTX64.EFI 的数据:
最终查看10240+(10-2)*4==10272扇区,就是 BOOTX64.EFI 的内容
从 10272到10275 是10号簇,接下来需要到 FAT中查看,可以看到下面的位置指向了11号簇,就是说BOOTX64.EFI 文件并未完结,接下来的内容可以在11号簇所在扇区
参考: