ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

PlayIntegrityFix 快速指南:3 个场景下如何修复 Root 设备的 Play Integrity 验证

PlayIntegrityFix 快速指南:3 个场景下如何修复 Root 设备的 Play Integrity 验证

PlayIntegrityFix 快速指南:3 个场景下如何修复 Root 设备的 Play Integrity 验证

【免费下载链接】PlayIntegrityFixFix Play Integrity (and SafetyNet) verdicts.项目地址: https://gitcode.com/GitHub_Trending/pl/PlayIntegrityFix

PlayIntegrityFix 是一个让 Android 8–15 的 Root 设备恢复 Play Integrity(含旧版 SafetyNet)判定的模块化工具,面向需要让 Root 设备通过银行、支付、流媒体应用设备完整性验证的用户,同时支持 Magisk 与 KernelSU 两套环境。

为什么 Root 设备会被 Play Integrity 判为“不可信”

银行 App 弹出“设备未通过认证”、游戏拒绝启动,背后都是 Google 的 Play Integrity 返回给应用的判定结果。设备一旦 Root,会留下多处“硬证据”:

  • 解锁 bootloader,ro.boot.flash.locked为 0
  • SELinux 处于 permissive,ro.boot.selinux不再是 enforcing
  • ADB 在运行,init.svc.adbd处于 started
  • 部分自定义 ROM 使用测试签名(test-keys)

Google 在Android 13 起移除了旧版检查:README 明确指出,高版本上Device verdict已等同于旧版 Strong 级别,需要配合有效的 keybox 才能通过;而Android 12 及以下仍走旧版检查,相对容易。另外,旧模块 safetynet-fix 已停止维护且与本方案冲突,module/customize.sh 在安装时会直接将其移除。

一句话结论:Android 12 及以下装好即可用;13 及以上必须搭配 keybox。

模块运行时动了哪三层东西

它是一个 Zygisk 模块,C++ 入口在 app/src/main/cpp/main.cpp,且**只驻留在com.google.android.gms.unstable(Play Services 后台进程)**中,其他应用里模块库会被立即卸载,改动范围尽量收拢。三层改动如下:

层级位置改动内容
① 内存属性GMS 进程Hook__system_property_read_callback,改写*.security_patch、*.build.id、*api_level、init.svc.adbd等属性的读取返回值
② Build 字段 + KeyStoreGMS 进程用配置改写android.os.Build静态字段;CustomProvider顶替系统 AndroidKeyStore,拦截密钥查询
③ 开机属性post-fs-data / service 脚本通过resetprop_if_diff仅修正不一致项:ro.boot.selinux、ro.boot.flash.locked、verifiedbootstate、warranty_bit等

几个关键细节:

// main.cpp:读取属性时的拦截改写(节选) } else if (prop.ends_with(".security_patch")) { value = SECURITY_PATCH.c_str(); }
  1. 所有属性修改只发生在内存,重启后由脚本重新应用,不写系统文件。
  2. ③ 层是条件触发:当前值与期望不一致才改;三星warranty_bit、Realme、OnePlus 等厂商启动状态各自单独处理,避免弄坏指纹识别。
  3. 模块自动探测 TrickyStore:检测到/data/adb/modules/tricky_store存在时,自动关闭 ①② 两层的伪装,避免重复修改。
  4. 检测到测试签名 ROM(扫描otacerts.zip)时,自动启用spoofSignature,把系统签名替换为正式 key。

如何在 Magisk、KernelSU 与 Android 13+ 上安装

Magisk 一键安装(新手场景)

  1. 从 release 下载 zip(当前v19.1),在 Magisk 应用里“本地安装”。
  2. 必须已启用 Zygisk:customize.sh安装时会校验三件事——禁止 recovery 刷入、系统不低于 Android 8、Zygisk 已开启(Magisk 内置 Zygisk 或 ZygiskNext / ReZygisk 均可),不满足会直接 abort 并提示。
  3. 重启。默认配置来自 module/pif.json,Play Services 启动时自动加载。

KernelSU / APatch 装法(带 Web 界面)

KSU 环境下模块自带 webroot 页面,在模块详情页可以看到版本号、Apply按钮和一个指纹来源开关:

  • 点Apply会执行 module/action.sh:抓取最新的Pixel Beta构建信息,从 OTA 元数据中提取指纹与安全补丁级别,写入/data/adb/pif.json,并重启 GMS 进程让配置生效;
  • 开关用于切换指纹来源为beta / preview(修改脚本里的FORCE_PREVIEW),切换后再点 Apply 重新抓取即可。

Android 13+ 如何通过 Device verdict

Android 13 及以上仅靠属性伪装无法通过 Device 判定,需要安装TrickyStore并导入有效 keybox;模块检测到 TrickyStore 后会自动让路。另一条不稳定路线是用 PlayIntegrityFork 变体并开启spoofVendingSdk强制走旧版检查——但Play Store 会偶发崩溃,不建议作为主方案。README 中也给出直白建议:经验不足又必须认证设备的用户,装官方 ROM 并锁 boot 更稳妥。

