I file sovrascritti possono essere recuperati?


42

Non sto parlando di recuperare file cancellati , ma di file sovrascritti . Vale a dire con i seguenti metodi:

# move
mv new_file old_file

# copy
cp new_file old_file

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

È possibile recuperare qualcosa se viene eseguita una qualsiasi delle tre azioni sopra presupponendo che non siano installati programmi speciali sulla macchina linux?


4
Intendi oltre ai tuoi backup?
Jasonwryan,

@jasonwryan, sì, certo.
Domanda Overflow

2
Voglio solo sottolineare che il tuo primo esempio ( mv) è simile all'eliminazione old_file, non alla sovrascrittura, quindi in questo caso si applicherebbero i metodi (se presenti) per il recupero dei file eliminati, anziché i file sovrascritti. Gli altri due esempi in effetti sovrascrivono uno esistente old_filee existing_file, rispettivamente.
Celada,

Tutti e tre gli esempi forniti vengono implementati eliminando tutti i blocchi di dati del file originale e scrivendoli in blocchi appena allocati, e la procedura per il ripristino di tali dati è la stessa del recupero di un file eliminato. Un'eccezione potrebbe essere se i file originali sono estremamente corti (inferiori a 60 byte su ext4) in cui gli ultimi due esempi probabilmente rendono i dati precedenti irrecuperabili.
Mark Plotnick,

1
@MarkPlotnick, secondo il commento di Celada, mvè diverso.
Domanda Overflow

Risposte:


60

La risposta è "Probabilmente sì, ma dipende dal tipo di filesystem e dai tempi".

Nessuno di questi tre esempi sovrascriverà i blocchi di dati fisici di file_vecchio o file_esistente, se non per caso.

  • mv new_file old_file. Questo scollegherà old_file. Se sono presenti ulteriori collegamenti fisici a old_file, i blocchi rimarranno invariati nei collegamenti rimanenti. Altrimenti, i blocchi saranno generalmente (dipende dal tipo di filesystem) inseriti in un elenco libero. Quindi, se ciò mvrichiede la copia (invece di spostare semplicemente le voci della directory), i nuovi blocchi verranno allocati come mvscritture.

    Questi blocchi appena allocati possono essere o meno gli stessi che sono stati appena liberati . Su filesystem come UFS , i blocchi sono allocati, se possibile, dallo stesso gruppo di cilindri della directory in cui è stato creato il file. Quindi c'è una possibilità che scollegare un file da una directory e creare un file in quella stessa directory riutilizzerà ( e sovrascrivere) alcuni degli stessi blocchi che sono stati appena liberati. Questo è il motivo per cui il consiglio standard alle persone che rimuovono accidentalmente un file è di non scrivere nuovi dati nei file nella loro struttura di directory (e preferibilmente non nell'intero filesystem) fino a quando qualcuno non può tentare il recupero dei file.

  • cp new_file old_filefarà quanto segue (è possibile utilizzare straceper vedere le chiamate di sistema):

    open ("old_file", O_WRONLY | O_TRUNC) = 4

    Il flag O_TRUNC causerà la liberazione di tutti i blocchi di dati, proprio come mvsopra. E come sopra, verranno generalmente aggiunti a un elenco gratuito e potrebbero o meno essere riutilizzati dalle successive scritture eseguite dal cpcomando.

  • vi existing_file. In caso viaffermativo vim, il :xcomando procede come segue:

    unlink ("isting_file ~ ") = -1 ENOENT (nessun file o directory)
    rinomina ("isting_file ", "isting_file ~") = 0
    aperto ("isting_file ", O_WRONLY | O_CREAT | O_TRUNC, 0664) = 3

    Quindi non rimuove nemmeno i vecchi dati; i dati sono conservati in un file di backup.

    Su FreeBSD, lo vifa open("existing_file",O_WRONLY|O_CREAT|O_TRUNC, 0664), che avrà la stessa semantica di cui cpsopra.


È possibile recuperare alcuni o tutti i dati senza programmi speciali; tutto ciò che serve è grepe dd, e l'accesso al dispositivo raw.

Per file di testo di piccole dimensioni, il modo più semplice è il singolo grepcomando nella risposta di @Steven D alla domanda a cui sei collegato:

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

Ma per file più grandi che possono trovarsi in più blocchi non contigui, faccio questo:

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

che ti darà l'offset in byte della linea corrispondente. Seguilo con una serie di ddcomandi, a partire da

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

Dovresti anche leggere alcuni blocchi prima e dopo quel blocco. Su UFS, i blocchi di file sono in genere 8 KB e vengono allocati in modo abbastanza contiguo, i blocchi di un singolo file vengono alternati alternativamente con blocchi di 8 KB da altri file o spazio libero. La coda di un file su UFS è composta da un massimo di 7 frammenti da 1 KB, che possono essere o meno contigui.

Ovviamente, sui file system che comprimono o crittografano i dati, il ripristino potrebbe non essere così semplice.


Esistono pochissime utility in Unix che sovrascriveranno i blocchi di dati di un file esistente. Uno che viene in mente è dd conv=notrunc. Un altro è shred.


3
Grazie per aver spiegato la meccanica interna delle tre diverse operazioni. Questo è davvero utile!
Domanda Overflow

