stevessr / PICO 4 Ultra 国际版组件替换实录:商店、用户中心与 Matrix 更新 API

Created Wed, 28 Oct 2026 08:00:00 +0800 Modified Wed, 28 Oct 2026 00:02:32 +0000

这次折腾的目标很简单:在 PICO 4 Ultra 上替换国际版商店、用户中心和 Matrix。前两个组件顺利安装,Matrix 却同时遇到了禁止降级和受保护应用限制。最终通过官方应用更新 API 找到了版本码更高、保留 PICO 原签名的国际版 Matrix,直接覆盖成功。

本文记录的是 2026 年 10 月 28 日的实际操作。版本和分发策略可能变化,执行前请重新检查自己的设备。

先说结果与适用范围

实测设备是 PICO 4 Ultra,ADB 型号 A9210,代号 sparrow,系统 5.15.8。国际版组件来源包括一份 5.15.7 国际版 OTA 和官方应用更新接口。

组件 包名 安装结果
商店 com.picovr.store 从 4.12.5 更新版退回后,覆盖为提取的 4.9.0
用户中心 com.picovr.vrusercenter 同为 5.10.0,签名一致,覆盖成功
Matrix com.bytedance.pico.matrix 国际版 6.3.4,版本码 600304021,覆盖成功

这里的“替换”是把 APK 安装到 /data/app,作为系统应用更新覆盖运行,没有刷写系统分区、解锁 Bootloader 或获取 Root。内置 APK 仍然存在。

商店和用户中心可以启动,用户中心进入登录页;Matrix 安装后进程正常运行。账号登录、购买、下载及组件间联动尚未完成端到端验证。单独替换组件也不能保证整机变成完整国际版系统。

普通 PICO 4 与 PICO 4 Ultra 的固件不可混用。操作账号组件可能需要重新登录;降级即使保留数据,也存在数据格式不兼容风险。先备份,后操作。

1. 准备工具与连接设备

电脑需要 Android Platform Tools 的 adb、Android SDK Build Tools 的 aapt 和 apksigner。若从 OTA 提取组件,还需要支持 Android OTA 的 payload 提取工具,以及 EROFS 工具包中的 dump.erofs。

在头显内打开 USB 调试,用数据线连接并确认授权:

adb devices -l
adb shell getprop ro.product.model
adb shell getprop ro.product.name
adb shell getprop ro.build.display.id

如果连接了多个 Android 设备,后续命令必须加 adb -s <设备序列号>,避免操作错设备。

查看当前组件版本:

for pkg in com.picovr.store com.picovr.vrusercenter com.bytedance.pico.matrix; do
  echo "=== $pkg ==="
  adb shell pm path "$pkg"
  adb shell dumpsys package "$pkg" | grep -E 'codePath=|versionCode=|versionName='
done

一个系统应用可能同时显示 /data/app 中的更新版与 /system 中的内置版。要确认实际生效的 APK,使用 pm path。

2. 先备份当前 APK

以下命令适用于本次这些只有单个 APK 的组件。若 pm path 返回多个 split APK,需要逐个备份,不要只取第一行。

mkdir -p backup extracted downloads
for pkg in com.picovr.store com.picovr.vrusercenter com.bytedance.pico.matrix; do
  path=$(adb shell pm path "$pkg" | head -n 1 | tr -d '\r' | cut -d: -f2-)
  test -n "$path" || exit 1
  adb pull "$path" "backup/$pkg.apk" || exit 1
  adb shell dumpsys package "$pkg" > "backup/$pkg-package.txt"
done

这只是 APK 与包状态备份,不是应用私有数据备份。不要把包含设备信息的诊断文件直接上传到公开仓库。

3. 从国际版 OTA 提取组件

本次使用的文件:

5.15.7-202608080609-RELEASE-user-sparrow-b9111-b2059d5f17.zip

可从 PICO 官方系统页面 和社区固件索引 核对型号与版本。索引页是线索,下载后仍需检查包本身;不要把“公开列表最新”当成服务器绝对没有其他版本。

OTA ZIP 内主要是 payload.bin,不能直接 unzip 出 APK。先查看并提取 system 分区。下面是本次所用 payload-dumper 的语法,其他工具的参数可能不同:

payload-dumper --list firmware.zip
payload-dumper firmware.zip -p system -o extracted

确认分区提取成功后,定位组件:

dump.erofs --ls --path=/system/priv-app extracted/system.img
dump.erofs --ls --path=/system/app extracted/system.img

本次文件路径如下:

dump.erofs --cat --path=/system/priv-app/store2d/store2d.apk \
  extracted/system.img > extracted/Store-global.apk

dump.erofs --cat --path=/system/priv-app/VRUserCenter2/VRUserCenter2.apk \
  extracted/system.img > extracted/UserCenter-global.apk

