在分析MBR的结构之前,先有来看看计算机的引导顺序(System Boot Sequence) Step 1. 内部电源打开,初始化,等待一小段时间用来产生稳定的电流。如果主板芯片和CPU收到了不符合规定的电流,将自动产生一个RESET信号。在主板没有收到电源的Power Good信号之前,重复步骤1。
Step 2. 执行BIOS中0FFF0h处的代码。这里只有一条JMP指令,将跳转到真正的BIOS启动程序处。
Step 3. BIOS开始加电自检(Power-On Self Test, POST),如果出现错误,启动停止。成功的话执行INT 19h(SYSTEM - BOOTSTRAP LOADER)
Step 4. BIOS开始寻找显卡,找到的话将执行显卡的BIOS。接着显卡初始化,将显示一段显卡信息,我们开机看到的第一屏就是它。
Step 5. BIOS开始执行所有其他设备的BIOS,包括软驱,硬盘等。
Step 6. BIOS显示启动信息
Step 7. BIOS开始额外的检测。一般有内存检测,如果内存有问题,将显示错误消息。
Step 8. BIOS探测所有的硬件,将显示如硬盘/光区信息等
Step 9. BIOS给出一个已知硬件的列表
Step 10. BIOS按照设置的驱动器顺序找驱动器,如果驱动器存在的话继续找启动扇区,软驱/硬盘的启动扇区都在0柱0头1扇区(cylinder 0, head 0, sector 1)
Step 11. 将启动扇区读到内存0000:7c00处,接着INT 19h开始执行0000:7c00处代码
Step 12. 如果找不到驱动器,系统显示错误信息并停止。通常是“No boot device“或“NO ROM BASIC -SYSTEM HALTED“
上面是冷启动的过程,热启动将从步骤8开始
磁盘的启动扇区就是主引导记录(Master Boot Record),包括0柱0头1扇区的512个字节,它的任务是完成BIOS到操作系统的交接。
MBR的大体结构: 偏移 内容 0000 MBR程序代码 01BE 分区表 01FE 结束标志
分区表结构 BYTE 1 如果是引导分区,就是80H,如果不是,就是00H 2-4 是该分区的起始扇区号 5 标志字节,比如05表示扩展分区 6-8 该分区的终止扇区号 9-12 该分区已使用的扇区数 13-16 该分区总共占用的扇区数
这是从我的硬盘上提取的MBR(硬盘是Maxtor的金钻20G,netfay的电脑早过时了:P),不同型号的硬盘MBR稍有不同,不过功能都是一样的
0000 33 C0 8E D0 BC 00 7C FB-50 07 50 1F FC BE 1B 7C 3.....|.P.P....| 0010 BF 1B 06 50 57 B9 E5 01-F3 A4 CB BE BE 07 B1 04 ...PW........... 0020 38 2C 7C 09 75 15 83 C6-10 E2 F5 CD 18 8B 14 8B 8,|.u........... 0030 EE 83 C6 10 49 74 16 38-2C 74 F6 BE 10 07 4E AC ....It.8,t....N. 0040 3C 00 74 FA BB 07 00 B4-0E CD 10 EB F2 89 46 25 〈.t...........F% 0050 96 8A 46 04 B4 06 3C 0E-74 11 B4 0B 3C 0C 74 05 ..F...〈.t...〈.t. 0060 3A C4 75 2B 40 C6 46 25-06 75 24 BB AA 55 50 B4 :.u+@.F%.u$..UP. 0070 41 CD 13 58 72 16 81 FB-55 AA 75 10 F6 C1 01 74 A..Xr...U.u....t 0080 0B 8A E0 88 56 24 C7 06-A1 06 EB 1E 88 66 04 BF ....V$.......f.. 0090 0A 00 B8 01 02 8B DC 33-C9 83 FF 05 7F 03 8B 4E .......3.......N 00A0 25 03 4E 02 CD 13 72 29-BE 59 07 81 3E FE 7D 55 %.N...r).Y..〉.}U 00B0 AA 74 5A 83 EF 05 7F DA-85 F6 75 83 BE 2E 07 EB .tZ.......u..... 00C0 8A 98 91 52 99 03 46 08-13 56 0A E8 12 00 5A EB ...R..F..V....Z. 00D0 D5 4F 74 E4 33 C0 CD 13-EB B8 00 00 80 08 10 16 .Ot.3........... 00E0 56 33 F6 56 56 52 50 06-53 51 BE 10 00 56 8B F4 V3.VVRP.SQ...V.. 00F0 50 52 B8 00 42 8A 56 24-CD 13 5A 58 8D 64 10 72 PR..B.V$..ZX.d.r 0100 0A 40 75 01 42 80 C7 02-E2 F7 F8 5E C3 EB 74 B7 .@u.B......^..t. 0110 D6 C7 F8 B1 ED CE DE D0-A7 A1 A3 B0 B2 D7 B0 B3 ................ 0120 CC D0 F2 CE DE B7 A8 BC-CC D0 F8 A1 A3 00 BC D3 ................ 0130 D4 D8 B2 D9 D7 F7 CF B5-CD B3 CA B1 B3 F6 CF D6 ................ 0140 B4 ED CE F3 A1 A3 B0 B2-D7 B0 B3 CC D0 F2 CE DE ................ 0150 B7 A8 BC CC D0 F8 A1 A3-00 C8 B1 C9 D9 B2 D9 D7 ................ 0160 F7 CF B5 CD B3 00 00 00-00 00 00 00 00 00 00 00 ................ 0170 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................ 0180 00 00 00 8B FC 1E 57 8B-F5 CB 00 00 00 00 00 00 ......W......... 0190 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................ 01A0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................ 01B0 00 00 00 00 00 2C 44 63-B5 D7 B5 D7 00 00 80 01 .....,Dc........ 01C0 01 00 0B FE 7F FD 3F 00-00 00 3F 04 7D 00 00 00 ......?...?.}... 01D0 41 FE 0C FE FF FF 7E 04-7D 00 7D 9B E5 01 00 00 A.....~.}.}..... 01E0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................ 01F0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 55 AA ..............U.
由于程序代码从0000:7C00开始,下面看反编译的结果(经过修改)
7C00 33C0 XOR AX,AX ;AX=0 7C02 8ED0 MOV SS,AX ;SS=0 7C04 BC007C MOV SP,7C00 ;SP=7C00 7C07 FB STI ;中断允许 7C08 50 PUSH AX 7C09 07 POP ES ;ES=0 7C0A 50 PUSH AX 7C0B 1F POP DS ;DS=0 7C0C FC CLD ;字符串操作方向:从低到高 7C0D BE1B7C MOV SI,7C1B ;源地址 DS:SI=0000:7C1B 7C10 BF1B06 MOV DI,061B ;目的地址 ES:DI=0000:061B 7C13 50 PUSH AX 7C14 57 PUSH DI 7C15 B9E501 MOV CX,01E5 ;共1E5h个字节 7C18 F3 REPZ 7C19 A4 MOVSB ;将MBR从0000:7C00移动到0000:0600 7C1A CB RETF ;跳转到0000:061B处
PARTITION_SEARCH_LOOP:
061B BEBE07 MOV SI,07BE ;SI指向分区表的开始 061E B104 MOV CL,04 ;循环4次,硬盘最多4个主分区 0620 382C CMP [SI],CH 0622 7C09 JL ACTIVE_PARTITION_FOUND ;分区是活动分区 0624 7515 JNZ INVALID_PARTITION_TABLE ;无效的分区表 0626 83C610 ADD SI,+10 ;每个分区占用16个字节,SI指向下一个分区 0629 E2F5 LOOP PARTITION_SEARCH_LOOP
062B CD18 INT 18 ;分区表搜索完,无活动分区,INT 18h=DISKLESS BOOT HOOK
ACTIVE_PARTITON_FOUND:
062D 8B14 MOV DX,[SI] ;下面的搜索保证只存在一个活动分区,否则分区表无效 062F 8BEE MOV BP,SI ;找到的引导分区标志和开始地址分别存入DX,BP
ONLY_ONE_ACTIVE_PARTITON_SEARCH_LOOP:
0631 83C610 ADD SI,+10 0634 49 DEC CX 0635 7416 JZ GOOD_PARTITION_TABLE ;搜索完毕,剩下的分区中无活动分区,分区表正常 0637 382C CMP [SI],CH 0639 74F6 JZ ONLY_ONE_ACTIVE_PARTITON_SEARCH_LOOP ;如果还有活动分区则继续向下执行
INVALID_PARTITION_TABLE:
063B BE1007 MOV SI,0710 ;SI指向要显示的错误信息处
HANG_MACHINE_LOOP:
063E 4E DEC SI
DISPLAY_ERROR_MESSAGE_LOOP:
063F AC LODSB 0640 3C00 CMP AL,00 0642 74FA JZ HANG_MACHINE_LOOP ;到字符串尾时进入死循环,停止运行 0644 BB0700 MOV BX,0007 0647 B40E MOV AH,0E 0649 CD10 INT 10 ;显示错误信息
DISPLAY_ERROR_MESSAGE_LOOP_ALIAS:
064B EBF2 JMP DISPLAY_ERROR_MESSAGE_LOOP
GOOD_PARTITION_TABLE:
064D 894625 MOV [BP+25],AX ;tmpvar=BP+25处清零,作为临时变量 0650 96 XCHG SI,AX ;SI=0 0651 8A4604 MOV AL,[BP+04] ;读分区类型入AL 0654 B406 MOV AH,06 0656 3C0E CMP AL,0E ;类型 WIN95: DOS 16-bit FAT, LBA-mapped 0658 7411 JZ TYPE_WIN95_DOS_16BIT_FAT_LBA
065A B40B MOV AH,0B 065C 3C0C CMP AL,0C ;类型 WIN95 OSR2 32-bit FAT, LBA-mapped 065E 7405 JZ TYPE_WIN95_OSR2_32BIT_FAT_LBA
0660 3AC4 CMP AL,AH ;类型 WIN95 OSR2 32-bit FAT 0662 752B JNZ TYPE_DEFAULT 0664 40 INC AX ;AX=0B0C
TYPE_WIN95_OSR2_32BIT_FAT_LBA:
0665 C6462506 MOV BYTE PTR [BP+25],06 ;tmpvar=06 0669 7524 JNZ TYPE_DEFAULT ;这里有点问题,这个转移应该肯定不成立?//本文转自www.45its.com电脑软硬件应用网
TYPE_WIN95_DOS_16BIT_FAT_LBA:
066B BBAA55 MOV BX,55AA 066E 50 PUSH AX 066F B441 MOV AH,41 0671 CD13 INT 13 ;int 13h扩展功能的检测,IBM/MS INT 13 Extensions - INSTALLATION CHECK 0673 58 POP AX 0674 7216 JB INT13H_EXTENSION_UNSUPPORTED ;CF=1 - 不支持int 13h扩展功能 0676 81FB55AA CMP BX,AA55 ;BX不为AA55 - 不支持int 13h扩展功能 067A 7510 JNZ INT13H_EXTENSION_UNSUPPORTED 067C F6C101 TEST CL,01 ;CL不为1 - 不支持int 13h扩展功能 067F 740B JZ INT13H_EXTENSION_UNSUPPORTED 0681 8AE0 MOV AH,AL ;AH=0E 0683 885624 MOV [BP+24],DL ;tmpvar=DL,引导分区标志 0686 C706A106EB1E MOV WORD PTR [06A1],1EEB ;改06A1处指令为PUSH DS; JMP NEW_LOCATION_1
INT13H_EXTENSION_UNSUPPORTED:
068C 886604 MOV [BP+04],AH ;如果支持的话置分区类型为0E(类型 WIN95: DOS 16-bit FAT, LBA-mapped) ;否则为06(类型 DOS 3.31+ 16-bit FAT over 32M)
TYPE_DEFAULT:
068F BF0A00 MOV DI,000A
READ_SECTOR_LOOP:
0692 B80102 MOV AX,0201 0695 8BDC MOV BX,SP ;BX设置为7C00 0697 33C9 XOR CX,CX ;CX=0 0699 83FF05 CMP DI,+05 069C 7F03 JG NEW_LOCATION_0
069E 8B4E25 MOV CX,[BP+25]
NEW_LOCATION_0:
06A1 034E02 ADD CX,[BP+02] 06A4 CD13 INT 13 ;将活动分区的起始扇区读到0000:7C00
NEW_LOCATION_1:
06A6 7229 JB READ_SECTOR_ERROR ;CF=1 - 错误 06A8 BE5907 MOV SI,0759 06AB 813EFE7D55AA CMP WORD PTR [7DFE],AA55 ;扇区结束标志是否正确? 06B1 745A JZ READ_SECTOR_SUCCEEDED ;正确 06B3 83EF05 SUB DI,+05 ;DI=DI-5 06B6 7FDA JG READ_SECTOR_LOOP
06B8 85F6 TEST SI,SI 06BA 7583 JNZ DISPLAY_ERROR_MESSAGE_LOOP: ;显示错误信息:缺少操作系统
06BC BE2E07 MOV SI,072E 06BF EB8A JMP DISPLAY_ERROR_MESSAGE_LOOP_ALIAS ;显示错误信息:加载操作系统时发生错误。
070D EB74 JMP CONTINUE_KOAD_OS
0783 8BFC MOV DI,SP ;DI=7C00 0785 1E PUSH DS 0786 57 PUSH DI 0787 8BF5 MOV SI,BP 0789 CB RETF ;转到执行0000:7C00处的语句,即操作系统的引导程序
|