Czy zastąpione pliki można odzyskać?


42

Nie mówię o odzyskiwaniu usuniętych plików , ale nadpisane pliki. Mianowicie następującymi metodami:

# move
mv new_file old_file

# copy
cp new_file old_file

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

Czy jest możliwe odzyskanie czegokolwiek, jeśli którakolwiek z powyższych trzech czynności zostanie wykonana przy założeniu, że na komputerze z systemem Linux nie są zainstalowane żadne specjalne programy?


4
Masz na myśli oprócz kopii zapasowych?
jasonwryan

@jasonwryan, tak, oczywiście.
Przepełnienie pytania,

2
Chcę tylko zaznaczyć, że twój pierwszy przykład ( mv) przypomina usuwanie old_file, a nie zastępowanie go, więc w takim przypadku zastosowanie miałyby metody (jeśli istnieją) odzyskiwania plików usuniętych, w przeciwieństwie do plików zastąpionych. Pozostałe dwa przykłady rzeczywiście zastępują odpowiednio istniejące old_filei existing_fileodpowiednio.
Celada,

Wszystkie trzy podane przez Ciebie przykłady zostały zaimplementowane poprzez usunięcie wszystkich bloków danych oryginalnego pliku i zapisanie ich w nowo przydzielonych blokach, a procedura odzyskiwania tych danych jest taka sama jak w przypadku odzyskiwania usuniętego pliku. Wyjątkiem może być sytuacja, gdy oryginalne pliki są wyjątkowo krótkie (krótsze niż 60 bajtów na ext4), gdzie dwa ostatnie przykłady prawdopodobnie uniemożliwiają odzyskanie poprzednich danych.
Mark Plotnick,

1
@MarkPlotnick, zgodnie z komentarzem Celady, mvjest inny.
Pytanie Przepełnienie

Odpowiedzi:


60

Odpowiedź brzmi: „Prawdopodobnie tak, ale zależy to od typu systemu plików i czasu”.

Żaden z tych trzech przykładów nie zastąpi fizycznych bloków danych starego_pliku lub istniejącego_pliku, z wyjątkiem przypadku.

  • mv new_file old_file. To rozłączy stary plik. Jeśli istnieją dodatkowe twarde linki do old_file, bloki pozostaną niezmienione w pozostałych linkach. W przeciwnym razie bloki będą na ogół (w zależności od typu systemu plików) umieszczone na wolnej liście. Następnie, jeśli mvwymaga kopiowania (w przeciwieństwie do tylko przenoszenia pozycji katalogu), nowe bloki zostaną przydzielone jako mvzapisy.

    Te nowo przydzielone bloki mogą, ale nie muszą być tymi samymi, które zostały właśnie uwolnione . W systemach plików, takich jak UFS , bloki są przydzielane, jeśli to możliwe, z tej samej grupy cylindrów, co katalog, w którym plik został utworzony. Istnieje więc szansa, że ​​połączenie pliku z katalogu i utworzenie pliku w tym samym katalogu zostanie ponownie wykorzystane ( i nadpisują) niektóre z tych samych bloków, które właśnie zostały uwolnione. Dlatego standardową poradą dla osób, które przypadkowo usuną plik, jest nie zapisywanie żadnych nowych danych w plikach w drzewie katalogów (a najlepiej nie w całym systemie plików), dopóki ktoś nie spróbuje odzyskać pliku.

  • cp new_file old_filewykona następujące czynności (możesz użyć, straceaby zobaczyć wywołania systemowe):

    open („stary_plik”, O_WRONLY | O_TRUNC) = 4

    Flaga O_TRUNC spowoduje zwolnienie wszystkich bloków danych, podobnie jak mvpowyżej. I jak wyżej, będą one generalnie dodawane do darmowej listy i mogą, ale nie muszą, zostać ponownie wykorzystane przez kolejne zapisy wykonane przez cppolecenie.

  • vi existing_file. Jeśli vitak vim, to :xpolecenie wykonuje następujące czynności:

    unlink ("exist_file ~") = -1 ENOENT (Brak takiego pliku lub katalogu)
    rename („istniejący_plik”, „istniejący_plik ~”) = 0
    open („plik_istniejący”, O_WRONLY | O_CREAT | O_TRUNC, 0664) = 3

    Więc nawet nie usuwa starych danych; dane są przechowywane w pliku kopii zapasowej.

    Na FreeBSD, virobi open("existing_file",O_WRONLY|O_CREAT|O_TRUNC, 0664), który będzie miał taką samą semantykę jak cppowyżej.


