Files
wx-win-agent/docs/validation/Database-Merged-Chat-2026-09-06.md
T
rogee 30df7ae433 feat: expand merged chat records directly from read-only databases
Add db merged with exact account/chat/local-ID selection and shard ambiguity checks. Preserve Int64 composite message types and parse bounded, DTD-free embedded record XML, including duplicate messages and source metadata. Revalidate cached keys against current page-1 HMAC; replace the SQL write probe with sqlite3_db_readonly. Core tests: 129 passed. Windows Session 0 database validation: 5/5; all 16 text/sender/source-ID/timestamp entries matched independent XML parsing. Read-only UI baseline: 3/3; zero sends.
2026-09-06 20:10:04 +08:00

42 lines
3.6 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
## 调用方式
```text
WxAgent.Host db merged --account <account-fingerprint> --chat filehelper --local-id 149
WxAgent.Host db merged --account <account-fingerprint> --chat filehelper --local-id 149 --include-content
```
可选 `--database <relative-path>` 消除不同消息分库 local ID 重复时的歧义;支持 `--key-file``--timeout`。只使用既有账户密钥缓存,不调用内存扫描器,也不打开聊天窗口。
默认返回父记录身份、条目路径、类型、脱敏发送人标识、原消息 ID、时间戳和正文长度;正文、显示名称、合并标题和描述为 null。`--include-content` 显式启用正文/名称。源 `hashusername` 不是可确认的真实 wxid,因此不把它伪装为 wxid。
## 实现与安全
- 将数据库 `local_type` 模型和转换从 Int32 修正为 **Int64**;实测合并类型为 `81604378673`。原先直接读取此记录会发生 Int32 溢出。
- 精确按聊天表及 `local_id` 参数查询,逐个消息分库检查;多处命中必须显式选择分库,不返回第一个碰巧匹配的消息。
- 解析 `appmsg/type=19 → recorditem → recordinfo/datalist/dataitem`,保留顺序、重复正文、原始字符串 ID、秒级 Unix 时间、显示时间和发送人名称。嵌套记录拥有独立路径,不把重复 dataid 当作去重依据。
- XML 禁止 DTD/外部实体,限制文档字符数、深度、嵌套记录层数及总条目数。声明数量与实际不符、文本缺失、非法时间等明确报错,不用空结果掩盖损坏。
- Hex/Zstd 解码有尺寸上限,避免压缩消息无限膨胀。
- 每次 SQLCipher 打开前,缓存密钥重新通过**当前目标数据库 page-1 HMAC**校验;连接仍为 `Mode=ReadOnly``query_only=ON`
- 移除原来的 `CREATE TABLE` 写拒绝探针,改为读取 `sqlite3_db_readonly`,不尝试任何数据库写入。打开失败时也释放连接。
- 仅输出允许的附件元数据,不导出 CDN 地址/AES 密钥,不下载附件或绕过协议。
## 真机验收
- 微信 `4.1.13.63`Windows `10.1.1.101`
- 最终发布:`C:\Users\Rogee\wx-agent\releases\db-merged-20260906T120104`
- EXE SHA-256`5DB6A6422F6DAD9AE76C6C4D5A522576C7B7EB0534396434A536190D4E0DEEF8`
- Linux **129/129 Core 测试通过**,完整 Release build 无警告/错误。
- `Test-DatabaseMerged.ps1`**SSH Session 0** 运行,5/5 通过:默认脱敏输出、显式正文输出、数据库只读状态、非法 ID、缺失 ID。数据库读操作无需微信所在交互桌面;没有在 Session 0 执行 UI 自动化。
- 既有交互会话另行执行 doctor、inspect-ui、`smoke --read-only`3/3 通过。
- 文件传输助手中父记录 local ID **149** 展开 **16 条文本消息**
- 用独立 Python XML 解析器逐条对照数据库原始嵌入 XML:正文、发送人、原始消息 ID、时间戳 **各 16/16 完全一致**
- 全程发送/转发次数 **0**。完整正文仅保留于忽略的私有验证产物,不进入 Git。
脱敏证据:[`evidence/Database-Merged-20260906/`](evidence/Database-Merged-20260906/)。第一次验证脚本误读 `metadata.WritesRejected` 的嵌套层次,修正脚本后同一二进制通过;并非数据库接受了写入。
## 验收范围
真实样本为 16 条文本;嵌套记录、附件元数据、恶意/截断 XML、重复条目和解压上限有离线测试。尚无混合图片/视频/文件、嵌套合并的真机样本;附件正文/原文件下载不属于本次展开结果。字段缺失保留 null,不补造身份或时间。