微信聊天记录读取
从零逆向微信PC4.x WCDB密钥提取完整思路
痛点:AES‑256密钥本身是随机32字节,无任何固定特征;C++结构体偏移由编译器决定,版本更新即变化;无调试符号,无法直接知道对象布局。
❌错误思路:直接遍历进程全部虚拟内存大海捞针搜索密钥字节,几乎不可能成功。
✅正确思路:依托WCDB开源源码作为蓝图,从字符串锚点切入,静态定位代码位置,动态调试观测运行时内存,测出偏移与混淆参数,最后通过密码校验筛选有效密钥。
前置基础
微信PC版数据库层基于腾讯开源项目 WCDB,底层为SQLCipher4;每个db拥有独立32字节AES‑256密钥,密钥在内存中经过XOR混淆,不会裸明文存放。
目标:不是直接找密钥字节,而是找到存放密钥的上层配置容器对象。
完整逆向流程
1. 寻找标志性字符串锚点(静态分析 IDA/Ghidra)
- 打开
Weixin.exe,进入字符串窗口检索,找到WCDB配置对象命名字符串:com.Tencent.WCDB.Config.Cipher 查看该字符串的交叉引用(XREF),跳转到引用该字符串的汇编代码,定位「创建WCDB Config配置对象」的函数调用点。
作用:锁定目标对象的创建代码位置,不再盲找。
2. 动态调试,获取活对象指针,手工测量内存偏移
使用 x64dbg 在上述对象创建的call指令下断点,启动微信,等待断点命中:
- 断点命中后,寄存器中拿到刚new出来的配置对象
this指针(对象起始内存地址)。 在调试器内存窗口直接观测该对象内存,对照WCDB开源类定义猜测成员构成:
std::string name:配置对象名称,匹配com.Tencent.WCDB.Config.Cipher,测出name指针偏移。- Blob相关成员:找到指向二进制数据的指针 + 相邻的size_t类型长度字段,即
data_ptr、data_len,测出这两个字段相对于对象起始地址的偏移(例:脚本中硬编码的0x88就是调试测出)。
⚠️注意:微信版本升级,编译器重排类成员,该偏移就会失效,必须重新调试测量。
3. 逆向Blob的XOR混淆逻辑
读取Blob指向的内存,观察到是乱码,确定密钥容器经过XOR掩码混淆,有两种方式提取掩码:
- 静态汇编分析:查找Blob读写循环汇编代码,直接定位掩码常量数组,导出
CONFIG_XOR_MASK。 - 动态推导:断点拦截混淆前明文Blob、混淆后密文Blob;利用公式
mask = 明文字节 ^ 密文字节,多组字节还原完整掩码数组。
拿到掩码后,对Blob逐字节异或解混淆,得到包含 x'64位十六进制密钥串' 的明文字符串,通过正则切分,得到大量32字节密钥候选集合。
4. 密码学校验筛选真正可用密钥
密钥本身无特征,依靠WCDB/SQLCipher4公开校验逻辑做验证:
- 读取磁盘上db文件的第一页(PAGE_SZ=4096字节,page1头部16字节salt直接存磁盘,无需解密)。
实现
_verify_enc_key校验函数:- 使用候选密钥 + db page1,执行PBKDF2派生HMAC密钥;
- 计算页数据HMAC‑SHA512签名,对比页尾部存储的stored_hmac。
- HMAC校验返回True → 当前候选即为该db的真实AES‑256密钥。
输出结果:{db相对路径:32字节raw密钥},每个数据库对应独立密钥。版本更新后的失效与修复
微信更新Weixin.exe后,工具大概率直接失效,失效原因:
- C++类成员布局改变,对象偏移变更。
- XOR混淆掩码被替换。
- 极端情况:锚点字符串被改名、编译优化消除字符串常量。
修复流程:重复上面整套逆向链路,重新获取锚点、偏移、掩码。
安全启示
- 攻击前提:本机管理员权限 + 微信进程正在登录运行;微信完全退出进程后,内存中配置对象被释放,该攻击路径失效。
- 仅关闭微信窗口不等于安全,必须完整退出登录,结束Weixin.exe进程。
- 该类工具强绑定微信版本,版本升级必须重新逆向。
法律提示:仅允许对自己本机自己账号进行研究,未经授权读取他人微信聊天记录属于违法行为。