解密微信聊天记录,语音,表情,照片, 生成可训练的数字分身
name: “wechat-decrypt”
description: “解密微信 4.x 数据库并导出聊天记录、语音、表情、照片,生成可训练的对话语料。当用户要求提取/破解微信数据、导出微信媒体(语音/表情/图片)、或为数字分身准备聊天训练语料时使用。”
微信聊天记录解密与语料提取工具包
用途
把微信 4.x 客户端的加密数据库解密出来,导出指定联系人的完整聊天记录、语音、表情包、照片,并整理成可用于训练"数字分身"(AI 人格模仿)的对话语料。
工具包位置:E:\project\yeyu\tools\wechat-decrypt\
已完成的导出示例:E:\project\yeyu\tools\wechat-decrypt\wechat_files\wxid_tx2otle9oiod22\kemy\(含 chat_enriched.txt / voice/ / images/ / emoji/ / asr/)
运行环境(前置条件)
| 项 | 要求 | 说明 |
|---|---|---|
| 操作系统 | Windows 10/11 | 密钥提取依赖进程内存扫描,必须 Windows |
| 权限 | 管理员权限运行终端 | 读 Weixin.exe 进程内存需要提权 |
| 微信 | 微信 4.x 已登录并保持运行 | 提取密钥的瞬间需要进程在跑;密钥每小时刷新,提取后立刻解密 |
| Python | 3.10+ | 脚本兼容性按 3.10 验证 |
| 依赖 | pip install -r requirements.txt | 含 pycryptodome、zstandard、pilk、faster-whisper 等 |
| 第三方 | ffmpeg | 语音/视频转换需要,加入 PATH |
配置文件(关键)
编辑config.json(工具包根目录),核心字段:
{"db_dir":"C:\\Users\\<用户名>\\xwechat_files\\<wxid>_<端口>\\db_storage","keys_file":"E:\\project\\yeyu\\tools\\wechat-decrypt\\all_keys.json","decrypted_dir":"E:\\project\\yeyu\\tools\\wechat-decrypt\\decrypted","wechat_base_dir":"C:\\Users\\<用户名>\\xwechat_files\\<wxid>_<端口>","output_base_dir":"E:\\project\\yeyu\\tools\\wechat-decrypt\\wechat_files\\<wxid>_<端口>","xwechat_attach_dir":"...\\msg\\attach","image_aes_key":"5b731f508c779a63","image_xor_key":145}完整流程
阶段 0:环境准备
- 确认微信 4.x 正在运行、已登录目标账号
- 管理员权限打开 PowerShell
- 安装依赖:
cd E:\project\yeyu\tools\wechat-decrypt; pip install -r requirements.txt - 检查/更新
config.json(见上表)
阶段 1:破解/提取数据库密钥(核心步骤,务必细读本节)
1.1 原理:为什么能从内存里"捡"到密钥
微信数据库由 SQLCipher 加密,密钥本身无法暴力破解(PBKDF2 迭代 256000 次)。但微信使用的 WCDB 数据库引擎会为每个 DB 缓存解密密钥,缓存在微信进程内存中,形式是 SQLite 的 hex 字面量字符串:
x'<64位十六进制=enc_key><32位十六进制=salt>' x'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy' |<------------ 32 字节加密密钥 ----------->|<-------- 16 字节 salt -------->|关键点:salt(盐)同时以明文存在每个数据库文件的前 16 字节里。所以提取思路是:
- 遍历微信数据目录所有
.db文件,读出每个文件头部的salt - 扫描
Weixin.exe全部可读内存,用正则x'([0-9a-fA-F]{64,192})'找出所有 key+salt 字符串 - 把内存里的 salt 和文件里的 salt 对上号,再用HMAC-SHA512 校验第 1 页(
verify_enc_key)确认真伪 - 所有匹配成功的 enc_key 写入
keys_file(JSON)
这就是"提取"而非"破解"——只是从运行中的进程内存里把缓存读出来。所以微信必须在运行状态,且要有管理员权限才能读进程内存。
1.2 运行命令
# 管理员 PowerShell,工具包根目录 python find_all_keys.py执行后会依次做两件事:
(A)离线爆破图片 AES 密钥(find_image_key_offline)
- 从
msg/attach/*/*/Img/*_t.dat缩略图文件推导 XOR key,再对 UIN 空间(2^24)多进程爆破出图片 AES key - 若微信里从没打开过图片(无
_t.dat缓存),这一步会跳过并提示"请先在微信中查看 2-3 张图片" - 成功则自动写回
config.json的image_aes_key/image_xor_key,该密钥只用于图片解密,与数据库无关
(B)提取所有数据库 key(find_all_keys_windows.main)
- 收集
db_dir下所有.db的 salt - 通过
tasklist找所有Weixin.exe进程(按内存降序,多进程都扫) VirtualQueryEx+ReadProcessMemory逐块读取可读内存区域(每块 <500MB,跳过不可读区)- 正则匹配 → salt 配对 → HMAC 校验 → 记录到
key_map
1.3 预期输出(对照判断进度)
提取所有微信数据库密钥 找到 37 个数据库, 12 个不同的salt salt a1b2...: message_0.db, message_1.db ... [+] Weixin.exe PID=1234 (2800MB) [*] 扫描 PID=1234 (3200MB, 42 区域) [12.5%] 0/12 salts matched, 2351 hex patterns, 21.3s ... [FOUND] salt=a1b2... enc_key=5f3d... PID=1234 地址: 0x000002A1F3C4D500 数据库: message_0.db, message_1.db判定成功:所有 salt 都打印[FOUND],最后一行:
结果: 12/12 salts 找到密钥 OK: message_0.db (12.3MB) OK: message_1.db ... 密钥保存到: E:\...\all_keys.json产物all_keys.json格式(供decrypt_db.py使用):
{"message_0.db":{"enc_key":"5f3d...64位hex","salt":"a1b2...32位hex","size_mb":12.3},"message_1.db":{"enc_key":"...","salt":"...","size_mb":8.1},"_db_dir":"C:\\Users\\25844\\xwechat_files\\wxid_xxx_8804\\db_storage"}1.4 耗时说明(为什么会花很长时间)
| 因素 | 影响 |
|---|---|
| 内存扫描量 | Weixin.exe 常占 2~4GB,全量逐块读取 + 正则匹配是主要耗时(几分钟量级) |
| 多进程 | 微信渲染/子进程也扫,进程越多越久 |
| salt 数量 | 每命中一个 salt 就少匹配一个,越到后面越快 |
| 图片爆破 | UIN 2^24 空间,多核并行下一般 1~3 分钟 |
整体上首次提取 3~10 分钟属正常。中途的[12.5%]进度行不是卡死,是正常的区域扫描进度。
1.5 失败排查表(按出现频率排序)
| 现象 | 原因 | 处理 |
|---|---|---|
Weixin.exe 未运行 | 微信没开/已退出 | 重新登录微信并保持前台运行 |
无法打开进程 PID=xxx | 权限不足 | 用管理员权限重开 PowerShell,杀软临时放行 python.exe |
扫完0/12 salts matched | 微信登录太短,key 缓存未建立 / 权限不足读不到内存 | 确认微信登录 >2 分钟、检查管理员权限,重跑 |
部分 DBMISSING | 该库 salt 未在内存中(key 未缓存) | 先解密已找到的,未找到的库可等下次微信运行重试 |
| 图片密钥爆破跳过 | 无_t.dat缩略图缓存 | 在微信里打开 2-3 张聊天图片,再重跑find_all_keys.py |
目录名不是wxid_xxx_端口 | 无法推导图片 key | 检查config.json的db_dir是否为微信默认账号目录 |
| 提取成功但解密报错 | key 是旧会话的,微信已刷新密钥 | key 约每小时刷新,提取后立即执行阶段 2 解密 |
1.6 提速与稳妥建议
- 提取前关掉其他大内存程序,减少微信进程分页(分页的内存读不到)
- 提取成功后立刻解密(密钥有时效,别隔天再跑)
- 可先只提取、不着急图片爆破:图片密钥是独立步骤,不影响聊天记录解密
阶段 2:解密数据库
python decrypt_db.py # 全量解密 python decrypt_db.py -i # 增量(只解更新的库) python decrypt_db.py --dry-run # 预览将解密的库- 读取
db_dir下message_*.db、micro_msg.db等加密库,按 key 解密 - 输出到
decrypted_dir(本项目decrypted/),得到明文 SQLite(message_0..6.db) - 注意:解密前若存在 -wal/-shm 残留,脚本会处理;若报"database disk image is malformed",删除对应 -wal/-shm 后重试
阶段 3:导出聊天记录(通用)
python export_all_chats.py- 把解密后的数据库导出为 JSON / CSV / HTML(按联系人拆分,自动关联媒体)
- 也可启动 Web UI 交互查看:
python monitor_web.py→ 浏览器打开 http://localhost:5678
阶段 4:导出目标联系人的媒体(图片/表情/语音)
本项目的定制脚本硬编码了目标 wxid 和输出路径,换联系人必须先改脚本顶部常量(见"关键常量"一节):
# 图片:解密 dec_all 目录下微信图片(V1/V2/XOR 解码)python batch_decrypt_save.py# 照片:全量导出到 kemy/images/(含 HEVC 解码,依赖 cv2)python export_photos.py# 表情包:下载/整理 emoji 到 kemy/emoji/,生成覆盖报告 emoji_report.txtpython finalize_emoji_all.py# 语音:SILK → WAV 转换(命名 日期_时间_序号.wav)→ kemy/voice/# 参考 voice_to_mp3.py 或 pilk 库转换,输出目录由脚本常量指定阶段 5:语音转写(ASR)
python asr_kemy_voice_parallel.py- 本地 faster-whisper(模型目录
tools/wechat-decrypt/models/small),CPU int8,2 进程并行 - 输入
kemy/voice/*.wav,输出kemy/asr/transcripts.csv(filename, datetime, duration_s, text) - 断点续跑:已转写的自动跳过
阶段 6:生成训练语料(数字分身用)
python export_kemy_full.py # 精确 join ASR 转写,输出统一 chat.txt python export_kemy_enriched.py # 增强版:媒体消息带具体文件标识,严格时间线- 输出
kemy/combined/chat_enriched.txt,格式:- 文本消息:直接输出
- 图片:
[图片:md5.jpg] - 表情:
[表情:md5.gif] - 语音:
[语音:xxx.wav] 转录文本 - 按
(create_time, local_id)严格时间线排序
- 同时生成
media_sender_map.csv(每条媒体是哪个发送者发的),供区分"我方/对方"
关键常量(换目标联系人必须改)
本项目以kemy为例,常量散落在各脚本顶部,换人时全局搜索替换:
| 常量 | 本项目值 | 说明 |
|---|---|---|
SELF_WXID | wxid_tx2otle9oiod22 | 你自己(本机账号)的 wxid |
KEMY(目标) | wxid_wx3ikgdnfk4u22 | 目标联系人的 wxid |
| 消息表名 | Msg_+ md5(目标wxid) | Msg_+ 目标 wxid 的 md5 十六进制 |
MESSAGE_DBS | message_0..6.db | 解密后的消息库列表 |
| 输出根 | ...\wechat_files\<wxid>_<端口>\kemy | 目标联系人导出目录 |
输出物清单\
wechat_files/wxid_tx2otle9oiod22/xxxx/ ├── combined/chat_enriched.txt # 最终训练语料(严格时间线、媒体标识) ├── voice/*.wav # 全部语音(724 个,137 分钟) ├── images/*.jpg # 照片(dec_all 解码后全量导出) ├── emoji/*.gif # 表情包 + emoji_report.txt ├── asr/transcripts.csv # 语音转写文本 └── media_sender_map.csv # 媒体-发送者映射注意事项
- 密钥有时效:微信密钥约每小时刷新,提取后尽快解密,避免 key 失效
- 管理员权限:
find_all_keys.py必须管理员运行,否则读不到内存 - 杀软干扰:内存读取会被 Defender/杀软拦截,需临时放行或白名单
- 路径硬编码:定制脚本(export_/asr_/finalize_emoji*)都是硬编码路径,换联系人必须改,否则会覆盖旧数据
- WAL 残留:解密遇到 malformed 报错,先清理对应 .db 的 -wal/-shm
- 隐私:解密数据含完整聊天/语音/照片,仅用于本人合法用途
