用途与实际影响
这项功能怎样使用
为什么需要它
主号、副号可能有相同昵称和联系人;真实数据库仍在写入,直接解密查询也可能得到不一致页面。若身份和快照不先闭合,后面的消息再完整也可能来自错账号或半写状态。
举个实际例子
主号和副号里都有人叫“小王”,我只说一句“别拿错”。工具会先让我确定账号,再核对这个账号与本地资料确实是一套;身份有一点对不上就停,不会因为头像和昵称很像便把两边聊天拼起来。
最后我会得到什么
得到已核对的微信账号和一份稳定、只读的本机资料副本,后续查询才会使用它。账号或来源对不上时停下,不泄露账号解密信息,也不混主副号。
可直接使用
账号和本机来源能唯一对应,临时读取副本完整,才开始读消息。
需要确认
依赖或语音解码器缺失时分别报告;只影响相关功能,不说全部微信读取都坏了。
当前不可用
账号目录不唯一、配置不可读或本机资料正在变化时先停,不能猜一个相似账号。
从哪里开始
读取微信前先指明主号或副号与对象,或让 auto 只在唯一匹配时选。
需要准备什么
- 指定主号、副号,或允许唯一匹配时自动选定
- 要读的联系人或群
从开始到拿到结果
- 1
系统核对并处理
核对账号来源,复制本机加密库到临时位置完成只读快照和完整性检查,源库变化时停止。
- 2
交付与接续
交回与正确账号绑定的上下文;多匹配、解密或快照失败时不借另一账号补空。
技术实现与依据
这里保留实现、关键条件、精确入口、历史记录和验证结果。
环境检查可独立于账号运行;文字/图片与Python3.11语音分别验收关键规则与设计选择
primary / secondary 是配置身份,不从窗口、头像或昵称推断和修复。
配置不保存微信密钥明文,真实路径与承诺值只留本机。
源数据库与 WAL 不被写入;所有查询发生在临时快照。
Doctor 不打开数据库正文,也不输出路径或密钥。
某个依赖缺失只影响对应能力,例如 voiceDecoder unavailable 不等于文字上下文不可用。
本模块用到的名词
- DPAPI(Windows 数据保护接口)
- 让配置载荷只能由当前 Windows 用户在本机解开,不把密钥明文写入项目。
- Account identity commitment(账号身份承诺)
- 原生微信身份的 SHA-256;验证同一来源而不公开真实 wxid。
- WAL(数据库预写日志)
- SQLite 尚未合并进主文件的已提交页面;快照需要一并处理才能保持一致。
- query_only
- SQLite 连接明确禁止写入,所有查询都针对临时快照。
专业定义
primary / secondary 只是两个严格隔离的配置槽位;每次读取先核对来源身份承诺,再在临时目录准备通过完整性检查的只读快照。
解决什么
解决双账号串源、凭据明文、读写源数据库、活动 WAL 导致不一致和把体检冒充真实读取。
当前怎样实现
- accounts.json 固定两个槽位,每个提供 config_path、local_state_path 和两个来源身份承诺。
- Windows DPAPI 解开 Local State 中的本机 AES key,再解开 dbPath、decryptKey 与 myWxid。
- load_direct_source_identity 只接受一个与原生身份匹配的 db_storage 账号根。
- EncryptedPageCodec验证加密页面与WAL校验和,只合并已提交WAL前缀,保留源数据库/WAL只读;不以临时快照成功推断原会话或远端内容完整。
- 快照复制前后比较源文件大小和 mtime,最多 3 次;通过 PRAGMA quick_check 后只读 query_only。
执行流程
- 1
解析命令行、环境、本地设置或默认 accounts.json。
- 2
校验两个账号槽位和必需身份承诺。
- 3
使用当前 Windows 用户的 DPAPI 解开本机保护配置。
- 4
锁定唯一账号目录并生成身份承诺。
- 5
复制或解密数据库,合并 WAL,比较前后签名。
- 6
quick_check 通过后以 query_only 打开;任务结束清理临时目录。
边界
- 真实 config、Local State、数据库路径、wxid、解密 key 和承诺值不进入网页或 Git。
- 只有当前 Windows 用户有权访问的本人设备数据属于来源。
- Doctor 证明文件和依赖入口存在,不证明数据库身份或聊天读取成功。
- 主 CLI(命令行工具) 只支持 Windows 和 Python 3.14+。
失败与恢复
- 配置或 Local State 不可解密
- DirectCredentialError,读取前停止,不输出值。
- 账号目录零个或多个匹配
- local source account directory is ambiguous,不猜目录。
- 页面、HMAC、WAL 或 quick_check 失败
- SnapshotCopyError / EncryptedPageError,不查询部分快照。
- 源在三次快照期间持续变化
- bounded snapshot retries 失败,稍后重试,不写源。
真实入口
accounts.example.json两个隔离槽位和身份承诺的公开结构。
wechat_source.py · load_direct_source_identityDPAPI、配置解密和唯一账号根。
wechat_source.py · EncryptedPageCodec / DirectWeChatReader页面解密、WAL、临时快照与只读连接。
wechat_cli.py · command_doctor无正文环境体检与局部可用状态。
如何验证
- 当前 Doctor 返回 success、configuredAccounts=2、所需文件 2/2、依赖与 voiceDecoder available。
- test_reader_rejects_wrong_source_identity_commitment_before_reads 验证身份不匹配在正文前失败。
- test_account_config_requires_both_identity_commitments 验证两个承诺必需。
- test_doctor_is_body_free_and_requires_windows 验证 Doctor 不打开正文且限制平台。
与其他模块的关系
所有聊天、朋友圈、媒体和归档模块都以这里的账号身份与稳定快照为前提;它只建立可信来源,不拥有聊天语义。
