MBR 扇区(LBA 0,共512字节)

MBR 负责描述”这个盘上有几个分区、每个分区从哪里开始”。取证第一步就是解析它,拿到分区的起始扇区(后续所有文件系统解析都基于这个偏移)。

但注意:U 盘有 MBR 和无 MBR 两种布局——后者(superfloppy,0 扇区直接是 DBR)在消费级 U 盘中同样常见,详见下文「无分区表(superfloppy)」一节。

偏移        内容
0x000  ┌─────────────────────────────┐
       │  引导代码 (446字节)           │
       │  其中 0x1B8: 磁盘签名(4字节)  │ ← Windows 写入,注册表 MountedDevices 可关联
0x1BE  ├─────────────────────────────┤
       │  分区表 (64字节 = 4项×16字节) │ ← 取证核心
0x1FE  ├─────────────────────────────┤
       │  结束标志 0x55AA (2字节)      │
0x200  └─────────────────────────────┘

C 结构体表示:

typedef struct _MBR_SECTOR {            // 共512字节
    BYTE    BootCode[440];              // 引导代码,恶意软件可能藏在这里
    DWORD   DiskSignature;              // 0x1B8 磁盘签名(Windows写入,取证关联点)
    WORD    Reserved;                   // 0x1BC 通常为0
    PART_ENTRY PartitionTable[4];       // 0x1BE 4个分区表项,每项16字节
    WORD    Signature;                  // 0x1FE 固定 0x55AA (小端显示为 55 AA)
} MBR_SECTOR;

分区表项(每项16字节,共4项)

这是核心结构,四个表项分别位于 0x1BE、0x1CE、0x1DE、0x1EE:

typedef struct _PART_ENTRY {            // 共16字节
    BYTE    BootFlag;                   // +0x00 引导标志: 0x80=活动分区(可引导) 0x00=非活动
    BYTE    StartHead;                  // +0x01 起始磁头
    BYTE    StartSector : 6;            // +0x02 低6位: 起始扇区(1~63)
    WORD    StartCylHigh : 2;           // +0x02 高2位 + +0x03: 起始柱面(共10位)
    BYTE    PartType;                   // +0x04 分区类型 ← 重点
    BYTE    EndHead;                    // +0x05 结束磁头
    BYTE    EndSector : 6;              // +0x06 低6位: 结束扇区
    WORD    EndCylHigh : 2;             // +0x06 高2位 + +0x07: 结束柱面
    DWORD   LBAStart;                   // +0x08 分区起始扇区号(LBA,小端) ← 重点
    DWORD   TotalSectors;               // +0x0C 分区总扇区数(小端) ← 重点
} PART_ENTRY;

CHS 寻址早已废弃,现代设备只看后 8 个字节(LBAStart + TotalSectors),CHS 字段通常填 0xFEFFFF 之类的最大值。CTF 中如果 LBA 字段被清零而 CHS 还在,就是让你手工解码 CHS 的题。

分区类型值(PartType,1字节)

值含义
0x00空表项
0x01FAT12
0x04FAT16(<32MB)
0x06FAT16(CHS 大容量)
0x07NTFS / exFAT(注意:两者相同!需到 DBR 再分辨)
0x0BFAT32(CHS)
0x0CFAT32(LBA)← U盘最常见
0x0EFAT16(LBA)
0x0F扩展分区(LBA)← 有隐藏分区的题常用
0xEEGPT 保护性MBR → 见 2 GPT分区表
0x82Linux swap / 0x83 Linux

手工解码示例

十六进制中看到一个表项:

80 01 01 00 0C FE FF FF  00 08 00 00 00 78 1E 00
│                    │   └────────┬┘ └──────┬──┘
活动标志            类型0x0C   LBA起点     总扇区数
                    FAT32-LBA =0x800      =0x1E7800

→ 分区从 扇区 0x800(2048) 开始,共 0x1E7800 个扇区。 → DBR 的文件偏移 = 0x800 × 512 = 0x100000,在 010 Editor 中 Ctrl+G 跳转。

扩展分区(隐藏分区题)

