Capítulo – 14
Programación para la recuperación de "archivo sin procesar"
Recuperación de archivos sin formato
Hay muchos tipos de archivos específicos que tienen una secuencia específica o una combinación de caracteres escritos al principio y al final del archivo. Podemos analizar estas combinaciones fácilmente con la ayuda de cualquier programa de edición de discos. También podemos usar el comando EDIT de DOS para estudiar la estructura del archivo en formato ASCII.
La secuencia específica o combinación de caracteres que está presente al comienzo del archivo generalmente se denomina encabezado y la secuencia o combinación de caracteres que se almacena al final del archivo se denomina pie de página.
Si hemos perdido nuestros datos en un tipo de bloqueo de disco tal que no hay información de directorio raíz o FAT disponible para recuperar los datos, podemos usar encabezados y pies de página para buscar estos tipos de archivos específicos. El encabezado indica el inicio del archivo de ese tipo en particular y el pie de página indica el final del archivo de ese tipo de archivo en particular.
Aquí estamos usando la estructura sin procesar de un tipo de archivo particular para recuperar los datos, por lo tanto, la técnica de recuperación se llama Recuperación de archivos sin procesar. Se busca en la superficie del disco sector por sector para encontrar la información de encabezado y pie de página.
Aunque Raw File Recovery puede tener una amplia área de aplicación, hay algunos casos específicos de recuperación en los que puede ayudar mucho. Por ejemplo, por error, si ejecutó algún programa de borrado de datos en el disco que tenía algunos archivos importantes, pero hasta que detenga el programa, toda la información de MBR, DBR, FAT y el directorio raíz, incluidos los archivos del sistema operativo, se borrarán.
En tal caso, es posible que incluso los programas de recuperación de formato no le ayuden a recuperar los datos. Aquí puede usar la recuperación de archivos sin procesar para recuperar los archivos de esos tipos de archivos específicos buscando en los encabezados y pies de página.
No solo esto, incluso usted puede recuperar datos en tales casos, donde tiene un disco duro en el que ha eliminado todas las particiones lógicas del disco, ha recreado las particiones de diferente tamaño que antes e incluso ha instalado el sistema operativo.
Ahora recuerda que tenía algunos datos importantes en el disco antes de particionarlo y formatearlo. Si acaba de instalar el sistema operativo, hay muchas posibilidades de que se recupere el archivo.
Los factores que afectan el rendimiento de Raw File Recovery son los datos fragmentados y la cantidad de datos sobrescritos por otros datos. Sin embargo, usted mismo puede encontrar más y más áreas de aplicación para la recuperación de archivos sin formato.
El procedimiento o casi las reglas para buscar los archivos con el programa de recuperación de archivos sin formato considera las siguientes condiciones:
- Busque el encabezado del archivo o varios tipos de archivos simultáneamente en los sectores del disco.
- Si se encuentra el encabezado de cualquier tipo de archivo, guarde los datos en un archivo y verifique las siguientes cuatro condiciones para cerrar y guardar el archivo
- Se encuentra el pie de página de ese tipo de archivo
- Se encuentra el otro encabezado del mismo tipo de archivo
- Se encuentra el encabezado de otro tipo de archivo
- No se encuentra ningún otro encabezado o pie de página para los tipos de archivo definidos en el programa y el tamaño del archivo en el que está almacenando los datos alcanza el límite de tamaño máximo, que definió para el tamaño del archivo, en su programa.
La información debe almacenarse en el archivo, incluidos los datos de los sectores en los que encontró el encabezado y los pies de página del tipo de archivo.
Encabezados y pies de página de algunos tipos de archivos importantes
Los encabezados y pies de página de algunos tipos de archivos importantes se proporcionan en la siguiente tabla. Los pies de página proporcionados en la tabla están al final del archivo del tipo de archivo especificado o están en los desplazamientos finales del archivo, de modo que puede usarlos como pies de página para recuperar los datos.
También puede buscar encabezados y pies de página, diferentes de estos tipos de archivos, usando el comando EDIT de DOS o usando cualquier herramienta de edición de disco. He usado el sistema hexadecimal para representar la información para que sea fácil de entender.
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 |
Escribir un programa para la recuperación de archivos sin formato
La codificación del programa para la recuperación de archivos sin procesar de archivos de Microsoft Word (extensión .DOC) se proporciona a continuación. El programa busca los archivos en los sectores del disco y guarda el archivo recuperado automáticamente creando el nombre del archivo automáticamente.
La ruta especificada por el usuario para guardar los archivos se utiliza como ruta de destino para guardar los datos recuperados. Si el directorio de destino no existe, el programa puede crear el destino hasta un nivel de directorio.
El programa de recuperación proporcionado aquí es compatible incluso con discos de gran tamaño para buscar y recuperar los datos. El programa ha sido escrito para buscar los datos en el segundo disco duro físico.
/* Programa de recuperación de archivos sin procesar para recuperar los archivos de 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 */
} ;
///// Función para obtener parámetros de la unidad \\\\\
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;
/* Encabezado de archivos de 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");
/* Función para ocultar (y mostrar) el cursor en la pantalla */
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++;
////////////// Condiciones de cierre de archivo \\\\\\\\\\\\\\\\
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++;
}
////////Mientras que el bucle termina aquí
/* 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();
}
}
La geometría de la estructura es utilizada por la función getdrivegeometry usando la extensión INT 13H, número de función 0x48 para obtener los diversos parámetros del disco.
La estructura diskaddrpacket es para el formato de paquete de dirección de disco, para ser utilizado por la función readabsolutesectors.
La función getdrivegeometry (int drive) es para obtener los parámetros de la unidad del número de unidad física especificado en el disco.
(char) peekb(0x0040, 0x0075) se usa para encontrar la cantidad de discos duros conectados a la computadora, almacenados en la ubicación de la memoria representada por el segmento 0040H: desplazamiento 0075H. Si el número total de discos duros conectados es inferior a dos Mostrar mensaje de error y salir.
Sectors_in_HDD2=getdrivegeometry (0x81); encuentra los diversos parámetros del segundo disco duro físico (0x81) y devuelve el número total de sectores del disco.
La sentencia if(access(path, 0) != 0) comprueba la accesibilidad de la ruta proporcionada por el usuario. Si el directorio de destino no existe, el destino se crea hasta un nivel y si la ruta determinada marcada por la condición if(mkdir(path)!=0) es ilegal, se muestra un mensaje de error.
Los nombres de archivo de los archivos creados automáticamente para guardar los datos recuperados se crean de manera que los tres primeros caracteres de los archivos reciben PTT de strcat(ruta,"\\Ptt"); función. Se hace así para evitar los nombres de archivos duplicados en el directorio de destino. Por lo tanto, los nombres de archivo de los archivos recuperados se dan en formato de "PTTxxxxx.DOC"
La Función show_hide_cursor ( 32, 0 ); se usa para Ocultar el Cursor de la pantalla donde show_hide_cursor ( 6, 7 ); recupera el cursor de vuelta a la pantalla.
La función readabsolutesectors (0x81, loop, 1, buffer); Lee un sector del segundo disco duro físico especificado por el bucle de número de sector.
Si se encuentra el encabezado del archivo, start_file = loop; establece start_file en el número de sector inicial del archivo que se va a recuperar. El programa sigue las tres condiciones dadas a continuación, para encontrar el sector final del archivo:
- Si el tamaño del archivo alcanza un tamaño máximo de 5 MB
- Si se encuentra el pie de página del archivo DOC
- Si se encuentra otro encabezado
El entero largo end_file se establece en el número de sector final del archivo mediante end_file=loop; si cualquiera de las tres condiciones se cumple. Ahora los datos de los sectores, desde el número de sector start_file hasta el número de sector end_file se guardan en el archivo con la función Recover_the_file().
La codificación de la función Recuperar_el_archivo() se da a continuación:
/* Función para guardar los datos de los sectores a partir del número de sector start_file hasta el número de sector 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;
}
A continuación se da la codificación de la función readabsolutesectors. La función utiliza la extensión INT 13H y el número de función 42H para leer los sectores.
Para obtener una descripción detallada de la función, consulte el capítulo "Realización de copias de seguridad" discutido anteriormente en este libro. La codificación de la función es la siguiente:
//// Función para leer sector(es) absoluto(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
}
La siguiente función se utiliza para ocultar o mostrar el cursor en la pantalla. La función usa Interrupción 10H, Función 01H para establecer el tipo de cursor. La codificación es la siguiente:
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 ) hides the cursor and show_hide_cursor( 6, 7 ) retrieves the cursor back. ssl is starting line for cursor and esl is ending line for cursor.
The little description of Function 01H of INT 10H is as follows:
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:
La función se utiliza para establecer el tipo de cursor seleccionando las líneas de inicio y fin para el cursor de hardware parpadeante en el modo de visualización de texto. En los modos gráficos, el cursor de hardware no está disponible.
Página modificada el: 17/01/2022