Files
kefu/wechat_rpa/scan_golden_window.py
2026-08-27 14:04:28 +08:00

87 lines
2.9 KiB
Python
Raw Permalink 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.
# -*- coding: utf-8 -*-
"""
scan_golden_window.py - 重启企微后的"黄金窗口"密钥扫描
========================================================
思路:企微密钥可能在登录/打开 db 时短暂存在内存,随后被清理。
本脚本在企微重启后立即执行多轮快速扫描,捕捉密钥初始化窗口。
用法:
python scan_golden_window.py [--rounds 6] [--wait 20]
--rounds 扫描轮数(默认 6
--wait 每轮间隔秒数(默认 20)
注意:需要先手动退出企微(或本脚本用 taskkill 终止,需用户确认)。
"""
from __future__ import annotations
import argparse
import os
import subprocess
import sys
import time
import wxwork_key as wk
from wxwork_crypto import generate_iv
def main():
ap = argparse.ArgumentParser()
ap.add_argument("--rounds", type=int, default=6)
ap.add_argument("--wait", type=float, default=20.0)
ap.add_argument("--kill", action="store_true", help="先 taskkill 企微再启动(需确认)")
args = ap.parse_args()
import multiprocessing as mp
mp.freeze_support()
wk._IV_PAGE1 = generate_iv(1)
dbs = wk.discover_db_files()
if not dbs:
print("未发现加密 db"); return 1
prep = wk._prep_verify(dbs[0])
if prep is None:
print("验证基准构造失败"); return 1
print(f"验证基准 OK: {os.path.basename(dbs[0])}")
if args.kill:
print("终止企微进程 ...")
subprocess.run(["taskkill", "/f", "/im", "WXWork.exe"], capture_output=True)
time.sleep(3)
print("启动企微 ...")
subprocess.Popen([r"D:\soft\WXWork\WXWork.exe"])
found: set[str] = set()
for rnd in range(1, args.rounds + 1):
pids = wk.find_wxwork_pids()
print(f"\n[轮次 {rnd}/{args.rounds}] 进程: {len(pids)} 个")
t0 = time.time()
for pid in pids:
for kl in (16, 32):
keys = wk.scan_binary_single(pid, prep, aligned=True, key_len=kl,
step=8, progress_cb=None)
for kh in keys:
if kh not in found:
found.add(kh)
print(f" 🎯 命中 PID={pid} key_len={kl}: {kh}")
print(f" 耗时 {time.time()-t0:.0f}s, 累计候选 {len(found)}")
if found:
# 全库复核
result = {}
for db in dbs:
for kh in found:
if wk.verify_key(bytes.fromhex(kh), db):
result.setdefault(db, []).append(kh)
if result:
print("\n=== 已验证密钥 ===")
for db, ks in result.items():
print(f"{db} -> {ks}")
return 0
if rnd < args.rounds:
time.sleep(args.wait)
print("\n黄金窗口内未捕获到密钥")
return 1
if __name__ == "__main__":
sys.exit(main())