Come trovo l'offset di un filesystem ext4?


9

Ho un disco rigido guasto che non è in grado di scrivere o leggere i primi settori del disco. Fornisce solo errori I / O e questo è tutto. Ci sono altre aree sul disco che sembrano (principalmente) soddisfacenti. Sto cercando di montare una partizione (ext4) e vedere se riesco ad accedere ad alcuni file che vorrei recuperare. Poiché il mountcomando supporta offsetun'opzione, dovrei essere in grado di montare il filesystem anche se la tabella delle partizioni è illeggibile e non scrivibile. Il problema è come trovare l'offset. Nessuno degli strumenti ext4 sembra avere questa caratteristica particolare.


1
Prova testdisk e il relativo photorec.
jippie,

@jippie ha impiegato testdisk 6 ore per scansionare l'intero disco e alla fine non ha trovato alcuna partizione. penso che la migliore strategia sia cercare di trovare direttamente la posizione del filesystem e montarlo.
Ernest A

photorec probabilmente sarà in grado di estrarre i file dal disco, ma i nomi dei file e i nomi dei percorsi andranno persi. Se riesci a montare il filesystem che è ovviamente la tua opzione migliore, ma se testdisk non ne ha trovato nessuno, è probabile che anche l'avvio del filesystem sia danneggiato.
jippie,

Risposte:


13

Non esiste un offset standard di per sé, poiché ovviamente puoi avviare la partizione dove vuoi. Ma supponiamo per un momento che stai cercando la prima partizione ed è stata creata più o meno accettando le impostazioni predefinite. Esistono quindi due posizioni in cui è possibile trovarlo, supponendo che si stesse utilizzando una tabella delle partizioni DOS tradizionale:

  1. A partire dal settore (512 byte) 63. Questa era la tradizione da molto tempo e ha funzionato fino a quando qualcuno non ha inventato dischi 4K ...
  2. A partire dal settore (512 byte) 2048. Questa è la nuova tradizione, per ospitare dischi 4K.
  3. Un'opzione bonus! Avvio nel settore 56. Questo è ciò che accade se qualcuno sposta la partizione 63-start per allinearla con un settore 4K.

Ora, per procedere, ti consigliamo di prendere il tuo strumento hex-dump preferito e imparare qualcosa sul layout del disco ext4 . In particolare, inizia con 1024 byte di riempimento, che ext4 ignora. Segue il superblocco. È possibile riconoscere il superblocco controllando il numero magico 0xEF53 all'offset 0x38 (dall'inizio del superblocco o 0x438 dall'inizio della partizione o 1080 in decimale.) Il numero magico è little-endian. Quindi è effettivamente memorizzato su disco come 0x53EF.

Ecco come si presenta 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..........

Nota che quando dai l'offset da montare (o losetup), devi dare l'offset a dove inizia il padding, non il superblocco.

Ora, se non è la prima partizione, o altrimenti non si trova in uno dei due (tre) punti previsti, in pratica puoi cercare il numero magico 0xEF53. Questo è ciò che testdisk(consigliato in un commento) fa per te.


2
SUCCESSO!!! Ho dovuto scrivere la mia sceneggiatura. testdisknon lo troverei. Grazie a tutti per l'aiuto.
Ernest A

Sulla base di questo, puoi usare qualcosa di simile dd if=/dev/sda skip=$start_sector | xxd -a | grep '[02468]30: .... .... .... .... 53ef'per ottenere alcune probabili partite. Probabilmente non molto veloce, ma puoi lasciarlo funzionare mentre trovi un metodo migliore.
mwfearnley,

Vedi la mia risposta qui sotto per il "metodo migliore" ora. Nota: solo la ricerca di questo numero in dati casuali troverà un falso positivo ogni 65536 settori (32 MB).
mwfearnley,

grazie per questo. a causa del fatto che ho notato una seconda lettura testdisk, ho dovuto solo aggiungere una modifica per un tl;dr:colpo di testa
Jan-Stefan Janetzky

5

Sulla base della risposta di @Derobert , ho scritto un programma ( gist ) che analizzerà un flusso di input da dde scansionerà ogni settore alla ricerca di qualcosa che assomigli all'inizio di una partizione ext.

Funzionerà almeno la più veloce ddpossibile leggere dal tuo disco rigido. Una versione ridotta è di seguito.

L'uso più semplice è giusto sudo dd if=/dev/xxx | ext2scan, anche se probabilmente vorrai modificare il ddcomando per migliorare la dimensione del blocco o scegliere una regione da cercare.

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

Nota: troverà non solo l'inizio delle partizioni, ma anche superblocchi al loro interno.

In entrambi i casi, consiglierei di utilizzare dumpe2fsper analizzare i risultati. Puoi scaricare l'inizio del sospetto superblocco in un file (almeno i primi sei settori, secondo il mio test informale), e se si tratta di un superblocco, dumpe2fsti dirà (tra le altre cose) le posizioni relative degli altri superblocchi .


2

Fai un'ipotesi su dove inizia la partizione e applica una forza bruta:

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

Immagino che questo potrebbe richiedere del tempo, ma se hai già trascorso 6 ore con testdisk, forse vale la pena provare.


Hah, questa è molta forza bruta!
derobert il

Funziona ma è lento; Ho provato questo su un'immagine multi-partizione di cui conoscevo gli offset, quindi ho potuto avviarlo abbastanza vicino. Gettato in echo "--->$i<---"linea a causa di ciò poiché altrimenti è impossibile misurare i progressi. Penso che potresti aumentare bsza 4096, il che accelererà le cose.
Riccioli d'oro

Si potrebbe accelerare molto se si assume un layout tradizionale in cui le partizioni iniziano su un limite di "traccia" (o è cilindro?).
derobert il

la mia stima era troppo scarsa perché questa soluzione fosse pratica ma potesse funzionare in altre circostanze
Ernest A

2

Prova diverse opzioni (ad es. Usando debugfs e fsck.ext4):

debugfs:

Devi prima montare il debugfs (non lo stesso disco fisso guasto):

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/

(essenzialmente, è usare "debugfs -w" con la modalità abilitata alla scrittura, e quindi seguito da "lsdel" per elencare tutti i file eliminati). in alternativa puoi usare

e qui è fsck.ext4:

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

Un altro è "sleuthkit" ("sudo apt-get install sleuthkit") che ha un comando come "istat" per fornire informazioni sui blocchi sugli inode, da cui è possibile ottenere l'offset e quindi bloccare facilmente il contenuto dei dati.

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

(A proposito, se la dimensione del blocco è 1024, dal comando "show_super_stats" di debugfs, ne consegue che il blocco 1 ha un offset di 1024 byte dall'inizio del disco e ogni gruppo di blocchi può avere anche diversi blocchi.)


1

Avevo un'immagine del firmware di un e-book che includeva l'immagine di partizione ext3fs, al fine di montare e modificare che dovevo scansionare l'immagine usando lo strumento bgrep per trovare tutte le posizioni del numero magico di ext3fs 0x53EFe provare a montare usando gli offset trovati.

Ecco uno script abbreviato che esegue il montaggio:

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

Script completo situato qui .


Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.