Глава – 14
ПРОГРАММИРОВАНИЕ ДЛЯ ВОССТАНОВЛЕНИЯ «RAW-ФАЙЛА»
Восстановление необработанных файлов
Существует множество определенных типов файлов, которые имеют определенную последовательность или комбинацию символов, записанных в начале и конце файла. Мы можем легко проанализировать эти комбинации с помощью любой программы редактирования диска. Мы также можем использовать команду EDIT DOS для изучения структуры файла в формате ASCII.
Конкретная последовательность или комбинация символов, присутствующая в начале файла, обычно называется заголовком, а последовательность или комбинация символов, которая хранится в конце файла, называется нижним колонтитулом файла.
Если мы потеряли наши данные в таком типе сбоя диска, что нет информации FAT или корневого каталога для восстановления данных, мы можем использовать заголовки и нижние колонтитулы для поиска этих конкретных типов файлов. Заголовок указывает на начало файла этого конкретного типа, а нижний колонтитул указывает на конец файла этого конкретного типа файла.
Здесь мы используем необработанную структуру определенного типа файла для восстановления данных, поэтому метод восстановления называется Raw File Recovery. Поверхность диска просматривается сектор за сектором для поиска информации заголовка и нижнего колонтитула.
Хотя Raw File Recovery может иметь широкую область применения, но есть некоторые особые случаи восстановления, где он может очень помочь. Например, по ошибке, если вы запустили какую-либо программу стирания данных на диске, на котором были некоторые важные файлы, но пока вы не остановите программу, вся информация MBR, DBR, FAT и корневого каталога, включая файлы операционной системы, будет стерта.
В таком случае даже программы восстановления формата могут не помочь вам восстановить данные. Здесь вы можете использовать Raw file Recovery для восстановления файлов этих конкретных типов файлов, выполняя поиск в заголовках и нижних колонтитулах.
Мало того, вы даже можете восстановить данные в таких случаях, когда у вас есть жесткий диск, на котором вы удалили все логические разделы диска, заново создали разделы другого размера, чем прежде, и даже установили операционную систему.
Теперь вы получаете воспоминание, что у вас были некоторые важные данные на диске до его разбиения на разделы и форматирования. Если вы только что установили операционную систему, есть много шансов, что файл будет восстановлен.
Факторы, которые влияют на производительность восстановления необработанных файлов, это фрагментированные данные и объем данных, перезаписанных другими данными. Однако вы можете самостоятельно найти все больше и больше областей применения для восстановления необработанных файлов.
Процедура или почти правила поиска файлов с помощью программы восстановления необработанных файлов учитывают следующие условия:
- Поиск заголовка файла или нескольких типов файлов одновременно в секторах диска.
- Если найден заголовок любого типа файла, сохраните данные в файле и проверьте следующие четыре условия, чтобы закрыть и сохранить файл.
- Найден нижний колонтитул этого типа файла
- Найден другой заголовок того же типа файла.
- Найден заголовок другого типа файла
- Никаких других заголовков или нижних колонтитулов для определенных типов файлов в программе не найдено, а размер файла, в котором вы сохраняете данные, достигает максимального предела размера, который вы определили для размера файла в своей программе.
Информация должна быть сохранена в файле, включая данные секторов, в которых вы нашли верхний и нижний колонтитулы типа файла.
Верхние и нижние колонтитулы некоторых важных типов файлов
Верхние и нижние колонтитулы некоторых важных типов файлов приведены в таблице, приведенной ниже. Нижние колонтитулы, приведенные в таблице, находятся либо в конце файла указанного типа файла, либо в конечных смещениях файла, так что вы можете использовать их в качестве нижних колонтитулов для восстановления данных.
Вы также можете самостоятельно искать заголовки и колонтитулы, отличные от этих типов файлов, используя команду EDIT DOS или используя любой инструмент редактирования диска. Я использовал шестнадцатеричную систему для представления информации, чтобы сделать ее более понятной.
Расширение |
Заголовок (шестнадцатеричный) |
Нижний колонтитул (шестнадцатеричный) |
ДОК |
Д0 CF 11 Е0 А1 В1 1А Е1 |
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 ;
ихах = 1 ;
ihch = ssl ;
ihcl = esl ;
ihbh = 0 ;
int86 ( 16, &i, &o ) ;
возвращаться;
}
show_hide_cursor( 32, 0 ) скрывает курсор, а show_hide_cursor( 6, 7 ) возвращает курсор обратно. ssl — начальная строка для курсора, а esl — конечная строка для курсора.
Краткое описание функции 01H INT 10H выглядит следующим образом:
INT 10H (16 или 0x10)
Функция 01H (или 0x01) --> Установить тип курсора
Звонок с: AH = 01H
Биты 0-4 CH = начальная строка для курсора
Биты CL 0-4 = конечная строка для курсора
Возврат: ничего.
Комментарии:
Функция используется для установки типа курсора путем выбора начальной и конечной строк для мигающего аппаратного курсора в режиме отображения текста. В графических режимах аппаратный курсор недоступен.