dump.erofs --cat --path=/system/app/Matrix/Matrix.apk \
  extracted/system.img > extracted/Matrix-global.apk

提取器报错时不要直接使用残缺镜像。 本次遇到 operation data hash mismatch:检查 manifest 后发现,操作数据偏移在跨过 4 GiB 时出现回绕,原工具按回绕后的偏移读取了错误位置。针对这份包修正偏移后,剩余操作数据的哈希校验通过,最终提取的 APK 也通过签名验证。这是针对该文件的处理,不能把“所有偏移加 4 GiB”当成通用修复,更不能跳过校验继续安装。

4. 安装前检查版本和签名

aapt dump badging extracted/Store-global.apk | head -n 3
apksigner verify --print-certs extracted/Store-global.apk
apksigner verify --print-certs backup/com.picovr.store.apk

对用户中心与 Matrix 重复相同检查。覆盖安装要求包名和签名兼容,版本显示名称相同也不够,Android 主要比较 versionCode。

本次验证的 PICO 签名证书 SHA-256 指纹为:

dc30289e0a61447d03c95d15e5acf63e18d109d545a766b1208f6b53cbdcd482

这是公开证书指纹,不是签名私钥。应与自己设备上的原 APK 对照,不能仅凭应用名称判断来源。

5. 商店与用户中心的替换

先尝试保留数据覆盖:

adb install -r extracted/Store-global.apk
adb install -r extracted/UserCenter-global.apk

本次用户中心同版本覆盖成功;商店原更新版为 4.12.5,提取版为 4.9.0,触发:

INSTALL_FAILED_VERSION_DOWNGRADE

adb install -r -d 并不能强制所有正式版应用降级,设备帮助也明确说明 -d 针对可调试应用。

确认已经备份、接受重新登录与降级数据风险后,本次对商店单独执行:

adb shell pm uninstall -k com.picovr.store
adb install -r extracted/Store-global.apk

在这台设备上,第一步成功移除了系统商店更新、退回内置版;随后国际版 APK 覆盖成功。-k 请求保留数据,但不保证旧版本能读取新版本的数据。不要把这一步扩展为批量卸载系统组件。

可分别启动检查:

adb shell am start -W -n com.picovr.store/.MainActivity
adb shell am start -W -n com.picovr.vrusercenter/.MainActivity

遇到验证码频率限制,应停止重复请求,稍后通过官方登录流程重试。替换 APK 本身不会解决账号地区或验证码限制。

6. Matrix 为什么不能照搬商店的办法

本次版本码是:

来源 versionName versionCode
头显当前更新版 6.3.4 600304020
5.15.7 国际版 OTA 内置版 6.3.4 600304016

提取版更旧,覆盖时被拒绝。尝试卸载更新又遇到:

DELETE_FAILED_INTERNAL_ERROR
Attempted to delete protected package: com.bytedance.pico.matrix

pm uninstall-system-updates com.bytedance.pico.matrix 同样失败;正式版系统也拒绝 adb root。此时继续反复加 -d 没有意义,应该寻找 官方签名、版本码不低于当前版本的国际版 APK。

还找到过一个社区 Matrix_GL.apk:版本码被改为 999999999,证书却是第三方签名。它不能直接作为官方系统应用更新安装。相关模块只声明支持 Root 后的普通 PICO 4 OS 5.13.7,不能套到这台 Ultra 上,因此没有安装。

7. 从官方 API 查到新版 Matrix

只搜索 APK 文件名没有找到合适的新版,于是检查了官方组件的实现:

  • SystemUpdate2.apk:整机 OTA 更新。
  • VersionManager.apk(com.pvr.version):系统应用更新。

可从自己的设备或对应国际版 OTA 提取 APK,用 JADX 本地查看:

jadx --no-res -d updater-src SystemUpdate2.apk
jadx --no-res -d version-src VersionManager.apk

客户端实现中的关键位置是 OtaService、AbstractOtaRequest、VersionApi、VersionRepo、RequestFactory。不同版本可能有混淆或路径变化。

整机固件查询

POST https://iot-global-api.picovr.com/open/v3/ota/check

请求包含设备型号、产品名、序列号、系统版本、构建时间、构建类型、地区及应用基线等字段,并使用 X-Signature 签名。本次 HTTP 200,业务返回:

{"code":0,"errmsg":"未匹配到合适的策略"}

这只能说明本次请求未匹配到分发策略;设备条件、地区、灰度与请求参数都可能影响结果,不能据此断言没有新固件。

系统应用查询:旧接口与新接口不同

旧接口:

POST https://appupdate-global-api.picovr.com/api/upgrade/v1/check

