Solución:
No existe un desplazamiento estándar per se, ya que, por supuesto, puede iniciar la partición donde desee. Pero supongamos por un momento que está buscando la primera partición y que se creó más o menos aceptando valores predeterminados. Entonces hay dos lugares donde puede encontrarlo, asumiendo que estaba usando una tabla de particiones de DOS tradicional:
- Comenzando en el sector 63 (512 bytes). Esta fue la tradición durante mucho tiempo y funcionó hasta que a alguien se le ocurrieron los discos 4K …
- Comenzando en el sector (512 bytes) 2048. Esta es la nueva tradición, para acomodar discos 4K.
- ¡Una opción de bonificación! Arrancando en el sector 56. Esto es lo que sucede si alguien mueve la partición de 63 inicios para alinearla con un sector de 4K.
Ahora, para continuar, querrá elegir su herramienta de volcado hexadecimal favorita y aprender un poco sobre el diseño de disco ext4. En particular, comienza con 1024 bytes de relleno, que ext4 ignora. Luego viene la supermanzana. 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. Entonces, en realidad, está almacenado en el disco como 0x53EF.
Así es como se ve con xxd -a
:
0000000: 0000 0000 0000 0000 0000 0000 0000 0000 ................
*
0000400: 0040 5d00 0084 7401 33a0 1200 33db a600 [email protected]]...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 losetup), debe dar el desplazamiento al lugar donde comienza el relleno, no al 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) lo hace por ti.
Basado en la respuesta de @ derobert, escribí un programa (esencia) que analizará un flujo de entrada de dd
y escanee cada sector en busca de algo que se parezca al inicio de una partición ext.
Funcionará al menos tan rápido como dd
puede leer desde su disco duro. A continuación se muestra una versión abreviada.
El uso más simple es simplemente sudo dd if=/dev/xxx | ext2scan
, aunque es probable que desee modificar el dd
comando 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 inicio de las particiones, sino también superbloques dentro de ellas.
En cualquier caso, recomendaría usar dumpe2fs
para analizar los resultados. Puede volcar el inicio del presunto superbloque en un archivo (al menos los primeros seis sectores, según mi prueba informal), y si es un superbloque, entonces dumpe2fs
le dirá (entre otras cosas) las ubicaciones relativas de los otros superbloques.
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 algo de tiempo, pero si ya ha pasado 6 horas con testdisk, tal vez valga la pena intentarlo.