Files
workphone-sdk/scan_wechat_classes.py

218 lines
7.4 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
扫描微信8.0.56真实类名,找到消息发送/朋友圈发送的真实接口
"""
import frida, time, json
from datetime import datetime
PHONE_IP = "192.168.110.80"
FRIDA_PORT = 27042
WECHAT_PID = 16816
BASE = "/Users/karuo/Documents/开发/2、私域银行/工作手机"
RESULT_FILE = BASE + "/scan_classes_20260518.json"
SCAN_SCRIPT = """
'use strict';
rpc.exports = {
// 扫描包含关键词的类名
scanClasses: function(keyword) {
var results = [];
Java.enumerateLoadedClasses({
onMatch: function(name) {
if (name.toLowerCase().indexOf(keyword.toLowerCase()) !== -1) {
results.push(name);
}
},
onComplete: function() {}
});
return { success: true, classes: results, count: results.length };
},
// 扫描类的方法
getMethods: function(className) {
try {
var cls = Java.use(className);
var methods = cls.class.getDeclaredMethods();
var result = [];
for (var i = 0; i < methods.length; i++) {
var m = methods[i];
result.push({
name: m.getName(),
params: m.getParameterTypes().map(function(p) { return p.getName(); }),
return_type: m.getReturnType().getName(),
modifiers: m.getModifiers()
});
}
return { success: true, class: className, methods: result, count: result.length };
} catch(e) {
return { success: false, error: String(e) };
}
},
// 检查类是否存在
classExists: function(className) {
try {
Java.use(className);
return { exists: true, class: className };
} catch(e) {
return { exists: false, class: className, error: String(e).substring(0, 100) };
}
},
// 批量检查类
checkClasses: function(classNames) {
var results = [];
for (var i = 0; i < classNames.length; i++) {
try {
Java.use(classNames[i]);
results.push({ class: classNames[i], exists: true });
} catch(e) {
results.push({ class: classNames[i], exists: false });
}
}
return { success: true, results: results };
},
// 扫描modelmulti包下的类
scanModelmulti: function() {
var results = [];
Java.enumerateLoadedClasses({
onMatch: function(name) {
if (name.indexOf('com.tencent.mm.modelmulti') !== -1 ||
name.indexOf('com.tencent.mm.sdk.platformtools') !== -1 ||
name.indexOf('messenger.foundation') !== -1) {
results.push(name);
}
},
onComplete: function() {}
});
return { success: true, classes: results, count: results.length };
},
// 尝试直接发送消息用AccessibilityService方式
sendViaInput: function(toId, content) {
try {
return Java.performNow(function() {
// 方法1: 通过InputMethodManager模拟输入
var ctx = Java.use('android.app.ActivityThread').currentApplication().getApplicationContext();
// 尝试找到当前焦点的EditText并输入
var Activity = Java.use('android.app.ActivityThread');
var app = Activity.currentApplication();
return { success: false, error: '需要UI线程访问' };
});
} catch(e) {
return { success: false, error: String(e) };
}
},
// 通过ADB shell am命令发送
getWechatSendActivity: function() {
try {
return Java.performNow(function() {
var ctx = Java.use('android.app.ActivityThread').currentApplication().getApplicationContext();
var pm = ctx.getPackageManager();
var intent = Java.use('android.content.Intent').$new('android.intent.action.SEND');
intent.setType('text/plain');
var activities = pm.queryIntentActivities(intent, 0);
var results = [];
for (var i = 0; i < activities.size(); i++) {
var ri = activities.get(i);
results.push(ri.activityInfo.packageName + '/' + ri.activityInfo.name);
}
return { success: true, activities: results };
});
} catch(e) {
return { success: false, error: String(e) };
}
}
};
"""
print(f"[{datetime.now().strftime('%H:%M:%S')}] 连接Frida...")
dm = frida.get_device_manager()
device = dm.add_remote_device(f"{PHONE_IP}:{FRIDA_PORT}")
session = device.attach(WECHAT_PID)
print(f"[OK] 附加微信 PID={WECHAT_PID}")
script = session.create_script(SCAN_SCRIPT)
script.on("message", lambda m, d: None)
script.load()
print("[OK] 扫描脚本已加载等待2秒...")
time.sleep(2)
rpc = script.exports_sync
results = {}
# 1. 扫描modelmulti和messenger.foundation
print("\n=== 扫描消息发送相关类 ===")
r1 = rpc.scan_modelmulti()
print(f"找到 {r1['count']} 个相关类")
for c in sorted(r1['classes'])[:50]:
print(f" {c}")
results["modelmulti_classes"] = r1['classes']
# 2. 检查已知候选类
print("\n=== 检查已知候选类 ===")
candidates = [
"com.tencent.mm.modelmulti.h",
"com.tencent.mm.modelmulti.g",
"com.tencent.mm.modelmulti.f",
"com.tencent.mm.modelmulti.e",
"com.tencent.mm.modelmulti.d",
"com.tencent.mm.modelmulti.c",
"com.tencent.mm.modelmulti.b",
"com.tencent.mm.modelmulti.a",
"com.tencent.mm.plugin.messenger.foundation.a.k",
"com.tencent.mm.plugin.messenger.foundation.a.j",
"com.tencent.mm.plugin.messenger.foundation.a.i",
"com.tencent.mm.plugin.messenger.foundation.a.h",
"com.tencent.mm.plugin.messenger.foundation.a.g",
"com.tencent.mm.plugin.messenger.foundation.a.f",
"com.tencent.mm.plugin.messenger.foundation.a.e",
"com.tencent.mm.plugin.messenger.foundation.a.d",
"com.tencent.mm.plugin.messenger.foundation.a.c",
"com.tencent.mm.plugin.messenger.foundation.a.b",
"com.tencent.mm.plugin.messenger.foundation.a.a",
]
r2 = rpc.check_classes(candidates)
for item in r2['results']:
status = "" if item['exists'] else ""
print(f" {status} {item['class']}")
results["class_check"] = r2['results']
# 3. 扫描包含"send"关键词的类
print("\n=== 扫描包含'SendMessage'的类 ===")
r3 = rpc.scan_classes("SendMessage")
print(f"找到 {r3['count']} 个类")
for c in r3['classes'][:30]:
print(f" {c}")
results["send_message_classes"] = r3['classes']
# 4. 扫描包含"Messenger"的类
print("\n=== 扫描包含'Messenger'的类前30===")
r4 = rpc.scan_classes("Messenger")
print(f"找到 {r4['count']} 个类")
for c in sorted(r4['classes'])[:30]:
print(f" {c}")
# 5. 扫描包含"ChatUI"的类
print("\n=== 扫描ChatUI相关类 ===")
r5 = rpc.scan_classes("ChatUI")
print(f"找到 {r5['count']} 个类")
for c in r5['classes'][:20]:
print(f" {c}")
results["chat_ui_classes"] = r5['classes']
# 保存
with open(RESULT_FILE, "w", encoding="utf-8") as f:
json.dump(results, f, ensure_ascii=False, indent=2, default=str)
print(f"\n结果已保存: {RESULT_FILE}")
script.unload()
session.detach()
print("完成!")