- Add Windows 4.1.x Config.Cipher pointer-chain key extraction with cross-chunk
MemoryPatternScanner and bounded blob XOR decoding; keys still require per-DB
page-1 HMAC verification before caching.
- Cache keys by account fingerprint + database relative path; db scan --save
skips memory scanning entirely once all discovered databases are cached.
- Add DbMessage model (localId, serverId, type, timestamp, sender, display name,
avatar, isSelf) read read-only from Msg_{md5(chat)} via SQLCipher with hex/zstd
content decoding and contact.db name resolution.
- CLI: db messages / db contacts / db schema with masked defaults; include the
earlier chat send --session wiring. 97 Core tests pass; real-machine validated.
3.9 KiB
3.9 KiB
完整消息模型:只读数据库消息读取与多账号密钥缓存(2026-09-06)
目标与边界
- 本阶段补齐「完整消息模型」:稳定消息 ID、发送者、时间戳、收发方向等 UIA 无法提供的字段,全部来自只读 SQLCipher 数据库。
- 不写数据库、不注入、不修改微信进程、不做登录绕过;密钥只通过页面 1 HMAC 校验后缓存。
- 一个机器多账号:密钥按「账号指纹 + 库相对路径」缓存,已缓存账号后续
db scan直接跳过内存扫描。
密钥提取(Windows 微信 4.1.13.63)
- 旧式明文十六进制扫描(ASCII/UTF-16)在该版本找不到可验证密钥。
- 新增 Windows 4.1.x 的
Config.Cipher只读指针链扫描:- 全内存找
com.Tencent.WCDB.Config.Cipher字符串地址; - 用字符串地址+长度组成的 16 字节对再次全内存定位对象节点(
节点基址 = 配对地址 - 0x10); - 沿节点
+0x28 → 配置指针 +0x88 → 数据指针 +0x8 / 长度 +0x10读回最多 1024 字节的加密配置块; - 固定 33 字节 XOR 掩码解码,提取
x'<64~192 hex>'字面量,候选密钥要求 ≥15 个不同字节且非全 0/全 FF; - 最终仍以每个目标库页面 1 HMAC 校验为准。
- 全内存找
MemoryPatternScanner处理跨分块/跨区边界匹配;所有读出的进程内存缓冲均清零。- 扫描结果:5 个进程、19,309 个候选、149,800 次校验 → 20 个数据库全部
PageHmacVerified,来源进程 8912。
多账号缓存
db scan --save先加载密钥缓存,计算「发现库 − 已缓存库」;无待办则scanned=false直接跳过(processCount/candidateCount=0)。- 第二次
db scan --save验证:scanned=false,缓存仍 20 个库,无需重扫。 - 缓存键大小写不敏感(Windows 路径);新账号/新库出现时才触发增量扫描。
消息模型与读取
- 消息表名:
Msg_{md5(chat_wxid)};在message/message_*.db、message/biz_message_*.db中定位。 - 只读查询列:
local_id, server_id, local_type, create_time, hex(message_content), WCDB_CT_message_content, real_sender_id,LEFT JOIN name2id得发送者 wxid。 - 内容解码:hex → UTF-8;压缩标记且带 zstd 魔数
28 b5 2f fd时用 zstd 解压(ZstdSharp.Port,Core 内跨平台)。 - 发送者显示名/头像:
contact/contact.db的contact表按 wxid 批量查remark → nick_name → username与small_head_url。 - 收发方向:账号根目录名
<wxid>_<random>前缀匹配发送者即IsSelf=true(AccountRootPath 指向db_storage,其父目录名才是账号目录)。 - CLI:
db messages --account <fp> --chat <wxid> [--limit] [--include-content]、db contacts、db schema;默认脱敏,--include-content才显示名称/内容/头像。
真机验收
- Windows 10.0.19044,微信 4.1.13.63,原交互会话 1(已解锁),唯一密钥缓存。
- 群聊名解析:
db contacts --contains 测试命中53271859539@chatroom,昵称「消息测试专用群组」。 - 消息读取:
db messages --chat 53271859539@chatroom --limit 6 --include-content返回 6 条:- 每条含
local_id(7–12)、server_id、type=1、RFC3339 时间戳、发送者、IsSelf、显示名、头像、内容。 - 内容正是此前本机发送的测试标记(
wx-agent-isolation-*、wx-agent-repeat-*、wx-agent-m6-listener-*),证明 hex/zstd 解码正确。 - 本机发送消息
IsSelf=true、senderName=Rogee;发送者名/头像经 contact.db 解析。
- 每条含
- Core:97/97 测试通过;Release 全量构建与 self-contained 发布 0 警告 0 错误。
- 密钥文件位于
%LOCALAPPDATA%\WxAgent\database-keys.json,ACL 仅当前用户;CLI 输出不含密钥。
尚未完成(本阶段之外)
- 通用发送能力、导航能力、合并聊天记录展开仍按顺序推进。
- 消息模型与 UIA 事件流的合并(实时新消息方向归属)不在本阶段。