import os import shutil import sys import time import struct def find_squashfs(filename): # Squashfs filesystem, little endian, version 4.0, compression:xz magic = '68 73 71 73 ** ** 00 00 ** ** ** ** 00 00 ** 00 ** 00 00 00 ** 00 ** 00 ** ** ** 00 ** 00 00 00 ** ** ** ** 00 00 00 00 ** ** ** 00 00 00 00 00 ** ** ** 00 00 00 00 00 FF FF FF FF FF FF FF FF' hex_bytes_list = magic.replace(' ','').split('**') first_bytes = bytes.fromhex(hex_bytes_list[0]) squashfs_files_list = [] with open(filename, 'rb') as f: data = f.read() index = data.find(first_bytes) start_index = index file_size = 0 while index != -1: # 当找到了匹配的字节序列时 find_flag = True f.seek(start_index) print(f"在偏移位置 {start_index} 找到了字节序列") for line in hex_bytes_list: line_byte_size = int(len(line)/2) if line_byte_size == 0 : index = int(index + 1) continue f.seek(index) if f.read(int(line_byte_size)) == bytes.fromhex(line): index = int(index + line_byte_size + 1) continue else: find_flag = False break if find_flag: f.seek(start_index + 40) raw_data = f.read(8) file_size = struct.unpack(' 0: if len(squashfs_files_list) > 1: print(f'发现 {len(squashfs_files_list)} 个镜像文件') for file_info in squashfs_files_list: extract_squashfs_file(image_file, file_info.get('offset'),file_info.get('size'),f"{hex(file_info.get('offset')).replace('0x', '')}-{hex(file_info.get('offset') + file_info.get('size')).replace('0x', '')}") elif sys.argv[1] == 'input': if len(sys.argv) < 4: print(f'必须最少3个参数:eg: python3 {script_name} input mtd4.bin example.squashfs') exit(1) input_image = sys.argv[3] squashfs_files_list = find_squashfs(image_file) if len(squashfs_files_list) > 0: replaced_image_file_info = squashfs_files_list[0] print(f'发现 {len(squashfs_files_list)} 个镜像文件') if len(squashfs_files_list) > 0: if len(squashfs_files_list) > 1 and len(sys.argv) < 5: print(f'发现 {len(squashfs_files_list)} 个镜像文件,必须4个参数才能打包替换') print(f'eg: python3 {script_name} input mtd4.bin example.squashfs 0') print(f'其中0 表示替换第一个镜像文件,大小不建议超过原始文件大小') exit(1) replaced_image_file_index = 0 if len(sys.argv) >= 5: replaced_image_file_index = int(sys.argv[4]) replaced_image_file_info = squashfs_files_list[replaced_image_file_index] original_image_offset = replaced_image_file_info.get('offset') original_image_size = replaced_image_file_info.get('size') input_image_size = os.path.getsize(input_image) if input_image_size > original_image_size: print(f'导入文件大小超过原始文件大小,可能导致文件结构破坏,建议新镜像文件≤原镜像文件') shutil.copy2(image_file, image_file + ".new") with open(image_file + ".new", 'r+b') as file_a: image_file_content = file_a.read() file_a.seek(original_image_offset) empty_bytes = bytes([0xFF] * original_image_size) with open(input_image, 'rb') as file_b: input_image_file_content = file_b.read() file_a.seek(original_image_offset) file_a.write(input_image_file_content)