Capitolo – 14
Programmazione per il recupero di "file non elaborati".
Recupero di file non elaborati
Ci sono molti tipi di file specifici che hanno una sequenza o una combinazione di caratteri specifica scritta all'inizio e alla fine del file. Possiamo analizzare facilmente queste combinazioni con l'aiuto di qualsiasi programma di editing del disco. Possiamo anche usare il comando EDIT del DOS per studiare la struttura del file in formato ASCII.
La sequenza o combinazione di caratteri specifica che è presente all'inizio del file è solitamente chiamata intestazione e la sequenza o combinazione di caratteri memorizzata alla fine del file è chiamata piè di pagina del file.
p>
Se abbiamo perso i nostri dati in un tale tipo di arresto anomalo del disco che non sono disponibili informazioni FAT o directory principale per recuperare i dati, possiamo utilizzare intestazioni e piè di pagina per cercare questi tipi di file specifici. L'intestazione indica l'inizio del file di quel particolare tipo e il piè di pagina indica la fine del file di quel particolare tipo di file.
Qui stiamo usando la struttura grezza di un particolare tipo di file per recuperare i dati, quindi la tecnica di recupero è chiamata Raw File Recovery. La superficie del disco viene cercata settore per settore per trovare le informazioni di intestazione e piè di pagina.
Sebbene Raw File Recovery possa avere una vasta area di applicazione, ci sono alcuni casi specifici di ripristino in cui può aiutare molto. Ad esempio, per errore, se hai eseguito un programma di cancellazione dei dati nel disco che conteneva alcuni file importanti ma fino a quando non arresti il programma, tutte le informazioni di MBR, DBR, FAT e directory principale inclusi i file del sistema operativo vengono cancellate.
In tal caso, anche i programmi di recupero del formato potrebbero non aiutarti a recuperare i dati. Qui puoi utilizzare Raw File Recovery per recuperare i file di quei tipi di file specifici cercando nelle intestazioni e nei piè di pagina.
Non solo questo, anche tu puoi recuperare i dati in questi casi, dove hai un disco rigido del genere in cui hai cancellato tutte le partizioni logiche del disco, ricreato le partizioni di dimensioni diverse rispetto a prima e anche tu le hai installate il sistema operativo.
Ora ti ricordi che avevi alcuni dati importanti nel disco prima di partizionarlo e formattarlo. Se hai appena installato il sistema operativo, ci sono molte possibilità che il file venga ripristinato.
I fattori che influiscono sulle prestazioni di Raw File Recovery sono i dati frammentati e la quantità di dati sovrascritti da altri dati. Tuttavia, puoi trovare sempre più aree di applicazione per il recupero di file non elaborati.
La procedura o quasi le regole per la ricerca dei file con il programma di recupero file raw considerano le seguenti condizioni:
- Cerca l'intestazione del file o più tipi di file contemporaneamente nei settori del disco.
- Se viene trovata un'intestazione di qualsiasi tipo di file, salva i dati in un file e verifica le quattro condizioni seguenti per chiudere e salvare il file
- È stato trovato il piè di pagina di quel tipo di file
- È stata trovata un'altra intestazione dello stesso tipo di file
- È stata trovata l'intestazione di un altro tipo di file
- Non viene trovata un'altra intestazione o piè di pagina per i tipi di file definiti nel programma e la dimensione del file in cui stai archiviando i dati raggiunge il limite di dimensione massima, che hai definito per la dimensione del file, nel tuo programma.
Le informazioni dovrebbero essere memorizzate nel file includendo i dati dei settori in cui hai trovato l'intestazione e i piè di pagina del tipo di file.
Intestazioni e piè di pagina di alcuni tipi di file importanti
Le intestazioni e i piè di pagina di alcuni tipi di file importanti sono stati riportati nella tabella riportata di seguito. I piè di pagina forniti nella tabella si trovano alla fine del file del tipo di file specificato o si trovano negli offset finali del file in modo da poterli utilizzare come piè di pagina per recuperare i dati.
Puoi anche cercare intestazioni e piè di pagina, diversi da questi tipi di file, usando il comando EDIT di DOS o usando qualsiasi strumento di modifica del disco. Ho utilizzato il sistema esadecimale per rappresentare le informazioni in modo da renderle facilmente comprensibili.
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 |
Scrivere un programma per il recupero di file non elaborati
Di seguito è stata data la codifica del programma per il recupero di file grezzi di file Microsoft Word (estensione .DOC). Il programma ricerca i file nei settori del disco e salva automaticamente il file recuperato creando automaticamente il nome del file.
Il percorso specificato dall'utente per salvare i file viene utilizzato come percorso di destinazione per salvare i dati recuperati. Se la directory di destinazione non esiste, il programma può creare la destinazione fino a un livello di directory.
Il programma di ripristino fornito qui supporta anche i dischi di grandi dimensioni per cercare e recuperare i dati. Il programma è stato scritto per cercare i dati nel secondo disco rigido fisico.
/* Programma di recupero di file non elaborati per recuperare i file di 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 */
} ;
///// Funzione per ottenere i parametri dell'unità \\\\\
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;
/* Responsabile dei file di 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");
/* Funzione per nascondere (e mostrare) il cursore sullo schermo */
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++;
///////////// Condizioni di chiusura del file \\\\\\\\\\\\\\\\
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++;
}
////////Mentre il ciclo finisce qui
/* 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 geometria della struttura viene utilizzata dalla funzione getdrivegeometry utilizzando INT 13H Extension, Function Number 0x48 per ottenere i vari parametri del disco.
La struttura diskaddrpacket è per il formato del pacchetto Disk Address, da utilizzare con la funzione readabsolutesectors.
La funzione getdrivegeometry (int drive) serve per ottenere i parametri dell'unità dell'unità con il numero di unità fisica specificata sul disco.
(char) peekb(0x0040, 0x0075) viene utilizzato per trovare il numero di dischi rigidi collegati al computer, archiviati nella posizione di memoria rappresentata dal segmento 0040H:offset 0075H. Se il numero totale di dischi rigidi collegati è inferiore a due Visualizza messaggio di errore ed esci.
Settori_in_HDD2=getdrivegeometry (0x81); trova i vari parametri del secondo hard disk fisico (0x81) e restituisce il numero totale di settori del disco.
L'istruzione if(access(path, 0) != 0) verifica l'accessibilità del percorso fornito dall'utente. Se la directory di destinazione non esiste, la destinazione viene creata fino a un livello e se il percorso specificato è controllato dalla condizione if(mkdir(path)!=0) è illegale, viene visualizzato un messaggio di errore.
I nomi dei file creati automaticamente per salvare i dati recuperati vengono creati in modo tale che i primi tre caratteri dei file siano dati PTT da strcat(path,"\\Ptt"); funzione. Viene fatto per evitare nomi di file duplicati nella directory di destinazione. Pertanto i nomi dei file recuperati vengono forniti nel formato “PTTxxxxx.DOC”
La funzione show_hide_cursor ( 32, 0 ); viene utilizzato per nascondere il cursore dallo schermo in cui show_hide_cursor ( 6, 7 ); riporta il cursore sullo schermo.
La funzione readabsolutesectors (0x81, loop, 1, buffer); Legge un settore del secondo disco rigido fisico specificato dal ciclo del numero di settore.
Se viene trovata l'intestazione del file, start_file = loop; imposta start_file sul numero del settore iniziale del file da recuperare. Il programma segue le tre condizioni indicate di seguito, per trovare il settore finale del file:
- Se la dimensione del file raggiunge la dimensione massima di 5 MB
- Se viene trovato il piè di pagina del file DOC
- Se viene trovata un'altra intestazione
L'intero lungo end_file è impostato sul numero del settore finale del file da end_file=loop; se una condizione su tre è soddisfatta. Ora i dati dei settori, partendo dal numero del settore start_file fino al numero del settore end_file, vengono salvati nel file con la funzione Recupera_il_file( ).
Di seguito è stata data la codifica della funzione Recover_the_file():
/* Funzione per salvare i dati dei settori partendo dal numero del settore start_file al numero del settore 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;
}
Di seguito è stata data la codifica della funzione readabsolutesectors. La funzione utilizza l'interno INT 13H e la funzione numero 42H per leggere i settori.
Per la descrizione dettagliata della funzione, fare riferimento al capitolo "Esecuzione di backup" discusso in precedenza in questo libro. La codifica della funzione è la seguente:
//// Funzione per leggere i settori assoluti \\\\
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 seguente funzione viene utilizzata per nascondere o mostrare il cursore sullo schermo. La funzione utilizza Interrupt 10H, Function 01H per impostare il tipo di cursore. La codifica è la seguente:
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 ) nasconde il cursore e show_hide_cursor( 6, 7 ) recupera il cursore. ssl è la riga iniziale per il cursore ed esl è la riga finale per il cursore.
La piccola descrizione della funzione 01H di INT 10H è la seguente:
INT 10H (16 o 0x10)
Funzione 01H (o 0x01) --> Imposta il tipo di cursore
Call with: AH = 01H
CH bits 0-4 = starting line for cursor
CL bits 0-4 = ending line for cursor
Returns: Nothing.
Comments:
La funzione viene utilizzata per impostare il tipo di cursore selezionando le righe di inizio e fine per il cursore hardware lampeggiante nella modalità di visualizzazione del testo. Nelle modalità grafiche, il cursore hardware non è disponibile.
Pagina modificata il: 10/03/2022