MBR、EBR与DBR详解

article/2025/8/27 15:42:19

demo:https://github.com/Hilaver/NtfsResolution/

先看一张硬盘图片(一个盘面):

MBR

主引导记录(MBR,Main Boot Record)是位于磁盘最前边的一段引导(Loader)代码。它负责磁盘操作系统(DOS)对磁盘进行读写时分区合法性的判别、分区引导信息的定位,它由磁盘操作系统(DOS)在对硬盘进行初始化时产生的。              --摘自百度百科

MBR扇区位于物理硬盘的0柱面,0磁头,1扇区,也就是整个硬盘的第一个扇区(偏移量为0),共占512个字节(即一个扇区),每个物理硬盘只有一个MBR扇区。

MBR扇区由三部分构成:第一部分是446字节的引导代码,也就是上面提到的MBR;第二部分是DPT(Disk Partition Table,硬盘分区表),包含4个表项,每个表项16字节,共占用64字节;第三部分是2个字节的结束标志,0x55AA。其结构如下图:

 

DBR

分区引导扇区也称DBR(DOS BOOT RECORD),是由FORMAT高级格式化命令写到该扇区的内容,DBR是由硬盘的MBR装载的程序段。DBR装入内存后,即开始执行该引导程序段,其主要功能是完成操作系统的自举并将控制权交给操作系统。每个分区都有引导扇区,但只有被设为活动分区才会被MBR装的DBR入内存运行。                 --摘自百度百科

在对硬盘分区之后,每一个分区均有一个DBR与之对应。DBR位于每个分区的第一个扇区,大小为512字节

DBR的结构与分区格式有关,NTFS与FAT32的DBR格式是不同的。

EBR

EBR(Extended Boot Record)是与MBR相对应的一个概念。前边已经讲过,MBR里有一个DPT(Disk Partition Table,磁盘分区表)的区域,它一共是64字节,按每16个字节作为一个分区表项,它最多只能容纳4个分区。能够在MBR的DPT里进行说明的分区称为主分区。如果我们想分区多于4个的时候,MBR的DPT里就会容纳不下来,于是微软就想出了另一个解决方案,在MBR里,只放不多于三个主分区,剩下的分区,则由与MBR结构很相像的另一种分区结构(EBR,也就是扩展分区引导记录)进行说明。一个EBR不够用时,可以增加另一个EBR,如此像一根链条一样地接下去,直到够用为止。                --又摘自百度百科

实际上,EBR中有用的部分仅为其DPT的前两个表项,第一个表项记录了扩展分区中该EBR对应的逻辑分区(逻辑驱动器)的偏移地址和扇区个数,第二个表项记录了下一个逻辑分区的必要信息,本质上是一个链表的结点。

实例分析

下面给出我的一个Windows7虚拟机的分区结构图(所有的分区文件系统格式均为NTFS):

在Winhex下读取到的硬盘信息如下:

其中MBR、DBR和EBR的位置如下图:

从上图可以看到,整个物理硬盘被分成了6个分区,其中C、E和F是主分区,G、H和I是逻辑分区。写代码获得各个分区的信息如下:

 

MBR扇区数据分析

读取MBR如下(在硬盘偏移量为0处读取512个字节),找到其中64个字节的DPT数据:

提取出来如下:

80  20 21 00 07  FE FF FF  00 08 00 00 00 F0 3F 06

00  FE FF FF 07  FE FF FF  00 F8 3F 06 00 F8 7F 02

00  FE FF FF 07  FE FF FF  00 F0 BF 08 00 00 40 02

00  FE FF FF 0F  FE FF FF  00 F0 FF 0A 00 08 40 00

上面四个表项分别指向分区CEFG

刚刚已经提到,DPT中最多包含4个表项,每个表项16字节,每个表项的结构如下:

 

//DPT表项typedefstruct_PartTableEntry {BYTE bootSignature;//引导标志BYTE startHead;//CHS寻址方式,起始磁头BYTE startSector;//起始扇区,本字节低六位BYTE startCylinder;//起始磁道(柱面),startSector高二位和本字节BYTE systemSignature;//文件系统类型标志BYTE endHead;//终止磁头BYTE endSector;//终止扇区BYTE endCylinder;//终止磁道unsignedint startSectorNo;//LBA寻址,起始扇区号unsignedint totalSectorsNum;//该分区扇区总数
}PartTableEntry,*pPartTableEntry;

 

 

先看第一个表项:

 

 

