blog.garaż.net

16 wrzesień 2007

Odzyskiwanie zdjęć

Każdemu może się czasami zdarzyć, że przez przypadek usunie zdjęcia... na szczęście nie mnie to spotkało (odpukać), ale mojego tatę, który kliknął o jeden raz za dużo na swoim nowym cyfraku.

Ale mniejsza o historię, postarajmy się coś odzyskać! Uprzedzam jednak, że sposób jest makabrycznie naiwny i lekko zawiły, wykorzystamy prosty program w C, skrypt Basha, narzędzie dd, zestaw ImageMagick oraz trochę wiedzy na temat formatu JPEG. :)

Drobna uwaga

Pamiętaj, że wszystko robisz tylko i wyłącznie na własną odpowiedzialność. Dołożyłem starań aby opisane tutaj rzeczy i programy działały poprawnie, ale nie biorę żadnej odpowiedzialności jeśli coś pójdzie nie tak, nie daję Ci także gwarancji, że cokolwiek uda Ci się dzięki temu JTZ uratować!

Czego potrzebujemy?

  • ImageMagick
  • kompilatora języka C (np. GCC standardowo dostępny w każdej dystrybucji)
  • Bash, inny interpreter skryptów, lub cierpliwość do ręcznego dłubania
  • aparatu\czytnika kart\przenośnego dysku widzianego w Linuksie jako dysk twardy - będziemy musieli dostać się bezpośrednio do systemu plików, oraz wiedzy na temat nazwy urządzenia (np. /dev/sda)
  • narzędzia dd (powinno być w standardzie)
  • uprawnień roota ;)

Jeśli jesteś posiadaczem standardowego pingwina powinieneś mieć już wszystko (no może oprócz ImageMagic, ale zapewne jest dostępny w standardowym repozytorium).

Zaczynamy

Pierwszy krok to skopiowanie całego systemu plików aparatu na dysk twardy. Warto to zrobić z conajmniej dwóch powodów, po pierwsze czytanie czegokolwiek z pamięci typu Flash może nie być zbyt szybkie, a może zajść potrzeba powtórzenia, któregoś z kroków, po drugie możesz wykonać kopię i spokojnie korzystać normalnie dalej z aparatu.

Aby wykonać kopię systemu plików zaloguj się jako root i następnie wykonaj komendę:

dd if=/dev/twoj_aparat of=/root/copy.img bs=1024K count=ile_MB

Zamiast /dev/twoj_aparat podajesz nazwę urządzenia, które reprezentuje sprzęt z naszymi fotami. Natomiast ile_MB to pojemność wyrażona w MB, najlepiej podać większą wartość od rzeczywistej pojemności karty pamięci czy wbudowanej pamięci aparatu, i tak zostanie skopiowana maksymalna możliwa ilość danych.

Jeśli nie wiesz jaka nazwa reprezentuje Twój aparat, ale system umie sam je wykryć i zamonotwać, wydaj komendę mount i odnajdź linię, w której widzisz odpowiedni punkt montowania (druga kolumna) - nazwa urządzenia znajduje się w pierwszej kolumnie.

Program przeszukujący

Napisałem prosty programik, który przeszukuje nasz skopiowany obraz pod kontem dwóch magicznych liczb specyficznych dla nagłówka pliku w formacie JPEG, jeśli natrafi na te dwie liczby zapisuje dokładnie 1MiB począwszy od tych liczb do pliku tymczasowego (test_numer.jpg). Tak duży zrzut powinien starczyć na pomieszczenie średniej wielkości zdjęcia (z powodzeniem stosowałem dla fotek o rozmiarze 1600x1200 pikseli). Tak przygotowane zrzuty można w sumie już przejrzeć programem graficznym, jeśli znajdują się w nim poprawne dane bez problemu obejrzymy sobie nasze zdjęcia, jeśli nie oznacza to, że nie trafiliśmy co jest zresztą dość prawdopodobne. ;)

