前段时间在安装黑苹果时,发现一个问题,电脑在启动时,会找激活分区,如果没有找到,那就启动不起来。
那能否写个小程序读取一下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; }else cout<<"非激活分区"<<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; }