doitaljosh/samsung-hass-fw-unpacker

GitHub: doitaljosh/samsung-hass-fw-unpacker

该工具用于解包、校验和重新打包三星 HASS 家电固件的 .tar 更新归档文件,处理其中定制压缩的 payload。

Stars: 0 | Forks: 0

# Samsung HASS 固件更新包解包/打包工具 此代码库包含一个 Python 工具,用于解包和重新打包 Samsung HASS 家电固件更新归档文件。 它可以: - 提取 `.tar` 更新包 - 将 Samsung 定制的 `.lzw` payload 解压缩为原始的 `.bin` 固件镜像 - 根据 `firminfo.xml` 校验大小和 CRC - 将原始的 `.bin` 固件镜像重新压缩为 Samsung 定制的 `.lzw` - 使用正确的压缩和解压缩大小/校验和更新 `firminfo.xml` - 构建新的更新 `.tar` 这些包使用的 `.lzw` 扩展名具有误导性。它**不是** Unix `compress` / 标准 LZW。这是一种从 Samsung HART-M320 / ABOV A33G527 家电 bootloader 中还原出来的小型 Samsung 定制 LZ 类格式。 ## 代码库文件 ``` hass_fw_tool.py Main unpack / pack / verify tool examples/ Example Samsung HASS update TAR archives requirements.txt Notes that no third-party dependencies are required ``` ## 环境要求 推荐使用 Python 3.9+。不需要任何第三方 Python 包。 ## 包结构 典型的 Samsung HASS 更新归档文件如下所示: ``` example_update.tar ├── firminfo.xml ├── SOME_PART_0x1234_YYMMDD.lzw └── another_payload.lzw ``` `firminfo.xml` 存储了压缩的 `.lzw` payload 和解压后的原始固件二进制文件的大小和 CRC 元数据。 ## 压缩格式 压缩流使用 256 字节的循环历史缓冲区。 - 除 `0xB4` 以外的任何字节都会按原样复制到输出,并插入到历史缓冲区中。 - `B4 00` 表示输出一个字面量 `0xB4`。 - `B4 DD NN` 表示从历史缓冲区中复制 `NN` 个字节,起始位置位于当前历史写入位置之后(向后偏移)的 `DD` 个字节处。 此代码库中的编码器为还原的 bootloader 解压缩器创建有效的流。它**不会**尝试逐字节复现 Samsung 原始的压缩数据,因此重新压缩的 `.lzw` 文件大小/校验和可能与原始文件不同。解压缩后的固件字节和 XML 最终校验和应与输入的 `.bin` 匹配。 ## 校验和验证 `firminfo.xml` 中的两个校验和字段均使用 **CRC-16/CCITT-FALSE**: - 多项式:`0x1021` - 初始值:`0xFFFF` - 反转输入/输出:否 - 最终异或值:`0x0000` XML 字段: - `Compressed_Size` = 原始 `.lzw` 大小,以十六进制存储 - `Compressed_Checksum` = 原始 `.lzw` 字节的 CRC - `Size` = 解压缩后的原始固件大小,以十六进制存储 - `Checksum` = 解压缩后的原始固件二进制文件的 CRC 如果在解包过程中任何声明的值不匹配,工具将停止并报错。 ## 解包示例 在代码库根目录下执行: ``` python3 hass_fw_tool.py unpack examples/DE92-04768A_240131.tar -o out --manifest ``` 这将生成: ``` out/ ├── DE92-04768A_240131/ │ └── DE92-04768A_0x4B6B_231216.bin └── manifest.csv ``` 解包所有包含的示例 TAR 文件: ``` python3 hass_fw_tool.py unpack examples/*.tar -o out --manifest ``` 预期结果:所有文件都应输出 `OK`,并且解码后的二进制文件应与 XML 中的 `Size` 和 `Checksum` 值相匹配。 ## 在不进行 XML 校验的情况下解码单个 `.lzw` 文件 ``` python3 hass_fw_tool.py unpack path/to/payload.lzw -o out ``` 直接的 `.lzw` 解码会计算 CRC 并生成一个 `.bin` 文件,但除非您提供原始的 TAR 包,否则它无法通过 XML 进行校验。 ## 使用原始 TAR 作为模板,将二进制文件重新打包为更新 TAR 最安全的工作流是使用原始的更新 TAR 作为模板。这会保留诸如 `DBCode`、`Version`、`Start`、`BPS`、`TargetName` 和根固件属性等元数据,同时替换指定的 payload 并刷新大小/校验和字段。 首先解包原始文件: ``` python3 hass_fw_tool.py unpack examples/DE92-04768A_240131.tar -o out ``` 然后重新打包解码或修改过的二进制文件: ``` python3 hass_fw_tool.py pack \ --template examples/DE92-04768A_240131.tar \ --replace DE92-04768A_0x4B6B_231216.lzw=out/DE92-04768A_240131/DE92-04768A_0x4B6B_231216.bin \ -o repacked_DE92-04768A_240131.tar ``` 该工具将会: 1. 将 `.bin` 压缩为 Samsung 定制的 `.lzw` 格式。 2. 在内部验证 `decompress(compress(bin)) == bin`。 3. 更新 `firminfo.xml` 中匹配的 `` 行: - `Compressed_Size` - `Compressed_Checksum` - `Size` - `Checksum` 4. 生成一个新的 TAR,其中包含重新压缩的 `.lzw` 和更新后的 `firminfo.xml`。 验证新的 TAR: ``` python3 hass_fw_tool.py unpack repacked_DE92-04768A_240131.tar -o verify --manifest ``` ## 将多个二进制文件重新打包到一个 TAR 中 为每个 payload 使用一个 `--replace` 参数: ``` python3 hass_fw_tool.py pack \ --template examples/DE92-04721A_DE92-04768A_240208.tar \ --replace DE92-04721A_0x99DF_240115.lzw=out/DE92-04721A_DE92-04768A_240208/DE92-04721A_0x99DF_240115.bin \ --replace DE92-04768A_0x4B6B_231216.lzw=out/DE92-04721A_DE92-04768A_240208/DE92-04768A_0x4B6B_231216.bin \ -o repacked_DE92-04721A_DE92-04768A_240208.tar ``` ## 构建没有模板的最小化 TAR 您可以从头创建一个最小化的 `firminfo.xml`。这主要用于研究,因为真实的家电可能需要特定于型号的元数据。 ``` python3 hass_fw_tool.py pack \ --replace MY_PAYLOAD.lzw=firmware.bin \ --attr OtnVersion=20260709 \ --attr TargetName=main \ -o custom_update.tar ``` 为了保证家电更新的兼容性,最好使用真实的原始 TAR 作为模板。 ## 包含的示例 TAR 文件 `examples/` 目录包含用于测试的 Samsung HASS 更新归档示例: ``` examples/DE92-04721A_DE92-04768A_240208.tar examples/DE92-04768A_240131.tar examples/DE92-04769A_DE92-04770A_240525.tar examples/FG_DA92-01156A_241204.tar ``` ## 安全提示 此工具不会刷写固件,也不会与家电硬件进行通信。 修改和刷写固件可能会对家电控制板造成永久性损坏,引发不安全的家电行为,或违反保修/监管要求。除非您完全了解目标 bootloader/更新过程,否则请仅将此工具用于研究、恢复、对比和存档工作。
标签:Python, 三星, 固件工具, 嵌入式, 文件解压缩, 无后门, 逆向工具