Some checks failed
SDK CI / python-compile (push) Has been cancelled
- 新增 sdk/app/agent(Hook/Skills/Anti-ban 等)及 NAS/ADB 脚本 - 更新 Android 端、unified、PHP SDK、Docker Compose - Soul 文档迁移至 Soul调研/;移除资料目录内 APK - .gitignore 排除 sdk/tmp、sdk/logs、sdk/tmp_rom Co-authored-by: Cursor <cursoragent@cursor.com>
102 lines
2.7 KiB
JavaScript
102 lines
2.7 KiB
JavaScript
// 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) });
|
||
}
|
||
});
|