btrfsè abbastanza resistente ai file eliminati. Tende a utilizzare i blocchi in modo round robin, quindi se si dispone di spazio sufficiente sul dispositivo, il file non verrà sovrascritto per lungo tempo. Vedi qui
pqnet,

come ottenere il blocco di testo precedente e cosa fa skip?
unixit,

@Islam Quando dai a dd il skip=parametro, invece di leggere dall'inizio dell'input salterà quel numero di blocchi. Un blocco è 512 byte per impostazione predefinita, ma può essere modificato con il bs=parametro.
Mark Plotnick,

1
@Islam Per ottenere il blocco di testo precedente, suggerirei di assegnare un skip=valore inferiore di 1 blocco (512 byte). Nel mio esempio $(expr 13813610612 / 512 - 1),. Se questo non ottiene ciò che desideri, riprova mentre sottrai 16 o 32, che esaminerà le aree che sono 8192 e 16384 byte in meno; i file sono spesso allocati in blocchi di 8192 byte. Se stai cercando di recuperare un file più grande, prova conteggio più grande per risparmiare tempo. Di solito uso count=16e guardo il risultato in un editor come a emacscui non importa se alcuni dei dati non sono testo.
Mark Plotnick,

6

Sto per dire di no (con un asterisco gigante).

Pensa a come vengono posizionati i dati su un disco. Hai blocchi che contengono dati e puntano al blocco successivo (se ce n'è uno).

Quando si sovrascrivono i dati, si modificano i contenuti del blocco (e se si sta estendendo il file tutto il marcatore finale). Quindi nulla dovrebbe essere in grado di essere recuperato (vedi sotto).

Se accorcia il file, perdi i vecchi blocchi e presto saranno riciclati. Se sei un programmatore, pensa a un elenco collegato in cui "perdi" metà dell'elenco senza effettuare una cancellazione / eliminazione gratuita. Quei dati sono ancora lì, ma buona fortuna trovarli.

Qualcosa che potrebbe essere interessante a cui pensare è la frammentazione.

La frammentazione si verifica quando sul disco sono presenti "buchi" di dati non contigui. Ciò può essere causato modificando i file in modo da estenderli o accorciarli e che non si adattano più alla loro posizione originale sul disco.

Nel caso in cui un file superi le dimensioni originali (a questo punto deve spostarsi), a seconda del file system è possibile copiare l'intero file in una nuova posizione in cui i vecchi dati sarebbero ancora presenti (ma contrassegnati come liberi) oppure basta cambiare il vecchio puntatore finale e farlo puntare a una nuova posizione (questo porterà a un thrashing).

Per farla breve, i tuoi dati sono probabilmente persi (senza passare attraverso un processo forense estremo in cui li guardi al microscopio); tuttavia, c'è la possibilità che sia ancora lì.


1
La tua risposta presuppone che sia in uso un filesystem non-copy-on-write basato su blocchi come ext4o xfs. Con la copia su file system di scrittura come zfse btrfsdi fatto non si "modifica il contenuto del blocco"; quei filesystem usano sempre blocchi nuovi per contenere nuovi dati. Inoltre, i filesystem basati su log come jffs2sempre scrivono sempre nuovi dati in nuove posizioni (non "blocchi", quei filesystem non sono basati su blocchi). Detto questo, ciò non significa che sia facile trovare dove vivono i vecchi dati e farlo prima che lo spazio venga riciclato. Quindi la tua risposta, che è no, è ancora corretta
Celada,

@Celada Grazie! L'ho trovato molto istruttivo. Non ho avuto il tempo di vedere come funziona btrfs o zfs, ma sapevo che esistono.
SailorCire,

2

Assicurati di avere abbastanza spazio su disco in / var / tmp o in qualche posto grande.

Provare

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

dove / dev / sda1 sarebbe il tuo disco sul tuo sistema.

Quindi cerca il mio file recuperato per la tua stringa.

Si potrebbe in gran parte essere lì, Se lo trovate verificare la presenza di dispersi linespaces, staffe, ecc sysmbols

Usa una parola di ricerca dal tuo file che è abbastanza inequivocabile o stringa che ridurrà la quantità di dati nel file. Se cerchi una parola come "echo" otterrai un sacco di stringhe poiché il sistema avrà molti file con la parola echo in esse.


0

Avevo sovrascritto un file di testo (VQ1.txt) con dati di test del valore di 12 ore :( Un'idea che unix salva la versione precedente del file in formato text.txt ~, mi ha fatto guardare nella cartella contenente il file sovrascritto con $ -ll Full l'elenco mostrava VQ1.txt ~ che aveva i miei dati "persi"!

$ 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

4
Non è più una caratteristica di alcuni editor di testo invece di Unix in generale? Non sono a conoscenza di un file system che salvi le vecchie versioni dei file in quel modo.
Joey,

0

TL; DR - Se il file sovrascritto viene ancora tenuto aperto da un processo in esecuzione, questo post del blog potrebbe salvare la tua pancetta:

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

In esso, parla di file cancellati , ma ho avuto buona fortuna con esso anche con un file che è stato sovrascritto da rsync. E sto parlando di un file da 60 GB sovrascritto da uno da 4 MB e sono stato in grado di recuperare l'originale perché per fortuna non avevo fermato il processo in esecuzione che lo teneva aperto.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.