Last active
September 9, 2016 07:50
-
-
Save Warchant/b7eb1de44f7e91ef84a0a5b718b4cd9e to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import struct | |
f = open("GPT_TABLE", "rb") | |
w = open("GPT_TABLE_PLUS_ZFS", "wb") | |
d = f.read() | |
fields = ["BA7C6E51CF6ED6118FF800022D09712B", # ParittionTypeGUID | |
"12312312312312312312312312312312", # UniquePartitionGUID | |
"0068707400000000", # StartingLBA | |
"0068B07400000000", # EndingLBA | |
"0000000000000080" # Attributes | |
] | |
def pack(s): | |
fmt = "<" + str(len(s)) + "s" | |
return struct.pack(fmt, s) | |
for v in fields: | |
h = bytes.fromhex(v) | |
d += pack(h) | |
# PartitionName | |
name = 'c398c59a33' # OS3 | |
name = bytes.fromhex(name) | |
pn = pack(name) + b'\x00' * (72 - len(name)) | |
d += pn | |
w.write(d) | |
w.close() | |
f.close() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/python3 | |
# SCRIPT WORKS ONLY UNDER PYTHON 3 | |
import re | |
import binascii | |
import struct | |
fields = ["Mnemonic", "Byte Offset", "Byte Length", "Contents"] | |
BLOCK_SIZE = 512 | |
def get_protective_mbr(offset): | |
p_mbr = [ | |
["Boot code", offset+0, 440, "Unused by UEFI systems"], | |
["Unique MBR Disk Signature", offset+440, 4, "Unused. Set to zero."], | |
["Unknown", offset+444, 2, "Unused. Set to zero."], | |
["Partition Record", offset+446, 16*4, "Array of four MBR partition records. Contains: one non-zero partition record and three partition records each set to zero."], | |
["Signature", offset+510, 2, "Set to 0xAA55 (i.e., byte 510 contains 0x55 and byte 511 contains 0xAA)."], | |
["Reserved", offset+512, BLOCK_SIZE-512, "The rest of the logical block, if any, is reserved. Set ot zero."], | |
#["", 0, 0, ""], | |
] | |
return p_mbr | |
def get_partition_record(offset): | |
pmbrpr = [ | |
["Boot Indicator", offset, 1, "Set to 0x00 to indicate a non-bootable partition. If set to any value other than 0x00 the behavior of this flag on non-UEFI systems is undefined. Must be ignored by UEFI implementations."], | |
["StartingCHS", offset+1, 3, "Set to 0x000200, corresponding to the Starting LBA field"], | |
["OSType", offset+4, 1, "Set to 0xEE (ie, GPT protective)"], | |
["EndingCHS", offset+5, 3, "Set to CHS address of the last logical block on the disk. Set tot 0xFFFFFF if it is not possible to represent the value in this field."], | |
["StartingLBA", offset+8, 4, "Set to 0x00000001 (ie, the LBA of the GPT Partition header)"], | |
["SizeInLBA", offset+12, 4, "Set to the size of the disk minus one. Set to 0xFFFFFFFF if the size of the disk is too large to be represented in this field"], | |
] | |
return pmbrpr | |
def get_gpt_header(offset): | |
partition = [ | |
["Signature", offset+0, 8, "Constant. 0x5452415020494645"], | |
["Revision", offset+8, 4, "The revision number for this header. This revision value is not related to the UEFI specification version. This header is version 1.0, so the correct value is 0x00010000"], | |
["HeaderSize", offset+12, 4, "Size in bytes of the GPT Header."], | |
["HeaderCRC32", offset+16, 4, "CRC32 checksum for the GPT Header structure."], | |
["Reserved", offset+20, 4, "Must be zero."], | |
["MyLBA", offset+24, 8, "The LBA that contains this data structure."], | |
["AlternateLBA", offset+32, 8, "LBA Address of the alternate GPT Header"], | |
["FirstUsableLBA", offset+40, 8, "The first usable logical block that may be used by a partition described by a GIUD partition entry."], | |
["LastUsableLBA", offset+48, 8, "The last usable logical block taht may be used by a partition described by a GUID Partition Entry"], | |
["DiskGUID", offset+56, 16, "GUID that can be used to uniquely identify disk"], | |
["PartitionEntryLBA", offset+72, 8, "The starting LBA of the GUID partition entry array"], | |
["NumberOfPartitionEntries", offset+80, 4, "The number of Partition Entries in the GUID Partition Entry array"], | |
["SizeOfPartitionEntry", offset+84, 4, "The size, in bytes, of each the GUID partition entry structures in the GUID partition entry array."], | |
["PartitionEntryArrayCRC32", offset+88, 4, "The CRC32 of the GUID Partition Entry array."], | |
["Reserved", offset+92, BLOCK_SIZE-92, "The rest of the block is reserved by UEFI and must be zero."], | |
] | |
return partition | |
def get_partition_entry_array(offset, SizeOfPartitionEntry): | |
partition = [ | |
["ParittionTypeGUID", offset+0, 16, "Unique ID that defines the purpose and type of this Partition. A value of zero defines that this partition entry is not being used."], | |
["UniquePartitionGUID", offset+16, 16, "GUID that is unique for every partition entry."], | |
["StartingLBA", offset+32, 8, "Starting LBA of the partition."], | |
["EndingLBA", offset+40, 8, "Ending LBA of the partition."], | |
["Attributes", offset+48, 8, "Attribute bits, all bits reserved by UEFI"], | |
["PartitionName", offset+56, 72, "Null-terminated string containing a human-readable name of the partition."], | |
["Reserved", offset+128, SizeOfPartitionEntry-128, "The rest of the GPT Partition Entry, if any, is reserved by UEFI and must be zero."], | |
] | |
return partition | |
def pphex(h): | |
if len(h) == 0: | |
raise Exception("len(h) == 0") | |
text = "" | |
for i, byte in enumerate(h): | |
if 33 <= byte <= 127: | |
text += chr(byte) | |
else: | |
text += "." | |
hh = ["{:02x}".format(x) for x in h] | |
hh = "".join(hh).upper() | |
d = int.from_bytes(h, byteorder='little') | |
hh = re.sub("([0-9A-Fa-f]{4})", lambda x: x.groups()[0] + " ", hh) | |
hh = re.sub("((?:[0-9A-Fa-f]{4} ){8})", lambda x: x.groups()[0] + "\n", hh) | |
return hh, d, text | |
with open("GPT_TABLE", "rb") as file: | |
data = file.read() | |
tables = [ | |
["Protective MBR", get_protective_mbr(0)], | |
["Partition record 0", get_partition_record(446 + 16*0)], | |
["Partition record 1", get_partition_record(446 + 16*1)], | |
["Partition record 2", get_partition_record(446 + 16*2)], | |
["Partition record 3", get_partition_record(446 + 16*3)], | |
["GPT header", get_gpt_header(512)], | |
["Partition 0", get_partition_entry_array(1024 + 128*0, 128)], | |
["Partition 1", get_partition_entry_array(1024 + 128*1, 128)], | |
["Partition 2", get_partition_entry_array(1024 + 128*2, 128)], | |
] | |
for title, table in tables: | |
print("\n\n#########", title.upper(), "#########") | |
for record in table: | |
for i in range(len(fields)): | |
print(fields[i],":",record[i]) | |
first = record[1] | |
last = record[1] + record[2] | |
d = data[first:last] | |
if len(d) > 0: | |
hhex, dec, text = pphex(d) | |
print("Value(hex)", ":\n", hhex, sep="") | |
print("Value(dec)", ":\n", dec, sep="") | |
print("Value(printable)", ":\n", text, sep="") | |
else: | |
print("Value: (zero-length)") | |
print("\n") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment