Obnova smazaného videa z SD karty (FAT32)

      3.7.2020 Občas se člověku stane, že se uklepne a smaže něco, co vůbec smazat nechtěl. A pokud jako já nepoužíváte ve Windows Koš, tak máte problém. Pokud si to hned uvědomíte a stihnete rychle zmáčknout RESET tlačítko, tak je určitá šance, že se data z cache ještě nezapsala fyzicky na disk (pokud systém používá pro danou jednotku write-back cache), ale můžete zas přijít o něco jiného. Mě se zrovna povedlo smazat jedno natočené video, které jsem myslel, že už je právě zpracované a přitom jsem omylem smazal jiné. A o to jsem rozhodně nechtěl přijít, tak jsem se ho pokusil obnovit z SD karty ve foťáku, kde jsem naštěstí nic nového nenafotil, takže data by tam měla ležet nepřepsaná.
      Operační systém při mazání soubor běžně nemaže celý jeho obsah, protože by to u velkých souborů trvalo docela dlouho (na skutečné přemazání obsahu souboru existují různé wipe utility). To však neplatí u moderních OS a SSD, kde se při mazání posílá i ATA příkaz TRIM, který SSD oznamuje, že se dané sektory uvolnily a interní logika je brzy smaže, aby mělo SSD dostatek prázdného místa a při dalším zápisu se nemuselo zdržovat mazáním bloků FlashROM. Na paměťových kartách, USB klíčenkách a klasických HDD se TRIM (zatím) nepoužívá. V případě souborového systému FAT16/32 (více o jeho fungování zde) se v adresářové položce přepíše první znak názvu souboru na speciální hodnotu E5h, která značí, že je adresářová položka uvolněna pro další použití a dokud není přepsaná jinou, tak ji lze snadno obnovit. Zároveň se ale ve FAT tabulce vymaže část spojového seznamu (cluster chain) příslušného souboru, což už je destruktivní operace, kterou nelze vrátit zpět (např. u NTFS se záznam v MFT celý nemaže a tak je obnova jednodušší). Adresářová položka obsahuje pouze číslo prvního clusteru, kde data souboru začínala. Pak velmi záleží na velikosti daného souboru a stavu fragmentace souborového systému, resp. zda byl daný soubor uložen na disku ve více nesouvislých fragmentech. K fragmentaci dochází přirozeně tím, jak přibývají nové a mažou se staré soubory různých velikostí.
      Pokud je soubor menší než samotný cluster, tak je obnova velmi jednoduchá, neboť ono číslo clusteru známe z adresářové položky a také z ní víme i přesnou velikost souboru, takže stačí cluster přečíst a oříznout zbytek. V mém případě ale mělo video cca 140 MB, což při dané velikosti clusteru 8 kB znamenalo cca 17000 clusterů, které by v nejnepříznivějším případě mohly tvořit 17000 nesouvislých úseků rozházených po celém disku. Je to jako když by vám někdo na zem rozsypal několik krabic puzzlí a promíchal. Kousek obrázku na kostičce alespoň dává nějaké vodítko, ale kousek binárního souboru se dost blbě určuje, kam má ve výsledku vlastně patřit. Postahoval jsem a vyzkoušel celou řadu programů na obnovu souborů, ale žádný z nich si s fragmentací neporadil. Ve sloupci "hash" jsou poslední 4 Byte MD5 hashe, z čehož je vidět, které programy obnovily soubor stejným způsobem. V dalším sloupci je pak použitelná velikost videa, kterou z obnoveného souboru získal program Recover MP4 1.92, čili výsledek nic moc, cca 1 s videa. Ještě znovu upozorňuju, že je velmi důležité si po smazání data nepřepsat. Tzn. obnovený soubor je třeba ukládat na jiný disk či oddíl, než kde jsou smazaná data. U systémového disku, kde jede swap a Windows si něco zapisují na pozadí holt asi smůla. U přenosného média není na škodu aktivovat ochranu proti zápisu, pokud taková možnost je (např. mechanický lock přepínač u disket a SD karet). Pozor na to, že prašivé Windows 10 na připojeném disku ihned vytvoří adresář System Volume Information. Naštěstí se to dá vypnout.

software recovery result hash usable video size
Active@ File Recovery 20.0.5 Demo najde soubor, ale demo ho neuloží - -
Active@ File Recovery Pro 18.0.8 obnoví bez ohledu na fragmentaci *E557 1068 kB
CnW Recovery 5.44 Demo najde soubor, ale demo ho neuloží - -
DiskDigger 1.31.43.3019 obnoví bez ohledu na fragmentaci *7A13 4198 kB
DMDE 3.6.0.770 Free obnoví bez ohledu na fragmentaci *920F 3038 kB
EaseUS Data Recovery Wizard 13.3 obnoví bez ohledu na fragmentaci *552E 3038 kB
GetDataBack for FAT 4.25 obnoví bez ohledu na fragmentaci - -
Glary Undelete 5.0.1.19 nelze vybrat externí disk - -
Hetman FAT Recovery 3.0 Demo najde soubor, ale demo ho neuloží - -
Kickass Undelete 1.5.5 obnoví bez ohledu na fragmentaci *920F 3038 kB
Lazesoft Recovery Suite Pro 4.3 nenajde požadovaný soubor - -
MiniTool Power Data Recovery 7.0 obnoví bez ohledu na fragmentaci
(limit free verze je 1 GB)
*552E 3038 kB
QPhotoRec 7.0 obnoví bez ohledu na fragmentaci - -
Puran Utilities 3.1 obnoví bez ohledu na fragmentaci *1B87 4198 kB
R-Studio 8.13.176095 Demo najde soubor, ale demo ho neuloží - -
Raise Date Recovery for FAT 5.19.1 obnoví bez ohledu na fragmentaci *1B87 4198 kB
Recuva 1.53.1087 obnoví bez ohledu na fragmentaci *920F 3038 kB
RS FAT Recovery 3.0 Demo najde soubor, ale demo ho neuloží - -
Stellar Data Recovery 9.0.0.4 Demo najde soubor, v demu nejde ani náhled
(limit demo verze je 25 MB)
- -
Stellar Data Recovery 9.0.0.1 Pro obnoví bez ohledu na fragmentaci *920F 3038 kB
StrongRecovery 4.0.7.0 Free obnoví bez ohledu na fragmentaci *920F 3038 kB
WinHex 14.9 obnoví bez ohledu na fragmentaci - -
Wise Data Recovery 5.1.5.333 Demo najde soubor, v demu nejde ani náhled - -
Wise Data Recovery 3.42 Free nenajde požadovaný soubor - -

      Dále jsem také vyzkoušel několik programů specializovaných na obnovu poškozených video souborů a předhodil jsem jim image SD karty začínající prvním clusterem videosouboru. Většina programů vyžaduje ještě nějaký nepoškozený vzorový videosoubor ve stejném formátu jako ten poškozený. Docela dobře si vedl program Kernel Video Repair 20.3, který obnovil asi 20 s videa, ale s různými kostičkovanými efekty a vynechanými částmi.

