debug_wechat_send7.js 6.4 KB
/**
 * Frida debug script v7 — deep inspect u01.g2 and u01.f2 constructor
 */

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

function deepInspect(obj, tag, depth) {
    if (!obj || depth <= 0) return;
    var cls = obj.getClass();
    log(tag, "class=" + cls.getName());

    var fields = cls.getDeclaredFields();
    for (var i = 0; i < fields.length; i++) {
        var f = fields[i];
        f.setAccessible(true);
        try {
            var val = f.get(obj);
            if (val === null) {
                log(tag, "  " + f.getName() + " = null [" + f.getType().getName() + "]");
            } else if (f.getType().getName() === "java.lang.String") {
                log(tag, "  " + f.getName() + " = \"" + val + "\" [String]");
            } else if (f.getType().getName() === "int" || f.getType().getName() === "long") {
                log(tag, "  " + f.getName() + " = " + val + " [" + f.getType().getName() + "]");
            } else if (f.getType().getName() === "boolean") {
                log(tag, "  " + f.getName() + " = " + val + " [boolean]");
            } else if (f.getType().getName().startsWith("[L")) {
                log(tag, "  " + f.getName() + " = array [" + f.getType().getName() + "]");
            } else {
                log(tag, "  " + f.getName() + " = " + val.toString().substring(0, 80) + " [" + f.getType().getName() + "]");
            }
        } catch (e) {
            log(tag, "  " + f.getName() + " [error: " + e + "]");
        }
    }

    // Also inspect methods
    var methods = cls.getDeclaredMethods();
    for (var i = 0; i < methods.length; i++) {
        var m = methods[i];
        if (m.getModifiers() & 0x0001) { // public
            var params = "";
            var pts = m.getParameterTypes();
            for (var j = 0; j < pts.length; j++) {
                params += pts[j].getName() + ",";
            }
            log(tag, "  method: " + m.getName() + "(" + params + ") -> " + m.getReturnType().getName());
        }
    }
}

Java.perform(function () {
    log("MAIN", "Inspecting u01.g2 and u01.f2...");

    try {
        var f2 = Java.use("u01.f2");
        var constructors = f2.class.getDeclaredConstructors();
        for (var i = 0; i < constructors.length; i++) {
            var ctor = constructors[i];
            var params = ctor.getParameterTypes();
            var sig = "";
            for (var j = 0; j < params.length; j++) {
                sig += params[j].getName() + ",";
            }
            log("MAIN", "u01.f2 constructor: (" + sig + ")");
        }
    } catch (e) {
        log("MAIN", "f2 constructor error: " + e);
    }

    try {
        var g2 = Java.use("u01.g2");
        var constructors = g2.class.getDeclaredConstructors();
        for (var i = 0; i < constructors.length; i++) {
            var ctor = constructors[i];
            var params = ctor.getParameterTypes();
            var sig = "";
            for (var j = 0; j < params.length; j++) {
                sig += params[j].getName() + ",";
            }
            log("MAIN", "u01.g2 constructor: (" + sig + ")");
        }
        log("MAIN", "u01.g2 methods:");
        var methods = g2.class.getDeclaredMethods();
        for (var i = 0; i < methods.length; i++) {
            var m = methods[i];
            if (m.getModifiers() & 0x0001) {
                var params = "";
                var pts = m.getParameterTypes();
                for (var j = 0; j < pts.length; j++) {
                    params += pts[j].getName() + ",";
                }
                log("MAIN", "  " + m.getName() + "(" + params + ") -> " + m.getReturnType().getName());
            }
        }
    } catch (e) {
        log("MAIN", "g2 inspect error: " + e);
    }

    // Hook f2 constructor to capture g2 instance
    try {
        var f2cls = Java.use("u01.f2");
        var ctors = f2cls.class.getDeclaredConstructors();
        for (var i = 0; i < ctors.length; i++) {
            var ctor = ctors[i];
            var ptypes = ctor.getParameterTypes();
            var overloadSig = [];
            for (var j = 0; j < ptypes.length; j++) {
                overloadSig.push(ptypes[j].getName());
            }
            log("MAIN", "Hooking f2 constructor overload: " + overloadSig.join(","));

            // Use Frida's overload system
            try {
                if (overloadSig.length === 1) {
                    f2cls.$init.overload(overloadSig[0]).implementation = function(arg0) {
                        log("F2_CTOR", "u01.f2 created with 1 arg: " + arg0);
                        if (arg0) {
                            deepInspect(arg0, "G2_INSIDE", 1);
                        }
                        this.$init(arg0);
                    };
                } else if (overloadSig.length === 2) {
                    f2cls.$init.overload(overloadSig[0], overloadSig[1]).implementation = function(arg0, arg1) {
                        log("F2_CTOR", "u01.f2 created with 2 args");
                        if (arg0) deepInspect(arg0, "G2_INSIDE", 1);
                        this.$init(arg0, arg1);
                    };
                } else if (overloadSig.length === 3) {
                    f2cls.$init.overload(overloadSig[0], overloadSig[1], overloadSig[2]).implementation = function(arg0, arg1, arg2) {
                        log("F2_CTOR", "u01.f2 created with 3 args");
                        if (arg0) deepInspect(arg0, "G2_INSIDE", 1);
                        this.$init(arg0, arg1, arg2);
                    };
                }
            } catch (e) {
                log("MAIN", "Failed to hook constructor: " + e);
            }
        }
    } catch (e) {
        log("MAIN", "f2 constructor hook error: " + e);
    }

    // Also hook f2.run to show full g2 fields
    try {
        var f2cls = Java.use("u01.f2");
        f2cls.run.implementation = function() {
            log("F2_RUN", "===== u01.f2.run() =====");
            try {
                var dField = this.getClass().getDeclaredField("d");
                dField.setAccessible(true);
                var g2 = dField.get(this);
                if (g2) {
                    deepInspect(g2, "G2_FULL", 2);
                }
            } catch (e) {
                log("F2_RUN", "Failed to get d field: " + e);
            }
            this.run();
            log("F2_RUN", "===== done =====");
        };
    } catch (e) {
        log("MAIN", "f2.run hook error: " + e);
    }

    log("MAIN", "All hooks installed. Send a message manually.");
});