Możesz odzyskać część lub całość danych bez specjalnych programów; Wszystko czego potrzebujesz to grepi dd, a dostęp do urządzenia surowego.

W przypadku małych plików tekstowych jedno greppolecenie w odpowiedzi z @Steven D w pytaniu, do którego się łączysz, jest najprostszym sposobem:

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

Ale w przypadku większych plików, które mogą znajdować się w wielu nieciągłych blokach, robię to:

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

co da ci przesunięcie w bajtach pasującej linii. Postępuj zgodnie z serią ddpoleceń, zaczynając od

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

Chciałbyś również przeczytać kilka bloków przed i po tym bloku. W systemie plików UFS bloki plików mają zwykle rozmiar 8 KB i zwykle są przydzielane dość ściśle, bloki jednego pliku są przeplatane naprzemiennie z blokami 8 KB z innych plików lub wolnej przestrzeni. Ogon pliku na UFS ma do 7 fragmentów 1 KB, które mogą, ale nie muszą być ciągłe.

Oczywiście w systemach plików kompresujących lub szyfrujących dane odzyskiwanie może nie być takie proste.


W Uniksie jest tak naprawdę niewiele narzędzi, które zastąpią bloki danych istniejącego pliku. Przychodzi mi na myśl jedna dd conv=notrunc. Innym jest shred.


3
Dziękujemy za wyjaśnienie wewnętrznej mechaniki trzech różnych operacji. To jest naprawdę przydatne!
Przepełnienie pytania

btrfsjest dość odporny na usunięte pliki. Zwykle używa bloków w sposób okrągły, więc jeśli masz wystarczająco dużo miejsca na urządzeniu, plik nie zostanie nadpisany przez długi czas. Zobacz tutaj
pqnet

jak uzyskać poprzedzający blok tekstowy i co robi pominięcie?
unixit

@Islam Gdy podasz skip=parametr dd , to zamiast czytać od początku wejścia, pominie tę liczbę bloków. Blok ma domyślnie 512 bajtów, ale można go zmienić za pomocą bs=parametru.
Mark Plotnick

1
@Islam Aby uzyskać poprzedni blok tekstowy, sugerowałbym podanie skip=wartości, która jest o 1 blok (512 bajtów) mniejsza. W moim przykładzie $(expr 13813610612 / 512 - 1). Jeśli to nie pomoże, spróbuj jeszcze raz, odejmując 16 lub 32, co pozwoli spojrzeć na obszary o 8192 i 16384 bajtów mniej; pliki są często przydzielane w 8192-bajtowych porcjach. Jeśli próbujesz odzyskać większy plik, wypróbuj większą liczbę, aby zaoszczędzić czas. Zwykle używam count=16i patrzę na wynik w edytorze, emacsktóry nie ma nic przeciwko, jeśli niektóre dane nie są tekstem.
Mark Plotnick

6

Powiem „nie” (z wielką gwiazdką).

Zastanów się, jak dane są układane na dysku. Masz bloki, które zawierają dane i wskazują następny blok (jeśli taki istnieje).

Kiedy nadpisujesz dane, zmieniasz zawartość bloku (a jeśli rozszerzasz plik cały znacznik końcowy). Więc nic nie powinno być w stanie odzyskać (patrz poniżej).

Jeśli skrócisz plik, tracisz stare bloki i wkrótce zostaną one poddane recyklingowi. Jeśli jesteś programistą, pomyśl o połączonej liście, w której „zgubisz” połowę listy bez wykonywania operacji usuwania / usuwania. Te dane wciąż istnieją, ale powodzenia w ich znalezieniu.

