Skip to content

Instantly share code, notes, and snippets.

@tranductam2802
Created October 8, 2019 05:38
Show Gist options
  • Save tranductam2802/6eb91e128b3d05a94b1c32f741c7cbac to your computer and use it in GitHub Desktop.
Save tranductam2802/6eb91e128b3d05a94b1c32f741c7cbac to your computer and use it in GitHub Desktop.
Master Boot Record format memo
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import distorm3
import hashlib
import struct
import sys
PARTITION_TYPES = {
0x00: 'Empty',
0x01: 'FAT12,CHS',
0x04: 'FAT16 16-32MB,CHS',
0x05: 'Microsoft Extended',
0x06: 'FAT16 32MB,CHS',
0x07: 'NTFS',
0x0b: 'FAT32,CHS',
0x0c: 'FAT32,LBA',
0x0e: 'FAT16, 32MB-2GB,LBA',
0x0f: 'Microsoft Extended, LBA',
0x11: 'Hidden FAT12,CHS',
0x14: 'Hidden FAT16,16-32MB,CHS',
0x16: 'Hidden FAT16,32MB-2GB,CHS',
0x18: 'AST SmartSleep Partition',
0x1b: 'Hidden FAT32,CHS',
0x1c: 'Hidden FAT32,LBA',
0x1e: 'Hidden FAT16,32MB-2GB,LBA',
0x27: 'PQservice',
0x39: 'Plan 9 partition',
0x3c: 'PartitionMagic recovery partition',
0x42: 'Microsoft MBR,Dynamic Disk',
0x44: 'GoBack partition',
0x51: 'Novell',
0x52: 'CP/M',
0x63: 'Unix System V',
0x64: 'PC-ARMOUR protected partition',
0x82: 'Solaris x86 or Linux Swap',
0x83: 'Linux',
0x84: 'Hibernation',
0x85: 'Linux Extended',
0x86: 'NTFS Volume Set',
0x87: 'NTFS Volume Set',
0x9f: 'BSD/OS',
0xa0: 'Hibernation',
0xa1: 'Hibernation',
0xa5: 'FreeBSD',
0xa6: 'OpenBSD',
0xa8: 'Mac OSX',
0xa9: 'NetBSD',
0xab: 'Mac OSX Boot',
0xaf: 'MacOS X HFS',
0xb7: 'BSDI',
0xb8: 'BSDI Swap',
0xbb: 'Boot Wizard hidden',
0xbe: 'Solaris 8 boot partition',
0xd8: 'CP/M-86',
0xde: 'Dell PowerEdge Server utilities (FAT fs)',
0xdf: 'DG/UX virtual disk manager partition',
0xeb: 'BeOS BFS',
0xee: 'EFI GPT Disk',
0xef: 'EFI System Parition',
0xfb: 'VMWare File System',
0xfc: 'VMWare Swap',
}
class PartitionEntry:
def __init__(self, data):
self.BootableFlag = struct.unpack('<c', data[:1])[0]
self.StartCHS0 = struct.unpack('<B', data[1:2])[0]
self.StartCHS1 = struct.unpack('<B', data[2:3])[0]
self.StartCHS2 = struct.unpack('<B', data[3:4])[0]
self.PartitionType = struct.unpack('<c', data[4:5])[0]
self.EndCHS0 = struct.unpack('<B', data[5:6])[0]
self.EndCHS1 = struct.unpack('<B', data[6:7])[0]
self.EndCHS2 = struct.unpack('<B', data[7:8])[0]
self.StartLBA = struct.unpack('<I', data[8:12])[0]
self.SizeInSectors = struct.unpack('<i', data[12:16])[0]
class PartitionTable:
def __init__(self, data):
self.DiskSignature0 = struct.unpack("<B", data[:1])[0]
self.DiskSignature1 = struct.unpack("<B", data[1:2])[0]
self.DiskSignature2 = struct.unpack("<B", data[2:3])[0]
self.DiskSignature3 = struct.unpack("<B", data[3:4])[0]
self.Unused = struct.unpack("<H", data[4:6])[0]
self.Entry0 = PartitionEntry(data[6:22])
self.Entry1 = PartitionEntry(data[22:38])
self.Entry2 = PartitionEntry(data[38:54])
self.Entry3 = PartitionEntry(data[54:70])
self.Signature = struct.unpack("<H", data[70:72])[0]
class MBRParser:
DATA_SIZE_BOOT_CODE = 440
DATA_SIZE_PARTITION_TABLE = 72
class MBR512Parser(MBRParser):
disonly = False
def __init__(self, data):
if len(data) == MBRParser.DATA_SIZE_BOOT_CODE:
self.BootCode = data[:MBRParser.DATA_SIZE_BOOT_CODE]
else:
raise InvalidSizeException('Invalid file size'.format(len(data)))
class MBR440Parser(MBRParser):
disonly = True
def __init__(self, data):
if len(data) == MBRParser.DATA_SIZE_BOOT_CODE + MBRParser.DATA_SIZE_PARTITION_TABLE:
self.BootCode = data[:MBRParser.DATA_SIZE_BOOT_CODE]
self.PartitionTable = PartitionTable(data[MBRParser.DATA_SIZE_BOOT_CODE:])
else:
raise InvalidSizeException('Invalid file size'.format(len(data)))
class InvalidSizeException(ValueError):
pass
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment