[linux-l] gelöschte Dateien wiederherstellen

Steffen Schulz pepeatgoofy at gmx.net
So Mär 2 15:06:47 CET 2003


On 030302 at 11:00, Oswald Buddenhagen wrote:
> On Sat, Mar 01, 2003 at 10:35:38PM +0100, Steffen Schulz wrote:
> > ich bezog mich aber auf die specs von oben, wegen diesen metadaten.
> >
> hab ich doch in der anderen mail geschrieben: dumpe2fs. das hilft schon
> ganz gut, denke ich.

Hab ich mir auch angesehen, aber das gibt mir doch nur die Metadaten.
Ausserdem hab ich nicht gesehen, wie man Adressen von Metadaten
ausgeben könnte. Ich bräuchte genau das Gegenteil, ich will ja die
reinen Daten haben. Oder wolltest du auf den Quellcode anspielen? Nee...

> und wenn man in google "ext2 file system layout" reinhaut, kriegt man
> auch reichlich dokumentation, um das zeug auch tatsächlich zu verstehen.

Hm...ich hab nach design statt layout gesucht, die Ergebnisse waren
irgendwie nicht ganz so gut. Was ich konkret brauche sind die Angaben,
wie die inodes aussehen und wo exakt sie sind. Ich bräucht also
sinngemäß ne RFC für ext2...bei deinen Treffern sind solche Sachen
dabei, aber die Sache hat noch nen Haken: Wenn ich das image mit dls
bearbeitet habe, ist es kein image mehr, dls gibt nach eigenen angaben
alle nicht alloziierten Daten aus, da sind keine metadaten drin, gar
nix. Nur noch Blockweise die Daten. Soweit so gut, nur halt noch
unterbrechnugen drin. Die Stellen, wo diese Unterbrechungen drin
sind(angenommen, es sind(leere, da kein rec-tool was findet) inodes),
dann stimmen deren Positionen nicht mehr mit den angaben in den specs
überein, weil u.a. Superblöcke von dls rausgeschnitten wurden.
Wenn ich nu auf dls verzichte, wird der Aufwand wieder recht gross,
dann fang ich nämlich an, anhand des Superblocks  zu rechnen, wo und
wie die inodes verteilt sind, wenn ich nen pdf aus obiger Suchanfrage
richtig verstehe. Da schreib ich nen halben fs-treiber. Und ich kann
kaum programmieren, am besten gehts immernoch per shell :(

> > Hab das script umgebaut, es ist jetzt noch viel langsamer und filtert
> > diese o.g. Blöcke aus.
> >
> das finde ich nicht gut. du benutzt heuristik an einer stelle wo du
> streng berechenbare daten nehmen könntest. wissen wegzuschmeißen und
> durch erratenes zu ersetzen ist nie eine gute idee ...

Du hast recht, aber der Rechenaufwand scheint kaum vertretbar zu sein.
Seit gestern nach 24Uhr lief nun ein nochmals verfeinertes script,
heute 10Uhr war der Rechner fertig, Script&Kommentar hängen an, wen's
interessiert. 250MB an jpegs hab ich schon wegsortiert, insgesamt waren
vielleicht 5 Stück aller jpegs beschädigt, wären die darunter wichtige
gewesen, hätte ich wegen Namensgebung problemlos weitere Dateifragmente
finden bzw aus dem image ziehen können. Meine paar shell-scripte waren
auch hübsch einsortiert. Die mboxes scheinen komplett zu sein, leider
läuft seit kurzem archivemail, sodass ich bei den gzips mal nachschauen
muss, dort haben aber auch schon viele funktioniert. Man findet nur
nix, zwischen themes, quellcodes, caches, std-configs und so...aber
wird schon gehen...dann weiss ich, was ich dies WE gemacht hab...

Vielen Dank für eure Anteilnahme&Hilfe :)
pepe


_______________________________________________________________________
#!/bin/bash
# Kratze alle Daten aus einem mit "dls $image.raw > $imgage.data"
# erzeugtem Image.

