Содержание
- 1 Используемое программное обеспечение.
- 2 Что из себя представляет загрузчик?
- 3 1. Количество байт в секторе
- 4 2. Количество секторов в кластере
- 5 3. Число зарезервированных секторов
- 6 4. Количество копий FAT.
- 7 5. Максимальное число 32-байтных элементов корневого каталога
- 8 6. Общее число секторов на томе.
- 9 7. Дескриптор носителя
- 10 8. Общее число секторов.
- 11 Конец загрузчика.
Начинаю готовить новый цикл статей, посвященных исследованию файловых систем.
И начну я с наиболее простой (для разогрева) файловой системы FAT12/16.
Вначале немного истории. Файловая система FAT (расшифровывается никак не иначе, как File Allocation Table) разработана Биллом Гейтсом (основатель Microsoft corp.) и Марком МакДональдом в 1977 году и изначально использовалась в ОС 86-DOS. Для сохранения переносимости программ из операционной системы CP/M в 86-DOS, в ней сохранились ранее принятые ограничения на длину имени файла и используемые символы. Позднее, ОС 86-DOS была куплена Microsoft и стала прообразом для ОС MS-DOS 1.0, увидевшей свет в августе 1981 года.
Файловая система FAT была предназначена для работы с гибкими дисками размером менее 1 Mb, в начале даже не поддерживала жесткие диски. В настоящее время файловая система FAT поддерживает разделы и файлы размером до 2 Gb.
Используемое программное обеспечение.
Для просмотра 16-ричного дампа диска и анализа всех параметров здесь и далее буду использовать утилиту WinHEX, мощный редактор. Обо всех функциях буду рассказывать по мере повествования. Так как этот софт я сам пока ещё не знаю, но планирую узнать. Итак, главное окно программы:
Открываем наш диск. Tools -> Open Disk. Для этого я отформатировал флешку в FAT (причём, не быстрое, а полное).
Структуру файловой системы FAT можно условно представить в виде таблицы.
Системная область
|
Загрузочный сектор (Boot)
|
Таблица размещения файлов (FAT)
|
|
Дублирующая таблица размещения файлов (FAT copy)
|
|
Корневой каталог (Root)
|
|
Область данных
|
Кластер 2
|
Кластер 3
|
|
…
|
|
Кластер N
|
Структура файловой системы FAT:
Нулевой сектор, называемый также загрузочным (Boot), содержит таблицу с параметрами диска и начальный загрузчик ОС. Первые 3 байта сектора содержат команду перехода JMP на начало загрузчика: либо байт 0E9h и 1 байт короткого смещения, после которых следует команда NOP (код 90h), либо байт 0EBh и два байта длинного смещения, которое используется, если загрузчик расположен в зарезервированной области.
Что из себя представляет загрузчик?
Загрузчик – короткая программа, загружающая ОС или только её ядро; так же он может являться менеджером загрузки (средством для выбора загружаемых операционных систем).
Далее расположено поле из 8 байт, содержащее текстовый идентификатор версии ОС.
Далее располагается таблица параметров диска, позволяющая вычислить правильный физический адрес на диске по данному номеру логического сектора.
Важно: байты читаются в обратном порядке!
Это мы уже увидели. Теперь немного расскажу, как нужно ориентироваться в WinHEX и вообще в 16-ричном дампе.
Смешение – это сдвиг от начала исследуемой области. После каждого 16-ричного числа ставится символ h (hex) что означает, что число 16-ричное. Вот краткий хелп, как ориентироваться в дампе:
Байт – это пара смежных символов 16-ричного алфавита. Слово – 2 байта, иначе говоря WORD. Двойное слово – 4 байта (DWORD). Поиск байта по смещению – это сложение смещения по строке и по столбцу. Например, ищем байт по смещению A5h. Для этого ищем по вертикали 000000A0, а по горизонтали откладываем 5. На пересечении будет находиться байт 46h [1]. Точно так же для примера я нашёл байт по смещению 2Dh [2]. Нужно привыкать к такому поиску, потому что будем часто перемещаться на произвольное смещение.
Смещение | Длина | Назначение |
0Bh | 2 | BytesPerSector – количество байт в секторе, обычно равно 512 (200h) |
0Dh | 1 | SectorPerCluster – количество секторов в кластере |
0Eh | 2 | ReservedSectors – количество зарезервированных секторов |
10h | 1 | NumberOfFATs – количество FAT таблиц |
11h | 2 | RootEntries – максимальное число 32-байтных элементов корневого каталога |
13h | 2 | TotalSectors – общее число секторов на томе. 0000h означает, что диск большого объема (> 32 Mb, поэтому число задается DWORD по смещению 20h, параметр BigTotSects |
15h | 1 | MediaDescriptor – дескриптор носителя (то же,что и в первом байте FAT таблицы) |
16h | 2 | SectorPerFat – число секторов в одной таблице FAT |
18h | 2 | SectorPerTrack – число секторов на треке |
1Ah | 2 | Heads – число головок |
1Ch | 4 | HiddenSectors – число скрытых секторов |
20h | 4 | BigTotalSectors – число секторов (для раздела >32 Mb) |
24h | 1 | PhysicalDiskNumber – физический номер устройства, номер присваивается в процессе форматирования (80h – первый десткий диск в системе) |
25h | 1 | CurrentHead – зарезервировано |
26h | 1 | Signature – сигнатура расширенного загрузчика (29h) |
27h | 4 | VolumeSerialNumber – серийный номер тома (устанавливается при форматировании) |
2Bh | 11 | VolumeLabel – метка тома (строка символов) |
36h | 8 | SystemID – символьный код идентификатора файловой системы, например FAT16. |
3Eh | 448 | Область кода загрузчика |
1FEh | 2 | BootSignature – сигнатура 55AAh – конец загрузочного сектора |
1. Количество байт в секторе
Итак, смещение 0Bh, длина – два байта.Мы видим там значения 00h 02h. Напоминаю, что у нас тут обратный порядок байт, то есть читаем с конца. 02h 00h = 0200h. Переводя в десятичное – 512. Кстати, в опциях рекомендую включить View -> Show -> Data Interperter. А в опциях Options -> Data Interpreter включить 8 bit (unsigned), 16 bit (unsigned), 32 bit (unsigned), Assembler opcodes, Digit Grouping. Тогда в плавающем окошке будет отображаться как у меня. Ставим курсор на первое число, и, поскольку у нас 2 байта – смотрим значение в поле 16 bit (для длины 1 байт смотрим 8 bit, для длины 4, dword, смотрим 32 бит, очень удобно.
Итак, переводим 0200h в десятичное число. 0200h = 512.
И действительно, на флешке у нас размер сектора 512 байт.
2. Количество секторов в кластере
Находим смещение 0Dh, так как длина поля 1 байт, смотрим значение 8 bit в Data Interpreter. Оно равно 64. Верно, 0Dh = 64 (dec).
Отсюда можно легко вычислить количество байт в кластере. Первое число умножаем на второе.
Количество байт в кластере = 512 * 64 = 32 768.
3. Число зарезервированных секторов
Согласно таблице, открываем смещение 0Eh и читаем 2 байта.
Значение равно 0002h, что в переводе на десятичные равно так же 2. Значит два сектора зарезервированы под загрузчик. Размер сектора – 512 байт, следовательно зарезервировано 2 * 512 = 1024 байта.
4. Количество копий FAT.
Я пометил это на предыдущем скриншоте, легко увидеть, что судя по значению байта по смещению 10h, используется 2 копии FAT.
5. Максимальное число 32-байтных элементов корневого каталога
Считываем два байта по смещению 11h и видим, сколько может уместиться 32-байтных элементов в корневом каталоге. И количество их равно 512. Что это значит – разберём немного позже.
6. Общее число секторов на томе.
Следующие два байта по смещению 13h – общее количество секторов. Для дисков, объем которых превышает 32 Mb, эти два байта заполнены нулями, и реальное количество секторов указывается по смещению 20h в четырёх байтах. Об этом скажу чуть ниже.
7. Дескриптор носителя
Этот дескриптор содержится в первом байте FAT-таблицы. В байте по смещению 15h мы видим значение F8. Забегая вперёд я хочу привести скрин FAT-таблицы, чтобы не быть голословным.
Некоторые параметры я пропущу, ввиду их очевидности. Итак, идём дальше.
8. Общее число секторов.
Для разделов > 32 Mb у нас находится по смещению 20h и занимает 4 байта.
Там мы видим последовательность байт: 80 B0 3B 00. Читаем их в обратном порядке 00 3B B0 80, переводим это число в десятичный вид: 3911808. Это число показывает, сколько секторов у нас на разделе. Умножаем на размер сектора в байт (см. пункт 1) и получаем 3911808 * 512 = 2 002 845 696 байт. В общем флешка на 2 Gb.
В калькуляторе преобразовывать числа из систем счисления не сложно. Запускаем калькулятор, Вид->Инженерный. Переключаем режим на Hex (16-ричные числа), вводим наше число 3BB080.
Затем переключаем режим на Dec (десятичные) и видим уже преобразованное число в десятичные.
Конец загрузчика.
Сигнатура конца бутового раздела – последовательность байт 55AAh – увидите её внизу. Показывает, что загрузочный сектор закончился. Эта сигнатура присутствует во всех файловых системах, поэтому можно легко идентифицировать конец загрузочного сектора.
Большое спасибо за цикл статей о файловых системах. Прицепил microSD к микроконтроллеру и с вашей помощью разобрался в структуре файлов на флешке.
Приятно слышать, что это вам показалось интересным. А могли бы написать более расширенно, что именно делали? Интересно посмотреть, думаю, не мне одному.
Отличный материал спасибо!!! стало намного понятней