// 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
    };
}
