在分析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 :[email protected]%.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 [email protected]......^..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.45it.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
06