工具 Xposed框架
本文由 Luzhuo 編寫,轉發請保留該信息.
原文: https://blog.csdn.net/Rozol/article/details/79779660
- Xposed框架是一款可以在不修改APK的情況下影響程序運行(修改系統)的框架服務
- 官網(需要翻牆):
http://repo.xposed.info
- 國內第三方網站:
http://xposed.appkg.com
(有廣告)http://www.xposed.pro
- 使用該框架手機需要root (也有不root的版本), 該框架還挑手機 (小心強擼灰飛煙滅)
- XposedInstaller-v2.6.1.jar : Android2.3
- XposedInstaller-v2.6.1st.jar : Android4.0.3
- XposedInstaller-v3.0_alpha4.jar : Android5.0/5.1/6.0
- XposedInstaller-v3.1.5.jar : Android7.0/7.1/8.x
- 作者系統:
- Win10
- Android4.4.2
- AndroidStudio2.2
安裝
- 將apk安裝到手機
- 點擊框架 -> 框架[安裝/更新]
- 給root權限後, 安裝, 並重啓
編寫模塊 (AndroidStudio)
1.
api下載:https://forum.xda-developers.com/xposed/xposed-api-changelog-developer-news-t2714067
2.
創建項目3.
添加jar包- 把下載的jar包放到
app/lib
目錄下 build.gradle引入
dependencies { // ... provided fileTree(dir: 'lib', include: ['XposedBridgeApi-54.jar']) }
- 把下載的jar包放到
4.
編寫代碼- 創建 類 實現
implements IXposedHookLoadPackage
接口 (其他代碼放到 編寫代碼 裏講)
public class Hook implements IXposedHookLoadPackage { private final String packageName = "me.luzhuo.xposeddemo"; @Override public void handleLoadPackage(XC_LoadPackage.LoadPackageParam loadPackageParam) throws Throwable { // 系統加載的應用包名, 可以用於過濾 if(!packageName.equals(loadPackageParam.packageName)) return; // 使用 XposedHelpers 類實現攔截操作 } }
- 創建 類 實現
5.
編寫xposed_init
- 在
/app/src/main/assets
目錄下創建文件xposed_init
- 編寫模塊入口(全類名):
me.luzhuo.xposeddemo.Hook
- 在
6.
編寫清單文件(去掉//註釋)<application ... > // 將Android作爲Xposed中的一個模塊 <meta-data android:name="xposedmodule" android:value="true"/> // 模塊描述 <meta-data android:name="xposeddescription" android:value="X測試"/> // xposed的jar包最低版本號 <meta-data android:name="xposedminversion" android:value="54"/> <activity> ... </activity> </application>
7.
安裝應用到手機8.
手機打開Xposed Installer
- 選擇
模塊
, 把自己剛安裝的模塊給√上
- 選擇
9.
重啓手機 (每次修改完代碼安裝到手機時後, 都要重啓)
編寫代碼
Bean類
public class Person { private String name = "pname"; private int age = 11; public void setName(String name){ this.name = name; } public String getName(){ return this.name; } public void setAge(int age){ this.age = age; } public int getAge(){ return this.age; } }
測試的MainActivity
android:text="修改數值" public void value(View view){ Person person = new Person(); person.setName("abc"); person.setAge(21); Log.i(TAG, "person-name: " + person.getName()); Log.i(TAG, "person-age: " + person.getAge()); }
修改設置數值
代碼 (放在
handleLoadPackage
回調裏)// 使用 XposedHelpers 類實現攔截操作 // public void setName(String name) hook_method("me.luzhuo.xposeddemo.bean.Person", "setName", loadPackageParam, String.class, new XC_MethodHook() { /** * 攔截之前 */ @Override protected void beforeHookedMethod(MethodHookParam param) throws Throwable { super.beforeHookedMethod(param); // 獲取傳入的參數值 Log.i(TAG, "before-setname: " + param.args[0]); // 修改傳入的參數值 param.args[0] = "before-hookname"; } }); // public int getAge() hook_method("me.luzhuo.xposeddemo.bean.Person", "getAge", loadPackageParam, new XC_MethodHook() { /** * 攔截之後 */ @Override protected void afterHookedMethod(MethodHookParam param) throws Throwable { super.afterHookedMethod(param); // 獲取返回結果的值 Log.i(TAG, "after-getage: " + param.getResult()); // 修改返回結果的值 param.setResult(123); } });
打印
// 修改設置值 要在攔截之前 //I/Hook: before-setname: abc //I/MainActivity: person-name: before-hookname // 修改返回值 要在攔截之後 //I/Hook: after-getage: 21 //I/MainActivity: person-age: 321
通過上述打印, 可知兩個方法的值都已被修改, 大家可能會發現
XposedHelpers
類哪去了, 拿去重新封裝了/** * hook操作 * @param className 期望被hoot的全類名 * @param methodName 期望被hoot的方法名 * @param parameterTypesAndCallback 參數類型 和 hoot回調 */ private void hook_method(String className, String methodName, XC_LoadPackage.LoadPackageParam loadPackageParam, Object... parameterTypesAndCallback){ try{ // 根據hoot類的名稱尋找方法 XposedHelpers.findAndHookMethod(className, loadPackageParam.classLoader, methodName, parameterTypesAndCallback); }catch (Exception e){ XposedBridge.log(e); } }