Wie finde ich den Offset eines ext4-Dateisystems?

9

Ich habe eine fehlerhafte Festplatte, die die ersten Sektoren der Festplatte nicht schreiben oder lesen kann. Es gibt nur E / A-Fehler und das ist alles, was es gibt. Es gibt andere Bereiche auf der Festplatte, die (meistens) in Ordnung zu sein scheinen. Ich versuche, eine Partition (ext4) zu mounten und zu prüfen, ob ich auf einige Dateien zugreifen kann, die ich wiederherstellen möchte. Da der mountBefehl eine offsetOption unterstützt , sollte ich das Dateisystem bereitstellen können, obwohl die Partitionstabelle nicht lesbar und nicht beschreibbar ist. Das Problem ist, wie man den Versatz findet. Keines der ext4-Tools scheint diese spezielle Funktion zu haben.

Ernest A.
quelle
1
Probieren Sie testdisk und das dazugehörige Fotorec aus .
Jippie
@jippie Es dauerte 6 Stunden, bis testdisk die gesamte Festplatte gescannt hatte, und am Ende wurde keine Partition gefunden. Ich denke, die beste Strategie ist es, zu versuchen, den Speicherort des Dateisystems direkt zu finden und es zu mounten.
Ernest A
photorec wird wahrscheinlich in der Lage sein, Ihre Dateien von der Festplatte zu holen, aber Dateinamen und Pfadnamen gehen verloren. Wenn Sie es schaffen, das Dateisystem zu mounten, das natürlich Ihre bessere Option ist, aber wenn testdisk keine gefunden hat, besteht die Möglichkeit, dass auch der Start des Dateisystems beschädigt ist.
Jippie

Antworten:

13

Es gibt keinen Standard-Offset an sich, da Sie die Partition natürlich überall starten können. Nehmen wir für einen Moment an, dass Sie nach der ersten Partition suchen und diese mehr oder weniger standardmäßig akzeptiert wurde. Es gibt dann zwei Stellen, an denen Sie es möglicherweise finden, vorausgesetzt, Sie verwenden eine herkömmliche DOS-Partitionstabelle:

  1. Beginnend bei (512-Byte) Sektor 63. Dies war eine sehr lange Tradition und funktionierte, bis jemand 4K-Festplatten entwickelte ...
  2. Ab (512 Byte) Sektor 2048. Dies ist die neue Tradition, 4K-Festplatten aufzunehmen.
  3. Eine Bonusoption! Start in Sektor 56. Dies passiert, wenn jemand die 63-Start-Partition verschiebt, um sie an einem 4K-Sektor auszurichten.

Um fortzufahren, sollten Sie Ihr bevorzugtes Hex-Dump-Tool auswählen und ein wenig über das ext4-Festplattenlayout lernen . Insbesondere beginnt es mit 1024 Byte Auffüllung, die ext4 ignoriert. Als nächstes kommt der Superblock. Sie können den Superblock erkennen, indem Sie bei Offset 0x38 (vom Superblock-Start oder 0x438 vom Partitionsstart oder 1080 in Dezimalzahl) nach der magischen Zahl 0xEF53 suchen. Die magische Zahl ist Little-Endian. Es ist also tatsächlich als 0x53EF auf der Festplatte gespeichert.

So sieht das aus 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..........

Beachten Sie, dass Sie, wenn Sie den Offset zum Mounten (oder Losetup) angeben, den Offset an der Stelle angeben müssen, an der das Auffüllen beginnt - nicht am Superblock.

Wenn es sich nicht um die erste Partition handelt oder sich auf andere Weise nicht an einer der zwei (drei) erwarteten Stellen befindet, können Sie im Grunde nach der magischen Zahl 0xEF53 suchen. Dies ist, was testdisk(in einem Kommentar empfohlen) für Sie tut.

derobert
quelle
2
ERFOLG!!! Ich musste mein eigenes Skript schreiben. testdiskwürde es nicht finden. Vielen Dank für die Hilfe.
Ernest A
Auf dieser Grundlage können Sie so etwas wie dd if=/dev/sda skip=$start_sector | xxd -a | grep '[02468]30: .... .... .... .... 53ef'einige wahrscheinliche Übereinstimmungen verwenden. Wahrscheinlich nicht sehr schnell, aber Sie können es laufen lassen, während Sie eine bessere Methode finden.
mwfearnley
Siehe meine Antwort unten für die "bessere Methode" jetzt. Hinweis: Wenn Sie nur in zufälligen Daten nach dieser Zahl suchen, wird alle 65536 Sektoren (32 MB) ein falsches Positiv gefunden.
mwfearnley
Danke dafür. Aufgrund der Tatsache, dass ich eine zweite Lektüre brauchte, um zu bemerken testdisk, musste ich nur eine Bearbeitung für einen tl;dr:Header hinzufügen
Jan-Stefan Janetzky
5

Basierend auf der Antwort von @ derobert habe ich ein Programm ( Gist ) geschrieben, das einen Eingabestream von ddjedem Sektor analysiert und nach etwas durchsucht , das wie der Start einer ext-Partition aussieht.

Es funktioniert mindestens so schnell, wie ddes von Ihrer Festplatte gelesen werden kann. Eine gekürzte Version ist unten.

Die einfachste Verwendung ist nur sudo dd if=/dev/xxx | ext2scan, obwohl Sie wahrscheinlich den ddBefehl ändern möchten , um die Blockgröße zu verbessern, oder eine Region für die Suche auswählen möchten .

#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++;
  }
}

Hinweis: Es werden nicht nur der Anfang von Partitionen, sondern auch Superblocks darin gefunden .

In beiden Fällen würde ich empfehlen dumpe2fs, die Ergebnisse zu analysieren. Sie können den Start des Verdacht Supers in eine Datei Dump (zumindest in den ersten sechs Sektoren, nach meinem informellen Test), und wenn es ein Superblock ist, dann dumpe2fswerden Sie sagen , (unter anderem) den relativen Positionen der anderen Super .

mwfearnley
quelle
2

Erraten Sie, wo die Partition beginnt, und wenden Sie rohe Gewalt an:

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

Ich kann mir vorstellen, dass dies einige Zeit dauern könnte, aber wenn Sie bereits 6 Stunden mit testdisk verbracht haben, ist es vielleicht einen Versuch wert.

Goldlöckchen
quelle
Hah, das ist viel rohe Gewalt!
Derobert
Es funktioniert, aber es ist langsam; Ich habe dies auf einem Multi-Partition-Image versucht, dessen Offsets ich kannte, damit ich es ziemlich nah starten konnte. Warf aus diesem echo "--->$i<---"Grund in die Reihe, da es sonst unmöglich ist, den Fortschritt zu messen. Ich denke, Sie könnten bszauf 4096 steigen , was die Dinge beschleunigen wird.
Goldlöckchen
Sie könnten es erheblich beschleunigen, wenn Sie ein traditionelles Layout annehmen, bei dem Partitionen an einer "Spur" -Grenze (oder ist es ein Zylinder?) Beginnen.
Derobert
Meine Schätzung war zu schlecht, als dass diese Lösung praktikabel wäre, aber unter anderen Umständen funktionieren könnte
Ernest A
2

Probieren Sie eine andere Option aus (z. B. mit debugfs und fsck.ext4):

debugfs:

Sie müssen zuerst debugfs mounten (nicht die fehlerhafte Festplatte selbst):

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/

(Im Wesentlichen wird "debugfs -w" mit schreibgeschütztem Modus verwendet, gefolgt von "lsdel", um alle gelöschten Dateien aufzulisten.) alternativ können Sie verwenden

und hier ist fsck.ext4:

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

Ein anderes ist "sleuthkit" ("sudo apt-get install sleuthkit"), das einen Befehl wie "istat" zum Bereitstellen von Blockinformationen über die Inodes hat - von dem Sie den Offset abrufen und so den Dateninhalt einfach blockieren können.

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

(Übrigens, wenn die Blockgröße 1024 ist, folgt aus dem Befehl "show_super_stats" von debugfs, dass Block 1 1024 Bytes vom Start der Festplatte entfernt ist und jede Blockgruppe auch mehrere Blöcke haben kann.)

Peter Teoh
quelle
1

Ich hatte ein E-Book-Firmware-Image, das ein ext3fs-Partitions-Image enthielt. Um es zu mounten und zu bearbeiten, musste ich das Image mit dem bgrep-Tool scannen , um alle Positionen der magischen ext3fs-Nummer zu finden 0x53EFund zu versuchen, mithilfe gefundener Offsets zu mounten.

Hier ist ein verkürztes Skript, das das Mounten ausführt:

#!/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

Komplettes Skript finden Sie hier .

Taro
quelle
0

Dies ist nicht getestet, aber ich denke, Sie können die in dieser SU- Frage und Antwort beschriebene Methode mit dem Titel verwenden: Reverse Lookup von Inode / Datei vom Offset im Raw-Gerät unter Linux und ext3 / 4? .

Es sieht so aus, als könnten Sie den Inode einer Datei + den Festplattenversatz + die Blockgröße verwenden, um den Versatz einer Datei zu bestimmen.

slm
quelle
1
Ich sehe nicht, wie diese Methode mir helfen könnte, herauszufinden, wo das Dateisystem startet.
Ernest A