如果某个表项类型是 0x0F/0x05(扩展分区),说明盘里还有”第二层分区表”(EBR):

EBR 位置 = 扩展分区的 LBAStart(相对磁盘0扇区)
EBR 结构与 MBR 相同,但只用前两个表项:
  第1项: 逻辑分区(LBAStart 相对本EBR)
  第2项: 指向下一个EBR(LBAStart 相对扩展分区起点),全0=链结束

顺着 EBR 链逐个解析,即可找出全部逻辑分区。CTF 常在 EBR 链的”缝隙”里藏数据。

无分区表(superfloppy):U盘为何常常”没有MBR”

实际取证中,大量 U 盘的 LBA 0 不是 MBR,而是文件系统的 DBR/VBR——整个盘就是一个裸文件系统,没有任何分区表。这种布局叫 superfloppy(软盘模式),是 U 盘出厂预格式化和 Windows 自带格式化对可移动介质的默认方式。这就是为什么 U 盘取证往往”直接从文件系统开始”:镜像 0 扇区就是 DBR,工具(FTK/Autopsy/TSK)会自动从偏移 0 挂载文件系统,看起来好像跳过了 MBR 这一步。

为什么 U 盘常用 superfloppy:

  • U 盘通常只需要一个文件系统,分区表是多余的一层
  • 可移动介质(removable bit)在旧版 Windows 上只识别第一个分区,多分区间无意义(Win10 1703 之后才支持可移动盘多分区)
  • 无分区表兼容性最好:相机、车载、打印机、BIOS 启动盘等嵌入式设备都按 superfloppy 识别

LBA 0 的身份判别(MBR 还是 DBR?)

两者都以 55 AA 结尾,只看结束标志无法区分。判别依据:

判据MBRFAT32 DBRexFAT VBRNTFS DBR
0x03 OEM 标识引导代码(乱码)MSDOS5.0EXFAT NTFS
0x52 处引导代码FAT32 ————
0x0B BPB(每扇区字节数等)无意义有效 BPB有效 BPB有效 BPB
0x1BE 分区表项有效(类型 0x0B/0x0C/0x07…)无效/全0规范要求全 0(可据此确认)无效

实用口诀:先看 0x03 的 OEM 字符串——是 EXFAT/NTFS/MSDOS 开头就是 DBR(superfloppy);否则再看 0x1BE 有没有合法分区表项。

工具侧表现:mmls 遇到 superfloppy 会显示 DOS Partition Table 但没有任何分区行(或直接提示无法识别)——这不是镜像损坏,而是本来就没有分区表;此时 fls -o 0 / fsstat -o 0 直接从偏移 0 解析文件系统即可。

superfloppy 的取证注意

  1. 容量核对仍然要做:对比文件系统总扇区数(DBR 0x20 处)与物理镜像大小,superfloppy 同样可能有尾部隐藏区(文件系统之后的剩余空间藏数据)。
  2. 双 LUN 设备例外:量产工具/U3 加密盘会虚拟出 CD-ROM + 移动盘两个 LUN,移动盘那个 LUN 里可能是 MBR 布局,两个 LUN 要分别提取。
  3. BitLocker To Go:加密 U 盘的 0 扇区 OEM 标识为 -FVE-FS-,看到它不要按 FAT 解析。
  4. CTF 中”0 扇区既是 MBR 又像 DBR”(0x1BE 有表项、0x52 也有 FAT32)的畸形结构,常是手工拼接的藏数据题,两个视角都要解析一遍。

取证要点

  1. 55 AA 不在 0x1FE → 扇区被加密/移位/损坏,先怀疑是不是普通 MBR。
  2. 磁盘签名(0x1B8) 可关联 Windows 注册表 HKLM\SYSTEM\MountedDevices,用于证明”这个U盘插过这台电脑”。
  3. 分区表项全 0 但有 55 AA → 无分区的软盘模式(superfloppy),0扇区直接是 DBR(详见上文「无分区表」一节及 2 FAT文件系统)。
  4. 分区表之后、第一个分区之前(通常 LBA 1~2047)是分区间隙,CTF 高频藏数据区域,blkcat 或 010 Editor 直接看。