Skip to content

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

Merged
2977094657 merged 5 commits into
LifeArchiveProject:mainfrom
coderscsy:agent/macos-wcdb-key-capture
Aug 24, 2026
Merged

feat(macos): 可恢复的 Apple Silicon WCDB 密钥捕获(Draft)#103
2977094657 merged 5 commits into
LifeArchiveProject:mainfrom
coderscsy:agent/macos-wcdb-key-capture

Conversation

@coderscsy

@coderscsy coderscsy commented Aug 16, 2026

Copy link
Copy Markdown
Contributor

目的

关联 #101。根据维护者关于“接入前端,类似 Windows Hook 兜底”的评审意见,本 Draft 现在同时包含可恢复的 macOS Apple Silicon WCDB 密钥捕获后端及主程序前端接线。

前端兜底边界

  • 现有 macOS 受限原生 helper 始终优先,不改变默认获取方式;
  • 只有 helper 返回允许降级的运行时、版本或进程附加错误,才向用户展示 LLDB 兜底;
  • helper 完整性、签名或信任校验失败不会降级到 LLDB;
  • 前端必须再次展示临时重签、调试、安全提醒和非 100% 成功风险,用户明确确认后才进入三阶段流程;
  • status / prepare / preflight / capture / cancel API 仅接受运行 WCDA 的 Mac 本机回环连接,Tailscale/局域网客户端不能触发;
  • 候选先通过目标库校验,再通过同一账号 message + session 双库校验,之后才写缓存并回填前端;
  • 停止、切页、异常及下次进入解密页都接入同一恢复事务,恢复后校验腾讯 Team ID 与正式签名。

实现范围

  • 验证 /Applications/WeChat.app 的 bundle identifier、腾讯 Team ID、深度签名、版本和恢复归档;
  • 改动前原子落盘 0600 恢复状态,成功/取消/超时/异常统一恢复腾讯原签名微信;
  • Apple Silicon LLDB 断点预检,PBKDF2 参数形状与目标数据库 salt 匹配;
  • 微信内部返回点仅按 Mach-O UUID 明确登记,未知版本不猜偏移;
  • APFS 写时复制隔离/恢复保护,拒绝跨卷整库复制和不安全恢复路径;
  • 前端 helper-first 选择、显式风险确认、三阶段引导、停止恢复和遗留状态恢复;
  • 发布包内容审计脚本及第三方 MIT License/notice。

设计和复现步骤见 docs/macos-wcdb-key-capture.md

当前验证

137 passed in 1.56s
frontend: 30 passed
Nuxt production generate: passed

覆盖 helper 优先、允许/拒绝兜底错误分类、本机请求限制、分阶段 API 脱敏、互斥操作、取消/遗留恢复、完整账号验真后再缓存、前端流程与原有 macOS 捕获回归。

真实端到端记录仍按脱敏文档区分已验证版本与未验证环境;本 PR 不承诺 100% 获取、Intel Mac 或未来微信版本兼容,也不把账号风险描述为零。

已知限制

  • LLDB 兜底仅支持 Apple Silicon 且依赖 Xcode Command Line Tools;
  • 临时重签只能作为用户明确选择的实验性兜底;
  • 正式 Release 的 Developer ID、公证和是否默认展示入口仍由维护者决定;
  • 本 PR 不提交二进制、数据库、密钥、日志、个人路径、本机配置或签名材料。

@2977094657

Copy link
Copy Markdown
Member

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

@coderscsy

Copy link
Copy Markdown
Contributor 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
@2977094657

Copy link
Copy Markdown
Member

大概这周内合并

@coderscsy

Copy link
Copy Markdown
Contributor Author

已推送跟进修复 e33b124:增加微信 4.1.13 build 269578 的严格 rounds=2 HMAC-salt 捕获路径、隔离微信提前退出诊断及 2 项回归测试。定向测试结果为 50 passed in 1.13s。PR 继续保持 Draft;rounds=2 逻辑已验证,但该 build 的 clone 登录成功路径仍等待社区原环境复测,不宣称已完全解决静默退出。

@2977094657

Copy link
Copy Markdown
Member

看看能不能接入到前端,类似win那种hook兜底方式,现在看起来还是全在后端

@coderscsy

Copy link
Copy Markdown
Contributor Author

可以接入,方向可以参考 Windows Hook 兜底,但 macOS 需要保留本机权限边界。

当前已经完成的是“独立本地 GUI + 后端捕获状态机”,还没有接入 WCDA 主前端。现有流程已经覆盖环境检查、活动数据库选择、断点预检、退出登录、启动监测、重新登录、候选密钥校验以及腾讯官方版本恢复。

前端接入建议如下:

  1. 仅在桌面端、现有无修改获取方式失败后显示“macOS 实时捕获”入口;
  2. 前端负责步骤引导和状态展示,管理员授权、临时签名、断点捕获、数据库 HMAC 校验和恢复继续由本机后端执行;
  3. 捕获接口只允许 Electron/本机回环访问,远程浏览器和跨设备页面不可调用;
  4. 明文密钥绝不进入 HTTP 响应、前端状态、日志或 LocalStorage;后端验证成功后直接写入本机受限密钥存储,前端只收到 validated=true 和脱敏状态;
  5. 用户必须二次确认,成功、取消、超时或异常均自动恢复腾讯官方签名版本;
  6. 未知版本或断点不匹配时失败关闭,不猜偏移、不保存未经跨库校验的候选。

最新本地实测环境为 Apple Silicon、macOS 27.0、SIP 开启、微信 4.1.13 build 269578:第二次监测能够正常启动,重新登录时成功捕获并通过数据库校验,完成后恢复腾讯 Team ID 5A4RE8SF68 的官方签名,成功路径不再出现 SIGTRAP 崩溃。

如果这个交互和安全边界符合项目要求,我可以把现有独立提取器状态机拆成“本机受限接口 + Nuxt/Electron 步骤页面”提交;密钥始终留在后端,不暴露给浏览器。

@2977094657

Copy link
Copy Markdown
Member

直接接入到主前端,方便测试

@coderscsy

Copy link
Copy Markdown
Contributor Author

已按建议直接接入 WCDA 主前端,最新提交为 24ca099,当前 PR head 为 e412579

入口位于主解密页面:现有无修改 helper 仍然优先,只有在允许降级的错误下才显示“macOS 实验性实时捕获”。前端已接入 status / prepare / preflight / capture / cancel 完整流程,包括风险确认、断点预检、登录引导、停止恢复和遗留状态恢复。

捕获接口仅允许运行 WCDA 的 Mac 本机回环连接调用,Tailscale、局域网和跨设备浏览器均无法触发。密钥通过当前账号的消息库与会话库校验后保存,并按 Windows 端现有交互填入本机前端输入框;不会写入日志、LocalStorage 或返回给远程客户端。

本地重新执行相关回归测试,结果为 73 passed in 1.22s。可以直接使用 PR 最新版本从主解密页面测试;如需调整入口位置或交互文案,我再继续修改。

@2977094657
2977094657 marked this pull request as ready for review August 24, 2026 04:47
@2977094657
2977094657 merged commit a605caf into LifeArchiveProject:main Aug 24, 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