Skip to content

Instantly share code, notes, and snippets.

@glem0
Last active April 28, 2023 14:39
Show Gist options
  • Save glem0/8ba1ee9b96767fed74db24defabc1d7e to your computer and use it in GitHub Desktop.
Save glem0/8ba1ee9b96767fed74db24defabc1d7e to your computer and use it in GitHub Desktop.
A little program to analyse the mbr of any drive on your system, and provide information about the partitions
/* analyse_mbr.c by glem */
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#define MBR_SIZE 512
#define NUM_PARTITIONS 4
/* offsets within the MBR */
#define SEC_PARTITION_START 0x1BE
#define SEC_MAGICBYTES_START 0x1FE
/* offsets within a partition record */
#define OFF_START_CHS 0x1
#define OFF_PART_DESC 0x4
#define OFF_END_CHS 0x5
#define OFF_START_SEC 0x8
#define OFF_PART_SZ 0xC
/* global mbr buffer */
static uint8_t mbr[512];
static void check_boot_indicator(uint32_t);
static void check_chs_values(char *, uint32_t);
static uint32_t check_partition_size(uint32_t);
static void check_starting_sector(uint32_t);
static void check_partition_fs(uint32_t);
static char * sector_to_size_str(uint32_t);
int
main(int argc, char **argv){
/* sanity checking, need to provide drive name */
if (argc < 2) {
printf("usage: %s /dev/<drive>\n", argv[0]);
exit(EXIT_FAILURE);
}
/* open drive and read first sector into mbr */
printf("** Opening drive %s..\n", argv[1]);
FILE *root_drive = fopen(argv[1], "r");
if (!root_drive) {
printf("Could not open %s, try running as root?\n", argv[1]);
exit(EXIT_FAILURE);
}
fread(&mbr, MBR_SIZE, 1, root_drive);
/* ensure magic bytes are in the sector read in */
if (mbr[SEC_MAGICBYTES_START+1]==0xaa && mbr[SEC_MAGICBYTES_START]==0x55)
puts("** MBR magic bytes in place!");
else {
puts("** Error - could not read magic bytes");
exit(EXIT_FAILURE);
}
/* loop through the partitions and print information */
for (uint8_t i = 0; i < NUM_PARTITIONS; i++) {
uint32_t start = SEC_PARTITION_START + i*0x10;
printf("** Analyzing Partition %u\n", i);
check_boot_indicator(start);
if(!check_partition_size(start+OFF_PART_SZ))
continue;
check_chs_values("Starting", start+OFF_START_CHS);
check_chs_values("Ending ", start+OFF_END_CHS);
check_starting_sector(start+OFF_START_SEC);
check_partition_fs(start+OFF_PART_DESC);
}
}
/*
* prints the boot flag, indicating if this partition is bootable or not
*/
static void
check_boot_indicator(uint32_t start) {
if (mbr[start]==0x00)
puts("\tThis is not bootable");
else if(mbr[start]==0x80)
puts("\tThis is bootable");
else
puts("\tError reading bootable flag");
}
/*
* retrieve the CHS value of the start/end of the partition for the drive
*/
static void
check_chs_values(char *str, uint32_t start) {
uint8_t c,h,s;
c = mbr[start];
h = mbr[start+0x1];
s = mbr[start+0x2];
printf("\t%s CHS values C=%u, H=%u, S=%u\n", str, c, h, s);
}
/*
* retrieve the number of sectors into the disk drive the partition exists
*/
static void
check_starting_sector(uint32_t start) {
uint8_t *start_loc = &mbr[start];
uint32_t start_sec = *(uint32_t *)start_loc;
char *sz_str = sector_to_size_str(start_sec);
printf("\tPartition starts at sector number %u (%s in)\n", start_sec, sz_str);
}
/*
* retrieve the number of sectors the partition occupies
*/
static uint32_t
check_partition_size(uint32_t start) {
uint8_t *size_loc = &mbr[start];
uint32_t size = *(uint32_t *)size_loc;
char *sz_str = sector_to_size_str(size);
if (size) {
sz_str = sector_to_size_str(size);
printf("\tPartition is %u sectors (%s)\n", size, sz_str);
} else
puts("\tIs an empty partition");
return size;
}
/*
* retrieve the ID indicating the type of filesystem the drive uses
*/
static void
check_partition_fs(uint32_t start) {
uint8_t fs_id = mbr[start];
printf("\tPartition filesystem id is %u\n", fs_id);
}
/*
* static function to convert a number of sectors into a useable size
*/
static char *
sector_to_size_str(uint32_t size) {
double sz_kb, sz_mb, sz_gb;
char *sz_str = malloc(10);
sz_kb = size / 2;
sz_mb = sz_kb / 1024;
sz_gb = sz_mb / 1024;
if (sz_gb>=1)
sprintf(sz_str, "%.2fGB", sz_gb);
else if (sz_mb>=1)
sprintf(sz_str, "%.2fMB", sz_mb);
else
sprintf(sz_str, "%.2fKB", sz_kb);
return sz_str;
}
** Opening drive /dev/sdb..
** MBR magic bytes in place!
** Analyzing Partition 0
This is not bootable
Partition is 1953521664 sectors (931.51GB)
Starting CHS values C=32, H=33, S=0
Ending CHS values C=254, H=255, S=255
Partition starts at sector number 2048 (1.00MB in)
Partition filesystem id is 7
** Analyzing Partition 1
This is not bootable
Is an empty partition
** Analyzing Partition 2
This is not bootable
Is an empty partition
** Analyzing Partition 3
This is not bootable
Is an empty partition
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment