xposed调试百度小程序的插件

起因

一直以来对小程序的架构和设计都比较感兴趣,因为各家都没有开源(据说百度小程序18年12月份全面开源),很多技术细节只能靠猜测,最多能看到小程序打包压缩文件,小程序是基于B/S架构的,在浏览器里面的DOM到底是咋样的呢?如果是自家程序的话,直接开始webView调试就好,基本上线上的程序都关闭了调试入口。怎么办呢,该我们无所不能的xposed出场了,接下来就该分析hook的入口了。

分析

百度小程序对应的Activity类是com.baidu.searchbox.ng.ai.apps.AiAppsActivity, 通过反编译源码,看到AiAppsActivity.onCreate()方法有这么一段代码:

if (com.baidu.searchbox.ng.ai.apps.core.a.bzr()) {  
    WebView.setWebContentsDebuggingEnabled(true);
}

好眼熟的代码,这不就是开启inspect调试的方法吗?话不多说,直接用xposed hook这个方法跳过判断。

XposedHelpers.findAndHookMethod("com.baidu.searchbox.ng.ai.apps.core.a",  
                loadPackageParam.classLoader, "bzr",
                new XC_MethodHook() {
                    @Override
                    protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
                        XposedBridge.log("@@@#bzr:" + packageName + ", obj=" +
                        param.thisObject + ", method=" + param.method);
                        super.beforeHookedMethod(param);
                    }

                    @Override
                    protected void afterHookedMethod(MethodHookParam param) throws Throwable {
                        super.afterHookedMethod(param);
                        XposedBridge.log("@@@#bzr setResult:" + packageName);
                        param.setResult(true);
                    }


                });

安装插件运行,oh my god还是不行。确实通过UIAutoMator Viewer看到的小程序WebView是基于百度的T7内核实现的,并不是系统webView,所以就算开启了setWebContentsDebuggingEnabled也没什么用。

基本上各家的浏览器内核都做了保护,内核加载失败的时候都会加载系统WebView,T7也不例外。那就想办法关掉T7内核呗。开启关闭T7内核的方法如下(别问我为什么知道!):BdSailor.getInstance().setWebkitEnable(true);

那就找找代码里面哪里开启了T7呗。找到了3个类。a.java,BdSailor.java,CommonIntentService.java, 分析过程就不详细说明了,在a.java里面有我们要的关键代码:

BdSailor.getInstance().init(this.mContext, null, ns.getUid());  
            boolean z = com.baidu.searchbox.config.c.ZS().getBoolean("USE_SYS_WEBKIT", false) || com.baidu.searchbox.ng.browser.a.a.a.bHi();
            if (z) {
                if (DEBUG) {
                    Log.d("BlinkAbTestManager", "doInitBWebkit use sys webview.");
                }
                BdSailor.getInstance().setWebkitEnable(false);
                if (DEBUG) {
                    new Handler(Looper.getMainLooper()).post(new a$2(this));
                }
            }

用来判断是否禁用T7内核的,啥都不说,xposed直接hook让直接返回true

XposedHelpers.findAndHookMethod("com.baidu.searchbox.ng.browser.a.a.a",  
                loadPackageParam.classLoader, "bHi",
                new XC_MethodHook() {
                    @Override
                    protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
                        XposedBridge.log("@@@#bHi:" + packageName + ", obj=" +
                                param.thisObject + ", method=" + param.method);
                        super.beforeHookedMethod(param);
                    }

                    @Override
                    protected void afterHookedMethod(MethodHookParam param) throws Throwable {
                        super.afterHookedMethod(param);
                        XposedBridge.log("@@@#bHi setResult:" + packageName);
                        param.setResult(true);
                    }


                });

完美解决问题,百度App没有启用T7内核。可以愉快的输入:chrome://inspect/#devices调试了

完整代码

public class WebViewHook implements IXposedHookLoadPackage {

    @Override
    public void handleLoadPackage(XC_LoadPackage.LoadPackageParam loadPackageParam) throws Throwable {

        final String packageName = loadPackageParam.packageName;

        XposedBridge.hookAllConstructors(WebView.class, new XC_MethodHook() {
            @Override
            protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
                XposedHelpers.callStaticMethod(WebView.class, "setWebContentsDebuggingEnabled", true);
            }
        });

        XposedBridge.hookAllMethods(WebView.class, "setWebContentsDebuggingEnabled", new XC_MethodHook() {
            @Override
            protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
                param.args[0] = true;
            }
        });

        Class fieldClass = loadPackageParam.classLoader.loadClass("com.baidu.searchbox.k");
        if (fieldClass != null) {
            XposedHelpers.setStaticBooleanField(fieldClass, "GLOBAL_DEBUG", true);
        }

        XposedHelpers.findAndHookMethod("com.baidu.searchbox.ng.ai.apps.core.a",
                loadPackageParam.classLoader, "bzr",
                new XC_MethodHook() {
                    @Override
                    protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
                        XposedBridge.log("@@@#bzr:" + packageName + ", obj=" +
                        param.thisObject + ", method=" + param.method);
                        super.beforeHookedMethod(param);
                    }

                    @Override
                    protected void afterHookedMethod(MethodHookParam param) throws Throwable {
                        super.afterHookedMethod(param);
                        XposedBridge.log("@@@#bzr setResult:" + packageName);
                        param.setResult(true);
                    }


                });


        XposedHelpers.findAndHookMethod("com.baidu.searchbox.ng.browser.a.a.a",
                loadPackageParam.classLoader, "bHi",
                new XC_MethodHook() {
                    @Override
                    protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
                        XposedBridge.log("@@@#bHi:" + packageName + ", obj=" +
                                param.thisObject + ", method=" + param.method);
                        super.beforeHookedMethod(param);
                    }

                    @Override
                    protected void afterHookedMethod(MethodHookParam param) throws Throwable {
                        super.afterHookedMethod(param);
                        XposedBridge.log("@@@#bHi setResult:" + packageName);
                        param.setResult(true);
                    }


                });

        XposedHelpers.findAndHookMethod("com.baidu.browser.sailor.BdSailor",
                loadPackageParam.classLoader, "setWebkitEnable", boolean.class,
                new XC_MethodHook() {
                    @Override
                    protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
                        param.args[0] = false;
                        XposedBridge.log("@@@#setWebkitEnable:" + packageName);
                        super.beforeHookedMethod(param);
                    }
                });
    }
}

参考文档