80  20 21 00 07  FE FF FF  00 08 00 00 00 F0 3F 06

第一个字节为引导标志,0x80表示活动分区,0x00表示非活动分区。接下来三个字节用来表示CHS寻址方式的起始地址,具体含义已经在上面结构体中给出。接下来一个字节表示分区文件系统的类型,0x07表示NTFS(参考最后的附表)。接下来的三个字节表示CHS寻址方式的终止地址(0xFEFFFF表示该字段无效,因为3个字节最大的寻址能力为2^(3*8)个扇区,即8GB。当分区大小超过8GB时该字段无效)。再后面的四个字节表示LBA(Logical Block Address)寻址方式的起始扇区(可以计算出最大支持2TB的硬盘),要注意小端字节序(数据存储时低字节在前),也就是说C盘的起始扇区为00 00 08 00。最后四个字节表示该分区的扇区数量,同样是小端模式,即C盘共0x063FF000个扇区。

接下来让我们跳转到C盘的起始扇区(00 00 08 00),读取该处512字节的数据如下:

你会看到熟悉的结束标志0x55AA,实际上这是C盘的DBR扇区。DBR扇区各个字段的含义在后面展开。

EBR扇区分析

MBR扇区的硬盘分区表的第二和第三个表项与第一个类似,这里不再展开,我们主要来看一下第四个表项:

00  FE FF FF 0F  FE FF FF  00 F0 FF 0A 00 08 40 00

第一个字节表示非活动分区,CHS寻址无效,第五个字节分区类型为0x0F,表示扩展分区。LBA寻址的起始扇区为0x0AFFF000,包含扇区个数为0x00400800。跳转到该扩展分区的起始扇区0x0AFFF000处读取512字节数据:

最后两个字节是结束标志0x55AA,这512字节实际上是一个EBR扇区,其结构与MBR扇区相同,但有用的部分仅为DPT的前两个表项,数据如下:

00  FE FF FF 07  FE FF FF  00 08 00 00 00 90 21 00

00  FE FF FF 05  FE FF FF  00 98 21 00 00 70 1E 00

第一个表项表示本该EBR对应的逻辑分区G的起始地址和扇区数量,其中LBA寻址的起始扇区为00 00 08 00,但是该地址为相对偏移,实际的起始扇区为本扇区的实际地址加上相对偏移量,即0x0AFFF000 + 0x00000800 = 0x0AFFF800。读取0x0AFFF800扇区的数据如下:

这个扇区实际上是逻辑分区G的DBR扇区,记录了G盘的基本信息。

第二个表项记录了下一个逻辑分区 H 的EBR扇区的起始地址和扇区总数量。其中,EBR扇区的起始地址为00 21 98 00,同样是一个相对地址,实际扇区为0x0AFFF000 + 0x00219800 = 0x0B218800,读取0x0B218800扇区的数据如下:

这512字节是逻辑分区H的EBR扇区,同样提取DPT的前两个表项:

00  FE FF FF 07  FE FF FF  00 08 00 00 00 B8 0B 00

00  FE FF FF 05  FE FF FF  00 58 2D 00 00 B0 12 00

与上一个EBR扇区类似,第一个表项的LBA寻址的起始扇区(00 00 08 00)仍是一个相对偏移,指向该EBR所对应的逻辑分区的起始地址,其实际扇区为:0x0B218800 + 0x00000800 = 0x0B219000,实际字节偏移为0x0B219000 *512字节每扇区 = 0x1643200000,从该字节处读取512字节数据可以得到分区H的DBR扇区,这里就不再截图。第二个表项的LBA寻址起始扇区(00 2D 58 00)同样是一个相对偏移,指向下一个逻辑分区(I:)的EBR扇区,其实际扇区为MBR扇区DPT第四个表项的起始扇区加上该相对偏移,即0x0AFFF000 + 0x002D5800 = 0x0B2D4800。该扇区的数据为:

在该EBR扇区中,DPT的第一个表项仍使用相对偏移指出本逻辑分区(I:)的起始扇区,这个扇区就是分区I:的DBR扇区。第二个表项全0,表示该逻辑分区即是最后一个逻辑分区。

总结一下,在Windows系统下如果采用MBR的引导方式,当分区个数大于等于4的时候,一般情况下系统会将前三个分区设为主分区,第四个作为扩展分区(扩展分区中包含若干个逻辑分区)。MBR扇区的DPT中前三个表项可以直接定位前三个主分区的DBR扇区,第四个表项指向第一个逻辑分区的EBR扇区,根据EBR中的DPT前两个表项分别可以定位本逻辑分区的DBR扇区和下一个逻辑分区的EBR扇区,由此逻辑分区链接成一条链进行管理。

