初めに
これまでの記事
FAT16の構造研究1ブートセクタ
FAT16の構造研究2ダンプを見て構造を分析
今回はFAT16上でファイル及びディレクトリを生成してルートディレクトリがどう変化するかをバイナリで追います。
細かい値は一旦気にせず、生成、削除でどのようなデータが登録されるのかを重点的に観察します。
観察対象
- 名前小文字ファイル(test1.txt)
- 名前大文字ファイル(TEST2.TXT)
- 名前小文字ファイル(test3.txt) 削除
- 名前大文字ファイル(TEST4.TXT) 削除
- 8文字を超える小文字ファイル名(very_long_file_name1.txt)
- 8文字を超える大文字ファイル名(VERY_LONG_FILE_NAME2.txt)
- 8文字を超える小文字ファイル名(very_long_file_name3.txt) 削除
- 8文字を超える大文字ファイル名(VERY_LONG_FILE_NAME4.txt) 削除
- 名前小文字ディレクトリ(dir1)
- 名前大文字ディレクトリ(DIR2)
- 名前小文字ディレクトリ(dir3) 削除
- 名前大文字ディレクトリ(dir4) 削除
FATルートディレクトリの構造
typedef struct __attribute__((packed)) {
uint8_t filename[8]; // ファイル名 (8バイト)
uint8_t extension[3]; // 拡張子 (3バイト)
uint8_t attributes; // ファイル属性
uint8_t reserved; // 予約領域 (通常0)
uint8_t creation_time_ms; // 作成時刻 (10ms単位)
uint16_t creation_time; // 作成時刻 (時/分/秒)
uint16_t creation_date; // 作成日付 (年/月/日)
uint16_t last_access_date; // 最終アクセス日付
uint16_t first_cluster_hi; // 開始クラスタ上位16bit (FAT16では通常0)
uint16_t last_write_time; // 最終更新時刻
uint16_t last_write_date; // 最終更新日付
uint16_t first_cluster_lo; // 開始クラスタ下位16bit
uint32_t file_size; // ファイルサイズ (バイト単位)
} fat16_dir_entry_t;
ルートディレクトリの開始位置
以下の記事でBPBを解析し、ルートディレクトリは以下のセクタから始まると判明しています。
ルートディレクトリ開始セクタ = 予約セクタ + (FAT数 × FAT大きさ) = 4 + (2 × 20) = 4 + 40 = 44セクタ
バイトオフセット: 44 × 512 = 22528バイト
ファイルの生成
仮想ディスク生成
dd if=/dev/zero of=fat16.img bs=1M count=10
sudo mkfs.vfat -F 16 fat16.img
sudo mount -o loop,uid=$(id -u),gid=$(id -g) fat16.img /mnt
ファイルを生成及び削除。※削除したあと上書きされないように一気に生成してから削除する
# 検体生成
echo "TEST FILE1" | sudo tee /mnt/test1.txt
echo "TEST FILE2" | sudo tee /mnt/TEST2.TXT
echo "TEST FILE3" | sudo tee /mnt/test3.txt # 削除
echo "TEST FILE4" | sudo tee /mnt/TEST4.TXT # 削除
echo "LONG FILE TEST FILE1" | sudo tee /mnt/very_long_file_name1.txt
echo "LONG FILE TEST FILE2" | sudo tee /mnt/VERY_LONG_FILE_NAME2.txt
echo "LONG FILE TEST FILE3" | sudo tee /mnt/very_long_file_name3.txt # 削除
echo "LONG FILE TEST FILE4" | sudo tee /mnt/VERY_LONG_FILE_NAME4.txt # 削除
sudo mkdir /mnt/dir1
sudo mkdir /mnt/DIR2
sudo mkdir /mnt/dir3 # 削除
sudo mkdir /mnt/DIR4 # 削除
# 検体削除
sudo rm /mnt/test3.txt
sudo rm /mnt/TEST4.TXT
sudo rm /mnt/very_long_file_name3.txt
sudo rm /mnt/VERY_LONG_FILE_NAME4.txt
sudo rmdir /mnt/dir3
sudo rmdir /mnt/DIR4
# 確認
ls -la /mnt/
ルートディレクトリの観察
test@test-fujitsu:~/kaihatsu$ xxd -s 22528 -l 1028 fat16.img
00005800: 4174 0065 0073 0074 0031 000f 00cb 2e00 At.e.s.t.1......
00005810: 7400 7800 7400 0000 ffff 0000 ffff ffff t.x.t...........
00005820: 5445 5354 3120 2020 5458 5420 002f 2521 TEST1 TXT ./%!
00005830: a15c a15c 0000 2521 a15c 0300 0b00 0000 .\.\..%!.\......
00005840: 5445 5354 3220 2020 5458 5420 0030 2521 TEST2 TXT .0%!
00005850: a15c a15c 0000 2521 a15c 0400 0b00 0000 .\.\..%!.\......
00005860: e574 0065 0073 0074 0033 000f 00d3 2e00 .t.e.s.t.3......
00005870: 7400 7800 7400 0000 ffff 0000 ffff ffff t.x.t...........
00005880: e545 5354 3320 2020 5458 5420 0031 2521 .EST3 TXT .1%!
00005890: a15c a15c 0000 2521 a15c 0000 0000 0000 .\.\..%!.\......
000058a0: e545 5354 3420 2020 5458 5420 0032 2521 .EST4 TXT .2%!
000058b0: a15c a15c 0000 2521 a15c 0000 0000 0000 .\.\..%!.\......
000058c0: 4265 005f 006e 0061 006d 000f 00b0 6500 Be._.n.a.m....e.
000058d0: 3100 2e00 7400 7800 7400 0000 0000 ffff 1...t.x.t.......
000058e0: 0176 0065 0072 0079 005f 000f 00b0 6c00 .v.e.r.y._....l.
000058f0: 6f00 6e00 6700 5f00 6600 0000 6900 6c00 o.n.g._.f...i.l.
00005900: 5645 5259 5f4c 7e31 5458 5420 0033 2521 VERY_L~1TXT .3%!
00005910: a15c a15c 0000 2521 a15c 0700 1500 0000 .\.\..%!.\......
00005920: 4245 005f 004e 0041 004d 000f 0090 4500 BE._.N.A.M....E.
00005930: 3200 2e00 7400 7800 7400 0000 0000 ffff 2...t.x.t.......
00005940: 0156 0045 0052 0059 005f 000f 0090 4c00 .V.E.R.Y._....L.
00005950: 4f00 4e00 4700 5f00 4600 0000 4900 4c00 O.N.G._.F...I.L.
00005960: 5645 5259 5f4c 7e32 5458 5420 0035 2521 VERY_L~2TXT .5%!
00005970: a15c a15c 0000 2521 a15c 0800 1500 0000 .\.\..%!.\......
00005980: e565 005f 006e 0061 006d 000f 0070 6500 .e._.n.a.m...pe.
00005990: 3300 2e00 7400 7800 7400 0000 0000 ffff 3...t.x.t.......
000059a0: e576 0065 0072 0079 005f 000f 0070 6c00 .v.e.r.y._...pl.
000059b0: 6f00 6e00 6700 5f00 6600 0000 6900 6c00 o.n.g._.f...i.l.
000059c0: e545 5259 5f4c 7e33 5458 5420 0036 2521 .ERY_L~3TXT .6%!
000059d0: a15c a15c 0000 2521 a15c 0000 0000 0000 .\.\..%!.\......
000059e0: e545 005f 004e 0041 004d 000f 00d0 4500 .E._.N.A.M....E.
000059f0: 3400 2e00 7400 7800 7400 0000 0000 ffff 4...t.x.t.......
00005a00: e556 0045 0052 0059 005f 000f 00d0 4c00 .V.E.R.Y._....L.
00005a10: 4f00 4e00 4700 5f00 4600 0000 4900 4c00 O.N.G._.F...I.L.
00005a20: e545 5259 5f4c 7e34 5458 5420 0037 2521 .ERY_L~4TXT .7%!
00005a30: a15c a15c 0000 2521 a15c 0000 0000 0000 .\.\..%!.\......
00005a40: 4164 0069 0072 0031 0000 000f 00a8 ffff Ad.i.r.1........
00005a50: ffff ffff ffff ffff ffff 0000 ffff ffff ................
00005a60: 4449 5231 2020 2020 2020 2010 0038 2521 DIR1 ..8%!
00005a70: a15c a15c 0000 2521 a15c 0b00 0000 0000 .\.\..%!.\......
00005a80: 4449 5232 2020 2020 2020 2010 0039 2521 DIR2 ..9%!
00005a90: a15c a15c 0000 2521 a15c 0c00 0000 0000 .\.\..%!.\......
00005aa0: e564 0069 0072 0033 0000 000f 001c ffff .d.i.r.3........
00005ab0: ffff ffff ffff ffff ffff 0000 ffff ffff ................
00005ac0: e549 5233 2020 2020 2020 2010 003a 2521 .IR3 ..:%!
00005ad0: a15c a15c 0000 2521 a15c 0d00 0000 0000 .\.\..%!.\......
00005ae0: e549 5234 2020 2020 2020 2010 003b 2521 .IR4 ..;%!
00005af0: a15c a15c 0000 2521 a15c 0e00 0000 0000 .\.\..%!.\......
00005b00: 0000 0000 0000 0000 0000 0000 0000 0000 ................
00005b10: 0000 0000 0000 0000 0000 0000 0000 0000 ................
...(省略)...
各要素毎に確認
ルートディレクトリの要素の一つは32バイト、よって32バイト毎に分割して見ていく
test1.txt
MSDOS等では8.3形式の規則(大文字、8文字+3拡張子)しか表示できない。
このファイル名には小文字が含まれているので、MSDOS等で表示出来る従来の8.3形式の要素と、
小文字の要素の2つが登録されている。
00005800: 4174 0065 0073 0074 0031 000f 00cb 2e00 At.e.s.t.1......
00005810: 7400 7800 7400 0000 ffff 0000 ffff ffff t.x.t...........
00005820: 5445 5354 3120 2020 5458 5420 002f 2521 TEST1 TXT ./%!
00005830: a15c a15c 0000 2521 a15c 0300 0b00 0000 .\.\..%!.\......
TEST2.TXT
8.3形式に合致するため、1つしか無い。
00005840: 5445 5354 3220 2020 5458 5420 0030 2521 TEST2 TXT .0%!
00005850: a15c a15c 0000 2521 a15c 0400 0b00 0000 .\.\..%!.\......
test3.txt
削除済みの為、先頭バイトがE5となっている。
00005860: e574 0065 0073 0074 0033 000f 00d3 2e00 .t.e.s.t.3......
00005870: 7400 7800 7400 0000 ffff 0000 ffff ffff t.x.t...........
00005880: e545 5354 3320 2020 5458 5420 0031 2521 .EST3 TXT .1%!
00005890: a15c a15c 0000 2521 a15c 0000 0000 0000 .\.\..%!.\......
TEST4.TXT
削除済み。先頭バイト = E5
000058a0: e545 5354 3420 2020 5458 5420 0032 2521 .EST4 TXT .2%!
000058b0: a15c a15c 0000 2521 a15c 0000 0000 0000 .\.\..%!.\......
very_long_file_name1.txt
ファイル名が長い場合は複数要素に分けて登録される模様。
000058c0: 4265 005f 006e 0061 006d 000f 00b0 6500 Be._.n.a.m....e.
000058d0: 3100 2e00 7400 7800 7400 0000 0000 ffff 1...t.x.t.......
000058e0: 0176 0065 0072 0079 005f 000f 00b0 6c00 .v.e.r.y._....l.
000058f0: 6f00 6e00 6700 5f00 6600 0000 6900 6c00 o.n.g._.f...i.l.
00005900: 5645 5259 5f4c 7e31 5458 5420 0033 2521 VERY_L~1TXT .3%!
00005910: a15c a15c 0000 2521 a15c 0700 1500 0000 .\.\..%!.\......
VERY_LONG_FILE_NAME2.txt
00005920: 4245 005f 004e 0041 004d 000f 0090 4500 BE._.N.A.M....E.
00005930: 3200 2e00 7400 7800 7400 0000 0000 ffff 2...t.x.t.......
00005940: 0156 0045 0052 0059 005f 000f 0090 4c00 .V.E.R.Y._....L.
00005950: 4f00 4e00 4700 5f00 4600 0000 4900 4c00 O.N.G._.F...I.L.
00005960: 5645 5259 5f4c 7e32 5458 5420 0035 2521 VERY_L~2TXT .5%!
00005970: a15c a15c 0000 2521 a15c 0800 1500 0000 .\.\..%!.\......
very_long_file_name3.txt
削除すると全要素の先頭バイトがE5になった。
00005980: e565 005f 006e 0061 006d 000f 0070 6500 .e._.n.a.m...pe.
00005990: 3300 2e00 7400 7800 7400 0000 0000 ffff 3...t.x.t.......
000059a0: e576 0065 0072 0079 005f 000f 0070 6c00 .v.e.r.y._...pl.
000059b0: 6f00 6e00 6700 5f00 6600 0000 6900 6c00 o.n.g._.f...i.l.
000059c0: e545 5259 5f4c 7e33 5458 5420 0036 2521 .ERY_L~3TXT .6%!
000059d0: a15c a15c 0000 2521 a15c 0000 0000 0000 .\.\..%!.\......
VERY_LONG_FILE_NAME4.txt
000059e0: e545 005f 004e 0041 004d 000f 00d0 4500 .E._.N.A.M....E.
000059f0: 3400 2e00 7400 7800 7400 0000 0000 ffff 4...t.x.t.......
00005a00: e556 0045 0052 0059 005f 000f 00d0 4c00 .V.E.R.Y._....L.
00005a10: 4f00 4e00 4700 5f00 4600 0000 4900 4c00 O.N.G._.F...I.L.
00005a20: e545 5259 5f4c 7e34 5458 5420 0037 2521 .ERY_L~4TXT .7%!
00005a30: a15c a15c 0000 2521 a15c 0000 0000 0000 .\.\..%!.\......
dir1
00005a40: 4164 0069 0072 0031 0000 000f 00a8 ffff Ad.i.r.1........
00005a50: ffff ffff ffff ffff ffff 0000 ffff ffff ................
00005a60: 4449 5231 2020 2020 2020 2010 0038 2521 DIR1 ..8%!
00005a70: a15c a15c 0000 2521 a15c 0b00 0000 0000 .\.\..%!.\......
DIR2
00005a80: 4449 5232 2020 2020 2020 2010 0039 2521 DIR2 ..9%!
00005a90: a15c a15c 0000 2521 a15c 0c00 0000 0000 .\.\..%!.\......
dir3
00005aa0: e564 0069 0072 0033 0000 000f 001c ffff .d.i.r.3........
00005ab0: ffff ffff ffff ffff ffff 0000 ffff ffff ................
00005ac0: e549 5233 2020 2020 2020 2010 003a 2521 .IR3 ..:%!
00005ad0: a15c a15c 0000 2521 a15c 0d00 0000 0000 .\.\..%!.\......
DIR4
00005ae0: e549 5234 2020 2020 2020 2010 003b 2521 .IR4 ..;%!
00005af0: a15c a15c 0000 2521 a15c 0e00 0000 0000 .\.\..%!.\......
ファイル名の見え方
Ubuntu
Ubuntuは小文字や長いファイル名に対応しており以下の様に表示されます。
MS-DOS
同じファイルをMS-DOS上で表示すると以下の様に8.3形式に合う形で表示されます
検証環境
機種 : FUJITSU FMVU14033
CPU : Intel® Core™ i5-7200U CPU @ 2.50GHz × 4
OS : Ubuntu 22.04.5 LTS