1. 创建Xposed工程
在Android Studio中新建一个app工程,修改其中的 AndroidManifest.xml 文件,在<application></application>标签中增加如下代码
<meta-data
android:name="xposedmodule"
android:value="true" />
<meta-data
android:name="xposeddescription"
android:value="hello xposed" />
<meta-data
android:name="xposedminversion"
android:value="82" />
在 app/libs 目录下添加Xposed的依赖库,api-82.jar, api-82-sources.jar(网上自行搜索)
修改 app 目录下的 build.gradle 文件,将以上的两个依赖库添加到 dependencies{} 中,如下
dependencies {
compileOnly 'de.robv.android.xposed:api:82'
compileOnly 'de.robv.android.xposed:api:82:sources'
// other content
......
}
在 mian 目录下创建一个assets文件夹,并在assets目录下创建一个 xposed_init 文件,文件中写入实现了 IXposedHookLoadPackage 接口的类名及包名;例如我当前新建了一个类 TestReverse 实现了 IXposedHookLoadPackage 接口,且当前包名为 com.test.xposed,则 xposed_init 中的内容应为
com.test.xposed.TestReverse
2. 相关API介绍
Xposed 模块API用法:XposedHelpers | Xposed Framework API
a.IXposedHookLoadPackage 接口,实现hook逻辑的类必须实现该接口,APP被加载的时候会调用该接口中的 handleLoadPackage(final XC_LoadPackage.LoadPackageParam lpparam) 方法,所以我们需要重写该函数,并在其中实现我们的hook逻辑
b.XC_LoadPackage.LoadPackageParam,该类下包含与正在加载的应用程序的有关信息。入下,其中packageName可以用于判断当前hook住的APP名称,processName表示当前APP所在的进程,classLoader表示当前APP使用的ClassLoader。
c.XposedHelpers类
1.findClass(String className, ClassLoader classLoader),使用特定的ClassLoader查找指定类,返回值为指定类的class;使用如下
final Class<?> callContextClass = XposedHelpers.findClass("com.alibaba.ariver.engine.api.bridge.model.NativeCallContext",lpparam.classLoader);
2.XposedHelpers.findAndHookMethod(String className, ClassLoader classLoader, String methodName, Object... parameterTypesAndCallback),hook指定的方法。
其中 Object... parameterTypesAndCallback是java中的范式,可以传递多个参数;当使用XposedHelpers.findAndHookMethod()方法时,需要传递被hook的函数所需要的全部参数的字节码,这些字节码可以通过.class获取到,或者findClass反射获取;java自带的类型比如String,就可以用String.class获取到。
回调对象XC_MethodHook()需重写两个方法 beforeHookedMethod(MethodHookParam param):这个方法中的代码逻辑会在hook住的方法调用前执行 ;afterHookedMethod(MethodHookParam param) 方法中的代码逻辑则会在hook住的方法调用完成后执行。
使用如下,以下代码逻辑表示,在com.baidu.swan.apps.jsbridge.SwanAppGlobalJsBridge 类下的 dispatchOnUiThread() 函数已经被hook住,在这个函数执行前后,beforeHookedMethod() 和 afterHookedMethod() 中的逻辑会分别执行。
XposedHelpers.findAndHookMethod("com.baidu.swan.apps.jsbridge.SwanAppGlobalJsBridge", lpparam.classLoader, "dispatchOnUiThread", String.class, new XC_MethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
super.beforeHookedMethod(param);
XposedBridge.log("Baidu: dispatchOnUiThread 的线程:" + Thread.currentThread().getName());
XposedBridge.log("Baidu:dispatchOnUiThread 入参:" + java.net.URLDecoder.decode(param.args[0].toString()) + "返回值:" + param.getResult());
}
@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
super.afterHookedMethod(param);
Field mCallbackHandler = jsbridge_a.getDeclaredField("mCallbackHandler");
Object mmCallbackHandler = (Object) mCallbackHandler.get(param.thisObject);
//com.baidu.swan.apps.core.slave.SwanAppWebViewWidget
XposedBridge.log("Baidu: mCallbackHandler在webview里调用API时的实现类:" + mmCallbackHandler.getClass().getName());
});
3. XposedHelpers.findAndHookConstructor(String className,