Data Recovery μετά από format..

Christos Ricudis ricudis at itc.auth.gr
Fri Jan 16 13:48:48 EET 2009


Houtouridis Christos wrote:
> Μετά απο μια πολύ έξυπνη κίνηση κατάφερα να κάνω format (mkfs.ext3) σε
> ένα δίσκο που είχε την δουλειά 7 χρόνων (κείμενα .doc και .xls κυρίως)
> της αδερφής μου καθώς και όλες της τις φωτογραφίες. Να πώ εδώ ότι παρόλο
> που υπήρχε η δυνατότητα, απο τον συγκεκριμένο δίσκο δεν υπάρχει BackUp.

Συγχαρητηρια.

>
> Μετά τα συγχαρητήρια, έχει κανείς να μου προτείνει κάποιο πρόγραμμα ή
> κάποια άλλη ιδέα. Δέχομαι και proprietary λύσεις.

Το πρωτο-πρωτο-πρωτο πραγμα που κανεις ειναι να παρεις ενα image του 
δισκου σε αρχειο - με την dd. Καλο ειναι να μην τον κανεις ουτε καν 
mount - το mounting *γραφει* και μαλιστα αρκετα bits δεδομενων στο 
device (βεβαια για να ειμαι ειλικρινης, αυτα που γραφει ενα σκετο mount 
μαλλον δεν θα επηρεασουν τη δυνατοτητα σου να ανακτησεις δεδομενα ουτε 
προς το καλυτερο ουτε προς το χειροτερο).

Τωρα, δυστυχως και αντιθετως απο οτι σου ειπαν οι υπολοιποι, πιθανοτατα 
θα χρειαστει να γραψεις κωδικα. Αν εχεις κανει mkfs μπορεις μαλλον να 
ξεχασεις *ολα* τα αντιγραφα του superblock, inode tables, κτλ κτλ - 
πρακτικα ολα τα metadata του filesystem. Οποτε μην περιμενεις οι λυσεις 
που σου προτειναν ηδη να εχουν κανενα σημαντικο αποτελεσμα.

Το καλο με την περιπτωση σου ειναι οτι τα δεδομενα που προσπαθεις να 
κανεις recover εχουν μια συγκεκριμενη δομη, αρα μπορεις να ψαξεις για τη 
δομη τους μεσα στο image και να την "ακολουθησεις" ανακτωντας τα 
δεδομενα (κατι τετοιο κανει π.χ. για τα JPEG αρχεια το 
http://www.clarity.net/~adam/recoverpix.html).

Η γενικη δομη που ακολουθουν σχεδον ολα τα filesystems ειναι πανω κατω η 
εξης :

Κατι-που-αποθηκευει-metadata
        Κατι-που-αποθηκευει-αναφορες-σε-αρχεια
                [αρχειο 
1]Κατι-που-αποθηκευει-αναφορες-στα-blocks-του-αρχειου1 (εστω blocks 5, 
6, 7, 8, 10)
                [αρχειο 
2]Κατι-που-αποθηκευει-αναφορες-στα-blocks-του-αρχειου2 (εστω blocks 
12,13,14,15)

κτλ κτλ

(στην πραξη βεβαια ειναι πολυ πιο περιπλοκο απο αυτο)

Υστερα ακολουθουν τα data blocks των αρχειων :

[block1][κατι που αποθηκευει metadata για το block 
1][δεδομεεεεεεεεεεεενααααααααααααααα]
[block2][κατι που αποθηκευει metadata για το block 2][κι αλλα 
δεδομεεεεεεεεεενααααααααα]
[block3][κατι που αποθηκευει metadata για το block 3][ακομα περισσοτερα 
δεδομεεεενααααα]

Εδω μπορεις να χρησιμοποιησεις επισης τις λογικες παραδοχες οτι τα data 
blocks εχουν συνηθως σταθερο μηκος, και οτι τα περισσοτερα filesystems 
κανουν αρκετη προσπαθεια να αποθηκευσουν τα data blocks του καθε αρχειου 
συνεχομενα.

Για να παρεις μια ιδεα του πραγματος στην πραξη, ας κανουμε ενα 
πραγματικο πειραμα.

Δημιουργουμε ενα loop device :

komodino:[ricudis]/home/ricudis/rec# yes sex | head -c 51200000 > image.img

Το 512*100000 επιλεχτηκε για να ταιριαζει με το sector size των 
περισσοτερων δισκων.

Το loop device δημιουργηθηκε επιτηδες με ενα γνωστο pattern - τρεις 
χαρακτηρες συν το end of line = 32 bits.

Δημιουργουμε ενα filesystem πανω στο loop device :

komodino:[root]/home/ricudis/rec# losetup /dev/loop0 image.img
komodino:[root]/home/ricudis/rec# losetup /dev/loop0
/dev/loop0: [0801]:8047760 (image.img)
komodino:[root]/home/ricudis/rec# mke2fs /dev/loop0
mke2fs 1.40.8 (13-Mar-2008)
Filesystem label=
OS type: Linux
Block size=1024 (log=0)
Fragment size=1024 (log=0)
12544 inodes, 50000 blocks
2500 blocks (5.00%) reserved for the super user
First data block=1
Maximum filesystem blocks=51380224
7 block groups
8192 blocks per group, 8192 fragments per group
1792 inodes per group
Superblock backups stored on blocks:
        8193, 24577, 40961

Writing inode tables: done
Writing superblocks and filesystem accounting information: done

This filesystem will be automatically checked every 37 mounts or
180 days, whichever comes first.  Use tune2fs -c or -i to override.

Κανουμε mount το loop device και δημιουργουμε μερικα directories

komodino:[root]/home/ricudis/rec# mount /dev/loop0 /mnt
komodino:[root]/home/ricudis/rec# mkdir -p /mnt/pera/stous/pera/kampous
komodino:[root]/home/ricudis/rec# mkdir -p /mnt/pera/smena/ksexa/smena

Δημιουργουμε μερικα αρχεια με *γνωστη* δομη και περιεχομενο. Ας 
δημιουργησουμε τρια αρχεια. Το ενα περιεχει καροτα, το τριτο περιεχει 
κουκουναρια, και το δευτερο ειναι ενα ταπερακι γεματο με ελιες (απο τη 
γνωστη εκφραση "θα μου κλασεις ενα ταπερακι ελιες")

komodino:[root]/home/ricudis/rec# (for (( i=1 ; i<10000 ; i++ )) ; do 
echo "karoto $i" ; done) > /mnt/pera/stous/pera/kampous/fytrwsane_karota
komodino:[root]/home/ricudis/rec# (for (( i=1 ; i<10000 ; i++ )) ; do 
echo "elia elia kai kwsto basilia $i" ; done) > 
/mnt/pera/stous/pera/kampous/taperaki
komodino:[root]/home/ricudis/rec# (for (( i=1 ; i<10000 ; i++ )) ; do 
echo "koukounari $i" ; done) > 
/mnt/pera/smena/ksexa/smena/koukounaria_petamena

komodino:[root]/home/ricudis/rec# ls -l /mnt/pera/stous/pera/kampous/
total 443
-rw-r--r-- 1 root root 118881 2009-01-16 11:45 fytrwsane_karota
-rw-r--r-- 1 root root 328860 2009-01-16 11:46 taperaki

komodino:[root]/home/ricudis/rec# ls -l /mnt/pera/smena/ksexa/smena/
total 157
-rw-r--r-- 1 root root 158877 2009-01-16 11:46 koukounaria_petamena

Κανουμε unmount το filesystem, κλεινουμε το loop device, κτλ κτλ.

komodino:[root]/home/ricudis/rec# umount /mnt
komodino:[root]/home/ricudis/rec# losetup -d /dev/loop0

Και αρχιζει τωρα το ενδιαφερον κομματι :

Παιρνουμε το image file και εξεταζουμε τη δομη του με το hd η οποιον 
αλλο αγαπημενο μας hex dumper.

komodino:[ricudis]~/rec$ hd image.img > image-hex-dump
komodino:[ricudis]~/rec$ less image-hex-dump

komodino:[ricudis]~/rec$ less image-hex-dump
00000000  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  
|................|
*
00000400  00 31 00 00 50 c3 00 00  c4 09 00 00 a0 b7 00 00  
|.1..PΓ..Δ... ·..|
00000410  eb 30 00 00 01 00 00 00  00 00 00 00 00 00 00 00  
|λ0..............|
00000420  00 20 00 00 00 20 00 00  00 07 00 00 d5 56 70 49  |. ... 
......ΥVpI|

κτλ κτλ

