Kapitel – 13
Lesen und Ändern von MBR mit Programmierung
DOS-Boot-Record (DBR) / DOS-Boot-Sektor
DOS-Boot-Record (DBR) / DOS-Boot-Sektor
Nach der Partitionstabelle ist der DOS Boot Record (DBR) oder manchmal auch DOS Boot Sector genannt, die zweitwichtigste Information auf Ihrer Festplatte.
Eine detaillierte Studie über DBR finden Sie im Kapitel „Logischer Ansatz für Festplatten und Betriebssystem“, das weiter vorne in diesem Buch besprochen wurde.
Der erste logische Sektor jeder DOS-Partition enthält einen DOS Boot Record (DBR) oder DOS Boot Sector. Die Aufgabe des DBR besteht darin, das Betriebssystem von der Festplatte in den Hauptspeicher des Computers zu laden und dem geladenen Programm die Kontrolle über das System zu geben.
Der DOS Boot Record (DBR) für die erste Partition auf einer Festplatte befindet sich normalerweise im absoluten Sektor 63 (dem 64. Sektor auf dem Laufwerk) oder in CHS-Form, für die wir C–H–S = 0–1–1 sagen können die meisten Laufwerke.
Diese Position kann jedoch je nach SPT (Sektoren pro Spur) des Laufwerks variieren. Beispielsweise befand sich auf einem alten 245-MB-Laufwerk mit nur 31 SPT der Boot Record im 32. Sektor (Absolute Sector 31).
Da die Diskette keine Partitionen hat, hat sie daher keinen MBR oder Master-Partitionstabelle in ihrem ersten Sektor, stattdessen enthält sie den DBR in ihrem allerersten Sektor.
Der DBR wird mit dem FORMAT-Befehl von DOS erstellt, nachdem die Partitionierung mit dem FDISK-Befehl durchgeführt wurde. Der Sektor, auf dem sich DBR befindet, wird für das DOS zum logischen Sektor 1 dieser bestimmten Partition. Die von DOS verwendete Sektornummer beginnt mit dem physischen Sektor, auf dem sich DBR befindet.
Der DBR enthält ein kleines Programm, das von dem ausführbaren Programm Master Boot Record (MBR) ausgeführt wird. Alle DOS-Partitionen enthalten den Programmcode zum Booten der Maschine, d. h. zum Laden des Betriebssystems, aber nur diese Partition erhält die Kontrolle durch den Master Boot Record, der als aktive Partition im Partitionstabelleneintrag angegeben ist.
Wenn der DBR irgendwie beschädigt ist, sollte das Laufwerk zugänglich sein, wenn Sie das System von der bootfähigen Diskette oder CD booten. Obwohl die Festplatte nicht bootfähig ist (wenn der DBR der aktiven Partition beschädigt ist), sollte dies im Allgemeinen den Zugriff auf die Daten des Laufwerks nicht beeinträchtigen. Nach dem Booten des Systems mit der bootfähigen Diskette können Sie auf die Daten zugreifen.
/* Boot-Parameter der Diskette anzeigen */
# 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;
}
Wenn Sie dieses Programm ausführen, um den DBR einer 1,44 MB großen 3½-Zoll-Diskette mit 70 Spuren, zwei Seiten, 18 Sektoren pro Spur und 512 Bytes in einem Sektor zu testen, wird die Ausgabe des Programms ähnlich wie folgt angezeigt:
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
Lesen des DBR großer Volumes
Die Partitionsvolumes mit einer Größe von mehr als 32 MB haben ein anderes DBR-Format als der DBR für Volumes mit weniger als oder gleich 32 MB.
Es dient dazu, Unterstützung für große Volumes der Festplatte bereitzustellen (eine detaillierte Beschreibung dazu finden Sie im Kapitel „Logischer Ansatz für Festplatten und Betriebssystem“, das früher in diesem Buch besprochen wurde).
Das Format des DOS Boot Record eines FAT32-Volumes ist in der folgenden Tabelle angegeben:
Das folgende Programm soll den DBR von großen Volumes lesen, die größer als 32 MB sind:
/* Programm zum Anzeigen der Boot-Parameter von Large Disk Volume */
# 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();
}
//////// Dezimal-zu-Binär-Umwandlungsfunktion \\\\\\\\
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);
/* Binäre Ziffern umkehren und ausgeben */
do
{
printf ("%d", binary[count - 1]);
count--;
} while (count > 0);
return 0;
}
Wenn das Programm ausgeführt wird, um den DBR eines großen Volumes zu lesen, wird die Ausgabe des Programms wie folgt angezeigt:
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)
In der Ausgabe des Programms sehen wir, dass die folgenden Parameter als Null angezeigt werden:
- Root-Verzeichniseintrag.
- Anzahl der Sektoren auf der Festplatte.
- Anzahl Sektoren pro FAT.
Diese Parameter sind so, weil diese Werte auf Null gesetzt werden, wenn das Partitionsvolume größer als 32 MB ist und die eigentlichen Informationen im Extended Volume Information Block des DBR zu finden sind.
Zum Beispiel ist im Anfangsteil der DBR-Informationen die Anzahl der Sektoren pro FAT 0 und im erweiterten Volume-Informationsblock von DBR ist die Anzahl der Sektoren pro FAT 11003, was der tatsächliche Wert für dieses große Volume ist.
Der DBR des Volumes enthält wichtige Informationen zu den Festplattenparametern, mit denen alle Dateninformationen für Programmierzwecke verknüpft werden können. Wenn Sie beispielsweise auf die DBRs anderer Partitionsvolumes auf der Festplatte zugreifen möchten, können Sie dies anhand der Anzahl der Sektoren berechnen, die in DBR und andere zugehörige Informationen geschrieben sind.
Wenn Sie auf den Disk with Cluster-Ansatz zugreifen möchten, können Sie Berechnungen mit Hilfe von Sektoren pro Cluster, Sektoren pro FAT und anderen Informationen durchführen.
Wenn Sie eine Festplatte mit mehr als 8,4 GB verwenden (siehe Kapitel „Logischer Ansatz für Festplatten und Betriebssystem“, weiter oben in diesem Buch besprochen), verwenden Sie Erweiterungen, um auf alle DBRs der Festplatte über 8,4 GB zuzugreifen. Siehe erweiterte Lese-/Schreibfunktionen in den vorherigen Kapiteln.
So stellen Sie DBR mit Programmierung wieder her
Sie können den DBR des Festplattenvolumens bis zu 100 Prozent wiederherstellen, indem Sie einen kniffligen Ansatz und logische Berechnungen verwenden. Wie wir im Kapitel „Logischer Ansatz für Festplatten und Betriebssysteme“ weiter vorne in diesem Buch über logische Ansätze von Dateisystemen diskutiert haben, werden alle Informationen in DBR innerhalb einer bestimmten Grenze oder Regel geschrieben.
Jeder im DBR geschriebene Parameter hat eine bestimmte Bedeutung und wird so geschrieben, dass er einer bestimmten Regel und einem bestimmten Grund folgt. Aus diesem Grund können die Informationen von DBR, wenn sie verloren gehen, neu verknüpft oder manuell neu geschrieben werden, wenn Sie diese Regeln befolgen und den trickreichen Verstand verwenden, um herauszufinden, was und wie zu heilen ist.
Die folgende Tabelle beschreibt beispielsweise die Anzahl der Sektoren pro Cluster für verschiedene Dateisysteme, anhand derer Sie die Anzahl der Sektoren pro Cluster für Ihre Festplatte ermitteln können. Nehmen wir an, Sie hätten ein Volumen von etwa 10 GB auf Ihrer Festplatte und das von Ihnen verwendete Betriebssystem war Windows 98.
Nun, wenn überhaupt, wie die „Sektoren pro Cluster“-Informationen des DBR des Volumes beschädigt sind. Lassen Sie uns versuchen herauszufinden, welches Dateisystem und wie viele Sektoren pro Cluster Sie im Volumen Ihrer Festplatte hatten.
Da das Betriebssystem auf Ihrer Festplatte Windows 98 war, das nur das FAT-Dateisystem unterstützt, war das Dateisystem Ihres Volumes daher FAT. Lassen Sie uns nun über die Größe des Volumes nachdenken, die ungefähr 10 GB betrug.
Wir wissen, dass die 10-GB-Partition nicht von FAT16 unterstützt wird (siehe folgende Tabelle), daher sollte das Dateisystem des Volumes FAT32 sein.
Lassen Sie uns nun versuchen, die Anzahl der Sektoren pro Cluster für das Volume zu berechnen. Wie wir in der Tabelle sehen, hat die Partition im Bereich von 8 GB bis 16 GB einen Cluster von 8 Sektoren.
Daher können wir jetzt schließen, dass das Dateisystem auf dem Volume FAT32 mit 8 Sektoren pro Cluster war. In ähnlicher Weise können wir die anderen Informationen des DBR mit anderen logischen Ansätzen zusammenstellen, die in den vorherigen Kapiteln dieses Buches beschrieben wurden.
Das folgende Programm wurde geschrieben, um die Informationen von Plattenparametern in DBR einer 1,44-Mb-, 3½-Zoll-Diskette mit 80 Spuren, 2 Köpfen (Seiten) und 18 Sektoren pro Spur neu zu schreiben.
/* Programm zum Umschreiben der Parameter einer 1,44 MB großen 3½-Zoll-Diskette in ihren 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;
}
/* Funktion zum Ändern der Parameter von 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;
}
Anmerkungen zur Codierung:
Die Struktur boot wird verwendet, um auf den DBR zuzugreifen, um die Parameter der Platte zu lesen und zu schreiben. Die Funktion display_info() zeigt die verschiedenen Parameter der Festplatte an und liest aus dem DBR. Die Funktion Recover_with_values() wird verwendet, um die Parameter des DBR von Floppy zu ändern und wiederherzustellen.
Die von der Funktion Recover_with_values() verwendeten Werte gelten für Parameter des DBR von 1,44 MB, 3 ½ Zoll Diskette. Die Beschreibung dieser Werte ist in der folgenden Tabelle angegeben:
Seite Geändert am: 08/03/2022