diff --git a/sdk/agent/hook/wechat_v6_backend.js b/sdk/agent/hook/wechat_v6_backend.js new file mode 100644 index 0000000000..572761d028 --- /dev/null +++ b/sdk/agent/hook/wechat_v6_backend.js @@ -0,0 +1,488 @@ +// 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 + }; +}