GPT 分区表(GUID Partition Table)
大容量设备与现代系统的分区方案,EFI 标准的一部分。U 盘场景遇到 GPT 的典型情况:
- 容量 > 2TB(MBR 的 32 位 LBA 上限约 2.2TB,超了必须 GPT)
- Mac / Linux 上制作或格式化的 U 盘
- Windows To Go、多分区 U 盘(Win10 1703+)
特征:LBA 0 是保护性 MBR(唯一表项类型 0xEE),真正的分区信息在 LBA 1 的 GPT 头和随后的分区表项里,盘尾还有一整套备份。
整体布局
LBA 0 ┌──────────────────────────────┐
│ 保护性 MBR(类型 0xEE) │ ← 骗过旧工具,别去解析它
LBA 1 ├──────────────────────────────┤
│ GPT 头(Primary Header) │ ← "EFI PART",取证核心
LBA 2~33 ├──────────────────────────────┤
│ 分区表项 128 项 × 128 字节 │ ← 默认占 32 个扇区
LBA 34~ ├──────────────────────────────┤
│ 分区数据区 │ ← 实际首分区通常对齐到 LBA 2048
├──────────────────────────────┤
LBA -33~-2 │ 备份分区表项 │
LBA -1 ├──────────────────────────────┤
│ 备份 GPT 头(Backup Header) │ ← 主表损坏时的救命稻草
└──────────────────────────────┘
保护性 MBR(LBA 0)
结构与普通 MBR 相同,但只有一条类型 0xEE 的表项,声明”全盘被一个 GPT 分区占用”(扇区数超 32 位时填 0xFFFFFFFF)。作用仅是让不认识 GPT 的旧工具(如老 fdisk)认为盘已被占用,防止误格式化。
取证判读:MBR 里看到 0xEE → 立即跳转 LBA 1 验证 "EFI PART" 签名;0xEE 存在但 LBA 1 没有签名 → 主头被擦除,先去盘尾找备份头。
GPT 头(LBA 1,共512字节,有效 92 字节)
typedef struct _GPT_HEADER { // 共92字节有效,扇区剩余部分置0
CHAR Signature[8]; // +0x00 "EFI PART" (45 46 49 20 50 41 52 54)
DWORD Revision; // +0x08 版本,通常 0x00010000
DWORD HeaderSize; // +0x0C 头大小 = 92 (0x5C)
DWORD HeaderCRC32; // +0x10 头的CRC32 ← 校验时此字段先按0算
DWORD Reserved; // +0x14 必须为0
QWORD CurrentLBA; // +0x18 本头所在LBA(主头=1,备份头=最后扇区)
QWORD BackupLBA; // +0x20 对方头的LBA(主头中=盘最后扇区)
QWORD FirstUsableLBA; // +0x28 数据区起点(通常34)
QWORD LastUsableLBA; // +0x30 数据区终点(通常倒数34扇区)
BYTE DiskGUID[16]; // +0x38 磁盘GUID ← 取证关联点
QWORD PartTableLBA; // +0x48 分区表起始LBA(主表中=2)
DWORD PartEntryCount; // +0x50 表项数(通常128)
DWORD PartEntrySize; // +0x54 每项字节数(通常128=0x80)
DWORD PartTableCRC32; // +0x58 分区表整体的CRC32
} GPT_HEADER;分区表项(每项 128 字节,默认 128 项)
typedef struct _GPT_ENTRY { // 共128字节
BYTE PartTypeGUID[16]; // +0x00 分区类型GUID,全0=空表项
BYTE UniqueGUID[16]; // +0x10 本分区唯一GUID ← 挂载记录关联点
QWORD FirstLBA; // +0x20 分区起始LBA ← 重点
QWORD LastLBA; // +0x28 分区结束LBA(含本扇区)← 重点
QWORD AttrFlags; // +0x30 属性位
WCHAR PartName[36]; // +0x38 分区名(UTF-16LE,72字节)
} GPT_ENTRY;与 MBR 的关键差异:没有 CHS、没有扩展分区/EBR、没有 4 个分区的上限;“删除分区”只是把类型 GUID 清零。
GUID 字节序陷阱(手工解析必踩)
GPT 中 GUID 的前三段按小端存储,后两段原样(mixed-endian)。例如 Microsoft Basic Data 的 GUID:
标准写法: EBD0A0A2-B9E5-4433-87C0-68B6B72699C7
盘上字节: A2 A0 D0 EB E5 B9 33 44 87 C0 68 B6 B7 26 99 C7
└──小端──┘ └小端┘ └小端┘ └────── 原样 ──────┘
010 Editor 等模板会自动转换;手工比对时必须先转,否则所有 GUID 都”对不上”。
常见分区类型 GUID
| GUID(标准写法) | 含义 |
|---|---|
| 00000000-0000-0000-0000-000000000000 | 空表项 |
| EBD0A0A2-B9E5-4433-87C0-68B6B72699C7 | Microsoft Basic Data(FAT/exFAT/NTFS 共用,需进 DBR 分辨) |
| C12A7328-F81F-11D2-BA4B-00A0C93EC93B | EFI 系统分区(ESP,FAT32) |
| E3C9E316-0B5C-4DB8-817D-F92DF00215AE | Microsoft 保留分区(MSR) |
| DE94BBA4-06D1-4D40-A16A-BFD50179D6AC | Windows 恢复分区 |
| 0FC63DAF-8483-4772-8E79-3D69D8477DE4 | Linux 文件系统 |
| 0657FD6D-A4AB-43C4-84E5-0933C84B4F4F | Linux swap |
| 48465300-0000-11AA-AA11-00306543ECAC | Apple HFS+ |
| 7C3457EF-0000-11AA-AA11-00306543ECAC | Apple APFS |
属性位(AttrFlags)
| 位 | 含义 |
|---|---|
| bit 0 | 平台必需分区(系统启动依赖) |
| bit 1 | EFI 忽略该分区 |
| bit 2 | Legacy BIOS 可引导 |
| bit 60 | 只读 |
| bit 62 | 隐藏(Windows 不显示) |
| bit 63 | 不自动分配盘符 |
bit 62/63 置位说明有人故意让系统不挂载这个分区——取证中遇到必须手工按 LBA 范围提取。
手工解码示例
GPT 头(LBA 1)前 16 字节:
45 46 49 20 50 41 52 54 00 00 01 00 5C 00 00 00
└──────┬──────────────┘ └────┬────┘ └────┬────┘
"EFI PART" 版本1.0 头大小=0x5C=92
一条分区表项(LBA 2 起):
A2 A0 D0 EB E5 B9 33 44 87 C0 68 B6 B7 26 99 C7 ← 类型GUID:EBD0A0A2-...(Microsoft Basic Data)
28 57 DE 71 22 68 CB 43 A2 37 2B BF 47 1F 04 8C ← 唯一GUID
00 08 00 00 00 00 00 00 FF F7 3D 00 00 00 00 00 ← FirstLBA=0x800=2048,LastLBA=0x3DF7FF
00 00 00 00 00 00 00 00 ← 无属性位
55 00 73 00 62 00 64 00 69 00 73 00 6B 00 ... ← 分区名 "usbdisk"(UTF-16LE)
→ 分区范围 = 扇区 2048 ~ 0x3DF7FF,文件系统入口偏移 = 0x800 × 512 = 0x100000。
备份机制与修复(取证高频)
- GPT 头中有
BackupLBA指向盘尾备份头,备份头再指向备份分区表(主表之后是镜像排列)。 - 主表损坏/被擦除:
gdisk打开时会自动提示用备份恢复;sgdisk -b可先备份现有结构再动。手工场景:从盘尾倒数第 1 扇区读备份头 → 其PartTableLBA指向备份表。 - CRC 校验定位坏点:头 CRC 坏但表 CRC 好 → 只坏头;反之只坏表。两者都对但内容不同 → 主备不一致,说明被手工改过(篡改/藏数据线索)。
- 用备份修复后,记得修复动作本身会写入磁盘——取证只读副本上操作,原件不动。
取证要点
- DiskGUID(头 0x38)和分区 UniqueGUID 都可与 Windows 注册表
HKLM\SYSTEM\MountedDevices关联(GPT 盘的挂载值含 GUID 而非磁盘签名),证明”这个盘插过这台电脑”。 - 头中
CurrentLBA/BackupLBA/LastUsableLBA与实际镜像大小不符 → 镜像被截断,或盘被扩容造假(小卡刷大容量)。 - 藏数据区:
LastUsableLBA之后到备份表之间、128 个表项中未使用的槽位(可能残留旧表项的非 GUID 字段)、表项首尾 LBA 之间的缝隙。 - 空表项只清类型 GUID,
PartName等字段常残留 → 可推断曾经存在过的分区名称与范围。 - 属性位 bit 62/63 的分区系统不挂载,取证工具可能也不自动列——按 LBA 手工提取。
- Hybrid MBR(Mac 制作常见):LBA 0 同时有 0xEE 和真实 DOS 分区表项,两套表可能不一致,两个视角都要解析。
- 工具侧:
mmls显示GUID Partition Table (EFI);X-Ways/FTK 均原生支持,主表坏时会提示是否使用备份。