入门开发
免root方案: LSpatch
下载:https://github.com/LSPosed/LSPatch
教程:https://www.52pojie.cn/thread-1598175-1-1.html
原理:将编写好的xposed.apk
注入到目标apk文件,生成一个新的apk
关于版本问题
Android Studio 连接夜神
先确保adb能连上虚拟机,连不上运行 adb connect 127.0.0.1:62001
,AS直接运行就可以将app装到模拟器
频繁掉线的问题,AS的adb版本和模拟器自带adb版本不一样导致,解决:https://blog.csdn.net/qq910689331/article/details/124115640
基本步骤,详细参考正己课程
- libs 导入 XposedBridgeAPI,然后
add as library ...
https://github.com/924587628/XposedBridgeAPI/blob/master/XposedBridgeAPI-89.jar
- AndroidManifest 引入下列 meta
1 2 3 4 5 6 7 8 9 10 11 12
| <meta-data android:name="xposedmodule" android:value="true" />
<meta-data android:name="xposeddescription" android:value="这是一个Xposed模块" />
<meta-data android:name="xposedminversion" android:value="89" />
|
- 修改 build.gradle,改成
compileOnly
- 创建Hook入口,在 Assets新建 xposed_init 文件,标明 hook类的位置
- 创建第四步中的hook类,初始内容为:
必须继承自 IXposedHookLoadPackage 和 handleLoadPackage 才有hook效果
1 2 3 4 5 6 7 8 9
| import de.robv.android.xposed.IXposedHookLoadPackage; import de.robv.android.xposed.callbacks.XC_LoadPackage;
public class Hook类名 implements IXposedHookLoadPackage { @Override public void handleLoadPackage(XC_LoadPackage.LoadPackageParam loadPackageParam) throws Throwable {
} }
|
- 点击
run
,等待一段时间,模块编译成功
- 导出 apk 文件
一些常用操作
- 添加依赖,在
app > build.gradle > dependencies
添加,然后 sync now ...
- 重启手机后,查看日志,需要
restart logcat
模板脚本
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64
| package com.example.xposed_demo_202408;
import android.util.Log;
import com.google.gson.Gson;
import java.io.IOException;
import de.robv.android.xposed.IXposedHookLoadPackage; import de.robv.android.xposed.XC_MethodHook; import de.robv.android.xposed.XposedHelpers; import de.robv.android.xposed.callbacks.XC_LoadPackage; import okhttp3.MediaType; import okhttp3.OkHttpClient; import okhttp3.Request; import okhttp3.RequestBody; import okhttp3.Response;
public class HookCxs implements IXposedHookLoadPackage { @Override public void handleLoadPackage(XC_LoadPackage.LoadPackageParam loadPackageParam) throws Throwable { XposedHelpers.findAndHookMethod("com.shizhuang.duapp.modules.du_mall_common.utils.product.BaseMallProductItemView", loadPackageParam.classLoader, "update", new Object[]{Object.class, new XC_MethodHook() { protected void beforeHookedMethod(XC_MethodHook.MethodHookParam param) throws Throwable { super.beforeHookedMethod(param); }
protected void afterHookedMethod(XC_MethodHook.MethodHookParam param) throws Throwable { super.afterHookedMethod(param); Object resultObj = param.args[0]; Gson gson = new Gson(); String resultObjStr = gson.toJson(resultObj); Log.d("cxs", resultObjStr); sendJsonData(resultObjStr); } }}); }
private void sendJsonData(String data) { new Thread(() -> { try { String url = "http://10.0.248.77:1427/dewu-hook"; OkHttpClient client = new OkHttpClient(); RequestBody body = RequestBody.create(data, MediaType.get("application/json; charset=utf-8")); Request request = new Request.Builder() .url(url) .post(body) .build(); Response response = client.newCall(request).execute(); if (response.isSuccessful()) { String responseBody = response.body().string(); Log.d("cxs", "JSON POST Response: " + responseBody); } else { Log.e("cxs", "JSON POST Error response: " + response.code() + " " + response.message()); } } catch (IOException e) { e.printStackTrace(); Log.e("cxs", "JSON POST Error", e); } }).start(); } }
|
gradle 依赖
1 2 3
| compileOnly(files("libs\\XposedBridgeAPI-89.jar")) implementation("com.google.code.gson:gson:2.8.6") implementation("com.squareup.okhttp3:okhttp:4.9.0")
|
Hook 技巧
xposed rpc:https://juejin.cn/post/6970958353673486343
渲染 / 视图组件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| public class MyXposedModule implements IXposedHookLoadPackage { @Override public void handleLoadPackage(final LoadPackageParam lpparam) throws Throwable { if ("目标应用包名".equals(lpparam.packageName)) { XposedHelpers.findAndHookMethod( View.class, "setOnTouchListener", new XC_MethodHook() { @Override protected void afterHookedMethod(MethodHookParam param) throws Throwable { super.afterHookedMethod(param); View view = (View) param.thisObject; System.out.println("View touched: " + view); } } ); } } }
|
指定类下所有方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| XposedHelpers.findAndHookMethod(ClassLoader.class, "loadClass", String.class, new XC_MethodHook() { @Override protected void afterHookedMethod(MethodHookParam param) throws Throwable { super.afterHookedMethod(param); Class clazz = (Class) param.getResult(); String clazzName = clazz.getName(); if(clazzName.equals("com.shizhuang.duapp.modules.du_mall_common.utils.product.BaseMallProductItemView")){ Method[] mds = clazz.getDeclaredMethods(); for(int i =0;i<mds.length;i++){ final Method md = mds[i]; int mod = mds[i].getModifiers(); if(!Modifier.isAbstract(mod) && !Modifier.isNative(mod) &&!Modifier.isAbstract(mod)){ XposedBridge.hookMethod(mds[i], new XC_MethodHook() { @Override protected void beforeHookedMethod(MethodHookParam param) throws Throwable { super.beforeHookedMethod(param); Log.d("cxs_call", "传参:" + param.args[0].toString()); Log.d("cxs_call", "方法:" + md.toString()); } }); }
} }
} });
|