Created
March 7, 2024 03:05
-
-
Save OlivierLaflamme/133cc802bc3eef9a57f7f379b2f86098 to your computer and use it in GitHub Desktop.
fuck this this waste of a god damn day
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 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