?? 硬盤主引導(dǎo)記錄.txt
字號:
; 說明:硬盤主引導(dǎo)記錄獨(dú)立于操作系統(tǒng),但又和操作系統(tǒng)息息相關(guān)——很多時(shí)候它又是由
; 操作系統(tǒng)所提供的工具所生成(例外的情況是您使用了其他的分區(qū)工具,不過它又運(yùn)行在
; 什么操作系統(tǒng)中呢?;()。
;
; 如果您安裝了Windows 98(我現(xiàn)在暫時(shí)不能接觸95下的主引導(dǎo)記錄,總不能用95重裝我的
; 系統(tǒng)吧?)操作系統(tǒng),那您機(jī)器上的主引導(dǎo)記錄已經(jīng)與以前的大有不同了,通過下面的分析
; 您一定能對Windows 98為什么要更改主引導(dǎo)記錄有所了解——它已經(jīng)開始支持?jǐn)U展Int13h
; 了!并且這個(gè)主引導(dǎo)記錄的編程技巧更是我們應(yīng)該學(xué)習(xí)的。
;
; 主引導(dǎo)記錄包括代碼、數(shù)據(jù)兩部分。它在被BIOS中斷Int19h裝入內(nèi)存后獲得控制權(quán)。數(shù)據(jù)
; 部分最重要的當(dāng)然是分區(qū)表了!徹底熟悉主引導(dǎo)記錄,可以幫助我們了解系統(tǒng)的引導(dǎo)過程,
; 處理因主引導(dǎo)記錄損壞所造成的無法引導(dǎo)故障,消除引導(dǎo)型計(jì)算機(jī)病毒,更使我們能通過
; 修改主引導(dǎo)記錄完成我們希望的工作:如多重引導(dǎo),系統(tǒng)加軟鎖等...
;
; BIOS中斷總是把主引導(dǎo)記錄所在扇區(qū)(硬盤的0頭0道1扇區(qū))的內(nèi)容(包括代碼和數(shù)據(jù))
; 裝入內(nèi)存0000:7C00起始的區(qū)域,然后檢驗(yàn)該扇區(qū)內(nèi)容的最后兩個(gè)字節(jié)是不是“AA55”,
; 如果不是,那么對不起,Int19h將不把控制權(quán)交給主引導(dǎo)記錄;若是,則下面的主引導(dǎo)記錄
; 才能獲得了控制權(quán)了(Int19通過跳轉(zhuǎn)指令交轉(zhuǎn)控制權(quán)):
;
; 反匯編結(jié)果
;
; 0000:7C00~0000:7C1A:初始化各個(gè)段寄存器、堆棧指針,最后將主引導(dǎo)記錄在內(nèi)存中搬家,騰出其所占內(nèi)
; 存空間以供裝入分區(qū)引導(dǎo)記錄。
0000:7C00 33C0 XOR AX,AX ;AX寄存器清0
0000:7C02 8ED0 MOV SS,AX ;SS=0
0000:7C04 BC007C MOV SP,7C00 ;裝填棧指針——SS:SP=0000:7C00
0000:7C07 FB STI ;開中斷(裝填棧指針時(shí)為避免硬件中斷引起棧混亂應(yīng)關(guān)中斷)
0000:7C08 50 PUSH AX ;
0000:7C09 07 POP ES ;裝填附加數(shù)據(jù)段寄存器ES=0
0000:7C0A 50 PUSH AX ;
0000:7C0B 1F POP DS ;裝填數(shù)據(jù)段寄存器DS=0
0000:7C0C FC CLD ;規(guī)定其后的串操作為正向串操作
0000:7C0D BE1B7C MOV SI,7C1B ;源指針
0000:7C10 BF1B06 MOV DI,061B ;目的指針
0000:7C13 50 PUSH AX ;
0000:7C14 57 PUSH DI ;看看0000:7C1A——構(gòu)造一個(gè)跳轉(zhuǎn)
0000:7C15 B9E501 MOV CX,01E5 ;
0000:7C18 F3 REPZ ;
0000:7C19 A4 MOVSB ;0000:7C1B起始的CX字節(jié)傳送至0000:061B起始的區(qū)域
0000:7C1A CB RETF ;跳轉(zhuǎn)到0000:061B(這是一種技巧跳轉(zhuǎn))
;
; 為直觀起見,下面的地址按實(shí)際運(yùn)行時(shí)的地址給出。
; 0000:061B~0000:062B:對分區(qū)表進(jìn)行初步檢驗(yàn),一旦檢測到某分區(qū)表項(xiàng)狀態(tài)字節(jié)大于等于80h,就通過(當(dāng)
; 然,在此之前如果檢測到某項(xiàng)分區(qū)表的狀態(tài)字節(jié)小于80h,就轉(zhuǎn)錯(cuò)誤處理。當(dāng)然,如果四個(gè)分區(qū)項(xiàng)的狀態(tài)字節(jié)
; 都為零,主引導(dǎo)記錄就會(huì)調(diào)用BIOS-ROM的INT 18h,顯示"PRESS A KEY TO REBOOT"信息等待你的操作。
0000:061B BEBE07 MOV SI,07BE ;SI指向第一個(gè)分區(qū)表項(xiàng),這時(shí)CX=0
0000:061E B104 MOV CL,04 ;分區(qū)表共四個(gè)表項(xiàng)
0000:0620 382C CMP [SI],CH ;
0000:0622 7C09 JL 062D ;大于等于80h轉(zhuǎn)[注意JL指令:(SF xor OF)=1則轉(zhuǎn)]
0000:0624 7515 JNZ 063B ;不為0則[SI]一定小于80h,只能轉(zhuǎn)錯(cuò)誤處理了!
0000:0626 83C610 ADD SI,+10 ;為零則檢查下一表項(xiàng)
0000:0629 E2F5 LOOP 0620 ;檢查下一表項(xiàng)
0000:062B CD18 INT 18 ;四表項(xiàng)的狀態(tài)字節(jié)都為0,則系統(tǒng)只好調(diào)用INT 18h了!
;
; 0000:062D~0000:0639:檢查剩余的分區(qū)表項(xiàng)——狀態(tài)字節(jié)必須為零,否則顯示錯(cuò)誤信息“分區(qū)表無效”然
; 后當(dāng)機(jī)!拜托,微軟搞錯(cuò)沒有,怎么用中文提示信息?真TM傻得可愛!
; 這里還有個(gè)小BUG,前面放行原則是只要狀態(tài)字節(jié)大于等于80h,那么如果這個(gè)字節(jié)是諸如A0h、E5h之類數(shù)值
; 呢?嘿嘿,這個(gè)引導(dǎo)記錄統(tǒng)統(tǒng)認(rèn)為是有效的可引導(dǎo)分區(qū)了!
0000:062D 8B14 MOV DX,[SI] ;為讀分區(qū)引導(dǎo)記錄做準(zhǔn)備:磁頭號→DH,驅(qū)動(dòng)器號→DL
0000:062F 8BEE MOV BP,SI ;SI→BP,保存可引導(dǎo)分區(qū)表項(xiàng)的指針
;
0000:0631 83C610 ADD SI,+10 ;其余的分區(qū)表項(xiàng)還要檢查檢查的
0000:0634 49 DEC CX ;
0000:0635 7416 JZ 064D ;CX=0則檢查順利通過,轉(zhuǎn)繼續(xù)
0000:0637 382C CMP [SI],CH ;
0000:0639 74F6 JZ 0631 ;為零,是合法表項(xiàng),再查下一表項(xiàng)
;
; 0000:063B~0000:064B:執(zhí)行錯(cuò)誤處理——報(bào)告錯(cuò)誤信息后當(dāng)機(jī)
0000:063B BE1007 MOV SI,0710 ;錯(cuò)誤信息字符串偏移+1→SI
0000:063E 4E DEC SI ;SI-1→SI
0000:063F AC LODSB ;SI+1→SI
0000:0640 3C00 CMP AL,00 ;
0000:0642 74FA JZ 063E ;AL=0則表明一條錯(cuò)誤信息顯示完畢,系統(tǒng)陷入一個(gè)死循環(huán)
0000:0644 BB0700 MOV BX,0007 ;字符方式顯示
0000:0647 B40E MOV AH,0E ;
0000:0649 CD10 INT 10 ;以寫電傳方式顯示信息(只顯示一個(gè)字符)
0000:064B EBF2 JMP 063F ;顯示下一個(gè)字符,直到遇到提示信息結(jié)束為止
;
; 0000:064D~0000:0662:判斷可引導(dǎo)分區(qū)的分區(qū)類型,然后轉(zhuǎn)相應(yīng)處理程序。
0000:064D 894625 MOV [BP+25],AX ;BP=指向第一個(gè)可引導(dǎo)分區(qū)表項(xiàng)的指針,這時(shí)AX=0000h
;使用長度最短的指令將[BP+25]起始的兩個(gè)單元清零
;這兩個(gè)單元將被用來存放中間變量
0000:0650 96 XCHG SI,AX ;此時(shí)SI清零的最佳指令選擇(僅1字節(jié)),將服務(wù)于0000:06B8
0000:0651 8A4604 MOV AL,[BP+04] ;取分區(qū)類型(本例是“06”嘍——FAT16主DOS分區(qū))
0000:0654 B406 MOV AH,06 ;為擴(kuò)展INT 13h無法使用做好更改分區(qū)類型的準(zhǔn)備
0000:0656 3C0E CMP AL,0E ;0Eh:需要用擴(kuò)展INT 13h訪問的FAT16主DOS分區(qū)
0000:0658 7411 JZ 066B ;0Eh類型的分區(qū)轉(zhuǎn)066Bh
0000:065A B40B MOV AH,0B ;
0000:065C 3C0C CMP AL,0C ;0Ch:需要用擴(kuò)展INT 13h訪問的FAT32分區(qū)
0000:065E 7405 JZ 0665 ;0Ch類型的分區(qū)轉(zhuǎn)0665h先行預(yù)處理
0000:0660 3AC4 CMP AL,AH ;0Bh:用傳統(tǒng)INT 13h就可以訪問的FAT32分區(qū)
0000:0662 752B JNZ 068F ;其他類型的分區(qū)轉(zhuǎn)068Fh
;
; 0000:0664~0000:06A1:根據(jù)分區(qū)類型和分區(qū)表表項(xiàng)內(nèi)容進(jìn)行讀取分區(qū)引導(dǎo)記錄前的處理工作
0000:0664 40 INC AX ;★★★0Bh類型的分區(qū)由此開始處理,此條指令用意是清ZF位
0000:0665 C6462506 MOV BYTE PTR [BP+25],06 ;★★★0Ch類型的分區(qū)由此開始處理
;為什么取值06,一時(shí)沒有自圓我說的解釋,請耐心幾天吧。
0000:0669 7524 JNZ 068F ;請注意上面指令對ZF位的影響:0Bh類型分區(qū)轉(zhuǎn),0Ch則不轉(zhuǎn)
; 0000:066B~0000:068C這段代碼僅當(dāng)分區(qū)類型是0Ch、0Eh才有獲得執(zhí)行的機(jī)會(huì)
0000:066B BBAA55 MOV BX,55AA ;★★★0Eh類型的分區(qū)由此開始處理
0000:066E 50 PUSH AX ;
0000:066F B441 MOV AH,41 ;擴(kuò)展INT 13h功能,檢測BIOS是否已經(jīng)支持?jǐn)U展INT13h
0000:0671 CD13 INT 13 ;入口參數(shù):BX=55AAh,DL=驅(qū)動(dòng)器號,AH=41h
0000:0673 58 POP AX ;執(zhí)行完恢復(fù)AX為060Eh
0000:0674 7216 JB 068C ;不支持則轉(zhuǎn)
0000:0676 81FB55AA CMP BX,AA55 ;
0000:067A 7510 JNZ 068C ;擴(kuò)展INT13h不可用也轉(zhuǎn)
0000:067C F6C101 TEST CL,01 ;測試擴(kuò)展盤訪問是否被支持
0000:067F 740B JZ 068C ;不支持還轉(zhuǎn)
; 因?yàn)閿U(kuò)展INT13h方式讀盤與標(biāo)準(zhǔn)INT13h方式讀盤有很大差別,所以0000:0686處指令修改其后的代碼以保證按
; 照擴(kuò)展讀方式讀分區(qū)引導(dǎo)扇區(qū)時(shí)能正確跳轉(zhuǎn)到相應(yīng)的處理程序中。
0000:0681 8AE0 MOV AH,AL ;分區(qū)類型→AH
0000:0683 885624 MOV [BP+24],DL ;保存驅(qū)動(dòng)器號→[BP+24]
0000:0686 C706A106EB1E MOV WORD PTR [06A1],1EEB ;修改0000:06A1處代碼為"JMP 06C1"
0000:068C 886604 MOV [BP+04],AH ;注意:如果擴(kuò)展INT13h不能使用則A改分區(qū)類型為06,但如果
;擴(kuò)展INT13h能使用,則仍保持原分區(qū)類型不變
0000:068F BF0A00 MOV DI,000A ;★★★其它類型分區(qū)由此開始處理。此條指令初始化計(jì)數(shù)器
0000:0692 B80102 MOV AX,0201 ;AH:讀操作,AL:讀取1個(gè)扇區(qū)的內(nèi)容
0000:0695 8BDC MOV BX,SP ;SP=7C00→BX,指定分區(qū)引導(dǎo)記錄裝入內(nèi)存的位置偏移
0000:0697 33C9 XOR CX,CX ;CX清零
0000:0699 83FF05 CMP DI,+05 ;注意50000:069C 7F03 JG 06A1 ;大于則轉(zhuǎn)去讀由分區(qū)表指定的分區(qū)引導(dǎo)扇區(qū)
0000:069E 8B4E25 MOV CX,[BP+25] ;小于則證明所讀分區(qū)表指定的引導(dǎo)扇區(qū)無合法的引導(dǎo)記錄,
;改按???再讀,畢竟多一種選擇多一次機(jī)會(huì)嘛!;)
; 以下標(biāo)有①②者請注意它們的地址都是一樣的,就是說實(shí)際運(yùn)行中只可能是二者之一,但為了分析之方便,我
; 把兩者都列了出來以供對比,閱讀時(shí)千萬別看成是兩條指令了啊!
①0000:06A1 034E02 ADD CX,[BP+02] ;獲取分區(qū)引導(dǎo)扇區(qū)所在的柱面號和物理扇區(qū)號
②0000:06A1 EB1E JMP 06C1 ;如果分區(qū)類型是0Ch、0Eh而且擴(kuò)展讀能使用則執(zhí)行該指令
;
; 0000:06A4:將可引導(dǎo)分區(qū)的分區(qū)引導(dǎo)記錄裝入內(nèi)存指定區(qū)域
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -