Jak znaleźć przesunięcie systemu plików ext4?

9

Mam uszkodzony dysk twardy, który nie może zapisać lub odczytać pierwszych sektorów dysku. Po prostu daje błędy we / wy i to wszystko. Istnieją inne obszary na dysku, które wydają się (w większości) w porządku. Próbuję zamontować partycję (ext4) i sprawdzić, czy mogę uzyskać dostęp do niektórych plików, które chciałbym odzyskać. Ponieważ mountpolecenie obsługuje tę offsetopcję, powinienem móc zamontować system plików, nawet jeśli tablica partycji jest nieczytelna i nie można jej zapisać. Problem polega na tym, jak znaleźć przesunięcie. Żadne z narzędzi ext4 nie wydaje się mieć tej konkretnej funkcji.

Ernest A.
źródło
1
Wypróbuj testdisk i towarzyszący mu fotorec .
jippie
@jippie zajęło testdiskowi 6 godzin, aby przeskanować cały dysk i ostatecznie nie znalazł żadnej partycji. myślę, że najlepszą strategią jest próba znalezienia lokalizacji systemu plików bezpośrednio i zamontowania go.
Ernest A
photorec prawdopodobnie będzie w stanie usunąć twoje pliki z dysku, ale nazwy plików i ścieżki zostaną utracone. Jeśli uda ci się zamontować system plików, co jest oczywiście lepszą opcją, ale jeśli testdisk go nie znalazł, istnieje prawdopodobieństwo, że początek systemu plików również jest uszkodzony.
jippie

Odpowiedzi:

13

Nie ma standardowego przesunięcia jako takiego, ponieważ oczywiście partycję można rozpocząć w dowolnym miejscu. Załóżmy jednak przez chwilę, że szukasz pierwszej partycji i została ona utworzona mniej lub bardziej jako domyślna. Są dwa miejsca, w których możesz je znaleźć, zakładając, że używasz tradycyjnej tablicy partycji DOS:

  1. Począwszy od (512-bajtowego) sektora 63. To była tradycja przez bardzo długi czas i działała, dopóki ktoś nie wymyślił dysków 4K ...
  2. Począwszy od (512-bajtowego) sektora 2048. Jest to nowa tradycja obsługi dysków 4K.
  3. Opcja bonusowa! Sarting w sektorze 56. Tak się dzieje, gdy ktoś przeniesie partycję 63-start, aby dopasować ją do sektora 4K.

Teraz, aby kontynuować, będziesz chciał wybrać swoje ulubione narzędzie zrzutu heksadecymalnego i dowiedzieć się trochę o układzie dysku ext4 . W szczególności zaczyna się od 1024 bajtów wypełnienia, co ext4 ignoruje. Następnie pojawia się superblok. Możesz rozpoznać superblok, sprawdzając magiczną liczbę 0xEF53 z przesunięciem 0x38 (od początku superbloku lub 0x438 od początku partycji lub 1080 w systemie dziesiętnym.) Magiczna liczba to little-endian. Tak naprawdę jest przechowywany na dysku jako 0x53EF.

Oto jak to wygląda z 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..........

Zauważ, że kiedy podajesz przesunięcie do montowania (lub losetup), musisz podać przesunięcie do miejsca, w którym zaczyna się wypełnianie - a nie do superbloku.

Teraz, jeśli nie jest to pierwsza partycja, lub w inny sposób nie znajduje się w jednym z dwóch (trzech) oczekiwanych miejsc, w zasadzie możesz poszukać magicznej liczby 0xEF53. To właśnie robi testdisk(zalecane w komentarzu) dla Ciebie.

derobert
źródło
2
SUKCES!!! Musiałem napisać własny skrypt. testdisknie znalazłbym tego. Dziękuję wszystkim za pomoc.
Ernest,
Na tej podstawie możesz użyć czegoś takiego, dd if=/dev/sda skip=$start_sector | xxd -a | grep '[02468]30: .... .... .... .... 53ef'aby uzyskać prawdopodobne dopasowania. Prawdopodobnie niezbyt szybko, ale możesz pozwolić mu działać, gdy znajdziesz lepszą metodę.
mwfearnley
Zobacz moją odpowiedź poniżej „lepszej metody” teraz. Uwaga: samo skanowanie tej liczby w losowych danych znajdzie fałszywy wynik pozytywny co 65536 sektorów (32 MB).
mwfearnley
dzięki za to. z uwagi na fakt, że zajęło mi to drugie czytanie testdisk, po prostu musiałem dodać edycję tl;dr:nagłówka
Jan-Stefan Janetzky
5

W oparciu o odpowiedź @ derobert napisałem program ( gist ), który przeanalizuje strumień wejściowy zi ddskanuje każdy sektor w poszukiwaniu czegoś, co wygląda jak początek partycji ext.

Będzie działać co najmniej tak szybko, jak ddmożna odczytać z dysku twardego. Skrócona wersja znajduje się poniżej.

Najprostsze użycie jest po prostu sudo dd if=/dev/xxx | ext2scan, chociaż prawdopodobnie będziesz chciał zmodyfikować ddpolecenie, aby poprawić rozmiar bloku lub wybrać region do przeszukania.

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

Uwaga: znajdzie nie tylko początek partycji, ale także superbloki w nich.

W obu przypadkach polecam użycie dumpe2fsdo analizy wyników. Możesz zrzucić początek podejrzanego superbloku do pliku (co najmniej pierwszych sześciu sektorów, zgodnie z moim nieformalnym testem), a jeśli jest to superblok, dumpe2fspowiesz (między innymi) względne lokalizacje innych superbloków .

mwfearnley
źródło
2

Zgadnij, gdzie zaczyna się partycja i zastosuj brutalną siłę:

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

Wyobrażam sobie, że może to zająć trochę czasu, ale jeśli spędziłeś już 6 godzin z testdisk, być może warto spróbować.

Złotowłosa
źródło
Hah, to dużo brutalnej siły!
derobert,
Działa, ale jest wolny; Próbowałem tego na obrazie z wieloma partycjami, którego przesunięcia znałem, więc mogłem zacząć dość blisko. Rzucił się z tego echo "--->$i<---"powodu, ponieważ w przeciwnym razie niemożliwe jest zmierzenie postępu. Myślę, że możesz zwiększyć bszdo 4096, co przyspieszy.
goldilocks,
Możesz to znacznie przyspieszyć, zakładając tradycyjny układ, w którym partycje zaczynają się na granicy „toru” (a może cylindra?).
derobert,
moje oszacowanie było zbyt słabe, aby to rozwiązanie było praktyczne, ale może działać w innych okolicznościach
Ernest A
2

Wypróbuj inną opcję (np. Używając debugfs i fsck.ext4):

debugfs:

Najpierw musisz zamontować debugfs (a nie sam wadliwy dysk twardy):

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/

(w gruncie rzeczy należy użyć „debugfs -w” z trybem zapisu, a następnie „lsdel”, aby wyświetlić listę wszystkich usuniętych plików). alternatywnie możesz użyć

a tu jest fsck.ext4:

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

Innym jest „sleuthkit” („sudo apt-get install sleuthkit”), które mają polecenie takie jak „istat” do dostarczania blokowych informacji o i-węzłach - z których można uzyskać przesunięcie, a tym samym łatwo zablokować zawartość danych.

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

(BTW, jeśli rozmiar bloku to 1024, z polecenia debugfs „show_super_stats”, to wynika z tego, że blok 1 jest przesunięty o 1024 bajty od początku dysku, a każda grupa bloków może mieć także kilka bloków.)

Peter Teoh
źródło
1

Miałem obraz oprogramowania układowego e-booka, który zawierał obraz partycji ext3fs, aby zamontować i edytować, musiałem zeskanować obraz za pomocą narzędzia bgrep, aby znaleźć wszystkie pozycje magicznej liczby ext3fs 0x53EFi spróbować zamontować przy użyciu znalezionych przesunięć.

Oto skrócony skrypt, który wykonuje montowanie:

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

Kompletny skrypt znajduje się tutaj .

taro
źródło
0

To nie zostało przetestowane, ale myślę, że możesz użyć metody omówionej w tym SU Pytania i odpowiedzi zatytułowanej: Odwrotne wyszukiwanie i-węzła / pliku od przesunięcia w surowym urządzeniu na Linuksie i ext3 / 4? .

Wygląda na to, że możesz użyć i-węzła pliku + przesunięcia dysków + rozmiaru bloku, aby określić przesunięcie pliku.

slm
źródło
1
nie rozumiem, w jaki sposób ta metoda mogłaby mi pomóc dowiedzieć się, gdzie zaczyna się system plików.
Ernest A