¿Cómo encuentro el desplazamiento de un sistema de archivos ext4?

9

Tengo un disco duro defectuoso que no puede escribir ni leer los primeros sectores del disco. Simplemente da errores de E / S y eso es todo lo que hay. Hay otras áreas en el disco que parecen (en su mayoría) bien. Estoy tratando de montar una partición (ext4) y ver si puedo acceder a algunos archivos que me gustaría recuperar. Dado que el mountcomando admite una offsetopción, debería poder montar el sistema de archivos a pesar de que la tabla de particiones no se puede leer ni escribir. El problema es cómo encontrar el desplazamiento. Ninguna de las herramientas ext4 parece tener esta característica particular.

Ernest A
fuente
1
Pruebe testdisk y el fotorrec que lo acompaña.
jippie
@jippie le tomó a testdisk 6 horas escanear todo el disco y al final no encontró ninguna partición. Creo que la mejor estrategia es tratar de encontrar la ubicación del sistema de archivos directamente y montarlo.
Ernest A
Photorec probablemente podrá sacar sus archivos del disco, pero se perderán los nombres de archivo y las rutas. Si logra montar el sistema de archivos que es, por supuesto, su mejor opción, pero si testdisk no encontró ninguno, es probable que el inicio del sistema de archivos también esté dañado.
jippie

Respuestas:

13

No hay un desplazamiento estándar per-se, ya que, por supuesto, puede iniciar la partición donde lo desee. Pero supongamos por un momento que está buscando la primera partición, y se creó más o menos aceptando valores predeterminados. Hay dos lugares donde puede encontrarlo, suponiendo que estaba usando una tabla de partición DOS tradicional:

  1. Comenzando en el sector 63 (512 bytes). Esta fue la tradición durante mucho tiempo y funcionó hasta que alguien creó discos 4K ...
  2. A partir del sector (512 bytes) 2048. Esta es la nueva tradición, para acomodar discos 4K.
  3. ¡Una opción extra! Iniciando en el sector 56. Esto es lo que sucede si alguien mueve la partición de 63 comienzos para alinearla con un sector 4K.

Ahora, para continuar, querrás elegir tu herramienta de volcado hexadecimal favorita y aprender un poco sobre el diseño del disco ext4 . En particular, comienza con 1024 bytes de relleno, que ext4 ignora. Luego viene el superbloque. Puede reconocer el superbloque comprobando el número mágico 0xEF53 en el desplazamiento 0x38 (desde el inicio del superbloque, o 0x438 desde el inicio de la partición, o 1080 en decimal). El número mágico es little-endian. Por lo tanto, en realidad se almacena en el disco como 0x53EF.

Así es como se ve eso con 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..........

Tenga en cuenta que cuando da el desplazamiento para montar (o perder), debe dar el desplazamiento donde comienza el relleno, no el superbloque.

Ahora, si no es la primera partición, o si no está en uno de los dos (tres) lugares esperados, básicamente puedes buscar el número mágico 0xEF53. Esto es lo que testdisk(recomendado en un comentario) hace por ti.

derobert
fuente
2
¡¡¡ÉXITO!!! Tuve que escribir mi propio guión. testdiskNo lo encontraría. Gracias a todos por la ayuda.
Ernest A
En base a esto, puede usar algo como dd if=/dev/sda skip=$start_sector | xxd -a | grep '[02468]30: .... .... .... .... 53ef'obtener algunas coincidencias probables. Probablemente no sea muy rápido, pero puede dejarlo correr mientras encuentra un método mejor.
mwfearnley
Vea mi respuesta a continuación para el "mejor método" ahora. Nota: solo escaneando este número en datos aleatorios encontrará un falso positivo cada 65536 sectores (32 MB).
mwfearnley
gracias por esto. debido al hecho de que me tomó una segunda lectura para darme cuenta testdisk, solo tuve que agregar una edición para un tl;dr:encabezado
Jan-Stefan Janetzky
5

Basado en la respuesta de @ derobert , escribí un programa ( gist ) que analizará una secuencia de entrada ddy escaneará cada sector en busca de algo que se parezca al comienzo de una partición ext.

Funcionará al menos tan rápido como ddpueda leer desde su disco duro. Una versión resumida está debajo.

El uso más simple es justo sudo dd if=/dev/xxx | ext2scan, aunque es probable que desee modificar el ddcomando para mejorar el tamaño del bloque o elegir una región para buscar.

#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: encontrará no solo el comienzo de las particiones, sino también superbloques dentro de ellas.

En cualquier caso, recomendaría usar dumpe2fspara analizar los resultados. Puede volcar el inicio del supuesto superbloque en un archivo (al menos los primeros seis sectores, según mi prueba informal), y si es un superbloque, dumpe2fsle dirá (entre otras cosas) las ubicaciones relativas de los otros superbloques .

mwfearnley
fuente
2

Adivine dónde comienza la partición y aplique algo de fuerza 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

Me imagino que esto podría llevar algún tiempo, pero si ya ha pasado 6 horas con testdisk, quizás valga la pena intentarlo.

encerrada dorada
fuente
¡Ah, eso es mucha fuerza bruta!
derobert
Funciona pero es lento; Probé esto en una imagen de varias particiones cuyos desplazamientos conocía, para poder comenzar bastante cerca. Lanzado en la echo "--->$i<---"línea debido a eso, ya que de lo contrario es imposible medir el progreso. Creo que podría aumentar bsza 4096, lo que acelerará las cosas.
Ricitos de oro
Podría acelerarlo mucho si asume un diseño tradicional donde las particiones comienzan en un límite de "pista" (¿o es un cilindro?).
derobert
mi estimación era demasiado baja para que esta solución fuera práctica, pero puede funcionar en otras circunstancias
Ernest A
2

Pruebe diferentes opciones (por ejemplo, usando debugfs y fsck.ext4):

debugfs:

Primero debe montar debugfs (no el disco duro que falla):

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/

(esencialmente, es usar "debugfs -w" con el modo habilitado para escritura, y luego seguido de "lsdel" para enumerar todos los archivos eliminados). alternativamente puedes usar

y aquí está fsck.ext4:

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

Otro es "sleuthkit" ("sudo apt-get install sleuthkit") que tiene un comando como "istat" para proporcionar información de bloques sobre los inodos, desde donde puede obtener el desplazamiento y así bloquear el contenido de datos fácilmente.

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

(Por cierto, si el tamaño de bloque es 1024, del comando "show_super_stats" de debugfs, entonces se deduce que el bloque 1 tiene un desplazamiento de 1024 bytes desde el inicio del disco, y cada grupo de bloques también puede tener varios bloques).

Peter Teoh
fuente
1

Tenía una imagen de firmware de libro electrónico que incluía la imagen de partición ext3fs, para montar y editar tuve que escanear la imagen usando la herramienta bgrep para encontrar todas las posiciones del número mágico ext3fs 0x53EFe intentar montar usando las compensaciones encontradas.

Aquí hay un script acortado que realiza el montaje:

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

Guión completo ubicado aquí .

taro
fuente