¿Se pueden recuperar archivos sobrescritos?


42

No estoy hablando de recuperar archivos borrados , sino de archivos sobrescritos . A saber por los siguientes métodos:

# move
mv new_file old_file

# copy
cp new_file old_file

# edit
vi existing_file
> D
> i new_content
> :x

¿Es posible recuperar algo si alguna de las tres acciones anteriores se realiza suponiendo que no hay programas especiales instalados en la máquina Linux?


44
¿Quieres decir aparte de tus copias de seguridad?
jasonwryan

@jasonwryan, sí, por supuesto.
Desbordamiento de preguntas el

2
Solo quiero señalar que su primer ejemplo ( mv) es similar a eliminar old_file, no sobrescribir, por lo que los métodos (si existen) para recuperar archivos eliminados, a diferencia de los archivos sobrescritos, se aplicarían en ese caso. Sus otros dos ejemplos de hecho sobrescriben un existente old_filey existing_file, respectivamente.
Celada

Los tres ejemplos que proporcionó se implementan eliminando todos los bloques de datos del archivo original y escribiendo en bloques asignados recientemente, y el procedimiento para recuperar esos datos es lo mismo que recuperar un archivo eliminado. Una excepción podría ser si los archivos originales son extremadamente cortos (más cortos que 60 bytes en ext4) donde los dos últimos ejemplos probablemente hagan que los datos anteriores sean irrecuperables.
Mark Plotnick el

1
@ MarkPlotnick, según el comentario de Celada, mves diferente.
Desbordamiento de preguntas

Respuestas:


60

La respuesta es "Probablemente sí, pero depende del tipo de sistema de archivos y el momento".

Ninguno de esos tres ejemplos sobrescribirá los bloques de datos físicos del archivo antiguo o el archivo existente, excepto por casualidad.

  • mv new_file old_file. Esto desvinculará old_file. Si hay enlaces duros adicionales a old_file, los bloques permanecerán sin cambios en los enlaces restantes. De lo contrario, los bloques generalmente (depende del tipo de sistema de archivos) se colocarán en una lista libre. Luego, si se mvrequiere copiar (en lugar de solo mover las entradas del directorio), los nuevos bloques se asignarán como mvescrituras.

    Estos bloques recién asignados pueden o no ser los mismos que fueron liberados . En sistemas de archivos como UFS , los bloques se asignan, si es posible, desde el mismo grupo de cilindros que el directorio en el que se creó el archivo. Por lo tanto, existe la posibilidad de que desvincular un archivo de un directorio y crear un archivo en ese mismo directorio se reutilice ( y sobrescribir) algunos de los mismos bloques que acaban de liberarse. Es por eso que el consejo estándar para las personas que eliminan accidentalmente un archivo es que no escriban datos nuevos en los archivos de su árbol de directorios (y preferiblemente no en todo el sistema de archivos) hasta que alguien pueda intentar la recuperación del archivo.

  • cp new_file old_filehará lo siguiente (puede usar stracepara ver las llamadas al sistema):

    abierto ("archivo_viejo", O_WRONLY | O_TRUNC) = 4

    El indicador O_TRUNC hará que se liberen todos los bloques de datos, tal como se mvhizo anteriormente. Y como se indicó anteriormente, generalmente se agregarán a una lista gratuita, y pueden o no ser reutilizados por las escrituras posteriores realizadas por el cpcomando.

  • vi existing_file. Si vies realmente vim, el :xcomando hace lo siguiente:

    unlink ("existente_file ~") = -1 ENOENT (No existe tal archivo o directorio)
    renombrar ("archivo_existente", "archivo_existente ~") = 0
    abierto ("existente_archivo", O_WRONLY | O_CREAT | O_TRUNC, 0664) = 3

    Por lo tanto, ni siquiera elimina los datos antiguos; Los datos se conservan en un archivo de copia de seguridad.

    En FreeBSD, vidoes open("existing_file",O_WRONLY|O_CREAT|O_TRUNC, 0664), que tendrá la misma semántica que la cpanterior.


Puede recuperar algunos o todos los datos sin programas especiales; todo lo que necesita es grepy dd, y acceso al dispositivo sin formato.

Para archivos de texto pequeños, el grepcomando único en la respuesta de @Steven D en la pregunta a la que se vinculó es la forma más fácil:

