汉王黄金屋3 (F6C) 破解 Writeup

6 天前(已编辑)
/ , ,
43
1

汉王黄金屋3 (F6C) 破解 Writeup

设备:汉王黄金屋3 电纸书 (F6C),君正 Ingenic MIPS SoC(板型 mensa),Android 2.2.1 (FRG83) eng 固件 目标:装第三方桌面、开 adb、解除5分钟锁屏限制,把机器变成可折腾状态
结果:达成。全程未拆机、未刷机、零变砖风险

Warning

我对「折腾『教程』」的态度同 乐视 CI 移植 Armbian 这篇文章: 好的教程应当提供思路、启发读者,而不是直接丢出一个现成的刷机包。因此你在这里得不到任何懒人包(AI 时代,找点没甲的随便一跑就出来了),但你能一定能找到灵感。

一、设备与固件概况

从 官方升级包 和实际设备 dump 交叉确认:

项值
平台Ingenic MIPS,产品代号 mensa,eng/test-keys 编译
分区mmcblk0p1=system(ext4,500MB 原始镜像直写) p2=cache p3=data p4=内部存储(vfat,MTP 可见)
系统应用hvLauncher60(桌面)、hvSettings(设置)、hvUsbConnectApp60、Term、Development、SpareParts 等
adb 设计态ro.secure=0、persist.service.adb.enable=1,开机 usb_gadget.sh 加载 android.ko 并重启 adbd,adbd 以 root 运行
recovery自制 recovery(非 AOSP 原版),inand_write_raw 按分区名直写镜像,adbd 同样开启

实测联机无法直接获得ADB权限。汉王桌面内设 系统升级 和 资源更新 两条可能实现破解的途径。系统更新会读 p4 内部存储根目录的 update.zip,资源更新会读 p4 内部存储根目录的hvResources.zip。


二、走不通的 update.zip 路线

TL; DR 没有私钥,任何改过的 update.zip 都会被 recovery 拒绝。此路永久关闭。

官方升级包是标准 SignApk 整包签名(签名块在 zip comment,recovery 的 verify_file 校验):

  1. 包内证书 META-INF/CERT.RSA 的 DN 伪装成 AOSP testkey(CN=Android, android@android.com),但 RSA 模数 FB6BD7A1… 与公网 testkey(D6931904…)不符,是厂商自生成密钥对。
Note

update.zip中的模数:

AOSP 公开证书文件 testkey.x509.pem:
得到 AOSP 公开证书文件的 RSA 模数:

  1. 解 recovery ramdisk,/res/keys 里只有一把 key,模数与该证书完全一致。V1.49(2015)与 2018 版包共用同一把私钥。

    Note

  2. 反汇编 recovery(MIPS32 静态链接,objdump + 自写脚本按指令编码定位字符串引用):安装流程中 verify_file 返回值直接门控,失败即 signature verification failed 中止,无旁路、无条件跳过。验签发生在任何写入之前,所以试刷坏包不会变砖。


三、完全不验签的 hvResources.zip 路线

TL; DR 关键突破,用官方资源更新机制自构造 payload、dump 出系统固件 build.prop、传入 apk。

逆向 hvSettings.apk(system uid 运行,sharedUserId="android.uid.system")发现:

系统设置里的"资源更新"按钮(btnUpdateResources)逻辑:

  1. 查找 /mnt/flash/hvResources.zip 或 /sdcard/hvResources.zip
  2. XZip.upZipFile() 解压到 /mnt/flash/hwsys/temp/(文件名还过一道 8859_1→GB2312 转码)
  3. 解析 temp/hvResources/HvResources.xml,按 <operation type="add|del|update"> 执行任意路径文件复制/删除——以 system 权限,无任何签名校验

这是汉王自己的资源(字体/词典)更新机制,等于一个官方后门。我们用它构造了三种 payload:

<resources>
  <operation type="add">
    <item><srcpath>/mnt/flash/hwsys/temp/hvResources/ADWLauncher.apk</srcpath>
          <dstpath>/data/app</dstpath></item>
  </operation>
</resources>
payload用途
安装包把 Holo/ADW/aLogcat 的 apk 复制进 /data/app,PMS 的目录监听自动完成安装
dump 包srcpath 填系统路径、dstpath 填 MTP 可见的 /mnt/flash/hwdump,把真实固件的 build.prop、hvSettings.apk、/data/system/dropbox 等全部拷出来——不需要 adb 就能任意读设备文件
回滚包type="del" 删掉 /data/app 里塞进去的 apk,随时恢复原状

四、装了两个桌面,两个全爆了

因为是 Android 2.2.3 的上古产物,必须找到支持 API = 8 的系统桌面。

