Capítulo– 15
Programação para limpadores de dados
Introdução
Já discutimos isso quando excluímos qualquer arquivo do disco, a informação não é apagada completamente da unidade, mas é marcada como disponível para que novos dados sejam gravados sobre ela.
Quando formatamos uma unidade, todas as informações de arquivos e diretórios da unidade, como FATs e entradas de diretório raiz, são apagadas, mas a área de dados permanece inalterada e nada da área de dados do disco é apagado. Os dados que são excluídos ou formatados usando o sistema operacional permanecem na área de dados como estão e podem ser recuperados com alguns esforços de recuperação de dados e software de recuperação de dados.
Portanto, a necessidade de eliminar totalmente os dados de uma unidade leva à necessidade de um programa que elimine completamente os dados do disco. Para fazer isso, não basta apenas excluir os arquivos ou apenas formatar a unidade, mas os dados no disco devem ser substituídos por outros dados.
Os programas usados para eliminar completamente os dados do disco são conhecidos como programas de eliminação de dados. Esses programas gravam caracteres aleatórios na área de dados para sobrescrever os dados e apagar todas as informações salvas anteriormente no disco.
Quando os dados se tornam completamente irrecuperáveis
Para eliminar os dados, a área de dados do disco deve ser substituída por alguns outros dados, mas o problema não termina aqui. Para complicar ainda mais as coisas, a tendência das unidades magnéticas de lembrar os dados que foram substituídos exige que os dados também sejam substituídos várias vezes por sequências aleatórias de dados, para que não possam ser recuperados mesmo com ferramentas sofisticadas de recuperação de dados
É assim porque as tecnologias que podem recuperar dados mesmo após o uso de alguns limpadores de dados simples estão disponíveis hoje.
Alguns produtos de eliminação de dados executam zeros binários e sobrescrevem uns binários nos dados. Escrever uma série de zeros binários e uns binários alcança o efeito de sobregravação mais profundo, pois esses valores são os valores magnéticos mínimo e máximo, respectivamente.
Embora esta seja a teoria de um programa de limpeza de dados ideal, mas geralmente, a sobregravação de dados por caractere ASCII aleatório é suficiente. A razão para dizer isso é que a recuperação por ferramentas e tecnologia de recuperação sofisticada não pode ser usada para recuperar os dados de qualquer organização para uma recuperação de dados de rotina, porque essas tecnologias são muito caras e custam milhões, mesmo para recuperação única. Não apenas isso, mas também essas tecnologias estão disponíveis apenas em alguns países ao redor do mundo.
Vamos discutir apenas a substituição de dados simples para limpar os dados do disco. No entanto, você pode modificar ainda mais os mesmos programas para escrever os caracteres aleatórios apenas com alguns pequenos esforços. Os dados eliminados por essa ideia também não podem ser recuperados por nenhum software de recuperação de dados.
Por que a limpeza de dados é tão importante
Quando discutimos sobre as técnicas de recuperação de dados, garantimos ao usuário que os dados podem ser recuperados com alguns esforços gerais ou específicos de recuperação de dados. Mas a recuperação de dados nem sempre é um recurso desejado e esperado para todos.
Pode haver muitas pessoas ou organizações que estão sempre dispostas a apagar os dados de seus discos de forma que não devam ser recuperados de forma alguma. Nesses casos, dados muito confidenciais podem ser armazenados anteriormente no disco, que, se caírem em mãos erradas, podem prejudicar a organização ou o usuário pelo uso indevido das informações.
Como sabemos, a necessidade de mais e mais espaço nos discos rígidos está aumentando dia a dia. Como resultado disso, as unidades mais antigas de pequena capacidade são substituídas por novos discos de grande capacidade em grande escala todos os anos em quase todas as organizações. Se esses discos mais antigos forem adquiridos por mãos erradas, isso poderá criar um problema muito sério para essa organização.
De acordo com notícias publicadas pela CNET News.com, em 16 de janeiro de 2003, os estudantes do Massachusetts Institute of Technology Simon Garfinkel e Abbi Shelat compraram discos rígidos antigos, em nome da pesquisa, da Web e outros vendas para descobrir a enorme quantidade de informações pessoais que as pessoas não se preocupam em apagar.
Após comprar 158 drives por cerca de US$ 1.000, eles conseguiram coletar mais de 5.000 números de cartão de crédito, registros médicos, informações financeiras pessoais e corporativas detalhadas e vários gigabytes de e-mails, códigos-fonte e outras informações.
A dupla desses alunos compilou suas descobertas em um relatório intitulado "Lembrança de dados passados: um estudo de higienização de disco" publicado na edição de fevereiro do IEEE Security and Privacy.
Os principais pontos que surgiram da pesquisa são que o mercado de discos rígidos de segunda mão está repleto de informações pessoais, tornando muito fácil para um comprador mal-intencionado assumir a identidade de outra pessoa.
Programa de escrita para limpador de dados não destrutivo
O limpador de dados não destrutivo é um tipo de programa de limpeza de dados usando o qual podemos eliminar todo o “espaço não alocado” do volume do disco, sem prejudicar os dados armazenados no disco, de forma alguma.
O escopo desse limpador de dados está nos casos em que você deseja eliminar todo o espaço não alocado do volume de disco enquanto os dados alocados armazenados no volume devem permanecer intocados. Esse tipo de programa de limpeza de dados também apaga a área de dados dos arquivos excluídos.
A codificação do programa para um tipo de não – programa de limpeza de dados destrutivo foi dado a seguir:
///// Programa para um limpador de dados não destrutivo \\\\\
#include <stdio.h>
unsigned int file_num=0; /* Provides File Number
During the Auto Creation
of Temporary Data files */
float status=0; /* How Much Disk space is
still Written */
static char dbuf[40000]; /* Data Buffer to write
Temporary Files with */
char file_extension[5]=".ptt";/* Unique Extensions for
Temporary Files */
char temp[5]; /* File Number converted to
String */
char filename[40]; /* Temporary File name */
void main()
{
unsigned int i=0;
clrscr();
while(i<40000)
{
dbuf[i] = ' ';
i++;
}
gotoxy(10,14);cprintf(" MB Still Written...");
while(1)
{
/* Lógica para criar arquivos temporários automaticamente com nome exclusivo */
strcpy(filename,"TTPT");
itoa(file_num,temp,10);
strcat(filename,temp);
strcat(filename,file_extension);
file_num++;
write_to_temp(filename);
}
} //// End of Main \\\\
///// Função para gravar os dados em arquivo temporário \\\\\
write_to_temp(char *filename)
{
unsigned int i, count=1;
float buf_status=0;
FILE *tt;
if((tt=fopen(filename,"wb"))==NULL)
{
fclose(tt);
printf("\n Error occurred while creating temporary
file, ");
printf("\n Removing temporery Files After KEY BOARD
HIT");
getch();
remove_temp_file();/* Remove All temporary files */
}
while(1)
{
for(i=0;i<50;i++)
{
fprintf(tt,"%s",dbuf);
}
buf_status = (float)((40000*50*count)/512);
status= status+(40000*50);
count++;
gotoxy(10,14);
cprintf("%.0f",(float)(status/1000000));
if(kbhit())
{
fclose(tt);
printf("\n Removing Temporery Files, Please
Wait...");
remove_temp_file();
}
if(buf_status>=10000)
{
fclose(tt);
return;
}
}
}
/* Função para excluir os arquivos temporários automaticamente*/
remove_temp_file()
{
int i=0;
for(i=0;i<=file_num;i++)
{
strcpy(filename,"TTPT");
itoa(i,temp,10);
strcat(filename,temp);
strcat(filename,file_extension);
remove(filename);
}
exit(1);
return 0;
}
Comentários sobre a lógica e a codificação do programa:
Neste programa, basicamente, seguimos as duas etapas a seguir para limpar o espaço não alocado do disco:
- Criar arquivos de dados temporários automaticamente: Primeiro, criamos arquivos temporários com nomes exclusivos e alguns dados neles até que o volume do disco esteja cheio com esses arquivos de dados temporários. Ao fazer isso, toda a área de dados não alocados da unidade lógica é ocupada pelos dados dos arquivos temporários e todos os dados não alocados são substituídos.
Para isso, escolhi os nomes dos arquivos temporários no formato TTPTxxxx.PTT, ou seja, os primeiros quatro caracteres dos arquivos temporários são TTPT e a extensão dos arquivos é .PTT. Isso é feito para fornecer aos arquivos temporários os nomes de arquivo exclusivos.
Eu defini o tamanho máximo do arquivo temporário único, equivalente a aproximadamente 11.718 dados de setores, mas você pode defini-lo de acordo com você. Eu escolhi o caractere de espaço “ ” (caractere ASCII 32) para preencher os dados em arquivos temporários. No entanto, caracteres aleatórios também podem ser usados em vez de espaço.
- Remover todos os arquivos temporários: Quando a unidade lógica está cheia de arquivos temporários, isso indica que toda a área de dados não alocada foi substituída. Agora todos os arquivos temporários criados pelo programa são removidos automaticamente. E, assim, o espaço não alocado é eliminado.
Na codificação do programa, o array de caracteres filename armazena o nome do arquivo para gerar arquivos temporários automaticamente, com nomes diferentes.
A função write_to_temp(nome do arquivo); preenche o arquivo temporário com até 11.718 setores (pois não há ocorrência de 10.000 setores no grupo especificado de escrita de buffer) dados equivalentes com auxílio do buffer de dados dbuf de 40.000 bytes. 50 vezes o buffer de dados é gravado por vez para acelerar a gravação.
Os arquivos temporários são criados até que o volume do disco esteja cheio e ocorra um erro de criação de arquivo. A função remove_temp_file() remove todos os arquivos temporários, criados pelo programa.
Dessa forma, todo o espaço não alocado é eliminado sem prejudicar os dados do volume do disco.
Programa de escrita para Destructive Data Wiper:
Os programas de limpeza de dados destrutivos são aqueles que escrevem diretamente na superfície do disco. Esse tipo de programa de limpeza de dados funciona em um nível mais baixo do que o sistema de arquivos e o sistema operacional, o que significa que todos os dados e outras informações lógicas, incluindo sistema operacional, sistemas de arquivos, entrada de diretório e tudo o que está escrito no disco, são apagados.
Esses programas de limpeza de dados limpam diretamente os setores da superfície do disco e apagam tudo o que está escrito nele. Como todos os dados do disco, incluindo o sistema operacional, são perdidos, esses programas são chamados de programas de limpeza de dados destrutivos.
Esses tipos de programas de limpeza são preferidos nesses casos, em que o usuário está disposto a substituir tudo no disco, incluindo o sistema operacional e todos os dados no disco.
No entanto, há mais alguns benefícios desse tipo de programa de limpeza de dados. Como esses programas de limpeza de dados destrutivos funcionam completamente livres do sistema operacional e do sistema de arquivos e gravam diretamente na superfície do disco, eles são razoavelmente mais rápidos do que os limpadores de dados não destrutivos.
Além disso, se houver como os setores lógicos defeituosos no disco são criados devido ao armazenamento ilegal de alguns dados aleatórios, esses setores lógicos defeituosos também são eliminados completamente com os dados do disco.
A codificação para um programa de limpeza de dados destrutivo foi dada a seguir. O programa foi escrito para suportar discos de tamanho grande também. O programa limpa os dados do segundo disco rígido físico conectado ao computador.
///// Codificação para um programa destrutivo de limpeza de dados \\\\\
#include<stdio.h>
#include<dos.h>
/* Estrutura a ser usada pela função getdrivegeometry usando 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 */
} ;
/* Estrutura do formato de pacote de endereço de disco, para ser usado pela função writeabsolutesectors */
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 */
} ;
/////Função para obter os parâmetros do inversor\\\\\
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 of INT 13H
Extensions */
i.h.dl = drive; /* Drive Number */
i.x.si = FP_OFF ( (void far*)&g ) ;
s.ds = FP_SEG ( (void far*)&g ) ;
/* Invoque o número de função especificado da extensão INT 13H com valores de registro de segmento */
int86x ( 0x13, &i, &o, &s ) ;
printf("\n Head = %lu, Sectors Per Track = %lu, Cylinder =
%lu\n",
g.heads,g.spt,g.cyl);
/* Se a função Get Drive Geometry falhar, exibir mensagem de erro e sair */
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 */
}
void main()
{
unsigned long loop=0, Sectors_in_ HDD2=0;
unsigned char buffer[61440]; /* Data buffer of 61440
bytes Equivalent to
120 Sectors */
unsigned long i=0;
char choice;
clrscr();
/*Se total não. de discos rígidos conectados é menor que dois Exibir mensagem de erro e sair. */
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 Wipe the Data of Second Hard Disk.");
printf("\n Press any Key to Exit... ");
getch();
exit(1);
}
Sectors_in_HDD2 = getdrivegeometry (0x81);
printf(" Total Sectors in Second Hard Disk =
%lu\n\n",
Sectors_in_HDD2);
/////Primeiro confirme, depois prossiga \\\\\
printf("\n It is A Data Wiping Program, and Writes on
the Surface of the Disk,");
printf("\n After running this program, Data can not
be recovered by any Software,");
printf("\n All The Data in Second Hard Disk will be
lost !!!");
printf("\n Press \'Y\' to Continue, Else any key to
Exit... ");
choice = getche();
switch(choice)
{
case 'y':
case 'Y':
break;
default:
exit(0);
}
gotoxy(10,15);cprintf(" Initializing, Please Wait...");
for(i=0;i<61440;i++)
{
buffer[i]='\0';
}
gotoxy(10,15);cprintf(" ");
gotoxy(10,15);
printf("Currently Wiping Absolute Sector: ");
for(loop=0;loop<= Sectors_in_HDD2;loop=loop+120)
{
writeabsolutesectors (0x81, loop, 120, buffer);
gotoxy(44,15); printf("%ld",loop);
if(kbhit())
{
exit(0);
}
///// Exibir mensagem quando concluído \\\\\
printf("\n\n Data wiping is Now Completed, All the Data in
Second Hard Disk is now");
printf("\n Completely Erased, Press any Key to Exit...");
getch();
}
//// Função para escrever setor(es) absoluto(s) \\\\
int writeabsolutesectors ( 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
be written */
/* para buffer de dados */
pp.bufferaddress = (char far*) MK_FP ( FP_SEG((void far*)buffer), FP_OFF((void far*)buffer));
pp.blocknumber[0] = sectornumber ; /* Sector number
to be written*/
pp.blocknumber[1] = 0 ; /* Block number = 0 */
i.h.ah = 0x43 ; /* Function Number */
i.h.al = 0x00 ; /* Write Flags */
i.h.dl = drive ; /* Physical Drive
number */
i.x.si = FP_OFF ( (void far*)&pp ) ; /* ds:si for
buffer Parameters */
s.ds = FP_SEG ( (void far*)&pp ) ; /* ds:si for
buffer Parameters */
/* Invoque a função especificada de INT 13H com valores de registro de segmento */
int86x ( 0x13, &i, &o, &s ) ;
if ( o.x.cflag==1)
return 0 ; //failure
else
return 1 ; // success
}
Comentários sobre a codificação:
A geometria da estrutura é usada pela função getdrivegeometry usando INT 13H Extension, Function Number 0x48 para obter os vários parâmetros do disco.
A estrutura diskaddrpacket é para o formato de pacote de endereço de disco, a ser usado pela função writeabsolutesectors.
A função getdrivegeometry (int drive) é para obter os parâmetros de unidade da unidade de número de unidade física especificada do disco. buffer [61440] é o buffer de dados de 61440 bytes, equivalente a 120 setores.
(char) peekb(0x0040, 0x0075) é usado para encontrar o número de discos rígidos conectados ao computador, armazenados no local de memória representado pelo segmento 0040H:offset 0075H. Se o número total de discos rígidos conectados for menor que dois Exibir mensagem de erro e sair.
A função writeabsolutesectors ( 0x81, loop, 120, buffer ) é usada para gravar os dados do buffer de dados em 120 setores por vez a partir do número absoluto do setor especificado pelo loop.
Escolhi ‘\0’ (caractere NULL, código ASCII 0) para escrever nos setores para substituir os dados. No entanto, você pode usar caracteres aleatórios para substituir os dados.
Para obter uma descrição detalhada das funções writeabsolutesectors e getdrivegeometry, consulte os capítulos fornecidos anteriormente neste livro.
Limpando a área de dados de um arquivo específico
Discutimos sobre os programas de limpeza de dados que limpam os dados do espaço não alocado do disco ou limpam o disco inteiro. Mas se o usuário estiver disposto a limpar os dados toda vez que excluir os dados, pode ser um processo demorado para limpar todo o espaço não alocado do disco.
Precisamos desse tipo de programa de limpeza de dados para limpar a área de dados ocupada apenas por esse arquivo específico. Para fazer isso, obtemos a ajuda das entradas do diretório FAT e Root, para encontrar a área de dados ocupada por esses arquivos específicos
Mesmo no caso de disquete, se os dados não estiverem fragmentados, podemos fazê-lo apenas com a ajuda das informações do diretório raiz. A tabela a seguir mostra as informações armazenadas por uma entrada de diretório raiz com 32 bytes, para qualquer arquivo:
Como vemos no índice da entrada do diretório raiz, somos capazes de encontrar o cluster inicial e final dos arquivos. O primeiro Byte do nome do arquivo também pode conter algumas informações importantes sobre o arquivo. A informação dada por este byte pode ser uma das seguintes:
Vamos tentar esta informação para limpar os dados de qualquer arquivo armazenado em 1.44Mb, 3 ½ disquete de polegada, com a ajuda de informações do diretório raiz. Assumindo que os dados no disquete não estão fragmentados, o programa fornecido a seguir limpa os dados do arquivo especificado de sua área de dados:
/* Programa para limpar a área de dados do arquivo especificado no disquete */
#include<stdio.h>
#include<dos.h>
///// Estrutura para ler 32 bytes de entrada de arquivo no diretório raiz \\\\\
struct root
{
unsigned char filename[8]; /* File name Entry of
8 Bytes */
unsigned char extension[3]; /* Extension of File of
3 Bytes */
unsigned char attribute; /* File Attribute Byte */
unsigned char reserved[10]; /* Reserved Bytes 10 */
unsigned int time; /* Time, 2 Bytes */
unsigned int date; /* Date, 2 Bytes */
unsigned int starting_cluster;/* Starting Cluster of File,
2 Bytes */
unsigned long file_size; /* File Size in Bytes,
4 Bytes */
};
/* Deve ser usado para ler todas as entradas do diretório raiz */
//estrutura a entrada raiz[224];
/* Estrutura para ler todas as 16 entradas de arquivo em um setor do diretório raiz */
struct one_root_sector
{
struct root entry[16];
};
struct one_root_sector one;
void main()
{
int result, i, num_sectors,j;
char wipe_buf[512]; /* Data Buffer to be used to wipe
out the data Area of file */
clrscr();
result= absread(0x00, 1, 19, &one); /* Read Absolute Sector
19 (First Sector of Root Directory) */
if (result != 0)
{
perror("Error in Reading Sector, Press any key to
Exit...");
getch();
exit(1);
}
/* Exibir informações dos arquivos após a leitura do diretório raiz */
printf(" FILE NO. FILENAME EXTENSION STARTING CLUSTER
FILESIZE \n\n");
for(i=1;i<16;i++)
{
printf("\n %5d %8.8s %3.3s %5u %10lu ",
i, one.entry[i].filename, one.entry[i].extension,
one.entry[i].starting_cluster, one.entry[i].file_size);
}
//// Obter entrada do usuário para excluir o arquivo\\\\
printf("\n\n Enter The File Number, you Want to Delete and
Wipe out Completely ");
scanf("%d", &i);
if(i<1 || i>15)
{
printf(" \"%d\" is an Invalid Choice..., Press any
Key to Exit...", i);
getch();
exit(1);
}
///// Primeiro confirme, depois continue \\\\\\
printf("\n You are About to wipe-out,
The File \"%.8s.%s\"",
one.entry[i].filename,
one.entry[i].extension);
printf("\n Do you Want to Continue...(Y/N) ");
switch(getche())
{
case 'y':
case 'Y':
break;
default:
exit(0);
}
///// Calcular o tamanho do arquivo em setores \\\\\
num_sectors = one.entry[i].file_size/512;
if((one.entry[i].file_size%512)>0)
{
num_sectors = num_sectors+1;
}
/* Buffer de dados de 512 bytes com 512 caracteres NULL*/
for(j=0;j<512;j++)
{
wipe_buf[j] = '\0';
}
///// Setor inicial do arquivo \\\\\
j= one.entry[i].starting_cluster+31;
/*Limpe a área de dados até que os setores do arquivo terminem */
while(j!=(one.entry[i].starting_cluster +
num_sectors+31) )
{
if((abswrite(0x00, 1, j, &wipe_buf))!=0)
{
printf("\n Error Writing on Disk Sectors");
getch();
exit(0);
}
j++;
}
printf("\n\n File \"%.8s.%.3s\" Deleted !!!" ,
one.entry[i].filename,
one.entry[i].extension);
one.entry[i].attribute = 0; /* Set the File Attribute
to 0 */
one.entry[i].time = 0; /* Wipe The Time information
of File */
one.entry[i].date = 0; /* Wipe The Date information
of File */
one.entry[i].starting_cluster = 0; /* Set the Starting cluster to 0
*/
one.entry[i].file_size = 0; /* Set the file Size to 0 */
one.entry[i].filename[0]=0xE5; /* Give the Deleted
file Status to the File */
/////Escreva as informações acima no diretório raiz \\\\\\
result= abswrite(0x00, 1, 19, &one);
if (result != 0)
{
perror("Error in Reading Sector, Press any key to
Exit...");
getch();
exit(1);
}
}
Comentários sobre lógica e codificação do programa:
A estrutura raiz é usada para ler 32 bytes de entrada de arquivo no diretório raiz e a estrutura one_root_sector lê todas as 16 entradas de arquivo em um setor do diretório raiz
Se você quiser ler todos os setores de informações do diretório raiz, você deve tomá-lo como struct root entry[224]; porém escrevi o programa para analisar as 16 entradas de apenas um setor do diretório raiz.
O setor inicial do arquivo foi calculado da seguinte forma:
j= one.entry[i].starting_cluster+31;
Isso é feito porque a área de dados de 1,44 MB, 3 ½ disquete de polegada inicia após os primeiros 32 setores do disquete. E no disquete de capacidade especificada, um cluster é de um setor.
A tabela a seguir mostra o mapa lógico de 1,44 MB, 3½ disquete de polegada:
A saída do programa é exibida da seguinte forma:
Aqui excluímos e limpamos os dados do arquivo PARTBOOT.C. Quando vemos o conteúdo do disquete com o comando DIR, o arquivo PARTBOOT.C não é exibido ali. Quando executamos o programa, a entrada do arquivo excluído é mostrada da seguinte maneira:
Aqui, o personagem “” (0xE5), representa que o arquivo foi excluído. (consulte a tabela para o primeiro caractere do nome do arquivo).
Se você deseja escrever o mesmo programa para o disco rígido, também deve usar o FAT com diretório raiz para obter as informações da área de dados de qualquer arquivo.
É assim porque, a taxa de dados fragmentados nas unidades de disco rígido aumenta com o tempo à medida que os arquivos mais antigos são excluídos e novos arquivos são criados. Então não é necessário que todos os clusters de dados de qualquer arquivo na unidade permaneçam um após um continuamente na área de dados. Ao acessar o FAT, você pode acessar todos esses clusters.
Página modificada em: 18/01/2022