Hoofdstuk – 14
Programmeren voor "Ruw bestand" herstel
Raw-bestandsherstel
Er zijn veel specifieke bestandstypen met een bepaalde volgorde of combinatie van tekens die aan het begin en einde van het bestand zijn geschreven. We kunnen deze combinaties gemakkelijk analyseren met behulp van elk schijfbewerkingsprogramma. We kunnen ook het EDIT-commando van DOS gebruiken om de structuur van een bestand in ASCII-formaat te bestuderen.
De specifieke tekenreeks of combinatie van tekens die aan het begin van het bestand aanwezig is, wordt meestal de koptekst genoemd en de reeks of combinatie van tekens die aan het einde van het bestand is opgeslagen, wordt de voettekst van het bestand genoemd.
Als we onze gegevens zijn kwijtgeraakt bij een dergelijk type schijfcrash dat er geen FAT- of rootdirectory-informatie beschikbaar is om de gegevens te herstellen, kunnen we kop- en voetteksten gebruiken om in deze specifieke bestandstypen te zoeken. De koptekst geeft het begin van het bestand van dat specifieke type aan en de voettekst geeft het einde aan van het bestand van dat specifieke bestandstype.
Hier gebruiken we de onbewerkte structuur van een bepaald bestandstype om de gegevens te herstellen, daarom wordt de hersteltechniek Raw Bestandsherstel genoemd. Het oppervlak van de schijf wordt sector voor sector doorzocht om de kop- en voettekstinformatie te vinden.
Hoewel Raw-bestandsherstel een breed toepassingsgebied kan hebben, zijn er enkele specifieke gevallen van herstel waarbij het veel kan helpen. Als u bijvoorbeeld per ongeluk een programma voor het wissen van gegevens op de schijf hebt uitgevoerd met enkele belangrijke bestanden, maar totdat u het programma stopt, wordt alle informatie van de MBR-, DBR-, FAT- en rootdirectory, inclusief besturingssysteembestanden, gewist.
In dat geval kunnen zelfs formatherstelprogramma's u niet helpen om de gegevens te herstellen. Hier kunt u Raw-bestandsherstel gebruiken om de bestanden van die specifieke bestandstypen te herstellen door in de kop- en voetteksten te zoeken.
Niet alleen dit, zelfs u kunt gegevens herstellen in dergelijke gevallen, waarbij u zo'n harde schijf hebt waarop u alle logische partities van de schijf hebt verwijderd, de partities van verschillende grootte opnieuw hebt gemaakt en zelfs u hebt geïnstalleerd het besturingssysteem.
Nu herinnert u zich dat u enkele belangrijke gegevens op de schijf had voordat u deze partitioneerde en formatteerde. Als je net het besturingssysteem hebt geïnstalleerd, is er een grote kans dat het bestand wordt hersteld.
De factoren die van invloed zijn op de prestaties van Raw File Recovery zijn: gefragmenteerde gegevens en de hoeveelheid gegevens die wordt overschreven door andere gegevens. U kunt echter zelf steeds meer toepassingsgebieden vinden voor het herstellen van onbewerkte bestanden.
De procedure of bijna de regels om de bestanden te doorzoeken met het programma voor het herstellen van onbewerkte bestanden, houdt rekening met de volgende voorwaarden:
- Zoek de header van het bestand of meerdere bestandstypes tegelijk in de sectoren van de schijf.
- Als een header van een bestandstype wordt gevonden, sla de gegevens dan op in een bestand en controleer de volgende vier voorwaarden om het bestand te sluiten en op te slaan
- De voettekst van dat bestandstype is gevonden
- Er is een andere kop van hetzelfde bestandstype gevonden
- De kop van een ander bestandstype is gevonden
- Er is geen andere kop- of voettekst voor de gedefinieerde bestandstypen in het programma gevonden en de grootte van het bestand waarin u de gegevens opslaat, bereikt de maximale groottelimiet, die u voor de bestandsgrootte in uw programma hebt gedefinieerd.
De informatie moet in het bestand worden opgeslagen, inclusief de gegevens van de sectoren waarin u de kop- en voetteksten van het bestandstype hebt gevonden.
Kop- en voetteksten van enkele belangrijke bestandstypen
De kop- en voetteksten van enkele belangrijke bestandstypen zijn weergegeven in de onderstaande tabel. De voetteksten in de tabel bevinden zich ofwel aan het einde van het bestand van het opgegeven bestandstype of bevinden zich in de eindverschuivingen van het bestand, zodat u ze als voetteksten kunt gebruiken om de gegevens te herstellen.
Je kunt ook zelf zoeken naar kop- en voetteksten, die verschillen van deze bestandstypen, door het EDIT-commando van DOS te gebruiken of door een schijfbewerkingstool te gebruiken. Ik heb het hexadecimale systeem gebruikt om de informatie weer te geven om het gemakkelijk te begrijpen te maken.
Extension |
Header (Hex) |
Footer (Hex) |
DOC |
D0 CF 11 E0 A1 B1 1A E1 |
57 6F 72 64 2E 44 6F 63 75 6D 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 |
ZIP |
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 (“Better To Use File size Check”) |
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 |
Een programma schrijven voor Raw File Recovery
De codering van het programma voor Raw-bestandsherstel van Microsoft Word-bestanden (.DOC-extensie) wordt hierna gegeven. Het programma zoekt naar de bestanden in de sectoren van de schijf en slaat het herstelde bestand automatisch op door de naam van het bestand automatisch aan te maken.
Het pad dat door de gebruiker is opgegeven om de bestanden op te slaan, wordt gebruikt als doelpad om de herstelde gegevens op te slaan. Als de doelmap niet bestaat, kan het programma de bestemming tot op één mapniveau maken.
Het hier gegeven herstelprogramma ondersteunt zelfs de grote schijven om de gegevens te zoeken en te herstellen. Het programma is geschreven om de gegevens op de tweede fysieke harde schijf te doorzoeken.
/* Raw-bestandsherstelprogramma om de Microsoft Word-bestanden te herstellen */
#include<stdio.h>
#include<dos.h>
/* Structure to be used by getdrivegeometry function using INT 13H Extension, Function Number 0x48. */
struct geometry
{
unsigned int size ; /* (call) size of Buffer */
unsigned int flags ; /* Information Flags */
unsigned long cyl ; /* Number of Physical
Cylinders on Drive */
unsigned long heads ;/* Number of Physical
Heads on Drive */
unsigned long spt ; /* Number of Physical
Sectors Per Track */
unsigned long sectors[2] ; /* Total Number of
Sectors on Drive */
unsigned int bps ; /* Bytes Per Sector */
} ;
/* Structure of Disk Address packet format, to be used by the readabsolutesectors Function */
struct diskaddrpacket
{
char packetsize ; /* Size of Packet, generally 10H */
char reserved ; /* Reserved (0) */
int blockcount ; /* Number of Blocks to Transfer */
char far *bufferaddress ; /* address to Transfer
Buffer */
unsigned long blocknumber[2] ; /* Starting Absolute
Block Number */
} ;
///// Functie om aandrijfparameters te krijgen: \\\\\
unsigned long getdrivegeometry (int drive)
{
union REGS i, o ;
struct SREGS s ;
struct geometry g = { 26, 0, 0, 0, 0, 0, 0, 0 } ;
i.h.ah = 0x48 ; /* Function Number 0x48 */
i.h.dl = drive; /* Drive Number */
i.x.si = FP_OFF ( (void far*)&g ) ;
s.ds = FP_SEG ( (void far*)&g ) ;
/* Invoke the specified function number of INT 13H extension with Segment Register Values */
int86x ( 0x13, &i, &o, &s ) ;
printf("\n Head = %lu, Sectors Per Track = %lu, Cylinder = %lu\n",
g.heads,g.spt,g.cyl);
/* If get drive Geometry function Fails, Display Error Message and Exit */
if(g.spt==0)
{
printf("\n Get Drive Geometry Function Fails....");
printf("\n Extensions Not Supported, Press any Key to
Exit...");
getch();
exit(1);
}
return *g.sectors; /* Return The Number of
Sectors on Drive */
}
unsigned long file_size=0, i=0;
unsigned long start_file=0, end_file=0;
unsigned long Sectors_in_HDD2=0, loop=0;
char buffer[512], filename[80], temp[8];
char path[80];
unsigned int result,num=0;
/* Koptekst van Microsoft Word-bestanden */
char header[10] = {0xD0,0xCF,0x11,0xE0, 0xA1,0xB1,0x1A,0xE1};
/* Footer of Microsoft Word Files */
char DOC_footer[14] =
{0x57,0x6F,0x72,0x64, 0x2E,0x44,0x6F,0x63,
0x75,0x6D,0x65,0x6E,0x74};
/// Start Of main \\\
void main()
{
clrscr();
/* If total no. of hard disks attached is less
then two, Display Error Message and Exit. */
if(((char)peekb(0x0040, 0x0075))<2)
{
printf("\n\n You Must Have At least Two Hard Disks
Attached to your Computer To Run This");
printf("\n Program. This Program has been developed
to recover the Data of Second Hard Disk.");
printf("\n Press any Key to Exit... ");
getch();
exit(1);
}
Sectors_in_HDD2=getdrivegeometry (0x81);
printf("\n Total Sectors in second Hard Disk = %lu",
Sectors_in_HDD2);
printf("\n\n \"You must save the recovered files in
another Hard Disk, Not in the Same Disk,");
printf("\n in which you are searching the lost
data.\"");
printf("\n\n Enter The Destination Path to save the
Recovered Files...\n ");
gets(path);
/* check if destination directory exists or Not */
if(access(path, 0) != 0)
{
/* if Destination directory does not exist, create
the Directory up to one level */
if(mkdir(path)!=0)
{
printf("\n Could Not Create Directory \"%s\"",
path);
printf("\n Check Path..., Press any key to
exit...");
getch();
exit(1);
}
}
strcat(path,"\\Ptt");
/* Functie om cursor op het scherm te verbergen (en weer te geven) */
show_hide_cursor ( 32,
gotoxy(15,18);cprintf("[ %d ] Files Recovered...",
num);
/* search for the data until the ending sector of the disk */
while(loop<Sectors_in_HDD2)
{
/* Read one Sector (Sector No. = loop) */
readabsolutesectors ( 0x81, loop, 1, buffer );
gotoxy(19,16);cprintf("Scanning Sector Number = % ld",
loop);
if(kbhit())
{
show_hide_cursor ( 6, 7 ); /* Retrieve the
cursor before
Exit the program
*/
exit(0);
}
/* if specified header is found */
if((memcmp ( buffer, header,7))==0)
{
/* logic to provide the file name to automatically
create the files to save the recovered data */
strcpy(filename, path);
itoa(num,temp,10);
strcat(filename, temp);
strcat(filename,".DOC");
start_file=loop; /* starting sector of file */
gotoxy(5,19);cprintf("File Found..., Saving As %s",
filename);
num++;
////////////// Voorwaarden voor het sluiten van bestanden \\\\\\\\\\\\\\\\
file_size=0;
while( file_size<5000000)
{
loop++;
file_size+=512;
readabsolutesectors ( 0x81, loop, 1, buffer );
gotoxy(19,16);cprintf("Scanning Sector Number = % ld" ,
loop);
/* if file size reaches up to maximum size of 5MB */
if(file_size>=5000000)
{
end_file=loop; /* Ending Sector of File */
Recover_the_file();/* write the data to file */
break;
}
/* if footer of DOC file is found */
for(i=0;i<512;i++)
{
if( memcmp(buffer+i,DOC_footer,12)==0 )
{
end_file=loop; /* Ending Sector of File */
Recover_the_file();/* write the data to file */
break;
}
}
/* if another header is found */
if( memcmp(buffer,header,7)==0 )
{
loop=loop-1;
end_file=loop; /* Ending Sector of File */
Recover_the_file();/* write the data to file */
break;
}
if(kbhit())
{
show_hide_cursor ( 6, 7 );
exit(0);
}
}
}
loop++;
}
////////Terwijl de lus hier eindigt
/* display message for completion of search and recovery */ if(loop>=Sectors_in_HDD2 )
{
gotoxy(17,23);cprintf("The Saving of files in the Disk is
Completed !!");
gotoxy(17,24);cprintf("Press Any Key to Exit...");
show_hide_cursor ( 6, 7 );
getch();
}
}
De structuurgeometrie wordt gebruikt door de getdrivegeometry-functie met behulp van INT 13H Extension, functienummer 0x48 om de verschillende parameters van de schijf te krijgen.
De structuur diskaddrpacket is voor het schijfadrespakketformaat, te gebruiken door de readabsolutesectors-functie.
De functie getdrivegeometry (int drive) is om Drive-parameters op te halen van het door de schijf gespecificeerde fysieke drivenummer.
(char) peekb(0x0040, 0x0075) wordt gebruikt om het aantal harde schijven te vinden dat op de computer is aangesloten, opgeslagen op de geheugenlocatie weergegeven door segment 0040H:offset 0075H. Als het totale aantal aangesloten harde schijven minder is dan twee Display Error Message en Exit.
Sectors_in_HDD2=getdrivegeometry (0x81); vindt de verschillende parameters van de tweede fysieke harde schijf (0x81) en geeft het totale aantal sectoren van de schijf terug.
Het statement if(access(path, 0) != 0) controleert de toegankelijkheid van het door de gebruiker opgegeven pad. Als de bestemmingsmap niet bestaat, wordt de bestemming tot op één niveau gemaakt en als het gegeven pad gecontroleerd door voorwaarde if(mkdir(pad)!=0) illegaal is, wordt een foutmelding weergegeven.
De bestandsnamen van automatisch gemaakte bestanden om de herstelde gegevens op te slaan, worden zo gemaakt dat de eerste drie tekens van de bestanden PTT worden gegeven door strcat(pad,"\\Ptt"); functie. Dit wordt gedaan om dubbele bestandsnamen in de doelmap te voorkomen. Daarom worden de bestandsnamen van herstelde bestanden gegeven in het formaat “PTTxxxxx.DOC”
De functie show_hide_cursor ( 32, 0 ); wordt gebruikt om de cursor van het scherm te verbergen waar show_hide_cursor ( 6, 7 ); haalt de cursor terug naar het scherm.
De functie readabsolutesectors (0x81, loop, 1, buffer); Leest één Sector van de tweede fysieke harde schijf gespecificeerd door sectornummerlus.
Als de header van het bestand wordt gevonden, start_file = loop; stelt het start_bestand in op het startsectornummer van het te herstellen bestand. Het programma volgt de drie hierna gegeven voorwaarden om de eindsector van het bestand te vinden:
- Als de bestandsgrootte de maximale grootte van 5 MB bereikt
- Als voettekst van DOC-bestand wordt gevonden
- Als een andere kop wordt gevonden
De lange integer end_file wordt ingesteld op het laatste sectornummer van het bestand door end_file=loop; als aan één van de drie voorwaarden is voldaan. Nu worden de gegevens van de sectoren, beginnend van sectornummer start_file tot sectornummer end_file, in het bestand opgeslagen met de functie Recover_the_file( ).
De codering van de functie Recover_the_file( ) is als volgende gegeven:
/* Functie om de gegevens van de sectoren op te slaan vanaf sectornummer start_file tot sectornummer end_file */
Recover_the_file()
{
FILE *fp;
if((fp=fopen(filename, "wb"))==NULL)
{
gotoxy(10,23);printf("Error Opening File %s",
filename);
getch();
exit(1);
}
for(i=start_file;i<=end_file;i++)
{
gotoxy(19,16);cprintf("Scanning Sector Number =
%ld", i);
readabsolutesectors ( 0x81, i, 1, buffer );
fwrite(buffer,512,1, fp);
}
fclose(fp);
gotoxy(15,18);cprintf("[ %d ] Files Recovered...",num);
gotoxy(5,19);cprintf(" ");
return;
}
Hierna volgt de codering van de functie readabsolutesectors. De functie gebruikt de INT 13H Extensie en functienummer 42H om de sectoren uit te lezen.
Raadpleeg het hoofdstuk "Back-ups maken" dat eerder in dit boek is besproken voor de gedetailleerde beschrijving van de functie. De codering van de functie is als volgt:
//// Functie om absolute sector(en) te lezen \\\\
int readabsolutesectors ( int drive,
unsigned long sectornumber,
int numofsectors,
void *buffer )
{
union REGS i, o ;
struct SREGS s ;
struct diskaddrpacket pp ;
pp.packetsize = 16 ; /* packet size = 10H */
pp.reserved = 0 ; /* Reserved = 0 */
pp.blockcount = numofsectors ; /* Number of sectors
to read */
/* for Data buffer */
pp.bufferaddress = (char far*) MK_FP ( FP_SEG((void far*)buffer), FP_OFF((void far*)buffer));
pp.blocknumber[0] = sectornumber ; /* Sector number
to read */
pp.blocknumber[1] = 0 ; /* Block number */
i.h.ah = 0x42 ; /* Function Number*/
i.h.dl = drive ; /* Physical Drive Number */
/* ds:si for buffer Parameters */
i.x.si = FP_OFF ( (void far*)&pp ) ;
/* ds:si for buffer Parameters */
s.ds = FP_SEG ( (void far*)&pp ) ;
/* Invoke the specified Function of INT 13H with
segment register values */
int86x ( 0x13, &i, &o, &s ) ;
if ( o.x.cflag==1)
return 0 ; //failure
else
return 1 ; // success
}
De volgende functie wordt gebruikt om de cursor op het scherm te verbergen of weer te geven. De functie gebruikt Interrupt 10H, Function 01H om het cursortype in te stellen. De codering is als volgt:
show_hide_cursor( ssl, esl )
int ssl, esl ;
{
union REGS i, o ;
i.h.ah = 1 ;
i.h.ch = ssl ;
i.h.cl = esl ;
i.h.bh = 0 ;
int86 ( 16, &i, &o ) ;
return;
}
show_hide_cursor( 32, 0 ) verbergt de cursor en show_hide_cursor( 6, 7 ) haalt de cursor terug. ssl is de beginregel voor de cursor en esl is de eindregel voor de cursor.
De kleine beschrijving van Functie 01H van INT 10H is als volgt:
INT 10H (16 or 0x10)
Function 01H (or 0x01) --> Set Cursor Type
Call with: AH = 01H
CH bits 0-4 = starting line for cursor
CL bits 0-4 = ending line for cursor
Returns: Nothing.
Comments:
De functie wordt gebruikt om het cursortype in te stellen door de begin- en eindregels voor de knipperende hardwarecursor in de tekstweergavemodus te selecteren. In de grafische modi is de hardwarecursor niet beschikbaar.
Pagina aangepast op: 17/01/2022