Capítulo – 13
Lendo e modificando o MBR com programação
Registro de inicialização do DOS (DBR) / Setor de inicialização do DOS
Registro de inicialização do DOS (DBR) / Setor de inicialização do DOS
Depois da tabela de partições, o DOS Boot Record (DBR) ou às vezes chamado DOS Boot Sector é a segunda informação mais importante em seu disco rígido.
Para um estudo detalhado sobre DBR, consulte o capítulo "Abordagem lógica para discos e SO", discutido anteriormente neste livro.
O primeiro setor lógico de cada partição DOS conterá um DOS Boot Record (DBR) ou DOS Boot Sector. O trabalho do DBR é carregar o sistema operacional do disco rígido para a memória principal do computador e dar o controle do sistema ao programa carregado.
O DOS Boot Record (DBR) para a primeira partição em um disco rígido é geralmente encontrado no Setor Absoluto 63 (o 64º setor na unidade de disco) ou na forma CHS, podemos dizer C–H–S = 0–1 –1 para a maioria das unidades.
No entanto, esta localização pode variar dependendo do SPT (Setores por Pista) do Drive. Por exemplo, em uma unidade antiga de 245 MB com apenas 31 SPT, o registro de inicialização estava localizado no 32º setor (Absolute Sector 31).
Como o disquete não possui partições, ele não possui MBR ou Master Partition Table em seu primeiro setor, em vez disso, ele contém o DBR em seu primeiro setor.
O DBR é criado pelo comando FORMAT do DOS, após o particionamento ser feito usando o comando FDISK. O setor no qual o DBR reside torna-se o setor lógico 1 dessa partição específica para o DOS. O número do setor usado pelo DOS começa no setor físico no qual o DBR está localizado.
O DBR contém um pequeno programa que é executado pelo programa executável Master Boot Record (MBR). Todas as partições DOS contêm o código do programa para inicializar a máquina, ou seja, carregar o sistema operacional, mas apenas essa partição recebe controle do Master Boot Record, que é especificado como partição ativa, na entrada da tabela de partições.
Se o DBR estiver corrompido de alguma forma, a unidade deve estar acessível se você inicializar o sistema a partir do disquete ou CD inicializável. Embora o disco rígido não seja inicializável (se o DBR da partição ativa estiver corrompido), isso geralmente não deve afetar o acesso aos dados da unidade de disco. Depois de inicializar o sistema com o disco inicializável, você pode acessar os dados.
/* Exibe os parâmetros de inicialização do disquete */
# include <dos.h>
# include <stdio.h>
main( )
{
struct boot
{
unsigned char code[3] ; /* Jump Code */
unsigned char system_id[8] ;/* OEM Name and Version*/
int bytes_per_sec ; /* Bytes Per Sector */
char sec_per_clus ; /* Sectors Per Cluster */
int res_sec ; /* Reserved Sectors */
char fat_copies ; /* Number of FATs */
int root_dir_entry ; /* Number of Root
Directory Entries */
unsigned int no_sects ; /* Number of Sectors in
Logical Volume */
unsigned char format_id ; /* Media Descriptor Byte
*/
int sec_per_fat ; /* Sectors Per FAT */
int sec_per_trk ; /* Sectors Per Track */
int no_sides ; /* Number of Heads */
int no_sp_res_sect ; /* Number of Hidden
Sectors */
unsigned char rest_code[482] ; /* Rest of the code */
} ;
struct boot b ;
char temp[4] ;
int val, drive ;
val = absread(0, 1, 0, &b) ; /* Use For Floppy Disk*/
if ( val == -1 )
{
printf ( "Disk read Error...bad sector\n" ) ;
exit ( 1 ) ;
}
clrscr ( ) ;
printf ( "System ID = %s\n",
b.system_id ) ;
printf ( "Bytes per sector = %d\n",
b.bytes_per_sec ) ;
printf ( "Sectors per cluster = %d\n",
b.sec_per_clus ) ;
printf ( "Reserved sectors = %d\n",
b.res_sec ) ;
printf ( "FAT copies = %d\n",
b.fat_copies ) ;
printf ( "Root directory entries = %d\n",
b.root_dir_entry ) ;
printf ( "No. of sectors on disk = %u\n",
b.no_sects ) ;
printf ( "Media Descriptor Byte = %X\n",
b.format_id ) ;
printf ( "Sectors per FAT = %d\n",
b.sec_per_fat ) ;
printf ( "Sectors per track = %d\n",
b.sec_per_trk ) ;
printf ( "No. of sides = %d\n",
b.no_sides ) ;
printf ( "No. of reserved sectors = %d\n",
b.no_sp_res_sect ) ;
return 0;
}
Se você executar este programa para testar o DBR de 1,44M, disquete de 3½ polegadas com 70 trilhas, dois lados, 18 setores por trilha e 512 bytes em um setor, a Saída do Programa será exibida semelhante a:
System ID = +1<*uIHC
Bytes per sector = 512
Sectors per cluster = 1
Reserved sectors = 1
FAT copies = 2
Root directory entries = 224
No. of sectors on disk = 2880
Media Descriptor Byte = F0
Sectors per FAT = 9
Sectors per track = 18
No. of sides = 2
No. of reserved sectors = 0
Lendo o DBR de grandes volumes
Os volumes de partição com tamanho superior a 32 MB têm algum formato de DBR diferente do DBR para volumes menores ou iguais a 32 MB.
É para fornecer suporte a grandes volumes do disco (para uma descrição detalhada, consulte o capítulo “Abordagem lógica para discos e SO”, discutido anteriormente neste livro).
O formato do DOS Boot Record de um volume FAT32 foi fornecido na tabela a seguir:
O programa a seguir é para ler o DBR de grandes volumes, com tamanho superior a 32 MB:
/* Programa para exibir os parâmetros de inicialização do Grande Volume de Disco */
# include "dos.h"
# include "stdio.h"
void main()
{
struct boot
{
unsigned char code[3] ; /* Jump Code */
unsigned char system_id[8] ; /* OEM name & Version */
int bytes_per_sec ; /* Bytes Per Sector */
char sec_per_clus ; /* Sectors Per Cluster*/
unsigned int res_sec ; /* Number of Reserved
Sectors */
char fat_copies ; /* Number of FATs */
unsigned int root_dir_entry ;/* Number of Root
Directory Entry */
unsigned int no_sects ; /* Number of Sectors in
Logical Volume (if
Volume is <= 32MB) */
unsigned char Media_id ; /* Media Descriptor Byte
*/
unsigned int sec_per_fat ; /* Sector Per FAT */
unsigned int sec_per_trk ; /* Sectors Per Track */
unsigned int no_sides ; /* Number of Heads */
unsigned long no_sp_res_sect ; /* Number of Hidden
Sectors */
unsigned long long_sec_num ; /* Total Sectors in
Logical Volume
( Size >32MB) */
unsigned long num_sec_per_FAT; /* Sectors Per FAT */
unsigned int binary_flags; /* Binary Flags */
unsigned char version_of_FAT1; /* First Byte of FAT
Version */
unsigned char version_of_FAT2; /* Second Byte of FAT
Version */
unsigned long root_dir_start_cluster;
/* Root Directory
Starting Cluster
Number */
unsigned int sec_num_of_file_sys;
/* Sector Number of
File System
Information Sector
*/
unsigned int sec_num_of_backup_boot_sec;
/* Sector Number of
Backup Boot Sector
*/
unsigned char reserved[12]; /* Reserved */
unsigned char logical_drive_number;
/* Physical Drive
Number of Logical
Volume */
unsigned char unused_byte; /* Unused Byte */
unsigned char hex_extd_boot_signature;
/* Extended Boot
Signature(29H) */
unsigned long binary_volume_ID;/* Binary Volume ID */
unsigned char volume_label[11];/* Volume Label */
unsigned char FAT_name[8]; /* FAT Name */
unsigned char rest_code[420] ; /* Rest 420 Bytes of
The DBR */
unsigned char magic_number[2]; /* Magic Number */
} ;
struct boot b ;
char temp[4] ;
int val, drive,i;
val = biosdisk( 2, 0x80, 1,0,1,1, &b ) ;
/* For First Hard Disk */
if ( val == -1 )
{
printf ( "Disk read Error...bad sector\n" ) ;
exit ( 1 ) ;
}
clrscr ( ) ;
printf ( " Jump Instruction Code = ");
for(i=0;i<=2;i++)
{
printf("%X",b.code[i]);
}
printf("(H)\n ");
printf ( "OEM name and version = %s\n ",
b.system_id ) ;
printf ( "Bytes per sector = %u\n ",
b.bytes_per_sec ) ;
printf ( "Sectors per cluster = %u\n ",
b.sec_per_clus ) ;
printf ( "Reserved sectors = %u\n ",
b.res_sec ) ;
printf ( "FAT copies = %d\n ",
b.fat_copies ) ;
printf ( "Root directory entries = %u\n ",
b.root_dir_entry ) ;
printf ( "No. of sectors on disk = %u\n ",
b.no_sects ) ;
printf ( "Media Descriptor Byte = %X(H)\n",
b.Media_id ) ;
printf ( "Sectors per FAT = %u\n ",
b.sec_per_fat ) ;
printf ( "Sectors per track = %u\n ",
b.sec_per_trk ) ;
printf ( "No. of sides = %u\n ",
b.no_sides ) ;
printf ( "No. of reserved (Hidden) sectors= %lu\n ",
b.no_sp_res_sect ) ;
printf ( "========== For Large(>32MB) Disks ========\n");
printf ( "No. of sectors,(if Volume is >32MB) = %lu\n ",
b.long_sec_num) ;
printf ( “Number of Sectors Per FAT = %lu\n “,
b.num_sec_per_FAT );
printf ( "Root Directory Starting Cluster = %lu\n ",
b.root_dir_start_cluster);
printf ( "File System Information Sector = %u\n ",
b.sec_num_of_file_sys);
printf ( "Sector Number of Backup Boot Sector = %u\n ",
b.sec_num_of_backup_boot_sec);
printf ( "Physical Drive Number = %X(H)\n",
b.logical_drive_number);
printf ( "Extended Boot Signature = %X(H)\n",
b.hex_extd_boot_signature);
printf ( "32-Bit Binary Volume ID = ");
Decimal_to_Binary (b.binary_volume_ID,32);
printf ( " (B)\n ");
printf ( "Volume Label = ");
for(i=0;i<=10;i++)
{
printf ( "%c",b.volume_label[i]);
}
printf ( "\n FAT name = ");
for(i=0;i<=7;i++)
{
printf ( "%c",b.FAT_name[i]);
}
printf ( "\n ");
printf ( "Magic Number = %X%X(H)",
b.magic_number[0],b.magic_number[1]);
getch();
}
//////// Função de conversão de decimal para binário \\\\\\\\
Decimal_to_Binary(unsigned long input)
{
unsigned long i;
int count = 0;
int binary [32]; /* 32 Bit MAX only 32
elements total */
do
{
i = input%2; /* MOD 2 to get 1 or a 0*/
binary[count] = i; /* Load Elements into the
Binary Array */
input = input/2; /* Divide input by 2 to
decrement via binary */
count++; /* Count howy elements
are needed */
}while (input > 0);
/* Dígitos binários reversos e de saída */
do
{
printf ("%d", binary[count - 1]);
count--;
} while (count > 0);
return 0;
}
Quando o programa é executado para ler o DBR de um grande volume, a saída do programa é exibida da seguinte forma:
Jump Instruction Code = EB5890 (H)
OEM name and version = MSWIN4.1
Bytes per sector = 512
Sectors per cluster = 8
Reserved sectors = 32
FAT copies = 2
Root directory entries = 0
No. of sectors on disk = 0
Media Descriptor Byte = F8 (H)
Sectors per FAT = 0
Sectors per track = 63
No. of sides = 255
No. of reserved (Hidden) sectors = 63
=========== For Large (>32MB) Disks ===========
No. of sectors, (if Volume is >32MB) = 11277567
Number of Sectors per FAT = 11003
Root Directory Starting Cluster = 2
File System Information Sector = 1
Sector Number of Backup Boot Sector = 6
Physical Drive Number = 80 (H)
Extended Boot Signature = 29 (H)
32-Bit Binary Volume ID = 110101010001100001110111100101 (B)
Volume Label = SAAYA
FAT name = FAT32
Magic Number = 55AA (H)
Na saída do programa vemos que os seguintes parâmetros são mostrados zero:
- Entrada de diretório raiz
- Número de setores no disco
- Número de setores por FAT
Esses parâmetros são assim porque esses valores são definidos como zero, se o volume da partição for maior que 32 MB e as informações reais forem encontradas no Bloco de Informações de Volume Estendido do DBR.
Por exemplo, na parte inicial das informações de DBR, o número de setores por FAT é 0 e no bloco de informações de volume estendido de DBR o número de setores por FAT é 11003, que é o valor real para esse grande volume .
O DBR do Volume contém as informações importantes sobre os parâmetros do disco, que podem ser usadas para vincular todas as informações de dados para fins de programação. Por exemplo, se você deseja acessar os DBRs de outro volume de partição no disco, pode calculá-lo pelo número de setores, escrito em DBR e outras informações relacionadas.
Se você deseja acessar a abordagem Disco com cluster, pode fazer cálculos com a ajuda de Setores por cluster, setores por FAT e outras informações.
Se você estiver usando o disco rígido com mais de 8,4 GB (consulte o capítulo “Abordagem lógica para discos e SO”, discutido anteriormente neste livro), use extensões para acessar todos os DBRs do disco além de 8,4 GB. Consulte as funções estendidas de leitura e gravação, fornecidas nos capítulos anteriores
Como recuperar o DBR com programação
Você pode recuperar o DBR do volume do disco em até 100% usando uma abordagem complicada e cálculos lógicos. Como discutimos sobre abordagens lógicas de sistemas de arquivos no capítulo “Abordagem lógica para discos e SO”, anteriormente neste livro, todas as informações em DBR são escritas dentro de algum limite ou regra.
Cada parâmetro escrito no DBR tem algum significado específico e é escrito seguindo alguma regra e razão específica. É por isso que as informações do DBR, se perdidas, podem ser vinculadas novamente ou reescritas manualmente se você seguir essas regras e usar a mente complicada para descobrir o que e como curar.
Por exemplo, a tabela a seguir descreve o número de setores por cluster para diferentes sistemas de arquivos, usando o qual você pode encontrar o número de setores por cluster para seu disco. Vamos supor que você tenha um volume de aproximadamente 10 GB em seu disco e que o sistema operacional que você estava usando fosse o Windows 98.
Agora, se houver, como as informações de “Setores por cluster” do DBR do volume estão corrompidas. Vamos tentar descobrir qual sistema de arquivos e quantos setores por clusters você tinha no volume do seu disco.
Como o sistema operacional em seu disco era o Windows 98, que suporta apenas o sistema de arquivos FAT, portanto, o sistema de arquivos do seu volume era FAT. Agora vamos pensar no tamanho do volume, que era de aproximadamente 10 GB.
Sabemos que a partição de 10 GB não é compatível com FAT16 (consulte a tabela a seguir), portanto, o sistema de arquivos do volume deve ser FAT32.
Agora vamos tentar calcular o número de setores por cluster para o volume. Como vemos na tabela que a partição dentro do intervalo de 8GB a 16GB possui um cluster de 8 setores.
Portanto, agora podemos concluir que no volume, o sistema de arquivos era FAT32 com 8 setores por cluster. Da mesma forma, podemos montar as outras informações do DBR usando outras abordagens lógicas descritas nos capítulos anteriores deste livro.
O programa a seguir foi escrito para reescrever as informações dos parâmetros do disco em DBR de 1,44Mb, disquete de 3½ polegadas, com 80 trilhas, 2 cabeças (lados) e 18 setores por trilha.
/* Programa para reescrever os parâmetros de um disquete de 1,44 MB e 3½ polegadas em seu DBR */
# include "dos.h"
# include "stdio.h"
struct boot
{
unsigned char code[3] ; /* Jump Code */
unsigned char system_id[8] ; /* OEM ID and Version*/
int bytes_per_sec ; /* Bytes Per Sector */
char sec_per_clus ; /* Number of Sectors
Per Cluster */
int res_sec ; /* Reserved Sectors */
char fat_copies ; /* Number of FATs */
int root_dir_entry ; /* Number of Root
Directory Entries */
unsigned int no_sects ; /* Number of Total
Sectors */
unsigned char format_id ; /* Media Descriptor
Byte */
int sec_per_fat ; /* Sectors Per FAT */
int sec_per_trk ; /* Sectors Per FAT */
int no_sides ; /* Number of
Sides(Heads) */
int no_sp_res_sect ; /* Number of Hidden
Sectors */
unsigned char rest_code[482] ;/* Rest 482 Bytes code
of DBR */
} ;
struct boot b ;
main( )
{
int val ;
val = absread(0, 1, 0, &b); /* Use For Floppy Disk */
if ( val == -1 )
{
printf ( "\n Disk read Error...bad sector\n" ) ;
exit ( 1 ) ;
}
clrscr ( ) ;
display_info();
getch();
printf("\n Now Recovering BDR of Floppy.....\n");
Recover_with_values();
printf ( "\n Disk Recovered Successfully." ) ;
display_info();
return 0;
}
/* Função para alterar os parâmetros do DBR */
Recover_with_values()
{
int val =0;
/* Jump Code of 3 Bytes For Floppy */
b.code[0] = 0xEB;
b.code[1]= 0x3E;
b.code[2]= 0x90 ;
/* System Id of 8 Bytes */
strcpy(b.system_id, "+05PSIHC");
/* Bytes Per Sector = 512 */
b.bytes_per_sec = 512;
/* Sector per Cluster for 1.44M 3.5" Floppy = 1 */
b.sec_per_clus = 1;
/* Number of Reserved Sectors = 1 */
b.res_sec =1;
/* Number of FAT Copies = 2 */
b.fat_copies =2;
/* Number of Root Directory Entry = 224 */
b.root_dir_entry =224;
/* Number of Sectors on Disk = 2880 */
b.no_sects =2880;
/* Media Descriptor Byte For Floppy = F0 (H) */
b.format_id =0xF0;
/* Sectors Per FAT = 9 */
b.sec_per_fat =9;
/* Sectors Per Track = 18 */
b.sec_per_trk =18;
/* Number of Sides = 2 */
b.no_sides =2;
/* Number of Special Reserved Sectors (or Hidden
Sectors) = 0 */
b.no_sp_res_sect =0;
/* Use For Floppy Disk*/
val = abswrite ( 0, 1, 0, &b ) ;
if ( val == -1 )
{
printf ( "\n Disk Write Error...bad sector\n" ) ;
printf ( " Disk was not Recovered." ) ;
exit ( 1 ) ;
}
return 0;
}
display_info()
{
printf ( "\n Jump Code (Hex) = %X%X%X (H)\n",
b.code[0],b.code[1],b.code[2]);
printf ( " System ID = %s\n",
b.system_id ) ;
printf ( " Bytes per sector = %d\n",
b.bytes_per_sec ) ;
printf ( " Sectors per cluster = %d\n",
b.sec_per_clus ) ;
printf ( " Reserved sectors = %d\n",
b.res_sec ) ;
printf ( " FAT copies = %d\n",
b.fat_copies ) ;
printf ( " Root directory entries = %d\n",
b.root_dir_entry ) ;
printf ( " No. of sectors on disk = %u\n",
b.no_sects ) ;
printf ( " Media Descriptor Byte = %X\n",
b.format_id ) ;
printf ( " Sectors per FAT = %d\n",
b.sec_per_fat ) ;
printf ( " Sectors per track = %d\n",
b.sec_per_trk ) ;
printf ( " No.sides = %d\n",
b.no_sides ) ;
printf ( " No. of reserved sectors = %d\n",
b.no_sp_res_sect ) ;
return 0;
}
Comentários sobre a codificação:
A estrutura boot é usada para acessar o DBR, para ler-escrever os parâmetros do disco. A função display_info(), exibe os diversos parâmetros do disco, lendo do DBR. A função Recover_with_values() é usada para modificar e recuperar os parâmetros do DBR do disquete.
Os valores usados pela função Recover_with_values(), são para parâmetros de DBR de disquetes de 1,44 MB, 3 ½ polegadas. A descrição desses valores foi dada na tabela a seguir:
Página modificada em: 17/01/2022