Unformat для NTFS

       

Ручное восстановление отформатированного диска


Нашей целью будет ручное восстановление всего отформатированного раздела без использования дополнительных носителей информации и дорогостоящих утилит от сторонних производителей. Все что потребуется— это любой редактор диска (предпочтительнее всего конечно же NT Explorer от Runtime Software, но на худой конец сойдет и бесплатный Disk Probe/Sector Inspector от Microsoft) и chkdsk.

Очевидно, что в процессе форматирования происходит необратимое разрушение большого количества ключевых структур данных, восстанавливать которые вручную было бы слишком затруднительно. Да это, собственно, и не нужно! Идея состоит в том, чтобы вернуть разделу потерянные файловые записи, а все остальные ремонтные работы поручить chkdsk'у — пускай старается.

Дизассемблирование показывает, что единственной структурой данных, без которой не может работать chkdsk, является атрибут $DATA файла $MFT. А раз так, все, что нам надо —воссоздать прежний $MFT:$DATA, разместив его поверх старых файловых записей. В простейшем случае (если $MFT:$DATA не фрагментирован) это достигается спекулятивным увеличением его длины. А как ее увеличить?

Запускаем NT Explorer, переходим в начало MFT (Goto à Mft), щелкаем по $MFT файлу, находим атрибут $DATA (80h) и увеличиваем поля Allocated Size/Real Size/Compressed Size на требуемую величину, параллельно с этим корректируя список отрезков (он же run-list). Поле Last VCN трогать не нужно — chkdsk исправит его и сам. Как определить длину не фрагментированного MFT-файла? Она равна разнице номеров первого и последнего секторов в начале которых присутствует сигнатура "FILE", умноженная на 512 байт (исключая сектора, принадлежащие $MFTMirr) Известные мне дисковые редакторы не поддерживают поиска последнего вхождения, поэтому соответствующую утилиту приходится писать самостоятельно. Впрочем, точную длину MFT определять совершенно необязательно и вполне допустимо взять ее с запасом — лишнее все равно отсеет chkdsk. Действуйте по принципу — лучше перебрать, чем недобрать.




Рисунок 6  ручное восстановление MFT. Подчеркнуты поля, подлежащие изменению

Коварный NT Explorer не позволяет редактировать поля в естественном режиме отображения, заставляя нас переключаться в HEX-mode и искать смещения всех значений самостоятельно. Найти заголовок атрибута $DATA очень просто — в его начале расположена последовательность 80 00 00 00 xx 00 00 00 01. В NTFS версии 3.0 она находится по смещению F8h от начала сектора. Поле Real Size во всех версиях NTFS располагается по смещению 30h относительно заголовка, а поля Allocated Size и Initialized Size соответственно по смещениям 28h/38h байт, причем значение Allocates Size должно быть кратно размеру кластера. Кстати, о кластерах. Убедитесь, что при переформатировании диска размер кластера не изменился, в противном случае у вас ничего не получится. Как восстановить исходный размер кластера? Да очень просто — набраться мужества и переформатировать восстанавливаемый диск с ключом /A:x, где x – размер кластера. А как его определить? Возьмем любой файл с известным содержимым и проанализируем его run-list. Пускаем контекстный поиск по всему диску, находим файл, запоминаем (записываем на бумажке) его стартовый сектор, после чего открываем закрепленный за ним FILE Record, декодируем run-list и вычисляем номер первого кластера. Делим номер сектора на номер кластера и получаем искомую величину.

Теперь необходимо сгенерировать новый run-list. В общем случае он будет выглядеть так: 13 XX XX XX YY 00, где XX XX XX – трехбайтовый размер $MFT в кластерах, а YY – стартовый кластер. Стартовый кластер обязательно должен указывать на первый кластер MFT, в противном случае chkdsk не сможет работать. Если новый run-list длиннее нынешнего (а именно так скорее всего и будет) необходимо скорректировать длину атрибутного заголовка (она расположена по смещению 04h от его начала). Проделав эту нехитрую операцию, запустим chkdsk с ключом /F и блаженно откинемся на спинку кресла, созерцая как возрождаются наши милые папки и файлы. Единственное, что не восстанавливается — так это дескрипторы безопасности: всем файлам/папкам назначаются права доступа по умолчанию. В остальном же, с отремонтированным диском вполне можно работать, не опасаясь, что он рухнет окончательно. Файлы, ссылающиеся на несуществующие каталоги складываются в папку Found.xxx. Это "долгожители" пережившие несколько циклов переформатирования, в буквальном смысле вытащенные с потустороннего света.



Сложнее восстановить том, чей MFT сильно фрагментирован. Прежний run-list при форматировании был уничтожен, зеркальная копия так же пострадала. Ничего другого не остается, как собирать все фрагменты руками. Звучит намного страшнее, чем выглядит. В отличии от всех остальных файлов диска, $MFT-файл имеет замечательную сигнатуру FILE, присутствующую в начале каждой файловой записи. Все, что нам нужно — последовательно сканируя раздел от первого кластера до последнего, выписать начало и конец каждого из фрагментов, принадлежащих MFT. Затем из этой цепочки необходимо исключить $MFTMirr. Его легко узнать — он расположен в середине раздела и содержит копии файловых записей $MFT, $MFTMirr, $LogFile и $Volume, причем $MFTMirr ссылается сам на себя. Допустим, наш список выглядит так: 08h – 333h, 669h – 966h, 1013 – 3210h. В грубом приближении ему будет соответствовать следующий run-list: 12 2B 03 08 22 23 03 69 96 22 FD 21 13 10 00. (Подробнее о кодировании/декодировании run-list'ов см. "списки отрезков" в прошлой статье этого цикла).

"В грубом" потому, что мы не знаем в какой последовательности располагались эти отрезки в файле (порядок расположения фрагментов на диске далеко не всегда совпадает с порядком отрезков в run-list'е). Что произойдет, если порядок сборки $MFT-файла окажется нарушен? А вот что — внутри MFT все файловые записи ссылаются друг на друга по своему порядковому номеру, представляющим индекс массива. Эти ссылки необходимы для восстановления структуры директорий, организации hard link'ов и еще кое-чего. Ссылки на материнский каталог дублируются в индексах и восстанавливаются элементарно. Hard link'и мрут безвозвратно (ну разве что попробовать пересобрать $MFT-файл в другом порядке), но они практически нигде и никем не используются, как говорится, было бы что терять. По-настоящему туго приходится сильно фрагментированным файлам, занимающим несколько файловых записей, раскиданных по разным $MFT-фрагментам. Здесь выручает только перестановка фрагментов. К счастью, количество комбинаций обычно бывает невелико и процедура восстановления занимает совсем немного времени. Хорошая новость – начиная с NTFS версии 3.1 (соответствующей Windows XP) в MFT номера файловых записей хранятся в явном виде (четырехбайтовое поле, расположенное по смещению 2Ch от начала FILE Record), что делает задачу восстановления тривиальной.


Содержание раздела