簡介
xposed框架出來已經有一段時間了,之前只是看別人的技術博客,說是很強大,但是自己并沒有親手去實踐過。一方面據說xposed需要root過的手機,自己沒有,最近把自己手機root,開始玩一玩xposed。當然沒有root的手機也可以安裝xposed。
作用
xposed可以給程序執行過程掛上勾子(hook),然后加入我們自己的處理邏輯。比如你想修改某應用程序中的變量,函數實現等等。
場景
需求開發完成,測試通過,打正式包,加固,上傳應用市場。突然第二天,發現線上應用出現bug,而測試環境又不能浮現。如果用線上正式包,看不到日志,不能調試等等。
當然你說,可以自己本地打一個可以調試,看日志的正式包,如果覺得不麻煩,當然可以(大一點的工程,編譯,打包可以要一點時間的),但是應用如果是經過加固的,那還得加固,估計調試解決bug有點頭疼。
那這時候,就可以用xposed寫個插件,將正式包的調試,日志開關打開,將崩潰的地方dialog提示,等等。這樣不會在原工程添加任何代碼或者修改,豈不是很方便。
參考
- xposed開源框架地址xposed-github
- xposed插件Xposed Module Repository
- 不同sdk版本的framework下載地址framework
- xposed編譯工具XposedTools
- Xposed框架中文站
- 非ROOT設備上使用Xposed功能VirtualXposed
說明
xposed插件開啟,關閉,插件修改后都需要重新啟動系統,才能生效。
免重啟
當然網上有關于插件開發過程中,修改后免重啟的解決辦法,可自行百度。
安裝
- 設備
root手機一臺 - xposed卡刷包
從framework下載xposed卡刷包,注意下載時候要對于自己手機的系統版本和cpu型號,cpu型號查看方法自己百度。使用第三方Recovery刷入xposed卡刷包。 - Xposed installer.apk
從xda-developers安裝包安裝到手機上。 - 重啟手機
-
打開Xposed installer.apk
如果出現下面界面,者安裝成功。
截屏2020-04-13下午3.19.27.png
右上角可以打開或者關閉xposed,左上角菜單中的模塊里面列舉就是目前手機安裝的xposed插件,可以在里面開啟或者關閉,但都需要重啟系統才能生效。
開發
開發xposed插件需要XposedBridge包,下載后,放入工程。
- 新建工程
Android Studio新建一個Android工程或者module - 編寫hook類
當然不是只能實現IXposedHookLoadPackage,xposed具體用法自己百度。public class XposedHookTest implements IXposedHookLoadPackage { @Override public void handleLoadPackage(XC_LoadPackage.LoadPackageParam lpparam) throws Throwable { // todo } }
- 告訴xposed插件hook實現類
在assets目錄下新建xposed_init文件,然后寫入hook類的全路徑名,比如:com.pds.xposed.hook.XposedHookTest
- 告訴xposed該module是一個xposed插件
在manifest下的application標簽下配置以下代碼:<!-- 是否是xposed模塊,xposed根據這個來判斷是否是模塊 --> <meta-data android:name="xposedmodule" android:value="true" /> <!-- 模塊描述,顯示在xposed模塊列表那里第二行 --> <meta-data android:name="xposeddescription" android:value=" HOOK TEST" /> <!-- 最低xposed版本號(lib文件名可知) --> <meta-data android:name="xposedminversion" android:value="30" />
- 安裝并開啟插件
安裝插件到手機上,然后打開上面安裝的xposed軟件,在模塊里找到你自己的xposed插件,打開,重啟系統。 - 驗證
重啟后,就可以驗證自己插件是否生效或者自己hook邏輯是否有問題。
修改變量
如果我們想修改應用程序某一變量
public void handleLoadPackage(XC_LoadPackage.LoadPackageParam paramLoadPackageParam) throws Throwable {
// 通過包名判斷,是不是我們要修改的應用
if (HOOK_APP_PACKAGE_NAME .equals(packageParam.packageName)){
// 找到變量所在的類文件
final Class<?> clazz = XposedHelpers.findClass("com.pds.base.network.RetrofitConfig",classLoader);
// 修改
XposedHelpers.setStaticIntField(clazz,"level",2);
}
}
加固
現在很多應用都使用了第三方進行加固,這時候傳入handleLoadPackage方法的XC_LoadPackage.LoadPackageParam參數中獲取的ClassLoader是第三方加固程序的ClassLoader,如果用這個ClassLoader去找我們自己應用中的類,會報“類找不到”異常。
而加固程序都會在自己的Application類里面做一些解密操作,我們可以hook加固程序的Application拿到應用真正的ClassLoader實例。下面以360加固講解。
360加固
獲取應用真正ClassLoader實現:
private void _360Firm(final XC_LoadPackage.LoadPackageParam packageParam){
//hook 360殼
XposedHelpers.findAndHookMethod("com.stub.StubApp", packageParam.classLoader,"getOrigApplicationContext", Context.class, new XC_MethodHook() {
@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
super.afterHookedMethod(param);
XposedBridge.log("_360Firm afterHookedMethod");
//獲取到360的Context對象,通過這個對象來獲取classloader
Context context = (Context) param.args[0];
//獲取360的classloader,之后hook加固后的代碼就使用這個classloader
ClassLoader classLoader =context.getClassLoader();
//替換classloader,hook加固后的真正代碼
hookMethod(packageParam,classLoader);
}
});
由于第三方加固隨時可能修改Application名,文件位置,方法名等,所以自己還是得知道怎么去分析。
- 分析
首先解壓應用,拿到用于解密的未加固dex,使用工具反編譯成jar,查看Application實現。然后對應修改就可以了。
xposed插件推薦
Lucky Patcher
Xposed module,具體各種破解功能,具網上資料,可以破解HttpCanary,但是我沒有成功。JustTrustMe
Xposed module,關閉證書檢測,這樣https可以直接抓包。BDOpener
開啟APK調試與備份選項的Xposed模塊