Журнал Системный Администратор, Декабрь 2004

Журнал Системный Администратор

Декабрь 2004

Цена: $4.5 US

  Подписаться

Зарегистриванные пользователи, пожалуйста следуйте этой ссылке

Версия для печати Вернуться к оглавлению

Файловая система NTFS извне и изнутри Часть 2

Часть 2

Крис Касперски

В продолжение знакомства с файловой системой NTFS сегодня мы сосредоточимся на строении атрибутов, исследовав их заголовок и механизмы хранения нерезидентного тела на диске, а также покажем, как рассмотренные нами структуры данных выглядят вживую в дисковом редакторе типа Disk Probe или Sector Inspector.

Атрибуты

Структурно всякий атрибут состоит из заголовка (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 байт от начала атрибутного заголовка, не равно нулю.

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

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

 

Смещение

Размер

Значение

Описание

00h

4

 

Тип (type) атрибута (например, 0x10, 0x60, 0xB0)

04h

4

 

Длина атрибута, включая этот заголовок

08h

1

00h

Нерезидентный флаг (non-resident flag)

09h

1

N

Длина имени атрибута (ноль, если атрибут безымянный)

0Ah

2

18h

Смещение имени (ноль, если атрибут безымянный)

0Ch

2

00h

Флаги

Значение

Описание

0001h

Сжатый атрибут (compressed)

4000h

Зашифрованный атрибут (encrypted)

8000h

Разряженный атрибут (sparse)

0Eh

2

 

Идентификатор атрибута (attribute ID)

10h

4

L

Длина тела атрибута, без заголовка

14h

2

2N+18h

Смещение тела атрибута

16h

1

 

Индексный флаг

17h

1

00h

Для выравнивания

18h

2N

UNICODE

Имя атрибута (если есть)

2N+18h

L

 

Тело атрибута

 

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

 

Смещение

Размер

Значение

Описание

00h

4

 

Тип (type) атрибута (например, 0x20, 0x80)

04h

4

 

Длина атрибута, включая этот заголовок

08h

1

01h

Нерезидентный флаг (non-resident flag)

09h

1

N

Длина имени атрибута (ноль, если атрибут безымянный)

0Ah

2

40h

Смещение имени (ноль, если атрибут безымянный)

0Ch

2

 

Флаги

Значение

Описание

0001h

Сжатый атрибут (compressed)

4000h

Зашифрованный атрибут (encrypted)

8000h

Разряженный атрибут (sparse)

0Eh

2

 

Идентификатор атрибута (attribute ID)

10h

8

 

Начальный виртуальный кластер (starting VCN)

18h

8

 

Конечный виртуальный кластер (last VCN)

20h

2

2N+40h

Смещение списка отрезков (data runs)

22h

2

 

Размер блока сжатия (compression unit size), округленный до 4 байт вверх

24h

4

00h

Для выравнивания

28h

8

 

Выделенный размер (allocated size), округленный до размера кластера

30h

8

 

Реальный размер (real size)

38h

8

 

Инициализированный размер потока (initialized data size of the stream)

40h

2N

UNICODE

имя атрибута если есть

2N+40h

..

 

Список отрезков (data runs)

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

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

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

 

Значение

ОС

Условное обозначение

Описание

010h

любая

$STANDARD_INFORMATION

Стандартная информация о файле (время, права доступа)

020h

любая

$ATTRIBUTE_LIST

Список атрибутов

030h

любая

$FILE_NAME

Полное имя файла

040h

NT

$VOLUME_VERSION

Версия тома

040h

2K

$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

NT

$SYMBOLIC_LINK

Символическая связь

0C0h

2K

$REPARSE_POINT

Для сторонних производителей

0D0h

любая

$EA_INFORMATION

Расширенные атрибуты для HPFS

0E0 h

любая

$EA

Расширенные атрибуты

для HPFS

0F0h

NT

$PROPERTY_SET

Устарело и ныне не используется

100h

2K

$LOGGED_UTILITY_STREAM

Используется шифрованной файловой системой (EFS)

Атрибут стандартной информации $STANDARD_INFORMATION

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

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

 

Смещение

Размер

ОС

Описание

~ ~

 

любая

Стандартный атрибутный заголовок (standard attribute header)