Program można ściągnąć stąd: rec.c

Aby skompilować program do postaci wykonywalnej, zapisz powyższy plik razem, z wykonaną wcześniej kopią, a następnie przejdź do katalogu i wykonaj z konsoli:

gcc rec.c -o rec

Jeśli wszystko poszło dobrze, masz plik rec, który można uruchomić poleceniem:

./rec copy.img

W zależności od wielkości kopii przeszukiwanie może zająć trochę czasu, na ekranie będą pojawiać się informacje na temat ilości znalezionych "magicznych liczb" - nie wszystkie muszą oznaczać odzyskanie zdjęcia. Jeśli jesteś mało cierpliwy po zakończeniu przeszukiwania możesz przejrzeć pliki swoją ulubioną przeglądarką graficzną (np. Gqview, Mirage, Gthum, itd.), jeśli chcesz od razu odzielić poprawne zdjęcia od przypadkowo zrzuconych danych to skorzystaj z narzędzia convert będącego częścią pakietu ImageMagic, przy okazji sprawimy, że odcięte zostaną zbędne śmieci znajdujące się za plikiem, które także zostały zrzucone.

Skrypt dla Basha, który odziela poprawne zdjęcia i wywala śmieci z końca przy pomocy convert: rec.sh

Ściągnij skrypt i zapisz w katalogu wraz z copy.img oraz rec, następnie wykonaj polecenie:

bash rec.sh

i cierpliwie poczekaj aż poprawione fotki znajdą się w katalogu ok.

Na zakończenie

Wiem, że sposób jest "lekko" zakręcony, ale nie mogłem (czytaj nie chciało mi się ;)) znaleźć darmowego narzędzia, które potrafiłoby zrzucić fotki z uszkodzonego systemu pliku. Zdaję sobie sprawę, że sposób jest bardzo naiwny i nieskuteczny na mocno sfragmentowanych systemach plików (a który jest? :)), ale powinien świetnie się spisywać w przypadku gdy stracimy całkowicie tablicę alokacji plików lub nawet uszkodzeniu ulegnie tablica partycji, rodzaj systemu plików prawdopodobnie nie powinien sprawiać różnicy, sposób testowałem na razie jedynie na FAT. Przy drobnych poprawkach sposób powinien nadawać się do odzyskiwania danych dowolnego typu.

*[JTZ]: Jak To Zrobić

