Files
MAG160C/analysis/sdk_re/android_app/palette_extraction_findings.md
T

4.7 KiB
Raw Blame History

Phase C —— 厂商 12 调色板精确提取:结论与证据

日期:2026-09-10。目标:从官方 native 库 libcxsdk.so 提取 12 个调色板精确表。

结论(TL;DR

libcxsdk.so 里没有静态调色板表。12 个调色板全部由 CFunctions::SetColorPaletteGhidra 偏移 0x00026c70)在运行时用算术生成。 对全文件扫描"连续 256 个 u32LE、alpha=0xFF 且 RGB 非零"的候选 命中 0 个 alpha=0x00 形式、BGR/RGB 三元组形式同样为 0)。

因此本阶段改用移植生成函数的路线并成功恢复: UI 索引 0..10 共 11 个调色板已为官方精确表(索引 11 见下), 已写入 android/.../core/VendorPalettes.kt 并由 Palettes.kt 使用。

验证链(三重独立验证)

  1. 铁虹锚点:移植的 case 2 输出与 OfficialTables.PALETTE256_ARGB 256/256 逐字节一致。该表是从厂商运行时(CoreSDKLib dev+0xb18)抓取、 并与官方渲染器逐像素比对验证过的,因此它同时锁死了:
    • 算术配方(除法取整方式、循环边界、常量)
    • 发布字节序 = {byte0=B, byte1=G, byte2=R, byte3=0}
  2. 完整性:每个 case 对 256 个槽位各写入恰好一次(无空洞、无覆盖), 由模拟器的写地址跟踪断言。
  3. 厂商侧预览图:官方 APK res/mipmap-hdpi-v4/palette_<name>.png 是官方用 对应调色板渲染的真实热像帧。每个调色板对其自身预览图的颜色覆盖率都是 全体候选中最高,且差距显著:
官方调色板 UI 索引 生成 case 自身覆盖率 次优候选
白热 white_hot 0 0 100.0% 100.0%(灰度图,天然重合)
黑热 black_hot 1 1 100.0% 100.0%(同上)
铁虹 iron_bow 2 2 9.0% 0.1%
彩虹 rain_bow 3 3 7.3% 0.1%
琥珀 glow_bow 4 4 30.7% 2.3%
金秋 autumn 5 5 15.4% 2.5%
寒冬 winter 6 6 22.3% 2.9%
热金属 hot_metal 7 7 42.1% 11.0%
喷射 jet 8 8 14.0% 6.3%
红饱和 red_saturation 9 9 26.7% 22.1%
高对比度 high_contrast 10 10 4.0% 0.2%
红热 red_hot 11 未解决

(预览图是缩放过的照片,存在插值产生的额外颜色,故绝对覆盖率不高; 关键是自身恒为最高。)

未解决项:索引 11「红热」

  • native 库里另有 case 12、case 13 两个生成体,但两者对任何官方预览图的 覆盖率都很低(最高 3–6%,指向 jet),不能认定为「红热」。
  • 官方 APK 的 palette_red_hot.png占位图11914 个像素中 11777 个与 palette_white_hot.png 完全相同(平均绝对差 0.5/255),不携带调色板信息。
  • 处理方式:Palettes.kt 索引 11 保留原近似曲线,并注明 // approximated (not found in binary)VendorPalettes.SOURCE_CASE[11] = -1不猜测未验证的表。

可复现产物

路径 说明
analysis/sdk_re/android_app/bin/libcxsdk.so 官方 native 库入库(372476 B
analysis/sdk_re/android_app/palette_candidates.json 扫描结论(静态候选为空)+ 全部恢复表
analysis/sdk_re/android_app/palette_candidates.png 12 组「官方预览图 + 恢复色条」对照图
analysis/sdk_re/android_app/palette_match_report.txt 覆盖率证据表
analysis/tools/extract_palettes.py 计划要求的纯标准库扫描脚本(可复现"无静态表"这一否定结论)
analysis/tools/PalIdentify.java 13 个生成体的机械移植(含写地址校验)
analysis/tools/PalExport2.java 导出 Kotlin/JSON/PNG/报告
android/.../core/VendorPalettes.kt 生成的 Kotlin 表(0..10 为精确表)

重跑(本机无 python3,Java 版单文件即可运行):

java analysis/tools/PalExport2.java \
  android/app/src/main/kotlin/com/mag160c/thermal/core/OfficialTables.kt \
  <解包APK的 res/mipmap-hdpi-v4 目录> \
  android/app/src/main/kotlin/com/mag160c/thermal/core \
  analysis/sdk_re/android_app

有 python3 的机器上:

python3 analysis/tools/extract_palettes.py \
  analysis/sdk_re/android_app/bin/libcxsdk.so \
  android/app/src/main/kotlin/com/mag160c/thermal/core/OfficialTables.kt \
  analysis/sdk_re/android_app

与执行计划的对照

计划 C3 的回退条款为"若扫不到锚点:如实记录未在 libcxsdk 静态数据中找到调色板表, 保留现有一套近似实现,本阶段只交付脚本与 JSON"。实际执行结果优于回退: 锚点确实不在静态数据里(按回退如实记录),但通过移植运行时生成函数恢复了 11/12 个精确表,并把它们接入 Palettes.kt