MBRは何をしてるか

HDDのMBRってのが何をしてるのかを調べてみた。

とりあえずターゲットはvistaでフォーマットしたHDD。
ダンプしてみるとこんな感じです。

まずざっくりと・・・



0000〜01bdはブートコード。
01b8〜01bbはNTシグネチャ。
01bc〜01bdは未使用?
01be〜01fdはパーティションテーブル。
01fe〜01ffはマジックナンバー(55,aa)。
まあこの辺はどっかで規格調べればすぐわかるかな。

というわけでMBRを逆アセンブルしてみました。

まず条件として、MBRが読み込まれるのは、
・CPUモード:8086互換モード(16bit)
・MBRが読み込まれるアドレス:0000:7c00
・DLレジスタ:起動ドライブ番号(80〜)
らしい。

でもって、重要なのはその中身。
逆アセンブル+コメントを作ったのでのせてみる。
結局のところ、処理自体は単純で、
・アクティブパーティションのサーチ
・アクティブパーティションの先頭を7C00に読み込む
・DLを設定(MBR読み込み時に貰った値)して7C00に飛ぶ
だけという事でした。
気になったのは、16bitモードで動いてるにもかかわらず、
LBAアクセスに32bitコードが混在している点。
素の8086じゃこのMBRは動かないわけで・・・・
まあ今更そんな環境ありえないだろうけどね。

謎なコードとしては、PS/2キーボード関連のIO操作。
これについては解りませんでした。

以下逆アセンブル結果。
7C00 33C0           xor ax, ax
7C02 8ED0           mov ss, ax
7C04 BC007C         mov sp, 7C00
7C07 8EC0           mov es, ax
7C09 8ED8           mov ds, ax
7C0B BE007C         mov si, 7C00
7C0E BF0006         mov di, 0600
7C11 B90002         mov cx, 0200
7C14 FC             cld
7C15 F3 A4          repz movsb          ;7c00-7dffを0600にコピー
7C17 50             push ax
7C18 681C06         push 061C
7C1B CB             retf                ;061cへ飛ぶ

061C FB             sti                 ;Set Interrupt Flag
061D B90400         mov cx, 0004        ;パーティションテーブルの数
0620 BDBE07         mov bp, 07BE        ;パーティションテーブルの開始アドレス
0623 807E0000       cmp byte ptr [bp+00], 00
0627 7C0B           jl 0634             ;アクティブパーティションならジャンプ
0629 0F851001       jne 073D            ;0以外ならジャンプ("Invalid partition tabe"を表示して停止)
062D 83C510         add bp, 0010
0630 E2F1           loop 0623
0632 CD18           int 18              ;ブート可能領域が無い

;パーティションテーブルに
;アクティブパーティションを発見
0634 885600         mov [bp+00], dl     ;dlはドライブ番号
0637 55             push bp
0638 C6461105       mov byte ptr [bp+11], 05    ;リードエラー時5回再試行
063C C6461000       mov byte ptr [bp+10], 00    ;LBAアクセスが使えるかのフラグ保存用
0640 B441           mov ah, 41
0642 BBAA55         mov bx, 55AA
0645 CD13           int 13              ;int13extが使えるかの確認
0647 5D             pop bp
0648 720F           jb 0659             ;使えないとジャンプ
064A 81FB55AA       cmp bx, AA55
064E 7509           jne 0659            ;使えないとジャンプ
0650 F7C10100       test cx, 0001
0654 7403           je 0659             ;使えないとジャンプ
0656 FE4610         inc byte ptr [bp+10]
0659 6660           pushad
065B 807E1000       cmp byte ptr [bp+10], 00
065F 7426           je 0687             ;int13extが使えない場合ジャンプ
0661 666800000000   push 00000000       ;int13-42用のパラメーター設定
0667 66FF7608       push dword ptr [bp+08];アクティブパーティションのLBA開始セクタ
066B 680000         push 0000
066E 68007C         push 7C00
0671 680100         push 0001
0674 681000         push 0010
0677 B442           mov ah, 42
0679 8A5600         mov dl, [bp+00]
067C 8BF4           mov si, sp
067E CD13           int 13              ;アクティブパーティションの先頭セクタを7c00に読み込む
0680 9F             lahf                ;フラグレジスタをahに待避
0681 83C410         add sp, 0010        ;int13-42に使ったスタックを復帰
0684 9E             sahf                ;フラグレジスタ復帰
0685 EB14           jmp 069B
0687 B80102         mov ax, 0201
068A BB007C         mov bx, 7C00
068D 8A5600         mov dl, [bp+00]
0690 8A7601         mov dh, [bp+01]
0693 8A4E02         mov cl , [bp+02]
0696 8A6E03         mov ch, [bp+03]
0699 CD13           int 13              ;アクティブパーティションの先頭セクタを7c00に読み込む(CHS使用)
069B 6661           popad
069D 731E           jnb 06BD            ;正常に読み込めたらジャンプ
069F FE4E11         dec byte ptr [bp+11];リードエラーカウント減算
06A2 0F850C00       jne 06B2
06A6 807E0080       cmp byte ptr [bp+00], 80
06AA 0F848A00       je 0738             ;ドライブ番号が80hなら"Error loading operating system"を表示して停止
06AE B280           mov dl, 80
06B0 EB82           jmp 0634            ;ドライブ番号を80hとして再試行(dlにドライブ番号を渡さないbiosがあるらしい)
06B2 55             push bp             ;disk reset
06B3 32E4           xor ah, ah
06B5 8A5600         mov dl, [bp+00]
06B8 CD13           int 13
06BA 5D             pop bp
06BB EB9C           jmp 0659            ;パーティション先頭のリード再試行

