Android Virtual Devices(AVD) root/Magisk/xposed
在 windows 下操作,终端使用 powershell。
旧系统(如 4.4 kitkat)+ supersu
主要参考文章:搞机:AS自带模拟器AVD Root 和 Xposed安装
旧系统可以安装 supersu + 旧版本 xposed。
在 as 中查询 sdk 目录位置(一般在
%localappdata%\Android\Sdk
),将其中的platform-tools
和tools
加入系统变量 path 中(一般来说,前者包含有 adb.exe,大多数人都已经加了。后者包含有 emulator.exe,大多数人没加但待会要用,如果不想加进去的话用这个命令的时候带上路径也可以;另外 emulator.exe 在%localappdata%\Android\Sdk\emulator
下也有一份,有时候高版本安卓要用 emulator 目录的打开才行。可以先用 emulator 命令带上路径启动虚拟机看看)查询要 root 的虚拟机名字
1
emulator -list-avds
以可读状态启动虚拟机(启动后这个终端窗口就别关了,后面的操作新建一个新终端窗口)
1
emulator -avd [刚刚查到的虚拟机名字] -writable-system
解除 selinux
1
2
3
4
5
6adb root
adb remount
adb shell
# 这里进入到虚拟机那边的 shell 中
> setenforce 0
> exit替换 su。需要获取对应的 su.pie。获取方法有这么几个:
- 文章里面有百度网盘,提取码 cg08,网盘里面有个压缩包,解压待用。
- github 的某个项目 meefik/avd-root。同样是里面的压缩包,版本还比较新。值得一提的是这个其实是个 avd 一键 root 工具,但脚本适用于 shell,但应该是 linux 下使用的或者在虚拟机 sdcard 内展开然后用 adb shell 进去,总之我不太明白怎么用。。。
- 编译。这个我有疑问,也挺麻烦,所以后面说。
将其中的两个 su.pie 用 adb push 到相应位置。如果是通过前两个方法,解压后进入文件夹中运行终端,然后输入:
1
2
3
4
5
6adb push .\x86\su.pie /system/bin/su
adb push .\x86\su.pie /system/xbin/su
chmod 0755 /system/bin/su
chmod 0755 /system/xbin/su
su --install
su --daemon&再新建终端窗口。这次是装软件,要装 supersu 的管理器和 xposed 管理器。supersu 同样在上面前两个获取项目中有。如果你的模拟器用的是 5.0-8.0 版本,那上面的 xposed-framework 也能用。但这是旧系统,也就是 4.4,就需要用更低版本的,不好找,在这个帖子:Xposed for android 4.4.4 is NOT fixed, please compile 87v for sdk19 里这里找到一个能用的:Xposed 2.7.1 by Sola Warez.apk。另外 4.4 版本 avd 没有文件管理器,也得装一个;装一个钛备份测试 root 结果,等等等等。可使用 adb install 命令安装,以 supersu 和 xposed 为例:
1
2adb install .\SuperSU-v2.82-SR5.apk
adb install .\Xposed_2.7.1_by_Sola_Warez.apk此时打开钛备份就会弹出 root 提示了。注意打开 supersu 会提示你更新 su 文件,不要点击确认,不管它,点击 cancel 即可。
如果要重启就比较麻烦。文章建议用
adb reboot
但亲测无效。另外两个方法是使用 xposed 软重启和直接通过 gui 进行软重启。重启后可能还需要再运行一次su --daemon&
。关闭的话,不要通过 gui 的电源关机,直接点右上角的 x 让 avd 保存快照就好了。但未来启动仍然需要通过emulator
命令启动而不是通过 avd gui 直接启动。
其他参考资料
- How to get root access on Android emulator? 这里似乎给出了固化 root 的方法。
- Rooting the Android Studio AVDs 这是另一个教程,补充了重启后失效的内容。
- su.pie 编译方法获取:[原创]学习Androidx86模拟器root安装xposed。这同时也是另一个教程。不过看得我有些云里雾里:编译时应该用 supersu 项目的代码还是安卓源码?如果是安卓源码那就有点麻烦了。。。安卓源码非常大,需要谷歌的专门 cli 工具(基于 git 开发的)下载还要先下载一个 30g 的 base 包;然后再下载相应分支(系统版本)的代码。。。但看这篇教程,好像只编译了部分代码?但要获取部分代码也很麻烦:谷歌将不同组件分散在一大堆库中,你得找到相应的库才有对应的文件(当然,在网页端点开相应的库,没点错的话就会直接让你选择系统分支了)。而且貌似对应源码目录的结构还和教程中的结构不太一样(少一个 mk 文件),所以我倾向于编译 supersu 的源码。更多关于安卓源码下载的文章:
- 如何下载Android源码 #1 谷歌那一大堆库中比较重要的几个仓库
- Android 系统源码——下载到编译 手把手源码下载教学
- 第三方 su 生效原理
- 听说该方法不能用在 google play 版本系统中(待验证)
新系统(android 10)+ magisk
先给两篇参考文章,分别代表了两种思路:
建议使用第一种。第二种需要手工编译并下载 sdk,操作繁琐的多。唯一的好处就是不用放修改后的 ramdisk.img 到 sdk 镜像里面。
第一种方法
到第一篇参考文章中,将整个项目拖下来(git clone / 直接下载源码压缩包)。
查询虚拟机名字后(见上文),启动虚拟机。
1
emulator -avd [刚刚查到的虚拟机名字]
找到 sdk 目录下的
system-images
文件夹,在你所启动的对应版本系统文件夹里面找到ramdisk.img
,先在原地复制并粘贴(为了保留一份副本),再将该文件拷到项目文件夹中。确认虚拟机和 adb 正常启动并运行的情况下,运行项目文件夹中的
patch.bat
。运行完毕后将项目文件夹中的
ramdisk.img
拷回system-images
对应版本系统文件夹中覆盖,关闭虚拟机并进行冷启动即可。
拓展
本方法是关键文件是项目文件夹里面的
magisk_emu.zip
。这个 zip 其实和官网 release 下载到的不同版本 magisk zip recovery 安装包是一个性质的东西。不同的地方在于,存在于项目文件夹的这个文件是 debug 版本的,文件大小要比 release 版大一倍。也正因如此,如果要升级 magisk / 使用 release 版本,替换这个 magisk 文件然后走一下 3~5 步即可。
不直接运行
patch.bat
,而是在 powershell 中运行,能查看到运行日志。release 版的压缩包,运行起来会会多显示一句1
run-as: package not debuggable: com.topjohnwu.magisk
也明显能感觉到
patch.bat
使用 release 包时比 canary 包慢。阅读文档,patch.bat 还能跑一个 canary 的参数。其实只是改为在线获取而已。
使用 release 版本,附带的 magisk manager 有可能因为某些原因(版本过旧[^1]/网络太差[^2])无法正常识别所安装的 magisk。覆盖安装最新版的 magisk manager 可解(在目前这个时间点,release 版本低于 v20.3 用的都是旧版 ui 客户端,基本都会报错;v20.4 虽然已经用了新版 ui 客户端但还是报错,只有 v21.0 不需要覆盖装 manager 本身就正常)。
(软件兼容性问题) 非 google play rom 版本下钛备份无法正常使用,获取不到 root。原因是钛备份读取的是
/system/xbin/su
,而用上面方法整出来的 magisk,生效文件在/sbin/su
。用 Root Checker Pro 就能发现问题,supersu 能够读取处 su 版本。magisk 这里就会显示有问题。
实机 magisk 因为
/system/xbin/su
处没有文件,所以钛备份就才会读取/sbin/su
。那虚拟机这里怎么会有文件呢?原来这里的/system/xbin/su
是给 adb 用的。。。解决方法,给一个硬连接。
先用可读 system 和 selinux 宽松模式启动虚拟机
1
emulator -avd [刚刚查到的虚拟机名字] -writable-system -selinux permissive
remount adb 的 su
1
2adb root
adb remount给上硬连接。
1
ln -sf /sbin/su /system/xbin/su
即可。重启不影响效果。和修改前的区别就是以后使用
adb root
时需要在系统内的 magisk 弹窗确认。
(系统兼容性)经测试不存在该问题。是否 google play 版本不影响 magisk 生效。另外 google play 版本不需要解决软件兼容性问题,因为本身就不运行在 adb 内运行 root,也就不会有
/system/xbin/su
的存在。
第二种方法
简单提一下,主要是编译坑多。编译步骤还可以看一下 magisk 项目 底下说明,参考文章里面用的是最新版的编译方法,旧一点的版本(低于 v21.0) build.py 里面就没有 ndk 的编译选项。如果要编译旧版本,可以从 magisk 项目切换到旧版本的 tag 就能在底下看到旧版本的对应说明了。
克隆项目。项目所在目录首选你系统的用户目录,其次是驱动器盘根目录(如果你的用户名是中文的话)。切记别放在路径有中文的目录中。
1
git clone --recurse-submodules https://github.com/topjohnwu/Magisk.git
安装 jdk8,python 3.6,设置好 path,另外旧版本 magisk 需要设置
ANDROID_HOME
这个用户变量;而新版本 magisk 需要设置ANDROID_SDK_ROOT
这个用户变量。两个用户变量都是指向 sdk 目录的。装个 colorma。或者删掉 colorma 在 build.py 中的依赖代码(显示个代码颜色,不用不会死)。
1
pip install colorama
将文件
config.prop.sample
复制并改为config.prop
。修改内容,要修改的内容类似于下面这两串代码。(其实是成功安装后在 magisk manager 里面显示出来的版本号,都自己编译了,别按下面模板改,该非亿点就非一点)1
2
3
4
5
6
7# The version name and version code of Magisk
version=20.4
versionCode=20400
# The version name and version code of Magisk Manager
appVersion=7.5.1
appVersionCode=267开始编译
1
2python build.py ndk
python build.py all可能会有很多报错坑,类似下 ndk 压缩包的时候网络慢报错(挂代理);
类似编译 ndk 的时候出现
1
'gbk' codec can't decode byte 0x8b in position 79: illegal multibyte...
这个需要修改 build.py 的相关位置,类似于
1
125 with open(file, 'r') as f:
改成
1
125 with open(file, 'r',encoding='utf-8') as f:
(话说回来这个错误在我把项目放在 c 盘根就出现了,放在用户目录就不会出现)
还有编译 all 的时候出现
1
windows javax.net.ssl.SSLException
这个得挂代理。
等等等。
一顿操作
1
2
3
4
5
6
7
8adb root
adb push native\out\x86\busybox scripts\emulator.sh /data/local/tmp
adb push native\out\x86\magiskinit64 /data/local/tmp/magiskinit
adb shell "mkdir -p /data/adb/magisk"
adb shell "cp /data/local/tmp/busybox /data/adb/magisk/"
adb push scripts\util_functions.sh /data/adb/magisk/
adb shell sh /data/local/tmp/emulator.sh验证一下
1
adb shell "ps -ef | grep -i magisk"
出现
1
root ..... 00:00:00 magiskd
然后装 magisk manager 就行了。
拓展
- 这个方法也会生成一个 zip 文件,也是个典型的 magisk.zip 文件。但这个 magisk-debug.zip 放到方法 1 里面用,用 Root Checker Pro 检查,su 参数正确但 root 确认框一闪而过,没法正常使用。。。
- 这个方法同样有钛备份的兼容问题,解决方法同上。
[^1]: 让模拟器 magisk 正常运行的 emulator.sh 放出时间不早于 v20.0。
[^2]: 让 magisk 网络功能在大陆能够比较畅快使用 cdn 功能的客户端大概版本也不低于 8.0。