DBR扇区分析

下面给出NTFS和FAT32的DBR扇区格式,注意一点:NTFS下的备份DBR在分区的最后一个扇区,FAT32下的备份DBR一般在第六个扇区。

 

//NTFS DBR扇区typedefstruct_NTFSDBR {BYTE JMP[3]; //跳转指令BYTE FsID[8]; //文件系统IDunsignedshortint bytePerSector;  //每扇区字节数BYTE secPerCluster;       //每簇扇区数BYTE reservedBytes[2];    //2个保留字节BYTE zeroBytes[3];    //三个0字节BYTE unusedBytes1[2]; //2个未用字节BYTE mediaType;//媒体类型BYTE unusedBytes2[2]; //2个未用字节unsignedshortint secPerTrack;    //每磁道扇区数unsignedshortint Heads; //磁头数unsignedint hideSectors; //隐藏扇区数BYTE unusedBytes3[4]; //4个未用字节BYTE usedBytes[4];    //4个固定字节unsigned__int64 totalSectors; //总扇区数unsigned__int64 MFT; //MFT文件起始簇号unsigned__int64 MFTMirror;    //MFTMirror文件起始簇号char fileRecord;  //文件记录BYTE unusedBytes4[3]; //3个未用字节char indexSize;   //索引缓冲区大小BYTE unusedBytes5[3]; //未用字节BYTEvolumeSerialID64[8]; //卷序列号unsignedint checkSum;    //校验和BYTE bootCode[426];   //引导代码BYTE endSignature[2]; //结束标志
}NTFSDBR,*pNTFSDBR;

 

typedefstruct_FAT32_Sector{unsignedint   Sectors_per_FAT_FAT32;    //FAT32每个FAT表占用扇区数unsignedshortint Extend_Flag;    //0-3位表示活动FAT数,7位:0表示在运行时FAT映射到所有FAT 1表示只有一个FAT是活动的,其他位保留unsignedshortint FS_Version;  //文件系统版本,高字节表示主要修订号,低直接表示次要修订号unsignedint   Root_Cluster_Number;                              //根目录簇号,一般取值为2unsignedshortint FS_Info_Sector;                                //文件系统扇区号,一般取1unsignedshortint Backup_Sector;                                 //备份引导扇区,一般取值为6BYTE   Reserved_Sector[12];        //保留扇区  
}FAT32_Sector, *pFAT32_Sector;
typedefstruct_Basic_BPB{unsignedshortint    Bytes_per_Sector;                  //每个扇区字节数,可取512,1024,2048,4096,通常取512BYTE     Sectors_per_Cluster;   //每簇扇区数,可取1,2,4,8,16,32,64,128,FAT32最多跟踪268,435,445个簇unsignedshortint    Reserved_Sector;                   //保留扇区,表示第一个FAT前的扇区数,通常取32BYTE     FATs;                                   //FAT表个数,通常取2unsignedshortint    RootEntry;                             //根目录项数,对FAT32,取值必为0unsignedshortint    SmallSector;                       //小扇区数,对FAT32,取值必为0BYTE     Media;                                 //存储介质描述,F8表示硬盘,F0表示3.5软盘unsignedshortint    Sector_per_FAT_FAT16;              //针对FAT12/16的每个FAT扇区数,对FAT32,取值为0unsignedshortint    Sector_per_Track;                  //每道扇区数,描述磁盘物理结构unsignedshortint    Heads;                                 //磁头数unsignedint      Hidden_Sector;                         //该块硬盘前用于存放引导代码及分区表的扇区数unsignedint      Large_Sector;      //总扇区数,若SmallSector为0,此处表示分区上扇区总数//可用扇区数 = 总扇区数-保留扇区-FAT表占用扇区_FAT32_Sector     Fat32_Sector;                      //FAT32文件系统扇区信息                
}Basic_BPB, *pBasic_BPB;
typedef  struct_FAT32_Extend_BPB{BYTE Physical_Drive;                            //物理驱动器号,0x80表示物理硬盘,0x00表示软盘驱动器BYTE Reserved;                                       //保留BYTE Extend_Singure;                            //0x28或0x29以供Windows NT识别unsignedint  Vol_Serial;                                //卷序列号,由格式化时随机获得BYTE Vol_Label[11];            //卷标示BYTE System_ID[8];                 //系统ID,根据格式化的格式为FAT32,FAT16等
}FAT32_Extend_BPB, *pFAT32_Extend_BPB;//FAT32 DBR扇区
typedefstruct_FAT32_DBR{BYTE     JumpInstrction[3]; //0x00,跳转指令,通常为EB5890,其中58指示了,跳转位置,在X86中,58+2就代表跳转到5A处BYTE     OEMID[8];                 //0x03,厂商标示和OS版本信息_Basic_BPB            BPB;                               //0x0B_FAT32_Extend_BPB Extend_BPB;                            //0x40BYTE Boot_Strap[420];              //文件系统引导代码                              //0x5A,引导区代码BYTE endSignature[2];                  //0x01FE,结束标示
}FAT32_DBR, *pFAT32_DBR;

 

 