software OS ref. video recovery result
Kernel Video Repair 20.3 Demo (limit 30 s) Win7+ potřebuje obnoví cca 20 s různých částí s chybami
Kernel Video Repair 19.0 Win7+ nepotřebuje neobnoví nic
Recover MP4 1.92 Free WinXP+ x32/64 potřebuje obnoví cca 1 s
Remo Repair MOV 2.0.0.56 Demo Win7+ x32 potřebuje neobnoví nic
Stellar Repair for Video 5.0.0.2 WinXP+ x32 potřebuje neobnoví nic
Stellar Phoenix Video Repair 3.0.0.0 WinXP+ x32 potřebuje po několika hodinách neobnoví nic, jen vytěžuje CPU
Wondershare Video Repair 1.1.2 Demo (limit 30 s) Win7+ x64 potřebuje obnoví cca 0,5 s

      Nakonec mi tedy nezbylo nic než poctivá ruční práce v hexaeditoru s vydatnou pomocí Recover MP4. Vycházel jsem z předpokladu, že fragmentů nebude zas tak mnoho (na kartu se ukládají většinou cca 20 - 30 MB velké RAWy) a že FAT allocator postupoval od prvního volného clusteru lineárně dále, takže na vyšších číslech clusterů budou pozdější části videa v nezměněném pořadí. Abych si práci alespoň trochu usnadnil, udělal jsem si dump pouze neobsazených clusterů. Zhruba na polovině karty mám totiž stále ještě nezpracované fotky a je tak lepší pracovat jen s cca 8GB image než 16GB. K tomu jsem použil linuxovou utilitu blkls, která je součástí balíku TSK (The Sleuth Kit) a je i v repozitáři Debianu, takže jsem jej snadno nainstaloval příkazem apt-get install sleuthkit. Obsahuje též utilitu pro obnovu smazaných souborů: tsk_recover -v -f fat32 -i raw /dev/sde1 /sddata, ale videosoubor mezi obnovenými soubory chyběl. Dump všech nealokovaných clusterů do image souboru jsem vytvořil příkazem blkls -A /dev/sde1 >/sddata/unallocated.bin.
      Moje zrcadlovka kóduje natáčená videa kodekem MPEG-4/H.264 s nekomprimovaným PCM zvukem v kontejneru Apple QuickTime (MOV). V mém případě mají soubory celkem snadno rozeznatelnou hlavičku 00 00 00 1C ftypqt 0000qt. Našel jsem si podle ní začátek videa a předchozí data odmazal. Dále jsem potřeboval najít nějakou opakující se signaturu ve videu, podle které bych bezpečně odlišil videodata od jiných dat. Video má rozlišení 1920 x 1080, 30 FPS a ukládá se jako pravidelná sekvence: 1 plný IDR (Instantaneous Decoder Refresh) snímek (velký cca 300 kB), 14 částečných P snímků (velkých cca 15 kB), opět 1 IDR snímek a 14 P snímků a blok PCM audia (48 kB), tedy po vteřině videa vteřina zvuku. Před každým IDR snímkem se nachází 6-Bytová sekvence 00 00 00 02 09 10 - první čtveřice Bytů je velikost NALU (Big Endian) a další 2 Byte jsou typ NALU: Access Unit Delimiter (NAL Unit Type: 9). Podobně před každým P snímkem je sekvence 00 00 00 02 09 30. Takže vyhledáváním těchto sekvencí jsem byl schopen rozlišit, jestli se koukám na části videa nebo fotek.
      Nejprve jsem Recover MP4 pustil na krátkém vzorovém videu, které jsem si foťákem natočil, pomocí příkazu recover_mp4_x86.exe sample.mov --analyze. Program si z něj vytvoří 2 hlavičkové soubory audio.hdr a video.hdr, které mu pomůžou při obnově poškozeného videa dalším příkazem recover_mp4_x86.exe unallocated.bin result.mp4 result.wav --qt --pcmfix 5DD8 (přídavné parametry program sám vypíše po prvním kroku). Program pak vypisuje nalezené IDR a P snímky a jejich offsety v daném souboru. Když narazí na nějaký problém (neznámá data), tak je buď přeskočí (např. "warn: 0x08696ABF [0x71FF8] {01 FF}}, False positive AVC detection. Unexpected PCM block size 0x48d95ce. Ignoring!") nebo skončí s chybou (např. "?big: 0x03DBD4F1 [0x 49FD54F] ??? {3D 2B BA C0 79 27}"). V takovém případě jsem se musel na daný offset podívat v hexaeditoru, najít podle Access Unit Delimiteru kde video pokračuje dále, blok cizích dat z image vyříznout a spustit Recover MP4 znovu. Takto jsem postupně pospojoval asi 20 fragmentů videa, dokud nebylo kompletní. Zde je ukázka výpisu Recover MP4:


recover_mp4 v1.92 (C) 2011-2017 Dmitry Vasilyev 
http://slydiman.me

