Shizuku
背景
在开发需要 root 权限的应用时,最常见的方法是在 su shell 中运行一些命令。例如,有一个应用使用 pm enable/disable
命令来启用/禁用组件。
这种方法有很大的缺点:
- 极其缓慢(需要创建多个进程)
- 需要处理文本(非常不可靠)
- 可能性仅限于可用的命令
- 即使 ADB 有足够的权限,应用也需要 root 权限才能运行
Shizuku 使用了一种完全不同的方式。详细描述如下。
用户指南与下载
Shizuku 如何工作?
首先,我们需要讨论应用如何使用系统 API。例如,如果应用想获取已安装的应用列表,我们都知道应该使用 PackageManager#getInstalledPackages()
。这实际上是应用进程和系统服务进程之间的进程间通信(IPC)过程,只是 Android 框架为我们处理了内部工作。
Android 使用 binder
来进行这种 IPC。Binder
允许服务端了解客户端的 uid 和 pid,这样系统服务就可以检查应用是否有权限执行操作。
通常,如果有一个供应用使用的"管理器"(例如 PackageManager
),在系统服务进程中就应该有一个对应的"服务"(例如 PackageManagerService
)。我们可以简单地认为,如果应用持有"服务"的 binder
,它就可以与"服务"通信。应用进程在启动时会收到系统服务的 binder。
Shizuku 引导用户首先使用 root 或 ADB 运行一个进程,即 Shizuku 服务器。当应用启动时,连接到 Shizuku 服务器的 binder
也会被发送到应用。
Shizuku 提供的最重要功能是充当中间人,接收来自应用的请求,将它们发送到系统服务器,然后将结果发送回来。你可以查看 rikka.shizuku.server.ShizukuService
类中的 transactRemote
方法和 moe.shizuku.api.ShizukuBinderWrapper
类以了解详情。
这样,我们就达到了使用更高权限系统 API 的目标。对于应用来说,这几乎与直接使用系统 API 相同。
开发者指南
API 和示例
https://github.com/RikkaApps/Shizuku-API
从 v11 之前版本迁移
现有应用当然仍然可以正常工作。
注意事项
-
ADB 权限有限
ADB 的权限有限,并且在不同的系统版本上有所不同。你可以在这里查看授予 ADB 的权限。
在调用 API 之前,你可以使用
ShizukuService#getUid
检查 Shizuku 是否正在使用 ADB,或使用ShizukuService#checkPermission
检查服务器是否有足够的权限。 -
Android 9 之后的隐藏 API 限制
从 Android 9 开始,普通应用对隐藏 API 的使用受到限制。请使用其他方法(例如 https://github.com/LSPosed/AndroidHiddenApiBypass)。
-
Android 8.0 和 ADB
目前,Shizuku 服务获取应用进程的方式是结合
IActivityManager#registerProcessObserver
和IActivityManager#registerUidObserver
(26+)来确保在应用启动时发送应用进程。然而,在 API 26 上,ADB 缺乏使用registerUidObserver
的权限,因此如果你需要在可能不是由 Activity 启动的进程中使用 Shizuku,建议通过启动一个透明的 activity 来触发 binder 的发送。 -
直接使用
transactRemote
需要注意-
不同 Android 版本下的 API 可能不同,请务必仔细检查。此外,
android.app.IActivityManager
在 API 26 及以后版本中有 aidl 形式,而android.app.IActivityManager$Stub
仅存在于 API 26。 -
SystemServiceHelper.getTransactionCode
可能无法获取正确的事务代码,例如android.content.pm.IPackageManager$Stub.TRANSACTION_getInstalledPackages
在 API 25 上不存在,而是有android.content.pm.IPackageManager$Stub.TRANSACTION_getInstalledPackages_47
(这种情况已经处理,但不排除可能存在其他情况)。使用ShizukuBinderWrapper
方法不会遇到这个问题。
-
开发 Shizuku 本身
构建
- 使用
git clone --recurse-submodules
克隆 - 运行 gradle 任务
:manager:assembleDebug
或:manager:assembleRelease
:manager:assembleDebug
任务生成可调试的服务器。你可以将调试器附加到 shizuku_server
以调试服务器。请注意,在 Android Studio 中,"运行/调试配置" - "始终使用包管理器安装" 应该被选中,这样服务器就会使用最新的代码。
许可证
本项目的代码可在 Apache-2.0 许可下使用。
例外情况
-
你禁止以任何方式使用以下列出的图像文件(除非用于显示 Shizuku 本身)。
manager/src/main/res/mipmap-hdpi/ic_launcher.png manager/src/main/res/mipmap-hdpi/ic_launcher_background.png manager/src/main/res/mipmap-hdpi/ic_launcher_foreground.png manager/src/main/res/mipmap-xhdpi/ic_launcher.png manager/src/main/res/mipmap-xhdpi/ic_launcher_background.png manager/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png manager/src/main/res/mipmap-xxhdpi/ic_launcher.png manager/src/main/res/mipmap-xxhdpi/ic_launcher_background.png manager/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png manager/src/main/res/mipmap-xxxhdpi/ic_launcher.png manager/src/main/res/mipmap-xxxhdpi/ic_launcher_background.png manager/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png
-
对于整个项目而言,它不是免费的。 你禁止将你编译的 apk(包括修改过的,例如将应用名称"Shizuku"改为其他名称) 分发到任何应用商店(包括但不限于 Google Play 商店、F-Droid、亚马逊应用商店等)。