Читаємо FAT32
Не так давно, я вирішив зрозуміти суть файлової системи FAT. Для цього я поставив перед собою завдання відшукати і прочитати файл на флешці, використовуючи тільки HxD і без Ctrl+F, звичайно.
У цьому пості буде поверхово розглянуто лише специфікацію FAT32. Цікаво? Заходьте. І так, не забувайте про зворотний порядок байтів та інші дрібниці, які роблять наше життя цікавим.

Перші 11 байтів відносяться до завантажувального сектора, три байти вказують на початок завантажувального сектора операційної системи (якщо вона там є, звичайно ж), інші вісім - назва ОС або виробника, в даному випадку це MSDOS5.0. Сенс інших байтів я наводжу нижче:
Байти - Призначення 2 - Кількість байтів у секторі, допустимі значення - 512, 1024, 2048 або 4096. 1 - Секторів на кластер, тут їх 8. Можливо 1,2,4,8,16,32 ,64 або 128. 2 — Кількість зарезервованих секторів. Зазвичай 32, але тут все інакше. Це не страшно. 1 — Кількість FAT таблиць, зазвичай двійка, інакше багато програм збожеволіють. Але з метою економії іноді залишають лише одну таблицю, коли не потрібна надмірність ФС (дані не дублюються). 4 — Використовуються у FAT12/16, а для FAT32 тут будуть нулі. 1 - Стандартне значення для жорстких дисків - 0xF8, для змінних - 0xF0. Також можуть бути значення 0xF9, 0xFA… 0xFF, головне, щоб у першому байті FAT таблиці стояло таке ж значення, інакше це привід для занепокоєння. Але це лише старе правило з часів MSDOS, яке використовувалося визначення типу диска. 2 - У FAT32 не використовується, 0x00. 2 — Кількість секторів на доріжці. 2 - Кількість головок. 4 - Кількість прихованих секторів, якщо диск розбитий на розділи, то нулі тут бути не повинно. 4 — Загальна кількість секторів на диску. 4 — Кількість секторів однієї FATтаблиці. 2 — Поле прапорів тут не розглядається. 2 — Номер версії FAT32, в даному випадку 00. 4 — Номер першого кластера кореневої директорії, найчастіше двійка, але якщо другий кластер пошкоджений, дискова утиліта може змінити номер. 2 — Номер сектора з дивною структурою FSINFO, яку зараз не зачіпатимемо. 2 - Номер сектора в резервній області диска, або 6, або 0, інші значення ведуть до занепокоєння та зайвих праць. 12 — Найдовше і непотрібне поле Зарезервовано, за замовчуванням нулі. 1 – 0x00 для гнучких та 0x80 для жорстких дисків. Використовується для BIOS функції int 13h. 1 — 0x00 1 — 0x29, індикатор того, що три поля існують. 4 - Серійний номер тома. 11 - Ім'я диска, що збігається з ім'ям кореневої директорії (але іноді дискова утиліта працює недоброякісно, і вони не збігаються), в даному випадку "NO NAME". 8 — Завжди має бути FAT32, але не використовуйте це поле для визначення типу ФС, це просто страхування. Розглядати способи визначення ФС не будемо.
510 і 511 байт містять значення 0x55 і 0xAA, в даному випадку вони знаходяться в кінці нульового сектора, але не факт, що так завжди і скрізь. Якщо кількість байтів на сектор більше 512, то й межа сектора буде далі цих циферок.
File&Data region
Так, ось ми і пройшлися заголовком і запам'ятали основні дані, що стосуються нашого диска. Тепер розглянемо саму структуру жирної файлової системи та спробуємо знайти регіон з потрібними даними. Директорія в FAT є файлом з прапором «директорія» і практично нічим не відрізняється від звичайного файлу.
ФС розподіляє дані за номерами кластерів, номер першого кластера в даному випадку - 2. Для того, щоб знайти номер початкового сектора другогокластера, слід зробити такі обчислення:
FirstDataSector = ResSec + (NumFATs * FATSz), де ResSec = у зарезервованих секторів, NumFATs - у FAT таблиць, FATSz - розмір FAT таблиці.
У цьому випадку це сектор 7672. Давайте перейдемо на нього.
Ми дісталися дивного файлу HABR. Перші 11 байтів – і є ім'я файлу. Далі йде байтик з атрибутами файлу, який тут дорівнює 0x08. Що це означає? Подивимося у специфікацію FAT:
ATTR_READ_ONLY 0x01 ATTR_HIDDEN 0x02 ATTR_SYSTEM 0x04 ATTR_VOLUME_ID 0x08 ATTR_DIRECTORY 0x10 ATTR_ARCHIVE 0x20 ATTR_LONG_NAME TR_VOLUME_ID
ATTR_VOLUME_ID? Уря, таки дісталися кореневої директорії. Якби то була просто папка, то стояв би атрибут ATTR_DIRECTORY. Наступний байт ми пропускаємо, він має сенс лише WinNT. Далі йдуть час створення, дата створення, старше слово номер кластера (яке тут все одно буде банкрутом), час останнього звернення та розмір файлу в байтах. Йдемо далі. Нас цікавить зараз той самий файл, який знаходиться у кореневій директорії. Як бачимо, цей файл називається GNU_GPL і він є архівом (WHAT?). Пропустимо 14 байтів і побачимо 2-байтне поле, що містить молодше слово номера першого кластера (03), а також 4-байтний розмір файлу в байтах (74 AF). Більше файлів тут немає, але ми прагнемо прочитати цей самий GNU_GPL! Маючи номер кластера N, ми легко можемо знайти сектор, який містить цей кластер:
Sector = ReservedSec + (N * 4 / BytePerSec), де ReservedSec - у зарезервованих секторів, а BytePerSec - у байтів на сектор.
У нас вийшло так, що кластер із даними йде відразу після кластера з кореневою директорією. Вау, тепер ми можемо почитати ліцензію:

Насправді файлові системи не така вже й проста тема. Якщо ви раптом хочете почитати про FAT якомога більше або написати свій драйвер FAT, рекомендую звернутися до офіційного буку від Microsoft: тик