2021 年 10 月 24 日,Android 玩机圈内无人不知的玩机工具 Magisk 突然有了新动态:其开发者 John Wu 更新了一条 推文,宣布推出全新的 Magisk 金丝雀(canary)版本。它虽然并非正式版,但给玩机圈带来的喜悦却胜过以往任何一个版本。

这种喜悦近似于久旱逢甘霖。

时间回到 21 年 5 月,Magisk 开发者 John Wu 通过社交平台透露自己即将加入 Google,负责 Android 平台的安全工作。John Wu 有在 Apple 的实习经历,对 Android 安全领域也颇为熟悉,Google 择才而用、Wu 求仁得仁,这本来是值得庆祝的事。但在他公布自己获得新工作的 推文 下,除了寥寥的几则祝福,大多数关注者都在询问另外一个问题 —— Magisk 将何去何从?

Twitter @topjohnwu

Magisk 可以获取设备的 root 权限,凭借其独特的模块挂载方式,在 Xposed 等老牌玩机工具陷入泥潭之际 Magisk 反倒跟随 Android 系统渡过了好几个大版本更新,以其广泛的设备兼容性和强大的模块生态逐渐成为每一个 Android 玩家的必备工具。

因此开发者 John Wu 在 Magisk 上做的工作一直以来也如同攻向 Android 和 Google 服务的一把长矛,在 Google 的新职位,却又赋予了他 Android 平台安全持盾人的全新身份。「以子之矛陷子之盾」的戏话会在现实发生吗?作为 Google 人,Wu 有访问大部分公司代码的权限,Google 会允许 John Wu 继续开发 Magisk 吗?

State of Magisk: 2021

正如很多人所预料的那样,Magisk 最初的情况并不乐观。

对于网友的问题,Wu 先是回复称自己的 Magisk 开发不会受影响,不久却删除了这一条回复。9to5Google 5 月 17 日以「Google 把 Magisk 开发者 John Wu 招进了 Android 安全团队」为题的报道也以给出了这样的推测:

这对 Magisk 的未来意味着什么……按之前的推文,Wu 也许能继续 Magisk 的工作,但这和他的新职位有明显的冲突。

而对 Magisk 而言,不管外界如何评论,今年 5 月后其 GitHub 项目的确迎来了一段时间的沉寂,John Wu 本人的提交热力图也难得有了数月的空白。在主项目停滞的情况下,John Wu 本人在此问题上的三缄其口也让用户对 Magisk 的未来普遍持悲观态度。

GitHub @topjohnwu

当然,我们后来才知道,不公开表态的 John Wu 在适应新工作的这几个月时间里,同时也正在推动 Google 对 Magisk 看法的改观,以求能够继续主持 Magisk 的开发:

大多数大型科技公司的职员,如果不经过某些审查,根本不被允许创建自己的开源项目亦或做贡献。

定音之锤在 8 月底落下,John Wu 获得了在 Magisk 项目上继续工作的许可。他结合自己的开发计划,于 8 月 29 日发布文章 State of Magisk: 2021,指出了 Magisk 项目未来的走向。

文章感谢了用户们一直以来的关心及开发者们的对项目的帮助,其中关涉 Magisk 的要点提炼如下:

  • John Wu 将继续维护 Magisk,开发重点放在 Magisk 更核心的功能上
  • Magisk 获取系统 root 权限、安装模块的能力和安装方式将不会改变
  • Magisk 将不再集成官方的模块库,现存的 GitHub 的模块库拟交给社区维护
  • 新推出 Zygisk,为模块提供更强大的 API;同时提供排除列表,让被排除的应用不受模块影响
  • MagiskHide 相关代码被移除,但用户仍可以通过一些方法通过 SafetyNet 测试。

这份来自开发者的文章驱散了人们心头的疑云,也带来一些新的问题:Zygisk 是什么?MagiskHide 被删除有什么影响?这些问题亟需由一个供用户实际上手的版本来解答。

文章开头提到的全新金丝雀版本正是这份答案。

GitHub @topjohnwu

和在线模块仓库说再见

和以前一样,Magisk Canary 已经面向喜欢尝鲜的用户开放下载。已经装有 Magisk 的用户,可以前往 Magisk 应用的「⚙️设置 > 更新通道 > 自定义通道」中填写 这个地址,再检查应用更新,亦或直接下载 APK(链接见文末)覆盖安装,即可到升级最新金丝雀版本。

