debug_builder_class.js 4.02 KB
/**
 * Debug script: verify builder class name when calling u01.r1.a("yibooo")
 *
 * Run on Mac:
 *   frida -U -n com.tencent.mm -l debug_builder_class.js
 *
 * This script will:
 *   1. Call u01.r1.a("yibooo") and print builder.getClass().getName()
 *   2. Print builder class hierarchy
 *   3. Test method calls via both builder.getClass() and Java.use("u01.q1")
 *   4. Check if setIntField("f", 0) / ("i", 4) causes any issue
 */

function log(msg) {
    console.log("[DebugBuilder] " + msg);
}

Java.perform(function () {
    var toUser = "yibooo";
    var content = "test msg from frida debug";

    try {
        var r1 = Java.use("u01.r1");
        var builder = r1.a(toUser);

        var builderClass = builder.getClass();
        var className = builderClass.getName();
        log("builder.getClass().getName() = " + className);

        // Print hierarchy
        var superClass = builderClass.getSuperclass();
        while (superClass) {
            log("  extends: " + superClass.getName());
            superClass = superClass.getSuperclass();
        }

        // Check if it's exactly u01.q1 or a subclass
        var isExactQ1 = (className === "u01.q1");
        log("Is exactly u01.q1? " + isExactQ1);

        // List all declared methods of the actual class
        var methods = builderClass.getDeclaredMethods();
        log("Declared methods on " + className + ":");
        for (var i = 0; i < methods.length; i++) {
            var m = methods[i];
            if (m.getName() === "e" || m.getName() === "h" || m.getName() === "a") {
                log("  " + m.getName() + "(" + m.getParameterTypes().map(function(t){return t.getName();}).join(", ") + ") -> " + m.getReturnType().getName());
            }
        }

        // Test 1: Call via builder.getClass().getMethod() (same as LSPosed)
        log("\n--- Test 1: builder.getClass().getMethod() ---");
        try {
            var m_e = builderClass.getMethod("e", java.lang.String.class);
            var m_h = builderClass.getMethod("h", java.lang.Integer.TYPE);
            var m_a = builderClass.getMethod("a");

            m_e.invoke(builder, content);
            log("  e() OK");

            m_h.invoke(builder, 0);
            log("  h(0) OK");

            // Try setIntField equivalent via reflection
            try {
                var f_field = builderClass.getDeclaredField("f");
                f_field.setAccessible(true);
                f_field.setInt(builder, 0);
                log("  set f=0 OK");
            } catch (f_err) {
                log("  set f=0 FAILED: " + f_err);
            }

            try {
                var i_field = builderClass.getDeclaredField("i");
                i_field.setAccessible(true);
                i_field.setInt(builder, 4);
                log("  set i=4 OK");
            } catch (i_err) {
                log("  set i=4 FAILED: " + i_err);
            }

            var result1 = m_a.invoke(builder);
            log("  a() result class: " + result1.getClass().getName());

            var submit1 = result1.getClass().getMethod("a");
            var ret1 = submit1.invoke(result1);
            log("  submit result: " + ret1);

        } catch (e) {
            log("Test 1 FAILED: " + e);
            if (e.getCause) log("  cause: " + e.getCause());
        }

        // Test 2: Call via Java.use("u01.q1") (same as working frida code)
        log("\n--- Test 2: Java.use(\"u01.q1\") ---");
        try {
            var builder2 = r1.a(toUser);
            var q1 = Java.use("u01.q1");
            q1.e.call(builder2, content);
            log("  q1.e() OK");
            q1.h.call(builder2, 0);
            log("  q1.h(0) OK");
            var result2 = q1.a.call(builder2);
            log("  q1.a() result class: " + result2.getClass().getName());
            var m1cls = Java.use("u01.m1");
            var ret2 = m1cls.a.call(result2);
            log("  submit result: " + ret2);
        } catch (e) {
            log("Test 2 FAILED: " + e);
        }

        log("\n--- Done ---");

    } catch (e) {
        log("Overall FAILED: " + e);
    }
});