Kapitel – 14
PROGRAMMIERUNG FÜR DIE WIEDERHERSTELLUNG VON RAW-DATEIEN
Wiederherstellen von RAW-Dateien
Bei vielen speziellen Dateitypen steht am Anfang und Ende der Datei eine bestimmte Zeichenfolge oder -kombination. Wir können diese Kombinationen problemlos mit jedem Festplattenbearbeitungsprogramm analysieren. Wir können auch den DOS-Befehl EDIT verwenden, um die Struktur einer ASCII-Datei zu untersuchen.
Eine bestimmte Zeichenfolge oder -kombination am Anfang einer Datei wird üblicherweise als Header bezeichnet, und eine Zeichenfolge oder -kombination, die am Ende einer Datei gespeichert ist, wird als Footer der Datei bezeichnet.
Wenn wir unsere Daten bei einem Festplattenfehler verloren haben und keine FAT- oder Stammverzeichnisinformationen zur Wiederherstellung der Daten vorhanden sind, können wir Kopf- und Fußzeilen verwenden, um diese spezifischen Dateitypen zu finden. Der Kopfbereich gibt den Anfang einer Datei dieses bestimmten Dateityps an, und der Fußbereich gibt das Ende einer Datei dieses bestimmten Dateityps an.
Hier verwenden wir die Rohstruktur eines bestimmten Dateityps, um Daten wiederherzustellen. Daher wird die Wiederherstellungsmethode „Raw File Recovery“ genannt. Die Festplattenoberfläche wird Sektor für Sektor gescannt, um Kopf- und Fußzeileninformationen zu finden.
Obwohl die Anwendungsmöglichkeiten von Raw File Recovery vielfältig sind, gibt es einige spezielle Wiederherstellungsfälle, in denen es sehr hilfreich sein kann. Wenn Sie beispielsweise versehentlich ein Datenlöschprogramm auf einer Festplatte ausführen, auf der sich einige wichtige Dateien befinden, werden bis zum Stoppen des Programms sämtliche MBR-, DBR-, FAT- und Stammverzeichnisinformationen einschließlich der Betriebssystemdateien gelöscht.
In diesem Fall können möglicherweise auch Formatwiederherstellungsprogramme nicht dabei helfen, die Daten wiederherzustellen. Hier können Sie Raw File Recovery verwenden, um Dateien dieser spezifischen Dateitypen durch die Suche in Kopf- und Fußzeilen wiederherzustellen.
Darüber hinaus können Sie sogar Daten wiederherstellen, wenn Sie eine Festplatte haben, auf der Sie alle logischen Partitionen gelöscht, Partitionen mit einer anderen Größe als zuvor neu erstellt und sogar ein Betriebssystem installiert haben.
Jetzt können Sie sich daran erinnern, dass sich vor der Partitionierung und Formatierung einige wichtige Daten auf der Festplatte befanden. Wenn Sie das Betriebssystem gerade erst installiert haben, besteht eine gute Chance, dass die Datei wiederhergestellt wird.
Faktoren, die die Leistung der Wiederherstellung von Rohdateien beeinträchtigen, sind fragmentierte Daten und die Menge der von anderen Daten überschriebenen Daten. Sie können jedoch immer mehr Anwendungen zur eigenständigen Wiederherstellung von RAW-Dateien finden.
Das Verfahren bzw. die Regeln für die Suche nach Dateien mithilfe einer Software zur Wiederherstellung von Rohdateien berücksichtigen die folgenden Bedingungen:
- Suchen Sie gleichzeitig in Datenträgersektoren nach einem Dateikopf oder mehreren Dateitypen.
- Wenn ein beliebiger Dateitypheader gefunden wird, speichern Sie die Daten in der Datei und überprüfen Sie die folgenden vier Bedingungen, um die Datei zu schließen und zu speichern.
- Fußzeile dieses Dateityps gefunden
- Es wurde ein anderer Header desselben Dateityps gefunden.
- Header eines anderen Dateityps gefunden
- Für bestimmte Dateitypen wurden im Programm keine anderen Kopf- oder Fußzeilen gefunden und die Dateigröße, in der Sie die Daten speichern, erreicht die maximale Größenbeschränkung, die Sie in Ihrem Programm für die Dateigröße definiert haben.
Die Informationen sollten in der Datei gespeichert werden, einschließlich der Sektordaten, in denen Sie die Kopf- und Fußzeile des Dateityps gefunden haben.
Kopf- und Fußzeilen einiger wichtiger Dateitypen
Die Kopf- und Fußzeilen einiger wichtiger Dateitypen sind in der folgenden Tabelle aufgeführt. Die in der Tabelle aufgeführten Fußzeilen befinden sich entweder am Ende der Datei des angegebenen Dateityps oder am Ende der Datei, sodass Sie sie als Fußzeilen für die Datenwiederherstellung verwenden können.
Sie können mit dem DOS-Befehl EDIT oder einem beliebigen Datenträgerbearbeitungstool auch selbst nach Kopf- und Fußzeilen außer diesen Dateitypen suchen. Um die Informationen verständlicher darzustellen, habe ich das Hexadezimalsystem verwendet.
Verlängerung |
Kopfzeile (Hexadezimal) |
Fußzeile (Hex) |
DOC |
D0 CF 11 E0 A1 B1 1A E1 |
57 6F 72 64 2E 44 6F 63 75 6G 65 6E 74 2E |
XLS |
D0 CF 11 E0 A1 B1 1A E1 |
FE FF FF FF 00 00 00 00 00 00 00 00 57 00 6F 00 72 00 6B 00 62 00 6F 00 6F 00 6B 00 |
PPT |
D0 CF 11 E0 A1 B1 1A E1 |
50 00 6F 00 77 00 65 00 72 00 50 00 6F 00 69 00 6E 00 74 00 20 00 44 00 6F 00 63 00 75 00 6D 00 65 00 6E 00 74 |
Postleitzahl |
50 4B 03 04 14 |
50 4B 05 06 00 |
JPG |
FF D8 FF E0 00 10 4A 46 49 46 00 01 01 |
D9 („Besser Dateigrößenprüfung verwenden“) |
GIF |
47 49 46 38 39 61 4E 01 53 00 C4 |
21 00 00 3B 00 |
PDF |
25 50 44 46 2D 31 2E |
25 25 45 4F 46 |
Schreiben eines Programms zum Wiederherstellen von RAW-Dateien
Unten finden Sie die Kodierung des Programms zur Raw-Dateiwiederherstellung von Microsoft Word-Dateien (Erweiterung .DOC). Das Programm sucht in den Datenträgersektoren nach Dateien und speichert die wiederhergestellte Datei automatisch, wobei automatisch ein Dateiname erstellt wird.
Der vom Benutzer zum Speichern der Dateien angegebene Pfad wird als Zielpfad zum Speichern der wiederhergestellten Daten verwendet. Wenn das Zielverzeichnis nicht existiert, kann das Programm es bis auf eine Verzeichnisebene erstellen.
Die hier bereitgestellte Wiederherstellungssoftware unterstützt die Suche und Wiederherstellung von Daten sogar auf großen Festplatten. Das Programm wurde geschrieben, um auf einer zweiten physischen Festplatte nach Daten zu suchen.
/* Software zur Wiederherstellung von Microsoft Word-RAW-Dateien */
#include<stdio.h>
#include<dos.h>
/* Von der Funktion getdrivegeometry verwendete Struktur mit der Erweiterung INT 13H, Funktionsnummer 0x48. */
Strukturgeometrie
{
vorzeichenlose Ganzzahlgröße; /* (Aufruf-)Puffergröße */
vorzeichenlose int-Flags; /* Informationsflags */
vorzeichenloser langer Zyl.; /* Anzahl der physischen
Zylinder auf dem Antrieb */
unsigned long headers ;/* Anzahl der physischen
Köpfe auf dem Laufwerk */
vorzeichenloser langer spt; /* Anzahl der physischen
Sektoren pro Spur */
unsignierter langer Sektor[2] ; /* Gesamtmenge
Sektoren auf der Festplatte */
vorzeichenlose Ganzzahl bps; /* Byte pro Sektor */
} ;
/* Von readabsolutesectors verwendete Datenträgeradresspaketformatstruktur */
Diskaddrpacket-Struktur
{
char-Paketgröße; /* Paketgröße, normalerweise 10H */
Symbol reserviert; /* Reserviert (0) */
int Blockanzahl; /* Anzahl der zu übertragenden Blöcke */
char far *Pufferadresse; /* Adresse für die Übertragung
Puffer */
unsigned long blocknumber[2] ; /* Anfänglich absolut
Blocknummer */
} ;
///// Funktion zum Abrufen von Antriebsparametern \\\\\
unsigniertes langes getdrivegeometry(intdrive)
{
Gewerkschaftsregister i, o;
Struktur SREGS s;
Strukturgeometrie g = { 26, 0, 0, 0, 0, 0, 0, 0 } ;
ihah = 0x48; /* Funktionsnummer 0x48 */
ihdl = Laufwerk; /* Datenträgernummer */
ixsi = FP_OFF ( (void weit*)&g ) ;
s.ds = FP_SEG ( (void far*)&g ) ;
/* Rufen Sie die angegebene INT 13H-Erweiterungsfunktionsnummer mit Segmentregisterwerten auf */
int86x (0x13, &i, &o, &s);
printf("\n Kopf = %lu, Sektoren pro Spur = %lu, Zylinder = %lu\n",
g.Kopf, g.SPC, g.Zyl.);
/* Wenn die Funktion zum Abrufen der Datenträgergeometrie fehlschlägt, drucken Sie eine Fehlermeldung und beenden Sie das Programm */
wenn(g.spt==0)
{
printf("\n Die Funktion zum Abrufen der Antriebsgeometrie wurde nicht ausgeführt....");
printf("\n Erweiterungen werden nicht unterstützt, drücken Sie eine beliebige Taste, um
Ausfahrt...");
getch();
Ausgang (1);
}
return *g.sectors; /* Gibt die Anzahl der
Sektoren auf Laufwerk */
}
vorzeichenlose lange Dateigröße=0, i=0;
vorzeichenloses langes Startdateiformat = 0, Enddateiformat = 0;
vorzeichenlose lange Sektoren_auf_HDD2=0, Schleife=0;
Zeichenpuffer[512], Dateiname[80], Temp[8];
Zeichenpfad[80];
vorzeichenloses int-Ergebnis, Num=0;
/* Header von Microsoft Word-Dateien */
Zeichenheader[10] = {0xD0,0xCF,0x11,0xE0, 0xA1,0xB1,0x1A,0xE1};
/* Fußzeile von Microsoft Word-Dateien */
char DOC_footer[14] =
{0x57,0x6F,0x72,0x64, 0x2E,0x44,0x6F,0x63,
0x75,0x6D,0x65,0x6E,0x74};
/// Beginn des Hauptteils \\\
void main()
{
clrscr();
/* Wenn die Gesamtzahl der angeschlossenen Festplatten kleiner ist
dann zwei, Fehlermeldung anzeigen und beenden. */
wenn(((char)peekb(0x0040, 0x0075))<2)
{
printf("\n\n Sie müssen mindestens zwei Festplatten haben
Zum Ausführen an Ihren Computer angeschlossen");
printf("\n Programm. Dieses Programm wurde entwickelt
um die Daten der zweiten Festplatte wiederherzustellen.");
printf("\n Zum Beenden eine beliebige Taste drücken... ");
getch();
Ausgang (1);
}
Sektoren_in_HDD2=getdrivegeometry (0x81);
printf("\n Gesamtzahl der Sektoren auf der zweiten Festplatte = %lu",
Sektoren_auf_HDD2);
printf("\n\n \"Sie müssen die wiederhergestellten Dateien speichern in
eine andere Festplatte, nicht auf derselben Festplatte");
printf("\n in dem du nach dem verlorenen
Daten.\"");
printf("\n\n Geben Sie den Zielpfad zum Speichern der
Wiederhergestellte Dateien...\n ");
bekommt(Pfad);
/* prüfen, ob das Zielverzeichnis existiert oder nicht */
wenn(Zugriff(Pfad, 0) != 0)
{
/* wenn das Zielverzeichnis nicht existiert, erstellen
das Verzeichnis bis zu einer Ebene */
if(mkdir(Pfad)!=0)
{
printf("\n Verzeichnis \"%s\" konnte nicht erstellt werden",
Weg);
printf("\n Pfad prüfen..., Drücken Sie eine beliebige Taste, um
Ausfahrt...");
getch();
Ausgang (1);
}
}
strcat(Pfad,"\\Ptt");
/* Funktion zum Ausblenden (und Anzeigen) des Cursors auf dem Bildschirm */
Cursor ein-/ausblenden ( 32,
gotoxy(15,18);cprintf("[ %d ] Wiederhergestellte Dateien...",
In);
/* Suche nach Daten bis zum letzten Sektor der Festplatte */
während(Schleife<Sektoren_auf_Festplatte2)
{
/* Einen Sektor lesen (Sektor-Nr. = Schleife) */
readabsolutesectors (0x81, Schleife, 1, Puffer);
gotoxy(19,16);cprintf("Scan-Sektornummer = % ld",
Schleife);
wenn(kbhit())
{
show_hide_cursor ( 6, 7 ); /* Abrufen der
Cursor vor
Beenden Sie das Programm
*/
Ausfahrt (0);
}
/* wenn angegebener Header gefunden wird */
wenn((memcmp (Puffer, Header,7))==0)
{
/* Logik zur Bereitstellung des Dateinamens für die automatische
Erstellen Sie die Dateien zum Speichern der wiederhergestellten Daten */
strcpy(Dateiname, Pfad);
itoa(Zahl,Temp,10);
strcat(Dateiname, temp);
strcat(Dateiname,".DOC");
start_file=loop; /* Startsektor der Datei */
gotoxy(5,19);cprintf("Datei gefunden..., Speichern unter %s",
Dateiname);
Zahl++;
////////////// Bedingungen zum Schließen der Datei \\\\\\\\\\\\\\\\\
Dateigröße=0;
während (Dateigröße < 5000000)
{
Schleife++;
Dateigröße+=512;
readabsolutesectors (0x81, Schleife, 1, Puffer);
gotoxy(19,16);cprintf("Scan-Sektornummer = % ld" ,
Schleife);
/* wenn die Dateigröße die maximale Größe von 5 MB erreicht */
wenn(Dateigröße>=5000000)
{
end_file=loop; /* Letzter Sektor der Datei */
Recover_the_file();/* Daten in Datei schreiben */
brechen;
}
/* wenn Fußzeile der DOC-Datei gefunden wird */
für (i = 0; i < 512; i++)
{
wenn (memcmp(Puffer+i,DOC_footer,12)==0)
{
end_file=loop; /* Letzter Sektor der Datei */
Recover_the_file();/* Daten in Datei schreiben */
brechen;
}
}
/* wenn ein anderer Header gefunden wird */
wenn (memcmp(Puffer,Header,7)==0)
{
Schleife=Schleife-1;
end_file=loop; /* Letzter Sektor der Datei */
Recover_the_file();/* Daten in Datei schreiben */
brechen;
}
wenn(kbhit())
{
Cursor ein-/ausblenden ( 6, 7 );
Ausfahrt (0);
}
}
}
Schleife++;
}
////////While-Schleife endet hier
/* Meldung zum Abschluss der Suche und Wiederherstellung anzeigen */ if(loop>=Sectors_in_HDD2 )
{
gotoxy(17,23);cprintf("Das Speichern von Dateien auf der Festplatte ist
Vollendet !!");
gotoxy(17,24);cprintf("Zum Beenden eine beliebige Taste drücken...");
Cursor ein-/ausblenden ( 6, 7 );
getch();
}
}
Die Strukturgeometrie wird von der Funktion getdrivegeometry mit der Erweiterung INT 13H, Funktionsnummer 0x48, verwendet, um die verschiedenen Parameter der Festplatte abzurufen.
Die Struktur „diskaddrpacket“ ist für das Disk-Adresspaketformat bestimmt und soll von der Funktion „readabsolutesectors“ verwendet werden.
Die Funktion getdrivegeometry (int drive) dient zum Abrufen der Laufwerksparameter der auf der Festplatte angegebenen physischen Laufwerksnummer.
(char) peekb(0x0040, 0x0075) wird verwendet, um die Anzahl der an den Computer angeschlossenen Festplatten zu ermitteln, die an der Speicherposition gespeichert sind, die durch das Segment 0040H:Offset 0075H dargestellt wird. Wenn die Gesamtzahl der angeschlossenen Festplatten kleiner als zwei ist, wird eine Fehlermeldung angezeigt und das System beendet.
Sectors_in_HDD2=getdrivegeometry (0x81); findet die verschiedenen Parameter der zweiten physischen Festplatte (0x81) und gibt die Gesamtzahl der Sektoren der Festplatte zurück.
Die Anweisung if(access(path, 0) != 0) prüft die Erreichbarkeit des vom Benutzer angegebenen Pfads. Wenn das Zielverzeichnis nicht existiert, wird das Ziel bis auf eine Ebene erstellt und wenn der durch die Bedingung if(mkdir(path)!=0) geprüfte angegebene Pfad ungültig ist, wird eine Fehlermeldung angezeigt.
Die Dateinamen der automatisch erstellten Dateien zum Speichern der wiederhergestellten Daten werden so erstellt, dass die ersten drei Zeichen der Dateien durch die Funktion strcat(path,"\\Ptt"); mit PTT versehen werden. Dies geschieht, um doppelte Dateinamen im Zielverzeichnis zu vermeiden. Daher werden die Dateinamen der wiederhergestellten Dateien im Format „PTTxxxxx.DOC“ angegeben.
Die Funktion show_hide_cursor (32, 0); wird verwendet, um den Cursor auf dem Bildschirm auszublenden, während show_hide_cursor (6, 7); den Cursor wieder auf den Bildschirm zurückholt.
Die Funktion readabsolutesectors (0x81, loop, 1, buffer); liest einen Sektor der zweiten physischen Festplatte, angegeben durch die Sektornummer „loop“.
Wenn der Header der Datei gefunden wird, setzt start_file = loop; die Startdatei auf die Startsektornummer der wiederherzustellenden Datei. Das Programm befolgt die drei nachstehenden Bedingungen, um den Endsektor der Datei zu finden:
- Wenn die Dateigröße die maximale Größe von 5 MB erreicht
- Wenn die Fußzeile einer DOC-Datei gefunden wird
- Wenn ein anderer Header gefunden wird
Die lange Ganzzahl end_file wird durch end_file=loop auf die letzte Sektornummer der Datei gesetzt, wenn eine von drei Bedingungen erfüllt ist. Nun werden die Daten der Sektoren, beginnend bei Sektornummer start_file bis Sektornummer end_file, mit der Funktion Recover_the_file( ) in der Datei gespeichert.
Nachfolgend ist die Kodierung der Funktion Recover_the_file( ) angegeben:
/* Funktion zum Speichern der Daten der Sektoren beginnend mit der Sektornummer start_file bis zur Sektornummer end_file */
Datei_wiederherstellen()
{
DATEI *fp;
wenn((fp=fopen(Dateiname, "wb"))==NULL)
{
gotoxy(10,23);printf("Fehler beim Öffnen der Datei %s",
Dateiname);
getch();
Ausgang (1);
}
für (i = Startdatei; i <= Dateiende; i++)
{
gotoxy(19,16);cprintf("Scan-Sektornummer =
%ld", i);
readabsolutesectors (0x81, i, 1, Puffer);
fwrite(Puffer,512,1, fp);
}
fschließen(fp);
gotoxy(15,18);cprintf("[ %d ] Wiederhergestellte Dateien...",num);
gotoxy(5,19);cprintf(" ");
zurückkehren;
}
Nachfolgend wird die Kodierung der Funktion readabsolutesectors beschrieben. Die Funktion verwendet die Erweiterung INT 13H und die Funktionsnummer 42H, um die Sektoren zu lesen.
Eine detaillierte Beschreibung der Funktion finden Sie im Kapitel „Backups erstellen“, das weiter oben in diesem Buch besprochen wurde. Die Codierung der Funktion lautet wie folgt:
//// Funktion zum Lesen absoluter Sektoren \\\\
int readabsolutesectors (int Laufwerk,
vorzeichenlose lange Sektornummer,
int AnzahlSektoren,
void *Puffer )
{
Gewerkschaftsreglemente i, o;
Struktur SREGS s;
Struktur Diskaddrpacket pp;
pp.packetsize = 16; /* Paketgröße = 10H */
pp.reserved = 0 ; /* Reserviert = 0 */
pp.blockcount = numofsectors; /* Anzahl der Sektoren
lesen */
/* für Datenpuffer */
pp.bufferaddress = (char far*) MK_FP ( FP_SEG((void far*)buffer), FP_OFF((void far*)buffer));
pp.blocknumber[0] = sectornumber ; /* Sektornummer
lesen */
pp.blocknumber[1] = 0 ; /* Blocknummer */
ihah = 0x42; /* Funktionsnummer*/
ihdl = Laufwerk; /* Physische Laufwerksnummer */
/* ds:si für Pufferparameter */
ixsi = FP_OFF ( (void far*)&pp ) ;
/* ds:si für Pufferparameter */
s.ds = FP_SEG ( (void far*)&pp ) ;
/* Rufen Sie die angegebene Funktion von INT 13H auf mit
Segmentregisterwerte */
int86x (0x13, &i, &o, &s);
wenn (oxcflag==1)
returniere 0; //Fehler
anders
return 1; // Erfolg
}
Mit der folgenden Funktion können Sie den Cursor auf dem Bildschirm ausblenden oder anzeigen. Die Funktion verwendet Interrupt 10H, Funktion 01H, um den Cursortyp festzulegen. Die Kodierung ist wie folgt:
Cursor ein-/ausblenden( ssl, esl )
ganze Zahlen ssl, esl;
{
Gewerkschaftsregister i, o;
Erhöhung = 1;
ihch = ssl;
ihcl = esl;
ihbh = 0;
int86 ( 16, &i, &o ) ;
Komm zurück;
}
show_hide_cursor( 32, 0 ) verbirgt den Cursor, und show_hide_cursor( 6, 7 ) bringt den Cursor zurück. „ssl“ ist die Startzeile für den Cursor und „esl“ ist die Endzeile für den Cursor.
Eine kurze Beschreibung der Funktion 01H INT 10H lautet wie folgt:
INT 10H (16 oder 0x10)
Funktion 01H (oder 0x01) --> Cursortyp festlegen
Anruf von: AH = 01H
Bits 0-4 CH = Startzeile für Cursor
CL-Bits 0-4 = Zeilenende für Cursor
Rückgabe: nichts.
Kommentare:
Mit dieser Funktion können Sie den Cursortyp festlegen, indem Sie die Start- und Endzeilen für den blinkenden Hardware-Cursor im Textanzeigemodus auswählen. Der Hardware-Cursor ist in den Grafikmodi nicht verfügbar.