Рис. 7.1. Утилита GetDataBack за восстановлением удаленных файлов
С другой стороны, утилиты, вносящие изменения непосредственно в структуру NTFS, рискуют серьезно повредить дисковый том, после чего ему не помогут даже профессионалы. Настоящие хакеры не доверяют никакому коду, кроме созданного лично ими, особенно, если исходные тексты недоступны, а документация туманна и двусмысленна. Различные версии NTFS отличаются друг от друга. Последние радикальные изменения произошли в Windows XP (NTFS версии 3.1) — массив последовательностей обновления (Update Sequence Number-n-Array) переместился на шесть байтов вперед, а его
место было отдано под выравнивание и поле номера текущей файловой записи (Number of this MFT Record). Восстанавливающая утилита должна не только поддерживать вашу версию файловой системы, но и безошибочно отличать ее ото всех остальных. При этом в дополнение к уже указанным сложностям встречаются и совершенно неочевидные "подводные камни". Например, при обновлении Windows 2000 до Windows XP обновления файловой системы не происходит вплоть до переформатирования диска. Эта небольшая особенность не слишком афишируется, и знают о ней лишь немногие. Большинство пользователей попадается в эту ловушку, и последствия оказываются катастрофическими.
Наконец, возможна и такая ситуация, когда утилит восстановления просто не окажется под рукой в тот момент, когда вам срочно потребуется восстановить какой-нибудь ценный файл. Законов Мэрфи еще никто не отменял! В этом случае вам придется рассчитывать только на свои силы.
Ручное восстановление ошибочно удаленных файлов
Начнем с простейшего. Файл только что удален, и принадлежащая ему файловая запись еще не затерта. Как найти его на диске? Существует два способа — "теоретический" и "практический". Теоретический метод исключительно надежен, но требует дополнительных операций, выполнения которых можно избежать, приняв ряд практических допущений.
Теоретически грамотный и правильный подход состоит в следующем. Извлекаем из загрузочного сектора указатель на MFT, извлекаем из нее первую запись (она описывает
$MFT
), находим атрибут
$DATA
(
80h
), декодируем список отрезков (data runs) и последовательно читаем все записи в MFT, анализируя содержимое атрибута
$FILE_NAME
(
30h
) — имя файла. Обратите внимание, что таких атрибутов у файла может быть несколько. Этот же атрибут хранит ссылку на родительский каталог. Поэтому, если несколько одноименных файлов были удалены из различных каталогов, то необходимо выяснить, какой именно из них должен быть восстановлен.
Практический подход выглядит следующим образом. В девяти случаях из десяти файл
$MFT
не фрагментирован и располагается практически в самом начале диска. Имена файлов хранятся по смещению
EAh
от начала сектора, в начале которого расположена сигнатура
FILE*
(
FILE0
— в NTFS 3.1). Поэтому можно просто запустить любой дисковый редактор (например, Disk Probe из комплекта Support Tools от Microsoft), ввести имя восстанавливаемого файла в кодировке UNICODE и дать редактору указание искать его по смещению
EAh
(в NTFS 3.1 —
F0h
) от начала сектора (рис. 7.2).
Рис. 7.2. Ручное восстановление удаленного файла с помощью Disk Probe
Когда же искомая строка будет найдена, необходимо проверить, находится ли в начале сектора сигнатура
FILE*
/
FILE0
. Если такой сигнатуры в начале сектора нет, следует продолжить поиск. Двухбайтное поле по смещению
16h
от начала сектора содержит флаги записи:
00h
— запись не используется или была удалена,
01h
— запись используется,
02h
— запись используется и описывает каталог. Встречаются и другие значения, например,
04h
,
08h
.
Эти значения не документированы. Возможно, что именно вы сможете пролить свет на этот вопрос?
Исправляем 00h на 01h, записываем изменения и... Ничего не выходит?! А чего вы хотели! Ведь помимо этого необходимо выполнить еще несколько действий. Во-первых, следует сообщить файлу
/$MFT:$BITMAP
, что данная запись MFT вновь используется. Во-вторых, необходимо исключить из файла
/$BITMAP
номера кластеров, принадлежащие восстанавливаемому файлу. Наконец, необходимо перестроить двоичное дерево индексов, хранящее содержимое каталога. Первые два пункта не представляют серьезной проблемы, но вот над последней задачей придется повозиться. Хотя ее можно существенно упростить, просто запустив chkdsk с ключом
/F
. Утилита chkdsk самостоятельно найдет "потерянный" файл и внесет все необходимые изменения в файловую систему (листинг 7.1). От вас потребуется только установить флаг по смещению 16h в единицу, а все остальное сделает chkdsk. После этих нехитрых манипуляций восстановленный файл окажется в своем родном каталоге.
Листинг 7.1. Восстановление удаленного файла при помощи chkdsk
C:\chkdsk D: /F
Тип файловой системы: NTFS.
Проверка файлов завершена.
Проверка индексов завершена.
Восстановление потерянных файлов.
Восстановление потерянного файла test.txt в файле каталога 5
Замена неправильного идентификатора безопасности для файла 29
Проверка дескрипторов безопасности завершена.
Исправление ошибок в атрибуте BITMAP основной таблицы файлов.
Windows сделала изменения в файловой системе.
1068290 КБ всего на диске.
20 КБ в 2 файлах.
4 КБ в 9 индексах.
0 КБ в поврежденных секторах.
7894 КБ используется системой.
7392 КБ занято под файл журнала.
1060372 КБ свободно на диске.
Размер кластера: 2048 байт.
Всего кластеров на диске: 534145.
530186 кластеров на диске.
Восстанавливаем руины
Рассмотрим более сложный случай восстановления, а именно — случай, когда файловая запись уже затерта. Если удаленный файл был резидентным (хранил свое тело в MFT), то восстанавливать уже нечего. Даже если на ранее занимаемом им месте создан нерезидентный файл (а файловая запись нерезидентного файла заканчивается там, где начинается резидентное тело), операционная система заботливо заполнит оставшийся "хвост" нулями, и для восстановления оригинального содержимого придется прибегнуть к дорогостоящему оборудованию, читающему поверхность жесткого диска на физическом уровне.
С нерезидентными файлами, хранящими свое тело вне MFT, ситуация обстоит не так плачевно, хотя и здесь проблем тоже хватает. Порядок размещения файла на диске хранится в списке отрезков (run-list) внутри файловой записи в MFT. При этом, поскольку файловая запись уже затерта, возможен лишь контекстный поиск по содержимому. Запускаем дисковый редактор, вводим последовательность, заведомо содержащуюся в удаленном файле, но не встречающуюся во всех остальных, и даем редактору команду начать поиск. Для ускорения поиска можно искать только в свободном дисковом пространстве (за это отвечает файл
/$BITMAP
). Известные мне редакторы напрасно пренебрегают этой возможностью, однако утилиту "продвинутого" поиска несложно написать и самостоятельно.