АвтоАвтоматизацияАрхитектураАстрономияАудитБиологияБухгалтерияВоенное делоГенетикаГеографияГеологияГосударствоДомДругоеЖурналистика и СМИИзобретательствоИностранные языкиИнформатикаИскусствоИсторияКомпьютерыКулинарияКультураЛексикологияЛитератураЛогикаМаркетингМатематикаМашиностроениеМедицинаМенеджментМеталлы и СваркаМеханикаМузыкаНаселениеОбразованиеОхрана безопасности жизниОхрана ТрудаПедагогикаПолитикаПравоПриборостроениеПрограммированиеПроизводствоПромышленностьПсихологияРадиоРегилияСвязьСоциологияСпортСтандартизацияСтроительствоТехнологииТорговляТуризмФизикаФизиологияФилософияФинансыХимияХозяйствоЦеннообразованиеЧерчениеЭкологияЭконометрикаЭкономикаЭлектроникаЮриспунденкция

Листинг 6.3. Восстановленная файловая запись

Читайте также:
  1. Аналитическая запись логической формулы КЦУ
  2. Двоичный (бинарный) ввод/вывод. Объектный ввод/вывод (запись объектов в файл и чтение объектов из файла).
  3. Двойная запись операций на счетах
  4. Двойная запись операций на счетах и ее сущность
  5. Задание 2. Запись макроса
  6. ЗАДАНИЕ 9. Деревья и польская запись
  7. Задача взрослого во всей этой работе - привести подобную запись, упорядочение и извлечение материала из памяти в устойчивый навык работы с информацией.
  8. Запись алгоритма в виде псевдокода
  9. Запись информации в файл
  10. Запись песен на студии.
  11. Запись под заголовком
  12. Запись полей в волноводе для любого типа волн

--> Начало первого сектора файловой записи

00000000: 46 49 4C 45-2A 00 03 00-7C 77 1A 04-02 00 00 00 FILE*...|w......

