Capitolo – 14
PROGRAMMAZIONE PER IL RECUPERO DI FILE RAW
Recupero di file raw
Esistono molti tipi di file specifici che presentano una sequenza o combinazione specifica di caratteri scritti all'inizio e alla fine del file. Possiamo analizzare facilmente queste combinazioni utilizzando qualsiasi programma di modifica dei dischi. Possiamo anche usare il comando EDIT DOS per esaminare la struttura di un file ASCII.
Una particolare sequenza o combinazione di caratteri presente all'inizio di un file è solitamente chiamata intestazione, mentre una sequenza o combinazione di caratteri memorizzata alla fine di un file è chiamata piè di pagina del file.
Se abbiamo perso i nostri dati a causa di un guasto del disco per cui non ci sono informazioni FAT o sulla directory root per recuperarli, possiamo usare intestazioni e piè di pagina per trovare questi tipi specifici di file. L'intestazione indica l'inizio di un file di quel particolare tipo di file, mentre il piè di pagina indica la fine di un file di quel particolare tipo di file.
In questo caso utilizziamo la struttura grezza di un determinato tipo di file per recuperare i dati, pertanto il metodo di recupero è denominato Raw File Recovery. La superficie del disco viene scansionata settore per settore per trovare informazioni di intestazione e piè di pagina.
Sebbene il recupero di file Raw possa avere una vasta gamma di applicazioni, ci sono alcuni casi di recupero speciali in cui può rivelarsi di grande aiuto. Ad esempio, se per errore si esegue un programma di cancellazione dati su un disco che contiene file importanti, finché il programma non viene arrestato, tutte le informazioni MBR, DBR, FAT e della directory root, compresi i file del sistema operativo, verranno cancellate.
In questo caso, anche i programmi di recupero formattazione potrebbero non aiutarti a recuperare i dati. Qui puoi utilizzare Raw file Recovery per recuperare file di questi specifici tipi di file effettuando la ricerca nelle intestazioni e nei piè di pagina.
Non solo, puoi anche recuperare i dati nei casi in cui hai un disco rigido in cui hai eliminato tutte le partizioni logiche dell'unità, ricreato partizioni di dimensioni diverse rispetto a prima e persino installato un sistema operativo.
Ora ottieni la memoria in cui erano presenti alcuni dati importanti sul disco prima che fosse partizionato e formattato. Se hai appena installato il sistema operativo, ci sono buone probabilità che il file venga recuperato.
I fattori che incidono sulle prestazioni del recupero dei file raw sono i dati frammentati e la quantità di dati sovrascritti da altri dati. Tuttavia, è possibile trovare sempre più applicazioni per il recupero autonomo di file raw.
La procedura o quasi le regole per la ricerca di file utilizzando il software di recupero file raw tengono conto delle seguenti condizioni:
- Cerca un'intestazione di file o più tipi di file contemporaneamente nei settori del disco.
- Se viene trovata un'intestazione di tipo file, salvare i dati nel file e verificare le quattro condizioni seguenti per chiudere e salvare il file.
- Trovato il piè di pagina di questo tipo di file
- È stata trovata un'altra intestazione dello stesso tipo di file.
- Trovata intestazione di un tipo di file diverso
- Non sono state trovate altre intestazioni o piè di pagina per determinati tipi di file nel programma e la dimensione del file in cui si stanno salvando i dati raggiunge il limite massimo definito per la dimensione del file nel programma.
Le informazioni dovrebbero essere salvate nel file, compresi i dati del settore in cui si trovano l'intestazione e il piè di pagina del tipo di file.
Intestazioni e piè di pagina di alcuni tipi di file importanti
Nella tabella seguente sono elencate le intestazioni e i piè di pagina di alcuni importanti tipi di file. I piè di pagina elencati nella tabella si trovano alla fine del file del tipo di file specificato oppure negli offset finali del file, pertanto è possibile utilizzarli come piè di pagina per il recupero dei dati.
È anche possibile cercare intestazioni e piè di pagina diversi da questi tipi di file utilizzando il comando EDIT di DOS o qualsiasi strumento di modifica del disco. Ho utilizzato il sistema esadecimale per rappresentare le informazioni e renderle più comprensibili.
Estensione |
Intestazione (esadecimale) |
Piè di pagina (esadecimale) |
DOC |
D0 CF 11 E0 A1 B1 1A E1 |
Italiano: |
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 |
Presentazione in PowerPoint |
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 |
Codice Postale |
50 4B 03 04 14 |
50 4B 05 06 00 |
Formato JPG |
Italiano: FF D8 FF E0 00 10 4A 46 49 46 00 01 01 |
D9 ("È meglio usare il controllo delle dimensioni del file") |
La Gif |
47 49 46 38 39 61 4E 01 53 00 C4 |
21 00 00 3B 00 |
Il PDF è in inglese. |
25 50 44 46 2G 31 2E |
25 25 45 4F 46 |
Scrivere un programma per recuperare file raw
Di seguito è riportata la codifica del programma per il recupero di file Raw di file Microsoft Word (estensione .DOC). Il programma cerca i file nei settori del disco e salva automaticamente il file recuperato, creando automaticamente un nome 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ò crearla fino a un livello di directory.
Il software di recupero fornito qui supporta anche dischi di grandi dimensioni per la ricerca e il recupero dei dati. Il programma è stato scritto per cercare dati su un secondo disco rigido fisico.
/* Software di recupero file RAW di Microsoft Word */
#include<stdio.h>
#include<dos.h>
/* Struttura utilizzata dalla funzione getdrivegeometry mediante l'estensione INT 13H, numero funzione 0x48. */
geometria strutturale
{
dimensione int senza segno; /* (chiamata) dimensione del buffer */
flag int senza segno; /* Flag di informazione */
unsigned long cyl ; /* Numero di dati fisici
Cilindri sulla trasmissione */
intestazioni lunghe senza segno ;/* Numero di dati fisici
Testine sul drive */
spt lungo senza segno; /* Numero di dati fisici
Settori per traccia */
settore lungo senza segno[2] ; /* Quantità totale
Settori su disco */
intero senza segno bps ; /* Byte per settore */
} ;
/* Struttura del formato del pacchetto di indirizzi del disco utilizzata da readabsolutesectors */
struttura diskaddrpacket
{
dimensione del pacchetto char; /* Dimensione del pacchetto, solitamente 10H */
simbolo riservato; /* Riservato (0) */
int conteggio blocchi; /* Numero di blocchi da trasferire */
char lontano *bufferaddress ; /* indirizzo per la trasmissione
Respingente */
numero di blocco lungo non firmato[2] ; /* Valore assoluto iniziale
Numero di blocco */
} ;
///// Funzione per ottenere i parametri dell'unità \\\\\
getdrivegeometry(intdrive) lungo non firmato
{
sindacato REGS i, o ;
struttura SREGS s;
geometria strutturale g = { 26, 0, 0, 0, 0, 0, 0, 0 } ;
ihah = 0x48 ; /* Numero funzione 0x48 */
ihdl = unità; /* Numero disco */
ixsi = FP_OFF ( (void far*)&g ) ;
s.ds = FP_SEG ( (void far*)&g ) ;
/* Chiama il numero di funzione di estensione INT 13H specificato con i valori del registro di segmento */
int86x ( 0x13, &i, &o, &s ) ;
printf("\n Testa = %lu, Settori per traccia = %lu, Cilindro = %lu\n",
g.testa, g.spc, g.cil);
/* Se la funzione per ottenere la geometria del disco fallisce, visualizza un messaggio di errore ed esci */
se(g.spt==0)
{
printf("\n La funzione per ottenere la geometria dell'unità non è stata eseguita....");
printf("\n Estensioni non supportate, premere un tasto qualsiasi per
Uscita...");
ottenere();
uscita(1);
}
restituisci *g.sectors; /* Restituisci il numero di
Settori su Drive */
}
unsigned long file_size=0, i=0;
unsigned long inizio_file=0, fine_file=0;
unsigned long Settori_in_HDD2=0, ciclo=0;
char buffer[512], nome file[80], temp[8];
percorso carattere[80];
intero senza segno risultato, num=0;
/* Intestazione dei file di Microsoft Word */
intestazione carattere[10] = {0xD0,0xCF,0x11,0xE0, 0xA1,0xB1,0x1A,0xE1};
/* Piè di pagina dei file di Microsoft Word */
carattere DOC_footer[14] =
{0x57,0x6F,0x72,0x64, 0x2E,0x44,0x6F,0x63,
};
/// Inizio del principale \\\
vuoto principale()
{
clrscr();
/* Se il numero totale di dischi rigidi collegati è inferiore
poi due, Visualizza messaggio di errore ed Esci. */
se(((char)peekb(0x0040, 0x0075))<2)
{
printf("\n\n Devi avere almeno due dischi rigidi
Collegato al computer per eseguire questo");
printf("\n Programma. Questo programma è stato sviluppato
per recuperare i dati del secondo disco rigido.");
printf("\n Premi un tasto qualsiasi per uscire... ");
ottenere();
uscita(1);
}
Settori_in_HDD2=getdrivegeometry (0x81);
printf("\n Totale settori nel secondo disco rigido = %lu",
Settori_in_HDD2);
printf("\n\n \"È necessario salvare i file recuperati in
un altro disco rigido, non nello stesso disco,");
printf("\n in cui stai cercando il file perduto
dati.\"");
printf("\n\n Inserisci il percorso di destinazione per salvare il
File recuperati...\n ");
ottiene(percorso);
/* controlla se la directory di destinazione esiste o meno */
se(accesso(percorso, 0) != 0)
{
/* se la directory di destinazione non esiste, creala
la Directory fino a un livello */
se(mkdir(percorso)!=0)
{
printf("\n Impossibile creare la directory \"%s\"",
sentiero);
printf("\n Controlla il percorso..., premi un tasto qualsiasi per
Uscita...");
ottenere();
uscita(1);
}
}
strcat(percorso,"\\Ptt");
/* Funzione per nascondere (e mostrare) il cursore sullo schermo */
mostra_nascondi_cursore ( 32,
gotoxy(15,18);cprintf("[ %d ] File recuperati...",
In);
/* cerca i dati fino al settore finale del disco */
while(loop<Settori_in_HDD2)
{
/* Leggi un settore (Settore n. = ciclo) */
readabsolutesectors (0x81, ciclo, 1, buffer);
gotoxy(19,16);cprintf("Numero settore di scansione = % ld",
ciclo continuo);
se(kbhit())
{
show_hide_cursor ( 6, 7 ); /* Recupera il
cursore prima
Esci dal programma
*/
uscita(0);
}
/* se viene trovata l'intestazione specificata */
se((memcmp(buffer,intestazione,7))==0)
{
/* logica per fornire automaticamente il nome del file
creare i file per salvare i dati recuperati */
strcpy(nomefile, percorso);
itoa(num,temp,10);
strcat(nomefile, temp);
strcat(nomefile,".DOC");
start_file=loop; /* settore iniziale del file */
gotoxy(5,19);cprintf("File trovato..., salvataggio come %s",
nome file);
numero++;
////////////// Condizioni di chiusura del file \\\\\\\\\\\\\\\
dimensione_file=0;
while( dimensione_file < 5000000)
{
ciclo++;
dimensione_file+=512;
readabsolutesectors (0x81, ciclo, 1, buffer);
gotoxy(19,16);cprintf("Numero settore di scansione = % ld" ,
ciclo continuo);
/* se la dimensione del file raggiunge la dimensione massima di 5 MB */
se(dimensione_file>=5000000)
{
end_file=loop; /* Settore finale del file */
Recover_the_file();/* scrive i dati nel file */
rottura;
}
/* se viene trovato il piè di pagina del file DOC */
per(i=0;i<512;i++)
{
se( memcmp(buffer+i,DOC_footer,12)==0 )
{
end_file=loop; /* Settore finale del file */
Recover_the_file();/* scrive i dati nel file */
rottura;
}
}
/* se viene trovata un'altra intestazione */
se( memcmp(buffer,intestazione,7)==0 )
{
ciclo=ciclo-1;
end_file=loop; /* Settore finale del file */
Recover_the_file();/* scrive i dati nel file */
rottura;
}
se(kbhit())
{
mostra_nascondi_cursore ( 6, 7 );
uscita(0);
}
}
}
ciclo++;
}
////////Il ciclo While termina qui
/* visualizza il messaggio per il completamento della ricerca e del ripristino */ if(loop>=Sectors_in_HDD2 )
{
gotoxy(17,23);cprintf("Il salvataggio dei file sul disco è
Completato!!");
gotoxy(17,24);cprintf("Premi un tasto qualsiasi per uscire...");
mostra_nascondi_cursore ( 6, 7 );
ottenere();
}
}
La geometria della struttura viene utilizzata dalla funzione getdrivegeometry mediante l'estensione INT 13H, numero funzione 0x48 per ottenere i vari parametri del disco.
La struttura diskaddrpacket è per il formato del pacchetto di indirizzi disco, da utilizzare dalla funzione readabsolutesectors.
La funzione getdrivegeometry (int drive) serve a ottenere i parametri dell'unità fisica specificata con il numero drive.
(char) peekb(0x0040, 0x0075) viene utilizzato per trovare il numero di dischi rigidi collegati al computer, memorizzati nella posizione di memoria rappresentata dal segmento 0040H:offset 0075H. Se il numero totale di dischi rigidi collegati è inferiore a due, visualizza un messaggio di errore ed esci.
Sectors_in_HDD2=getdrivegeometry (0x81); trova i vari parametri del secondo disco rigido 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 che i primi tre caratteri dei file ricevano PTT dalla funzione strcat(path,"\\Ptt");. Ciò avviene 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 utilizzata per nascondere il cursore dallo schermo, mentre 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 numero di settore loop.
Se l'intestazione del file viene trovata, start_file = loop; imposta start_file al numero di settore iniziale del file da recuperare. Il programma segue le tre condizioni fornite 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
Il long integer end_file viene impostato sul numero di settore finale del file da end_file=loop; se una qualsiasi delle tre condizioni è soddisfatta. Ora i dati dei settori, a partire dal numero di settore start_file fino al numero di settore end_file, vengono salvati nel file con la funzione Recover_the_file( ).
Di seguito è riportata la codifica della funzione Recover_the_file( ):
/* Funzione per salvare i dati dei settori a partire dal numero di settore start_file fino al numero di settore end_file */
Recupera_il_file()
{
FILE *fp;
if((fp=fopen(nomefile, "wb"))==NULL)
{
gotoxy(10,23);printf("Errore durante l'apertura del file %s",
nome file);
ottenere();
uscita(1);
}
per(i=file_di_avvio;i<=file_di_fine;i++)
{
gotoxy(19,16);cprintf("Numero settore di scansione =
%ld", i);
leggisettoriassoluti (0x81, i, 1, buffer);
fwrite(buffer,512,1, fp);
}
fclose(fp);
gotoxy(15,18);cprintf("[ %d ] File recuperati...",num);
gotoxy(5,19);cprintf(" ");
ritorno;
}
Di seguito è stata fornita la codifica della funzione readabsolutesectors. La funzione utilizza l'estensione INT 13H e il numero di funzione 42H per leggere i settori.
Per la descrizione dettagliata della funzione, fare riferimento al capitolo "Creazione di backup" discusso in precedenza in questo libro. La codifica della funzione è la seguente:
//// Funzione per leggere i settori assoluti \\\\
int readabsolutesectors ( int unità,
numero di settore lungo senza segno,
int numero di settori,
vuoto *buffer )
{
unione REGS i, o ;
costruire SREGS s ;
struct diskaddrpacket pp ;
pp.packetsize = 16 ; /* dimensione del pacchetto = 10H */
pp.reserved = 0 ; /* Riservato = 0 */
pp.blockcount = numofsectors ; /* Numero di settori
leggere */
/* per buffer dati */
pp.bufferaddress = (char far*) MK_FP ( FP_SEG((void far*)buffer), FP_OFF((void far*)buffer));
pp.blocknumber[0] = sectornumber ; /* Numero del settore
leggere */
pp.blocknumber[1] = 0 ; /* Numero del blocco */
ihah = 0x42 ; /* Numero funzione*/
ihdl = drive ; /* Numero unità fisica */
/* ds:si per i parametri del buffer */
ixsi = FP_OFF ( (void far*)&pp ) ;
/* ds:si per i parametri del buffer */
s.ds = FP_SEG ( (void far*)&pp ) ;
/* Richiama la funzione specificata di INT 13H con
valori del registro del segmento */
int86x ( 0x13, &i, &o, &s ) ;
se (oxcflag==1)
ritorna 0 ; //fallimento
altro
ritorno 1 ; // successo
}
La seguente funzione viene utilizzata per nascondere o mostrare il cursore sullo schermo. La funzione utilizza l'interruzione 10H, funzione 01H per impostare il tipo di cursore. La codifica è la seguente:
mostra_nascondi_cursore( ssl, esl )
interi ssl, esl;
{
sindacato REGS i, o ;
aumentare = 1 ;
ihch = ssl ;
Italiano:
ihbh = 0 ;
int86 ( 16, &i, &o ) ;
ritorno;
}
show_hide_cursor( 32, 0 ) nasconde il cursore, mentre show_hide_cursor( 6, 7 ) lo riporta indietro. ssl è la riga di partenza del cursore, mentre esl è la riga di arrivo del cursore.
Una breve descrizione della funzione 01H INT 10H è la seguente:
INT 10H (16 o 0x10)
Funzione 01H (o 0x01) --> Imposta il tipo di cursore
Chiamata da: AH = 01H
Bit 0-4 CH = Linea di partenza per il cursore
Bit CL 0-4 = fine riga per cursore
Ritorno: nulla.
Commenti:
La funzione viene utilizzata per impostare il tipo di cursore selezionando le righe di inizio e fine per il cursore hardware lampeggiante in modalità di visualizzazione del testo. Il cursore hardware non è disponibile nelle modalità grafiche.