// wechat_hook_v1.js 'use strict'; const CONFIG = { WECHAT_PACKAGE: 'com.tencent.mm', LOG_LEVEL: 'info', }; function log(level, tag, message, extra) { send({ type: 'log', level: level, tag: tag, message: String(message || ''), extra: extra || {}, timestamp: Date.now(), }); } function safeToString(v) { if (v === null || v === undefined) return ''; try { return v.toString(); } catch (_) { return ''; } } rpc.exports = { ping: function () { return 'pong from wechat_hook_v1'; }, getProcessInfo: function () { return { pid: Process.id, arch: Process.arch, moduleCount: Process.enumerateModules().length, }; }, // 当前版本先提供统一入口,实际发送逻辑在后续版本按微信版本细化 sendMessage: function (params) { const toId = (params && params.to_id) || ''; const content = (params && params.content) || ''; log('info', 'rpc', 'sendMessage called', { to_id: toId, content_len: content.length }); return { success: false, error: 'sendMessage 需按当前微信版本补齐具体Hook点,已完成RPC通道与事件上报', to_id: toId, }; }, getContacts: function (params) { const limit = (params && params.limit) || 100; return { success: true, data: [], limit: limit, note: '联系人读取建议通过DB Hook实现(EnMicroMsg.db)', }; }, }; Java.perform(function () { log('info', 'init', 'wechat_hook_v1 loaded'); try { const SQLiteDatabase = Java.use('android.database.sqlite.SQLiteDatabase'); SQLiteDatabase.insert.overload( 'java.lang.String', 'java.lang.String', 'android.content.ContentValues' ).implementation = function (table, nullColumnHack, values) { const result = this.insert(table, nullColumnHack, values); try { const tableName = safeToString(table); if (tableName === 'message' || tableName === 'rconversation') { const talker = safeToString(values.getAsString(Java.use('java.lang.String').$new('talker'))); const content = safeToString(values.getAsString(Java.use('java.lang.String').$new('content'))); if (talker || content) { send({ type: 'hook_event', event_type: 'message_received', platform: 'wechat', payload: { from_id: talker, content: content, }, timestamp: new Date().toISOString(), }); } } } catch (_) {} return result; }; log('info', 'hook', 'SQLite message hook enabled'); } catch (e) { log('warn', 'hook', 'SQLite hook unavailable', { error: String(e) }); } });