Skip to content

Instantly share code, notes, and snippets.

@OlivierLaflamme
Created March 7, 2024 03:05
Show Gist options
  • Save OlivierLaflamme/133cc802bc3eef9a57f7f379b2f86098 to your computer and use it in GitHub Desktop.
Save OlivierLaflamme/133cc802bc3eef9a57f7f379b2f86098 to your computer and use it in GitHub Desktop.
fuck this this waste of a god damn day
import os
import struct
# Constants
START_OF_DICT = 0x11d
PARTITION_TABLE_START = 0x929
PARTITION_NAME_OFFSET = 0x21c
DICT_RECORDS_START = 0x43d
DICT_RECORD_SIZE = 0x114
BDL_RECORD_NAME_LEN = 0x100
LZMAGIC = 0x5d
# Helper function to trim trailing zeroes
def trim0(data):
if isinstance(data, bytes):
data = data.rstrip(b'\x00')
elif isinstance(data, str):
data = data.rstrip('\x00')
return data
# Parse the partition table
def parse_bdl_partition_table(binary_data):
partitions = []
while binary_data.startswith(b'ipkg'):
offset, length = struct.unpack('<QQ', binary_data[:16])
partitions.append((offset, length))
binary_data = binary_data[16:]
return partitions
# Process a partition
def process_bdl_partition(dirname, partition_data):
part_name_offset = PARTITION_NAME_OFFSET
partition_name = trim0(partition_data[part_name_offset:part_name_offset + BDL_RECORD_NAME_LEN].decode('utf-8'))
print("Partition Name:", partition_name)
part_path = os.path.join(dirname, partition_name)
os.makedirs(part_path, exist_ok=True)
process_bdl_dictionary(part_path, partition_data)
# Process the dictionary within a partition
def process_bdl_dictionary(dir_path, partition_data):
offset = DICT_RECORDS_START
while offset < len(partition_data):
filename = trim0(partition_data[offset:offset + BDL_RECORD_NAME_LEN].decode('utf-8'))
file_offset, file_len = struct.unpack('<QQ', partition_data[offset + BDL_RECORD_NAME_LEN:offset + BDL_RECORD_NAME_LEN + 16])
print("Dictionary record {}: {} {}".format(filename, file_offset, file_len))
file_data = partition_data[file_offset:file_offset + file_len]
with open(os.path.join(dir_path, filename), 'wb') as f:
f.write(file_data)
offset += DICT_RECORD_SIZE
# Main function
def main(args):
for filename in args:
print("Parsing:", filename)
with open(filename, 'rb') as f:
binary_data = f.read()
dirname = filename + ".extracted"
os.makedirs(dirname, exist_ok=True)
partition_table_data = binary_data[PARTITION_TABLE_START:]
partitions = parse_bdl_partition_table(partition_table_data)
for offset, length in partitions:
process_bdl_partition(dirname, binary_data[offset:offset + length])
if __name__ == "__main__":
import sys
main(sys.argv[1:])
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment