From a94d8cb84221d92d682807e511b4984b352a39c1 Mon Sep 17 00:00:00 2001 From: fnvtk Date: Mon, 18 May 2026 22:03:13 +0800 Subject: [PATCH] =?UTF-8?q?[v9]=20=E4=B8=8A=E4=BC=A0=20wechat=5Fsend=5Fhoo?= =?UTF-8?q?k.js?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sdk/agent/hook/wechat_send_hook.js | 135 +++++++++++++++++++++++++++++ 1 file changed, 135 insertions(+) create mode 100644 sdk/agent/hook/wechat_send_hook.js diff --git a/sdk/agent/hook/wechat_send_hook.js b/sdk/agent/hook/wechat_send_hook.js new file mode 100644 index 0000000000..10f3e62988 --- /dev/null +++ b/sdk/agent/hook/wechat_send_hook.js @@ -0,0 +1,135 @@ +// 微信8.0.56 消息真实发送Hook脚本 +// 策略:Hook OkHttp网络层,捕获微信发送消息的真实HTTP请求,然后重放 + +'use strict'; + +var capturedSendRequests = []; +var sendClassFound = null; +var sendMethodFound = null; +var isReady = false; + +// 等待微信完全初始化 +Java.perform(function() { + + // 1. Hook OkHttp3 - 捕获所有网络请求 + try { + var OkHttpClient = Java.use('okhttp3.OkHttpClient'); + var Request = Java.use('okhttp3.Request'); + var RequestBody = Java.use('okhttp3.RequestBody'); + + // Hook newCall + OkHttpClient.newCall.implementation = function(request) { + var url = request.url().toString(); + if (url.indexOf('weixin') > -1 || url.indexOf('tencent') > -1 || url.indexOf('wx') > -1) { + var method = request.method(); + var body = ''; + try { + var rb = request.body(); + if (rb != null) { + var buf = Java.use('okio.Buffer').$new(); + rb.writeTo(buf); + body = buf.readUtf8(); + } + } catch(e) {} + + capturedSendRequests.push({ + url: url, + method: method, + body: body.substring(0, 500), + time: Date.now() + }); + + if (capturedSendRequests.length > 50) { + capturedSendRequests.shift(); + } + } + return this.newCall(request); + }; + send({type: 'log', data: '[OK] OkHttp3 hooked'}); + } catch(e) { + send({type: 'log', data: '[SKIP] OkHttp3: ' + e.message}); + } + + // 2. Hook 微信MMServiceManager - 找到消息发送服务 + try { + var MMServiceManager = Java.use('com.tencent.mm.sdk.platformtools.MMServiceManager'); + send({type: 'log', data: '[OK] MMServiceManager found'}); + } catch(e) { + send({type: 'log', data: '[SKIP] MMServiceManager: ' + e.message}); + } + + // 3. Hook XMPP/MMProtocol - 微信自定义协议 + var xmppClasses = [ + 'com.tencent.mm.protocal.MMProtocal', + 'com.tencent.mm.protocal.b', + 'com.tencent.mm.network.MMNetworkService', + 'com.tencent.mm.network.b', + 'com.tencent.mm.xmpp.XMPPService', + ]; + + xmppClasses.forEach(function(cls) { + try { + Java.use(cls); + send({type: 'log', data: '[FOUND] ' + cls}); + } catch(e) {} + }); + + // 4. 扫描所有已加载的类,找到包含"sendMsg"或"sendMessage"的类 + // 使用精准枚举而不是全量扫描 + var targetPatterns = [ + 'com.tencent.mm.model', + 'com.tencent.mm.messenger', + 'com.tencent.mm.modelmulti', + ]; + + // 5. Hook SQLiteDatabase.execSQL - 捕获消息写入时的调用栈 + try { + var WCDB = Java.use('com.tencent.wcdb.database.SQLiteDatabase'); + + WCDB.execSQL.overload('java.lang.String').implementation = function(sql) { + if (sql && sql.indexOf('message') > -1 && sql.indexOf('INSERT') > -1) { + var stack = Java.use('android.util.Log').getStackTraceString( + Java.use('java.lang.Exception').$new('STACK') + ); + send({type: 'msg_insert_stack', data: {sql: sql.substring(0, 200), stack: stack.substring(0, 2000)}}); + } + return this.execSQL(sql); + }; + send({type: 'log', data: '[OK] WCDB.execSQL hooked'}); + } catch(e) { + send({type: 'log', data: '[SKIP] WCDB.execSQL: ' + e.message}); + } + + // 6. Hook insert方法 + try { + var WCDB2 = Java.use('com.tencent.wcdb.database.SQLiteDatabase'); + WCDB2.insert.overload('java.lang.String', 'java.lang.String', 'android.content.ContentValues').implementation = function(table, nullColumnHack, values) { + if (table && table.indexOf('message') > -1) { + var stack = Java.use('android.util.Log').getStackTraceString( + Java.use('java.lang.Exception').$new('STACK') + ); + send({type: 'msg_insert_stack', data: {table: table, stack: stack.substring(0, 3000)}}); + } + return this.insert(table, nullColumnHack, values); + }; + send({type: 'log', data: '[OK] WCDB.insert hooked'}); + } catch(e) { + send({type: 'log', data: '[SKIP] WCDB.insert: ' + e.message}); + } + + isReady = true; + send({type: 'ready', data: 'Hook脚本已就绪,请在手机上发送一条微信消息'}); +}); + +rpc.exports = { + getCapturedRequests: function() { + return capturedSendRequests; + }, + isReady: function() { + return isReady; + }, + clearRequests: function() { + capturedSendRequests = []; + return true; + } +};