Files
wx-win-agent/docs/validation/Message-Model-2026-09-06.md
T
rogee fb8c25c83c feat: database-backed message model with multi-account key cache
- 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.
2026-09-06 14:35:19 +08:00

51 lines
3.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 完整消息模型:只读数据库消息读取与多账号密钥缓存(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 事件流的合并(实时新消息方向归属)不在本阶段。