21 KiB
qianbian Android APK 逆向分析报告(client-qbsg_v1.1.0.apk)
分析方法:androguard 4.1.4 静态分析(DEX 字符串表 + xref + DAD 反编译目标类);native 库 strings/导出符号粗扫。 对照基线:analysis/web/protocol-raw.md(下称"Web 报告")。 分析产物:analysis/apk/{classes.txt, classes-qbsg.txt, strings-clean.txt, xrefs-key-strings.txt, decomp/*.java, native/libapp.so, native/libeditor.so}
0. APK 基本信息
| 项 | 值 | 证据 |
|---|---|---|
| 包名 | io.github.bszapp.dzjq42 |
AndroidManifest |
| 版本 | v1.1.0-20260612-a2c9488 (versionCode 4) | AndroidManifest |
| minSdk / targetSdk | 24 / 37 | AndroidManifest |
| 主 Activity | qbsg.top.MainActivity |
AndroidManifest |
| 权限 | BLUETOOTH/ADMIN/SCAN/CONNECT、ACCESS_FINE_LOCATION、INTERNET、REQUEST_INSTALL_PACKAGES | AndroidManifest |
| native 库 | arm64-v8a: libapp.so (1.5MB)、libeditor.so (3.8MB)、libandroidx.graphics.path.so | APK lib/ |
| 技术栈 | Kotlin Compose Multiplatform;共享逻辑经 R8 混淆(La0/*、Lz7/* 等);qbsg.top.* 为保留名的 Android 平台层;libapp.so/libeditor.so 为 Rust 编译(含 sha2 0.10.9、aes 0.8.4、rust-secp256k1 0.11 crate 路径字符串) |
classes.txt、libapp.so strings |
应用结构要点:
qbsg.top.ble.BleManager/BleSession:Android GATT 平台层(未混淆)。e8.o(抽象 EpdManager)两个实现:c8.g(固件家族名"平平/扫地",j()返回)与d8.f("轻舞/时光")——APK 显式支持至少两个固件家族,协议细节有差异(见 §3/§4)。z7.b0:独立 SUOTA 管理器(扫描→连接→SPOTA 全流程,20.6 万字符反编译代码)。a8.g:经已有会话的 OTA 通道(GattOtaChannel)。qbsg.top.ble.Simulated*:整套模拟设备框架("NRF-模拟设备"演示模式,SimulatedBleKt.buildSimulatedProfiles 引用 "NRF-")。qbsg.top.template.editor.LibEditor:JNI 桥到 libeditor.so(Rust 模板编辑器,导出 create/renderPng/exportBitmap/createElement 等)。
a. GATT UUID 对照
证据:qbsg.top.ble.BleManagerKt.<clinit>(decomp/qbsg_top_ble_BleManagerKt.java:11-21)。
| UUID | 用途 | 与 Web 一致? |
|---|---|---|
13187b10-eba9-a3ba-044e-83d3217d9a38 |
EPD_SERVICE_UUID | ✅ 一致 |
4b646063-6264-f3a7-8941-e65356ea82fe |
EPD_CHAR_UUID | ✅ 一致 |
00001f10-0000-1000-8000-00805f9b34fb |
TX_SERVICE_UUID(RXTX) | ✅ 一致 |
00001f1f-0000-1000-8000-00805f9b34fb |
TX_CHAR_UUID | ✅ 一致 |
00002902-... |
CCCD | Web 未显式用(Web BLE 隐式) |
00002A24-... / 00002A26-... |
MODEL_NUMBER / FIRMWARE_REVISION(DIS) | Web 端没有(APK 连接后读型号+固件版本,BleManager$startDeviceInfoRead$1.java:47-56) |
Web 端没有、APK 新增的 UUID(全部用于 OTA,详见 §e):
| UUID | 角色 |
|---|---|
0000fef5-0000-1000-8000-00805f9b34fb |
Dialog SPOTA 服务(z7_b0.java:666 等) |
64b4e8b5-0de5-401b-a21d-acc8db3b913a |
SPOTA_SERV_STATUS(z7_b0.java:768) |
8082caa8-41a6-4021-91c6-56f9b954cc34 |
SPOTA_MEM_DEV(z7_b0.java:679) |
724249f0-5ec3-4b5f-8804-42345af08651 |
SPOTA_GPIO_MAP(z7_b0.java:677) |
457871e8-d516-4ca1-9116-57d0b17b9cb2 |
本固件的 SPOTA_PATCH_DATA(z7_b0.java:665/1029 错误文案"SPOTA_PATCH_DATA未找到"对应此 UUID;注意这是 Dialog 标准里的 PATCH_LEN UUID,厂商做了自定义映射) |
9d84b9a3-000c-49d8-9183-855b673fda31 |
本固件的 SPOTA_PATCH_LEN(z7_b0.java:670/1023;非标准 UUID) |
42c3dfdd-77be-4d9c-8454-8f875267fb3b |
SPOTA_MEM_INFO(兼容探测,z7_b0.java:772、a8_g.java:255) |
61c8849c-f639-4765-946e-5c3419bebb2a / b7de1eea-823d-43bb-a3af-c4903dfce23c |
OTA 兼容探测用备选特征(z7_b0.java:769-770、a8_g.java 头部) |
0000221f-...(Web 声明未用) |
APK strings 中未出现 |
258EAFA5-E914-47DA-95CA-C5AB0DC85B11 |
仅字符串表存在,无代码 xref |
设备名过滤:代码扫描不过滤(startScan(0, ...) 无 ScanFilter,BleManager.java:761),UI 层按 name.startsWith("NRF-") 过滤(a9_b0.java:102;SUOTA 扫描同,a9_v2.java:190)。与 Web namePrefix:'NRF-' 一致。
连接参数:连接后 requestMtu(512)(BleManager$startDeviceInfoRead$1.java:80),onMtuChanged 更新会话 negotiatedMtu(默认 23);BleSession.getMaxPayloadBytes() = max(20, mtu-3)(BleSession.java:162-170)。connectGatt 用 TRANSPORT_LE(2)、autoConnect=false(BleManager.java:619)。
b. 命令集对照
APK 命令发送模型与 Web 不同:命令列表执行器 e8.j——把 ["e10201","TIME","e2"] 这类列表逐条经 RXTX sendCommand 发出,"TIME" 占位符运行时替换为 e8.o.m() 构造的 dd… 时间命令(e8_j.java:111-114)。sendCommand 按 MTU-3 分块、互斥锁串行、10s 超时(BleSession.java:187-258)。
| 命令 | APK 证据 | 与 Web 一致? |
|---|---|---|
dd{unix:4B}{year:2B}{mo}{d}{week} 设置时间 |
e8.o.m()(e8_o.java:57-73):unix 秒+时区偏移、4B/2B/1B/1B/1B 大端 hex |
✅ 完全一致(Web ble.js:251-257) |
e2 提交 |
所有命令列表收尾(c8_g.java:63 等) | ✅ |
| 模式切换 e100/e101/e102 系列 | 动态构造:行 0/1/2 → 前缀 e102/e101/e100(c8_g.java:39-54、s() in d8_f.java:135-150);e1020{n+1} 时钟、e1010{n+3} 日历、e10000 图片(c8_g.java:137-146) |
✅ 覆盖 Web 的 e10000-03/e10103-05/e10201-03 |
停车牌 ef+号码 |
c8.g.d():逐字符双写("12"→ef1122,c8_g.java:72-91);d8.f.d():逐字符转 hex 拼接(Integer.toString(char,16),d8_f.java:168-189)——两固件家族格式不同!均校验 11 位数字 |
⚠️ Web 只有双写式;d8/f 的 hex 拼接式 Web 没有 |
倒计时文字位图 04/0{n}/990{j} |
f8.a.c()(f8_a.java:70-162):gridSize 16 → ≤4 字 0{n} 单包、5-8 字 04+前段 / 0{n}+128B 后段;gridSize 24 → 每字 990{j}+72B;位图 MSB-first |
✅ 与 Web timedjs2 一致 |
倒计时日期 ff00/ffff+%04d%02d%02d |
f8.a.b()(f8_a.java:58-68):gridSize≠24→ff00,24→ffff,年为 4 位十进制 ASCII |
✅ 一致 |
FA 关倒计时 |
字符串表存在(fa),命令列表中未直接出现(UI 文案有"关闭") |
≈ |
| 全刷/其他设置(e3/e4/e5/e6/14/15/2300/2301/FB/e901/EA0x) | DEX 字符串与 xref 中均无(xref 验证:'2300'/'2301'/'fb01'/'e901'/'EA00'/'EFEF' → 0 引用) | ❌ APK 不实现(三色/黑白切换、12/24h、颜色、反色、字体、旋转、LUT 校准 E6、休眠时段 FB、轮播 e901/EA000、模板槽位 EA0x 均为 Web 独有) |
EFEF 请求设备 ID |
无(xref=0)。APK 不读设备 14B ID,改用 DIS 2A24/2A26 + MAC 识别设备 | ❌ Web 独有 |
WiFi 配置 WIFI_SSID:... |
无(strings 无 WIFI_SSID,UI 无 WiFi 入口) | ❌ Web 独有 |
激活 EF{code} 发设备 |
无(APK 激活是 App 本地的,见 §d) | ❌ 机制完全不同 |
$IMG(0,0)(hex 24494d4728302c3029) |
c8/f 图片上传末尾经 RXTX 发送(c8_f.java:186) | ❌ APK 独有,Web 无此命令 |
上传开始 8000/8001、0000、020000,结束 0101 |
见 §c | ❌ 帧格式与 Web 不同(见差异节) |
c. 图像传输与像素处理
发送流程(EPD 通道,BleSession.sendEpdBytes,带写完成回调、互斥锁、5s 超时)
c8.f("平平/扫地"固件,c8_f.java:137-200):
- EPD
{80,00}(8000) - EPD
{00,00}(0000) - EPD
{02,00,00}(020000) - 数据帧循环:
[0x03, plane, offHi, offLo, ≤240B],plane:BW 平面0xFF、红平面0x00,offset 大端(c8_f.java:246-270) - EPD
{01,01}(0101) - RXTX
$IMG(0,0)→ RXTXe2
d8.e("轻舞/时光"固件,d8_e.java:92-170):
- EPD
8001→0000→020000 - 同样的 0x03 数据帧(240B/块,ff=BW、00=红)
- EPD
0101→ delay(300ms) → RXTXe2(普通)或aa(isCalendar 预设为真时,d8_e.java:150-167,g8.c.f=isCalendar)
与 Web 对照:分块 240B、平面码 ff/00、offset 大端 ✅ 一致;帧头恒为 0x03,APK 没有 Web 的 0x04 小图帧;首尾帧不同(Web:00{cmd} 开头 / 01 或 AA 结尾;APK:80xx+0000+020000 开头 / 0101 结尾 + RXTX e2/aa)。三色 = 两个平面依次发送 ✅。
像素打包(与 Web 完全同源)
a.b.h()(a_b.java:866-914):行主序 MSB-first 8px/B;BW 平面R>0&&G>0&&B>0→1,红平面R>0&&G==0&&B==0→1—— = Web canvas2bytes。a.b.i()(a_b.java:916-963):列主序 x 从 W-1→0 —— = Web canvas2bytes_bw(296/250/212 宽屏用)。d8.f.o()(d8_f.java:39-96):d8/f 家族自带打包:宽 212/250/296 走列主序否则行主序;BW 平面判定为R>0→1(d8_f.java:119-133,不含 G/B 检查;对抖动后的纯色调色板等价,但红像素在 BW 平面也会置 1,与 a.b.h 不同)。- 红色判定
g8.f.e():r > g*1.5 && r > b*1.5 && r > threshold(g8_f.java:45-53,float 1.5)—— = Web timedjs.js:255。 - 灰度
g8.f.d():0.299/0.587/0.114(g8_f.java:40-43)。 - Bayer 4x4 矩阵 15,135,45,165],[195,75,225,105],[60,180,30,150],[240,120,210,90(g8_f.java:5-8)—— 与 Web 逐值一致。
抖动算法
g8.a 枚举:NONE / FLOYD_STEINBERG / ATKINSON(默认,g8.a.d) / BAYER / STUCKI / JARVIS(g8_a.java:10-16)——与 Web 同 6 种;默认 Atkinson 与 Web 默认 bwr_atkinson 对应。配置 g8.d(ImageConfig):亮度/对比度/饱和度/diffusion/threshold(默认128)/旋转角度/scaleMode/isThreeColor(g8_d.java:229-250)。
预设 g8.c = FirmwareImageUploadPreset(screenSize, uploadWidthPx, uploadHeightPx, useRotatedScan, singleChannel, isCalendar)——上传参数由固件型号预设驱动,默认 400x300(g8_d.java:102-130)。
倒计时文字位图渲染 f8.a.a():Android Canvas 绘制(DEFAULT_BOLD、fakeBold、抗锯齿、居中),按阈值二值化(f8_a.java:10-56)。
d. 激活流程 ★(Web 端没有的关键信息)
APK 的激活完全是 App 本地校验,算法在 libapp.so(Rust)里。
JNI 接口 qbsg.top.activation.ActivationManager(decomp/qbsg_top_activation_ActivationManager.java):
static { System.loadLibrary("app"); }
public final native boolean nativeActivate(String code);
public final native boolean nativeChecksumOk(String code);
public final native String nativeDecryptSegment(String hex);
public final native String nativeGetDeviceId();
public final native void nativeInit(Object ctx);
libapp.so 导出符号(readelf .dynstr):
Java_qbsg_top_activation_ActivationManager_native{Init,GetDeviceId,ChecksumOk,Activate,DecryptSegment}Java_io_github_bszapp_dzjq42_utils_SignatureUtils_getNativeSignature(签名防伪校验)- 字符串证据:引用
android/provider/Settings$Secure、android_id、getContentResolver()(设备 ID 源自 ANDROID_ID);rust-secp256k1(pubkey != NULL、SECP256K1_FLAGS_BIT_COMPRESSION)、sha2-0.10.9、aes-0.8.4 crate;运行时错误串[not activated]、[decrypt error: too short]。
调用链(MainActivity.onCreate,qbsg_top_MainActivity.java:19-35):
nativeInit(context)→nativeGetDeviceId()写入 StateFlow(UI 展示设备 ID)。- 读 SharedPreferences
activation_code;非空且nativeChecksumOk(code)为真 →nativeActivate(code)→ 置"已激活"全局标志(w7.a.h.b.c)。 y7.a.a(code, fromQr)(y7_a.java:21-61):手动/扫码激活入口,成功则持久化activation_code;失败提示"激活码无效或不属于本设备"。- 扫码激活
y7.a.b(bytes)(y7_a.java:63-110):QR 原始字节 ≥71、前 4 字节 ASCII"qbsg",取最后 67 字节作为激活码字符串 →nativeActivate。→ 激活码为 67 字符。 s0.u0case 13(s0_u0.java:82-99):nativeDecryptSegment仅在"已激活且处于特定模式"时可用——用于解密 §e 的两段密文 UUID。
密码学形态推断(基于 crate 组合,未做指令级逆):secp256k1(很可能 ECDSA/Schnorr 公钥验证,私钥在签发方)+ SHA-256 + AES(DecryptSegment 用)。"不属于本设备"说明激活码与 nativeGetDeviceId()(ANDROID_ID 派生)绑定。这取代了 Web 的服务端 key_generator.php 模式:Web 发 EF+激活码给设备固件校验;APK 在 App 侧本地校验,不给设备发任何激活命令。
另有服务端激活 API(面向"换固件"付费场景,与本地码并行):
POST https://qbsg.top/api/activation/activate,JSON{token, provider_id, firmware_id, mac: "mac1,mac2,…"}(a8_f.java:529-545,k8.h.c= okhttp POST application/json,k8_f.java)。POST https://qbsg.top/api/activation/check,body 为设备 ID 字符串(a9_c2.java:62/80/98)。POST https://qbsg.top/api/activation/firmware-list(b9_g0.java:127)。- 文案佐证:"Switching firmware requires paid activation."、"以下 %s 台设备未找到激活码"、"BatchActivationFirmwareOption(id=…"、"Batch firmware upgrades and sequential commands"(批量固件升级+顺序命令)。
e. 固件 OTA / SUOTA ★(Web 端完全没有)
APK 有完整 OTA 体系,两条路径同一协议核心:
路径 1:独立 SUOTA 管理器 z7.b0(扫描 NRF- 设备→专连升级,支持批量/并发 Semaphore)
流程(z7_b0.java:655-1720,超时:连接 30s、写 8s、状态等待 60s):
- 连接 + 服务发现,必须存在服务
0000fef5(否则"设备不支持SUOTA服务")。 - 兼容探测 SERV_STATUS
64b4e8b5;另探测42c3dfdd/b7de1eea/61c8849c备选特征。 requestMtu(23)(默认;若已协商更高则用 min(20, mtu-3) 作写块),requestHighPriority()。- SERV_STATUS 开 notify(CCCD 写
{01,00},z7.k0.a)。 - 写 MEM_DEV
8082caa8←g(318767104)= 4B 小端{00,00,00,13}(mem type 0x13=SPI Flash;z7.b0.c()恒返回该值,z7_b0.java:426-430)。 - 写 GPIO_MAP
724249f0←g(84280064)={00,00,06,05}(对应 UploadConfig 默认 misoGpio=5, mosiGpio=6, csGpio=3, sckGpio=0, i2cAddress=0x50,z7_o0.java toString)。 - 镜像封装
z7.h0(z7_h0.java:7-34):固件字节末尾追加 1 字节全镜像 XOR 校验;块长 b = max(240, chunk)(默认 240B),写块长 c = MTU-3(默认 20B)。 - 每块:写 PATCH_LEN
9d84b9a3←f(blockLen)(2B 小端)→ 分 20B 无响应写 PATCH_DATA457871e8→ 等 SERV_STATUS notify == 2,否则报"块N失败: …"。 - 全部块后写 MEM_DEV ←
g(-33554432)={00,00,00,FE}(END_SIGNAL)→ 等最终 SERV_STATUS==2(设备侧 XOR/CRC 校验,失败报"CRC校验失败")。 - 写 MEM_DEV ←
g(-50331648)={00,00,00,FD}(重启设备)。
SERV_STATUS 错误码表(z7_k0.java:8-28,中文文案):2=操作成功 3=强制退出SPOTA 4=Patch Data CRC失败 5=长度与PATCH_LEN不符 6=外部存储写失败 7=内部存储不足 8=无效存储器类型 9=应用层错误 17=无效镜像Bank 18=无效镜像头部 19=无效镜像大小 20=无效产品头部 21=相同镜像错误 22=外部存储读失败 65535=通信错误 65534=设备不支持SUOTA。
路径 2:会话内 OTA a8.g.f(byte[] firmware, String, GattOtaChannel)(a8_g.java:94-…)
同一协议核心(fef5 服务探测、MTU 默认 23→20B 块、z7.h0 240B 块封装、PATCH_LEN/PATCH_DATA、SERV_STATUS 轮询),经 BleManager$AndroidGattOtaChannel 在已连接会话上执行。
固件来源与目录
POST https://qbsg.top/api/firmware/catalog→ 固件目录(b9_g0.java:118);POST /api/activation/firmware-list→ 已购固件列表(b9_g0.java:127)。- 目录项字段:firmwareId / firmwareFileName / firmwareCrc / firmwareTotalBytes / downloadUrl(strings-clean.txt:2247-2253、21021-21023;b1_m 同构解析逻辑)。
- 下载
k8.h.b(url,…)流式写本地缓存(a8_f.java:396-435),.img后缀(strings:3035)。OTA 用固件从 qbsg.top 服务器下载,与 Web 端 4638e813e4.qicp.vip:8889/GuJian/file_down.php 不同源。 - OTA 前还有 FirmwareImageUploadPreset 驱动的"升级画面"图片上传(g8.c)。
激活门控的加密 UUID
z7.b0 构造时(z7_b0.java:50-51)调 s0.u0(13) → ActivationManager.nativeDecryptSegment 解密两段 128-hex 密文:
a232499efa74dd64…d01d→this.e3fd29fea11187d48…7791→this.f
字段初始为全零 UUID(00000000-0000-0000-8000-000000000000),未激活时解密返回空串(s0_u0.java:89-97 的门控逻辑)。两段明文应为 UUID(类静态块编译了 UUID 正则)。这是反盗版设计:部分 OTA 能力(大概率是某自定义服务/特征 UUID 或厂商私有权鉴)只对已激活 App 可用。
App 自更新(与设备固件无关)
POST https://qbsg.top/api/check-update,body {machine: <设备ID>, version: 4, platform: "android"} → {isLatest, latestVersionCode, latestVersionName, downloadUrl, updates:[{versionName,changelog}]}(b1_m.java:215-245);下载 APK 后借 FileProvider + REQUEST_INSTALL_PACKAGES 安装("下载完成,点击安装")。
f. 网络依赖清单(本地化去云清单)
DEX 中全部 URL(strings-clean.txt 提取,无 mspppclock.tech、无 4638e813e4.qicp.vip——Web 端两个服务器在 APK 均不存在):
| 端点 | 用途 | 证据 |
|---|---|---|
https://qbsg.top/api/activation/activate |
固件激活(付费换固件) | a8_f.java:541 |
https://qbsg.top/api/activation/check |
激活状态查询 | a9_c2.java |
https://qbsg.top/api/activation/firmware-list |
已购固件列表 | b9_g0.java:127 |
https://qbsg.top/api/firmware/catalog |
固件目录 | b9_g0.java:118 |
https://qbsg.top/api/check-update |
App 自更新 | b1_m.java:217 |
https://qbsg.top/api/fonts |
云端字体 | strings |
https://qbsg.top/api/pictures(+/thumbnail?name=)、https://qbsg.top/Pictures/ |
云图库 | strings |
https://qbsg.top/api/templates/community/{list,download,downloaded,like,unlike}、/api/templates/{submit,my-list,preview,delete,tags,tmp-upload?token=} |
模板社区 | strings |
https://qbsg.top/api/user/{info,logout}、https://qbsg.top/#/loginonly、/#/me?logintoken= |
账号体系(AccountManager、网页登录 token) | strings、AccountScreen$submitToken |
| 营销外链 | QQ 群 280372025、拼多多店铺 mall_id=214155601、闲鱼 userid=355198804 | strings |
HTTP 栈:okhttp3,k8.h(POST JSON k8.h.c、下载 k8.h.b)。Web 端协议报告的激活站 key_generator.php 与固件站 file_down.php 在 APK 中均无迹。
g. 与 Web 端差异汇总
| # | 差异 | 说明 |
|---|---|---|
| 1 | 激活机制根本不同 | Web:设备 ID(EFEF 14B)→qicp.vip key_generator.php→EF{码} 发设备;APK:App 本地 libapp.so(Rust, secp256k1+SHA-256+AES) 校验 67 字符码(QR: "qbsg"+67B),绑定 ANDROID_ID,不发任何激活命令给设备 |
| 2 | OTA 仅 APK 有 | 完整 Dialog SPOTA/SUOTA(fef5 服务、240B 块+20B 写块、XOR 尾字节、FE/FD 收尾),固件来自 qbsg.top;Web 无任何 OTA |
| 3 | 图像首尾帧不同 | Web:00{cmd} 起、01/AA(EPD) 止;APK:8000/8001+0000+020000 起、0101(EPD)+e2/aa(RXTX) 止,c8/g 家族还发 ASCII $IMG(0,0);APK 恒用 0x03 帧头(无 Web 的 0x04 小图帧) |
| 4 | Web 独有的设备功能 | WiFi 配置、EFEF 设备 ID、2300/2301、14/15、e3/e4/e5、E6 LUT、FB 休眠、e901/EA000 轮播、EA0x 槽位——APK 全部未实现(APK 定位是"图片/模板/倒计时上传 + 固件升级"工具) |
| 5 | APK 独有的协议细节 | 连接后 requestMtu(512);读 DIS 2A24/2A26 型号与固件版本;双固件家族(平平/扫地 vs 轻舞/时光)打包与停车牌格式分叉;aa 按 isCalendar 预设走 RXTX;SUOTA PATCH_LEN/DATA 使用非标准 UUID 映射(9d84b9a3 / 457871e8) |
| 6 | 服务器完全不同 | Web:4638e813e4.qicp.vip:8889(激活+固件);APK:qbsg.top 全家桶 API(激活/固件/字体/图库/模板社区/账号/自更新) |
| 7 | 一致项 | EPD/RXTX UUID、NRF- 前缀、240B 分块、ff/00 平面码、dd 时间帧、e2 收尾、e100/e101/e102 模式族、倒计时 04/0n/990/ff00/ffff 帧、6 种抖动(Bayer 矩阵逐值一致)、红色判定 r>1.5g&&r>1.5b、灰度系数 |
附:关键文件位置
- 反编译源码:analysis/apk/decomp/(BleManagerKt=UUID 常量、BleSession=发送层、e8_o/e8_j=命令执行器、c8_g/d8_f=模式管理器、c8_f/d8_e=图像上传、g8_f/a_b=像素与抖动、f8_a=倒计时、z7_b0/z7_h0/z7_k0=SUOTA、a8_g/a8_f=OTA 与会话、b9_g0=固件目录、b1_m=自更新、y7_a=激活入口、s0_u0=解密门控)
- native 库:analysis/apk/native/libapp.so(激活算法,Rust)、libeditor.so(模板编辑器)
- 字符串表:analysis/apk/strings-clean.txt(28367 条);关键字符串 xref:analysis/apk/xrefs-key-strings.txt