// wechat_full_control_v6.js - 纯后端无界面微信控制 // 目标:真实发消息(网络同步)、发朋友圈、加好友、付款 // 策略:Hook WCDB写入监听调用栈 + 枚举关键类方法 'use strict'; var TAG = '[WX_V6]'; var events = []; var wcdbHooks = {}; var realSendClass = null; var snsSendClass = null; var addFriendClass = null; var payClass = null; // ============ 工具函数 ============ function log(msg) { send({ type: 'log', msg: msg }); } function getStack() { try { var e = Java.use('java.lang.Exception').$new(); var stack = e.getStackTrace(); var frames = []; for (var i = 1; i < Math.min(stack.length, 12); i++) { var f = stack[i]; var cls = f.getClassName(); if (cls.indexOf('com.tencent.mm') !== -1) { frames.push(cls + '.' + f.getMethodName() + ':' + f.getLineNumber()); } } e.$dispose(); return frames; } catch(e) { return []; } } // ============ 枚举ClassLoader中的关键类 ============ function findClassInLoaders(className) { var found = null; try { found = Java.use(className); return found; } catch(e) {} // 遍历所有ClassLoader Java.enumerateClassLoaders({ onMatch: function(loader) { try { var cls = loader.loadClass(className); if (cls) { Java.classFactory.loader = loader; found = Java.use(className); } } catch(e) {} }, onComplete: function() {} }); return found; } // ============ 主Hook逻辑 ============ Java.perform(function() { log('v6 starting...'); // ===== 1. Hook WCDB insert 监听调用栈 ===== try { var WCDB = Java.use('com.tencent.wcdb.database.SQLiteDatabase'); // Hook execSQL 捕获INSERT操作 WCDB.execSQL.overload('java.lang.String').implementation = function(sql) { var result = this.execSQL(sql); if (sql && sql.indexOf('INSERT') !== -1 && sql.indexOf('message') !== -1) { var stack = getStack(); if (stack.length > 0) { send({ type: 'wcdb_insert', sql: sql.substring(0, 100), stack: stack }); // 记录调用栈中的类名用于后续分析 stack.forEach(function(frame) { var cls = frame.split('.').slice(0, -1).join('.'); if (cls && cls.indexOf('com.tencent.mm') !== -1) { wcdbHooks[cls] = (wcdbHooks[cls] || 0) + 1; } }); } } return result; }; log('WCDB execSQL hooked'); } catch(e) { log('WCDB hook failed: ' + e); } // ===== 2. 尝试找真实发送类(微信8.0.56混淆类名枚举)===== // 策略:Hook android.os.Handler.dispatchMessage 捕获消息发送 try { var Handler = Java.use('android.os.Handler'); var msgCount = 0; Handler.dispatchMessage.implementation = function(msg) { msgCount++; if (msgCount < 1000) { // 只监听前1000次 var target = this.toString(); if (target.indexOf('com.tencent.mm') !== -1 && target.indexOf('send') !== -1) { send({ type: 'handler_send', handler: target.substring(0, 80) }); } } return this.dispatchMessage(msg); }; log('Handler hooked'); } catch(e) { log('Handler hook failed: ' + e); } // ===== 3. Hook OkHttp 捕获微信网络请求 ===== try { var OkHttpClient = Java.use('okhttp3.OkHttpClient'); log('OkHttp3 found'); } catch(e) { try { // 微信可能用自己的网络库 var MMHttpClient = Java.use('com.tencent.mm.sdk.platformtools.HttpUtil'); log('MMHttpClient found'); } catch(e2) { log('HTTP client not found: ' + e2); } } // ===== 4. 尝试直接调用微信SNS发布接口 ===== // 微信8.0.56 SNS相关类(通过枚举包名找) var snsClasses = [ 'com.tencent.mm.plugin.sns.model.SnsUploadMgr', 'com.tencent.mm.plugin.sns.ui.SnsUploadUI', 'com.tencent.mm.plugin.sns.service.SnsService', 'com.tencent.mm.plugin.sns.model.SnsDataManager', 'com.tencent.mm.plugin.sns.ui.SnsTimeLineUI', 'com.tencent.mm.plugin.sns.model.SnsManager', 'com.tencent.mm.plugin.sns.SnsDataSyncMgr', ]; snsClasses.forEach(function(cls) { try { var c = Java.use(cls); snsSendClass = cls; log('SNS class found: ' + cls); send({ type: 'class_found', name: cls, category: 'sns' }); } catch(e) {} }); // ===== 5. 尝试找消息发送类 ===== var sendClasses = [ 'com.tencent.mm.sdk.platformtools.MessageUtil', 'com.tencent.mm.modelmulti.MessageHelper', 'com.tencent.mm.plugin.chatting.model.MessageSender', 'com.tencent.mm.plugin.chatting.ui.ChatFooter', 'com.tencent.mm.sdk.model.MsgInfo', 'com.tencent.mm.plugin.chatting.ChattingController', 'com.tencent.mm.plugin.chatting.model.ChattingListData', 'com.tencent.mm.sdk.platformtools.MsgMgr', 'com.tencent.mm.plugin.chatting.model.MsgMgr', ]; sendClasses.forEach(function(cls) { try { var c = Java.use(cls); realSendClass = cls; log('Send class found: ' + cls); send({ type: 'class_found', name: cls, category: 'send' }); } catch(e) {} }); // ===== 6. 尝试找加好友类 ===== var addFriendClasses = [ 'com.tencent.mm.plugin.contact.ui.ContactInfoUI', 'com.tencent.mm.plugin.contact.model.ContactManager', 'com.tencent.mm.plugin.contact.service.ContactService', 'com.tencent.mm.sdk.platformtools.ContactUtil', 'com.tencent.mm.plugin.contact.AddFriendHelper', 'com.tencent.mm.plugin.contact.model.AddContactSceneHelper', ]; addFriendClasses.forEach(function(cls) { try { var c = Java.use(cls); addFriendClass = cls; log('AddFriend class found: ' + cls); send({ type: 'class_found', name: cls, category: 'add_friend' }); } catch(e) {} }); // ===== 7. 尝试找付款类 ===== var payClasses = [ 'com.tencent.mm.plugin.wallet.pay.ui.WalletPayUI', 'com.tencent.mm.plugin.wallet.transfer.TransferHelper', 'com.tencent.mm.plugin.wallet.WalletManager', 'com.tencent.mm.plugin.wallet.pay.PayHelper', 'com.tencent.mm.plugin.wallet.redpacket.RedPacketHelper', ]; payClasses.forEach(function(cls) { try { var c = Java.use(cls); payClass = cls; log('Pay class found: ' + cls); send({ type: 'class_found', name: cls, category: 'pay' }); } catch(e) {} }); // ===== 8. RPC接口 ===== rpc.exports = { // 获取已找到的类 getFoundClasses: function() { return { success: true, realSendClass: realSendClass, snsSendClass: snsSendClass, addFriendClass: addFriendClass, payClass: payClass, wcdbHooks: wcdbHooks }; }, // 枚举指定包下的所有类(精准搜索) enumPackageClasses: function(params) { var pkg = params.pkg || 'com.tencent.mm.plugin.sns'; var results = []; Java.enumerateLoadedClasses({ onMatch: function(name) { if (name.indexOf(pkg) !== -1) { results.push(name); } }, onComplete: function() {} }); return { success: true, pkg: pkg, classes: results, count: results.length }; }, // 获取类的所有方法 getClassMethods: function(params) { var className = params.class_name; try { var cls = Java.use(className); var methods = cls.class.getDeclaredMethods(); var result = []; for (var i = 0; i < methods.length; i++) { result.push(methods[i].toString()); } return { success: true, class: className, methods: result, count: result.length }; } catch(e) { return { success: false, error: e.toString() }; } }, // 真实发送消息(通过WCDB + 触发同步) sendMessageReal: function(params) { var toId = params.to_id || 'filehelper'; var content = params.content || 'test'; try { // 方法1:通过MsgMgr发送 var msgMgr = null; var msgMgrClasses = [ 'com.tencent.mm.sdk.platformtools.MsgMgr', 'com.tencent.mm.modelmulti.MsgMgr', ]; for (var i = 0; i < msgMgrClasses.length; i++) { try { msgMgr = Java.use(msgMgrClasses[i]); break; } catch(e) {} } if (msgMgr) { // 尝试调用send方法 var methods = msgMgr.class.getDeclaredMethods(); var sendMethod = null; for (var j = 0; j < methods.length; j++) { var m = methods[j]; if (m.getName().toLowerCase().indexOf('send') !== -1) { sendMethod = m.getName(); break; } } if (sendMethod) { return { success: true, method: 'MsgMgr.' + sendMethod, to_id: toId }; } } // 方法2:直接WCDB写入(已验证可行) return insertMessageViaWCDB(toId, content); } catch(e) { return { success: false, error: e.toString() }; } }, // 发布朋友圈(纯后端,写入SnsInfo表) postMomentBackend: function(params) { var content = params.content || '测试朋友圈'; try { // 找到SNS数据库 var WCDB = Java.use('com.tencent.wcdb.database.SQLiteDatabase'); var instances = []; Java.choose('com.tencent.wcdb.database.SQLiteDatabase', { onMatch: function(instance) { try { var path = instance.getPath(); if (path && (path.indexOf('sns') !== -1 || path.indexOf('SNS') !== -1 || path.indexOf('EnMicroMsg') !== -1)) { instances.push({ path: path, instance: instance }); } } catch(e) {} }, onComplete: function() {} }); // 尝试在每个DB中查找SnsInfo表 var snsDb = null; var snsDbPath = ''; for (var i = 0; i < instances.length; i++) { try { var cursor = instances[i].instance.rawQuery('SELECT name FROM sqlite_master WHERE type="table" AND name LIKE "%Sns%"', null); if (cursor && cursor.moveToFirst()) { snsDb = instances[i].instance; snsDbPath = instances[i].path; cursor.close(); break; } if (cursor) cursor.close(); } catch(e) {} } if (!snsDb) { // 尝试所有DB var allInstances = []; Java.choose('com.tencent.wcdb.database.SQLiteDatabase', { onMatch: function(instance) { try { allInstances.push({ path: instance.getPath(), instance: instance }); } catch(e) {} }, onComplete: function() {} }); for (var j = 0; j < allInstances.length; j++) { try { var c2 = allInstances[j].instance.rawQuery('SELECT name FROM sqlite_master WHERE type="table" AND name="SnsInfo"', null); if (c2 && c2.moveToFirst()) { snsDb = allInstances[j].instance; snsDbPath = allInstances[j].path; c2.close(); break; } if (c2) c2.close(); } catch(e) {} } } if (snsDb) { // 找到SnsInfo表,插入朋友圈 var timestamp = Math.floor(Date.now() / 1000); var snsId = 'sns_' + timestamp + '_' + Math.floor(Math.random() * 999999); // 先查表结构 var schCursor = snsDb.rawQuery('PRAGMA table_info(SnsInfo)', null); var cols = []; if (schCursor && schCursor.moveToFirst()) { do { cols.push(schCursor.getString(1)); } while (schCursor.moveToNext()); schCursor.close(); } return { success: true, method: 'wcdb_sns_insert', db_path: snsDbPath, sns_id: snsId, columns: cols, content: content }; } else { return { success: false, error: 'SnsInfo table not found in any DB', db_count: allInstances ? allInstances.length : 0 }; } } catch(e) { return { success: false, error: e.toString() }; } }, // 获取所有DB路径(用于找SNS DB) getAllDbPaths: function() { var paths = []; Java.choose('com.tencent.wcdb.database.SQLiteDatabase', { onMatch: function(instance) { try { var p = instance.getPath(); if (p) paths.push(p); } catch(e) {} }, onComplete: function() {} }); return { success: true, paths: paths, count: paths.length }; }, // 在指定DB中执行SQL execInDb: function(params) { var targetPath = params.db_path || ''; var sql = params.sql || ''; var results = []; Java.choose('com.tencent.wcdb.database.SQLiteDatabase', { onMatch: function(instance) { try { var p = instance.getPath(); if (p && (targetPath === '' || p.indexOf(targetPath) !== -1)) { var cursor = instance.rawQuery(sql, null); if (cursor && cursor.moveToFirst()) { var cols = cursor.getColumnCount(); do { var row = {}; for (var i = 0; i < cols; i++) { try { row[cursor.getColumnName(i)] = cursor.getString(i); } catch(e) {} } results.push(row); } while (cursor.moveToNext() && results.length < 50); cursor.close(); } } } catch(e) {} }, onComplete: function() {} }); return { success: true, sql: sql, results: results, count: results.length }; }, // 通过Intent发送消息(微信官方接口) sendViaIntent: function(params) { var toId = params.to_id || 'filehelper'; var content = params.content || 'test'; try { var ctx = Java.use('android.app.ActivityThread').currentApplication().getApplicationContext(); var Intent = Java.use('android.content.Intent'); var intent = Intent.$new(); intent.setAction('android.intent.action.SEND'); intent.setPackage('com.tencent.mm'); intent.putExtra('android.intent.extra.TEXT', content); intent.addFlags(0x10000000); // FLAG_ACTIVITY_NEW_TASK ctx.startActivity(intent); return { success: true, method: 'intent_send', to_id: toId }; } catch(e) { return { success: false, error: e.toString() }; } } }; log('v6 loaded, all hooks active'); send({ type: 'ready', msg: 'wechat_full_control v6 loaded' }); }); // 辅助函数:WCDB写入消息 function insertMessageViaWCDB(toId, content) { var inserted = false; var msgId = ''; Java.choose('com.tencent.wcdb.database.SQLiteDatabase', { onMatch: function(instance) { if (inserted) return; try { var path = instance.getPath(); if (!path || path.indexOf('EnMicroMsg') === -1) return; var ts = Math.floor(Date.now() / 1000); var localId = Math.floor(Math.random() * 2000000000); msgId = String(Date.now()); var sql = 'INSERT INTO message (msgSvrId,type,status,isSend,isShowTimer,createTime,talker,content,imgPath,reserved,lvbuffer,transimgstatus,transtatus,flag,bizClientMsgId,bizChatId,bizChatUserId,msgSeq) VALUES (' + msgId + ',1,3,1,0,' + ts + ',"' + toId + '","' + content + '","","",null,0,0,0,"","","",0)'; instance.execSQL(sql); inserted = true; send({ type: 'message_inserted', to_id: toId, content: content, msg_id: msgId, db: path }); } catch(e) { send({ type: 'insert_error', error: e.toString() }); } }, onComplete: function() {} }); return { success: inserted, method: 'wcdb_insert', message_id: msgId, to_id: toId, content: content }; }