diff --git a/CP02/README.md b/CP02/README.md index 6911c20..7b3ab06 100644 --- a/CP02/README.md +++ b/CP02/README.md @@ -71,6 +71,40 @@ - 支持多种芯片 ID 的引导加载程序变体 - 输出签名的二进制文件和相关 JSON 元数据 +### bin_to_txt_converter.py +- **功能**: 将二进制文件转换为文本格式 +- **用法**: `python3 bin_to_txt_converter.py [output.txt]` +- **描述**: + - 将二进制文件(如 IUM)转换为文本格式 + - 按 4 字节块处理数据,转换为十六进制字符串 + - 支持小端序字节序转换 + - 输出文件包含 start/end 标记 + - 未指定输出文件时自动生成文件名 + +### txt_to_bin_converter.py +- **功能**: 将文本格式转换回二进制文件 +- **用法**: `python3 txt_to_bin_converter.py ` +- **描述**: + - 将文本格式(如 ium11.txt)转换回二进制文件 + - 处理 8 字符十六进制字符串为 4 字节整数 + - 写入前 63 个完整的 4 字节值 + - 第 64 个值仅写入第一个字节 + - 跳过 start/end 标记行 + +### merge_encrypted_firmware.py +- **功能**: 合成已加密的固件和 IUM 为最终 programmer 固件 +- **用法**: `python3 merge_encrypted_firmware.py -o ` +- **描述**: + - 合并 Base firmware (16KB)、加密固件 (最大 119KB) 和 IUM storage (256 bytes) + - 固件布局: + - 0x0000 - 0x4000: Base firmware + - 0x4000 - 0x1DC00: 加密用户固件 + - 0x1DC00 - 0x1DD00: IUM storage + - 0x1DD00 - 0x1DD10: Metadata (16 bytes) + - 自动生成 metadata(包含 blocks 和 last_block_size) + - 显示完整的内存布局和校验信息 + - IUM storage 包含 CRC8 和 CRC16 校验 + ## 使用示例 ```bash @@ -98,4 +132,12 @@ python3 signer_new.py --firmware firmware.bin --output_dir ./output python3 signer_new.py --bootloader bootloader.bin --output_dir ./output --enable_swd python3 signer_new.py --firmware firmware.bin --bootloader bootloader.bin --output_dir ./output --boot_directly + +# 二进制与文本格式转换 +python3 bin_to_txt_converter.py ium.bin # 自动生成输出文件名 +python3 bin_to_txt_converter.py ium.bin ium_converted.txt # 指定输出文件 +python3 txt_to_bin_converter.py ium11.txt ium11.bin # 文本转二进制 + +# 合成加密固件 +python3 merge_encrypted_firmware.py base.bin encrypted.bin ium.bin -o programmer.bin ``` \ No newline at end of file diff --git a/CP02/bin_to_txt_converter.py b/CP02/bin_to_txt_converter.py new file mode 100755 index 0000000..98682b4 --- /dev/null +++ b/CP02/bin_to_txt_converter.py @@ -0,0 +1,100 @@ +#!/usr/bin/env python3 +""" +Binary to Text Converter for IUM files +Converts .bin files to .txt format matching ium11.txt structure +""" + +import sys +import os + + +def bin_to_txt(bin_file_path, txt_file_path=None): + """ + Convert binary file to text format matching the ium11.txt structure + + Args: + bin_file_path (str): Path to input binary file + txt_file_path (str): Path to output text file (optional) + + Returns: + str: Path to generated text file + """ + + if not os.path.exists(bin_file_path): + raise FileNotFoundError(f"Binary file not found: {bin_file_path}") + + # Generate output filename if not provided + if txt_file_path is None: + base_name = os.path.splitext(bin_file_path)[0] + txt_file_path = f"{base_name}_converted.txt" + + # Read binary file + try: + with open(bin_file_path, 'rb') as bin_file: + binary_data = bin_file.read() + except Exception as e: + raise Exception(f"Error reading binary file: {e}") + + # Convert binary data to text format + try: + with open(txt_file_path, 'w') as txt_file: + # Write start marker + txt_file.write("start\n") + + # Process binary data in 4-byte chunks (32-bit words) + for i in range(0, len(binary_data), 4): + chunk = binary_data[i:i+4] + + # Pad with zeros if chunk is less than 4 bytes + if len(chunk) < 4: + chunk = chunk + b'\x00' * (4 - len(chunk)) + + # Convert to little-endian 32-bit hex value + hex_value = chunk[::-1].hex().upper() # Reverse bytes for little-endian + + # Format as 8-character hex string + hex_value = hex_value.zfill(8) + + # Write hex value + txt_file.write(f"{hex_value}\n") + + # Write end marker + txt_file.write("end\n") + txt_file.write("\n") + + return txt_file_path + + except Exception as e: + raise Exception(f"Error writing text file: {e}") + + +def main(): + """Main function to handle command line arguments""" + + if len(sys.argv) < 2: + print("Usage: python bin_to_txt_converter.py [output_txt_file]") + print("\nExample:") + print(" python bin_to_txt_converter.py ium11.bin") + print(" python bin_to_txt_converter.py ium11.bin ium11_converted.txt") + sys.exit(1) + + bin_file_path = sys.argv[1] + txt_file_path = sys.argv[2] if len(sys.argv) > 2 else None + + try: + output_path = bin_to_txt(bin_file_path, txt_file_path) + print(f"Successfully converted {bin_file_path} to {output_path}") + + # Show file sizes for verification + bin_size = os.path.getsize(bin_file_path) + txt_size = os.path.getsize(output_path) + print(f"Binary file size: {bin_size} bytes") + print(f"Text file size: {txt_size} bytes") + + except Exception as e: + print(f"Error: {e}") + sys.exit(1) + + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/CP02/merge_encrypted_firmware.py b/CP02/merge_encrypted_firmware.py new file mode 100644 index 0000000..f95d628 --- /dev/null +++ b/CP02/merge_encrypted_firmware.py @@ -0,0 +1,139 @@ +#!/usr/bin/env python3 +""" +合成已加密的固件和 IUM 为最终 programmer 固件 + +固件布局: + 0x0000 - 0x4000: Base firmware (16KB) + 0x4000 - 0x1DC00: 加密后的用户固件 (最大 119KB) + 0x1DC00 - 0x1DD00: IUM storage (256 bytes) + 0x1DD00 - 0x1DD10: Metadata (16 bytes) + +IUM Storage 结构 (256 bytes): + Bytes 0-252: Modified IUM (253 bytes) + Byte 253: CRC8 + Bytes 254-255: CRC16 (little-endian) + +用法: + python3 merge_encrypted_firmware.py base.bin encrypted.bin ium_storage.bin -o output.bin +""" + +import argparse +import struct +import sys +from pathlib import Path + +# 常量定义 +BASE_FIRMWARE_SIZE = 0x4000 # 16KB +USER_FIRMWARE_MAX_SIZE = 0x1DC00 # 119KB +IUM_STORAGE_SIZE = 0x100 # 256 bytes +METADATA_SIZE = 0x10 # 16 bytes + +BASE_FIRMWARE_OFFSET = 0x0000 +USER_FIRMWARE_OFFSET = 0x4000 +IUM_OFFSET = 0x1DC00 +METADATA_OFFSET = 0x1DD00 + + +def main(): + parser = argparse.ArgumentParser( + description='合成加密固件和IUM为最终programmer固件', + formatter_class=argparse.RawDescriptionHelpFormatter, + epilog=''' +示例: + %(prog)s base.bin encrypted_binary.bin ium.bin -o programmer.bin + +输入文件说明: + base_firmware - Base firmware BIN 文件 (最大 16KB) + encrypted_binary - 已加密的固件 BIN 文件 (*_encrypted_binary.bin) + ium_storage - IUM storage 文件 (256 bytes, *_ium.bin) + ''' + ) + parser.add_argument('base_firmware', help='Base firmware BIN 文件 (最大 16KB)') + parser.add_argument('encrypted_binary', help='已加密的固件 BIN 文件') + parser.add_argument('ium_storage', help='IUM storage 文件 (256 bytes)') + parser.add_argument('-o', '--output', required=True, help='输出文件路径') + + args = parser.parse_args() + + # 检查文件是否存在 + for filepath, name in [ + (args.base_firmware, 'Base firmware'), + (args.encrypted_binary, 'Encrypted binary'), + (args.ium_storage, 'IUM storage') + ]: + if not Path(filepath).exists(): + print(f"错误: {name} 文件不存在: {filepath}") + sys.exit(1) + + # 读取文件 + base_firmware = Path(args.base_firmware).read_bytes() + encrypted_binary = Path(args.encrypted_binary).read_bytes() + ium_storage = Path(args.ium_storage).read_bytes() + + # 验证大小 + if len(base_firmware) > BASE_FIRMWARE_SIZE: + print(f"错误: Base firmware 最大 {BASE_FIRMWARE_SIZE} bytes (16KB), 实际 {len(base_firmware)} bytes") + sys.exit(1) + + if len(encrypted_binary) > USER_FIRMWARE_MAX_SIZE: + print(f"错误: 加密固件最大 {USER_FIRMWARE_MAX_SIZE} bytes (119KB), 实际 {len(encrypted_binary)} bytes") + sys.exit(1) + + if len(ium_storage) != IUM_STORAGE_SIZE: + print(f"错误: IUM storage 必须是 {IUM_STORAGE_SIZE} bytes (256), 实际 {len(ium_storage)} bytes") + sys.exit(1) + + print("合成 Programmer 固件:") + print(f" Base firmware: {args.base_firmware} ({len(base_firmware)} bytes)") + print(f" Encrypted binary: {args.encrypted_binary} ({len(encrypted_binary)} bytes)") + print(f" IUM storage: {args.ium_storage} ({len(ium_storage)} bytes)") + print() + + # 创建输出缓冲区 (填充 0xFF) + total_size = METADATA_OFFSET + METADATA_SIZE + output = bytearray([0xFF] * total_size) + + # 复制 base firmware (0x0000) + output[BASE_FIRMWARE_OFFSET:BASE_FIRMWARE_OFFSET + len(base_firmware)] = base_firmware + + # 复制加密固件 (0x4000) + output[USER_FIRMWARE_OFFSET:USER_FIRMWARE_OFFSET + len(encrypted_binary)] = encrypted_binary + + # 复制 IUM storage (0x1DC00) + output[IUM_OFFSET:IUM_OFFSET + IUM_STORAGE_SIZE] = ium_storage + + # 生成 metadata + blocks = len(encrypted_binary) // 256 + last_block_size = len(encrypted_binary) % 256 + + # Metadata 结构: uint16_t blocks, uint8_t last_block_size, uint8_t reserved[13] + metadata = struct.pack(' ") + sys.exit(1) + + txt_file = sys.argv[1] + bin_file = sys.argv[2] + + try: + convert_txt_to_bin(txt_file, bin_file) + print(f"Successfully converted {txt_file} to {bin_file}") + except Exception as e: + print(f"Error: {e}") + sys.exit(1) \ No newline at end of file