Skip to content

Instantly share code, notes, and snippets.

@Warchant
Last active September 9, 2016 07:50
Show Gist options
  • Save Warchant/b7eb1de44f7e91ef84a0a5b718b4cd9e to your computer and use it in GitHub Desktop.
Save Warchant/b7eb1de44f7e91ef84a0a5b718b4cd9e to your computer and use it in GitHub Desktop.
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()
#!/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