120 lines
3.8 KiB
Python
120 lines
3.8 KiB
Python
#!/usr/bin/env python3
|
||
# -*- coding: utf-8 -*-
|
||
"""v6 探索脚本:找到微信8.0.56真实类名和DB路径"""
|
||
import frida, time, json, subprocess
|
||
from datetime import datetime
|
||
|
||
PHONE_IP = "192.168.110.80"
|
||
FRIDA_PORT = 27042
|
||
ADB_SERIAL = "192.168.110.80:5555"
|
||
WECHAT_PID = 20745
|
||
BASE = "/Users/karuo/Documents/开发/2、私域银行/工作手机"
|
||
|
||
dm = frida.get_device_manager()
|
||
device = dm.add_remote_device(f"{PHONE_IP}:{FRIDA_PORT}")
|
||
session = device.attach(WECHAT_PID)
|
||
|
||
events = []
|
||
found_classes = {}
|
||
|
||
def on_msg(m, d):
|
||
if m.get("type") == "send":
|
||
p = m["payload"]
|
||
events.append(p)
|
||
t = p.get("type", "")
|
||
if t == "class_found":
|
||
cat = p.get("category", "")
|
||
name = p.get("name", "")
|
||
found_classes[cat] = name
|
||
print(f" 🎯 [{cat}] {name}")
|
||
elif t == "log":
|
||
print(f" [LOG] {p.get('msg', '')}")
|
||
elif t == "wcdb_insert":
|
||
print(f" [WCDB] {p.get('sql', '')[:60]} | stack: {p.get('stack', [])[:2]}")
|
||
elif t == "ready":
|
||
print(f" ✅ {p.get('msg', '')}")
|
||
|
||
with open(BASE + "/sdk/agent/hook/wechat_v6_backend.js", encoding="utf-8") as f:
|
||
src = f.read()
|
||
|
||
script = session.create_script(src)
|
||
script.on("message", on_msg)
|
||
script.load()
|
||
time.sleep(5)
|
||
rpc = script.exports_sync
|
||
|
||
print("\n" + "="*60)
|
||
print("v6 探索:找关键类名和DB路径")
|
||
print("="*60)
|
||
|
||
# 1. 获取已找到的类
|
||
print("\n【已找到的类】")
|
||
r = rpc.get_found_classes()
|
||
print(json.dumps(r, ensure_ascii=False, indent=2))
|
||
|
||
# 2. 获取所有DB路径
|
||
print("\n【所有DB路径】")
|
||
r_db = rpc.get_all_db_paths()
|
||
for p in r_db.get("paths", []):
|
||
print(f" - {p}")
|
||
|
||
# 3. 在每个DB中查找SnsInfo表
|
||
print("\n【查找SnsInfo表】")
|
||
for db_path in r_db.get("paths", []):
|
||
r_sns = rpc.exec_in_db({
|
||
"db_path": db_path,
|
||
"sql": "SELECT name FROM sqlite_master WHERE type='table' AND name LIKE '%Sns%'"
|
||
})
|
||
if r_sns.get("results"):
|
||
print(f" ✅ 找到SNS表: {db_path}")
|
||
for row in r_sns["results"]:
|
||
print(f" - {row}")
|
||
|
||
# 4. 枚举SNS包下的类
|
||
print("\n【枚举SNS包下的类(前30个)】")
|
||
r_sns_classes = rpc.enum_package_classes({"pkg": "com.tencent.mm.plugin.sns"})
|
||
if r_sns_classes.get("classes"):
|
||
for c in r_sns_classes["classes"][:30]:
|
||
print(f" - {c}")
|
||
print(f" ... 共{r_sns_classes.get('count', 0)}个类")
|
||
|
||
# 5. 枚举chatting包下的类
|
||
print("\n【枚举chatting包下的类(前20个)】")
|
||
r_chat_classes = rpc.enum_package_classes({"pkg": "com.tencent.mm.plugin.chatting"})
|
||
if r_chat_classes.get("classes"):
|
||
for c in r_chat_classes["classes"][:20]:
|
||
print(f" - {c}")
|
||
|
||
# 6. 枚举contact包下的类
|
||
print("\n【枚举contact包下的类(前20个)】")
|
||
r_contact_classes = rpc.enum_package_classes({"pkg": "com.tencent.mm.plugin.contact"})
|
||
if r_contact_classes.get("classes"):
|
||
for c in r_contact_classes["classes"][:20]:
|
||
print(f" - {c}")
|
||
|
||
# 7. 枚举wallet包下的类
|
||
print("\n【枚举wallet包下的类(前20个)】")
|
||
r_wallet_classes = rpc.enum_package_classes({"pkg": "com.tencent.mm.plugin.wallet"})
|
||
if r_wallet_classes.get("classes"):
|
||
for c in r_wallet_classes["classes"][:20]:
|
||
print(f" - {c}")
|
||
|
||
# 保存结果
|
||
output = {
|
||
"time": datetime.now().isoformat(),
|
||
"found_classes": found_classes,
|
||
"db_paths": r_db.get("paths", []),
|
||
"sns_classes": r_sns_classes.get("classes", []),
|
||
"chat_classes": r_chat_classes.get("classes", []),
|
||
"contact_classes": r_contact_classes.get("classes", []),
|
||
"wallet_classes": r_wallet_classes.get("classes", []),
|
||
"events": events
|
||
}
|
||
with open(BASE + "/explore_v6_results.json", "w", encoding="utf-8") as f:
|
||
json.dump(output, f, ensure_ascii=False, indent=2)
|
||
print(f"\n结果已保存: explore_v6_results.json")
|
||
|
||
try: script.unload()
|
||
except: pass
|
||
session.detach()
|