Writing H264 video file 'result.mp4'...
Video format: AVC video 1920x1080, High Profile, Level 4.0
Assuming max AVC/HEVC NAL unit size (IDR) 0xEA3800, (non IDR) 0xFFFFF
Used AVC templates: QuickTime MOV
WARNING: Cannot find 'esds' atom inside audio header 'audio.hdr'.
Writing audio file 'result.wav'...
Audio format: Assuming audio stream is PCM (BE), 48000Hz 1ch 16bit
Assuming fix audio chunk size 0x5DD8
Searching 'mdat' atom in 'unallocated.bin'...
mdat (32-bit) payload from 0x24 to 0x87BAA40
H264: 0x00000024 [0x       6] -> 0x      22 {09 10}
H264: 0x0000002A [0x   4369F] -> 0x      28 {25 88 84 00} IDR frame
H264: 0x000436C9 [0x       6] -> 0x   436C7 {09 30}
H264: 0x000436CF [0x     C17] -> 0x   436CD {21 9A 24 20} P frame
H264: 0x000442E6 [0x       6] -> 0x   442E4 {09 30}
H264: 0x000442EC [0x    3C1E] -> 0x   442EA {21 9A 48 24} P frame
H264: 0x00047F0A [0x       6] -> 0x   47F08 {09 30}
H264: 0x00047F10 [0x    8433] -> 0x   47F0E {21 9A 6C 23} P frame
H264: 0x00050343 [0x       6] -> 0x   50341 {09 30}
H264: 0x00050349 [0x    96C5] -> 0x   50347 {21 9A 90 21} P frame
H264: 0x00059A0E [0x       6] -> 0x   59A0C {09 30}
H264: 0x00059A14 [0x    D383] -> 0x   59A12 {21 9A B4 21} P frame
H264: 0x00066D97 [0x       6] -> 0x   66D95 {09 30}
H264: 0x00066D9D [0x    DAE8] -> 0x   66D9B {21 9A D8 21} P frame
H264: 0x00074885 [0x       6] -> 0x   74883 {09 30}
H264: 0x0007488B [0x    FC24] -> 0x   74889 {21 9A FC 21} P frame
H264: 0x000844AF [0x       6] -> 0x   844AD {09 30}
H264: 0x000844B5 [0x    F246] -> 0x   844B3 {21 9B 00 21} P frame
H264: 0x000936FB [0x       6] -> 0x   936F9 {09 30}
H264: 0x00093701 [0x   159DE] -> 0x   936FF {21 9B 24 21} P frame
H264: 0x000A90DF [0x       6] -> 0x   A90DD {09 30}
H264: 0x000A90E5 [0x    B1CF] -> 0x   A90E3 {21 9B 48 21} P frame
H264: 0x000B42B4 [0x       6] -> 0x   B42B2 {09 30}
H264: 0x000B42BA [0x   12DFF] -> 0x   B42B8 {21 9B 6C 21} P frame
H264: 0x000C70B9 [0x       6] -> 0x   C70B7 {09 30}
H264: 0x000C70BF [0x    BA88] -> 0x   C70BD {21 9B 90 21} P frame
H264: 0x000D2B47 [0x       6] -> 0x   D2B45 {09 30}
H264: 0x000D2B4D [0x    F8AF] -> 0x   D2B4B {21 9B B4 21} P frame
H264: 0x000E23FC [0x       6] -> 0x   E23FA {09 30}
H264: 0x000E2402 [0x   14A22] -> 0x   E2400 {21 9B D8 21} P frame
warn: 0x000F8016 [0x   10400]               {01 00}}
      False positive AVC detection. Unexpected PCM block size 0x11f2. Ignoring!
warn: 0x000F8033 [0x      E2]               {01 00}}
      False positive AVC detection. Unexpected PCM block size 0x120f. Ignoring!
...      
warn: 0x085B2FC8 [0x   BDFF3]               {0C FF}}
      False positive AVC detection. Invalid NAL unit 12. Ignoring!
warn: 0x0862CB68 [0x   DBFF3]               {0C FF}}
      False positive AVC detection. Invalid NAL unit 12. Ignoring!
warn: 0x08696ABF [0x   71FF8]               {01 FF}}
      False positive AVC detection. Unexpected PCM block size 0x48d95ce. Ignoring!
?big: 0x03DBD4F1 [0x 49FD54F] ???           {3D 2B BA C0 79 27}
Complete!
H264 IDR NAL unit size: Min 0x4369B, Avg 0x5E8FE, Max 0x7A21D
H264 non-IDR NAL unit size: Min 0x2, Avg 0x2, Max 0x159DA
Audio frame size: Min 0xBBB0, Avg 0xBBB0, Max 0xBBB0
Skipped 1 blocks: Min 0x3D584, Avg 0x3D584, Max 0x3D584
WARNING: The current max AVC NAL unit (IDR) size 0xEA3800.
WARNING: The current max AVC NAL unit (non IDR) size 0xFFFFF.
Try to change it adding parameter --avcidrmax 6DEB3 and/or --avcxmax 13744
'result.mp4' created, size 3038231 (2.133%)
'result.wav' created, size 48048 (0.034%)

      Video se mi nepovedlo obnovit úplně bez chyby, bylo v něm pár rozkostkovaných snímků. Otevřel jsem ho v Avidemuxu a tyto poškozené snímky jsem vystříhal, přidal jsem obnovenou zvukovou stopu a 2-průchodově zkomprimoval do H.264 s nižším bitrate. Tak to byla typická ukázka pinožení, jak kvůli 1 vteřině nepozornosti vznikne práce na mnoho hodin...



Zpět

Aktualizováno 22.7.2020 v 4:24