Warto zastanowić się nad fragmentacją.

Fragmentacja występuje, gdy na dysku znajdują się „dziury” niesąsiadujące dane. Może to być spowodowane modyfikacją plików, tak aby je rozszerzyć lub skrócić i nie mieszczą się już w oryginalnym miejscu na dysku.

Jeśli plik przekroczy swój pierwotny rozmiar (w tym momencie musi się przenieść), w zależności od systemu plików możesz skopiować cały plik do nowej lokalizacji, w której nadal byłyby stare dane (ale oznaczone jako wolne) lub po prostu zmienisz stary wskaźnik zakończenia i wskażesz nową lokalizację (doprowadzi to do przeładowania).

Krótko mówiąc, twoje dane są prawdopodobnie utracone (bez przechodzenia przez ekstremalny proces sądowy, w którym patrzysz na nie pod mikroskopem); istnieje jednak szansa, że ​​nadal tam jest.


1
Twoja odpowiedź zakłada, że używany jest oparty na blokach system plików, który nie jest przeznaczony do kopiowania przy zapisie, taki jak ext4lub xfs. Z kopiowaniem przy zapisywaniu systemów plików takich jak zfsi btrfstak naprawdę nigdy nie „zmieniasz zawartości bloku”; te systemy plików zawsze używają zupełnie nowych bloków do przechowywania nowych danych. Również systemy plików oparte na logach, takie jak jffs2zawsze, zawsze zapisują nowe dane w nowych lokalizacjach (nie „blokach”, te systemy plików nie są oparte na blokach). Biorąc to pod uwagę, nie oznacza to, że łatwo jest znaleźć miejsce, w którym znajdują się stare dane i zrobić to, zanim przestrzeń zostanie poddana recyklingowi. Więc twoja odpowiedź, która nie jest, jest wciąż poprawna
Celada,

@Celada Thanks! Uważam to za bardzo pouczające. Nie miałem czasu na sprawdzenie, jak działają btrfs lub zfs, ale wiedziałem, że istnieją.
SailorCire,

2

Upewnij się, że masz wystarczająco dużo miejsca na dysku w / var / tmp lub gdzieś dużym.

Próbować

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

gdzie / dev / sda1 będzie twoim dyskiem w twoim systemie.

Następnie wyszukaj mój ciąg odzyskanego pliku.

To może przede wszystkim tam, Jeśli okaże się to sprawdzić brakuje linespaces, wsporniki, sysmbols etc.

Użyj słowa wyszukiwania z pliku, które jest dość niepotrzebne, lub ciągu, który zmniejszy ilość danych w pliku. Jeśli wyszukasz słowo takie jak „echo”, odzyskasz mnóstwo ciągów znaków, ponieważ system będzie zawierał wiele plików z wyrazem echo.


0

Zastąpiłem plik tekstowy (VQ1.txt) danymi testowymi wartymi 12 godzin :( Idea, że ​​Unix zapisuje poprzednią wersję pliku w formacie text.txt ~, sprawiła, że ​​zajrzałem do folderu zawierającego nadpisany plik z $ -ll Full lista pokazała VQ1.txt ~, który zawierał moje „utracone” dane!

$ 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
Czy nie jest to raczej cecha niektórych edytorów tekstu zamiast ogólnie Uniksa? Nie znam systemu plików, który zapisuje w ten sposób stare wersje plików.
Joey,

0

TL; DR - Jeśli nadpisany plik jest nadal utrzymywany przez uruchomiony proces, ten post na blogu może zapisać bekon:

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

Mówi w nim o usuniętych plikach, ale miałem szczęście, nawet z plikiem, który został zastąpiony przez rsync. Mówię o pliku o pojemności 60 GB, który został zastąpiony plikiem o rozmiarze 4 MB, i mogłem odzyskać oryginał, ponieważ na szczęście nie zatrzymałem trwającego procesu, który go utrzymywał.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.