grep -i -a -B100 -A100 'text in the deleted file' /dev/sda1

Pero para archivos más grandes que pueden estar en múltiples bloques no contiguos, hago esto:

grep -a -b "text in the deleted file" /dev/sda1
13813610612:this is some text in the deleted file

que le dará el desplazamiento en bytes de la línea correspondiente. Siga esto con una serie de ddcomandos, comenzando con

dd if=/dev/sda1 count=1 skip=$(expr 13813610612 / 512)

También querrás leer algunos bloques antes y después de ese bloque. En UFS, los bloques de archivos generalmente son de 8 KB y generalmente se asignan de manera bastante contigua, los bloques de un solo archivo se intercalan alternativamente con bloques de 8 KB de otros archivos o espacio libre. La cola de un archivo en UFS tiene hasta 7 fragmentos de 1 KB, que pueden ser contiguos o no.

Por supuesto, en los sistemas de archivos que comprimen o encriptan datos, la recuperación podría no ser tan sencilla.


En realidad, hay muy pocas utilidades en Unix que sobrescriban los bloques de datos de un archivo existente. Uno que viene a la mente es dd conv=notrunc. Otro es shred.


3
Gracias por explicar la mecánica interna de las tres operaciones diferentes. ¡Esto es realmente útil!
Desbordamiento de preguntas

btrfses bastante resistente a los archivos eliminados. Tiende a usar bloques de forma circular, por lo que si tiene suficiente espacio en el dispositivo, el archivo no se sobrescribirá durante mucho tiempo. Ver aquí
pqnet

¿Cómo obtener el bloque de texto anterior y qué hace saltar?
unixit

@Islam Cuando le da a dd el skip=parámetro, en lugar de leerlo desde el principio de la entrada, omitirá ese número de bloques. Un bloque tiene 512 bytes por defecto, pero se puede cambiar con el bs=parámetro.
Mark Plotnick

1
@Islam Para obtener el bloque de texto anterior, sugeriría dar un skip=valor que sea 1 bloque (512 bytes) menos. En mi ejemplo $(expr 13813610612 / 512 - 1),. Si eso no obtiene lo que desea, intente nuevamente mientras resta 16 o 32, que examinará las áreas que son 8192 y 16384 bytes menos; los archivos a menudo se asignan en fragmentos de 8192 bytes. Si está intentando recuperar un archivo más grande, intente conteos más grandes para ahorrar tiempo. Usualmente uso count=16y miro el resultado en un editor como el emacsque no le importa si algunos de los datos no son texto.
Mark Plotnick

6

Voy a decir que no (con un asterisco gigante).

Piense en cómo se almacenan los datos en un disco. Tiene bloques que contienen datos y apuntan al siguiente bloque (si hay uno).

Cuando sobrescribe datos, está cambiando el contenido del bloque (y si está extendiendo el archivo todo el marcador final). Por lo tanto, nada debería poder recuperarse (ver más abajo).

Si acorta el archivo, está perdiendo los bloques antiguos y pronto se reciclarán. Si usted es un programador, piense en una lista vinculada en la que "pierde" la mitad de su lista sin hacer una descarga / eliminación gratuita. Esa información todavía está ahí, pero buena suerte para encontrarla.

Algo que puede ser interesante pensar es la fragmentación.

La fragmentación se produce cuando tiene "agujeros" de datos no contiguos en su disco. Esto puede deberse a la modificación de archivos de modo que los extienda o acorte y ya no quepan en su lugar original en el disco.

En el caso de que un archivo crezca más allá de su tamaño original (necesita moverse en este punto), dependiendo de su sistema de archivos, puede copiar todo el archivo a una nueva ubicación donde los datos antiguos aún estarían allí (pero marcados como libres) o simplemente cambia el puntero final anterior y hace que apunte a una nueva ubicación (esto provocará una paliza).

En resumen, sus datos probablemente se pierdan (sin pasar por un proceso forense extremo en el que los mira bajo un microscopio); Sin embargo, existe la posibilidad de que todavía esté allí.


