Читаем FAT32

в 9:42, , рубрики: diy или сделай сам, FAT, метки:

kon'nichiwa!

Не так уж и давно, я решил понять суть файловой системы FAT. Для этого я поставил перед собой задачу — отыскать и прочитать файл на флешке, используя только HxD и без Ctrl+F, конечно же.

В этом посте будет поверхностно рассмотрена только спецификация FAT32. Интересно? Заходите. И да, не забывайте про обратный порядок байтов и прочие мелочи, которые делают нашу жизнь увлекательной.

Открываем свою флешку или жесткий диск в своем любимом HEX редакторе и видим что-то знакомое и незнакомое одновременно. Файловая система FAT32 состоит из 3 «уровней» — BPB, FAT Region и F&D Region. FAT регион рассматривать тут не будем. В нулевом секторе диска с файловой системой FAT находится так называемый BIOS Parameter Block (BPB), в котором содержится основная информация о мироздании диске и ФС.

BPB

Sector 0

Читаем 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. Давайте перейдем на него.

Sector 7672

Читаем FAT32

Мы добрались до странного файла 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 ATTR_READ_ONLY | ATTR_HIDDEN | ATTR_SYSTEM | ATTR_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 — кол-во байтов на сектор.

У нас вышло так, что кластер с данными идет сразу после кластера с корневой директорией. Вау, теперь мы можем почитать лицензию:

Sector 7680

Читаем FAT32
!

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

Автор: holmuk

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js