从零开始也不困难,Magisk Canary 和以往的 Magisk 安装流程一致:检查设备、安装工具 > 下载并安装 app-debug.apk下载地址),检查 Ramdisk 值 > 提取系统镜像 > 修改并打包镜像 > fastboot 刷入。具体流程可以参考少数派之前的文章。

关联阅读:Android 玩家必备神器入门:从零开始安装 Magisk

按照流程安装 Magisk Canary 后,可以发现设备已经可以授权 root、安装模块了,目前的版本为 23014。

App 主界面的 UI 沿袭了旧版本的设计,但老用户很快就会发现 Canary 版第一屏上的「测试 SafetyNet 证明」按钮和设置界面中的 MagiskHide 开关消失了,取而代之的是陌生的 Zygisk 选项。另外正如公告所说,第四屏中以往会出现的在线模块列表没有了。

用 Magisk 开发者的话来说,移除对官方模块库的集成实际上对开发者和用户都有好处。

原先集成的在线模块列表托管在 GitHub Magisk Modules Repo 上,由 John Wu 抽空清理和维护列表的模块。Wu 曾经集中移除一批字体修改模块,NotoCJK 就是那个时候被移出官方库的,这么做的理由是此时已经有修改系统字体的更强大的模块,这些模块显得多余。不过 Wu 的做法也引起了一些开发者的不满。

另一方面,官方库的模块整体质量低得令人发指。在柯帕的 模块推荐文章 中,他整理了官方库总共一百零几个模块,列为一个 表格,其中半数以上的模块年久失修,完全不可用,还有许多模块功能重复或者系统适配差。因此在这篇 2021 年写就的模块推荐文章中作者仅推荐了 20 多个模块,并非因为篇幅所限,而是官方库中还能正常工作的模块只有这么多。

各种原因综合下来,John Wu 分身乏术,自然希望由社区接管模块库的维护工作。Magisk 选择暂时不展示这份低质量的模块列表。他有允许用户维护自定义模块列表的长期规划,等到那时,Magisk App 的在线模块列表对每个用户而言才更有价值。

所以在这个版本中,所有模块就只能通过下载 Zip 包、再本地安装的形式进行了。不少社区一直在维护的 模块库 将来可能会变成寻找模块的更好去处。

Zygisk:Android 的「遗传信息」编辑工具

Zygote 在生物学上意为「受精卵」,于人而言,受精卵是生命的第一阶段,存储了发育所需的所有遗传信息。 Android 将一个特殊的进程命名为 Zygote,它于系统而言亦有类似的意义。

Android 开发文档 如此描述 Zygote:

每个应用进程都从一个名为 Zygote 的现有进程分叉。系统启动并加载通用框架代码和资源时,Zygote 进程随之启动。为启动新的应用进程,系统会分叉 Zygote 进程,然后在新进程中加载并运行应用代码。

Android 完整启动顺序 | Miso Ivanisevic

Zygote 是 Android 所有其他应用进程的父进程,如果将代码注入此进程中,类似于编辑了受精卵中的遗传信息,更改将对所有应用生效。从原理上来说,Zygisk 的得名非常直白 —— 注入 Zygote 的 Magisk。

Zygisk 的开启方式很简单,在 Magisk Canary 中,通过设置 > Zygisk 即可启用。对于模块开发者而言,Zygisk 提供了更加方便易用的 接口和文档;但对于一般用户而言,由于 Zygisk 与 riru 模块(这篇文章 有介绍)无法兼容,部分受影响的模块还需要等开发者进行适配。

当下,LSPosed 已经完成对 Zygisk 的适配,用户在开启 Zygisk 后可以通过刷入 LSPosed Zygisk 版本的方式来进行使用。当我们尝试在开启了 Zygist 的 Magisk 使用 Riru 相关模块时,会显示「由于 Zygisk 已被启用,此模块不再生效」字样。启用 Zygisk 则必须停用 Riru 系列模块(见下方第三张图),Zygisk 和 Riru 必须二选一的情况预计在新的稳定版本推出时仍然不会改变。

