Как найти смещение файловой системы ext4?


9

У меня неисправный жесткий диск, который не может записать или прочитать первые сектора диска. Это просто дает ошибки ввода-вывода, и это все, что есть. На диске есть и другие области, которые кажутся (в основном) хорошими. Я пытаюсь смонтировать раздел (ext4) и посмотреть, могу ли я получить доступ к некоторым файлам, которые я хотел бы восстановить. Поскольку mountкоманда поддерживает offsetопцию, я смогу смонтировать файловую систему, даже если таблица разделов не читается и не перезаписывается. Проблема в том, как найти смещение. Похоже, что ни один из инструментов ext4 не обладает этой особенностью.


1
Попробуйте тестдиск и сопутствующий фоторепортаж .
— Джиппи

@jippie потребовалось 6 часов тестового диска, чтобы просканировать весь диск, и в итоге он не нашел ни одного раздела. Я думаю, что лучшая стратегия - попытаться найти местоположение файловой системы напрямую и смонтировать ее.
— Эрнест А

photorec, вероятно, сможет получить ваши файлы с диска, но имена файлов и пути будут потеряны. Если вам удастся смонтировать файловую систему, что, конечно, является лучшим вариантом, но если testdisk не обнаружил ни одной, есть вероятность, что запуск файловой системы также поврежден.
— Джиппи

Ответы:


13

Там нет стандартного смещения как такового, так как, конечно, вы можете начать раздел где угодно. Но давайте на минутку предположим, что вы ищете первый раздел, и он был создан более или менее с учетом значений по умолчанию. Тогда есть два места, где вы можете найти его, при условии, что вы использовали традиционную таблицу разделов DOS:

  1. Начиная с сектора (512 байт) 63. Это было традицией в течение очень долгого времени и работало до тех пор, пока кто-то не придумал диски 4K ...
  2. Начиная с (512-байтового) сектора 2048. Это новая традиция для размещения 4K дисков.
  3. Бонусная опция! Сарт в секторе 56. Вот что происходит, если кто-то перемещает 63-пусковой раздел, чтобы выровнять его с сектором 4К.

Теперь, чтобы продолжить, вам нужно выбрать свой любимый инструмент hex-dump и немного узнать о макете диска ext4 . В частности, он начинается с 1024 байтов заполнения, которое ext4 игнорирует. Далее идет суперблок. Вы можете распознать суперблок, проверив магическое число 0xEF53 со смещением 0x38 (от начала суперблока, или 0x438 от начала раздела, или 1080 в десятичном формате.) Магическое число имеет младший порядок. Так что на самом деле он хранится на диске как 0x53EF.

Вот как это выглядит xxd -a:

0000000: 0000 0000 0000 0000 0000 0000 0000 0000 ................ * 0000400: 0040 5d00 0084 7401 33a0 1200 33db a600 .@]...t.3...3... 0000410: 4963 5300 0000 0000 0200 0000 0200 0000 IcS............. 0000420: 0080 0000 0080 0000 0020 0000 6637 0952 ......... ..f7.R 0000430: 6637 0952 0200 1600 53ef 0100 0100 0000 f7.R....S....... 0000440: 9938 f851 004e ed00 0000 0000 0100 0000 .8.Q.N..........

Обратите внимание, что когда вы задаете смещение для монтирования (или потерянного), вы должны указать смещение, с которого начинается заполнение, а не суперблок.

Теперь, если это не первый раздел или иное не в одном из двух (трех) ожидаемых мест, вы в основном начинаете искать магическое число 0xEF53. Это то, что testdisk(рекомендуется в комментарии) делает для вас.


2
УСПЕХ !!! Я должен был написать свой собственный сценарий. testdiskне нашел бы это. Спасибо всем за помощь.
— Эрнест А

Исходя из этого, вы можете использовать что-то вроде, dd if=/dev/sda skip=$start_sector | xxd -a | grep '[02468]30: .... .... .... .... 53ef'чтобы получить возможные совпадения. Возможно, не очень быстро, но вы можете позволить ему работать, пока вы найдете лучший метод.
— mwfearnley

Смотрите мой ответ ниже для "лучшего метода" сейчас. Примечание: просто сканирование этого числа в случайных данных обнаружит ложное срабатывание каждые 65536 секторов (32 МБ).
— mwfearnley

Спасибо за это. из-за того, что мне потребовалось второе чтение, чтобы заметить testdisk, мне просто нужно было добавить правку для tl;dr:заголовка
— Ян-Стефан Янецкий

5

Основываясь на ответе @ derobert , я написал программу ( gist ), которая будет анализировать входной поток ddи сканировать каждый сектор на предмет чего-то похожего на начало раздела ext.

Он будет работать по крайней мере так же быстро, как ddможет читать с вашего жесткого диска. Сокращенная версия приведена ниже.

Самое простое использование - просто sudo dd if=/dev/xxx | ext2scan, хотя вы, вероятно, захотите изменить ddкоманду, чтобы улучшить размер блока или выбрать регион для поиска.

#include <unistd.h>
#include <stdio.h>
#include <string.h>

