87 lines
2.9 KiB
Python
87 lines
2.9 KiB
Python
# -*- 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())
|