;アクティブパーティションの先頭が読み込めた
06BD 813EFE7D55AA   cmp word ptr [7DFE], AA55   ;そもそもMBRのマジックナンバーが有効かの確認
06C3 756E           jne 0733            ;有効で無い場合"Missing operating system"を表示して停止
06C5 FF7600         push word ptr [bp+00]
06C8 E88A00         call 0755           ;PS/2キーボードリセット(?)
06CB 0F851500       jne 06E4
06CF B0D1           mov al, D1
06D1 E664           out 64, al
06D3 E87F00         call 0755
06D6 B0DF           mov al, DF
06D8 E660           out 60, al
06DA E87800         call 0755
06DD B0FF           mov al, FF
06DF E664           out 64, al
06E1 E87100         call 0755

06E4 B800BB         mov ax, BB00        ;int1a bb00(TCG_StatusCheck)
06E7 CD1A           int 1A
06E9 6623C0         and eax, eax
06EC 753B           jne 0729            ;TCG非対応ならジャンプ
06EE 6681FB54435041 cmp ebx, 41504354
06F5 7532           jne 0729            ;TCG非対応ならジャンプ
06F7 81F90201       cmp cx, 0102
06FB 722C           jb 0729             ;Ver1.2未満ならジャンプ
06FD 666807BB0000   push 0000BB07       ;eax
0703 666800020000   push 00000200       ;ecx(Length)
0709 666808000000   push 00000008       ;edx(PCR index=NTFSブートセクター)
070F 6653           push ebx            ;ebx=41504354h
0711 6653           push ebx            ;esp(dummy)
0713 6655           push ebp            ;ebp(dummy)
0715 666800000000   push 00000000       ;esi
071B 6668007C0000   push 00007C00       ;edi
0721 6661           popad
0723 680000         push 0000
0726 07             pop es
0727 CD1A           int 1A              ;int1a bb07(TCG_CompactHashLogExtendEvent)
                                         ※TCG用のMBRのハッシュ化?

0729 5A             pop dx              ;dlを復帰
072A 32F6           xor dh, dh
072C EA007C0000     jmp 0000:7C00       ;リードしたアクティブパーティションのIPLへ

0731 CD18           int 18

0733 A0B707         mov al, [07B7]      ;"Missing operating system"文字列へのポインタ
0736 EB08           jmp 0740
0738 A0B607         mov al, [07B6]      ;"Error loading operating system"文字列へのポインタ
073B EB03           jmp 0740
073D A0B507         mov al, [07B5]      ;"Invalid partition tabe"文字列へのポインタ

;文字列表示
0740 32E4           xor ah, ah
0742 050007         add ax, 0700
0745 8BF0           mov si, ax
0747 AC             lodsb
0748 3C00           cmp al, 00
074A 74FC           je 0748             ;文字列終了なら無限ループ
074C BB0700         mov bx, 0007
074F B40E           mov ah, 0E
0751 CD10           int 10              ;一文字表示
0753 EBF2           jmp 0747

;PS/2キーボードIOバッファクリア?
0755 2BC9           sub cx, cx
0757 E464           in al, 64
0759 EB00           jmp 075B
075B 2402           and al, 02
075D E0F8           loopnz 0757
075F 2402           and al, 02
0761 C3             ret


0762 db "Invalid partition tabe",0
077a db "Error loading operating system",0
0799 db "Missing operating system",0

07B5 db 62h
07b6 db 7ah
07b7 db 99h


感想、要望、バグ報告、その他何かありましたら、メールもしくは掲示板にてご連絡ください。
裕之  
ホームに戻る