Files
WeChatDataAnalysis/tools/extract_media_keys.py
2977094657 eaec54a517 feat(chat): 增强聊天媒体能力(表情下载/资源定位/会话预览)
新增 /api/chat/media/emoji/download,支持将表情资源下载到本地 resource

消息列表补充 emojiRemoteUrl,本地存在资源时优先返回本地 emojiUrl

open_folder 行为增强:更智能定位 emoji/资源目录,并改进 Windows Explorer 打开方式

会话列表预览改为使用 _load_latest_message_previews,提升 last message 准确性

工具脚本移除对 WxDatDecrypt 的依赖,媒体密钥提取逻辑内置到 media_key_finder

wheel 打包包含 VoipEngine.dll(Windows 解码依赖随包分发)
2025-12-18 21:19:02 +08:00

100 lines
3.0 KiB
Python

#!/usr/bin/env python3
"""
提取微信 4.x 媒体解密密钥 (需要管理员权限运行)
用法:
1. 确保微信正在运行
2. 以管理员身份运行 PowerShell
3. cd 到项目目录
4. 运行: uv run python tools/extract_media_keys.py
"""
import sys
sys.path.insert(0, "src")
import json
from pathlib import Path
try:
from wechat_decrypt_tool.media_key_finder import find_key
except ImportError as e:
print(f"[ERROR] 无法导入 media_key_finder: {e}")
print("请确保 pymem, yara-python, pycryptodome 已安装")
sys.exit(1)
# ========== 配置 ==========
REPO_ROOT = Path(__file__).resolve().parents[1]
OUTPUT_DB_DIR = REPO_ROOT / "output" / "databases"
def main():
print("=" * 60)
print("微信 4.x 媒体解密密钥提取工具")
print("=" * 60)
# 1. 列出所有账号
print("\n[1] 列出已解密账号...")
if not OUTPUT_DB_DIR.exists():
print("[ERROR] output/databases 目录不存在")
sys.exit(1)
accounts = []
for p in OUTPUT_DB_DIR.iterdir():
if p.is_dir() and (p / "_source.json").exists():
accounts.append(p.name)
if not accounts:
print("[ERROR] 没有找到已解密的账号")
sys.exit(1)
print(f" 找到 {len(accounts)} 个账号")
# 2. 处理每个账号
for account in accounts:
print(f"\n[2] 处理账号: {account}")
account_dir = OUTPUT_DB_DIR / account
# 读取 _source.json
source_json = account_dir / "_source.json"
with open(source_json, "r", encoding="utf-8") as f:
source = json.load(f)
wxid_dir_str = source.get("wxid_dir", "")
if not wxid_dir_str:
print(" [SKIP] 没有 wxid_dir")
continue
wxid_dir = Path(wxid_dir_str)
if not wxid_dir.exists():
print(f" [SKIP] wxid_dir 不存在: {wxid_dir}")
continue
# 使用 WxDatDecrypt 的 find_key 函数
print(f" wxid_dir: {wxid_dir}")
print(" 正在提取密钥 (需要微信正在运行且有管理员权限)...")
try:
xor_key, aes_key = find_key(wxid_dir, version=4)
# 保存到 _media_keys.json
keys_file = account_dir / "_media_keys.json"
keys_data = {
"xor": xor_key,
"aes": aes_key.decode("ascii") if isinstance(aes_key, bytes) else str(aes_key),
}
with open(keys_file, "w", encoding="utf-8") as f:
json.dump(keys_data, f, indent=2)
print(f" [OK] 密钥已保存到: {keys_file}")
print(f" XOR key: {xor_key}")
print(f" AES key: {keys_data['aes']}")
except Exception as e:
print(f" [ERROR] 提取失败: {e}")
print("\n" + "=" * 60)
print("完成!请重启后端服务以使密钥生效。")
print("=" * 60)
if __name__ == "__main__":
main()