Студопедия

Главная страница Случайная страница

Разделы сайта

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






Путешествие по NTFS






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

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

: 00 01 02 03 04 05 06 07 | 08 09 0A 0B 0C 0D 0E 0F
00000000: 46 49 4C 45 2A 00 03 00 | 60 79 1A 04 02 00 00 00 FILE* | `y> |O
00000010: 01 00 01 00 30 00 01 00 | 50 01 00 00 00 04 00 00................
00000020: 00 00 00 00 00 00 00 00 | 04 00 03 00 00 00 00 00................

00000030: 10 00 00 00 60 00 00 00 | 00 00 00 00 00 00 00 00................
00000040: 48 00 00 00 18 00 00 00 | B0 D5 C9 2F C6 0B C4 01................
00000050: E0 5A B3 7B A9 FA C3 01 | 90 90 F1 2F C6 0B C4 01................
00000060: 50 7F BC FE C8 0B C4 01 | 20 00 00 00 00 00 00 00................
00000070: 00 00 00 00 00 00 00 00 | 00 00 00 00 05 01 00 00................
00000080: 00 00 00 00 00 00 00 00 | 00 00 00 00 00 00 00 00................
00000090: 30 00 00 00 70 00 00 00 | 00 00 00 00 00 00 02 00................
000000A0: 54 00 00 00 18 00 01 00 | DB 1A 01 00 00 00 01 00................
000000B0: B0 D5 C9 2F C6 0B C4 01 | B0 D5 C9 2F C6 0B C4 01................
000000C0: B0 D5 C9 2F C6 0B C4 01 | B0 D5 C9 2F C6 0B C4 01................
000000D0: 00 00 00 00 00 00 00 00 | 00 00 00 00 00 00 00 00................
000000E0: 20 00 00 00 00 00 00 00 | 09 03 49 00 6C 00 66 00................
000000F0: 61 00 6B 00 2E 00 64 00 | 62 00 78 00 00 00 00 00................
00000100: 80 00 00 00 48 00 00 00 | 01 00 00 00 00 00 03 00................
00000110: 00 00 00 00 00 00 00 00 | ED 04 00 00 00 00 00 00................
00000120: 40 00 00 00 00 00 00 00 | 00 E0 4E 00 00 00 00 00................
00000130: F0 D1 4E 00 00 00 00 00 | F0 D1 4E 00 00 00 00 00................
00000140: 32 EE 04 D9 91 00 00 81 | FF FF FF FF 82 79 47 11................
000001F0: 00 00 00 00 00 00 00 00 | 00 00 00 00 00 00 03 00................
: 00 01 02 03 04 05 06 07 | 08 09 0A 0B 0C 0D 0F 0F................

Листинг 4. Ручное декодирование файловой записи (разные атрибуты выделены разным цветом).

Первым делом необходимо восстановить оригинальное содержимое последовательности обновления. По смещению 04h от начала сектора лежит 16-разрядный указатель на нее, равный в данном случае 2Ah (значит, это NTFS 3.0 или младше). А что у нас лежит по смещению 2Ah? Ага, пара байт 03 00. Это - номер последовательности обновления. Сверяем его с содержимым двух последних байт этого и следующего секторов (смещения 1FEh и 3FEh соответственно). Они равны! Значит, данная файловая запись цела (по крайней мере, внешне) и можно переходить к операции спасения. По смещению 2Ch расположен массив, содержащий оригинальные значения последовательности обновления. Количество элементов в нем равно содержимому 16-разрядного поля, расположенному по смещению 06h от начала сектора и уменьшенного на единицу (т.е. в данном случае 03h - 01h = 02h). Извлекаем два слова, начиная со смещения 2Ch (в данном случае они равны 00 00 и 00 00), и записываем их в конец первого и последнего секторов.

Теперь нам необходимо выяснить - используется ли данная файловая запись или ассоциированный с ней файл/каталог был удален. 16-разрядное поле, расположенное по смещению 16h, содержит значение 01h. Следовательно, перед нами файл, а не каталог и этот файл еще не удален. Но является ли данная файловая запись базовой для данного файла или мы имеет дело с ее продолжением? 64-разрядное поле, расположенное по смещению 20h, равно нулю, следовательно данная файловая запись - базовая.

Ок, переходим к исследованию атрибутов. 16-разрядное поле, находящееся по смещению 14h равно 30h, следовательно заголовок первого атрибута начинается со смещения 30h от начала сектора.

Первое двойное слово атрибута равно 10h, значит перед нами атрибут типа $STANDARD_INFORMATION. 32-разрядное поле длины атрибута, находящееся по смещению 04h и равное в данном случае 60h байт, позволяет нам вычислить смещение следующего атрибута в списке - 30h (смещение нашего атрибута) + 60h (его длина) = 90h (смещение следующего атрибута). Первое двойное слово следующего атрибута равно 30h, значит, это атрибут типа $NAME и следующее 32-разрядное поле хранит его длину, равную в данном случае 70h. Сложив длину атрибута с его смещением, мы получим смещение следующего атрибута - 90h + 70h = 100h. Первое двойное слово третьего атрибута равно 80h, следовательно это атрибут типа $DATA, хранящий основные данные файла. Складываем его смешение с длиной - 100h + 32h = 132h. Упс! Мы наткнулись на частокол FFFFFFh, сигнализирующий о том, что атрибут $DATA последний в списке.

Теперь, разбив файловую запись на атрибуты, как мясник рассекает телячью тушу (try the veil, как говаривал старина Шрек), не грех будет приступить к исследованию каждого из атрибутов в отдельности. Начнем с имени. 8-разрядное поле, находящееся по смещению 08h от начала атрибутного заголовка (и по смещению 98h от начала сектора), содержит флаг неризидентности, который в данном случае равен нулю (т.е. атрибут резидентный и его тело хранится непосредственно в самой файловой записи, что есть гуд). 16-разрядное поле, расположенное по смещению 0Ch от начала атрибутного заголовка (и по смещению 9Ch от начала сектора) равно нулю, следовательно тело атрибута не сжато и не зашифровано. Хорошо! Тогда подать это тело на стол! 32-разрядное поле, расположенное по смещению 10h от начала атрибутного заголовка и по смещению A0h от начала сектора, содержит длину атрибутного тела, равную в данном случае 54h байт, а 16-разрядное поле, расположенное по смещению 14h от нача ла атрибутного заголовка и по смещению A4h от начала сектора, хранит смещение атрибутного тела, равное в данном случае 18h, следовательно тело атрибута $NAME располагается по смещению A8h от начала сектора.

Формат атрибута типа $NAME описан выше в таблице. Первые восемь байт содержат ссылку на материнский каталог данного файла, равную в данном случае 11ADBh: 01 (индекс - 11ADBh, номер последовательности - 01h). Следующие 32-байта содержат штаммы времени создания, изменения и времени последнего доступа к файлу. По смещению 28h от начала тела атрибута и D0h от начала сектора лежит 64-разрядное поле выделенного размера, а за ним - 64-разрядное поле реального размера. Оба равны нулю, что означает, что за размером файла следует обращаться к атрибутам типа $DATA.

Длина имени файла содержится в 8-разрядном поле, находящемся по смещению 40h байт от начала тела атрибута и по смещению E8h от начала сектора. В данном случае оно равно 09h. Само же имя начинается со смещения 42h от начала тела атрибута и со смещения EAh от начала сектора. И здесь находится Ilfak.dbx.

Переходим к атрибуту основных данных файла, пропустив атрибут стандартной информации, который не содержит решительно ничего интересного. 8-разрядный флаг неризидентности, расположенный по смещению 08h от начала атрибутного заголовка и по смещению 108h от начала сектора, равен 01h, следовательно атрибут неризидентный. 16-разрядный флаг, расположенный по смещению 0Ch от начала атрибутного заголовка и по смещению 10Сh от начала сектора, равен нулю, значит, атрибут не сжат и не зашифрован. 8-разрядное поле, расположенное по смещению 09h от начала атрибутного заголовка и по смещению 109h от начала сектора, равно нулю - атрибут безымянный. Реальная длина тела атрибута (в байтах) содержится в 64-разрядном поле, расположенном по смещению 30h от начала атрибутного заголовка и по смещению 130h от начала сектора. В данном случае она равна 4ED1F0h (5.165.552). Два 64-разрядных поля, расположенных по смещениям 10h/110h и 18h/118h байт от начала атрибутного заголовка/сектора соответственно, содержат начальный и конечный номер виртуального кластера неризидентного тела. В данном случае они равны: 0000h/4EDh.

Остается лишь декодировать список отрезков, адрес которого хранится в 16-разрядном поле, находящемся по смещению 20h от начала атрибутного заголовка и 120h от начала сектора. В данном случае оно равно 40h, что соответствует смещению от начала сектора в 140h. Сам же список отрезков выгляди так: 32 EE 04 D9 91 00 00. Ага! Два байта занимает поле длины (равное в данном случае 04EEh кластерам) и три - поле начального кластера (0091h). Завершающий ноль на конце говорит о том, что этот отрезок последний в списке отрезков.

Подытожим полученную информацию. Файл называется Ilfak.dbx, он начинается с кластера 0091h и продолжается вплоть до кластера 57Fh при реальной длине файла в 5.165.552 байт. За сим - все! Теперь уже ничего не стоит скопировать файл на резервный носитель (например, ZIP или стример).

Заключение

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

 






© 2023 :: MyLektsii.ru :: Мои Лекции
Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав.
Копирование текстов разрешено только с указанием индексируемой ссылки на источник.