在Nexus6P上安装xposed的三种方法

前些天有朋友问我怎么安装xposed,于是开动了一下思路,想到三种不同的方式去安装xposed框架,写篇文章分享一下。

一、xposed原理

xposed 原理是一个老生常谈的问题,android 里的所有应用程序都是由zygote 进程fork 出来的,而zygote 就是app_process ,所以xposed替换掉了app_process ,预先加载自己的钩子,在加载dex时候就可以提前做一些修改。而app_process 位于system 分区,本身是不可以被写的,所以xposed 需要root 以后才可以使用。

再多说一点,在Dalvik 和ART 换代过程中,xposed 从2.7变为了3.0,之间的变化还是很大的,所以本文只介绍xposed3.0以上的部分,毕竟Dalvik太久远了。而且那个年代的手机基本可以被第三方工具提权到root,所以也没必要自己给自己找麻烦。

为一台手机安装xposed 框架的最终目标也比较明确,修改掉system 分区下的一些文件,并且分配好owner 和SELinux 。

二、方法0:使用第三方root工具后直接安装

为什么叫方法0,因为不一定可靠,基本是靠运气,使用流行的工具对手机进行root,通常老的手机可以这么做,新一点的手机很难用第三方的root工具进行root,一般也会集成一个SuperSU进去。如果成功的话,就可以先安装一个xposed installer ,在线去让它自动安装,基本不会出问题。

三、方法1:编译源码

先科普一下背景知识,如果只看文件的话,手机里的xposed 框架由一个XposedBridge.jar 的包、一个prop 文件、一些binary 文件组成,这些都是提供源码的,这一段主要讲如何从源码生成整个xposed。而在开发插件时候,会用到XposedBridgeAPI-XX.jar 的包。

1、下载aosp 并且完成一次编译,刷入手机,使之可以正常启动

2、XposedBridge.jar 和 XposedBridgeAPI-XX.jar

首先明确一点,这两个是不一样的,前者是位于手机里的、拥有大量的实际解析代码的东西,并不是一个jar包,而是一个被改名为jar的apk,将来用于加载用户插件;后者是用于Android Studio 开发的,是一个货真价实的jar,一般是作为provided的依赖,而且千万不能被编译到apk里。

二者的源码位于rovo89/XposedBridge 中,使用git clone 并且checkout 到指定的版本号,版本号之间的区别比较小,都按照最新的来就行,这个地方不会出大问题。

XposedBridge.jar

使用代码 ./gradlew build ,得到一个未签名的apk,里面基本只有一个classes.dex ,包名是de.revb.android.xposed ,将这个apk改名为XposedBridge.jar ,留作备用。

XposedBridgeAPI-XX.jar

方法A:直接到jcenter的仓库里去下载,https://bintray.com/rovo89/de.robv.android.xposed/api/

方法B:使用代码 ./gradlew jarStubsjarStubsSourcegenerateAPI (这几个命令都可以),阅读一下build.gradle 就可以大概知道意思,编译出来的位于app/build/api 。开发时可以使用这个jar。

3、编写xposed.prop

创建一个简单的文本文件,放到AOSP/out/target/product/angler/system/ 下。

4、xposed

代码位于rovo89/Xposed ,git clone 并且checkout 出对应的分支,与XposedBridge 保持一致。将整个目录移动到AOSP/framework/base/cmds/ ,并且将文件夹命名为xposed 。

注意,下载下来的repo是大写Xposed,Android.mk里写的是小写xposed,所以这里需要重命名一下。

使用mmm 即可进行编译,成功后,在AOSP/out/target/product/angler/system/bin 里就会有app_process32_xposed 和app_process64_xposed 。留作备用。

5、android_art

光有app_process 的替换是不够的,在Android 5.0 以上,需要对art 虚拟机和相关的工具进行大量的修复,编译需要AOSP 。

代码位于rovo89/android_art ,git clone 并且checkout 出对应分支,将整个目录覆盖掉AOSP/art ,注意,是完全的覆盖,不要害怕,确实是这样的。

使用m 进行编译,成功后,在AOSP/out/target/product/angler/system/lib(lib64) 里会出现额外的libxposed_art.so ,和被修改过的librart.so 等文件,在system/bin 里的dex2oat 同样也被修改过。

6、打包

在AOSP/out/target/product/angler/system/bin 里,使用xposed 版的app_process 替换原来的app_process ; 将XposedBridge.jar 放入system/framework/ 里。

将xposed.prop 放入system /里。

system/lib 和system/lib64 不做任何处理。

一定要注意大小写 ,严格按照硬编码的文件名,之后make snod 进行打包。

7、重启 刷入手机并且重启,在logcat里grep一下,看看运行情况,报错的话就按照错误去猜哪里可能出错了,只遇到过一次符号没找到的问题。此时手机大概率是可以用了。

四、方法2:解开release包并替换文件

假设我们拥有了一个userdebug 版的手机,此时SDK 和armeabi 其实是知道的,可以在官网上下载已经打包好的zip,http://dl-xda.xposed.info/framework/,找到对应的zip。

解开后按照flash-script.sh 里的最后几行,依次把system 目录里的文件替换过去,虽然是system 只读分区,但我们可以用adb root; adb remount 来让system 分区可写,用adb shell stop 将系统停下来再进行操作。

之后挨个将文件先push 到/data/local/tmp ,再cp到 对应的位置,默认情况下owner 和SELinux 是不会出问题的,不要手残或者漏掉的话,直接开机就没问题了。

五、方法3:在recovery模式下刷入release包

先下载方法2时涉及的zip文件,但是不要解压。

recovery 相当于一个小型的操作系统,进入的方法是adb reboot recovery ,这时候各个分区都没有被挂载。推荐使用第三方的recovery 。为什么要用第三方的呢?因为aosp 自带的recovery 是无法对分区进行挂载操作的,而release包里是有对vender 进行操作的代码和对system 的写操作,这样我们要么改代码并且重新签名,要么找个能操作vendor 的recovery 。

经过尝试,自带的recovery 似乎始终无法让system 挂载可写,不知道为什么。

刷第三方recovery 的话,强烈推荐TWRP ,到官网找一下手机型号,之后fastboot flash recovery twrp-recovery.img ,进入以后就是一股清流,比aosp 的recovery 舒服多了,选择来自SD卡的xposed 包即可。

六、总结

思路都是一致的,想办法让system可写,覆盖掉那几个文件即可。