下面是一个FAT32分区的DBR扇区数据,具体含义在上述结构体中已做声明,这里就不再展开:

 

 

下面是一张以前的FAT32分区DBR扇区的数据,部分字段含义做了解释:

附-磁盘分区类型标志表:


http://chatgpt.dhexx.cn/article/TwrBKPPW.shtml

相关文章

MBR、EBR、DBR是什么

通常情况下可以这样描述这几个概念: MBR:为计算机启动后从可启动介质上首先装入内存并且执行的代码,通常用来解释分区结构。以硬盘为例,通常为LBA的0扇区。 EBR:自MICROSOFT推出扩展分区的概念后,扩展分区就沿用了基本…

NTFS文件系统详解(二)之MBR(EBR)基本信息

经过上一篇文章对硬盘的基本结构的详细介绍后,我们再来看看MBR和EBR的结构 MBR(Main Boot Record 主引导记录区)位于整个硬盘的0磁道0柱面1扇区。不过,在总共512字节的主引导扇区中,MBR只占用了其中的446个字节,另外的64个字节交给了 DPT(Disk Partition Table硬盘分区表…

EBR内容解析

原先博客放弃使用,几篇文章搬运过来 EBR(Extended Boot Record)即扩展分区引导记录.类似于主引导记录MBR.因为MBR的四条分区信息的限制,可以使用EBR方便扩展. 它的结构与MBR类似于,但是没有引导程序和磁盘签名,仅仅保留了分区表和结束标志. 下面以实例分析: 新建一个512MB虚拟…

C++中常见的几种输入字符串的方法

C中常见的几种输入字符串的方法_是赵薰薰呀的博客-CSDN博客_c输入字符串 可以用的函数 substr substr有2种用法: 假设:string s "0123456789"; string sub1 s.substr(5); //只有一个数字5表示从下标为5开始一直到结尾:sub1 &…

MATLAB-字符串

本节我们学习如何在MATLAB中创建一个字符串。 例如: my_string 搬砖工程师domi MATLAB执行上述语句,返回以下结果: my_string 搬砖工程师domi MATLAB 认为所有变量,数组和字符串被视为字符数组。 让我们使用命令检查上面创建…

c语言:动态输入字符串数组

考研题中经常会遇到给定一条英文句子,让我们对其每个单词进行操作,不同于对整型数据操作,字符串在c语言中必须存放到数组中,无形之中又给考题增加了难度 一般情况下,字符串数组都以二维数组或指针数组定义&#xff0c…

用scanf_s输入字符串

用的是vs2019。 为了安全,scanf_s输入字符串时需要加一个数字来限制最多读取的字符数。 错误示例: char* str[100]; scanf_s("%s",str);这样写编译器没有报错,但是运行会出错,debug显示 正确写法: char…

写一函数,求一个字符串的长度。在main函数中输入字符串,并输出其长度。

写一函数,求一个字符串的长度。在main函数中输入字符串,并输出其长度。 解题思路&#xff1a; 字符串以\0作为结尾&#xff0c;则从第一个字符开始向后移动遇到\0认为字符串结束。 答案&#xff1a; #include <stdio.h> int mystrlen(char *str) {int len 0;char *pt…

C++输入字符串的几种方式

最近有复习到 C 基础知识&#xff0c;这里总结下在 C 中输入字符串的几种方式&#xff0c;有需要的可以参考&#xff1a; 1、cin >> <1> 输入一个数字 void Cin1() {int a, b;cin >> a >> b;cout << "a b " << a b <&l…

c语言如何用循环输入字符串,C语言使用scanf连续输入字符串出现的问题

#include int main() { char a,b; scanf("%c",&a)&#xff1b; scanf("%c",&b); printf("%c,%c",a,b); } 一段看上去很简单的代码&#xff0c;即使是C语言初学者也能看懂。 可是在运行的时候却出现了问题&#xff1a; ①输入a后按下回车…

c语言用scanf输入指针字符串,c语言如何用scanf输入字符串

在C语言中&#xff0c;可以使用“scanf(“格式控制字符串”,变量内存地址)”语句输入字符串。scanf()函数的第一个参数是格式字符串&#xff0c;它指定了输入的格式&#xff0c;并按照格式说明符解析输入对应位置的信息并存储于可变参数列表中对应的指针所指位置。 本教程操作环…

C++中输入字符串的几种方法

C中输入字符串的几种方法 C的字符串输入方式有 1.cin>> 2.cin.get() 3.cin.getline() 4.getline() 5.gets()cin 第一种用法是逐个输入数字或者字符&#xff0c;中间用空格隔开。 第二种用法是读入一个字符串&#xff0c;遇到“空格”“TAB”“回车” 都会结束。例如&a…

C语言输入字符串

文章目录 1.scanf2.gets 1.scanf 输入字符串使用 %s。不能读取空格&#xff0c;遇到空格自动结束。例如&#xff0c;输入abcde&#xff0c;得到abcde&#xff1b;而输入abc de&#xff0c;只能得到abc。输入格式&#xff1a;scanf("%s",str)。其中str表示 地址值。 …

【C语言】字符串输入的三种方式

一、gets() 该函数原型为&#xff1a; # include <stdio.h> char *gets(char *str);gets() 函数的功能是从输入缓冲区中读取一个字符串存储到字符指针变量 str 所指向的内存空间 # include <stdio.h> int main(void) {char a[256] {0};gets(a);printf("%s…

字符串输入的2种常用方法详解

字符串输入的2种常用方法详解 一.scanf函数1.扫描集2.逆向使用扫描集 二.gets函数 一.scanf函数 int main() {char arr[50] { 0 };scanf("%s", arr);printf("%s", arr);return 0; }这种方法可以输入字符串&#xff0c;但是只能输入一个词&#xff0c;遇到…

字符串的输入

字符串数据作为经常需要使用的数据&#xff0c;我们需要掌握它的输入&#xff0c;下面总结了不同的输入字符串的方式 c和c的有一点点不同 ①逐个逐个字符输入 我们可以设置一个数组&#xff0c;或者数组加指针的形式&#xff0c; 通过for循环或while循环的方式&#xff0c;…

C++字符串的几种输入方法(string和字符数组)

ps:本文大部分内容参考于这篇博客&#xff0c;在这里加入了自己对这些函数在字符数组和string变量的理解和总结。 C中的输入大致有6种方法&#xff1a;cin&#xff0c;cin.get(),cin.getline(),gets(),getchar() 1,cin 用法一&#xff1a;最常用的方法&#xff0c;接收一个字…

制作黑苹果安装U盘(Clover+OC+PE)三引导

制作黑苹果安装U盘&#xff08;OCCloverPE&#xff09;三引导 1.删除U盘分区表2.写入dmg到U盘3.替换EFI(Clover引导)4.扩建U盘分区表5.转换U盘分区类型 效果如图所示&#xff0c;嫌麻烦可以关注 黑果小兵的部落阁微信公众号&#xff0c;在“安装镜像”里找"10.15.6 19G73…

MINIS FORUM U820 黑苹果引导OC或CLOVER更新教程

准备工具&#xff1a;1.OC Auxiliary Tools&#xff08;简称OCAT)&#xff0c;OC Auxiliary Tools for Mac-OC Auxiliary Tools Mac版下载 V0.6.9-PC6苹果网 即新OC引导的编辑器&#xff0c;须与OC引导版本相对应&#xff0c;否则容易出错&#xff1b;2.Clover ConfiGurator&a…

黑苹果引导介绍篇

引导篇 1、EFI分区&#xff1a;全称是EFI System Partition(ESP)&#xff0c;是一个使用FAT16或FAT32的系统引导物理分区&#xff0c;支持EFI模式的电脑需要从ESP分区启动系统&#xff0c;EFI固件可从ESP加载EFI启动程序或者应用。目前主流的Clover安装的黑苹果&#xff0c;普…