00000010: 01 00 02 00-30 00 01 00-28 02 00 00-00 04 00 00....0...(.......

00000020: 00 00 00 00-00 00 00 00-06 00 06 00-00 00 47 11..............G.

...

000001F0: 00 00 00 00-00 00 00 00-00 00 00 00-00 00 00 00................

<-- Конец первого сектора файловой записи

000003F0: 07 СС E1 0D-00 09 00 00-FF FF FF FF-82 79 47 11.Іа..... ВyG.

<-- Конец второго сектора файловой записи

Внимание!

FILE Record, INDEX Record, RCRD Record или RSTR Record искажены последовательностями обновления и в обязательном порядке должны быть восстановлены перед их использованием, в противном случае вместо актуальных данных вы получите мусор!

Атрибуты

Структурно всякий атрибут состоит из атрибутного заголовка (attribute header) и тела атрибута (attribute body). Заголовок атрибута всегда хранится в файловой записи, расположенной внутри MFT. Тела резидентных атрибутов хранятся там же. Нерезидентные атрибуты хранят свое тело вне MFT, в одном или нескольких кластерах, перечисленных в заголовке данного атрибута в специальном списке. Если 8-разрядное поле, расположенное по смещению 08h байт от начала атрибутного заголовка, равно нулю, то атрибут считается резидентным, а если единице, то атрибут нерезидентен. Любые другие значения недопустимы.

Первые четыре байта атрибутного заголовка определяют его тип. Тип атрибута, в свою очередь, определяет формат представления тела атрибута. В частности, тело атрибута данных (тип: 80h — $DATA) представляет собой "сырую" последовательность байт. Тело атрибута стандартной информации (тип: 10h — $STANDARD_INFORMATION) описывает время его создания, права доступа и т.д. Более подробно эта тема будет рассмотрена далее в данной главе.

Следующие четыре байта заголовка содержат длину атрибута, выражаемую в байтах. Длина нерезидентного атрибута равна сумме длин его тела и заголовка, а длина резидентного атрибута равна длине его заголовка. Если к смешению атрибута добавить его длину, мы получим указатель на следующий атрибут (или маркер конца, если текущий атрибут — последний в цепочке).

Длина тела резидентных атрибутов, выраженная в байтах, хранится в 32- разрядном поле, расположенном по смещению 10h байт от начала атрибутного заголовка. 16-разрядное поле, следующее за его концом, хранит смещение резидентного тела, отсчитываемое от начала атрибутного заголовка. С нерезидентными атрибутами в этом плане все намного сложнее, и для хранения длины их тела используется множество полей. Реальный размер тела атрибута (real size of attribute), выраженный в байтах, хранится в 64-разрядном поле, находящемся по смещению 30h байт от начала атрибутного заголовка. Следующее за ним 64-разрядное поле хранит инициализированный размер потока (initialized data size of the stream), выраженный в байтах. Судя по всему, инициализированный размер потока всегда равен реальному размеру тела атрибута. 64-разрядное поле, расположенное по смещению 28h байт от начала атрибутного заголовка, хранит выделенный размер (allocated size of attribute), выраженный в байтах и равный реальному размеру тела атрибута, округленному до размера кластера (в большую сторону).

Два 64-разрядных поля, расположенные по смещениям 10h и 18h байт от начала атрибутного заголовка, задают первый (starting VCN) и последний (last VCN) номера виртуального кластера, принадлежащего телу нерезидентного атрибута. Виртуальные кластеры представляют собой логические номера кластеров, не зависящие от своего физического расположения на диске. В подавляющем большинстве случаев номер первого кластера тела нерезидентного атрибута равен нулю, а последний — количеству кластеров, занятых телом атрибута, уменьшенному на единицу. 16-разрядное поле, расположенное по смещению 20h от начала атрибутного заголовка, содержит указатель на массив Data Runs, расположенный внутри этого заголовка и описывающий логический порядок размещения нерезидентного тела атрибута на диске.

Каждый атрибут имеет свой собственный идентификатор (attribute ID), уникальный для данной файловой записи и хранящийся в 16-разрядном поле, расположенном по смещению 0Eh от начала атрибутного заголовка.

Если атрибут имеет имя (attribute Name), то 16-разрядное поле, расположенное по смещению 0Ah байт от атрибутного заголовка, содержит указатель на него. Для безымянных атрибутов оно равно нулю (большинство атрибутов имен не имеют). Имя атрибута хранится в атрибутном заголовке в формате UNICODE, а его длина определяется 8-разрядным полем, расположенным по смещению 09h байт от начала атрибутного заголовка.

Если тело атрибута сжато, зашифровано или разрежено, 16-разрядное поле флагов, расположенное по смещению 0Ch байт от начала атрибутного заголовка, не равно нулю.

Основные поля резидентных и нерезидентных атрибутов кратко описаны в табл. 6.4 и 6.5. Остальные поля не играют существенной роли, и потому здесь они не рассматриваются.

 

Таблица 6.4. Структура резидентного атрибута

Смещение Размер (байт) Значение Описание
00h     Тип атрибута (например, 0x10, 0x60, 0xB0)
04h     Длина атрибута, включая этот заголовок
08h   00h Флаг нерезидентности (non-resident flag)
09h   N Длина имени атрибута (ноль, если атрибут безымянный)
0Ah   18h Смещение имени (ноль, если атрибут безымянный)
0Ch   00h Флаги
Значение Описание
0001h Сжатый атрибут (compressed)
4000h Зашифрованный атрибут (encrypted)
8000h Разреженный атрибут (sparse)
0Eh     Идентификатор атрибута (attribute ID)
10h   L Длина тела атрибута, без заголовка
14h   2N+18h Смещение тела атрибута
16h     Индексный флаг
17h   00h Используется для выравнивания
18h 2N UNICODE Имя атрибута (если есть)
2N+18h L   Тело атрибута

 

Таблица 6.5. Структура нерезидентного атрибута

Смещение Размер (байт) Значение Описание
00h     Тип атрибута (например, 0x20, 0x80)
04h     Длина атрибута, включая этот заголовок
08h   01h Флаг нерезидентности (non-resident flag)
09h   N Длина имени атрибута (ноль, если атрибут безымянный)
0Ah   40h Смещение имени (ноль, если атрибут безымянный)
0Ch     Флаги
Значение Описание
0001h Сжатый атрибут (compressed)
4000h Зашифрованный атрибут (encrypted)
8000h Разреженный атрибут (sparse)
0Eh     Идентификатор атрибута (attribute ID)
10h     Начальный виртуальный кластер (starting VCN)
18h     Конечный виртуальный кластер (last VCN)
20h   2N+40h Смещение списка отрезков (data runs)
22h     Размер блока сжатия (compression unit size), округленный до 4 байт в большую сторону
24h   00h Используется для выравнивания
28h     Выделенный размер (allocated size), округленный до размера кластера
30h     Реальный размер (real size)
38h     Инициализированный размер потока (initialized data size of the stream)
40h 2N UNICODE Имя атрибута (если есть)
2N+40h   Список отрезков (data runs)

Типы атрибутов

NTFS поддерживает большее количество предопределенных типов атрибутов, перечисленных в табл. 6.6. Тип атрибута определяет его назначение и формат представления тела. Полное описание всех атрибутов заняло бы не одну главу, а целую книгу, поэтому здесь приводятся лишь наиболее "ходовые" из них, а за информацией об остальных обращайтесь к документации Linux-NTFS Project.

 

Таблица 6.6. Основные типы атрибутов

Значение ОС Условное обозначение Описание
010h Любая $STANDARD_INFORMATION Стандартная информация о файле (время, права доступа)
020h Любая $ATTRIBUTE_LIST Список атрибутов
030h Любая $FILE_NAME Полное имя файла
040h Windows NT $VOLUME_VERSION Версия тома
040h Windows 2000 $OBJECT_ID Глобально уникальный идентификатор (GUID) и прочие ID
050h Любая $SECURITY_DESCRIPTOR Дескриптор безопасности и списки прав доступа (ACL)
060h Любая $VOLUME_NAME Имя тома
070h Любая $VOLUME_INFORMATION Информация о томе
080h Любая $DATA Основные данные файла
090h Любая $INDEX_ROOT Корень индексов
0A0h Любая $INDEX_ALLOCATION Ветви (sub-nodes) индекса
0B0h Любая $BITMAP Карта свободного пространства
0C0h Windows NT $SYMBOLIC_LINK Символическая ссылка
0C0h Windows 2000 $REPARSE_POINT Для сторонних производителей
0D0h Любая $EA_INFORMATION Расширенные атрибуты для HPFS
0E0h Любая $EA Расширенные атрибуты для HPFS
0F0h Windows NT $PROPERTY_SET Устарело и ныне не используется
100h Windows 2000 $LOGGED_UTILITY_STREAM Используется шифрующей файловой системой (EFS)

$STANDARD_INFORMATION

Атрибут стандартной информации описывает время создания/изменения/последнего доступа к файлу и права доступа, а также некоторую другую вспомогательную информацию (например, квоты). Структура атрибута стандартной информации кратко описана в табл. 6.7.

 

Таблица 6.7. Структура атрибута $STANDARD_INFORMATION

Смещение Размер ОС Описание
- -   Любая Стандартный атрибутный заголовок (standard attribute header)
00h   Любая C — время создания (creation) файла
08h   Любая A — время изменения (altered) файла
10h   Любая M — время изменения файловой записи (MFT changed)
18h   Любая R — время последнего чтения (read) файла
20h   Любая Права доступа MS-DOS (MS-DOS file permissions)
Значение Описание
0001h Только на чтение (read-only)
0002h Скрытый (hidden)
0004h Системный (system)
0020h Архивный (archive)
0040h Устройство (device)
0080h Обычный (normal)
0100h Временный (temporary)
0200h Разреженный (sparse) файл
0400h Точка передачи (reparse point)
0800h Сжатый (compressed)
1000h Оффлайновый (offline)
2000h Неиндексируемый (not content indexed)
4000h Зашифрованный (encrypted)
24h   Любая Старшее двойное слово номера версии (maximum number of versions)
28h   Любая Младшее двойное слово номера версии (version number)
2Ch   Любая Идентификатор класса (class ID)
30h   Windows 2000 Идентификатор владельца (owner ID)
34h   Windows 2000 Идентификатор безопасности (security ID)
38h   Windows 2000 Количество квотируемых байт (quota charged)
40h   Windows 2000 Номер последней последовательности обновления (update sequence number USN)

$ATTRIBUTE_LIST

Атрибут списка атрибутов (прямо каламбур) используется в тех случаях, когда все атрибуты файла не умещаются в базовой файловой записи, и файловая система вынуждена располагать их в расширенных файловых записях. Индексы расширенных файловых записей содержатся в атрибуте списка атрибутов, помещаемом в базовую файловую запись.

При каких обстоятельствах атрибуты не умещаются в одной файловой записи? Это может произойти в следующих случаях:

□ файл содержит много альтернативных имен или жестких ссылок;

□ файл сильно фрагментирован;

□ файл содержит очень сложный дескриптор безопасности;

□ файл имеет очень много потоков данных (т.е. атрибутов типа $DATA).

Структура атрибута списка атрибутов приведена в табл. 6.8.

 

Таблица 6.8. Структура атрибута $ATTRIBUTE_LIST

Смещение Размер Описание
- -   Стандартный атрибутный заголовок (standard attribute header)
00h   Тип (type) атрибута (см. табл. 6.6)
04h   Длина записи (record length)
06h   Длина имени (name length), или ноль, если нет, условно — N
07h   Смещение имени (offset to name), или ноль если нет
08h   Начальный виртуальный кластер (starting VCN)
10h   Ссылка на базовую/расширенную файловую запись
18h   Идентификатор атрибута (attribute ID)
1Ah 2N Если N>0, то имя в формате UNICODE

$FILE_NAME

Атрибут полного имени файла хранит имя файла в соответствующем пространстве имен. Таких атрибутов у файла может быть и несколько (например, имя Win32 и имя MS-DOS). Здесь же хранятся и жесткие ссылки (hard link), если они есть.

Структура атрибута полного имени приведена в табл. 6.9.

 

Таблица 6.9. Структура атрибута $FILE_NAME

Смещение Размер Описание
- -   Стандартный атрибутный заголовок (standard attribute header)
00h   Ссылка (file reference) на материнский каталог
08h   C — время создания (creation) файла
10h   A — время последнего изменения (altered) файла
18h   M — время последнего изменения файловой записи (MFT changed)
20h   R — время последнего чтения (read) файла
28h   Выделенный размер (allocated size) файла
30h   Реальный размер (real size) файла
38h   Флаг (см. табл. 6.7)
3Ch   Используется HPFS
40h   Длина имени в символах — L
41h   Пространство имен файла (filename namespace)
42h 2L Имя файла в формате UNICODE без завершающего нуля

Списки отрезков

Тела нерезидентных атрибутов хранятся на диске в одной или нескольких кластерных цепочках, называемых отрезками (runs). Отрезком называется последовательность смежных кластеров, характеризующаяся номером начального кластера и длиной. Совокупность отрезков называется списком (run-list или data run).

Внутренний формат представления списков не то, чтобы сложен, но простым его тоже на назовешь. Для экономии места длина отрезка и номер начального кластера хранятся в полях переменной длины. Если размер отрезка умещается в байт (т.е. его значение не превышает 255), то он займет один байт. По аналогии, если размер отрезка требует для своего представления двойного слова, то он займет двойное слово.

Сами же поля размеров хранятся в 4-битных ячейках, называемых нибблами (nibble) или полубайтами. Шестнадцатеричная система счисления позволяет легко переводить байты в нибблы и наоборот. Младший ниббл равен (X & 15), а старший — (X / 16). Иначе говоря, младший ниббл соответствует младшему шестнадцатеричному разряду байта, а старший — старшему. Например, 69h состоит из двух нибблов, причем младший равен 9h, а старший — 6h.

Список отрезков представляет собой массив структур, каждая из которых описывает характеристики "своего" отрезка. Структура элемента списка отрезков показана в табл. 6.10. В конце списка находится завершающий ноль. Первый байт структуры состоит из двух нибблов: младший задает длину поля начального кластера отрезка (условно обозначаемого буквой F), а старший — количество кластеров в отрезке (L). Затем идет поле длины отрезка. В зависимости от значения L оно может занимать от одного до восьми байт (поля большей длины недопустимы). Первый байт поля стартового кластера файла расположен по смещению 1+L байт от начала структуры (что соответствует 2+2*L нибблам). Кстати говоря, в документации Linux-NTFS Project (версия 0.4) поля размеров начального кластера и количества кластеров в отрезке перепутаны местами.

 

Таблица 6.10. Структура одного элемента списка отрезков

Смещение в нибблах Размер в нибблах Описание
    Размер поля длины (L)
    Размер поля начального кластера (S)
  2*L Количество кластеров в отрезке
2+2*L 2*S Номер начального кластера отрезка

Покажем, как с этим работать на практике. Предположим, что мы имеем следующий список отрезков, соответствующий нормальному не фрагментированному файлу (что может быть проще!): 21 18 34 56 00. Попробуем его декодировать?

Начнем с первого байта — 21h. Младший полубайт (01h) описывает размер поля длины отрезка, старший (02h) — размер поля начального кластера. Следующие несколько байт представляют поле длины отрезка, размер которого в данном случае равен одному байту — 18h. Два других байта (34h 56h) задают номер начального кластера отрезка. Нулевой байт на конце сигнализирует о том, что это последний отрезок в файле. Таким образом, наш файл состоит из одного-единственного отрезка, начинающегося с кластера 5634h и заканчивающегося кластером 5634h + 18h == 564Ch.

Рассмотрим более сложный пример фрагментированного файла со следующим списком отрезков: 31 38 73 25 34 32 14 01 E5 11 02 31 42 AA 00 03 00. Извлекаем первый байт — 31h. Один байт приходится на поле длины, и три байта — на поле начального кластера. Таким образом, первый отрезок (run 1) начинается с кластера 342573h и продолжается вплоть до кластера 342573h + 38 == 3425ABh. Чтобы найти смещение следующего отрезка в списке, мы складываем размер обоих полей с их начальным смещением: 3 + 1 == 4. Отсчитываем четыре байта от начала списка отрезков и переходим к декодированию следующего отрезка: 32h — два байта на поле длины отрезка (равное в данном случае 0114h) и три байта — на поле номера начального кластера (0211E5h). Следовательно, второй отрезок (run 2) начинается с кластера 0211E5h и продолжается вплоть до кластера 0211E5h + 114h == 212F9h. Третий отрезок (run 3): 31h — один байт на поле длины и три байта — на поле начального кластера, равные 42h и 0300AAh соответственно. Поэтому третий отрезок (run 3) начинается с кластера 0300AAh и продолжается вплоть до кластера 0300AAh + 42h == 300ECh. Завершающий ноль на конце списка отрезков сигнализирует о том, что это последний отрезок в файле.

Таким образом, подопытный файл состоит из трех отрезков, разбросанных по диску в следующем живописном порядке: 342573h–3425ABh; 0211E5h–212F9h; 0300AAh–300ECh. Остается только прочитать его с диска! Нет ничего проще!

Начиная с версии 3.0, NTFS поддерживает разреженные (sparse) атрибуты, т.е. такие атрибуты, которые не записывают на диск кластеры, содержащие одни нули. При этом поле номера начального кластера отрезка может быть равным нулю, что означает, что данному отрезку не выделен никакой кластер. Поле длины содержит количество кластеров, заполненных нулями. Их не нужно считывать с диска. Вы должны самостоятельно изготовить их в памяти. Между прочим, далеко не все дисковые доктора знают о существовании разреженных атрибутов (если атрибут разрежен, его флаг равен 8000h), и интерпретируют нулевую длину поля номера начального кластера весьма странным образом. Последствия такого "лечения" обычно оказываются весьма печальными.

Пространства имен

NTFS изначально проектировалась как файловая система, не зависящая от платформы, способная работать с большим количеством различных подсистем, в том числе: Win32, MS-DOS, POSIX. Так как каждая из перечисленных подсистем налагает собственные ограничения на набор символов, допустимых для использования в имени файла, NTFS вынуждена поддерживать несколько независимых пространств имен (name spaces).

POSIX

Допустимы все символы UNICODE (с учетом регистра), за исключением символа нуля (NULL), обратной косой черты (\) и знака двоеточия (:). Последнее из перечисленных ограничений, кстати говоря, не есть ограничение POSIX. Напротив, это — внутреннее ограничение файловой системы NTFS, использующей этот символ для доступа к именованным атрибутам. Максимально допустимая длина имени составляет 255 символов.

Win32

Доступны все символы UNICODE (без учета регистра), за исключением следующего набора: кавычки ("), звездочка (*), косая черта (/), двоеточие (:), знак "меньше" (<), знак "больше" (>), вопросительный знак (?), обратная косая черта (\), а также символ конвейера (|). Кроме того, имя файла не может заканчиваться точкой или пробелом. Максимально допустимая длина имени составляет 255 символов.

MS-DOS

Доступны все символы пространства имен Win32 (без учета регистра), за исключением следующих: знак плюса (+), запятая (,), точка (.), точка с запятой (;), знак равенства (=). Длина имени файла не должна превышать восьми символов, за которыми следует необязательное расширение имени файла, имеющее длину от одного до трех символов.

Назначение служебных файлов

NTFS содержит большое количество служебных файлов (метафайлов) строго определенного формата. Важнейший из метафайлов, $MFT, мы только что рассмотрели. Остальные метафайлы играют вспомогательную роль. Для восстановления данных детально знать их структуру необязательно. Тем не менее, если они окажутся искажены, то штатный драйвер файловой системы не сможет работать с таким томом, поэтому иметь некоторые представления о назначении каждого из них все же необходимо.

Краткие сведения о назначении важнейших метафайлов приведены в табл. 6.11. К сожалению, в пределах одной главы нет возможности подробно рассмотреть структуру всех существующих метафайлов, поэтому заинтересованным читателям рекомендуется искать эту информацию в документации к Linux-NTFS Project.

 

Таблица 6.11. Назначение основных метафайлов NTFS

Inode Имя файла ОС Описание
  $MFT Любая Главная файловая таблица (Master File Table, MFT)
  $MFTMirr Любая Резервная копия первых четырех элементов MFT
  $LogFile Любая Журнал транзакций (transactional logging file)
  $Volume Любая Серийный номер, время создания, флаг не сброшенного кэша (dirty flag) тома
  $AttrDef Любая Определение атрибутов
  . (точка) Любая Корневой каталог (root directory) тома
  $Bitmap Любая Карта свободного/занятого пространства
  $Boot Любая Загрузочная запись (boot record) тома
  $BadClus Любая Список плохих кластеров (bad clusters) тома
  $Quota Windows NT Информация о квотах (quota information)
  $Secure Windows 2000 Использованные дескрипторы безопасности (security descriptors)
  $UpCase Любая Таблица заглавных символов (uppercase characters) для трансляции имен
  $Extend Windows 2000 Каталоги: $ObjId, $Quota, $Reparse, $UsnJrnl
12-15 не используется Любая Помечены как использованные, но в действительности пустые
16-23 не используется Любая Помечены как неиспользуемые
Любой $ObjId Windows 2000 Уникальные идентификаторы каждого файла
Любой $Quota Windows 2000 Информация о квотах (quota information)
Любой $Reparse Windows 2000 Информация о точке передачи (reparse point)
Любой $UsnJrnl Windows 2000 Журнал шифрованной файловой системы (journaling of encryption)
>24 Пользовательский файл Любая Обычные файлы
>24 Пользовательский каталог Любая Обычные каталоги

 

Практический пример

Рассказ о файловой системе NTFS был бы неполным без практической иллюстрации техники разбора файловой записи вручную. До сих пор мы витали в облаках теоретической абстракции. Пора спускаться на грешную землю.

Воспользовавшись любым дисковым редактором, например, Disk Probe, попробуем декодировать одну файловую запись вручную. Найдем сектор, содержащий сигнатуру FILE в его начале (не обязательно брать первый встретившийся сектор). Он может выглядеть, например, как в листинге 6.4.


1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 |

Поиск по сайту:



Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Студалл.Орг (0.012 сек.)