Глава – 14
Программирование для восстановления "Raw File"
Восстановление необработанных файлов
Существует много конкретных типов файлов, которые имеют определенную последовательность или комбинацию символов, записанных в начале и в конце файла. Мы можем легко проанализировать эти комбинации с помощью любой программы для редактирования дисков. Мы также можем использовать команду EDIT DOS для изучения структуры файла в формате ASCII.
Определенная последовательность или комбинация символов, которая присутствует в начале файла, обычно называется заголовком, а последовательность или комбинация символов, которая хранится в конце файла, называется нижним колонтитулом файла.
Если мы потеряли наши данные в результате сбоя диска такого типа, что информация FAT или корневого каталога недоступна для восстановления данных, мы можем использовать верхние и нижние колонтитулы для поиска этих конкретных типов файлов. Заголовок указывает на начало файла этого конкретного типа, а нижний колонтитул указывает на конец файла этого конкретного типа файла.
Здесь мы используем необработанную структуру файлов определенного типа для восстановления данных, поэтому метод восстановления называется восстановлением необработанных файлов. Поверхность диска просматривается сектор за сектором, чтобы найти информацию заголовка и нижнего колонтитула.
Хотя Raw File Recovery может иметь широкую область применения, но есть некоторые конкретные случаи восстановления, где это может очень помочь. Например, по ошибке, если вы запустили какую-либо программу очистки данных на диске, на котором были важные файлы, но до тех пор, пока вы не остановите программу, вся информация MBR, DBR, FAT и корневого каталога, включая файлы операционной системы, будет удалена.
В таком случае даже программы восстановления форматов могут не помочь вам восстановить данные. Здесь вы можете использовать Raw File Recovery для восстановления файлов этих конкретных типов путем поиска в верхних и нижних колонтитулах.
Не только это, вы даже можете восстановить данные в таких случаях, когда у вас есть такой жесткий диск, на котором вы удалили все логические разделы диска, воссоздали разделы другого размера, чем раньше, и даже вы установили операционная система.
Теперь вы вспоминаете, что у вас были важные данные на диске до его разметки и форматирования. Если вы только что установили операционную систему, есть много шансов восстановить файл.
На производительность восстановления необработанных файлов влияют следующие факторы: фрагментированные данные и количество данных, перезаписанных другими данными. Однако вы сами можете найти все больше и больше областей применения для восстановления необработанных файлов.
Процедура или почти правила поиска файлов с помощью программы восстановления необработанных файлов учитывают следующие условия:
- Поиск заголовка файла или нескольких типов файлов одновременно в секторах диска.
- Если найден заголовок файла любого типа, сохраните данные в файле и проверьте следующие четыре условия, чтобы закрыть и сохранить файл.
- Найден нижний колонтитул файла этого типа
- Обнаружен другой заголовок того же типа файла
- Обнаружен заголовок файла другого типа
- Другой верхний или нижний колонтитул для определенных типов файлов в программе не найден, а размер файла, в котором вы сохраняете данные, достигает максимального предела размера, который вы определили для размера файла в вашей программе.
Информация должна храниться в файле, включая данные секторов, в которых вы нашли верхний и нижний колонтитулы типа файла.
Верхние и нижние колонтитулы некоторых важных типов файлов
В следующей таблице приведены верхние и нижние колонтитулы некоторых важных типов файлов. Нижние колонтитулы, указанные в таблице, находятся либо в конце файла указанного типа файла, либо в конечных смещениях файла, чтобы их можно было использовать в качестве нижних колонтитулов для восстановления данных.
Вы также можете сами искать верхние и нижние колонтитулы, отличные от файлов этих типов, с помощью команды EDIT в DOS или с помощью любого инструмента редактирования диска. Я использовал шестнадцатеричную систему для представления информации, чтобы ее было легко понять.
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 |
Написание программы для восстановления необработанных файлов
Код программы для Raw File Recovery файлов Microsoft Word (расширение .DOC) приведен ниже. Программа ищет файлы в секторах диска и автоматически сохраняет восстановленный файл, автоматически создавая имя файла.
Путь, указанный пользователем для сохранения файлов, используется в качестве пути назначения для сохранения восстановленных данных. Если каталог назначения не существует, программа может создать его до одного уровня каталога.
Приведенная здесь программа восстановления поддерживает даже диски большого размера для поиска и восстановления данных. Программа была написана для поиска данных на втором физическом жестком диске.
/* Программа Raw File Recovery для восстановления файлов Microsoft Word */
#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 */
} ;
///// Функция для получения параметров привода \\\\\
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;
/* Заголовок файлов Microsoft Word */
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");
/* Функция для скрытия (и отображения) курсора на экране */
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_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++;
}
////////Пока цикл заканчивается здесь
/* 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();
}
}
Геометрия структуры используется функцией getdrivegeometry с расширением INT 13H, номер функции 0x48 для получения различных параметров диска.
Структура diskaddrpacket предназначена для формата пакета адреса диска, используемого функцией readabsolutesectors.
Функция getdrivegeometry (int drive) предназначена для получения параметров диска с указанным номером физического диска.
(char) peekb(0x0040, 0x0075) используется для поиска количества жестких дисков, подключенных к компьютеру, хранящихся в ячейке памяти, представленной сегментом 0040H: смещение 0075H. Если общее количество подключенных жестких дисков меньше двух, отобразить сообщение об ошибке и выйти.
Sectors_in_HDD2=getdrivegeometry (0x81); находит различные параметры второго физического жесткого диска (0x81) и возвращает общее количество секторов диска.
Утверждение if(access(path, 0) != 0) проверяет доступность пути, заданного пользователем. Если каталог назначения не существует, создается место назначения до одного уровня, и если заданный путь проверяется условием if(mkdir(path)!=0) недопустимо, отображается сообщение об ошибке.
Имена автоматически создаваемых файлов для сохранения восстановленных данных создаются таким образом, что первые три символа файлов задаются PTT с помощью strcat(path,"\\Ptt"); функция. Это сделано для того, чтобы избежать дублирования имен файлов в целевом каталоге. Поэтому имена восстановленных файлов даются в формате «PTTxxxxx.DOC»
Функция show_hide_cursor ( 32, 0 ); используется для скрытия курсора с экрана, где show_hide_cursor ( 6, 7 ); возвращает курсор обратно на экран.
Функция чтения абсолютных секторов (0x81, цикл, 1, буфер); Читает один сектор второго физического жесткого диска, заданного циклом номеров секторов.
Если найден заголовок файла, start_file = loop; устанавливает start_file равным номеру начального сектора восстанавливаемого файла. Программа следует трем приведенным далее условиям, чтобы найти конечный сектор файла:
- Если размер файла достигает максимального размера 5 МБ
- Если найден нижний колонтитул файла DOC
- Если найден другой заголовок
Длинное целое число end_file устанавливается равным номеру конечного сектора файла с помощью end_file=loop; если выполнено любое одно условие из трех. Теперь данные секторов, начиная с сектора с номером start_file до сектора с номером end_file, сохраняются в файл с помощью функции Recover_the_file().
Код функции Recover_the_file() приведен ниже:
/* Функция для сохранения данных секторов, начиная с номера сектора start_file до номера сектора 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;
}
Далее приведено кодирование функции readabsolutesectors. Функция использует расширение INT 13H и номер функции 42H для чтения секторов.
Подробное описание функции см. в главе «Создание резервных копий», рассмотренной ранее в этой книге. Код функции следующий:
//// Функция для чтения абсолютных секторов \\\\
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 для установки типа курсора. Кодировка выглядит следующим образом:
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 ) скрывает курсор, а show_hide_cursor( 6, 7 ) извлекает курсор обратно. ssl — это начальная строка для курсора, а esl — конечная строка для курсора.
Небольшое описание функции 01H INT 10H выглядит следующим образом:
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:
Функция используется для установки типа курсора путем выбора начальной и конечной строк для мигающего аппаратного курсора в режиме отображения текста. В графических режимах аппаратный курсор недоступен.
Страница изменена: 16/03/2022