feat(hook): 新增 diag_sns 安全诊断(试探候选类名,禁用全量枚举)

定位 8.0.69 朋友圈混淆类名工具。实测 Java.enumerateLoadedClassesSync 在微信10万+类会阻塞agent致WS掉线,故禁用全量枚举,改为试探 params.candidates(来自离线apk分析)。get_sticker_list 真RPC同文件保留。

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Manus AI
2026-05-30 17:26:00 +08:00
parent f5ae40632c
commit 76041c52b0
2 changed files with 47 additions and 1 deletions

View File

@@ -70,7 +70,7 @@ ACTION_TO_RPC: Dict[str, str] = {
"set_avatar": "setAvatar",
"set_sex": "setSex",
"set_region": "setRegion",
"set_whats_up": "setWhatUp",
"set_what_up": "setWhatUp",
# ── H24 账号安全 ──
"unblock_self": "unblockSelf",
@@ -177,6 +177,8 @@ ACTION_TO_RPC: Dict[str, str] = {
# ── 系统 ──
"get_hook_status": "getHookStatus",
"diag_sns": "diagSns",
"diag_wcdb": "diagWcdb",
"get_process_info": "getProcessInfo",
"get_wechat_version": "getWechatVersion",
"batch_execute": "batchExecute",

View File

@@ -445,6 +445,50 @@ rpc.exports = {
}
},
// 诊断:运行时反射枚举 8.0.69 朋友圈(SNS)发布/读取相关类与方法
// 用于在混淆版定位 post_moments(sns.model.ay 等价) / get_moments(m3.onGYNetEnd 等价) 真实类名。
diagSns: function (params) {
// 安全诊断:**禁用** Java.enumerateLoadedClassesSync微信 10万+ 类,桥接枚举会阻塞
// agent 事件循环导致 WS 掉线 — 2026-05-30 实测)。改为「试探调用方提供的候选类名」:
// params.candidates = ["com.tencent.mm.plugin.sns.model.xx", ...](来自离线 apk/smali 分析)
// 对每个候选 Java.use + 反射方法名(最多 8 个,快速、不枚举),定位发/读朋友圈真实类。
var cands = (params && params.candidates) || [];
if (!cands || cands.length === 0) {
return {
success: false,
error: 'no_candidates',
hint: '运行时全量枚举已禁用(会致 WS 掉线)。请先离线对 8.0.69 apk 跑 jadx/baksmali 取候选类名,再传 params.candidates=[...] 试探。',
};
}
var lim = Math.min(cands.length, 8);
try {
return Java.performNow(function () {
var out = [];
for (var i = 0; i < lim; i++) {
var cn = cands[i];
var info = { cls: cn, exists: false, methods: [], ctors: 0, hasCommit: false };
try {
var k = Java.use(cn);
info.exists = true;
var ms = k.class.getDeclaredMethods();
var names = {};
for (var m = 0; m < ms.length; m++) {
var mn = ms[m].getName();
names[mn] = 1;
if (mn.toLowerCase().indexOf('commit') >= 0) info.hasCommit = true;
}
info.methods = Object.keys(names).slice(0, 30);
info.ctors = k.class.getDeclaredConstructors().length;
} catch (e0) { info.err = String(e0); }
out.push(info);
}
return { success: true, tested: lim, classes: out };
});
} catch (e) {
return { success: false, error: String(e) };
}
},
getWechatVersion: function () {
if (_wechatVersion) return { success: true, version: _wechatVersion };
try {