本次返回空列表。继续按客户端实现调用新版单应用接口:

POST https://appupdate-global-api.picovr.com/api/upgrade/v1/check/single

查询参数有 _timestamp、_nonce,请求头包括 Content-Type: application/json、Locale、X-Signature。请求结构示意:

{
  "head": {
    "uuid": "自己的设备标识",
    "os_version": "客户端对应系统版本",
    "rom_version": "客户端对应完整构建版本",
    "build_type": "user",
    "model": "客户端读取的型号字段",
    "product_name": "客户端读取的产品字段",
    "android_version": "34",
    "category": "vr",
    "vendor": "pico",
    "app_id": "pico_self_update",
    "did": "客户端设备ID",
    "country_code": "HK",
    "device_bc_flag": 0,
    "self_pkg_name": "com.pvr.version"
  },
  "body": {
    "business_id": 74,
    "need_upgrade_apps": [{"pkg_name": "com.bytedance.pico.matrix"}]
  }
}

这是字段说明,不是填上就能直接 curl 的免签接口。字段应依据客户端实际读取逻辑生成:例如 ro.pxr.usebuildinfo 会影响型号和产品名的来源,不能把显示名称一律填到每个字段里。上面的地区也不代表所有设备都应使用 HK。

本次客户端的签名流程是:对查询参数排序、对原始 JSON 请求体计算 MD5,再按 RequestFactory 的格式拼接方法、参数与正文摘要,使用 HMAC-SHA256 后 Base64 编码,组成 X-Signature。JSON 序列化后必须用同一份字节签名和发送。本文不公开客户端签名密钥、设备序列号或账号令牌,也不提供绕过服务端鉴权的方法。

新版接口实际返回的关键字段:

{
  "code": 0,
  "msg": "success",
  "data": {
    "apps": [{
      "pkg_name": "com.bytedance.pico.matrix",
      "version_name": "6.3.4",
      "version_code": 600304021,
      "file_size": 92457772,
      "file_md5": "23abe9130f2647d15862e44f33049fac",
      "task_id": 4021
    }]
  }
}

apps 中还会提供 file_url 与备用下载地址。应重新查询并使用当次返回地址,避免把历史 CDN 链接当成永久下载入口。HTTP 200 之后,还要检查业务 code、目标包名与版本码。

8. 下载、验证、覆盖新版 Matrix

从上一步响应的 file_url 下载,保存为 Matrix-oversea-6.3.4-600304021.apk。本次检查:

md5sum downloads/Matrix-oversea-6.3.4-600304021.apk
aapt dump badging downloads/Matrix-oversea-6.3.4-600304021.apk \
  | grep -E '^package:|^application-label:'
apksigner verify --print-certs downloads/Matrix-oversea-6.3.4-600304021.apk

结果:

  • 文件大小:92457772 字节。
  • MD5:23abe9130f2647d15862e44f33049fac,与 API 一致。
  • 应用名:pui_matrix_oversea。
  • 包名:com.bytedance.pico.matrix。
  • 版本码:600304021。
  • 签名证书:与原机 PICO 证书一致,APK 签名校验通过。

MD5 用于和分发元数据核对;官方来源判断还要结合 HTTPS 来源及 APK 签名,不能单靠 MD5。

确认后直接覆盖,不再卸载:

adb install -r downloads/Matrix-oversea-6.3.4-600304021.apk

本次返回 Success,未主动清除数据。检查安装状态和实际 APK:

adb shell dumpsys package com.bytedance.pico.matrix \
  | grep -E 'codePath=|versionCode=|versionName='

path=$(adb shell pm path com.bytedance.pico.matrix | head -n 1 \
  | tr -d '\r' | cut -d: -f2-)
adb shell md5sum "$path"
adb shell pidof com.bytedance.pico.matrix

最终生效路径位于 /data/app,版本码为 600304021,MD5 与下载文件一致,Matrix 进程存在。至此可以确认安装与进程状态;账号、商店与应用授权行为仍需在头显内逐项测试。

回退与排错

  • 签名不一致:停止安装,不要为了提高版本码重签系统 APK。
  • 版本降级:寻找官方更高版本;受保护应用不要反复尝试卸载。
  • 功能异常:先记录日志和当前版本,不要立即清空所有账号组件数据。
  • 需要回退:原 APK 已备份,但高版本覆盖后,低版本备份仍可能被降级规则拦截;备份不等于保证能一键恢复。不要为回退贸然恢复出厂或刷机。
  • APK 下载已完成:优先复用本地文件,重新核对哈希即可,无需重复下载整包固件。

这次真正解决问题的不是“强行绕过”,而是区分整机 OTA 与应用更新两条分发链路,并从正确的新接口找到版本码更高、签名匹配的国际版组件。