前言
Xposed框架(Xposed Framework)是一套開源的、在Android高權(quán)限模式下運行的框架服務,可以在不修改APK文件的情況下影響程序運行(修改系統(tǒng))的框架服務,基于它可以制作出許多功能強大的模塊,且在功能不沖突的情況下同時運作。--百度百科
準備
1、 Xposed Installer apk包下載:https://repo.xposed.info/module/de.robv.android.xposed.installer
這里唯一要注意的是Android 4.0.3 - Android 4.4.X和 Android 5.0以上,下載的版本不相同。
2、編寫測試APP
3、編寫Xposed插件APP
4、一個Root的手機
步驟
安裝Xposed Installer
安裝好XposedInstaller后進入應用程序,會出現(xiàn)需要激活框架的界面,如下圖所示,這里我們點擊“安裝/更新”就能完成框架的激活了。部分設備如果不支持直接寫入的話,可以選擇“安裝方式”,修改為在Recovery模式下自動安裝即可。


安裝成功之后重啟手機,激活顯示58、54框架的版本

新建測試apk
Android Studio新建一個工程,這里就寫個TextView顯示文字,將apk運行到手機上。
public class MainActivity extends AppCompatActivity {
TextView test;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//控件
test = findViewById(R.id.test);
test.setText("XposedHook");
}
}
編寫Xposed插件
Android Studio新建一個沒有Activity的項目

添加依賴
在Module 中Gradle添加,這里特別【注意】
這里只是參與編譯,不會將代碼打入包中
compileOnly 'de.robv.android.xposed:api:82'
compileOnly 'de.robv.android.xposed:api:82:sources'
配置插件
在AndroidManifest.xml文件中application標簽中配置插件名稱和Api版本號
<application
··· >
<meta-data
android:name="xposedmodule"
android:value="true"/>
<meta-data
android:name="xposeddescription"
android:value="Xposed插件測試"/>
<meta-data
android:name="xposedminversion"
android:value="30"/>
</application>
新建一個入口類
新建一個XposedHook類繼承IXposedHookLoadPackage方法,這里我通過Hook改變測試APP TextView的值。
//包名路徑
package com.zhj.xposedhooklib;
public class XposedHook implements IXposedHookLoadPackage {
@Override
public void handleLoadPackage(final LoadPackageParam loadPackageParam) throws Throwable {
// 判斷是不是要Hook的包,不是直接返回 com.zhj.xposedhook為測試Demo的包名
if (!"com.zhj.xposedhook".equals(loadPackageParam.packageName)) {
//打印日志加載的包名
XposedBridge.log("Loaded app: " + loadPackageParam.packageName);
return;
}
// 需要Hook測試的 app的類絕對路徑"com.zhj.xposedhook.MainActivity" 方法名 "onCreate" 方法參數(shù) Bundle.class
XposedHelpers.findAndHookMethod("com.zhj.xposedhook.MainActivity", loadPackageParam.classLoader,
"onCreate", Bundle.class, new XC_MethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
XposedBridge.log("beforeHookedMethod");
super.beforeHookedMethod(param);
}
@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
XposedBridge.log("afterHookedMethod");
//加載類
Class c = loadPackageParam.classLoader.loadClass("com.zhj.xposedhook.MainActivity");
//獲取類中"test"成員變量
Field field = c.getDeclaredField("test");
//成員變量為private,故必須進行此操作
field.setAccessible(true);
//獲取控件對象
TextView tv = (TextView) field.get(param.thisObject);
//改變TextView的值
tv.setText("我的值被hook改變了");
super.afterHookedMethod(param);
}
}
);
}
}
聲明主入口路徑
新建Assets目錄中添加xposed_init文件


xposed_init文件內(nèi)容,XposedHook的類包名路徑
com.zhj.xposedhooklib.XposedHook
將插件打包
因為控件沒有Activity,將build方式改成Nothing,將插件apk運行到手機上,再將插件添加到Xposed Installer模塊中,如下圖所示,重啟手機


驗證
打開測試apk,可以發(fā)現(xiàn)里面的值發(fā)生改變

打開Xposed Installer日志,可以發(fā)現(xiàn)我們打印的日志信息

原理
Xposed框架是基于一個Android的本地服務應用XposedInstaller,與一個提供API 的jar文件來完成的。
通過替換/system/bin/app_process程序控制zygote進程,使得app_process在啟動過程中會加載XposedBridge.jar這個jar包,從而完成對Zygote進程及其創(chuàng)建的Dalvik虛擬機的劫持。
基于Xposed框架可以制作出許多功能強大的模塊,且在功能不沖突的情況下同時運作。此外,Xposed框架中的每一個庫還可以單獨下載使用,如Per APP Setting(為每個應用設置單獨的dpi或修改權(quán)限)、Cydia、XPrivacy(防止隱私泄露)、BootManager(開啟自啟動程序管理應用)對原生Launcher替換圖標等應用或功能均基于此框架。
參考文獻
Xposed hook:http://www.itdecent.cn/p/f163c5eacf03