/** * Frida debug script v9 — trace u01.r1, u01.q1, u01.m1 during manual send * Also trace a2 methods and WCDB to confirm the real path */ function log(tag, msg) { console.log("[" + tag + "] " + msg); } function printStack(tag) { try { var Thread = Java.use("java.lang.Thread"); var stack = Thread.currentThread().getStackTrace(); var lines = []; for (var i = 0; i < stack.length; i++) { lines.push(" at " + stack[i].toString()); } console.log("[" + tag + " STACK]\n" + lines.join("\n") + "\n[END STACK]"); } catch (e) { console.log("[" + tag + " STACK] failed: " + e + "\n[END STACK]"); } } Java.perform(function () { log("MAIN", "Tracing u01.r1/q1/m1 and a2 during manual send..."); // Hook u01.r1.a(String) try { var r1 = Java.use("u01.r1"); r1.a.overload("java.lang.String").implementation = function(toUser) { log("R1", "u01.r1.a(\"" + toUser + "\") called"); printStack("R1"); return this.a(toUser); }; log("MAIN", "u01.r1.a(String) hooked"); } catch (e) { log("MAIN", "u01.r1 hook failed: " + e); } // Hook u01.q1.e(String) content setter try { var q1 = Java.use("u01.q1"); q1.e.overload("java.lang.String").implementation = function(content) { log("Q1", "u01.q1.e(\"" + content.substring(0, 30) + "\") called"); printStack("Q1_E"); return this.e(content); }; log("MAIN", "u01.q1.e(String) hooked"); } catch (e) { log("MAIN", "u01.q1.e hook failed: " + e); } // Hook u01.q1.a() build method try { var q1 = Java.use("u01.q1"); q1.a.overload().implementation = function() { log("Q1", "u01.q1.a() build called"); printStack("Q1_A"); return this.a(); }; log("MAIN", "u01.q1.a() hooked"); } catch (e) { log("MAIN", "u01.q1.a() hook failed: " + e); } // Hook u01.m1.a() submit method try { var m1 = Java.use("u01.m1"); m1.a.overload().implementation = function() { log("M1", "u01.m1.a() called"); printStack("M1"); return this.a(); }; log("MAIN", "u01.m1.a() hooked"); } catch (e) { log("MAIN", "u01.m1.a() hook failed: " + e); } // Hook a2.b() which was in the real send stack try { var a2 = Java.use("com.tencent.mm.plugin.messenger.foundation.a2"); a2.b.overload("com.tencent.mm.modelbase.p0", "f35.pu4", "ef3.z4").implementation = function(p0, pu4, z4) { log("A2", "a2.b() called"); printStack("A2_B"); return this.b(p0, pu4, z4); }; log("MAIN", "a2.b() hooked"); } catch (e) { log("MAIN", "a2.b() hook failed: " + e); } // Hook a2.c() try { var a2 = Java.use("com.tencent.mm.plugin.messenger.foundation.a2"); a2.c.overload("f35.i4", "java.lang.Object", "int", "f35.pu4", "ef3.z4").implementation = function(i4, obj, i, pu4, z4) { log("A2", "a2.c() called"); printStack("A2_C"); return this.c(i4, obj, i, pu4, z4); }; log("MAIN", "a2.c() hooked"); } catch (e) { log("MAIN", "a2.c() hook failed: " + e); } // Hook az0.l.l() which was in the real stack try { var l_cls = Java.use("az0.l"); var methods = l_cls.class.getDeclaredMethods(); for (var i = 0; i < methods.length; i++) { var m = methods[i]; if (m.getName() === "l" && m.getModifiers() & 0x0001) { var params = m.getParameterTypes(); var sig = ""; for (var j = 0; j < params.length; j++) { sig += params[j].getName() + ","; } log("MAIN", "az0.l.l() signature: (" + sig + ")"); break; } } } catch (e) { log("MAIN", "az0.l inspect failed: " + e); } // Hook WCDB insert try { var SQLiteDatabase = Java.use("com.tencent.wcdb.database.SQLiteDatabase"); SQLiteDatabase.insert.overload('java.lang.String', 'java.lang.String', 'android.content.ContentValues').implementation = function(table, nullCol, values) { if (table && table.toLowerCase().indexOf("message") !== -1) { var isSend = values ? values.getAsInteger("isSend") : null; var talker = values ? values.getAsString("talker") : null; if (isSend && isSend == 1) { log("WCDB", "INSERT SEND talker=" + talker); printStack("WCDB_SEND"); } } return this.insert(table, nullCol, values); }; log("MAIN", "WCDB hooked"); } catch (e) { log("MAIN", "WCDB hook failed: " + e); } log("MAIN", "All hooks installed. Send a message manually."); });