固件签名验证机制详细报告
1. 概述
本报告详细分析了 l66 智能手表固件的签名验证机制,包括:
- HMBZSIGN (bootloader 签名)
- HMRVYSIG (recovery 签名)
- 固件头验证 (CRC16)
- 文件哈希验证 (SHA256)
- 云绑定签名验证
2. 固件结构
2.1 固件文件清单
| 文件 |
大小 |
用途 |
| firmware.bin |
5,792,564 bytes |
主固件 |
| bootloader_sign.bin |
381,740 bytes |
Bootloader 签名 |
| recovery_sign.bin |
438,032 bytes |
Recovery 签名 |
| extfw/recovery_sign.bin |
438,032 bytes |
Recovery 签名 (扩展) |
| filehash |
32 bytes |
SHA256 文件哈希 |
2.2 固件头结构
偏移 长度 内容 说明
0x00-07 8 "Qq4_X" Magic 签名
0x08-0F 8 "g2.1.0.1" 版本字符串 (长度+字符串)
0x10-17 8 "Pp" Product Header
0x18-... ... 代码/数据 实际固件内容
0x38D866 2 head_sign CRC16 签名
0x38D8F8 2 crc16 CRC16 校验和
3. HMBZSIGN (Bootloader 签名)
3.1 位置
- 文件:
bootloader_sign.bin
- 偏移:
0x5D2BC (文件末尾)
3.2 结构
偏移 长度 内容 说明
+0x00-07 8 "HMBZSIGN" 魔数 (Magic)
+0x08-0B 4 0xD2BC0030 大小/偏移 (LE)
+0x0C-0F 4 0x00670005 标志/版本
+0x10-11 2 0x0001 状态标志
+0x12-17 6 00 00 00 00 00 00 保留
+0x18-27 16 "1.5.5" 版本字符串 (null-padded)
+0x28-2B 4 0xD2BC0030 大小 (重复)
+0x2C-2F 4 00 00 00 00 保留
+0x30-6F 64 [签名数据] SHA256/AES 签名哈希
3.3 版本差异
| 版本 |
偏移 |
+0x30-0x3F (签名数据) |
| 2012 |
0x5D2BC |
a6 6e 81 df 29 32 a6 a2 3e 16 5f 9b 1b c1 7e 10 |
| 2101 |
0x5D2BC |
66 7e 73 37 18 e6 53 37 63 af 31 82 0d 27 9f 7e |
结论: 签名数据不同,说明 bootloader 在版本间有变化。
3.4 命名含义
HMBZSIGN = Hardware Model Bootloader Zone Signature
- H: Hardware
- M: Model
- BZ: Bootloader Zone
- SIGN: Signature
4. HMRVYSIG (Recovery 签名)
4.1 位置
- 文件:
extfw/recovery_sign.bin
- 偏移:
0x6AEA0 (文件末尾)
4.2 结构
偏移 长度 内容 说明
+0x00-07 8 "HMRVYSIG" 魔数 (Magic)
+0x08-0B 4 0xAEA00030 大小/偏移 (LE)
+0x0C-0F 4 0x00670006 标志/版本
+0x10-11 2 0x0001 状态标志
+0x12-17 6 00 00 00 00 00 00 保留
+0x18-27 16 "1.5.7" 版本字符串 (null-padded)
+0x28-2B 4 0xAEA00030 大小 (重复)
+0x2C-2F 4 00 00 00 00 保留
+0x30-6F 64 [签名数据] SHA256/AES 签名哈希
4.3 版本差异
| 版本 |
偏移 |
+0x30-0x3F (签名数据) |
| 2012 |
0x6AEA0 |
E0 13 0D A6 66 E0 02 9E 27 8F A1 61 AC 35 18 C0 |
| 2101 |
0x6AEA0 |
B0 41 DD F0 BA AB DC B9 01 EC E9 BA AA 70 00 72 |
结论: 签名数据不同,说明 recovery 固件在版本间有变化。
4.4 命名含义
HMRVYSIG = Hardware Model Recovery Version Y Signature
- H: Hardware
- M: Model
- RV: Recovery Version
- Y: 签名算法标识 (Y=某种对称/非对称签名)
- SIG: Signature
5. 验证流程
5.1 启动验证流程
┌─────────────────────────────────────────────────────────┐
│ 设备启动 │
├─────────────────────────────────────────────────────────┤
│ 1. Bootloader 阶段 │
│ - 加载 bootloader_sign.bin │
│ - 验证 HMBZSIGN 签名 │
│ - 验证 bootloader 版本 (1.5.5) │
│ - 验证签名数据 (+0x30-0x6F) │
│ │
│ 2. Firmware 阶段 │
│ - 加载 firmware.bin │
│ - 验证 Magic: "Qq4_X" │
│ - 验证 CRC16: head_sign[0x%04X] │
│ - 验证 SHA256: 对比 /mnt/system/filehash │
│ │
│ 3. Recovery 阶段 (如进入 Recovery 模式) │
│ - 加载 extfw/recovery_sign.bin │
│ - 验证 HMRVYSIG 签名 │
│ - 验证 recovery 版本 (1.5.7) │
│ - 验证签名数据 (+0x30-0x6F) │
└─────────────────────────────────────────────────────────┘
5.2 验证步骤详情
步骤 1: 固件头验证
// 验证 Magic
if (memcmp(firmware, "Qq4_X", 5) != 0) {
// 错误: 无效的固件 Magic
}
// 验证 CRC16
uint16_t expected_crc = *(uint16_t*)(firmware + 0x38D866);
uint16_t calculated_crc = crc16(firmware + 0x18, firmware_size - 0x18);
if (expected_crc != calculated_crc) {
printf("[EC=%04X] head_sign[0x%04x] isn't equal [0x%04x]",
error_code, expected_crc, calculated_crc);
}
步骤 2: 文件哈希验证
// 读取存储的哈希
FILE* f = fopen("/mnt/system/filehash", "rb");
fread(stored_hash, 1, 32, f);
fclose(f);
// 计算固件哈希
sha256(firmware + 0x18, firmware_size - 0x18, calculated_hash);
// 比较哈希
if (memcmp(stored_hash, calculated_hash, 32) != 0) {
printf("factory fs check fail");
} else {
printf("factory fs check success");
}
步骤 3: HMBZSIGN 验证
// 读取 bootloader_sign.bin
FILE* f = fopen("/mnt/system/bootloader_sign.bin", "rb");
fread(bootloader_sign, 1, bootloader_sign_size, f);
fclose(f);
// 查找 HMBZSIGN
char* hmbz_pos = memmem(bootloader_sign, bootloader_sign_size, "HMBZSIGN", 8);
if (hmbz_pos == NULL) {
// 错误: 找不到 HMBZSIGN
}
// 验证版本
char* version = hmbz_pos + 0x18;
if (strcmp(version, "1.5.5") != 0) {
// 错误: 版本不匹配
}
// 验证签名数据
// +0x30-0x6F 包含 64 字节签名哈希
// 使用 SHA256/AES 验证
步骤 4: HMRVYSIG 验证
// 读取 recovery_sign.bin
FILE* f = fopen("/mnt/system/extfw/recovery_sign.bin", "rb");
fread(recovery_sign, 1, recovery_sign_size, f);
fclose(f);
// 查找 HMRVYSIG
char* hmrvy_pos = memmem(recovery_sign, recovery_sign_size, "HMRVYSIG", 8);
if (hmrvy_pos == NULL) {
// 错误: 找不到 HMRVYSIG
}
// 验证版本
char* version = hmrvy_pos + 0x18;
if (strcmp(version, "1.5.7") != 0) {
// 错误: 版本不匹配
}
// 验证签名数据
// +0x30-0x6F 包含 64 字节签名哈希
// 使用 SHA256/AES 验证
5.3 错误处理
| 错误代码 |
字符串 |
说明 |
| - |
head_sign[0x%04x] isn't equal [0x%04x] |
CRC16 验证失败 |
| - |
crc16[0x%04x] isn't equal [0x%04x] |
CRC16 校验和不匹配 |
| - |
factory fs check fail |
文件哈希验证失败 |
| - |
sign verify not pass |
签名验证失败 |
| 0x%02X |
verify cloud binding signature failed |
云绑定签名验证失败 |
| - |
EC[%d%03d%ld] set factory_fs_check_key check fail |
工厂密钥检查失败 |
6. 关键字符串位置
6.1 固件验证字符串
| 地址 |
字符串 |
作用 |
| 0x38D866 |
head_sign[0x%04X] |
打印头签名 |
| 0x38D912 |
[EC=%04X] head_sign[0x%04x] isn't equal [0x%04x] |
头签名不匹配错误 |
| 0x38D8F8 |
crc16[0x%04X] |
打印 CRC16 |
| 0x38D943 |
[EC=%04X] crc16[0x%04x] isn't equal [0x%04x] |
CRC16 不匹配错误 |
| 0x39BE71 |
#### start check system resource filehash |
开始文件哈希检查 |
| 0x39BDB7 |
factory fs check success |
文件系统检查成功 |
| 0x39BDD0 |
factory fs check fail |
文件系统检查失败 |
| 0x3C214D |
EC[%d%03d%ld] sign verify not pass |
签名验证失败 |
| 0x3A0F6B |
EC[%d%03d%ld] verify cloud binding signature failed with code: 0x%02X |
云绑定签名失败 |
| 0x38D744 |
bootloader_upgrade start |
Bootloader 升级开始 |
| 0x38E228 |
Enter %s, line:%d need upgrade recovery gapp. |
需要升级 recovery |
6.2 加密相关字符串
| 地址 |
字符串 |
作用 |
| 0x3AEE56 |
SHA256 |
SHA256 算法标识 |
| 0x3A096C |
size % BX_AUTHORIZE_AES_KEY_LENGTH == 0 |
AES 密钥长度检查 |
| 0x3A099C |
EC[%d%03d%ld] cannot create AES context for encryption |
AES 加密上下文创建失败 |
| 0x3A09C5 |
EC[%d%03d%ld] AES encrypt failed cause mbedtls_aes_setkey_enc return: %d |
AES 加密失败 |
| 0x3A0A27 |
EC[%d%03d%ld] AES encrypt failed cause mbedtls_aes_crypt_ecb return: %d |
AES ECB 加密失败 |
| 0x3A0AA5 |
EC[%d%03d%ld] AES decrypt failed cause mbedtls_aes_setkey_enc return: %d |
AES 解密失败 |
6.3 文件路径字符串
| 地址 |
字符串 |
作用 |
| 0x39BEE2 |
/mnt/system/filehash |
文件哈希存储路径 |
| 0x3C2284 |
A/extfw/recovery_sign.bin |
Recovery 签名文件路径 |
| 0x3FA40C |
m/extfw/recovery_sign.bin |
Recovery 签名文件路径 (备份) |
| 0x39BED2 |
//components/fs/storage/src/app_fs.c |
源代码路径 |
7. 版本间差异总结
7.1 HMBZSIGN (bootloader_sign.bin)
| 项目 |
2012 版本 |
2101 版本 |
差异 |
| 文件大小 |
381,740 bytes |
381,740 bytes |
相同 |
| HMBZSIGN 偏移 |
0x5D2BC |
0x5D2BC |
相同 |
| 版本字符串 |
"1.5.5" |
"1.5.5" |
相同 |
| +0x30-0x3F |
a6 6e 81 df... |
66 7e 73 37... |
不同 |
7.2 HMRVYSIG (extfw/recovery_sign.bin)
| 项目 |
2012 版本 |
2101 版本 |
差异 |
| 文件大小 |
438,032 bytes |
438,032 bytes |
相同 |
| HMRVYSIG 偏移 |
0x6AEA0 |
0x6AEA0 |
相同 |
| 版本字符串 |
"1.5.7" |
"1.5.7" |
相同 |
| +0x30-0x3F |
E0 13 0D A6... |
B0 41 DD F0... |
不同 |
7.3 firmware.bin
| 项目 |
2012 版本 |
2101 版本 |
差异 |
| 文件大小 |
5,792,556 bytes |
5,792,564 bytes |
+8 bytes |
| MD5 |
311e6ccfa0f924ef30fa5b0fc358dde3 |
d7969693c4c2afe87ee185e045006598 |
不同 |
| SHA256 |
93cde60f... |
73abe4ed... |
不同 |
8. 结论
-
HMBZSIGN 和 HMRVYSIG 是固件签名元数据,用于验证 bootloader 和 recovery 固件的完整性。
-
签名验证流程:
- 启动时验证固件头 (Magic + CRC16)
- 验证文件哈希 (SHA256)
- 验证签名文件 (HMBZSIGN/HMRVYSIG)
- 验证云绑定签名 (可选,用于 APP 绑定)
-
版本间签名数据不同,说明:
- 固件内容有变化
- 签名需要重新计算
- 不能直接替换旧版本的签名
-
验证使用 MbedTLS 库:
- SHA256 用于哈希计算
- AES-ECB 用于加密/解密
- CRC16 用于快速校验
-
验证失败会导致:
- 固件升级失败
- 设备无法启动
- 进入 Recovery 模式
9. 附录
9.1 相关文件
firmware.bin: 主固件文件
bootloader_sign.bin: Bootloader 签名文件
recovery_sign.bin: Recovery 签名文件
extfw/recovery_sign.bin: 扩展 Recovery 签名文件
filehash: SHA256 文件哈希
9.2 验证代码位置
| 功能 |
代码地址 |
说明 |
| 固件头验证 |
0x38D866 |
验证 Magic 和 CRC16 |
| 文件哈希验证 |
0x39BE71 |
验证 SHA256 哈希 |
| 签名验证 |
0x3C214D |
验证签名数据 |
| 云绑定验证 |
0x3A0F6B |
验证云绑定签名 |
| Bootloader 升级 |
0x38D744 |
Bootloader 升级流程 |
| Recovery 升级 |
0x38E228 |
Recovery 升级流程 |
9.3 加密库
- MbedTLS: 加密库
- SHA256: 哈希算法
- AES-ECB: 对称加密算法
- CRC16: 快速校验算法
9.4 存储路径
/mnt/system/filehash: 文件哈希存储
/mnt/system/bootloader_sign.bin: Bootloader 签名
/mnt/system/extfw/recovery_sign.bin: Recovery 签名
报告生成时间: 2026-04-25
分析工具: Python, IDA Pro
分析版本: 2012, 2101
bootloader_sign.bin 分析报告
1. 概述
本报告对 bootloader_sign.bin 进行签名校验机制的逆向分析。
1.1 二进制基本信息
| 属性 |
值 |
| 文件路径 |
C:\Users\meny\Desktop\2101\META\bootloader_sign.bin |
| 文件大小 |
381,740 bytes (372 KB) |
| MD5 |
d60059396546aec49858e7063b835baf |
| SHA256 |
0c81abdb3a6908c33548ad8d86f915e7a63b3c0e0cd69f4467b42baf22701c63 |
| 平台 |
bootloader@da1470x |
| 处理器架构 |
ARM Thumb |
| 函数数量 |
11 |
| 字符串数量 |
1,934 |
1.2 头部结构
00000000 51 71 bc ce 05 00 f9 63 86 49 31 2e 35 2e 35 00 Qq.....c.I1.5.5.
00000010 00 00 00 00 00 00 00 00 00 00 00 29 cf 61 00 04 ...........).a..
00000020 00 00 aa 22 00 00 01 00 00 00 aa 44 00 00 ff ff ...".......D....
| 偏移 |
内容 |
说明 |
| 0x0 |
51 71 |
Magic "Qq" |
| 0x2 |
bc ce 05 |
固件标识 |
| 0x7 |
63 86 |
校验数据 |
| 0x9 |
49 31 2e 35 2e 35 00 |
版本 "I1.5.5" |
| 0x14 |
00 29 |
产品标识 |
| 0x16 |
cf 61 |
CRC/校验值 |
2. 签名验证机制
2.1 验证函数
firmware_validate: path: %s, buf_len = %d
firmware_validate_rawfs_common: addr: %x, size %x, buf_len = %d
sign verify not pass
2.2 验证内容
| 检查项 |
错误信息 |
严重程度 |
| 文件大小 |
file size is small |
中 |
| Archive Magic |
archive magic not match %08x %08x |
高 |
| Archive PnP |
archive pnp not match expect %x %x, got %x %x |
高 |
| 读取缓冲 |
archive read buf malloc error |
低 |
| 硬件版本 |
hw_major_minor_ver expect %x, got %x |
高 |
| OTA 版本 |
board_hwinfo_has_ota_ver failed |
中 |
2.3 验证流程
firmware_validate()
├─ file size is small?
│ └─ 检查固件文件大小
│
├─ archive magic not match
│ └─ 检查 ZIP 头部魔数 (PK)
│
├─ archive pnp not match
│ └─ 检查 ZIP PnP 标识
│
├─ hw_major_minor_ver expect %x, got %x
│ └─ 检查硬件版本
│
├─ board_hwinfo_has_ota_ver failed
│ └─ 检查 OTA 版本信息
│
└─ sign verify not pass
└─ 签名验证失败
3. 启动流程
3.1 启动检查
boot check reason %d ← 启动原因检查
boot check key pass ! ← 启动密钥验证
reset boot magic ← 重置启动魔数
boot_goto_recovery ← 跳转 Recovery
boot_finish_recovery ← 完成 Recovery
3.2 启动原因码
| 原因 |
说明 |
| boot check key pass |
按键启动 |
| boot press detected |
检测到按键 |
| boot no power supply |
无电源 |
3.3 启动流程图
┌─────────────────────────────────────────────────────────┐
│ 启动流程 │
├─────────────────────────────────────────────────────────┤
│ │
│ 1. boot check reason %d │
│ └─ 检查启动原因 (按键/充电/定时) │
│ │
│ 2. boot check key pass ! │
│ └─ 验证启动密钥 │
│ │
│ 3. reset boot magic │
│ └─ 重置启动魔数 │
│ │
│ 4. sign verify │
│ └─ 签名验证 │
│ ├─ archive magic │
│ ├─ archive pnp │
│ ├─ hw_major_minor_ver │
│ └─ board_hwinfo_has_ota_ver │
│ │
│ 5. jump to app / boot_goto_recovery │
│ └─ 跳转到应用或 Recovery │
│ │
└─────────────────────────────────────────────────────────┘
4. 签名文件
4.1 文件路径
| 路径 |
用途 |
/mnt/backup/backup_fw_sign.zip |
备份固件签名 (ZIP) |
/mnt/data/recovery_ota_sign.bin |
Recovery OTA 签名 |
TA/extfw/recovery_sign.bin |
Recovery 扩展签名 |
4.2 ZIP 内容
bootloader_sign.bin 内嵌 ZIP 文件:
pictures/number_0.bmp
pictures/number_1.bmp
pictures/number_2.bmp
pictures/number_3.bmp
pictures/number_4.bmp
pictures/number_5.bmp
pictures/number_6.bmp
pictures/number_7.bmp
pictures/number_8.bmp
pictures/number_9.bmp
5. 加密组件
5.1 AES-CTR
| 函数 |
说明 |
oqspi_set_aes_ctr_key |
设置 AES-CTR 密钥 |
oqspi_set_aes_ctr_nonce |
设置 AES-CTR Nonce |
oqspi_set_aes_ctr_addr_range |
设置加密地址范围 |
5.2 哈希
| 函数 |
说明 |
aes_hash_event |
AES 哈希事件 |
ad_crypto_init |
加密初始化 |
6. Flash 操作
6.1 OQSPI 操作
| 函数 |
说明 |
oqspi_init |
OQSPI 初始化 |
oqspi_set_bus_mode |
设置总线模式 |
oqspi_set_access_mode |
设置访问模式 |
oqspi_set_clock_mode |
设置时钟模式 |
hw_oqspi_erase_block |
擦除块 |
ad_flash_write_from_oqspi |
从 OQSPI 写入 Flash |
6.2 分区操作
| 分区 |
路径 |
用途 |
| Boot |
/flash/boot |
启动分区 |
| Recovery |
/flash/recovery |
恢复分区 |
| Backup |
/mnt/backup |
备份分区 |
7. 与 firmware.bin 的关系
7.1 版本对比
| 组件 |
版本 |
大小 |
| bootloader_sign.bin |
I1.5.5 |
372 KB |
| firmware.bin |
g2.1.0.1 |
5.52 MB |
7.2 功能分工
| 功能 |
bootloader_sign.bin |
firmware.bin |
| 启动引导 |
负责 |
不负责 |
| 签名验证 |
负责 |
不负责 |
| Recovery 管理 |
负责 |
不负责 |
| 主要业务逻辑 |
不负责 |
负责 |
| UI 显示 |
不负责 |
负责 |
| BLE 通信 |
不负责 |
负责 |
8. 安全评估
8.1 安全机制
| 机制 |
强度 |
说明 |
| Archive Magic |
低 |
ZIP 头部检查 |
| Archive PnP |
低 |
ZIP PnP 检查 |
| 硬件版本匹配 |
中 |
防止刷错硬件 |
| OTA 版本检查 |
弱 |
仅检查版本信息 |
| AES-CTR |
中 |
Flash 加密 |
8.2 安全风险
- 无非对称签名: 无 RSA/ECDSA 签名验证
- ZIP 检查弱: Archive Magic/PnP 可伪造
- 版本检查弱: 无强制版本下限
- 密钥存储: AES 密钥安全依赖硬件
8.3 绕过难度
| 检查项 |
绕过难度 |
方法 |
| Archive Magic |
低 |
保持 ZIP 头部 |
| Archive PnP |
低 |
保持 PnP 标识 |
| 硬件版本 |
中 |
需匹配目标硬件 |
| OTA 版本 |
低 |
添加版本信息 |
9. 关键字符串地址索引
| 地址 |
字符串 |
| 0x36286 |
bootloader build info %s |
| 0x362ba |
boot check reason %d |
| 0x36346 |
reset boot magic |
| 0x3636f |
bootver |
| 0x363af |
/mnt/backup/backup_fw_sign.zip |
| 0x36545 |
bootloader@da1470x |
| 0x3707d |
TA/extfw/recovery_sign.bin |
| 0x37098 |
/mnt/data/recovery_ota_sign.bin |
| 0x370de |
boot check key pass ! |
| 0x371da |
boot_goto_recovery |
| 0x37e8e |
/flash/recovery |
| 0x3ca18 |
sign verify not pass |
| 0x3ca6a |
firmware_validate: path: %s |
| 0x3ca90 |
board_hwinfo_has_ota_ver failed |
| 0x3cab3 |
hw_major_minor_ver expect %x, got %x |
| 0x3caf4 |
archive magic not match %08x %08x |
| 0x3cb24 |
archive pnp not match |
| 0x3cb61 |
firmware_validate_rawfs_common |
| 0x3cbaa |
boot_finish_recovery |
| 0x417b5 |
oqspi_set_aes_ctr_key |
| 0x43df5 |
aes_hash_event |
10. 改进建议
10.1 签名机制
- 增加 RSA-2048/ECDSA-P256 非对称签名
- 使用 SHA-256 替代简单 Magic/PnP 检查
- 实现 Secure Boot 链式验证
10.2 版本控制
- 增加固件版本下限检查
- 实现 Anti-Rollback 保护
- 记录并验证升级历史
10.3 密钥管理
- 使用 HSM/TrustZone 存储密钥
- 实现密钥派生函数 (KDF)
- 增加密钥轮换机制
报告生成时间: 2026-04-24
分析工具: IDA Pro + opencode MCP
firmware.bin固件签名校验分析报告
1. 概述
本报告对 firmware.bin 进行固件签名校验机制的逆向分析。
1.1 二进制基本信息
| 属性 |
值 |
| 文件路径 |
C:\Users\meny\Desktop\2101\META\firmware.bin |
| 文件大小 |
0x586334 (5.52 MB) |
| MD5 |
d7969693c4c2afe87ee185e045006598 |
| SHA256 |
73abe4edcd67749c6dc78b738b569c42e8a1cee7fd0ef399eef2db666b2b478e |
| 处理器架构 |
ARM Thumb |
| 函数数量 |
180 |
| 字符串数量 |
28599 |
1.2 固件头部 Magic 验证
固件头部包含两层 Magic 标识:
| 类型 |
偏移 |
Magic 值 |
说明 |
| Product Header |
[0]=0x50, [1]=0x70 |
Pp |
产品头标识 |
| Active FW Image |
[0]=0x51, [1]=0x71 |
Qq |
活动固件标识 |
断言检查代码:
((uint8_t*) product_header_addr)[0] == 0x50
((uint8_t*) product_header_addr)[1] == 0x70
((uint8_t*) active_fw_image_addr)[0] == 0x51
((uint8_t*) active_fw_image_addr)[1] == 0x71
2. 签名校验机制详解
2.1 头部签名校验 (head_sign)
固件启动时对头部签名进行 16-bit CRC 校验:
head_sign[0x%04X]
EC=%04X] head_sign[0x%04x] isn't equal [0x%04x]
- 校验算法: CRC16
- 校验失败输出错误码 EC
- 字符串地址: 0x38d867, 0x38d909
2.2 CRC16 完整性校验
crc16 [0x%04X]
EC=%04X] crc16[0x%04x] isn't equal [0x%04x]
- CRC16 用于验证固件数据完整性
- 校验不匹配时触发错误断言
- 字符串地址: 0x38d8f8, 0x38d93a
2.3 产品头验证
Invalid product header
fw_address_boot > 0
fw_address_app > 0
- 产品头 Magic 校验失败触发断言
- 验证 Boot/App 地址有效性
- 字符串地址: 0x38d968, 0x38d984, 0x38d998
3. 启动选择与恢复机制
3.1 Boot 选择函数
| 函数 |
说明 |
| boot_select_load |
加载启动选择配置 |
| boot_select_store |
存储启动选择配置 |
| product_boot_select |
产品级启动选择 |
3.2 双区启动地址
fw_address_boot[0x%08x] fw_address_app[0x%08x] update_fw[0x%08x]
| 地址常量 |
用途 |
| HEADER_ADDR |
主头存储区 |
| BACKUP_ADDR |
备份头存储区 |
| fw_address_boot |
Boot 固件起始地址 |
| fw_address_app |
App 固件起始地址 |
| update_fw |
更新固件写入地址 |
3.3 Bootloader 升级流程
bootloader_upgrade start
get image file stat failed
image file not exist
boot part cannot open -> /flash/boot
boot part seek fail
boot part write fail, offset %x
- 升级目标: /flash/boot 分区
- 校验步骤: 文件存在 -> 文件大小 -> 读取 -> 写入
- 字符串地址: 0x38d744, 0x38d75f, 0x38d791
3.4 Recovery 跳转
jump to raw recovery, addr %x
/flash/recovery
- Recovery 分区路径: /flash/recovery
- 支持 raw recovery 跳转
- 字符串地址: 0x38d712, 0x39bf68
4. 密码学组件 (mbedTLS)
4.1 SHA256 哈希校验
mbedtls_sha256_context
mbedtls_sha256_starts_ret
mbedtls_sha256_update_ret
mbedtls_sha256_finish_ret
错误日志:
- malloc failed for mbedtls_sha256_context
- calculate sha256 failed cause mbedtls_sha256_starts_ret
- calculate sha256 failed cause mbedtls_sha256_update_ret
- calculate sha256 failed cause mbedtls_sha256_finish_ret
- calculate plaintext sha256 failed
4.2 SHA1 公钥哈希
mbedtls_sha1_context
mbedtls_sha1_starts_ret
mbedtls_sha1_update_ret
mbedtls_sha1_finish_ret
- 用于计算公钥哈希 (sha128)
- calculate public key hash sha128 failed
- 字符串地址: 0x3a1062, 0x3a1184
4.3 AES 加密/解密
mbedtls_aes_setkey_enc
mbedtls_aes_crypt_ecb
AES 用于绑定和授权密文验证:
-
binding AES ciphertext mismatch
-
authorize AES ciphertext mismatch
-
AES encrypt failed cause mbedtls_aes_setkey_enc
-
AES decrypt failed cause mbedtls_aes_crypt_ecb
-
加密模式: ECB
-
密钥管理: 通过 get_aes_key / save_aes_key 按 app_id 存取
-
字符串地址: 0x3a09ba, 0x3a0a81, 0x3a0c6d, 0x3a0c9b
5. 云端签名校验
5.1 云端绑定签名验证
verify cloud binding signature failed with code: 0x%02X
verify cloud binding signature OK
verify cloud auth signature OK
5.2 内置公钥
use built-in cloud signature public key
read public key from system failed
- 使用内置公钥验证云端签名
- 支持从系统读取公钥
- 公钥哈希使用 SHA128 计算
- 字符串地址: 0x3a0f60, 0x3a0fa4, 0x3a11f8, 0x3fc3a3
6. App 绑定与授权
6.1 绑定保护机制
- settings.connection.binding_protected
- cloud auth opened, local binding is forbidden
- battery charged full, skip protect binding
- battery charging and level is: %d, skip protect binding
6.2 授权流程
事件状态:
- event_auth_bind_start
- event_auth_bind_success
- event_auth_bind_disconnect
- event_auth_bind_unbind
- event_auth_bind_app_refused
授权结果:
- authorize ok for app id: %d
- authorize fail for app id: %d with code: %d
- bind ok for app id: %d
- unbind fail for app id: %d with code: %d
6.3 密钥存储
| 存储键 |
用途 |
| auth.keys |
应用授权密钥 |
| iui.keys |
UI 交互密钥 |
- 按 app_id 管理 AES 密钥
- get_random_key 生成随机密钥
- 字符串地址: 0x3a0921, 0x39ee5a
7. OTA 升级校验
7.1 UIHH 头部结构
UIHH (Unified Image Header Handler) 升级包头部:
IHH magic: %c%c%c%c, type: %d, version: %d, length: %d
invalid UIHH magic: %c%c%c%c
UIHH version: %d != OTA_UIHH_HEADER_VERSION: %d
sub header version != OTA_UIHH_SUB_HEADER_VERSION: %d
UIHH 头部字段:
| 字段 |
说明 |
| magic |
4字节魔数标识 |
| type |
升级包类型 |
| version |
头部版本号 |
| length |
数据长度 |
校验步骤:
- 验证 magic 标识
- 验证 UIHH 主版本号
- 验证 UIHH 子版本号
- 验证文件大小 > header size + sub header size
7.2 下载记录校验
saving download record for file type: %d, file size: %d, crc32: 0x%08X, received size: %d, received CRC32: 0x%08X
restore download record for file type: %d, file size: %d, CRC32: 0x%08X, received size: %d, received crc32: 0x%08X
下载记录包含:
| 字段 |
说明 |
| file type |
文件类型标识 |
| file size |
期望文件大小 |
| CRC32 |
期望 CRC32 校验值 |
| received size |
实际接收大小 |
| received CRC32 |
实际 CRC32 校验值 |
升级包记录:
- saving upgrade package record for firmware version: %s file size: %d
- saving upgrade package record failed cause no download record exist
- saving upgrade package record failed cause file size: %d mismatch
7.3 Flash ECC 校验
Ecc Check fail ecc1 %0x ecc2 %0x
upgrade Flash ecc OK
upgrade flash ecc check status failed
ecc check.
- 升级前进行 Flash ECC 纠错校验
- ECC 校验失败阻止升级
- 字符串地址: 0x39bbfb, 0x39bc2a, 0x39bc40
7.4 文件大小限制
OTA 升级包大小受 OTA_CFG_MAXIMUM_FILE_SIZE 限制:
- file size exceeds OTA_CFG_MAXIMUM_FILE_SIZE
- write failed cause offset + size exceeds limit
- read failed cause offset + size exceeds limit
- 超限读写操作被拒绝
8. 工厂与文件系统校验
8.1 工厂密钥校验
factory fs check running
factory fs check success
factory fs check fail
set factory_fs_check_key check fail
set factory_fs_check_key fail
8.2 文件哈希校验
## start check system resource filehash
/mnt/system/filehash
- 启动时校验系统资源文件哈希
- 哈希文件路径: /mnt/system/filehash
- 字符串地址: 0x39be72, 0x39bed6
9. 固件签名备份
| 路径 |
用途 |
| /mnt/backup/backup_fw_sign.zip |
主备份固件签名 |
| /mnt/system/extfw/backup_fw_sign.zip |
扩展固件签名 |
9.1 SHA256 文件校验
get sha256sum failed
get file sha256 done
get_file_sha256
- 使用 get_file_sha256 计算文件哈希
- 校验固件签名文件完整性
- 字符串地址: 0x3c28bc, 0x3fac5a, 0x3fac81
10. Flash 分区结构
10.1 分区操作函数
| 函数 |
说明 |
| orflash_init |
Flash 初始化 |
| orflash_read |
Flash 读取 |
| orflash_write |
Flash 写入 |
| orflash_erase |
Flash 擦除 |
| orflash_ioctrl |
Flash IO 控制 |
10.2 分区管理
| 函数 |
说明 |
| drv_flash_partition_init |
分区表初始化 |
| drv_partition_find |
查找分区 |
| drv_partition_read |
分区读取 |
| drv_partition_write |
分区写入 |
| drv_partition_erase |
分区擦除 |
| raw_partition_section_init |
原始分区段初始化 |
10.3 已知分区
| 分区路径 |
用途 |
| /flash/boot |
Boot 分区 |
| /flash/recovery |
Recovery 分区 |
| /mnt/backup |
备份分区 |
| /mnt/system |
系统分区 |
| /mnt/system/extfw |
扩展固件分区 |
分区验证:
- raw_partition_section_range_check 校验地址范围
- partition table destroyed 检测分区表完整性
11. 安全评估
11.1 安全机制汇总
| 机制 |
算法 |
强度 |
覆盖范围 |
| 头部签名 |
CRC16 |
低 (16-bit) |
固件头部 |
| 数据完整性 |
CRC16 |
低 |
固件数据 |
| 产品头验证 |
Magic + CRC16 |
低 |
启动阶段 |
| 云端签名 |
内置公钥 + SHA1 |
中 |
绑定/授权 |
| App 绑定 |
AES-ECB |
中 |
设备配对 |
| 文件哈希 |
SHA256 |
高 |
系统资源 |
| Flash ECC |
ECC |
中 |
升级写入 |
| OTA 头部 |
UIHH Magic + Version |
低 |
升级包 |
| 下载校验 |
CRC32 |
中 |
传输完整性 |
11.2 安全优点
- 多层校验机制: CRC16 + SHA256 + AES + ECC 组合验证
- 双区启动: HEADER_ADDR / BACKUP_ADDR 支持故障恢复
- 云端签名验证: 内置公钥验证绑定签名
- 文件哈希校验: 启动时校验系统资源完整性
- App 绑定保护: AES 加密验证设备配对
- Flash ECC: 写入时纠错校验
- 下载完整性: CRC32 校验传输数据
- 大小限制: OTA_CFG_MAXIMUM_FILE_SIZE 防止溢出
11.3 安全风险
- CRC16 强度不足: 16-bit 枚举空间小,易被碰撞攻击
- 缺少非对称签名: 固件更新未使用 RSA/ECDSA 签名验证
- AES-ECB 模式: ECB 模式存在明文模式泄露风险
- SHA1 公钥哈希: SHA1 已被证明存在碰撞风险
- 回滚保护缺失: 未发现版本回滚保护机制
- 密钥存储: AES 密钥通过系统属性存储,安全性依赖系统
- 工厂密钥: factory_fs_check_key 校验机制强度未知
- 固件版本: g2.1.0.1 可能存在已知漏洞
12. 改进建议
12.1 签名机制升级
- 将 head_sign 从 CRC16 升级为 HMAC-SHA256
- 增加 RSA-2048 或 ECDSA-P256 非对称签名验证
- 实现 Secure Boot 链式验证 (Boot -> App -> OTA)
12.2 加密算法升级
- AES-ECB 升级为 AES-GCM 或 AES-CTR
- SHA1 升级为 SHA256 用于公钥哈希
- CRC32 升级为 SHA256 用于下载完整性校验
12.3 安全加固
- 添加固件版本回滚保护 (anti-rollback)
- 实现密钥派生函数 (KDF) 保护 AES 密钥
- 增加安全启动 (Secure Boot) 验证链
- 密钥存储使用硬件安全模块 (HSM) 或 TrustZone
- 增加固件加密存储机制
附录 A: 关键字符串地址索引
| 地址 |
字符串 |
| 0x38d867 |
head_sign[0x%04X] |
| 0x38d909 |
head_sign isn't equal |
| 0x38d8f8 |
crc16 [0x%04X] |
| 0x38d93a |
crc16 isn't equal |
| 0x38d968 |
Invalid product header |
| 0x38d744 |
bootloader_upgrade start |
| 0x38d7a8 |
/flash/boot |
| 0x39bf68 |
/flash/recovery |
| 0x39d26b |
/mnt/backup/backup_fw_sign.zip |
| 0x3a29a3 |
/mnt/system/extfw/backup_fw_sign.zip |
| 0x39bed6 |
/mnt/system/filehash |
| 0x3a0e06 |
mbedtls_sha256_context |
| 0x3a09ba |
AES encrypt failed |
| 0x3a0c6d |
binding AES ciphertext mismatch |
| 0x3a0c9b |
authorize AES ciphertext mismatch |
| 0x3a0f60 |
verify cloud binding signature failed |
| 0x3a11f8 |
use built-in cloud signature public key |
| 0x3a2f63 |
IHH magic |
| 0x3a0921 |
auth.keys |
附录 B: 固件版本信息
| 信息 |
值 |
| 固件 Magic |
Qq4_X (0x51 0x71 0x34 0x5F 0x58) |
| 固件版本 |
g2.1.0.1 |
| 产品头 Magic |
Pp (0x50 0x70) |
| 活动固件 Magic |
Qq (0x51 0x71) |
| 密码学库 |
mbedTLS |
| UIHH 版本 |
OTA_UIHH_HEADER_VERSION |
报告生成时间: 2026-04-24
分析工具: IDA Pro + opencode MCP