PATH=/bin:/sbin:/usr/bin:/usr/sbin

bs=4096 # blocksize
delta=4030 # threshold

test -n $1 || { echo "Usage: $0 imagefile nonexistant_destination_directory" && exit; }
test -n $2 || { echo "Usage: $0 imagefile nonexistant_destination_directory" && exit; }
mkdir $2   || { echo "Usage: $0 imagefile nonexistant_destination_directory" && exit; }

image=$1
dest=$2
temp=$(tempfile)

# calc number of blocks in $image
blocks=$(echo $(du -b $image|awk '{print $1}' )/$bs|bc)

i=0
while [ "$i" -lt "$blocks" ]; do {
	dd if=$image bs=$bs count=1 skip=$i 2>/dev/null > $temp
	[ "" == "$(dd if=$temp bs=128 skip=31 2>/dev/null)" ] && \
	[ "$(dd if=$temp bs=1 skip=7 count=1 2>/dev/null|hexdump -b|awk '{print $2}' )" == \
	  "$(dd if=$temp bs=1 skip=3 count=1 2>/dev/null|hexdump -b|awk '{print $2}' )" ] &&
	[ "$(dd if=$temp bs=1 skip=15 count=1 2>/dev/null |hexdump -b|awk '{print $2}')" == \
	  "$(dd if=$temp bs=1 skip=11 count=1 2>/dev/null |hexdump -b|awk '{print $2}')" ] &&
	i=$(echo "$i+1"|bc)
	dir=$(dd if=$image bs=$bs count=1 skip=$i  2>/dev/null |file -b -)
	dir=$dest/$(echo $dir|awk '{print $2}')/$(echo $dir|awk '{print $1}')
	test -d $dir || mkdir -p $dir
	file=$dir/file$i.raw
	dd if=$image bs=$bs count=1 skip=$i 2>/dev/null > $file
	end=$(dd if=$file count=$bs skip=$delta bs=1 2> /dev/null)
	while test -n "$end"; do {
		i=$(echo "$i+1"|bc)
		dd if=$image bs=$bs count=1 skip=$i 2>/dev/null > $temp
		[ "" == "$(dd if=$temp bs=128 skip=31 2>/dev/null)" ] && \
		[ "$(dd if=$temp bs=1 skip=7 count=1 2>/dev/null|hexdump -b|awk '{print $2}' )" == \
		  "$(dd if=$temp bs=1 skip=3 count=1 2>/dev/null|hexdump -b|awk '{print $2}' )" ] &&
		[ "$(dd if=$temp bs=1 skip=15 count=1 2>/dev/null |hexdump -b|awk '{print $2}')" == \
		  "$(dd if=$temp bs=1 skip=11 count=1 2>/dev/null |hexdump -b|awk '{print $2}')" ] &&
		i=$(echo "$i+1"|bc) && dd if=$image bs=$bs count=1 skip=$i 2>/dev/null > $temp
		end=$(dd if=$temp count=66 skip=$delta bs=1 2> /dev/null)
		cat $temp >> $file
	}; done
	i=$(echo "$i+1"|bc)


}; done

sudo halt
-----------------------------------------------------------------------
Wir sortieren nur nach Blockgrenzen, sollte der aktuelle Block nach
einem dieser inodes ausehen(oder was immer das war...), überspringen
wir den. Sollten mehr als 66Byte nullen am Ende stehen, fangen wir ne
neue Datei an.(siehe $delta) Genauer konnt ich nicht auf inodes testen,
weil deren Inhalt recht variabel war.

Ca 9h40min für 5.4GB möglichst viele Prozesse beendet,
renice -15 $script, 700Mhz,512MB RAM, image und ziel auf dem
selben raid0, welches sich über 2 std-IDE-Platten erstreckt)

-- 
In truth, death may be the only true freedom there is.
				- Kaworu Nagisa



Mehr Informationen über die Mailingliste linux-l