Skip to content

Instantly share code, notes, and snippets.

@u1735067
Last active February 9, 2023 16:23
Show Gist options
  • Star 8 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save u1735067/ebd6a06aacedc3c045b6f31fdf4c829c to your computer and use it in GitHub Desktop.
Save u1735067/ebd6a06aacedc3c045b6f31fdf4c829c to your computer and use it in GitHub Desktop.
Python gpt.bin decoder (gpt.bin for Xiaomi MiPad2, but probably for other plateforms too) ; you'll want https://gist.github.com/u1735067/b3a23c9461e95433387f285f6e0860ca
#!python3
''' BSD 3-Clause License — but if it was useful to you, you may tell me :)
Copyright (c) 2016-2017, Alexandre Levavasseur
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the copyright holder nor the names of its
contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
'''
import sys, io
from struct import unpack
from uuid import UUID
# Utils
try:
# See https://gist.github.com/Alex131089/b3a23c9461e95433387f285f6e0860ca
# and put guids.py in the same location
from guids import guids
except:
guids = {}
# https://stackoverflow.com/questions/1094841/reusable-library-to-get-human-readable-version-of-file-size
def sizeof_fmt(num, suffix='B'):
for unit in ['','Ki','Mi','Gi','Ti','Pi','Ei','Zi']:
if abs(num) < 1024.0:
return "%g %s%s" % (num, unit, suffix)
num /= 1024.0
return "%g %s%s" % (num, 'Yi', suffix)
# Help
if len(sys.argv) < 2:
print('Usage: ./{} <gpt.bin>'.format(sys.argv[0]))
exit(-1)
# Defines
# https://github.com/android-ia/vendor_intel_common/blob/master/gpt_bin/gpt_ini2bin.py
expected_magic = 0x6a8b0da1
header_len = 0xC # = 3*4 : A1 0D 8B 6A 00 00 00 00 0D 00 00 00
# MAGIC Start LBA ENTRY COUNT
entry_len = 0x6C
# Now start
# http://www.devdungeon.com/content/working-binary-data-python
with open(sys.argv[1], "rb") as binary_file:
# Read the whole file at once
data = binary_file.read()
# https://stackoverflow.com/questions/18563018/how-to-remove-a-range-of-bytes-from-a-bytes-object-in-python
#del data[0:0xc]
# https://stackoverflow.com/questions/20024490/how-to-split-a-byte-string-into-separate-bytes-in-python
entries = [data[i:i+entry_len] for i in range(header_len, len(data)-header_len, entry_len)]
magic, start_lba, entries_count = unpack('<LLL', data[:header_len])
print('{:<16} = 0x{:x} ({})'.format('Magic', magic, ('valid' if magic == expected_magic else 'invalid, 0x{:x} expected'.format(expected_magic))))
print('{:<16} = {}'.format('Start LBA', start_lba))
print('{:<16} = {} (file size allows {} entries)'.format('Partition count', entries_count, len(entries)))
print()
print ('{:<36} {:<10} {:36}\t{}'.format('Partition name', 'Size', 'GPT Type GUID', 'Partition UUID'))
print ('{:-<36} {:-<10} {:-<36}\t{:-<36}'.format('', '', '', ''))
for entry in entries:
# https://stackoverflow.com/questions/14859578/how-to-read-bytes-as-stream-in-python-3
# https://docs.python.org/3/library/io.html
entry = io.BytesIO(entry)
# https://docs.python.org/3/library/struct.html
size = unpack('<L', entry.read(4))[0]
size_pp = sizeof_fmt(size*1024*1024)
#print(size[0], 'MB')
# https://docs.python.org/3/library/codecs.html#standard-encodings
# https://stackoverflow.com/questions/1185524/how-to-trim-whitespace-including-tabs
name = entry.read(0x48).decode('utf_16_le').strip('\0')
#print(name)
# https://docs.python.org/3.1/library/uuid.html
guid = UUID(bytes_le=entry.read(0x10))
guid_name = guids[guid] if guid in guids else str(guid)
#print(guid)
puid = UUID(bytes_le=entry.read(0x10))
puid_name = guids[puid] if puid in guids else str(puid)
#print(puid)
print ('{:<36} {:<10} {:36}\t{}'.format(name, size_pp, guid_name, puid_name))
end = entry.read()
if len(end) > 0:
print('Extra data:', end)
'''
--Sample outputs :
PS D:\Dev\GPT> py -3 .\read.py .\gpt_dual.bin
Magic = 0x6a8b0da1 (valid)
Start LBA = 0
Partition count = 13 (file size allows 13 entries)
Partition name Size GPT Type GUID Partition UUID
------------------------------------ ---------- ------------------------------------ ------------------------------------
android_persistent 7 MiB Linux filesystem data Android-IA Persistent
android_config 8 MiB Linux filesystem data Android-IA Config
android_factory 10 MiB Linux filesystem data Android-IA Factory
android_misc 6 MiB Android-IA Misc Android-IA Misc
android_metadata 16 MiB Android-IA Metadata Android-IA Metadata
android_bk1 16 MiB Linux filesystem data Linux filesystem data
android_bootloader 32 MiB EFI System partition Android-IA Bootloader
android_bootloader2 32 MiB Windows Basic data partition Android-IA Bootloader2
android_boot 32 MiB Android-IA Boot Android-IA Boot
android_recovery 32 MiB Android-IA Recovery Android-IA Recovery
android_system 1.875 GiB Linux filesystem data Android-IA System
android_cache 256 MiB Linux filesystem data Android-IA Cache
android_data 12 GiB Linux filesystem data Android-IA Data
PS D:\Dev\GPT> py -3 .\read.py .\gpt_miui.bin
Magic = 0x6a8b0da1 (valid)
Start LBA = 0
Partition count = 13 (file size allows 13 entries)
Partition name Size GPT Type GUID Partition UUID
------------------------------------ ---------- ------------------------------------ ------------------------------------
android_persistent 7 MiB Linux filesystem data Android-IA Persistent
android_config 8 MiB Linux filesystem data Android-IA Config
android_factory 10 MiB Linux filesystem data Android-IA Factory
android_misc 6 MiB Android-IA Misc Android-IA Misc
android_metadata 16 MiB Android-IA Metadata Android-IA Metadata
android_bk1 16 MiB Linux filesystem data Linux filesystem data
android_bootloader 32 MiB EFI System partition Android-IA Bootloader
android_bootloader2 32 MiB Windows Basic data partition Android-IA Bootloader2
android_boot 32 MiB Android-IA Boot Android-IA Boot
android_recovery 32 MiB Android-IA Recovery Android-IA Recovery
android_system 1.875 GiB Linux filesystem data Android-IA System
android_cache 256 MiB Linux filesystem data Android-IA Cache
android_data 4 PiB Linux filesystem data Android-IA Data
'''
@davidtuti
Copy link

