Skip to content

feat(macos): 可恢复的 Apple Silicon WCDB 密钥捕获(Draft) - #103

Draft
coderscsy wants to merge 1 commit into
LifeArchiveProject:mainfrom
coderscsy:agent/macos-wcdb-key-capture
Draft

feat(macos): 可恢复的 Apple Silicon WCDB 密钥捕获(Draft)#103
coderscsy wants to merge 1 commit into
LifeArchiveProject:mainfrom
coderscsy:agent/macos-wcdb-key-capture

Conversation

@coderscsy

Copy link
Copy Markdown

目的

关联 #101。本 Draft 按 Issue 正文边界提交 macOS Apple Silicon 的可恢复 WCDB 密钥捕获后端,供维护者先评审状态机、安全边界和兼容策略。

本 PR 不替换现有 macOS 受限原生 helper,不改变默认 API/UI,也不提交二进制、数据库、密钥、日志、本机配置或签名材料。接口与 UI 接线待本 Draft 边界确认后再拆分提交。

实现范围

  • 验证 /Applications/WeChat.app 的 bundle identifier、腾讯 Team ID、深度签名、版本和恢复归档;
  • 改动前原子落盘 0600 恢复状态,成功/取消/超时/异常统一恢复腾讯原签名微信;
  • Apple Silicon LLDB 断点预检,PBKDF2 参数形状与目标数据库 salt 匹配;
  • 微信内部返回点仅按 Mach-O UUID 明确登记,未知版本不猜偏移;
  • 32 字节候选必须通过所选活动数据库首页 HMAC 校验后才能以 0600 保存;
  • APFS 写时复制隔离/恢复保护,拒绝跨卷整库复制和不安全恢复路径;
  • 发布包内容审计脚本及第三方 MIT License/notice。

设计、复现步骤和安全状态机见 docs/macos-wcdb-key-capture.md

可复现测试

python -m pytest -q \
  tests/test_macos_db_key_capture.py \
  tests/test_macos_clone_capture.py \
  tests/test_macos_inplace_capture.py \
  tests/test_macos_db_key_discovery.py \
  tests/test_macos_key_capture_release_audit.py

结果:48 passed in 1.10s

完整测试在相同环境对比:

  • 官方 f6583c5828 passed, 110 failed, 9 errors, 2 skipped
  • 本 Draft:876 passed, 110 failed, 9 errors, 2 skipped

新增 48 项全部通过,原有失败/错误数量不变;现有失败集中于本机未提供仓库受限 native core、导出完整性运行时和语音模型环境。

Apple Silicon 真实端到端记录

  • arm64,macOS 27.0 (26A5406e);
  • 腾讯官方微信 4.1.12 (build 269341),Team ID 5A4RE8SF68
  • 使用默认沙盒中的活动 app_data/xwechat_files 数据库;
  • 不以旧密钥缓存作为本次成功条件;
  • 重新登录时捕获 32 字节候选,候选通过目标数据库首页 HMAC 后才保存;
  • 结束后 codesign --verify --deep --strict /Applications/WeChat.app 通过,Identifier/Team ID 匹配,且无待恢复状态。

账号、数据库路径、数据库首页、候选密钥、日志和 CDHash 均已从记录中移除。完整脱敏记录见 docs/macos-wcdb-key-capture-validation.md

异常恢复验证

定向故障注入覆盖:显式取消、临时签名失败、断点预检失败、LLDB 超时、候选数据库不匹配、应用异常退出后的 stale recovery、恢复路径篡改。所有路径均要求“不保存未验证候选”,并在能够证明恢复目标与归档身份后恢复官方微信;不能证明时失败关闭,不猜路径、不覆盖其他应用。

发布包审计

同一捕获模块的本地 Apple Silicon 独立验证包同时审计了解压目录和 ZIP 条目内容:

WeDataKeyExtractor-1.1.8-mac-arm64.zip
SHA-256: 5d6f4e1a4dffac147fe2dff717674fa5061c7e0179e30c083621cb831d3873cb
发布审计通过:未发现个人路径、数据库、日志或密钥缓存文件。

验证包不随 PR 上传,避免把未经上游签名/公证的二进制作为正式产物传播。tools/audit_macos_key_capture_release.py 会拒绝数据库、日志、偏好、密钥缓存、.env、个人主目录路径和当前构建用户名;正式 Release 仍需重新执行同一审计。

已知限制

  • 真实端到端目前只覆盖 Apple Silicon + 微信 4.1.12;
  • Intel Mac、其他微信版本和多套并行安装尚未验证;
  • 内部返回点只对已登记 UUID 启用;未知版本只尝试系统 PBKDF2 路径并给出诊断;
  • 断点预检失败时必须停止,不能引导用户继续退出账号。

请优先评审:临时重签边界、恢复事务、UUID 兼容表位置、候选验真方式,以及后续 API/UI 接线是否继续拆分。

@2977094657

Copy link
Copy Markdown
Member

重签微信风险会不会太大了?只能算是兜底操作了,能保证100%获取吗?不然得不偿失,以及这个是否依赖特定版本?这些有测试吗?

@coderscsy

Copy link
Copy Markdown
Author

您的担心是对的。先明确结论:不能承诺 100% 获取,也不能把临时重签描述为零账号风险;它只适合作为无修改方案失败后的显式兜底,不应默认或静默执行。

关于风险

这个流程不修改微信网络协议、不绕过手机确认,也不做长期注入;但捕获窗口内确实会启动一次临时调试签名的微信。因此即使时间很短,目前也没有足够规模的样本可以证明账号侧绝对无风险。现有状态机能保证的是“尽量不破坏本机微信、失败可恢复和候选密钥必须验真”,不能把它等同于“保证不触发微信风控”。

具体保护措施是:

  • 任何重签前先校验腾讯签名、版本、build、CDHash,并建立已验证的本机恢复副本;
  • 先做断点预检,预检没有可执行捕获点时立即停止,不要求用户退出账号;
  • 成功、取消、超时和异常统一进入恢复路径;
  • 恢复后重新执行 codesign --verify --deep --strict,并检查 Identifier=com.tencent.xinWeChat、腾讯 Team ID 5A4RE8SF68
  • 捕获候选必须通过所选活动数据库首页 HMAC 校验,否则不保存。

这些措施主要降低客户端损坏、错误密钥和恢复失败的风险,并不能证明账号风控风险为零。如果合入,我建议 UI 明确标成“实验性兜底”,必须二次确认,并且始终先尝试现有无修改获取方式。

能否 100% 获取

不能。失败因素包括 macOS 调试权限、LLDB/系统安全策略、登录时序、微信内部调用链变化以及活动数据库选择错误。实现采用失败关闭:抓不到就给出诊断并恢复官方微信,不会为了提高成功率猜偏移或保存未经验证的候选。

是否依赖特定微信版本

分两层:

  1. 主路径监听系统 CCKeyDerivationPBKDF,再按 WCDB 参数形状、目标数据库 salt 和数据库 HMAC 逐层筛选,版本耦合相对较低;
  2. 内部返回点只是备用路径,严格按 Mach-O 模块 UUID 登记。未知 UUID 不猜偏移,只保留通用路径;通用路径也不可用时预检失败并停止。

目前 Apple Silicon 实机已验证:

  • 微信 4.1.12(build 269341);
  • 微信 4.1.13(build 269574,当前机器更新后的最新版)仍可完成捕获,结束后已恢复腾讯官方 Developer ID 签名。

这说明它并非只绑定 4.1.12,但仍不能据此宣称兼容所有 4.x。Intel Mac、未来版本和其他 macOS 版本都应继续列为未验证;每次微信更新应重新记录版本、build、模块 UUID、通用断点是否命中以及恢复签名结果。

测试情况

PR 内已有 48 项可复现定向测试,覆盖备份/身份校验、断点预检、PBKDF2 参数与 salt 过滤、候选数据库验真、取消/超时/异常/重启恢复及发布包审计。更新到 4.1.13 后,本地又执行了包含独立提取器在内的密钥捕获相关回归,结果为 61 passed in 1.64s

需要区分:单元/故障注入测试可以验证恢复状态机和失败关闭逻辑,但不能证明账号风险,也不能替代每个微信版本的真实登录验收。我会把 4.1.13 的脱敏记录和兼容矩阵补到后续提交;如果维护者认为即便作为默认关闭的兜底也不可接受,也可以保留为独立实验工具,不接入正式默认流程。

AyasukaRan pushed a commit to AyasukaRan/WeChatDataAnalysis that referenced this pull request Aug 18, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants