一直耳闻xposed无所不能,今天体验了一把,果然如其名。
背景,最近在琢磨一款混合开发的游戏资讯app(假定为测试app)的架构模式,抓包发现接口返回的是html内容片段,片段里没有完整的样式定义。但观察页面明显的有样式效果。反编译app在assets目录下发现了样式文件,js文件和一些模板文件,想要进一步了解app是怎样把html代码片段和样式文件,js文件,模板文件组合在一起。最直接的是把组合之后的html源码跟html片段和模板文件比对。刚好android webiew的远程调试工具可以做到查看webview加载的网页源码。so 最后的重点是如何开启webview的调试开关。
1所需工具:root过的手机(由于嫌root手机麻烦,我使用的是雷电模拟器3.66);xposed框架和对应版本的xposedapi jar,android studio,合作方app。
使用步骤
1.下载xposed框架(xposed installed)并安装。
xposed框架是一个app,安装后启动app,点击 Version 89安装/更新,弹出的对话框中点击安装。安装时需要授权root权选,点击永久授权,安装结束后,会自动重启系统。(雷电模拟器重启时间特别长,直接关掉模拟器重新打开,夜神模拟器则可以正常重启)
重启后如果安装成功则显示下面的界面
2.编写hook代码模块
xposed api 提供了hook的api,我们只需要按照自己的需求调用即可。
android studio里新建android项目,把xposedapi jar拷贝的项目的libs目录,在build.gradle文件的dependencies模块添加对xposedapi.jar的依赖,compileOnly files('libs/api-82.jar');如下图:
配置manifest:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.wellxq.xqxposedhook">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme" >
<meta-data
android:name="xposedmodule"
android:value="true" />
<meta-data
android:name="xposeddescription"
android:value="调试x5浏览器" />
<meta-data
android:name="xposedminversion"
android:value="53" />
</application>
</manifest>
编写hook代码,开启webview的debug模式。
新建java类,实现IXposedHookLoadPackage接口,在handleLoadPackage里实现业务逻辑。
确保能调用setWebContentsDebuggingEnabled方法开启debug模式,最好在 webview的构造方法方法里调用,因此我们需要hook webview的构造方法。代码如下:
package com.wellxq.xqxposedhook;
import android.util.Log;
import android.webkit.WebView;
import de.robv.android.xposed.IXposedHookLoadPackage;
import de.robv.android.xposed.XC_MethodHook;
import de.robv.android.xposed.XposedBridge;
import de.robv.android.xposed.XposedHelpers;
import de.robv.android.xposed.callbacks.XC_LoadPackage;
public class HookZhangyu implements IXposedHookLoadPackage {
private final String TAG = "HookZhangyu";
private final String ZHANG_YU_PACKAGE_NAME = "net.ali213.YX";// xx网
private final String HOOK_METHOD_NAME = "shouldOverrideUrlLoading";
private final String HOOK_CLASS_NAME = "android.webkit.WebViewClient"
;
private final String HOOK_CLASS_NAME_X5 = "com.tencent.smtt.sdk.WebViewClient";
@Override
public void handleLoadPackage(XC_LoadPackage.LoadPackageParam loadPackageParam) throws Throwable {
if(!loadPackageParam.packageName.equals(ZHANG_YU_PACKAGE_NAME)) {
XposedBridge.log(TAG+"|"+"我抓到你了:"+loadPackageParam.packageName);
return;
}
XposedBridge.hookAllConstructors(WebView.class, new XC_MethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
super.beforeHookedMethod(param);
XposedHelpers.callStaticMethod(WebView.class, "setWebContentsDebuggingEnabled", true);
XposedBridge.log("WebViewHook new WebView()xxxxx: " + param.args);
}
@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
super.afterHookedMethod(param);
}
});
}
}
3 .安装启用模块
代码编写完了,点击android studio工具栏的绿色三角形将模块安装到模拟器,如下图:
模块安装成功后,在模拟器中打开 xposed installer app可以在下面的目录中找到刚刚安装的模块,
点击模块右边的小方框,启用模块。然后打开我们要调试的app(本文开始提到的游戏资讯app(测试app)),打开资讯详情页面。这时再在xposed installer中的日志中看到有之前编写代码时hook成功后打日志WebViewHook new WebView()xxxxx,就说明webview的调试开关已经打开。接下来可以使用webview的远程调试工具查看测试app的webview加载的网页源码了。