一番搜索后,选择了 Holo Launcher 和 ADW Launcher。然后它们都不工作。

  1. 很抱歉!进程com.holoxxxxx意外终止。
    这个所谓 froyo 专版(3.1.2, minAPI8)实际引用了 Android 3.0 (API 11) 才有的 View.setLayerType(),在 2.2.1 上必抛 NoSuchMethodError。后用逐 API 引用扫描验证。换用 ADW Launcher 1.3.6(minSdk 5,零高版本引用)后复活。

  2. 很抱歉!android.proccess.acore意外终止 。
    这是一个复制安装的权限陷阱。资源更新通道用 FileOutputStream 落地,进程 umask 导致文件权限为 -rw------- system system。PMS(system uid)自己能读,所以安装、图标、HOME 选择器全部正常;但应用进程(uid 10xxx)读不到自己的 apk,PathClassLoader 加载 dex 失败:

    java.lang.ClassNotFoundException: ... in loader dalvik.system.PathClassLoader[/data/app/ADWLauncher.apk]

    (ADW 的 Application 声明跑在 android.process.acore,所以 FC 弹窗显示的是 acore,一度误导排查方向。崩溃堆栈由 DropBox 持久化在 /data/system/dropbox/,用 dump 包拷出来后真相大白)。 chmod 644 /data/app/*.apk 后复活。


五、你这 adb 保真吗

  • recovery 里 adbd 开启,但验签失败后几秒内自动重启,窗口极短。
  • 正常系统 adb 同样开启(root!),但进入汉王桌面几秒后 adb 消失,此时 Windows 只认到 MTP——推测是 MTP/存储守护进程启动后把 USB gadget 从 adb 模式抢走(属性并未被关,抓到窗口时 persist.service.adb.enable=1)。也可能与自动休眠有关。
  • 对策:PC 端看门狗脚本 race_adb.sh,死循环盯 adb devices,设备一出现立刻抢进去执行修复(chmod、写 persist 属性、拿 wake_lock、抓 ps/lsmod 诊断)。
  • 另一进 recovery 的方法:系统升级按钮的预检只检查 update.zip 存在性 + zip 内 version 文件的 HWV 记录与机型匹配(version 文件结构:1024 字节一条记录,HWV\x042.23 @1024、SYV\x04x.xx @2048),放入带真 version 文件的假包即可走到确认框并重启进 recovery。所有塞入应用,随时回到原厂状态。

六、锁屏的两层机制与彻底禁用

我计划让该设备做为时钟/台历类似物,因此必须停用恼人的5分钟自动锁屏。

设备的锁屏/休眠完全不走 Android 电源管理,所以 screen_off_timeout、svc power stayon、FLAG_KEEP_SCREEN_ON 全部无效。实际是三层:

第 1 层 —— poweroffserver(关机编排服务) init.rc 里的 root 服务,注册 binder android.os.IPowerOffService:负责关机前清场(遍历 /proc 杀占用进程、umount /data /cache /sdcard、sync、reboot)。stop poweroffserver 无副作用且adb 断连问题随之消失(此前 adb 只有开机几秒窗口,就是它把整机挂起导致 USB 断电)。

第 2 层 —— HvLockScreenService(自动锁屏调度) com/android/server/HvLockScreenService(services.odex,baksmali 可读),核心逻辑:

goToLockScreenAtDefaultTime():
    if SystemProperties.get("sys.eink.hvlockscreen.autolock", "1") == "1":
        t = 300000;  // 硬编码默认 5 分钟
        try { t = Settings.System.getInt("hanvon_lockscreen_timeout"); } catch {}
        设置 RTC_WAKEUP 闹钟 now + t → 到点弹锁屏界面
    else:
        取消闹钟

关键结论:

  • hanvon_lockscreen_timeout(Settings.System,毫秒)是官方锁屏时间配置项,每次调度都现读——改成 2147483647(约 68 年)即永久不锁;
  • autolock 属性只在调度入口被读一次,中途 setprop 0 无法取消已排程的闹钟(这就是中途设 0 无效的原因);
  • 取消当前闹钟可走 binder:service call hvlockscreen 3 i32 -1。

binder 接口 android.os.IHvLockScreenService(服务名 hvlockscreen)交易码:

code方法说明
1setHvLockScreentime(int)只写内存静态变量,不持久,基本无用
2goToLockScreenAtDefaultTime()按 autolock + 设置键重新调度
3goToLockScreenAtDefinedTime(int)传 -1 = 取消闹钟;50 = 用户手动锁(userlock 门控)

最终修复命令(adb 内执行):

adb shell sqlite3 /data/data/com.android.providers.settings/databases/settings.db \
  "insert into system (name,value) select 'hanvon_lockscreen_timeout','2147483647' where (select count(*) from system where name='hanvon_lockscreen_timeout')=0;"
adb shell sqlite3 /data/data/com.android.providers.settings/databases/settings.db \
  "update system set value='2147483647' where name='hanvon_lockscreen_timeout';"
adb shell service call hvlockscreen 3 i32 -1
adb shell stop poweroffserver   # 每次开机一次,或 remount 后改名固化

七:enjoy yourself !

44d5faad3fadbb983e92f96329432450_720

44d5faad3fadbb983e92f96329432450_720

使用社交账号登录

  • Loading...
  • Loading...
  • Loading...
  • Loading...
  • Loading...