FATで遊んだ話

お久しぶりです。今は人権がない状態なのですが、ここ最近はFAT(File Allocation Tableですよ)で遊んでます。特にFAT12/16をターゲットにしています。仕様はとてもシンプルですし、ドキュメントも、品質が高いものから低いものまでいろいろあります。

なにはともあれ、まずは
dd if=/dev/zero of=testimg1 bs=1024 count=32
mkfs.vfat ./testimg1
mkdir imgmnt
mount -t vfat testimg1 imgmnt
として環境を作って、その中で(英数字ファイル名、内容で)ファイルを作ったり書き込んだりしてから
umount testimg1
として、イメージ(testimg1)をバイナリエディタで見てみましょう。0埋めされている間にところどころ見覚えのある単語が見えるはずです。

下のスクショはルートディレクトリ領域。ここを主に触るソフトウェアを書きました。後述するように、SFNにASCII範囲外の文字列が入っていたり、LFNがUTF-8なのがわかるかと思います。実に謎です。

スクリーンショット_2016-04-20_21-39-27

ボリュームの最初にあるのがセクタサイズやクラスタサイズなどの読み込むのに必要な情報(予約領域)、次はどのセクタが使用済みか(FAT領域)、そしてファイル名及びその内容が記録されているクラスタ番号(ルートディレクトリ領域)、そのあとはデータ領域です。

とりあえずlsするものを作ってみました。8.3のSFN(Short File Name)とLFN(Long File Name)が記録されているので、それを読み出して表示するものです。FAT16でフォーマットされていれば、もちろん本物のUSBからでも読み込めます。マルチバイトファイル名にも対応しています。
./fat_ls /dev/sdb1
のように。マウントしないで中身を見られるのは面白い。


LFNはUTF-16-LEだと書いてあるところが多いのですが、どうもUTF-8の間1バイトずつに0x00を入れた実装をしているものもあるようです。空イメージをmountでマウントして書き込んだところ、そうなりました。
しかし、XfceのThunarの自動マウントではUTF-16。また、mountもUTF-16で書き込まれたLFNが一つでもあるとUTF-16で読み書きするので、それまでに作ったUTF-8のファイル名は文字化けします。これはmountがイカれてるのか、そういう仕様も一部では使われているのかわかりませんが、どうも混沌としているようです。iocharsetというオプションで変わるみたいですが…もしかして、文字コードって指定されていないのかな。VFATの仕様書、どっかにないのかな…
UTF-16とUTF-8を100%正しく区別する方法はなくてどうしようもないので、今回作ったfat_lsでは、指定しない限りポピュラーなUTF-16を優先しています。
さらに、mountはUTF-8での読み書き時に、マルチバイトLFNの場合SFNにASCIIコード範囲外を使うという、実に訳のわからないことをします。これはいいんでしょうか。VFATは無法地帯ですね。

ファイルを削除すると、ディレクトリテーブルのSFNとLFNの1バイト目に0xE5がセットされます。チェックサムは元のままです。新たなファイルを作成すると、一番上にある削除済みエントリを上書きします。
ファイルの名前を変更すると、エントリでは削除した扱いになって、また新しいエントリを作成します。mv、renameともに同じ挙動でした。
データがあるクラスタ番号を書き換えて、2つのファイルで共通にすると、当たり前ですが、片方での変更がもう片方でも反映されます。ファイル長を変えてしまうと変な挙動になりますが。
そのうち、削除済みの0xE5を適当なコードに変えて、さらにチェックサムを書き換えてファイルをサルベージするものを書きたいです。チェックサムから元のSFNの1バイト目を逆算できるかもしれないです。

チェックサムを計算するやつはこれ

それと、タイムスタンプを読むときに苦労したのですが、ビット0って一番右のことなんですね。リトルエンディアンなので左右のバイトを組み替えてから、右から読んでいく。気づきませんでした

バイナリエディタはOktetaというのを使っています。なかなかいいです。一列32バイトに設定すると、ちょうどルートディレクトリ領域が32バイトなのでちょうど一列に収まって見やすいです。

今日はこのへんで。スマホで書いたのでだいぶ微妙な文ですが。

最後に参考文献。ここを参照していろいろしました。

FATファイル システムのしくみと操作法

広告
カテゴリー: コンピュータ パーマリンク

コメントを残す

以下に詳細を記入するか、アイコンをクリックしてログインしてください。

WordPress.com ロゴ

WordPress.com アカウントを使ってコメントしています。 ログアウト / 変更 )

Twitter 画像

Twitter アカウントを使ってコメントしています。 ログアウト / 変更 )

Facebook の写真

Facebook アカウントを使ってコメントしています。 ログアウト / 変更 )

Google+ フォト

Google+ アカウントを使ってコメントしています。 ログアウト / 変更 )

%s と連携中