Как найти смещение файловой системы 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(рекомендуется в комментарии) делает для вас.

derobert
источник
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вам сообщат (среди прочего) об относительном расположении других суперблоков ,

mwfearnley
источник
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? ,

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

SLM
источник
1
Я не понимаю, как этот метод может помочь мне понять, где начинается файловая система.
Эрнест А