1. MBR数据格式
一个扇区的硬盘主引导记录MBR由4个部分组成。
- 主引导程序(偏移地址0000H--0088H),它负责从活动分区中装载,并运行系统引导程序。
- 出错信息数据区,偏移地址0089H--00E1H为出错信息,00E2H--01BDH全为0字节。
- 分区表(DPT,Disk Partition Table)含4个分区项,偏移地址01BEH--01FDH,每个分区表项长16个字节,共64字节为分区项1、分区项2、分区项3、分区项4。
- 结束标志字,偏移地址01FE--01FF的2个字节值为结束标志55AA,如果该标志错误系统就不能启动。
1.1 MBR功能
在CPU上电之后,若由硬盘启动,则BIOS将硬盘的主引导记录(位于0柱面、0磁道、1扇区)读入7C00处,然后将控制权交给主引导代码。主引导代码的任务包括:
- 扫描分区表,找到一个激活(可引导)分区;
- 找到激活分区的起始扇区;
- 将激活分区的引导扇区装载到内存7C00处;
- 将控制权交给引导扇区代码;
1.2 主格式如下
占用512个字节的MBR中,偏移地址01BEH--01FDH的64个字节,为4个分区项内容(分区信息表)。它是由磁盘介质类型及用户在使用 FDISK定义分区时确定的。在实际应用中,FDISK对一个磁盘划分的主分区可少于4个,但最多不超过4个。每个分区表的项目是16个字节,其内容含义如下表所示。
偏移地址 | 大小 | 结束地址 | 名称 | 说明 |
---|---|---|---|---|
0x000 | 0x088 | 0x088 | 主引导程序 | Master Boot Record 主引导程序 |
0x089 | 0x136 | 0x1bd | 数据区 | 出错信息数据区 |
0x1be | 0x00f | 0x1cd | 分区1 | 第一个分区表 |
0x1ce | 0x00f | 0x1dd | 分区1 | 第一个分区表 |
0x1de | 0x00f | 0x1ed | 分区1 | 第一个分区表 |
0x1ee | 0x00f | 0x1fd | 分区1 | 第一个分区表 |
0x1fe | 0x002 | 0x1ff | MBR结束标记 | 结束校验 0x55aa |
1.3 分区表格式
偏移地址 | 大小 | 名称 | 备注 |
---|---|---|---|
0x00 | 1B | 引导标记 | 若值为80H表示活动分区,若值为00H表示非活动分区。 |
0x01 | 3B | 本分区的起始磁头号、扇区号、柱面号。其 | 磁头号——第2字节;扇区号——第3字节的低6位;柱面号——为第3字节高2位+第4字节8位。 |
0x05 | 1B | 分区类型符。 | 00H-表示该分区未用(即没有指定); 06H-FAT16基本分区; 0BH-FAT32基本分区; 05H-扩展分区;07H-NTFS分区 |
0x06 | 3B | 本分区的结束磁头号、扇区号、柱面号。其 | 磁头号——第6字节;扇区号——第7字节的低6位;柱面号——为第8字节高2位+第4字节8位。 |
0x09 | 4B | 本分区已用的扇区数/该分区的偏移地址。 | 小端格式,具体偏移地址需要x512 |
0x0d | 4B | 小端格式,本分区总扇区数/该分区的实际扇区 | 小端格式,具体容量需要x512。 |
1.4 解析MBR代码
python
filetypes={0x00:"无效分区",0x01:"FAT12",0x04:"FAT16<32MB",0x06:"FAT16>32MB"}
class FileSystem(object):
filehandler=None
fileoffset=0
def __init__(self,filename:str,offset) -> None:
self.filehandler=open(filename,'rb')
self.fileoffset=offset
pass
def resethead(self):
self.filehandler.seek(self.fileoffset)
def dump_mbr(self):
self.resethead()
# print(f"mast boot:{self.filehandler.read(0x88).hex()}")
# print(f"error info:{self.filehandler.read(0x136).hex()}")
self.filehandler.read(0x1be)
for i in range(0,4):
mbrtable=self.filehandler.read(16)
print(f"分区:{i}")
print(f"活动分区:{mbrtable[0]==0x80}")
print(f"开始磁头:{mbrtable[1]}")
value=int.from_bytes(mbrtable[2:4],"little")
print(f"起始扇区:{value&0x3f}")
print(f"起始柱面:{value>>6}")
print(f"分区类型:{filetypes.get(mbrtable[4:5][0])}")
print(f"结束磁头:{mbrtable[5:6].hex()}")
value=int.from_bytes(mbrtable[6:8],"little")
print(f"结束扇区:{value&0x3f}")
print(f"结束柱面:{value>>6}")
offsetsectot=int.from_bytes(mbrtable[8:12],"little")
print(f"偏移扇区:{offsetsectot} 偏移地址:0x{self.fileoffset+offsetsectot*512:08x} 偏移大小:{offsetsectot*512/1024/1024}MB")
countsectot=int.from_bytes(mbrtable[12:16],"little")
print(f"分区扇区:{countsectot} 可用容量:0x{countsectot*512:08x} 容量大小:{countsectot*512/1024/1024}MB")
print(f"endflag:{self.filehandler.read(2).hex()}")
filesystem=FileSystem("FULL_DUMP_FT2232.bin",0x590000)
filesystem.dump_mbr()