Como encontro o offset de um sistema de arquivos ext4?

8

Eu tenho um disco rígido com falha que é incapaz de escrever ou ler os primeiros setores do disco. Apenas dá erros de E / S e isso é tudo o que existe. Existem outras áreas no disco que parecem (principalmente) boas. Eu estou tentando montar uma partição (ext4) e ver se consigo acessar alguns arquivos que gostaria de recuperar. Como o comando mount suporta uma opção offset , eu deveria ser capaz de montar o sistema de arquivos mesmo que a tabela de partição seja ilegível e não possa ser escrita. O problema é como encontrar o deslocamento. Nenhuma das ferramentas do ext4 parece ter esse recurso em particular.

    
por Ernest A 05.12.2013 / 21:48

6 respostas

12

Não há um deslocamento padrão por si, como é claro, você pode iniciar a partição onde quiser. Mas vamos supor por um momento que você está procurando pela primeira partição, e ela foi criada aceitando mais ou menos os padrões. Existem dois lugares onde você pode encontrá-lo, supondo que você esteja usando uma tabela de partição tradicional do DOS:

  1. Começando no setor de (512 bytes) 63. Essa foi a tradição por muito tempo e funcionou até que alguém surgiu com discos 4K ...
  2. Começando no setor (de 512 bytes) 2048. Essa é a nova tradição, para acomodar discos de 4K.
  3. Uma opção de bônus! Sarting no setor 56. Isto é o que acontece se alguém mover a partição 63-start para torná-la alinhada com um setor 4K.

Agora, para prosseguir, você vai querer pegar sua ferramenta hex-dump favorita e aprender um pouco sobre o ext4 Layout de disco . Em particular, ele começa com 1024 bytes de preenchimento, que o ext4 ignora. Em seguida vem o superbloco. Você pode reconhecer o superbloco verificando o número mágico 0xEF53 no deslocamento 0x38 (do início do superbloco, ou 0x438 do início da partição, ou 1080 em decimal). O número mágico é little-endian. na verdade, é armazenado no disco como 0x53EF.

Aqui está o que parece com 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..........

Note que quando você dá o offset para montar (ou losetup), você deve dar o offset para onde o preenchimento começa - não o superbloco.

Agora, se não for a primeira partição, ou não estiver em um dos dois (três) pontos esperados, você basicamente procurará pelo número mágico 0xEF53. Isso é o que o testdisk (recomendado em um comentário) faz por você.

    
por 05.12.2013 / 23:23
4

Com base na resposta do @derobert , escrevi um programa ( gist ) que irá analisar um fluxo de entrada de dd e varrer cada setor para algo que se parece com o início de uma partição ext.

Ele funcionará pelo menos tão rápido quanto dd pode ler em seu disco rígido. Uma versão abreviada está abaixo.

O uso mais simples é apenas sudo dd if=/dev/xxx | ext2scan , embora você provavelmente queira modificar o comando dd para melhorar o tamanho do bloco ou escolher uma região para pesquisar.

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

Observação: ele não encontrará apenas o início das partições, mas também superblocos dentro deles.

Em ambos os casos, recomendamos o uso de dumpe2fs para analisar os resultados. Você pode descarregar o início do superbloco suspeito em um arquivo (pelo menos nos seis primeiros setores, de acordo com meu teste informal), e se for um superbloco, então dumpe2fs dirá (entre outras coisas) as localizações relativas de os outros superblocos.

    
por 20.02.2017 / 00:45
2

Faça uma suposição sobre onde a partição começa e aplique força 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

Eu imagino que isso pode levar algum tempo, mas se você já passou 6 horas com testdisk, talvez valha a pena tentar.

    
por 05.12.2013 / 23:04
2

Tente uma opção diferente (por exemplo, usando debugfs e fsck.ext4):

debugfs:

Você precisa montar o debugfs primeiro (não o próprio disco rígido com falha):

link

link

link

(essencialmente, é usar "debugfs -w" com o modo habilitado para gravação e, em seguida, seguido por "lsdel" para listar todos os arquivos excluídos). alternativamente você pode usar

e aqui está fsck.ext4:

link

Outro é o "sleuthkit" ("sudo apt-get install sleuthkit") que possui comandos como "istat" para fornecer informações sobre os inodes - a partir dos quais você pode obter o offset e assim bloquear facilmente o conteúdo dos dados.

link

(BTW, se o tamanho do bloco for 1024, do comando "show_super_stats" do debugfs, segue-se que o bloco 1 é 1024 bytes a partir do início do disco, e cada grupo de blocos também pode ter vários blocos.)

    
por 26.02.2014 / 02:36
1

Eu tinha uma imagem de firmware de e-book, que incluía a imagem da partição ext3fs, para montar e editar, tive que digitalizar a imagem usando a ferramenta bgrep para encontrar todas as posições do número mágico ext3fs 0x53EF e tente montar usando deslocamentos encontrados.

Aqui está um script resumido que realiza a montagem:

#!/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 localizado aqui .

    
por 02.11.2018 / 18:26
0

Isso não foi testado, mas acho que você pode usar o método discutido neste SU Q & A intitulado: Reverse lookup de inode / file from offset no dispositivo raw no linux e ext3 / 4? .

Parece que você pode usar o inode de um arquivo + o tamanho de bloco + offset do disco para determinar o deslocamento de um arquivo.

    
por 05.12.2013 / 22:17