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, 三星, 固件工具, 嵌入式, 文件解压缩, 无后门, 逆向工具