01000fd0  0b 56 00 00 0c 56 00 00  0d 56 00 00 0e 57 00 00  
|.V...V...V...W..|
01000fe0  00 00 00 00 6a 24 c5 c1  00 00 00 00 00 00 00 00  
|....j$ΕΑ........|
01000ff0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  
|................|
*
01038c00  73 65 78 0a 73 65 78 0a  73 65 78 0a 73 65 78 0a  
|sex.sex.sex.sex.|
*
01400400  6b 61 72 6f 74 6f 20 31  0a 6b 61 72 6f 74 6f 20  |karoto 
1.karoto |
01400410  32 0a 6b 61 72 6f 74 6f  20 33 0a 6b 61 72 6f 74  |2.karoto 
3.karot|
01400420  6f 20 34 0a 6b 61 72 6f  74 6f 20 35 0a 6b 61 72  |o 4.karoto 
5.kar|
01400430  6f 74 6f 20 36 0a 6b 61  72 6f 74 6f 20 37 0a 6b  |oto 
6.karoto 7.k|

Ωπ! Βρηκαμε τα καροτα! Παρατηρουμε οτι τα δεδομενα αρχιζουν στο byte 
0x1400400, δεκαδικο 20972544, που ναι, ειναι ακεραιο πολλαπλασιο του 512 
(40962*512).

Μαζευουμε προσεκτικα τα καροτα ενα ενα, και βρισκουμε το επομενο 
ενδιαφερον σημειο εδω :

014033c0  0a 6b 61 72 6f 74 6f 20  31 31 31 32 0a 6b 61 72  |.karoto 
1112.kar|
014033d0  6f 74 6f 20 31 31 31 33  0a 6b 61 72 6f 74 6f 20  |oto 
1113.karoto |
014033e0  31 31 31 34 0a 6b 61 72  6f 74 6f 20 31 31 31 35  |1114.karoto 
1115|
014033f0  0a 6b 61 72 6f 74 6f 20  31 31 31 36 0a 6b 61 72  |.karoto 
1116.kar|
01403400  0e 50 00 00 0f 50 00 00  10 50 00 00 11 50 00 00  
|.P...P...P...P..|
01403410  12 50 00 00 13 50 00 00  14 50 00 00 15 50 00 00  
|.P...P...P...P..|
01403420  16 50 00 00 17 50 00 00  18 50 00 00 19 50 00 00  
|.P...P...P...P..|
01403430  1a 50 00 00 1b 50 00 00  1c 50 00 00 1d 50 00 00  
|.P...P...P...P..|

Βλεπουμε οτι εχουμε μια διακοπη μετα απο 0x3000 (12288 = 24*512) bytes 
δεδομενων. Το τελος του ενιαιου "block" δεδομενων βρισκεται στο 
0x14033ff, δεκαδικο 20984831. Το αμεσως επομενο byte βρισκεται επισης σε 
ακεραιο πολλαπλασιο του 512 (40986*512).

Παρακατω :

01403580  6e 50 00 00 6f 50 00 00  70 50 00 00 71 50 00 00  
|nP..oP..pP..qP..|
01403590  72 50 00 00 73 50 00 00  74 50 00 00 75 50 00 00  
|rP..sP..tP..uP..|
014035a0  76 50 00 00 00 00 00 00  00 00 00 00 00 00 00 00  
|vP..............|
014035b0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  
|................|
*
01403800  6f 74 6f 20 31 31 31 37  0a 6b 61 72 6f 74 6f 20  |oto 
1117.karoto |
01403810  31 31 31 38 0a 6b 61 72  6f 74 6f 20 31 31 31 39  |1118.karoto 
1119|
01403820  0a 6b 61 72 6f 74 6f 20  31 31 32 30 0a 6b 61 72  |.karoto 
1120.kar|
01403830  6f 74 6f 20 31 31 32 31  0a 6b 61 72 6f 74 6f 20  |oto 
1121.karoto |
01403840  31 31 32 32 0a 6b 61 72  6f 74 6f 20 31 31 32 33  |1122.karoto 
1123|

Τα δεδομενα μας συνεχιζουν ακαθεκτα απο το byte 0x1403800, dec 20985856, 
40988*512. Η "διακοπη" εχει μηκος 1024 bytes.

...και τελειωνουν καπου εδω, χωρις περαιτερω διακοπες :

0141d840  6f 74 6f 20 39 39 39 37  0a 6b 61 72 6f 74 6f 20  |oto 
9997.karoto |
0141d850  39 39 39 38 0a 6b 61 72  6f 74 6f 20 39 39 39 39  |9998.karoto 
9999|
0141d860  0a 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  
|................|
0141d870  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  
|................|
*
0141dc00  73 65 78 0a 73 65 78 0a  73 65 78 0a 73 65 78 0a  
|sex.sex.sex.sex.|