1
Su respuesta hace la suposición de que un sistema de archivos basado en bloques no copia en escritura como ext4o xfsestá en uso. Con copia en sistemas de archivos de escritura como zfsy btrfs, de hecho, nunca está "cambiando el contenido del bloque"; esos sistemas de archivos siempre usan bloques nuevos para contener nuevos datos. Además, los sistemas de archivos basados ​​en registros como jffs2siempre también escriben datos nuevos en nuevas ubicaciones (no "bloques", esos sistemas de archivos no están basados ​​en bloques). Dicho esto, esto no significa que sea fácil encontrar dónde viven los datos antiguos y hacerlo antes de reciclar el espacio. Entonces su respuesta, que es no, sigue siendo correcta
Celada

@Celada ¡Gracias! Eso me pareció muy informativo. No he tenido tiempo de ver cómo funcionan btrfs o zfs, pero sabía que existían.
SailorCire

2

Asegúrese de tener suficiente espacio en disco en / var / tmp o en algún lugar grande.

Tratar

 grep -i -a -B100 -A100 'a string unique to your file' /dev/sda1 |
 strings > /var/tmp/my-recovered-file

donde / dev / sda1 sería su disco en su sistema.

Luego busque mi archivo recuperado para su cadena.

En su mayoría, puede estar allí. Si lo encuentra, compruebe si faltan espacios de líneas, corchetes, símbolos, etc.

Use una palabra de búsqueda de su archivo que sea bastante única o una cadena que reducirá la cantidad de datos en el archivo. Si busca una palabra como "echo", obtendrá muchas cadenas, ya que el sistema tendrá muchos archivos con la palabra echo en ellas.


0

Había sobrescrito un archivo de texto (VQ1.txt) con 12 horas de datos de prueba :( Una noción de que Unix guarda la versión anterior del archivo en formato text.txt ~, me hizo buscar en la carpeta que contiene el archivo sobrescrito con $ -ll Full ¡La lista mostró VQ1.txt ~ que tenía mis datos 'perdidos'!

$ cat VQ1.txt~  
Start time at: Thu Apr  2 18:07:23 PDT 2015
User, KW: 12hrFA_OEM_HelloVoiceQ
Test Case: 
Detection:  1, 1, 04-03 01:07:00.673 D/MultiKeywordBdctReceiver( 1743): vs status 258 : 2 : 1
Detection:  2, 1, 04-03 01:09:04.813 D/MultiKeywordBdctReceiver( 1743): vs status 258 : 2 : 1
Detection:  3, 1, 04-03 04:09:26.023 D/MultiKeywordBdctReceiver( 1743): vs status 258 : 2 : 1
Detection:  4, 1, 04-03 04:11:29.893 D/MultiKeywordBdctReceiver( 1743): vs status 258 : 2 : 1
Detection:  5, 1, 04-03 07:12:27.013 D/MultiKeywordBdctReceiver( 1743): vs status 258 : 2 : 1
Detection:  6, 1, 04-03 07:14:30.803 D/MultiKeywordBdctReceiver( 1743): vs status 258 : 2 : 1
Detection:  7, 1, 04-03 08:37:13.113 D/MultiKeywordBdctReceiver( 1743): vs status 258 : 2 : 1
Detection:  8, 1, 04-03 10:21:23.533 D/MultiKeywordBdctReceiver( 1743): vs status 258 : 2 : 1
Detection:  9, 1, 04-03 10:23:27.733 D/MultiKeywordBdctReceiver( 1743): vs status 258 : 2 : 1
Detection:  10, 1, 04-03 13:23:47.893 D/MultiKeywordBdctReceiver( 1743): vs status 258 : 2 : 1
Detection:  11, 1, 04-03 13:25:52.203 D/MultiKeywordBdctReceiver( 1743): vs status 258 : 2 : 1

12hrFA_OEM_HelloVoiceQ,  
KW detect count: 11

44
¿No es más una característica de ciertos editores de texto en lugar de Unix en general? No conozco un sistema de archivos que guarde versiones antiguas de archivos de esa manera.
Joey

0

TL; DR: si el archivo sobrescrito aún se mantiene abierto por un proceso en ejecución, entonces esta publicación de blog podría guardar su tocino:

https://www.linux.com/news/bring-back-deleted-files-lsof/

En él, habla de archivos eliminados , pero tuve buena suerte incluso con un archivo que fue sobrescrito por rsync. Y estoy hablando de un archivo de 60 GB sobrescrito por uno de 4 MB, y pude recuperar el original porque afortunadamente no había detenido el proceso de ejecución que lo mantenía abierto.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.