#!/usr/bin/env python3 # -*- coding: utf-8 -*- """扫描微信所有23个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" BASE = "/Users/karuo/Documents/开发/2、私域银行/工作手机" HOOK_JS = BASE + "/sdk/agent/hook/wechat_full_control_v4.js" result = subprocess.run(["adb","-s",ADB_SERIAL,"shell","ps -A | grep 'com.tencent.mm$'"],capture_output=True,text=True) WECHAT_PID = int(result.stdout.strip().split()[1]) if result.stdout.strip() else 20745 print(f"微信PID: {WECHAT_PID}") dm = frida.get_device_manager() device = dm.add_remote_device(f"{PHONE_IP}:{FRIDA_PORT}") session = device.attach(WECHAT_PID) def on_msg(m,d): if m.get("type")=="send": p=m["payload"] if p.get("type") in ("ready","hook_ok"): print(f" [{p['type']}] {p.get('msg','')}") with open(HOOK_JS,encoding="utf-8") as f: src=f.read() script=session.create_script(src) script.on("message",on_msg) script.load() time.sleep(3) rpc=script.exports_sync print("\n=== 枚举所有DB实例 ===") db_info = rpc.get_db_info() all_dbs = db_info.get("instances",[]) print(f"DB总数: {len(all_dbs)}") for db in all_dbs: print(f" {db.get('path','')}") print("\n=== 枚举所有DB表 ===") tables_info = rpc.list_all_tables() all_tables = tables_info.get("databases",{}) # 关键词匹配 keywords = { "朋友圈": ["sns","Sns","SnsInfo","moment","Moment","feed","Feed"], "视频号": ["finder","Finder","video","Video","channel","Channel"], "收藏": ["fav","Fav","collect","Collect","star","Star","bookmark"], "红包": ["hongbao","HongBao","redpacket","RedPacket","lucky","Lucky","wallet"], "文件": ["file","File","attach","Attach","media","Media","storage"], "群管理": ["chatroom","Chatroom","group","Group","room","Room"], "支付": ["pay","Pay","wallet","Wallet","finance","Finance"], "标签": ["label","Label","tag","Tag"], "小程序": ["applet","Applet","mini","Mini","plugin","Plugin"], } found = {} for db_name, tables in all_tables.items(): for table in tables: for category, kws in keywords.items(): for kw in kws: if kw.lower() in table.lower(): if category not in found: found[category] = [] found[category].append(f"{db_name}.{table}") print("\n=== 关键表定位 ===") for cat, tables in found.items(): print(f"\n【{cat}】") for t in tables[:10]: print(f" {t}") # 详细查询关键DB print("\n=== 详细查询各DB表 ===") detail = {} for db_name, tables in all_tables.items(): print(f"\n[{db_name}] {len(tables)}张表: {tables[:20]}") detail[db_name] = tables # 特别查询sns相关DB for db_name, tables in all_tables.items(): if "sns" in db_name.lower() or "star" in db_name.lower(): print(f"\n=== SNS DB详情: {db_name} ===") for t in tables: r = rpc.raw_query({"sql": f"SELECT COUNT(*) as cnt FROM {t}", "db": db_name}) cnt = r.get("rows",[{}])[0].get("cnt","?") if r.get("success") else "ERR" print(f" {t}: {cnt}条") # 查找红包表 print("\n=== 查找红包/钱包相关表 ===") for db_name, tables in all_tables.items(): for t in tables: if any(kw in t.lower() for kw in ["hongbao","redpacket","wallet","pay","lucky","finance","money"]): r = rpc.raw_query({"sql": f"PRAGMA table_info({t})", "db": db_name}) cols = [row.get("name","") for row in r.get("rows",[])] print(f" {db_name}.{t}: {cols[:10]}") # 查找文件/附件表 print("\n=== 查找文件/附件表 ===") for db_name, tables in all_tables.items(): for t in tables: if any(kw in t.lower() for kw in ["file","attach","media","storage","img","voice","video"]): r = rpc.raw_query({"sql": f"SELECT COUNT(*) as cnt FROM {t}", "db": db_name}) cnt = r.get("rows",[{}])[0].get("cnt","?") if r.get("success") else "ERR" print(f" {db_name}.{t}: {cnt}条") # 保存完整结果 output = { "time": datetime.now().isoformat(), "pid": WECHAT_PID, "db_count": len(all_dbs), "all_dbs": [db.get("path","") for db in all_dbs], "all_tables": all_tables, "found_by_category": found } with open(BASE+"/db_full_scan_20260518.json","w",encoding="utf-8") as f: json.dump(output,f,ensure_ascii=False,indent=2) print(f"\n完整扫描结果已保存: db_full_scan_20260518.json") try: script.unload() except: pass session.detach()