int main() {
  unsigned char const MAGIC[2] = {0x53, 0xef};
  unsigned char const ZEROS[512] = {0};

  long long int sector = 0;

  char buf[4][512];
  int empty1, empty2;

  while (read(STDIN_FILENO, buf[sector&3], 512) > 0) {
    if (!memcmp(buf[sector&3] + 0x38, MAGIC, 2)) {
      printf("Found a possible ext2 partition at sector %lld", sector-2);

      empty1 = !memcmp(buf[(sector-2)&3], ZEROS, 512);
      empty2 = !memcmp(buf[(sector-1)&3], ZEROS, 512);

      if (empty1 && empty2) printf(" (first two sectors are empty :)\n");
    }
    sector++;
  }
}

Примечание: он найдет не только начало разделов, но и суперблоки внутри них.

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


2

Угадайте, где начинается раздел, и примените грубую силу:

bsz=512 # or 1024, 2048, 4096 higher = faster

for i in {2..10000000}; do
    echo "--->$i<---"
    mount -o offset=$(($bsz*$i)) -t ext4 /dev/whatever /mnt/foo
    if [ $? == 0 ]; then # whahoo!
        echo Eureka
        break
    fi
done

Я полагаю, это может занять некоторое время, но если вы уже потратили 6 часов на testdisk, возможно, стоит попробовать.


Ха, это много грубой силы!
— Дероберт

Это работает, но это медленно; Я попробовал это на многосегментном образе, смещения которого я знал, поэтому я мог начать его довольно близко. Вбросил echo "--->$i<---"линию из-за этого, так как иначе невозможно оценить прогресс. Я думаю, что вы можете увеличить bszдо 4096, что ускорит процесс.
— Златовласка

Вы могли бы значительно ускорить его, если бы вы использовали традиционную компоновку, в которой разделы начинаются на границе «дорожка» (или это цилиндр?).
— Дероберт

моя оценка была плохой для того, чтобы это решение было практичным, но может работать в других обстоятельствах
— Эрнест А

2

Попробуйте другой вариант (например, используя debugfs и fsck.ext4):

debugfs:

Сначала вы должны смонтировать debugfs (а не сам сбойный жесткий диск):

http://johnsofteng.wordpress.com/2013/11/20/sysfs-procfs-sysctl-debugfs-and-other-similar-kernel-interfaces/

http://afzalkhanlinuxtalk.wordpress.com/2013/08/07/how-to-recover-deleted-file-in-linux/comment-page-1/#comment-8

http://blesseddlo.wordpress.com/2010/10/12/using-debugfs/

(по сути, это использование «debugfs -w» в режиме с включенной записью, а затем «lsdel» для вывода списка всех удаленных файлов). В качестве альтернативы вы можете использовать

и вот fsck.ext4:

http://linuxexpresso.wordpress.com/2010/03/31/repair-a-broken-ext4-superblock-in-ubuntu/

Другой - это «sleuthkit» («sudo apt-get install sleuthkit»), в котором есть команда типа «istat» для предоставления информации о блоках об инодах, из которой вы можете получить смещение и, таким образом, легко заблокировать содержимое данных.

https://www.ibm.com/developerworks/cn/linux/l-cn-ext4resize/

(Кстати, если размер блока равен 1024, из команды debugfs «show_super_stats», то из этого следует, что блок 1 смещен на 1024 байта от начала диска, и каждая группа блоков также может иметь несколько блоков.)


1

У меня был образ прошивки электронной книги, который включал образ раздела ext3fs, чтобы смонтировать и отредактировать то, что мне пришлось сканировать образ с помощью инструмента bgrep, чтобы найти все позиции магического числа ext3fs 0x53EFи попытаться смонтировать, используя найденные смещения.

Вот сокращенный скрипт, который выполняет монтирование:

#!/bin/sh
FW_IMAGE=$1
MOUNT_POINT=$2

FS_TYPE=ext3
EXTFS_MAGIC_NUM=53ef
MAGIC_OFFSET=1080

OFFSETS=`bgrep $EXTFS_MAGIC_NUM $FW_IMAGE | awk '{print toupper($NF)}'`
for OFFSET in $OFFSETS; do
  OFFSET=`echo "ibase=16; $OFFSET" | bc`
  OFFSET=`expr $OFFSET - $MAGIC_OFFSET`
  sudo mount -t $FS_TYPE -o loop,offset=$OFFSET $FW_IMAGE $MOUNT_POINT 2>/dev/null
  if [ $? -eq 0 ]; then
    echo "Success!  Offset is: $OFFSET."
    break
  fi
done

Полный сценарий находится здесь .


0

Это не проверено, но я думаю, что вы можете использовать метод, обсуждаемый в этом SU Q & A под названием: Обратный поиск inode / файла со смещения в raw-устройстве на linux и ext3 / 4? ,

Похоже, вы можете использовать индекс файла + смещение дисков + размер блока, чтобы определить смещение файла.


1
Я не понимаю, как этот метод может помочь мне понять, где начинается файловая система.
— Эрнест А
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.