多设备批量部署

管理多台 Root 设备时,用 adb 统一推送自定义指纹:

for d in $(adb devices | grep -w device | awk '{print $1}'); do adb -s $d push pif.json /data/local/tmp/pif.json adb -s $d shell "su -c 'cp /data/local/tmp/pif.json /data/adb/pif.json'" done

/data/adb/pif.json是优先级最高的配置文件,GMS 进程下次启动即生效。

如何用 pif.json 定制设备指纹

配置文件是 JSON,默认内容(以 Pixel 6 为伪装目标):

{ "FINGERPRINT": "google/oriole_beta/oriole:16/BP22.250325.012/13467521:user/release-keys", "MANUFACTURER": "Google", "MODEL": "Pixel 6", "SECURITY_PATCH": "2025-04-05" }

模块按/data/adb/pif.json→custom.pif.json→pif.json的顺序读取,找到即用。常用配置项:

配置项类型作用
FINGERPRINTstring需为brand/product/device:release/id/incremental/type/tags八段格式,会自动拆分成 8 个 Build 字段
SECURITY_PATCHstring安全补丁日期,如2025-04-05
MANUFACTURER/MODEL/BRAND等string任何同名的android.os.Build字段都可覆盖
DEVICE_INITIAL_SDK_INTstring 或数字读取*api_level属性时返回的 API 级别
spoofProvider/spoofPropsbool分别开关 KeyStore 伪装与属性 Hook
spoofSignaturebool开关系统签名伪装(测试签名 ROM 上自动开启)
DEBUGbool输出详细日志,排障时打开

两条实操建议:

  1. 不要手写指纹——action.sh自动抓取的 Pixel Beta 构建保证可用,失败时会打印download failed并退出;KSU 网页里点 Apply 即可重试。
  2. 更新模块不会丢配置——customize.sh会先把你的自定义/data/adb/pif.json备份为.old;若指纹格式错误,日志里会出现Error parsing fingerprint values!。

三种常见验证失败的定位方法

日志入口:模块 C++ 与 Java 两侧统一使用标签PIF:

adb logcat -s PIF

看到hook __system_property_read_callback successful at ...说明 Hook 成功;Set 'XXX' to '...'表示字段已改写。

现象可能原因处理动作
❌ 安装即 abort,提示 Zygisk is not enabledZygisk 未开启在 Magisk 设置中开启,或安装 ZygiskNext / ReZygisk
❌ Android 13+ 仍过不了 Device缺有效 keybox安装 TrickyStore 并导入 keybox,重启
⚠️ 网页 Apply 报 Unable to connect设备访问不了 Google 域名检查网络后重新点击 Apply
⚠️ 判定异常、指纹被覆盖playcurl 模块冲突卸载 playcurl(安装时已有警告)
⚠️ 装过 MagiskHidePropsConf可能干扰属性伪装卸载或移除该模块
✅ 改完配置判定没变化GMS 进程未重启adb shell "su -c 'killall com.google.android.gms.unstable'"后重新测试

再确认一下模块目录与自定义配置是否就位:

adb shell "su -c 'ls /data/adb/modules/playintegrityfix; cat /data/adb/pif.json 2>/dev/null'"

如何保持模块持续有效:更新与兼容

  • 更新机制:module.prop指向 update.json,应用内检测更新即可看到当前版本v19.1与安装包地址;changelog.md 记录每次变更,多数版本只是“Update fingerprint”级别的刷新。
  • DenyList 自动维护:post-fs-data.sh在 Magisk DenyList 常规模式下把 GMS 移出列表;装了 Shamiko 且未开启白名单特性时,则把 GMS、GMS unstable 与 Play Store 加入列表,保证注入链正常。
  • 自定义 ROM 兼容:脚本对 AOSPA 的 PropImitationHooks、受支持 ROM 的 PixelPropsUtils、LeafOS 的 gmscompat 都有专门处理,避免互相覆盖。
  • 卸载:uninstall.sh会清理其触及的 LeafOS 相关属性,移除模块后重启即可。
  • 社区:官方 Telegram 频道入口写在 changelog.md 顶部,关注它获取更新通知。

现在动手:克隆仓库并在设备上验证

设计思路一句话概括:只改 Play Services 看到的东西,其余系统一概不动。先安装模块,再用adb logcat -s PIF确认 Hook 成功,需要最新指纹时点一次 Apply。

git clone https://gitcode.com/GitHub_Trending/pl/PlayIntegrityFix

【免费下载链接】PlayIntegrityFixFix Play Integrity (and SafetyNet) verdicts.项目地址: https://gitcode.com/GitHub_Trending/pl/PlayIntegrityFix

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进