Βλεπουμε οτι μετα το τελευταιο καροτο ακολουθουν μηδενικα για padding 
απο το byte 0x141d860 μεχρι το 0x141dbff.

Παρακατω βρισκουμε αρκετο sex - που αντιστοιχει σε unallocated blocks - 
και λιγο πιο κατω ξεκινανε οι ελιες :

0141dc00  73 65 78 0a 73 65 78 0a  73 65 78 0a 73 65 78 0a  
|sex.sex.sex.sex.|
*
01580400  65 6c 69 61 20 65 6c 69  61 20 6b 61 69 20 6b 77  |elia elia 
kai kw|
01580410  73 74 6f 20 62 61 73 69  6c 69 61 20 31 0a 65 6c  |sto basilia 
1.el|
01580420  69 61 20 65 6c 69 61 20  6b 61 69 20 6b 77 73 74  |ia elia kai 
kwst|

Ας ψαξουμε να βρουμε τα κουκουναρια. Ωπ, νατα.

018320d0  0b 78 00 00 0c 78 00 00  0d 78 00 00 00 00 00 00  
|.x...x...x......|
018320e0  00 00 00 00 6b 24 c5 c1  00 00 00 00 00 00 00 00  
|....k$ΕΑ........|
018320f0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  
|................|
*
0186a000  73 65 78 0a 73 65 78 0a  73 65 78 0a 73 65 78 0a  
|sex.sex.sex.sex.|
*
01e00400  6b 6f 75 6b 6f 75 6e 61  72 69 20 31 0a 6b 6f 75  |koukounari 
1.kou|
01e00410  6b 6f 75 6e 61 72 69 20  32 0a 6b 6f 75 6b 6f 75  |kounari 
2.koukou|
01e00420  6e 61 72 69 20 33 0a 6b  6f 75 6b 6f 75 6e 61 72  |nari 
3.koukounar|
01e00430  69 20 34 0a 6b 6f 75 6b  6f 75 6e 61 72 69 20 35  |i 
4.koukounari 5|


Προσεχουμε οτι τα καροτα βρισκονται πιο κοντα στις ελιες (0x1580400 - 
0x1400400 = 0x180000 = 22545408) και αρκετα μακρια απο τα κουκουναρια 
(0x1e00400 - 0x1400400 = 0xa00000 = 10485760). 

Περαν της προφανους εξηγησης οτι σπανιως θα βρεις καροτα πολυ κοντα στο 
ιδιο μερος με κουκουναρια η ελιες, μια που τα μεν ειναι ριζες ενω τα δε 
οχι και σπανιως φυτευονται μαζι, υπαρχει και μια πιο unix-oriented 
εξηγηση :

Τα unix filesystems ειναι optimized για την περιπτωση directories που 
περιεχουν αρκετα μικρα αρχεια, και κανουν αρκετη προσπαθεια να 
συγκεντρωνουν κοντα-κοντα τα αρχεια που βρισκονται στο ιδιο directory.

Αγνοω πως ακριβως κανει το allocation του το ext3, αλλα θα δωσω ενα 
παλιοτερο παραδειγμα τετοιου optimization: Την εποχη του 4.3BSD το UFS 
ομαδοποιουσε τους sectors σε cylinder groups, ωστε οι sectors του καθε 
cylinder group να βρισκονται σε διαφορετικα platters του σκληρου δισκου, 
στην ιδια "ακτινα" απο το κεντρο. Ετσι, ελαχιστοποιουσε τις κινησεις των 
κεφαλων του δισκου για να διαβασει τους sectors που ανηκαν στο ιδιο 
cylinder group, και φροντιζε τα αρχεια που αποθηκευοταν σε καθε 
directory να βρισκονται στο ιδιο η σε κοντινα cylinder groups. (γι αυτο 
και το BSD οταν πας να φτιαξεις filesystem σε ρωταει τη γωνιακη ταχυτητα 
περιστροφης του δισκου, ποσα platters εχει, τι χρωμα ειναι ο connector, 
τη γωνιακη αποσταση που καλυπτει ενας sector σε χιλιοστα της μοιρας, την 
τιμη του Π με ακριβεια δεκαοχτω δεκαδικων ψηφιων, ποσα αρχεια χωραει 
καθε directory, ποσα απιδια χωραει ο σακκος, κτλ κτλ).

