主引导记录(MBR)信息分析与获取

来源:互联网 发布:淘宝买港版单反靠谱吗 编辑:程序博客网 时间:2024/06/08 11:12

前段时间在安装黑苹果时,发现一个问题,电脑在启动时,会找激活分区,如果没有找到,那就启动不起来。

那能否写个小程序读取一下MBR信息,把激活分区换成其它,搞点恶作剧呢,于是就有了这篇读取MBR信息的文章,但是没写入,不敢尝试。

通过动手学习,对硬盘MBR信息有了更好的了解。

1、我的硬盘主引导记录信息及分析

80 01 01 00 07 FE FF FF 3F 00 00 00 0D F0 BF 03(主分区)
偏移00H---80---激活标志---表示可引导
偏移01H---01---表示分区开始的磁头号为1
偏移02H---01---转换为二进制后为8位,0-5位表示该分区的起始扇区号---此处为1
偏移03H---00---02H的6-7位与03H的全部8位,共10位,组成起始磁柱号---此处为0
偏移04H---07---表示文件系统类型NTFS。
偏移05H---FE---转换为十进制254,表示分区结束的磁头号为254
偏移06H---FF---转换为二进制1111 1111,0-5位即3F,十进制下的63---该分区的结束扇区号为63。
偏移07H---FF---与06H的6-7位10合起来为3FF,即十进制下的1023---该分区的结束磁柱号为1023。
偏移08H、09H、0AH,0BH---3F 00 00 00---为分区起始相对扇区号63
偏移0CH、0DH、0EH,0FH---0D F0 BF 03---为分区总的扇区数3BFF00D,转换为十进制为62910477。

00 FE FF FF 05 FE FF FF 4C F0 BF 03 75 E6 82 21(扩展分区)
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00(没有使用)
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00(没有使用)
55 AA(MBR的结束标志位)
从上面可以看出MBR开分区结构最多只能识别4个主要分区,但是为什么我们的电脑上可以分4个以上的盘呢?
这是因为一般电脑上是一个主分区,一个扩展分区,在扩展分区中又分的逻辑分区(扩展分区中可以有多个逻辑分区)


2、获取相关信息的代码(Win7下,请以管理员身份运行)

//基于http://www.cnblogs.com/onepc/archive/2011/12/01/2270468.html来修改的。//在此感谢此博友//2012.10.10#include <iostream>#include <windows.h>using namespace std;#pragma pack(1) //字节对齐typedef struct _PARTITION_ENTRY//分区表结构{    UCHAR active; //状态(是否被激活)   重要    UCHAR StartHead; //分区起始磁头号       USHORT StartSecCyli; //与63相位与得出的是开始扇区,把它右移6位就是开始柱面    UCHAR PartitionType; // 分区类型   重要     UCHAR EndHead; //分区结束磁头号    USHORT EndSecCyli; //与63相位与得出的就是结束扇区,把它右移6位就是结束柱面    ULONG StartLBA; // 扇区起始逻辑地址(相对扇区号)   重要    ULONG TotalSector; // 分区大小      重要} PARTITION_ENTRY, *PPARTITION_ENTRY;//引导区512BYTE结构typedef struct _MBR_SECTOR{    UCHAR BootCode[440];//启动记录440 Byte    ULONG DiskSignature;//磁盘签名    USHORT NoneDisk;//二个字节    PARTITION_ENTRY Partition[4];//分区表结构64 Byte    USHORT Signature;//结束标志2 Byte 55 AA} MBR_SECTOR, *PMBR_SECTOR;#pragma pack()int main(){TCHAR szDevicename[64]={0};MBR_SECTOR _ReadMbr;wsprintf(szDevicename,L"\\\\.\\PHYSICALDRIVE0");HANDLE hDevice=CreateFile(szDevicename,GENERIC_READ|GENERIC_WRITE,FILE_SHARE_READ|FILE_SHARE_WRITE,NULL,OPEN_EXISTING,0,NULL);if(hDevice==INVALID_HANDLE_VALUE){cout<<"打开设备出错"<<endl;return -1;}memset(&_ReadMbr,0,sizeof(MBR_SECTOR));DWORD leng=512;DWORD count;DeviceIoControl(hDevice,FSCTL_LOCK_VOLUME,NULL,0,NULL,0,&count,NULL);UCHAR sz[512]={0};//ReadFile(hDevice,sz,512,&leng,NULL);BOOL bcheck=ReadFile(hDevice,&_ReadMbr,512,&leng,NULL);memcpy(sz,&_ReadMbr,512);for(int i=0;i<66;i++){printf("%02X ",sz[446+i]);if((i+1)%16==0)printf("\n");}printf("\n");if(bcheck==FALSE && leng<512){cout<<"读取MBR出错!"<<endl;DeviceIoControl(hDevice,FSCTL_UNLOCK_VOLUME,NULL,0,NULL,0,&count,NULL);CloseHandle(hDevice);return -1;}char *szTemp=new char[64];for(int i=0;i<4;i++){if(_ReadMbr.Partition[i].PartitionType==0){continue;}memset(szTemp,0,64);if(_ReadMbr.Partition[i].active==128){cout<<"激活分区"<<endl;}elsecout<<"非激活分区"<<endl;        memset(szTemp,0,64);        sprintf(szTemp,"激活分区标志位:%02X",_ReadMbr.Partition[i].active);        cout<<szTemp<<endl;        memset(szTemp,0,64);        sprintf(szTemp,"分区起始磁头号:%d",_ReadMbr.Partition[i].StartHead);        cout<<szTemp<<endl;        memset(szTemp,0,64);        int temp = _ReadMbr.Partition[i].StartSecCyli;        sprintf(szTemp,"分区起始扇区号:%d",temp & 63);//63转为二进制111111,做&运算,只取低6位        cout<<szTemp<<endl;        memset(szTemp,0,64);        sprintf(szTemp,"分区起始磁柱号:%d",temp>>6);//取高10位        cout<<szTemp<<endl;        memset(szTemp,0,64);        sprintf(szTemp,"分区文件类型标识:%02d",_ReadMbr.Partition[i].PartitionType);        cout<<szTemp<<endl;        memset(szTemp,0,64);        sprintf(szTemp,"分区结束磁头号:%d",_ReadMbr.Partition[i].EndHead);        cout<<szTemp<<endl;        memset(szTemp,0,64);        temp = _ReadMbr.Partition[i].EndSecCyli;        sprintf(szTemp,"分区结束扇区号:%d",temp & 63);        cout<<szTemp<<endl;        memset(szTemp,0,64);        sprintf(szTemp,"分区结束磁柱号:%d",temp>>6);        cout<<szTemp<<endl;        memset(szTemp,0,64);        sprintf(szTemp,"分区起始相对扇区号:%d",_ReadMbr.Partition[i].StartLBA);        cout<<szTemp<<endl;        memset(szTemp,0,64);        sprintf(szTemp,"分区总的扇区数:%d",_ReadMbr.Partition[i].TotalSector);        cout<<szTemp<<endl;}DeviceIoControl(hDevice, FSCTL_UNLOCK_VOLUME, NULL, 0, NULL, 0, &count, NULL);    CloseHandle(hDevice);system("pause");return 0;}