另外,当在设置中开启 Zygisk 时,会多出「排除列表」的选项。排除列表的作用是使模块不对列表中的应用生效。举例来说,某模块通过 Zygisk 相关的 API 修改了字体,若将应用 A 添加进排除列表,那么应用 A 内的字体是不会发生变化的,因为它被排除在模块起作用的进程之外。

虽然效果和 MagiskHide 有些类似,但排除列表并不会起到任何隐藏的作用,这也是 John Wu 反复强调的。

SafetyNet 墙高,MagiskHide 退场

在 State of Magisk: 2021 发布之后又有了另一种谣言:失去了它最重要的功能 —— MagiskHide 后,Magisk 已经名存实亡。一些 Canary 版用户一厢情愿地把排除列表当作 MagiskHide 也正反映了用户们对 MagiskHide 的留念。

然而玩机经验丰富的人应该知道,如果把 MagiskHide 当作 Magisk 最重要的功能的话,那么 Magisk 的病危通知书在 2020 年初就下达了。

MagiskHide 确实有着不可或缺的地位,它被设计用于隐藏 root,同时帮助设备通过 SafetyNet 验证。

SafetyNet 全称为 SafetyNet Attestation API ,是 Google 内置于 GMS 中的用于认证设备完整性状态的接口。使用 SafetyNet 的应用向 Google 服务应用发送请求,SafetyNet Attestation 此时会评估硬件设备的运行环境,然后向远程的 SafetyNet 服务器请求签名的评估结果证明 —— 代表基本完整性的 basicIntegrity 和代表处于已知的良好环境的ctsProfileMatch

一般来说,只有设备通过 SafetyNet 验证,金融、通信和游戏应用才能够正确运行

验证完整过程 | Google 开发文档

Android 玩机用户所熟悉的解锁 Bootloader、获取 root 权限,自然会导致设备无法通过这项证明,于是便有了 MagiskHide。它为 SafetyNet 验证创造隔离环境,伪造设备仍然完整的假象——这同样也是许多玩家敢于在自己的主力手机上安装 Magisk 的原因。

一直到 2020 年 5 月,一些用户的 MagiskHide 功能突然失效:昨天依然可以通过 SafetyNet 证明的设备、今天 Google 商店就无法搜到某些应用;昨天还能正常运行游戏,今天就再也打不开《宝可梦 Go》了;部分设备则在短暂「宕机」后恢复正常……种种迹象表明,某个更高级别的安全验证措施就要来了。

2021 年 2 月,Google 正式揭开了这个新技术的面纱 —— Hardware Key Attestation,基于硬件密钥的 SafetyNet 验证方法。这项技术将在受支持的设备上逐步推行,采用这项技术的设备安装 Magisk 后只能通过基本的 Basic 验证,无法通过更为严苛的 CTS 验证,它几乎也在第一时间宣判了 MagiskHide 的死刑。

中招表现 | thecustomdroid

Hardware Key Attestation 使用根植在设备硬件的密钥来与 Google SafetyNet 服务器进行匹配。具体到接口,SafetyNet API 中增加了一个新的返回项目 evaluationType,若此项目为 BASIC,则表明设备仍然是传统的验证方法,若为 HARDWARE_BACKED,则表明设备已经采用基于硬件的新验证方法

对黑客们而言,Google 服务器自然不可能被修改,破解设备硬件密钥也因此变得极为困难。而对 MagiskHide 来说,它仍然可以伪造设备镜像依然完整的假象,但在新的验证机制下已无法隐藏设备已解锁 Bootloader 的事实。

第三方 ROM & Bootloader 解锁设备无法通过 cts 认证 | Google 开发者文档

一些民间的开发者请求不要广泛推行此措施,因为这种技术也是对自定义 ROM 社区的毁灭性打击。不能通过 SafetyNet,意味着不能使用一些关键的银行、影视和游戏应用,极大限制了自定义 ROM 的生存空间。但目前来看,已经有越来越多的设备部署了这一安全技术。MagiskHide 更无法再凭一己之力「瞒天过海」了。

因此当 Magisk Canary 移除了 MagiskHide 相关代码时,也有人对此毫不惊讶,这可以说是一场酝酿许久的退场。一方面,来自雇主 Google 的压力让 John Wu 不可能「自相矛盾」;另一方面,以往的 MagiskHide 已经没有能力应对 SafetyNet,在此领域投入更多的开发精力并不明智,也不是 Wu 希望做的。

