試しに、手元のUSBメモリを覗いてみよう。
データ用で使用しているのだが、ブートコードっぽい物もあるようなので、
とりあえず、追ってみる。
0x7c00 FA cli
0x7c01 B8 00 00 mov ax, 0
0x7c04 8E D0 mov ss, ax
0x7c06 BC 00 7C mov sp, 0x7c00
0x7c09 8B F4 mov si, sp
0x7c0b 50 push ax
0x7c0c 07 pop es
0x7c0d 50 push ax
0x7c0e 1F pop ds
0x7c0f FB sti
0x7c10 FC cld
0x7c11 BF 00 06 mov di, 0x600
0x7c14 B9 00 01 mov cx, 0x100
0x7c17 F3 A5 rep movsw word ptr es:[di], word ptr [si]
0x7c19 EA 1E 06 00 00 ljmp 0:0x61e
冒頭の処理は、見慣れた、お約束の手順で、
今回は、0x0600以降に自分自身をコピーしてから、処理を継続している。
なので、ロングジャンプ以降は、0x0000:0x0600からコードが始まっている前提になる。
0x061e BE BE 07 mov si, 0x7be
0x0621 80 3C 80 cmp byte ptr [si], 0x80
0x0624 74 02 je 0x628
0x0626 CD 18 int 0x18
0x0628 56 push si
0x0629 53 push bx
0x062a 06 push es
0x062b BB 00 7C mov bx, 0x7c00
0x062e B9 01 00 mov cx, 1
0x0631 BA 00 00 mov dx, 0
0x0634 B8 01 02 mov ax, 0x201
0x0637 CD 13 int 0x13
0x0639 07 pop es
0x063a 5B pop bx
0x063b 5E pop si
0x063c B2 80 mov dl, 0x80
0x063e 72 0B jb 0x64b
0x0640 BF BC 7D mov di, 0x7dbc
0x0643 81 3D 55 53 cmp word ptr [di], 0x5355
0x0647 75 02 jne 0x64b
0x0649 B2 00 mov dl, 0
0x064b BF EB 06 mov di, 0x6eb
0x064e 88 15 mov byte ptr [di], dl
0x0650 8A 74 01 mov dh, byte ptr [si + 1]
0x0653 8B 4C 02 mov cx, word ptr [si + 2]
0x0656 8B EE mov bp, si
0x0658 EB 15 jmp 0x66f
ドライブ番号0x00(フロッピーディスク)から1セクタ読み込みしているようだけど、かなり、謎な処理に見える。
とりあえず、フロッピーディスクから読み込みが成功した上で、特定のシグネチャが存在すれば、そのまま、フロッピーディスクから、
そうでなければ、ハードディスクから... のような流れに見える。
何故か、ここから、0x066Fへジャンプしていて、
後続のコードは、処理的には、エラーメッセージを表示した後、無限ループに入る。
エラーメッセージ:"Invalid partition table"
0x065a BE 9B 06 mov si, 0x69b
0x065d AC lodsb al, byte ptr [si]
0x065e 3C 00 cmp al, 0
0x0660 74 0B je 0x66d
0x0662 56 push si
0x0663 BB 07 00 mov bx, 7
0x0666 B4 0E mov ah, 0xe
0x0668 CD 10 int 0x10
0x066a 5E pop si
0x066b EB F0 jmp 0x65d
0x066d EB FE jmp 0x66d
続きは、結局、指定ドライブから1セクタ読み込んで、
ちょいちょい、意味不明な処理があるけど、
ブートシグネチャがあれば、そのまま、ロングジャンプする。
0x066f BB 00 7C mov bx, 0x7c00
0x0672 B8 01 02 mov ax, 0x201
0x0675 CD 13 int 0x13
0x0677 73 05 jae 0x67e
0x0679 BE B3 06 mov si, 0x6b3
0x067c EB DF jmp 0x65d
0x067e BE D2 06 mov si, 0x6d2
0x0681 BF FE 7D mov di, 0x7dfe
0x0684 81 3D 55 AA cmp word ptr [di], 0xaa55
0x0688 75 D3 jne 0x65d
0x068a BF 24 7C mov di, 0x7c24
0x068d BE EB 06 mov si, 0x6eb
0x0690 8A 04 mov al, byte ptr [si]
0x0692 88 05 mov byte ptr [di], al
0x0694 8B F5 mov si, bp
0x0696 EA 00 7C 00 00 ljmp0:0x7c00
まぁ、微妙に怪しいコードなんですが、パーティションテーブルを見てみると...
| 要素 |
16進値 |
10進値 |
補足 |
| ブートフラグ |
0x00 |
0 |
ブート不可 |
| 先頭セクタ[0] |
0xBC |
188 |
|
| 先頭セクタ[1] |
0x3D |
61 |
|
| 先頭セクタ[2] |
0x00 |
0 |
|
| タイプ |
0x0B |
11 |
FAT32 |
| 最終セクタ[0] |
0xBC |
188 |
|
| 最終セクタ[1] |
0xB8 |
184 |
|
| 最終セクタ[2] |
0x84 |
132 |
|
| 先頭セクタLBA |
0x00002E80 |
11,904 |
|
| 全セクタ数 |
0x1D0D5180 |
487,412,096 |
|
ブートフラグが、0x00なので、そもそも、ブート不可。
ブートコードが、怪しかろうが、関係なかった...
全セクタ数が、487,412,096(≒232GiB)なので、
CHS形式の方は、役に立たないので、多分、適当な値になっていると思われる。
3Byteフルに使っても、全然、足りないもんね...
パーティション先頭までの予約領域?が、11,904セクタってのも、大容量メディアには、ありがちなのだろうか?
ほぼ、6MiB... 小さくはないけれど、100Gi超えの容量では、誤差程度か?
誤差でフロッピー6枚分だもんなぁ... 隔世の感があるよなぁ...
何は、ともあれ、11,904セクタを覗いてみると、ちゃんとBPBが確認出来る。
| オフセット |
要素 |
サイズ |
16進値 |
10進値 |
補足 |
| 0x00 |
ジャンプコード |
3 |
EB 58 90 |
--- |
JMP 0x7C5A, NOP |
| 0x03 |
OEM名称 |
8 |
--- |
--- |
"MSDOS5.0" |
| 0x0B |
セクタサイズ |
2 |
0x0200 |
512 |
1セクタ=512Byte |
| 0x0D |
クラスタサイズ |
1 |
0x20 |
32 |
1クラスタ=32セクタ(16KiB) |
| 0x0E |
予約セクタ |
2 |
0x4FB8 |
20,408 |
これまた、でかいな... |
| 0x10 |
FATの数 |
1 |
0x02 |
2 |
|
| 0x11 |
ルートディレクトリのエントリ最大数 |
2 |
0x0000 |
0 |
FAT32だからね |
| 0x13 |
全セクタ数(16bit) |
2 |
0x0000 |
0 |
FAT32だからね |
| 0x15 |
メディア |
1 |
0xF8 |
--- |
|
| 0x16 |
FATサイズ(16bit) |
2 |
0x0000 |
0 |
FAT32だからね |
| 0x18 |
トラックあたりのセクタ数 |
2 |
0x003F |
63 |
|
| 0x1A |
ヘッド数 |
2 |
0x00FF |
256 |
|
| 0x1C |
隠しセクタ数 |
4 |
0x00002E80 |
11,904 |
パーティションテーブルの内容と一致 |
| 0x20 |
全セクタ数(32bit) |
4 |
0x1D0D5180 |
487,412,096 |
パーティションテーブルの内容と一致 |
| |
|
|
|
|
|
| 0x24 |
FATサイズ(32bit) |
4 |
0x0001D0B4 |
118,964 |
一つのFATが必要とするセクタ数 |
| 0x28 |
拡張フラグ |
2 |
0x0000 |
0 |
FATミラーリング有効 |
| 0x2C |
ルートクラスタ |
4 |
0x00000002 |
2 |
|
| 0x30 |
FSInfo |
2 |
0x0001 |
1 |
|
| 0x32 |
ブートセクタバックアップ |
2 |
0x006 |
6 |
|
| 0x34 |
予約 |
12 |
ALL 0 |
0 |
|
| |
|
|
|
|
|
| 0x40 |
ドライブ番号 |
0x00 |
0 |
フロッピー扱い? |
| 0x41 |
予約 |
1 |
0x00 |
0 |
|
| 0x42 |
シグネチャ |
1 |
0x29 |
--- |
お約束 |
| 0x43 |
ボリュームID |
4 |
0x5819BFB2 |
|
| 0x47 |
ボリュームラベル |
11 |
ALL 0x20 |
--- |
スペース埋め(NO NAME じゃなかったっけ?) |
| 0x53 |
ファイルシステム |
8 |
"FAT32 " |
--- |
|
一応、ブートコードっぽいバイナリが続くが、
ブート不可ボリュームだし、内容が怪しいので、今回は、スルー。
予約セクタが、20,408セクタってのも、デカすぎる気がするが、そういうもんなのか?
ひとまず、これを信じると、(隠しセクタ数) 11,904 + (予約セクタ数) 20,408 = 32, 312 が、FATの先頭になるはず。
実際に見てみると...
F8 FF FF FF
FF FF FF FF
FF FF FF 0F
FF FF FF 0F
それっぽい...
F8は、BPB_Media と同じ値。
1クラスタ目は、特殊フラグとして利用される場合もあるらしいが、ALL 1 であれば、異常なし。
2クラスタ目、3クラスタ目は、クラスタチェーンの終端となっている。
2クラスタ目は、ルートディレクトリのはず。
(FATサイズ) 118,964 x 2 = 237,928
なので...
(FAT先頭) 32,312 + 237,928 = 270,240
2クラスタ目の先頭は、ここになる。
以降、Nクラスタ目は、270,240 + 32 * (N - 2) という事になる。
とりあえず、これで、ディレクトリ情報は、追えそうな感じ。