Σημερα οι δισκοι ειναι πιο περιπλοκες συσκευες και δεν ειναι τοσο ευκολο 
να κανεις τοσο "βαθια" optimizations, αλλα οι περισσοτεροι σου δινουν 
μια εγγυησουλα του ειδους "η αποθηκευση δεδομενων σε κοντινα μεταξυ τους 
blocks εχει ως αποτελεσμα καλυτερους χρονους προσπελασης", και τα 
σημερινα optimizations βασιζονται περισσοτερο πανω σ'αυτο. Οποτε ειναι 
μαλλον βεβαιο οτι το ext3 χρησιμοποιει καποιο σχετικο ανωμαλγοριθμο για 
το allocation του με αποτελεσμα οι ελιες με τα καροτα να βρισκονται 
αρκετα κοντα.

Ας ξαναγυρισουμε τωρα στις ελιες. Εδω εχουμε δυο "διακοπες".

Αρχη :

0141d860  0a 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  
|................|
0141d870  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  
|................|
*
0141dc00  73 65 78 0a 73 65 78 0a  73 65 78 0a 73 65 78 0a  
|sex.sex.sex.sex.|
*
01580400  65 6c 69 61 20 65 6c 69  61 20 6b 61 69 20 6b 77  |elia elia 
kai kw|
01580410  73 74 6f 20 62 61 73 69  6c 69 61 20 31 0a 65 6c  |sto basilia 
1.el|
01580420  69 61 20 65 6c 69 61 20  6b 61 69 20 6b 77 73 74  |ia elia kai 
kwst|
01580430  6f 20 62 61 73 69 6c 69  61 20 32 0a 65 6c 69 61  |o basilia 
2.elia|

Πρωτη διακοπη :

015833c0  69 20 6b 77 73 74 6f 20  62 61 73 69 6c 69 61 20  |i kwsto 
basilia |
015833d0  33 38 36 0a 65 6c 69 61  20 65 6c 69 61 20 6b 61  |386.elia 
elia ka|
015833e0  69 20 6b 77 73 74 6f 20  62 61 73 69 6c 69 61 20  |i kwsto 
basilia |
015833f0  33 38 37 0a 65 6c 69 61  20 65 6c 69 61 20 6b 61  |387.elia 
elia ka|
01583400  0e 56 00 00 0f 56 00 00  10 56 00 00 11 56 00 00  
|.V...V...V...V..|
01583410  12 56 00 00 13 56 00 00  14 56 00 00 15 56 00 00  
|.V...V...V...V..|
....
015837e0  06 57 00 00 07 57 00 00  08 57 00 00 09 57 00 00  
|.W...W...W...W..|
015837f0  0a 57 00 00 0b 57 00 00  0c 57 00 00 0d 57 00 00  
|.W...W...W...W..|
01583800  69 20 6b 77 73 74 6f 20  62 61 73 69 6c 69 61 20  |i kwsto 
basilia |
01583810  33 38 38 0a 65 6c 69 61  20 65 6c 69 61 20 6b 61  |388.elia 
elia ka|
01583820  69 20 6b 77 73 74 6f 20  62 61 73 69 6c 69 61 20  |i kwsto 
basilia |

Δευτερη διακοπη :

015c37e0  69 6c 69 61 20 38 33 34  39 0a 65 6c 69 61 20 65  |ilia 
8349.elia e|
015c37f0  6c 69 61 20 6b 61 69 20  6b 77 73 74 6f 20 62 61  |lia kai 
kwsto ba|
015c3800  0f 57 00 00 00 00 00 00  00 00 00 00 00 00 00 00  
|.W..............|
015c3810  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  
|................|
*
015c3c00  10 57 00 00 11 57 00 00  12 57 00 00 13 57 00 00  
|.W...W...W...W..|
015c3c10  14 57 00 00 15 57 00 00  16 57 00 00 17 57 00 00  
|.W...W...W...W..|
....
015c3cc0  40 57 00 00 41 57 00 00  42 57 00 00 43 57 00 00  
|@W..AW..BW..CW..|
015c3cd0  44 57 00 00 45 57 00 00  00 00 00 00 00 00 00 00  
|DW..EW..........|
015c3ce0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  
|................|
*
015c4000  73 69 6c 69 61 20 38 33  35 30 0a 65 6c 69 61 20  |silia 
8350.elia |
015c4010  65 6c 69 61 20 6b 61 69  20 6b 77 73 74 6f 20 62  |elia kai 
kwsto b|
015c4020  61 73 69 6c 69 61 20 38  33 35 31 0a 65 6c 69 61  |asilia 
8351.elia|

...και τελος δεδομενων, με το γνωστο μας πια padding :