以退为进:通过 SafetyNet 的新方案

MagiskHide 开关和代码被移除已成既定事实,用户无法再借助 Magisk 来欺骗 SafetyNet。John Wu 退了一步,新增的 Zygisk 排除列表用另一种方式真正地保证了应用运行环境的完整性,比起以往 MagiskHide 与应用开发者检测手段「斗智斗勇」的情形来说,通过排除这种方式隔离模块作用范围,是一种将选择交给用户、同时与应用开发者互相信任的新思路。

但从用户的角度说,MagiskHide 退场后,我们依然可以利用模块通过 SafetyNet 验证。尤其是当有专人精于此道时,效果说不定能比以前更好。

首先需要弄明白我们是想要欺骗 SafetyNet 还是单纯隐藏 root 或模块

SafetyNet 是 Google 移动服务套件的功能,这意味着,只有装有 GMS 并且应用调用了相关接口的情况下,我们才需要通过 SafetyNet 验证。逃避国内应用的 root 检测大部分情况下并不需要通过 SafetyNet 认证,只要使模块和 Magisk 不对这些应用生效即可,无需在意 SafetyNet 结果。

针对这种情况,我们可以在新版 Magisk 中开启 Zygisk,并在排除列表中添加这些应用。

而如果确实需要通过 SafetyNet,比如在 Google Play 应用商店中搜索下载 Netflix、Apple Music 等对媒体 DRM 级别要求较高的应用,鉴于新 Magisk 连同内嵌的 SafetyNet 测试功能也一并删除了,我们首先需要下载 SafetyNet 验证应用。

这里个人推荐的是 YASNAC。下载此软件,然后进行一次测试,我们便知道自己的设备是否启用了基于硬件的安全验证:

留意 evaluationType 一项的结果,根据前文的解释,若此结果为 basic,则意味着没有启用基于硬件的安全验证,若此结果为 hardware,则增强安全验证已经启用。

如果选项为 basic,我们可以:

  • 开启 Zygisk,使用排除列表,将需要的应用添加进排除列表中;依照前面的说法,排除列表中的应用是不受 Magisk 影响的,并且由于系统没有基于硬件的安全验证,此时设备仍然可以通过 SafetyNet;然而其代价是所有模块在此应用上均无效果
  • 使用 Magisk Alpha,一个基于 Magisk 的分支版本。该版本新增了 Zygisk 的同时保留了 MagiskHide 功能。但 Zygisk 和 MagiskHide 不能同时打开

如果选项为 hardware,则意味着我们需要第三方模块的协助:

  • 在 Magisk 中启用 Zygisk,开启排除列表并且安装 SafetyNet Fix 2.2 的 Zygisk 版本
  • 或者,在 Magisk Alpha 中启用 MagiskHide,并安装 SafetyNet Fix 2.1.2 的 Riru 版本
注意版本区分

这里提到的 SafetyNet Fix,是自从 MagiskHide 失效以来,在一些部署了基于硬件验证的设备上通过 SafetyNet 的少数有效方案。不过它并没有破解硬件密钥,而是通过巧妙伪装的方式,使 Google 采用 Basic 级别的安全认证,因而在应用模块后我们会发现 evaluationType 显示为 basic

小结

Zygisk 的实装似乎给 Magisk 模块铺就了一条充满希望的前路,而 MagiskHide 的退场却不甚乐观。虽然目前尚有替补队员,但如果 Google 和其他厂商推行更加严格的安全措施,那么 Android 玩机用户的未来是注定艰难的。

Magisk 仍将继续前进,在可以解锁 Bootloader 的设备上,我们依然拥有 root 的自由,但可以预想,这自由将会伴随着越来越多人无法接受的代价。

如果有那么一天,root Android 这份「虚假的自由」消失殆尽,我们或许还可以慰藉自己说「我至少曾经有过」。

感谢 Magisk Alpha 讨论组的夜猫子们对本文技术性问题的解答

参考链接:

> 下载少数派 客户端、关注 少数派公众号,了解更多 Android 玩法 🚀

> 特惠、好用的硬件产品,尽在 少数派 sspai 官方店铺 🛒