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