015d1480  65 6c 69 61 20 6b 61 69  20 6b 77 73 74 6f 20 62  |elia kai 
kwsto b|
015d1490  61 73 69 6c 69 61 20 39  39 39 39 0a 00 00 00 00  |asilia 
9999.....|
015d14a0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  
|................|
*
015d1800  73 65 78 0a 73 65 78 0a  73 65 78 0a 73 65 78 0a  
|sex.sex.sex.sex.|

Η πρωτη "διακοπη" βρισκεται παλι μετα απο 0x3000 bytes δεδομενων, και 
εχει μηκος 1024 bytes.

Η δευτερη "διακοπη" βρισκεται 0x40000 bytes μετα απο την πρωτη, και εχει 
μηκος 2048 bytes.

Για να δουμε τωρα και τα κουκουναρια. Εδω τα δεδομενα διακοπτονται παλι 
μονο μια φορα :

Αρχη :

018320e0  00 00 00 00 6b 24 c5 c1  00 00 00 00 00 00 00 00  
|....k$ΕΑ........|
018320f0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  
|................|
*
0186a000  73 65 78 0a 73 65 78 0a  73 65 78 0a 73 65 78 0a  
|sex.sex.sex.sex.|
*
01e00400  6b 6f 75 6b 6f 75 6e 61  72 69 20 31 0a 6b 6f 75  |koukounari 
1.kou|
01e00410  6b 6f 75 6e 61 72 69 20  32 0a 6b 6f 75 6b 6f 75  |kounari 
2.koukou|

"Διακοπη" :

01e033e0  6f 75 6e 61 72 69 20 38  32 35 0a 6b 6f 75 6b 6f  |ounari 
825.kouko|
01e033f0  75 6e 61 72 69 20 38 32  36 0a 6b 6f 75 6b 6f 75  |unari 
826.koukou|
01e03400  0e 78 00 00 0f 78 00 00  10 78 00 00 11 78 00 00  
|.x...x...x...x..|
01e03410  12 78 00 00 13 78 00 00  14 78 00 00 15 78 00 00  
|.x...x...x...x..|
01e03420  16 78 00 00 17 78 00 00  18 78 00 00 19 78 00 00  
|.x...x...x...x..|
...
01e03630  9a 78 00 00 9b 78 00 00  9c 78 00 00 9d 78 00 00  
|.x...x...x...x..|
01e03640  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  
|................|
*
01e03800  6e 61 72 69 20 38 32 37  0a 6b 6f 75 6b 6f 75 6e  |nari 
827.koukoun|
01e03810  61 72 69 20 38 32 38 0a  6b 6f 75 6b 6f 75 6e 61  |ari 
828.koukouna|

και τελος :

01e27480  6b 6f 75 6e 61 72 69 20  39 39 39 38 0a 6b 6f 75  |kounari 
9998.kou|
01e27490  6b 6f 75 6e 61 72 69 20  39 39 39 39 0a 00 00 00  |kounari 
9999....|
01e274a0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  
|................|
*
01e27800  73 65 78 0a 73 65 78 0a  73 65 78 0a 73 65 78 0a  
|sex.sex.sex.sex.|
*
01f80400  01 15 00 00 0c 00 01 02  2e 00 00 00 06 0e 00 00  
|................|
01f80410  0c 00 02 02 2e 2e 00 00  02 15 00 00 e8 03 14 01  
|............θ...|

H "Διακοπη" βρισκεται ξανα 0x3000 bytes μετα την αρχη των δεδομενων, και 
εχει παλι μηκος 1024 bytes.

Ας ριξουμε τωρα και μια ματια στα δεδομενα που βρισκονται στις 
"διακοπες" μεταξυ των ενιαιων blocks δεδομενων :

Πρωτη "διακοπη" :

01403400  0e 50 00 00 0f 50 00 00  10 50 00 00 11 50 00 00  
|.P...P...P...P..|
01403410  12 50 00 00 13 50 00 00  14 50 00 00 15 50 00 00  
|.P...P...P...P..|
01403420  16 50 00 00 17 50 00 00  18 50 00 00 19 50 00 00  
|.P...P...P...P..|
01403430  1a 50 00 00 1b 50 00 00  1c 50 00 00 1d 50 00 00  
|.P...P...P...P..|
01403440  1e 50 00 00 1f 50 00 00  20 50 00 00 21 50 00 00  |.P...P.. 
P..!P..|
01403450  22 50 00 00 23 50 00 00  24 50 00 00 25 50 00 00  
|"P..#P..$P..%P..|
01403460  26 50 00 00 27 50 00 00  28 50 00 00 29 50 00 00  
|&P..'P..(P..)P..|
...