Hi!
Congratulations for these wonderfoul development. Is possible to can change the size of the partition with these script? Thanks, and sorry for my English!

@u1735067
Copy link
Author

@davidtuti : if you're not afraid to open an hex editor, probably yes, but this script is not intended to make changes, only to read data. You can check your modifications after with it though.
Hint, if I'm not making mistake : size is 4 bytes (xx xx xx xx) just before the name, in MB. Bytes are reversed due to endianness.
Example : https://imgur.com/a/Xvk6s (0x00000780 = 1920MB = 1,875GB (/1024))

@kuri65536
Copy link

Thank you, this works perfect for me.
my result (output) here.

Magic            = 0x6a8b0da1 (valid)
Start LBA        = 0
Partition count  = 11 (file size allows 11 entries)

Partition name                       Size       GPT Type GUID                           Partition UUID
------------------------------------ ---------- ------------------------------------    ------------------------------------
android_bootloader                   100 MiB    c12a7328-f81f-11d2-ba4b-00a0c93ec93b    2568845d-2332-4675-bc39-8fa5a4748d15
android_bootloader2                  100 MiB    ebd0a0a2-b9e5-4433-87c0-68b6b72699c7    114eaffe-1552-4022-b26e-9b053604cf84
android_boot                         30 MiB     49a4d17f-93a3-45c1-a0de-f50b2ebe2599    49a4d17f-93a3-45c1-a0de-f50b2ebe2599
android_recovery                     30 MiB     4177c722-9e92-4aab-8644-43502bfd5506    4177c722-9e92-4aab-8644-43502bfd5506
android_misc                         1 MiB      ef32a33b-a409-486c-9141-9ffb711f6266    ef32a33b-a409-486c-9141-9ffb711f6266
android_metadata                     16 MiB     20ac26be-20b7-11e3-84c5-6cfdb94711e9    20ac26be-20b7-11e3-84c5-6cfdb94711e9
android_system                       2.5 GiB    0fc63daf-8483-4772-8e79-3d69d8477de4    38f428e6-d326-425d-9140-6e0ea133647c
android_cache                        256 MiB    0fc63daf-8483-4772-8e79-3d69d8477de4    a893ef21-e428-470a-9e55-0668fd91a2d9
android_data                         4 PiB      0fc63daf-8483-4772-8e79-3d69d8477de4    dc76dda9-5ac1-491c-af42-a82591580c0d
android_persistent                   1 MiB      0fc63daf-8483-4772-8e79-3d69d8477de4    ebc597d0-2053-4b15-8b64-e0aac75f4db1
android_config                       8 MiB      0fc63daf-8483-4772-8e79-3d69d8477de4    bd59408b-4514-490d-bf12-9878d963f378

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment