汉王黄金屋3 (F6C) 破解 Writeup
设备:汉王黄金屋3 电纸书 (F6C),君正 Ingenic MIPS SoC(板型 mensa),Android 2.2.1 (FRG83) eng 固件 目标:装第三方桌面、开 adb、解除5分钟锁屏限制,把机器变成可折腾状态
结果:达成。全程未拆机、未刷机、零变砖风险
我对「折腾『教程』」的态度同 乐视 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 校验):
- 包内证书
META-INF/CERT.RSA的 DN 伪装成 AOSP testkey(CN=Android, android@android.com),但 RSA 模数FB6BD7A1…与公网 testkey(D6931904…)不符,是厂商自生成密钥对。
update.zip中的模数:

testkey.x509.pem:


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

反汇编 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)逻辑:
- 查找
/mnt/flash/hvResources.zip或/sdcard/hvResources.zip XZip.upZipFile()解压到/mnt/flash/hwsys/temp/(文件名还过一道 8859_1→GB2312 转码)- 解析
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。然后它们都不工作。
很抱歉!进程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,零高版本引用)后复活。很抱歉!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 | 方法 | 说明 |
|---|---|---|
| 1 | setHvLockScreentime(int) | 只写内存静态变量,不持久,基本无用 |
| 2 | goToLockScreenAtDefaultTime() | 按 autolock + 设置键重新调度 |
| 3 | goToLockScreenAtDefinedTime(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