Hoofdstuk – 14
PROGRAMMERING VOOR HERSTEL VAN RAW-BESTANDEN
Raw-bestanden herstellen
Er zijn veel specifieke bestandstypen waarbij aan het begin en einde van het bestand een specifieke volgorde of combinatie van tekens staat. Deze combinaties kunnen we eenvoudig analyseren met elk schijfbewerkingsprogramma. We kunnen ook de DOS-opdracht EDIT gebruiken om de structuur van een ASCII-bestand te onderzoeken.
Een bepaalde reeks of combinatie van tekens aan het begin van een bestand wordt doorgaans een header genoemd. Een reeks of combinatie van tekens die aan het einde van een bestand is opgeslagen, wordt een footer van het bestand genoemd.
Als we gegevens zijn verloren door een schijfstoring waarbij er geen FAT- of hoofddirectorygegevens beschikbaar zijn om de gegevens te herstellen, kunnen we kop- en voetteksten gebruiken om deze specifieke bestandstypen te vinden. De header geeft het begin van een bestand van dat specifieke bestandstype aan, en de footer geeft het einde van een bestand van dat specifieke bestandstype aan.
Hierbij gebruiken we de ruwe structuur van een bepaald bestandstype om gegevens te herstellen. Deze herstelmethode wordt daarom Raw File Recovery genoemd. Het schijfoppervlak wordt sector voor sector gescand om kop- en voettekstinformatie te vinden.
Hoewel Raw File Recovery een breed scala aan toepassingen kent, zijn er enkele speciale herstelgevallen waarbij het erg nuttig kan zijn. Als u bijvoorbeeld per ongeluk een programma voor het wissen van gegevens uitvoert op een schijf waarop belangrijke bestanden staan, worden alle MBR-, DBR-, FAT- en rootdirectorygegevens, inclusief de bestanden van het besturingssysteem, gewist totdat u het programma stopt.
In dit geval kunnen zelfs format-herstelprogramma's u niet helpen bij het herstellen van gegevens. Hier kunt u Raw File Recovery gebruiken om bestanden van deze specifieke bestandstypen te herstellen door te zoeken in kop- en voetteksten.
Bovendien kunt u zelfs gegevens herstellen als u een harde schijf hebt waarop u alle logische partities hebt verwijderd, partities met een andere grootte dan voorheen hebt aangemaakt of zelfs een besturingssysteem hebt geïnstalleerd.
Nu krijgt u het geheugen terug dat er belangrijke gegevens op de schijf stonden voordat deze werd gepartitioneerd en geformatteerd. Als u het besturingssysteem net hebt geïnstalleerd, is de kans groot dat het bestand kan worden hersteld.
Factoren die de prestaties van het herstel van onbewerkte bestanden beïnvloeden, zijn gefragmenteerde gegevens en de hoeveelheid gegevens die door andere gegevens wordt overschreven. Er zijn echter steeds meer toepassingen waarmee u zelf ruwe bestanden kunt herstellen.
De procedure of bijna regels voor het zoeken naar bestanden met behulp van software voor het herstellen van onbewerkte bestanden houden rekening met de volgende voorwaarden:
- Zoek naar een bestandsheader of meerdere bestandstypen tegelijkertijd in schijfsectoren.
- Als er een bestandstypeheader wordt gevonden, slaat u de gegevens in het bestand op en controleert u de volgende vier voorwaarden om het bestand te sluiten en op te slaan.
- Voettekst van dit bestandstype gevonden
- Er is een andere header van hetzelfde bestandstype gevonden.
- Header van een ander bestandstype gevonden
- Er zijn geen andere kop- of voetteksten gevonden voor bepaalde bestandstypen in het programma en de bestandsgrootte waarin u de gegevens opslaat, bereikt de maximale bestandsgrootte die u in uw programma hebt gedefinieerd.
De informatie moet in het bestand worden opgeslagen, inclusief de sectorgegevens waar u de kop- en voettekst van het bestandstype hebt gevonden.
Kop- en voetteksten van enkele belangrijke bestandstypen
De kop- en voetteksten van enkele belangrijke bestandstypen vindt u in de onderstaande tabel. De voetteksten die in de tabel worden vermeld, bevinden zich óf aan het einde van het bestand van het opgegeven bestandstype, óf aan de eindoffsets van het bestand. U kunt ze dus gebruiken als voetteksten voor gegevensherstel.
U kunt ook zelf naar andere kop- en voetteksten dan deze bestandstypen zoeken met de DOS-opdracht EDIT of met een ander hulpprogramma voor schijfbewerking. Om de informatie begrijpelijker te maken, heb ik het hexadecimale stelsel gebruikt.
Verlenging |
Koptekst (Hexadecimaal) |
Voettekst (Hex) |
DOC |
D0 CF 11 E0 A1 B1 1A E1 |
57 6Ф 72 64 2Э 44 6Ф 63 75 6Г 65 6Э 74 2Э |
XLS |
Д0 CF 11 Е0 А1 В1 1А Е1 |
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 |
ППT |
Д0 CF 11 Е0 А1 В1 1А Е1 |
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 |
Почтовый индекс |
50 4Б 03 04 14 |
50 4Б 05 06 00 |
JPG |
ФФ Д8 ФФ Е0 00 10 4А 46 49 46 00 01 01 |
D9 («Лучше использовать проверку размера файла») |
GIF |
47 49 46 38 39 61 4E 01 53 00 C4 |
21 00 00 3Б 00 |
PDF |
25 50 44 46 2D 31 2E |
25 25 45 4Ф 46 |
Написание программы для восстановления необработанных файлов
Далее приведена кодировка программы для Raw File Recovery файлов Microsoft Word (расширение .DOC). Программа ищет файлы в секторах диска и автоматически сохраняет восстановленный файл, автоматически создавая имя файла.
Путь, указанный пользователем для сохранения файлов, используется как путь назначения для сохранения восстановленных данных. Если каталог назначения не существует, программа может создать его до одного уровня каталога.
Программа восстановления, представленная здесь, поддерживает даже диски большого размера для поиска и восстановления данных. Программа была написана для поиска данных на втором физическом жестком диске.
/* Программа восстановления необработанных файлов Microsoft Word */
#include<stdio.h>
#include<dos.h>
/* Структура, используемая функцией getdrivegeometry с использованием расширения INT 13H, номер функции 0x48. */
структурная геометрия
{
unsigned int size ; /* (вызов) размер буфера */
unsigned int flags ; /* Информационные флаги */
unsigned long cyl ; /* Количество физических
Цилиндры на приводе */
беззнаковые длинные заголовки ;/* Количество физических
Головы на приводе */
unsigned long spt ; /* Количество физических
Секторов на дорожку */
unsigned long sector[2] ; /* Общее количество
Сектора на диске */
unsigned int bps ; /* Байт на сектор */
} ;
/* Структура формата пакета адреса диска, используемая функцией readabsolutesectors */
структура diskaddrpacket
{
char packetsize ; /* Размер пакета, обычно 10H */
символ зарезервирован ; /* Зарезервировано (0) */
int blockcount ; /* Количество блоков для передачи */
char far *bufferaddress ; /* адрес для передачи
Буфер */
unsigned long blocknumber[2] ; /* Начальный абсолютный
Номер блока */
} ;
///// Функция для получения параметров привода \\\\\
беззнаковый длинный getdrivegeometry (целый диск)
{
профсоюз РЕГС i, o ;
структура SREGS s ;
структурная геометрия g = { 26, 0, 0, 0, 0, 0, 0, 0 } ;
ihah = 0x48 ; /* Номер функции 0x48 */
ihdl = drive; /* Номер диска */
ixsi = FP_OFF ( (void far*)&g ) ;
s.ds = FP_SEG ( (void far*)&g ) ;
/* Вызов указанного номера функции расширения INT 13H со значениями сегментного регистра */
int86x ( 0x13, &i, &o, &s ) ;
printf("\n Головка = %lu, Секторов на дорожку = %lu, Цилиндр = %lu\n",
г.головки, г.спц, г.цил);
/* Если функция получения геометрии диска не удалась, вывести сообщение об ошибке и выйти */
если(г.спт==0)
{
printf("\n Функция получения геометрии привода не выполнена....");
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;
/* Header of Microsoft Word Files */
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");
/* Function to Hide (and show) Cursor on the screen */
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++;
////////////// File Close Conditions \\\\\\\\\\\\\\\\
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++;
}
////////While Loop Ends Here
/* 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();
}
}
The structure geometry is used by getdrivegeometry function using INT 13H Extension, Function Number 0x48 to get the various parameters of the disk.
The structure diskaddrpacket is for Disk Address packet format, to be used by the readabsolutesectors Function.
The Function getdrivegeometry (int drive) is to get Drive Parameters of the disk specified physical drive number drive.
(char) peekb(0x0040, 0x0075) is used to find the number of hard disks connected to the computer, stored at memory location represented by segment 0040H:offset 0075H. If total number of hard disks attached is less then two Display Error Message and Exit.
Sectors_in_HDD2=getdrivegeometry (0x81); finds the various parameters of the second physical hard disk (0x81) and returns the total number of sectors of the disk.
The statement if(access(path, 0) != 0) checks the accessibility of the path given by the user. If destination directory does not exist, the destination is created up to one level and if the given path checked by condition if(mkdir(path)!=0) is illegal, error message is displayed.
The file names of automatically created files to save the recovered data are created such that the first three characters of the files are given PTT by strcat(path,"\\Ptt"); function. It is done so to avoid the duplicate file names in the destination directory. Therefore the file names of recovered files are given in format of “PTTxxxxx.DOC”
The Function show_hide_cursor ( 32, 0 ); is used to Hide the Cursor from the screen where show_hide_cursor ( 6, 7 ); retrieves the cursor back to screen.
The function readabsolutesectors (0x81, loop, 1, buffer); Reads one Sector of the second physical hard disk specified by sector number loop.
If the header of the file is found, start_file = loop; sets the start_file to starting sector number of the file to be recovered. The program follows the three conditions given next, to find the ending sector of the file:
- If file size reaches up to maximum size of 5MB
- If footer of DOC file is found
- If another header is found
The long integer end_file is set to the ending sector number of the file by end_file=loop; if any one condition out of three is satisfied. Now the data of the sectors, starting from sector number start_file to sector number end_file is saved to the file with the function Recover_the_file( ).
The coding of the function Recover_the_file( ) has been given next:
/* Function to save the data of the sectors starting from sector number start_file to sector number 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;
}
The coding of the function readabsolutesectors has been given next. The function uses the INT 13H Extension and function number 42H to read the sectors.
For the detailed description of the function, refer the chapter “Making Backups” discussed earlier in this book. The coding of the function is as follows:
//// Function to read absolute sector(s) \\\\
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
}
Следующая функция используется для скрытия или отображения курсора на экране. Функция использует прерывание 10H, функцию 01H для установки типа курсора. Кодировка следующая:
показать_скрыть_курсор( ssl, esl )
целые ssl, esl ;
{
профсоюз РЕГС i, o ;
toename = 1 ;
ihch = ssl ;
ihcl = esl ;
ihbh = 0 ;
int86 ( 16, &i, &o );
kom terug;
}
show_hide_cursor( 32, 0 ) verbergt de cursor, en show_hide_cursor( 6, 7 ) brengt de cursor terug. ssl is de beginregel voor de cursor en esl is de eindregel voor de cursor.
Een korte beschrijving van de 01H INT 10H-functie is als volgt:
INT 10H (16 of 0x10)
Functie 01H (of 0x01) --> Cursortype instellen
Bellen vanaf: AH = 01H
Bits 0-4 CH = Startregel voor cursor
CL bits 0-4 = eindregel voor cursor
Retour: niets.
Reacties:
Met deze functie kunt u het cursortype instellen door de begin- en eindregels voor de knipperende hardwarecursor in de tekstweergavemodus te selecteren. De hardwarecursor is niet beschikbaar in de grafische modus.