debug_provider.js 5.21 KB
// Frida script to debug WeChat ContentProvider
// Hook ExtControlProviderMsg and ExtContentProviderBase to understand why query/insert return null

Java.perform(function() {
    var TAG = "HermesProvider";

    function logMethodCalls(clsName) {
        try {
            var cls = Java.use(clsName);
            var methods = cls.class.getDeclaredMethods();
            methods.forEach(function(m) {
                var sig = m.getName() + "(" + m.getParameterTypes().map(function(p) { return p.getName(); }).join(", ") + ")";
                console.log("[Provider] " + clsName + " method: " + sig);
            });
        } catch(e) {
            console.log("[Provider] Cannot list methods for " + clsName + ": " + e);
        }
    }

    // Hook ExtContentProviderBase methods
    try {
        var base = Java.use("com.tencent.mm.plugin.ext.provider.ExtContentProviderBase");

        base.h.implementation = function() {
            var ret = this.h();
            console.log("[Provider] ExtContentProviderBase.h() -> " + ret);
            return 1;
        };

        base.b.implementation = function() {
            var ret = this.b();
            console.log("[Provider] ExtContentProviderBase.b() -> " + ret);
            return true;
        };

        try {
            base.i.overload("android.content.Context").implementation = function(ctx) {
                var ret = this.i(ctx);
                console.log("[Provider] ExtContentProviderBase.i(ctx) -> " + ret);
                return true;
            };
        } catch(e) {}

        console.log("[Provider] ExtContentProviderBase hooks installed");
    } catch(e) {
        console.log("[Provider] ExtContentProviderBase hook failed: " + e);
    }

    // Hook ExtControlProviderMsg
    try {
        var msgProvider = Java.use("com.tencent.mm.plugin.ext.provider.ExtControlProviderMsg");

        msgProvider.query.overload("android.net.Uri", "[Ljava.lang.String;", "java.lang.String", "[Ljava.lang.String;", "java.lang.String").implementation = function(uri, projection, selection, selectionArgs, sortOrder) {
            console.log("[Provider] query called:");
            console.log("  uri=" + uri);
            console.log("  projection=" + (projection ? projection.join(",") : "null"));
            console.log("  selection=" + selection);
            console.log("  selectionArgs=" + (selectionArgs ? selectionArgs.join(",") : "null"));
            console.log("  sortOrder=" + sortOrder);
            var ret = this.query(uri, projection, selection, selectionArgs, sortOrder);
            console.log("[Provider] query returned: " + ret);
            return ret;
        };

        msgProvider.insert.overload("android.net.Uri", "android.content.ContentValues").implementation = function(uri, values) {
            console.log("[Provider] insert called:");
            console.log("  uri=" + uri);
            console.log("  values=" + values);
            if (values) {
                var keys = values.keySet().toArray();
                for (var i = 0; i < keys.length; i++) {
                    var k = keys[i];
                    var v = values.get(k);
                    console.log("    " + k + "=" + v);
                }
            }
            var ret = this.insert(uri, values);
            console.log("[Provider] insert returned: " + ret);
            return ret;
        };

        msgProvider.call.overload("java.lang.String", "java.lang.String", "android.os.Bundle").implementation = function(method, arg, extras) {
            console.log("[Provider] call called: method=" + method + " arg=" + arg + " extras=" + extras);
            var ret = this.call(method, arg, extras);
            console.log("[Provider] call returned: " + ret);
            return ret;
        };

        console.log("[Provider] ExtControlProviderMsg hooks installed");
    } catch(e) {
        console.log("[Provider] ExtControlProviderMsg hook failed: " + e);
    }

    // Also hook all ContentProvider query/insert methods to catch any provider
    try {
        var ContentProvider = Java.use("android.content.ContentProvider");

        ContentProvider.query.overload("android.net.Uri", "[Ljava.lang.String;", "java.lang.String", "[Ljava.lang.String;", "java.lang.String").implementation = function(uri, projection, selection, selectionArgs, sortOrder) {
            var uriStr = uri ? uri.toString() : "null";
            if (uriStr.indexOf("ext") !== -1 || uriStr.indexOf("tencent.mm") !== -1) {
                console.log("[Provider] ANY query: uri=" + uriStr);
            }
            return this.query(uri, projection, selection, selectionArgs, sortOrder);
        };

        ContentProvider.insert.overload("android.net.Uri", "android.content.ContentValues").implementation = function(uri, values) {
            var uriStr = uri ? uri.toString() : "null";
            if (uriStr.indexOf("ext") !== -1 || uriStr.indexOf("tencent.mm") !== -1) {
                console.log("[Provider] ANY insert: uri=" + uriStr);
            }
            return this.insert(uri, values);
        };

        console.log("[Provider] Global ContentProvider hooks installed");
    } catch(e) {
        console.log("[Provider] Global hook failed: " + e);
    }

    console.log("[Provider] Script loaded. Send a message to trigger provider calls.");
});