Komentarze

  • Grzegorz | grzglo.jogger.pl (2007-09-16 20:31:08):

    I pomyśleć, że pod Windowsa są dziesiątki programów z graficznym interfejsem, w których odzyskiwanie zdjęć polega na przyciśnięciu „Recover” i oglądaniu animacji obrazującej skanowanie lub odtwarzanie zdjęć ;P

    Jako, że mam i Ubuntu i Windowsa to jednak wybrałbym do tego zadania Windows.

  • Sebas86 (2007-09-16 20:33:50):

    I dokładnie prawie taka sama liczba jest płatna. ;)

  • Grzegorz | grzglo.jogger.pl (2007-09-16 20:35:50):

    @Seban – Te 30 dni na testowanie (którym zwykle dysponuje użytkownik płatnego programu) w zupełności pozwoliłoby mi odzyskać wszystkie zdjęcia nie tylko swoje ale i sąsiadów.

  • SebaS86 (2007-09-16 20:38:37):

    Nie chcę się kłócić o to, wczoraj kiedy miałem dostęp do kompa z Win przetestowałem może z trzy, więcej mi się nie chciało już o 3 nad ranem. :P Żaden z nich nie oferował więcej jak podgląd.

  • Grzegorz | grzglo.jogger.pl (2007-09-16 20:43:25):

    5 min. szukanie i 3 darmowe programy do odzyskiwania:
    TestDisk & PhotoRec 6.8 – używałem też pod Linuksem, naprawdę dobry soft!
    Digital Image Recovery 1.47
    PC Inspector File Recovery 4.0

  • SebaS86 (2007-09-16 20:48:10):

    EasyRecovery właśnie poinformowało mnie, że mogę się pocałować „w pompkę”, poza tym na tej samej stronie, którą podałeś: „Wersja testowa programu posiada pełną funkcjonalność nie oferuje jednak możliwości odzyskiwania plików (można je jedynie podejrzeć)”. Pełna funkcjonalność? błahaha :D

  • SebaS86 (2007-09-16 21:00:40):

    Grzegorz, masz jednak rację. Nie widziałem jeszcze żadnej aplikacji do odzyskiwania danych dla pingwina, a tym bardziej programu tego typu z interfejsem. Ot dobry pomysł żeby trochę przysiedzieć w ciągu najbliższego semestru. :)

  • Grzegorz | grzglo.jogger.pl (2007-09-16 21:01:40):

    W takim razie koniecznie daj znać jak coś napiszesz! Bardzo chętnie potestuję :)

  • Michał Górny (2007-09-16 21:07:05):

    TestDisk++. OS, UI na ncurses, powinien sobie bez problemu poradzić.

  • Sebas86 (2007-09-16 22:18:06):

    O TestDisk będę pamiętał, bo widać fajne narzędzie, chociaż nie udało mi się odzyskać dzięki niemu wszystkich zdjęć, za to wyłapał masę zaśmieconych plików tekstowych… :)

  • Sebas86 (2007-09-16 22:20:23):

    I czemu nikt nie krzyczy o ten straszny babol w rec.c! ;)

  • Hoppke (2007-09-18 12:56:39):

    Możnaby też wziąć obraz karty i spróbować na nim uruchomić pod dosemu np. to:
    http://iancoog.altervista.org/ (MultiRipper, freeware)

    Ma szanse zadziałać...

  • Sebas86 (2007-09-18 13:04:47):

    Ale ja już wszystko odzyskałem, nie pisałbym gdyby było inaczej. :)

  • GiM (2007-10-02 08:48:20):

    fajny artykuł.
    btw: zczytywanie przy uzyciu fread po 1 bajcie (tam gdzie zczytujesz fotkę), to raczej średni pomysł. poza tym z tego o widzę, to rozmiar masz ustawiony na 10K a nie na 1M jak napisałeś w poście.
    btw2: zamiast binarnego | w jednym z ifów, sugerowałbym jednak logicznego ||.
    btw3: po co robisz loop=0 skoro linię niżej jest i tak break?

  • Sebas86 (2007-10-02 08:58:13):

    Po 1B bo to tylko szybki pomysł, nie chciało mi się tego nawet optymalizować, po prostu powstało bo tata mi marudził ciągle i nie mogłem na spokojnie wziąć się za inne rzeczy, zamiast ImageMagic mogłem zaimplementować jakąś bibliotekę do wczytywania jpg i byłby automat. :)

    10241000 = 1024000 = 1M czyli się zgadza.
    1024
    10 = 10240 = 10K

    Rzeczywiście z warunkiem moje przeoczenie, ale pod względem poprawności obliczeń\podjętej decyzji jest poprawnie. :)

    Loop jest po to bo jest jeszcze pętla for wewnątrz, z której nie mogę w prosty sposób przejść na zewnątrz, a momencie którym użyłbym goto zmieszano by mnie z błotem.

  • GiM (2007-10-02 09:18:09):

    jakoś zera mi się z rana poprzestawiały
    co do ifa w twoim prypadku różnica jest jedynie w side-effect-cie, mianowicie sprawdzanie drugiego warunku nawet gdy pierwszy prawdziwy.
    a widzę fora, jakoś wcześniej nie zobaczyłem ;)

  • matekm (2007-11-25 00:21:58):

    calkiem przyjemny pomysl, chociaz mi osobiscie nie chcialoby sie nad tym siedziec;)

Comments !