Δευτερη "διακοπη" :

01583400  0e 56 00 00 0f 56 00 00  10 56 00 00 11 56 00 00  
|.V...V...V...V..|
01583410  12 56 00 00 13 56 00 00  14 56 00 00 15 56 00 00  
|.V...V...V...V..|
01583420  16 56 00 00 17 56 00 00  18 56 00 00 19 56 00 00  
|.V...V...V...V..|
01583430  1a 56 00 00 1b 56 00 00  1c 56 00 00 1d 56 00 00  
|.V...V...V...V..|
01583440  1e 56 00 00 1f 56 00 00  20 56 00 00 21 56 00 00  |.V...V.. 
V..!V..|
01583450  22 56 00 00 23 56 00 00  24 56 00 00 25 56 00 00  
|"V..#V..$V..%V..|
01583460  26 56 00 00 27 56 00 00  28 56 00 00 29 56 00 00  
|&V..'V..(V..)V..|
01583470  2a 56 00 00 2b 56 00 00  2c 56 00 00 2d 56 00 00  
|*V..+V..,V..-V..|
01583480  2e 56 00 00 2f 56 00 00  30 56 00 00 31 56 00 00  
|.V../V..0V..1V..|
...

Τριτη "διακοπη" :

015c3800  0f 57 00 00 00 00 00 00  00 00 00 00 00 00 00 00  
|.W..............|
015c3810  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  
|................|
*
015c3c00  10 57 00 00 11 57 00 00  12 57 00 00 13 57 00 00  
|.W...W...W...W..|
015c3c10  14 57 00 00 15 57 00 00  16 57 00 00 17 57 00 00  
|.W...W...W...W..|
015c3c20  18 57 00 00 19 57 00 00  1a 57 00 00 1b 57 00 00  
|.W...W...W...W..|
015c3c30  1c 57 00 00 1d 57 00 00  1e 57 00 00 1f 57 00 00  
|.W...W...W...W..|
015c3c40  20 57 00 00 21 57 00 00  22 57 00 00 23 57 00 00  | 
W..!W.."W..#W..|
015c3c50  24 57 00 00 25 57 00 00  26 57 00 00 27 57 00 00  
|$W..%W..&W..'W..|
015c3c60  28 57 00 00 29 57 00 00  2a 57 00 00 2b 57 00 00  
|(W..)W..*W..+W..|
015c3c70  2c 57 00 00 2d 57 00 00  2e 57 00 00 2f 57 00 00  
|,W..-W...W../W..|
...

και τελος η τεταρτη :

01e03400  0e 78 00 00 0f 78 00 00  10 78 00 00 11 78 00 00  
|.x...x...x...x..|
01e03410  12 78 00 00 13 78 00 00  14 78 00 00 15 78 00 00  
|.x...x...x...x..|
01e03420  16 78 00 00 17 78 00 00  18 78 00 00 19 78 00 00  
|.x...x...x...x..|
01e03430  1a 78 00 00 1b 78 00 00  1c 78 00 00 1d 78 00 00  
|.x...x...x...x..|
01e03440  1e 78 00 00 1f 78 00 00  20 78 00 00 21 78 00 00  |.x...x.. 
x..!x..|
01e03450  22 78 00 00 23 78 00 00  24 78 00 00 25 78 00 00  
|"x..#x..$x..%x..|
01e03460  26 78 00 00 27 78 00 00  28 78 00 00 29 78 00 00  
|&x..'x..(x..)x..|
01e03470  2a 78 00 00 2b 78 00 00  2c 78 00 00 2d 78 00 00  
|*x..+x..,x..-x..|

Παρατηρουμε οτι στην πρωτη, την δευτερη και την τεταρτη περιπτωση εχουμε 
ενα σταθερο pattern :

0e 50 00 00
0f 50 00 00
10 50 00 00
11 50 00 00
...

0e 56 00 00
0f 56 00 00 
10 56 00 00
11 56 00 00
...

0e 78 00 00
0f 78 00 00 
10 78 00 00
11 78 00 00
...

Η τριτη περιπτωση διαφερει λιγο, αλλα και παλι βρισκουμε το γνωστο 
pattern :

10 57 00 00
11 57 00 00 
12 57 00 00
13 57 00 00
...

(χωρις να γνωριζω καθολου το ext3, υποψιαζομαι οτι αυτες οι "διακοπες" 
περιεχουν indirect block references που "συνδεουν¨ τα τμηματα του 
αρχειου μεταξυ τους).


Τι καταφεραμε μεχρι τωρα ?

Καταφεραμε να εχουμε ηδη αρκετες πληροφοριες ωστε να μπορεσουμε να 
κανουμε μια πρωτη ανακτηση των δεδομενων που βρισκονται στο filesystem, 
και μαλιστα *χωρις καν να εχουμε την παραμικρη εκ προτερων γνωση για την 
εσωτερικη του δομη και οργανωση* - που σε δευτερο βημα μπορουμε να 
αποκτησουμε διαβαζοντας τα διαφορα design documents του filesystem, εαν 
με τη μεχρι τωρα γνωση μας δεν καταφερουμε να διασωσουμε αρκετο ογκο 
δεδομενων.

Στην περιπτωση που θελησεις να το κανεις, να εχεις υποψη σου πρωτον οτι 
το παραπανω παραδειγμα, επειδη ειναι εντελως τεχνητο, εχει αρκετες 
ατελειες και προφανως δεν ειναι ακριβως το ιδιο που θα συναντησεις στην 
πραξη. Η εσωτερικη δομη ειναι σιγουρα πιο περιπλοκη απο οτι φαινεται 
εδω, και σε ενα πραγματικο filesystem θα συναντησεις σχεδον σιγουρα 
fragmentation. Επισης οι αριθμοι που βγαλαμε εδω ειναι μαλλον βεβαιο οτι 
εχουν σχεση με τις παραμετρους δημιουργιας του fileysystem, και 
ενδεχομενως σε καποιο αλλο filesystem να ειναι διαφορετικοι. Αν κανεις 
και αλλες τετοιες δοκιμες με διαφορετικα μεγεθη αρχειων μπορει να 
διαπιστωσεις και τα "ορια" των μεγεθων των αρχειων για τα οποια 
χρειαζεται indirect block allocation - οι "διακοπες" που λεγαμε.

Τελος, στην πραξη δεν θα εχεις να κανεις με τοσο καλοβολα δεδομενα, 
οποτε θα πρεπει να ψαξεις να βρεις μονος σου τα σχετικα patterns των 
δεδομενων που ψαχνεις. Εκει θα σε βοηθησει παρα πολυ η εσωτερικη γνωση 
της δομης των αρχειων που ενδιαφερεσαι να ανακτησεις, και μερικες φορες 
και το περιεχομενο τους (ειδικα αν ειναι κατι που τυχαινει να ειναι 
διαβασable απο το hex dump του - π.χ. plain text files).

Π.Χ. ενα JPEG αρχειο αρχιζει παντα με εναν JFIF header. Παραδειγματα 
JPEG αρχειων :

00000000  ff d8 ff e0 00 10 4a 46  49 46 00 01 01 01 00 48  
|.Ψ.ΰ..JFIF.....H|
00000000  ff d8 ff e0 00 10 4a 46  49 46 00 01 01 00 00 01  
|.Ψ.ΰ..JFIF......|
00000000  ff d8 ff e0 00 10 4a 46  49 46 00 01 02 00 00 64  
|.Ψ.ΰ..JFIF.....d|
00000000  ff d8 ff e0 00 10 4a 46  49 46 00 01 01 01 00 4b  
|.Ψ.ΰ..JFIF.....K|

Τα .DOC και τα .XLS αρχεια ειναι OLE2 documents. Κι εδω υπαρχουν σταθερα 
patterns στην αρχη :

00000000  d0 cf 11 e0 a1 b1 1a e1  00 00 00 00 00 00 00 00  
|ΠΟ.ΰ‘±.α........|
00000000  d0 cf 11 e0 a1 b1 1a e1  00 00 00 00 00 00 00 00  
|ΠΟ.ΰ‘±.α........|
00000000  d0 cf 11 e0 a1 b1 1a e1  00 00 00 00 00 00 00 00  
|ΠΟ.ΰ‘±.α........|

Πολλες και χρησιμες υπογραφες για διαφορους τυπους αρχειων θα βρεις και 
στο /etc/magic και στο /usr/share/file/magic.

Καλη τυχη !


[1] (ανεπιβεβαιωτες φημες αναφερουν οτι Ελληνοαμερικανοι τριτης γενιας 
προγραμματιστες στη Microsoft, προσπαθησαν ανεπιτυχως να εισαγουν ως 
υπογραφη στα OLE2 documents το string "Πουτανα το καναμε παλι").






More information about the Linux-greek-users mailing list