Recuperando arquivos apagados - parte III
Por: Guilherme Cox

Arquivos grandes (mais de 12 blocks)

O problema aparece para arquivo com mais de 12 blocos. Para conseguirmos recuperar esses arquivos precisamos contar que o disco não está fragmentado. E quanto maior for o arquivo mais difícil vai ser a recuperação total dele. Vamos descrever um pequeno resumo de como funciona o armazenamento de grandes arquivos na filesystem.

Um inode é um identificador unico que um arquivo recebe, nele contém uma lista com 12 blocos diretos de dados que o arquivo deve ter, se ele possui mais de 12 blocos, ele segue um regra para gravar esses blocos no disco e poder achar mais tarde.

  • os 12 primeiros blocos são gravados diretamente, são conhecidos como direct blocks.
  • O inode contém o número para um bloco que seria um bloco indireto. Um bloco indireto contém dados para 256 blocos adicionais.
  • o inode contém o número para um bloco que seria um segundo bloco indireto. Esse contém 256 blocos indiretos adicionais.
  • o inode contém o número para um bloco que seria um terceiro bloco indireto. Esse contém 256 segundos-blocos indiretos adicionais.

O problema consiste em que os blocos indiretos são (geralmente) zerados quando o arquivo é deletado. Então, não existe grandes esperancas ou garantias para achar os blocos caso o arquivo esteja fragmentando, a nossa unica esperanca é considerar que o arquivo está gravado de forma sequencial. Assumindo que ele não está fragmentando podemos usar a tabela abaixo como referência.

0 até 12
Os blocos diretos que são gravados no inode.

13 até 268 Logo apos os blocos diretos, os blocos indiretos. Neste primeiro caso 256 blocos de dados.

269 até 65804
Como antes, depois dos 12 blocos diretos, um bloco indireto inútil (que seria uma lista com os blocos indiretos), e 256 blocos. São seguidos por um (inútil) segundo-bloco e 256 repetições de blocos (inúteis) mais 256 repetições de blocos de dados.

E assim por diante. Você não precisa entender a fundo como isso funciona, apenas os conceitos são importantes.

Estamos contando que nenhum dos blocos foi sobrescrito e que ele foi gravado de maneira sequência. Outro fator importante é verificar que o nosso blocksize é de 1024. Você pode estar adotando outro valor para o seu filesystem. Considera sempre blocksize/4 o número de blocos que podem ser gravador indiretamente por um inode.

Veja o exemplo abaixo:

    debugfs: stat <1387>
     Inode: 148004 Type: regular Mode: 0644 Flags: 0x0 Version:
    1
     User: 503 Group: 100 Size: 1851347
     File ACL: 0 Directory ACL: 0
     Links: 0 Blockcount: 3616
     Fragment: Address: 0 Number: 0 Size: 0
     ctime: 0x31a9a574 -- Mon May 27 13:52:04 2000
     atime: 0x31a21dd1 -- Tue May 21 20:47:29 2000
     mtime: 0x313bf4d7 -- Tue Mar 5 08:01:27 2000
     dtime: 0x31a9a574 -- Mon May 27 13:52:04 2000
     BLOCKS:
     8314 8315 8316 8317 8318 8319 8320 8321 8322 8323 8324 8325
    8326 8583
     TOTAL: 14

Grandes chances desse arquivo ser sequencial, podemos notar isso pelos blocos diretos.

Recuperando o arquivo

Vamos agora a sequência de comandos para recuperar o arquivo:

# dd bs=1k if=/dev/hda5 count=12 skip=8314 > /mnt/recovered.001

 

Agora o próximo bloco é o inode 8026, é um bloco indireto, então:

# dd bs=1k if=/dev/hda5 count=256 skip=8327 \>\> /mnt/recovered.001

O último bloco é o inode 8583. Ainda me parece amigável quanto a continuidade do arquivo (sem fragmentação). Temos que ignorar os blocos iniciais, por que não nos interessão aqui, são listas que foram zeradas quando o arquivo foi apagado e como estamos considerando que o arquivo está em modo sequencial, podemos ignorar:

# dd bs=1k if=/dev/hda5 count=256 skip=8585 \>\> /mnt/recovered.001
#dd bs=1k if=/dev/hda5 count=256 skip=8842 \>\> /mnt/recovered.001
#dd bs=1k if=/dev/hda5 count=256 skip=9099 \>\> /mnt/recovered.001
#dd bs=1k if=/dev/hda5 count=256 skip=9356 \>\> /mnt/recovered.001
#dd bs=1k if=/dev/hda5 count=256 skip=9613 \>\> /mnt/recovered.001
#dd bs=1k if=/dev/hda5 count=256 skip=9870 \>\> /mnt/recovered.001
 

Com isso concluimos que escrevemos no total 12 + (7 * 256) blocks, 1804. O comando 'stat' nos mostrou 3616, basta perceber que os blocos mostrados são de 512 bytes, então 3616/2 = 1808 blocos de 1024 bytes. Isso significa que faltam apenas 4 bytes para recompor perfeitamente o arquivo. Então precisamos incluir mais um bloco indireto. O último incluido foi 10125, pulamos o 10126 e continuamos como antes, mas para agora somente 4 bytes:

# dd bs=1k if=/dev/hda5 count=4 skip=10127 \>\> /mnt/recovered.001

Se tivermos sorte, esse arquivo foi recuperado com sucesso.

Vamos agora fazer uma breve descrição do primeiro método. Recomendamos não utilizar esse método. Ele é mais fácil, porém não é capaz de recuperar arquivos acima de 12 blocos.

Para cada inode que você queira recuperar, você precisa setar o link count para 1 e setar o deletion para 0. Você faz isso usando o 'mi', um comando do debugfs. Veja o exemplo para o inode 148003.

    debugfs: mi <148003>
     Mode [0100644]
     User ID [503]
     Group ID [100]
     Size [6065]
     Creation time [833201524]
     Modification time [832708049]
     Access time [826012887]
     Deletion time [833201524] 0
     Link count [0] 1
     Block count [12]
     File flags [0x0]
     Reserved1 [0]
     File acl [0]
     Directory acl [0]
     Fragment address [0]
     Fragment number [0]
     Fragment size [0]
     Direct Block #0 [594810]
     Direct Block #1 [594811]
     Direct Block #2 [594814]
     Direct Block #3 [594815]
     Direct Block #4 [594816]
     Direct Block #5 [594817]
     Direct Block #6 [0]
     Direct Block #7 [0]
     Direct Block #8 [0]
     Direct Block #9 [0]
     Direct Block #10 [0]
     Direct Block #11 [0]
     Indirect Block [0]
     Double Indirect Block [0]
     Triple Indirect Block [0]
     

Mude o Link Count para 1 o Deletion time para 0, e aperte enter para os outros campos. Isso é pouco usual se você possui muitos arquivos para recuperar. Após fazer essas mudanças, você precisa executar:

# e2fsck -f /dev/hda5
 

Assim os inodes agora modificados precisam reaparecer, e eles reapareceram no diretório /lost+found da sua particação. Provavelmente o e2fsck irá mostrar algumas informações de danos e etc, responda yes para todas.

Conclusão

Esse texto teve diversas referências, mas sobretudo o documento (Ext2fs-Undeletion) escrito por Aaron Crane.

Isso é tudo pessoal, qualquer dúvida entrem em contato!