-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathmbr_parse.py
More file actions
108 lines (96 loc) · 5.08 KB
/
mbr_parse.py
File metadata and controls
108 lines (96 loc) · 5.08 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
# Python script to parse MBR image files
# This just parses the first 512 bytes
#
# Tom Yarrish
# Version 2.0
#
# To run, simply type: mbr_parse.py <file to parse>
#
# To do:
# - Only bring in first 512 bytes in case it's run against an image
# - Handle extended partitions
import sys
import struct
import binascii
from binascii import hexlify
# This is a dictionary listing to identify the partition type
def check_partition_type(file_type_hex):
file_system = { '0x0' : "Empty", '0x1' : "FAT12", '0x2' : "XENIX root", '0x3' : "XENIX usr",
'0x4' : "FAT16", '0x5' : "Extended", '0x6' : "FAT16B", '0x7' : "NTFS", '0x8' : "AIX" ,
'0x9' : "AIX Bootable" , '0xa' : "OS/2 Boot" , '0xb' : "Win95 FAT32" , '0xc' : "Win95 FAT32" ,
'0xd' : "Reserved" , '0xe' : "Win95 FAT16" , '0xf' : "Win95 Ext" , '0x10' : "OPUS" ,
'0x11' : "FAT12 Hidden" , '0x12' : "Compaq Diag" , '0x13' : "N/A" , '0x14' : "FAT16 Hidden" ,
'0x15' : "Extended Hidden" , '0x16' : "FAT16 Hidden" , '0x17' : "NTFS Hidden" , '0x18' : "AST" ,
'0x19' : "Willowtech" , '0x1a' : "N/A" , '0x1b' : "Hidden FAT32" , '0x1c' : "Hidden FAT32X" ,
'0x1d' : "N/A" , '0x1e' : "Hidden FAT16X" }
try:
file_partition_type = file_system[file_type_hex]
except:
file_partition_type = "File system not recognized."
return file_partition_type
# This function is used to parse out the partition start and partition length data
def partition_value(decode):
byte_1 = struct.pack("<B", decode[0])
byte_2 = struct.pack("<B", decode[1])
byte_3 = struct.pack("<B", decode[2])
byte_4 = struct.pack("<B", decode[3])
combine_bytes = byte_1 + byte_2 + byte_3 + byte_4
partition_data = struct.unpack("<L",combine_bytes)[0]
return partition_data
# This function does the heavy lifting and parses out the parition information
def parse_partition(partition):
# Check to see if there is an actual partition. This checks the start_head, start_sector,
# start_cylinder, partition_type, and partition_start
if (partition[1] == 0) and (partition[2] == 0) and (partition[3] == 0) and (partition[4] == 0) and (partition_value(partition[8:12]) == 0):
return False
else:
try:
boot_ind = hex(partition[0]) # Boot indicator
start_head = (partition[1]) # Get start head value
start_sector = (partition[2]) # Get start sector value
start_cylinder = (partition[3]) # Get start cylinder value
partition_type = hex(partition[4]) # Get file system type
end_head = (partition[5]) # Get end head value
end_sector = (partition[6]) # Get end sector value
end_cylinder = (partition[7]) # Get end cylinder value
partition_start = partition_value(partition[8:12])
partition_length = partition_value(partition[12:16]) # Get the length of the partition
return boot_ind, start_head, start_sector, start_cylinder, partition_type, end_head,\
end_sector, end_cylinder, partition_start, partition_length
except:
print "Unable to parse partition."
mbr_file = sys.argv[1]
with open(mbr_file, "rb") as f:
mbr_data = f.read(512)
disk_sig = struct.unpack("<L", mbr_data[440:444])
start = 446
end = 462
print "\nDisk Signature is {}\n".format(hex(disk_sig[0]))
# This section reads in each 16 bytes of data from the MBR partition section and interprets the data
num_partitions = 0
while(num_partitions <= 3): # stop when we have iterated 4 times
# grab data
partition_data = struct.unpack("<BBBBBBBBBBBBBBBB", mbr_data[start:end])
#do_something(partition_data)
format_partition = parse_partition(partition_data)
if format_partition == False:
print "Partition {} is not a valid....skipping".format(num_partitions)
else:
print "Here is the information for partition {}:\n ".format(num_partitions)
if (format_partition[0]) == "0x80": # Is it bootable or no?
print "Partition is bootable"
else:
print "Partition is not bootable"
print "Start head is {}".format(format_partition[1])
print "Start sector is {}".format(format_partition[2])
print "Start cylinder is {}".format(format_partition[3])
print "Partition type is {} {}".format((format_partition[4]), check_partition_type((format_partition[4])))
print "End head is {}".format(format_partition[5])
print "End sector is {}".format(format_partition[6])
print "End cylinder is {}".format(format_partition[7])
print "Partition start is at sector {}".format(format_partition[8])
print "Partition size is {}".format(format_partition[9])
# increment our variables
start = end # after the first pass, 446 becomes 462
end = end + 16 # after the first pass, 462 becomes 478
num_partitions = num_partitions + 1