经历了两天的苦苦编译,终于我的Android 6.0.1_r77集成了我想要的Xposed环境,经此一役,又再次验证了那一句话,我果然是一个自带Bug的男人。
与我之前的这篇文章几乎一样,只是下载源码的版本不一样,具体不再赘述,多说一嘴,我选择lunch
的是aosp_hammerhead-userdebug
,这个很重要!
为了使得XposedInstaller
安装上的时候,能够获取root
权限,需要在环境中集成SuperSU
su
由于系统自带的su
文件,存在着一系列限制,比如只能root
用户或者shell
执行,这部分其实可以改动源码实现去除,但在实际操作时,即使改了,我的Superuser.apk
仍然不可以检测到root
环境的存在,所以使用了SuperSU.zip中的su
,而将原本的su
屏蔽掉了,su
的文件夹位置为system/extras/su
,你可以选取删除su
文件夹或者直接将这个文件夹下的Android.mk
文件改名就行。我这里直接改了名字
然后拷贝出SuperSU.zip
下的su
,libsupol.so
,supolicy
(这里的文件必须选择对应设备版本的文件,我这里使用的是N5,所以选择的是armv7
文件夹下的),到源码根目录下的packages
文件夹下,创建了名为su
的文件夹,同时将这三个文件paste进去,并将su
可执行文件复制一份并重命名为daemonsu
放到同一目录,
然后,在这个文件夹里面新建一个Android.mk
,具体内容如下
LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE_TAGS := optional LOCAL_MODULE := su LOCAL_SRC_FILES := $(LOCAL_MODULE) LOCAL_MODULE_CLASS := EXECUTABLES LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES) LOCAL_UNSTRIPPED_PATH := $(LOCAL_MODULE_PATH) include $(BUILD_PREBUILT) include $(CLEAR_VARS) LOCAL_MODULE_TAGS := optional LOCAL_MODULE := daemonsu LOCAL_SRC_FILES := $(LOCAL_MODULE) LOCAL_MODULE_CLASS := EXECUTABLES LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES) LOCAL_UNSTRIPPED_PATH := $(LOCAL_MODULE_PATH) include $(BUILD_PREBUILT) include $(CLEAR_VARS) LOCAL_MODULE_TAGS := optional LOCAL_MODULE := supolicy LOCAL_SRC_FILES := $(LOCAL_MODULE) LOCAL_MODULE_CLASS := EXECUTABLES LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES) LOCAL_UNSTRIPPED_PATH := $(LOCAL_MODULE_PATH) include $(BUILD_PREBUILT) include $(CLEAR_VARS) LOCAL_MODULE_TAGS := optional LOCAL_MODULE := libsupol.so LOCAL_MODULE_CLASS := SHARED_LIBRARIES LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES) LOCAL_SRC_FILES := $(LOCAL_MODULE) OVERRIDE_BUILD_MODULE_PATH := $(TARGET_OUT_INTERMEDIATE_LIBRARIES) include $(BUILD_PREBUILT)
最终目录结构如下
之后,为了能够apk申请root
权限时,能够弹框询问,将SuperSU.zip
下的common/Superuser.apk
拷贝,放到源码根目录下的packages/apps/SuperSU
文件夹下,这里的SuperSU
文件夹需要自己建立,在文件夹里新建一个Android.mk
,具体内容如下
LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE := SuperSU LOCAL_SRC_FILES := Superuser.apk LOCAL_MODULE_CLASS := APPS LOCAL_MODULE_SUFFIX := $(COMMON_ANDROID_PACKAGE_SUFFIX) LOCAL_CERTIFICATE := PRESIGNED include $(BUILD_PREBUILT)
最终目录结构如下:
SELinux
进入源码根目录下的/device/
目录下,选择对应编译的设备版本,具体目录如下
可以看到支持很多设备,我之前说了,我编译的是N5的版本,所以选择lge/hammerhead
,进入对应目录,修改BoardConfig.mk
文件,在BOARD_KERNEL_CMDLINE :=
下一行加上BOARD_KERNEL_CMDLINE += androidboot.selinux=permissive
,具体如下
网上有博客说,也可以把permissive
改为disabled
,具体效果我没试。有兴趣可以试试。
su
等文件在与关闭SELinux
操作的相同目录下,
打开device.mk
,增加如下文本
# SuperSU PRODUCT_PACKAGES += \ su \ daemonsu \ supolicy \ libsupol.so \ SuperSU
使得在重新编译源码时,将这些文件"安装"到对应目录,比如su
安装到/system/xbin/
目录下等等。
su
等文件权限打开源码根目录下的system/core/libcutils
的fs_config.c
文件,增加相关文件权限
{ 04750, AID_ROOT, AID_SHELL, 0, "system/xbin/su" }, { 07777, AID_ROOT, AID_ROOT, 0, "system/xbin/daemonsu" }, { 06755, AID_ROOT, AID_ROOT, 0, "system/xbin/supolicy" },
效果如下
SuperSU
的deamon
打开system/core/rootdir/init.rc
,增加以下代码
# SuperSU service daemonsu /system/xbin/daemonsu --auto-daemon & class main oneshot
使得在系统启动时,劫持app_process
,作为守护进程存在
至此,我们的SuperSU
就集成完毕了。最终效果如下
Xposed
Xposed
一共由3部分组成:Xposed Installer
+ Xposed native
部分 + XposedBridge.jar
.各自的作用不再赘述。下面开始设置编译
Xposed-art
首先,由于Android 6.0
基于ART
,Xposed
在实现ART
模式下的hook
时,修改了部分ART
虚拟机代码,为此需要下载Xposed-art
替换原本源码根目录下的art
文件夹,并切换到6.0的分支,具体操作如下
rm -rf art git clone https://github.com/rovo89/android_art.git art cd art git checkout xposed-marshmallow
Xposed-native
部分进入源码根目录下的frameworks/base/cmds
文件夹,下载Xposed-native
部分
cd frameworks/base/cmds git clone https://github.com/rovo89/Xposed.git
XposedBridge.jar
这个部分的编译我是使用的IDEA
去编译的。。。
具体过程不再赘述。最后实际上编译出一个apk,将这个文件改名为XposedBridge.jar
并拷贝到源码根目录下的out/target/product/hammerhead/system/framework
文件夹下
XposedInstaller
从网上下载XposedInstaller-3.15.apk放到源码根目录下的packages/apps/XposedInstaller
文件夹下,这里的XposedInstaller
文件夹同样需要自己建立,同样地,新建一个Android.mk
,内容类似于SuperSU
的。这里也贴出来吧
LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE := XposedInstaller LOCAL_MODULE_TAGS := optional LOCAL_SRC_FILES := $(LOCAL_MODULE).apk LOCAL_MODULE_CLASS := APPS LOCAL_MODULE_SUFFIX := $(COMMON_ANDROID_PACKAGE_SUFFIX) LOCAL_CERTIFICATE := PRESIGNED include $(BUILD_PREBUILT)
目录结构如下
同样地,为了使得编译源码时,XposedInstaller
“安装”上,需要修改/device/lge/hammerhead
文件夹下device.mk
文件,在刚才增加的地方后面再加上XposedInstaller
,当然这里也要对应自己的设备。
# XposedInstaller PRODUCT_PACKAGES += \ XposedInstaller
然后再次编译一下源码
。
Xposed
相关最后一步,但也是最重要的一步,下载XposedTools
cd ~ git clone https://github.com/rovo89/XposedTools.git cd XposedTools
然后在XposedTools
根目录下,参照已有的build.conf.example
创建一个build.conf
文件,我的文件内容如下
[General] # 注释,可删除:指定,输出编译结果目录 outdir = /home/simp1er/XposedTools/out [Build] # 版本大于89就行 version = 99(custom build by author ) # 根据CPU情况设置线程 makeflags = -j6 [GPG] sign = release user = Simp1er [AospDir] # 23代表SDK版本,等于号后接的是Android源码根目录 23 = /home/simp1er/android-6.0.1_r77
然后新建out
文件夹并进入out
文件夹下新建java
文件夹,将之前编译生成的XposedBridge.jar
拷贝到这个目录下,最终XposedTools
目录结构如下
然后,进入XposedTools
根目录,开始编译!
./build.pl -t arm:23
这里的arm
代表我的设备是arm
架构的,23
代表SDK
版本。由于这个脚本是基于perl
的,在执行过程中,可能会提示缺少一些依赖包,例如可能会缺少Config::IniFiles
,使用apt-cache search Config::IniFiles
搜索,然后sudo apt-get install
安装缺少的包即可。我这边缺失的库以及解决的办法如下
然后重新编译
之后
cd out/sdk23/arm/files/system/bin mv app_process32_xposed app_process32 #修改文件名 cd ../../ cp -r system ~/android-6.0.1_r77/out/target/product/hammerhead/ #将编译好的`Xposed`相关文件复制到对应文件夹
最后重新编译下系统源码
cd ~/android-6.0.1_r77 source build/envsetup.sh lunch 19 make -j6 snod #只打包文件
然后fastboot
重新刷所有img
,注意第一次启动手机由于此时无XposedInstaller
数据目录,所以是会报错XposedInstaller
意外中止的。忽略不管,直接上最终效果
Xposed
效果图
安装GravityBox
,并测试更改状态栏效果,观察下图,可以明显地看到状态栏地WIFI
信号变成了红色。
可见集成编译成功!
给 Android ROM(AOSP)集成 SuperSU 的方法
其实这个编译过程中还参考了很多其他博客,就不一一列举了,在此表示感谢,另外感谢@r0ysue
师傅,感谢提示使用SuperSU
帮助Xposed
获取root
.最后写的不好的地方敬请指摘.