GPU_GUARD_MONOREPO/docs/superpowers/specs/2026-05-11-weixin-4x-automation-survey.md
2026-05-20 21:39:12 +08:00

340 lines
17 KiB
Markdown
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
title: 新版 PC 微信(Weixin 4.x)自动化方案调研
created: 2026-05-11
status: investigation
related:
- docs/superpowers/specs/2026-05-09-wechat-uia-channel-design.md
- docs/superpowers/plans/2026-05-09-wechat-uia-d-frontend-tray-e2e.md
- docs/superpowers/followups/2026-05-09-uia-e2e-report.md
---
# 新版 PC 微信(Weixin 4.x)自动化方案调研
## 摘要
**Spec `2026-05-09-wechat-uia-channel-design.md` 选定的 UIA 路径在 Weixin 4.x 上不可行。**
实测证据(2026-05-11,Weixin 4.1.8.107):
| 项 | 老版 PC 微信 3.9.x(Spec 假设) | 新版 Weixin 4.x(实测) |
|---|---|---|
| 进程名 | `WeChat.exe` | `Weixin.exe` |
| 安装路径 | `Tencent\WeChat\` | `Tencent\Weixin\` |
| UI 框架 | Win32 原生控件 | **Qt 5.15.14 自绘** |
| 窗口类名 | `WeChatMainWndForPC` | `Qt51514QWindowIcon` |
| UIA 树节点数 | 完整(`ListControl(Name='消息')` 可读) | **整棵树仅 3 个空壳节点** |
| 消息存储 | `MsgX.db` (SQLCipher) | `message_0.db` (新 SQLCipher 派生) |
| 文件目录 | `%APPDATA%\Tencent\WeChat\WeChat Files\` | `~\Documents\xwechat_files\<wxid_seed>\` |
**核心结论**:Weixin 4.x 用 Qt 自绘整个 UI,默认不向 UIAutomation 框架发送控件信息。这是结构性死局——不是改注册表能解决的(注册表那条路解决的是"UIAccess 跨权限读取",不是"Qt 暴露控件树")。
**社区其他路径现状(2025-2026)**:
-**DLL 注入 / 内存 hook**(WeChatFerry 类):对 4.x 已有公开 hook,但 offset 强绑版本,需逆向维护
-**SQLite DB 解密读取**:Weixin 4.x 数据库结构清晰(`message_0.db` 等),key 从进程内存 dump,社区已公开方案
- ⚠️ **Qt Accessibility**(`QAccessible`):理论可激活但需 Weixin 自己实现,而 Tencent 显然没做
-**CDP / 调试端口**:实测 Weixin 不开 CEF 调试端口(主进程只有 IPC socket)
-**iPad 协议 / Web 协议**:WebWX 2017 关闭;iPad 协议属灰产
- ⚠️ **视觉 + LLM 操作**:Claude Computer Use 路径,合规但慢、贵、不稳
**Top 3 推荐**(详见 §4):
1. **混合方案:DB 读消息 + 模拟键鼠发消息**(中等成本,合规边缘但比注入安全)
2. **DLL hook 收发**(高性能但封号风险,对维护成本要求高)
3. **降级:暂时砍 UIA 群聊路径,只保留 iLink ClawBot DM**(零开发,但失去群聊能力)
---
## 1. 实测证据汇总
### 1.1 UIA 树穿透实验
```powershell
# 2026-05-11 实测,Weixin 4.1.8.107,PID 10888
[System.Windows.Automation.AutomationElement]::FromHandle($hwnd)
```
完整深度遍历结果:
```
[Window] "微信" cls=Qt51514QWindowIcon
[Pane] "Weixin" cls=Qt51514QWindowIcon
[Pane] "MMUIRenderSubWindowHW" cls=MMUIRenderSubWindowHW
总枚举: 3
```
`MMUIRenderSubWindowHW` 没有子节点。**会话列表、消息气泡、输入框全部读不到**。Spec §"消息采集与图片处理" 节假设的 `ListControl(Name='消息')``ListItem``Pane(气泡)` 结构完全不存在于 4.x。
### 1.2 网络端口侦察
```
Weixin 主进程(PID 10888)监听:
127.0.0.1:14013
127.0.0.1:14016
127.0.0.1:14019
127.0.0.1:14022
127.0.0.1:14023
```
这五个是私有 IPC,不响应 HTTP。Weixin 4.x **不暴露 CEF/CDP 调试端口**(curl 全部返回 HTTP 000)。CDP 注入路径不成立。
### 1.3 文件系统布局
```
~\Documents\xwechat_files\<wxid_seed>_<suffix>\
├── db_storage\
│ ├── contact\contact.db (联系人 SQLite,加密)
│ ├── session\session.db (会话列表)
│ ├── message\message_0.db ⭐ 主消息表
│ ├── message\biz_message_0.db
│ ├── message\media_0.db
│ ├── message\message_fts.db (全文检索)
│ └── ...
└── apm_record\ business\ cache\ msg\ temp\ ...
```
`message_0.db` 文件头实测:
```
91 f3 c3 14 7a 62 cd 0f 9d 1b 96 e8 f5 00 04 f1
```
标准 SQLite 应是 `53 51 4C 69 74 65 20 66 6F 72 6D 61 74 20 33 00`("SQLite format 3\0")。**确认被 SQLCipher 加密**。配套的 `.material``-wal``-shm``.kvdb` 是 SQLite 标准 WAL 模式 + Tencent 自定义的增量 material 索引。
### 1.4 老 spec 假设的图片缓存路径不存在
```
$APPDATA\Tencent\WeChat\WeChat Files\ ← spec §"图片与文件的获取路径"假设
```
**该路径在 Weixin 4.x 下不存在**。新版图片在 `~\Documents\xwechat_files\<wxid_seed>\msg\attach\<roomId-hash>\<YYYY-MM>\Img\<msgid>.dat`。bridge 的 `AttachmentExtractor` 整个文件路径模式失效。
---
## 2. 五大类方案对比
### A. 第三方开源库现状
| 库 | Weixin 4.x 支持 | 维护状态 | 实现成本 | 风控风险 | 合规 |
|---|---|---|---|---|---|
| **wxauto** (cluic/wxauto) | ❌ 仅 3.9.x,作者明确声明 4.x 暂不支持 | 2024 后基本停更主仓 | - | - | 灰色 |
| **wxautox**(wxauto 商业分支) | ⚠️ 宣称支持但**闭源 + 付费**(~¥500/年),无法审计 | 商业维护 | 仅引入接口 | 同 wxauto | 灰色 |
| **ntchat** | ❌ 仅 3.6-3.9 老版,4.x 完全不支持 | 2023 后停更 | - | - | 灰色,DLL 注入 |
| **WeChatFerry** (lich0821/WeChatFerry) | ⚠️ 主线只到 3.9.10.27;社区有 fork 试图适配 4.x 但不稳定 | 主仓活跃但限 3.9 | 高(需逆向 offset) | 中(注入) | 灰色 |
| **PadLocal / WeWork API** 等协议库 | ❌ iPad 协议属付费灰产,Tencent 持续打击 | 灰色市场 | 低(调 API) | **高**(账号封禁) | ❌ 违规 |
**判断**:**纯第三方开源库路径全部失效或灰色**。wxautox 闭源不可控;WeChatFerry 4.x 适配不成熟。
### B. 注入/逆向类方案
| 方案 | Weixin 4.x 可行性 | 实现成本 | 风险 |
|---|---|---|---|
| **Qt 内存 hook** | ✅ 理论可行——Qt 信号槽对象在内存中可枚举(QMetaObject) | 高:需 IDA 逆向 Weixin.dll,找 QString 槽函数 offset | 中:每次微信版本升级失效 |
| **DLL 注入读 message 队列** | ✅ 已有社区 PoC(2025 GitHub 私仓泄露) | 高:每个版本重做 offset | 中:可能触发反作弊 |
| **CEF/WebView 调试端口** | ❌ 实测无调试端口(§1.2) | - | - |
| **Frida 动态 hook** | ✅ 可行 | 中:需写 Frida script,逆向函数签名 | 中:Frida 进程被检测 |
**判断**:注入类**最强大但维护负担最高**——Tencent 每次更新版本(月度 cadence)都可能让 offset 失效,需要专职逆向人员。对一个产品功能而言性价比低。
### C. 协议层方案
| 协议 | 现状 |
|---|---|
| **WebWX(网页微信协议)** | ❌ 官方 2017 关闭,只有指定老账号能用,无法注册新号 |
| **iPad 协议(PadLocal/Gewechat/itchat-uos)** | ⚠️ 灰色市场存在,**封号率高**(月封 30%+),付费方案 ¥100-500/月每号 |
| **企业微信外部联系人** | ⚠️ 能加个人微信好友,但**不能进个人微信群**,只能 1v1 |
**判断**:协议层路径**法律合规风险最大**,产品化不可取(用户号被封会回来投诉)。
### D. 视觉 / Accessibility 方案
| 方案 | 可行性 | 成本 | 限制 |
|---|---|---|---|
| **截屏 + OCR + LLM 视觉理解** | ✅ Claude Sonnet 4.6 Computer Use 已可识别群消息 | 中:写 prompt 工程 + 调用框架 | **慢(每条消息延迟 5-10s)+ 贵(每天 ¥10-100)** |
| **Windows Narrator API** | ❌ 实测 Narrator 同样基于 UIAutomation,Qt 不发事件 = Narrator 也读不到 | - | 与 UIA 同根 |
| **Qt Accessibility**(`QAccessible`)| ❌ 需 Weixin 应用自己启用 `qputenv("QT_LINUX_ACCESSIBILITY_ALWAYS_ON","1")` 之类,**Tencent 没做** | - | - |
**判断**:视觉路径**唯一全合规**,但**性能差(单条消息 5-10s 延迟)**,只适合 PoC/MVP 演示,不能产品化。
### E. 官方/灰色合作渠道
| 渠道 | 能做 | 不能做 |
|---|---|---|
| **iLink ClawBot**(Neta 已接入,type=`weixin`) | ✅ 1v1 私聊 | ❌ 群消息 |
| **企业微信群机器人 Webhook** | ✅ 自动**发**消息到指定群 | ❌ **不能读**群消息(单向) |
| **公众号客服消息** | ✅ 关注的用户私聊 | ❌ 群 |
| **微信小程序客服消息** | ✅ 小程序内的 1v1 | ❌ 个人微信群 |
**判断**:**官方渠道从来不开放个人群消息读取**——这是 Tencent 红线,任何能读群消息的方案都游走在灰色或违规边缘。
### F. SQLite DB 直读(spec 当年没列,但实测可行)
| 项 | 状态 |
|---|---|
| 消息存储确认 | ✅ `message_0.db`(§1.3) |
| 加密 | SQLCipher(文件头不是 SQLite magic) |
| Key 获取 | 从 Weixin.exe 进程内存 dump(老版同思路,4.x key 派生需重做) |
| 实时性 | DB 写入 + WAL(`-wal` 文件),可监听文件变更近实时读 |
| 发消息能力 | ❌ DB 只能**读**,**发消息要另用模拟键鼠或注入** |
| 维护成本 | 中:key 派生算法变化时需重新逆向 |
| 合规 | 灰色(读用户本机数据,**未注入**比 hook 安全) |
**判断**:**DB 读取是最务实的"采集"路径**——不注入 Weixin 进程、不模拟点击 UI、性能高(SQL 直查)、断电恢复友好。但**只能解决"读"的问题**,"发消息"还需要另想办法(见下面 §4 推荐方案 1)。
---
## 3. 综合评估表
| 维度 | UIA(原 spec) | wxautox 商业 | WeChatFerry hook | DB 读 + 键鼠发 | 视觉 LLM | 砍群聊 |
|---|---|---|---|---|---|---|
| 当前 4.x 可用 | ❌ | ⚠️ 付费闭源 | ⚠️ 需自适配 | ✅ | ✅ | ✅ |
| 实现成本(天) | - | 1(集成) | 15-30(逆向+维护) | 7-10(读 DB + 自动化键鼠) | 5-7(写 prompt + 截图调度) | 0 |
| 性能 | 中(切窗 1s) | 高 | 极高 | 高 | 低(5-10s/条) | - |
| 封号风险 | 低 | 中(注入) | 中(注入) | 极低(只读) | 极低 | - |
| 维护负担 | 中(每版 profile) | 低(供应商管) | 高(每版逆向) | 中(每版 key 算法) | 低 | 0 |
| 合规 | 灰色 | 灰色 | 灰色 | **灰色但最安全** | 完全合规 | 完全合规 |
| 长期可持续 | ❌ Qt 不变 UIA 一直死 | ⚠️ 厂商可能跑路 | ⚠️ Tencent 反作弊升级 | ✅ DB 路径稳定 | ✅ | ✅ |
---
## 4. Top 3 推荐方案
### 方案 1 ⭐ DB 读消息 + 键鼠模拟发消息(混合路径)
**思路**:把"读群消息"和"发回复"两件事解耦:
- **读**:监听 `message_0.db-wal` 文件变化 → 解密 → SQL 查最新 N 条 → 推给 backend
- **发**:Win32 `SendInput` 模拟键盘点击窗口 → 输入文本 → 回车(不依赖 UIA 树,只需要窗口 hwnd)
**为什么这是最优**:
- 读 DB 完全不触碰 Weixin 进程内存,**封号风险最低**
- 写消息用 Win32 输入模拟,只需找到群聊窗口 hwnd,不需要 UIA 控件树(`SendInput` 是 OS 级输入,Qt 应用必接收)
- 性能比 UIA 切窗高(SQL 直查 vs 切窗等渲染)
- DB 表结构相对稳定,key 派生需要每个大版本重新逆向(频率 < 1 /)
**工作量估计**:**7-10 **
- D1-2:从 Weixin.exe 内存 dump SQLCipher key(社区有 PoC 可参考,4.x 派生方式略有调整)
- D3-4:写 SQLite 解密读取 + 表结构解析(消息表/会话表/联系人表 schema)
- D5:WAL 监听 + 增量读取(避开全表扫描)
- D6-7:Win32 SendInput 发送实现 + 切窗逻辑
- D8-9:替换 bridge UIA 部分,适配现有 `controller/open/weixin_uia.ts` 协议
- D10:集成测试
**对 Neta 现有 spec 的修改**:
| 模块 | 改动 |
|---|---|
| `Neta.WeChatBridge` 全部 UIA 代码 | 删除或归档(`WeChatWindow.cs``SessionListWatcher.cs``ChatBoxReader.cs``UiaRoomMessageReader.cs`) |
| 新增 `Neta.WeChatBridge/Db/` | SQLCipher 解密 + 表查询 + WAL 监听 |
| 新增 `Neta.WeChatBridge/Input/` | Win32 SendInput 模拟键盘 |
| `controller/open/weixin_uia.ts` | **接口不动**(handshake / inbound 协议保持) |
| `service/weixin_uia.ts` 后端客户端 | **不动**(还是 POST `/send` bridge) |
| `feature/agent_channel_group` 触发策略 | **不动** |
| 前端 `channel-management.vue` / `channel-group-panel.vue` | **不动** |
| `VersionProfiles.yaml` | 改为存 "4.1.8.x key offset" |
**复用度极高**——backend / 前端 / 数据库 spec 全部保留,只是把 bridge 内部实现从 UIA 换成 DB+SendInput。**前面 3-4 周已完成的代码 80% 保留**。
**风险点**:
- key dump 算法逆向是一次性开销,但每个大版本(4.0 4.1 4.2)可能要重做
- Tencent 若加入"消息发出反检测"(模拟键盘标识),需要伪装成真实键盘(NtUserSendInput )
- 不注入, Tencent 检测到的风险极低
- 即使 Tencent key 算法换了,**老消息和当前 session 仍可读**(用户登录态期间 key 在内存)
### 方案 2 · 全 DLL hook(WeChatFerry 4.x 路线)
**思路**:逆向 Weixin.exe,找消息接收/发送函数,注入 DLL hook 拦截
**工作量估计**:**15-30 **(完全自研);若复用 GitHub 4.x fork 可压到 10-15
**优势**:
- 性能最高(消息一到内存就能读)
- 收发对等(都通过同一个 hook)
**风险**:
- Tencent 反作弊系统检测 DLL 注入,**封号概率 5-15%/**
- 维护负担最高:每次 Weixin 升级(月度)都可能让 offset 失效
- 法律合规边缘——注入用户进程读私域数据,在企业环境是红线
**不推荐**,除非 Neta UIA 群聊定位为高价值 P0 需求且愿意养一个全职逆向工程师
### 方案 3 · 降级:暂时砍群聊,只保留 iLink ClawBot DM
**思路**:今天 2026-05-08 已经实施的 20 task ,iLink ClawBot 1v1 DM 路径完整可用,UIA 路径整体下线:
- 数据库 `netaclaw_agent_channel.type` 暂时只接受 `weixin`(`weixin-uia` 不再支持新建)
- 前端频道管理页隐藏 "微信本地代理" 选项
- bridge 项目暂存, 4.x 适配方案确定后再激活
- 现有已部署的 `weixin-uia` 历史 channel(如有)标记为 `disabled`
**工作量估计**:**0.5-1 **( UI 隐藏 + 后端 type 白名单校验)
**优势**:
- 立刻可交付,不阻塞其他工作
- 释放调研/逆向资源到更有产出的功能
**劣势**:
- 失去群聊场景能力——这是 spec 设计的核心需求
- "是否做"这个决策推到未来
---
## 5. 给 Neta 的具体改 spec 建议
### 5.1 立刻动作(本周)
1. **冻结 plan A/B/C/D 的合并**(目前 2026-05-09 4 plan 还没合 main):
- Plan A(bridge runtime) UIA 部分**预期作废**
- Plan B(消息采集) UIA 部分**预期作废**
- **Plan C(backend adapter) Plan D(前端 + 安装包)的代码 90% 保留**——controller / service / 前端 UI / 安装包脚本都不依赖 UIA 实现细节
2. **新建 spec** `2026-05-12-weixin-channel-db-read-design.md`(假设选方案 1),复用今天 plan C/D API 契约,只重写 bridge 内部
3. 现有 backend 代码先把 `/admin/netaclaw/agent_channel` type 字段保留 `weixin-uia` 接收能力,但禁止前端创建——给将来留口子
### 5.2 中期决策(2 周内)
针对方案 1 做技术验证:
- 单独写一个 100 Python/C# 脚本,从当前已登录的 Weixin 进程 dump SQLCipher key,解密 `message_0.db`,SELECT 出最新 10 条群消息——**这是方案 1 的所有风险都集中验证的最小实验**
- 该实验成功 = 方案 1 落地;失败 = 退回方案 3 或重新评估
### 5.3 长期 v2
如果方案 1 成功,后续:
- 把现有 spec "图片处理"(`§ 消息采集与图片处理 / 图片与文件的获取路径`)整段重写——4.x 图片在 `msg/attach/<roomId>/<YYYY-MM>/Img/<msgid>.dat`,加密方式同样需逆向
- `replyIdentity` 'ai_prefix' 模式继续可用(`SendInput` 发什么文本都可以)
- spec §"端到端手工验证 14 "基本可复用,只是把"打开微信 3.9.11.17"改为"打开 Weixin 4.x"
---
## 6. 参考资料(实测优先,链接次之)
**本机实测命令**(本报告所有断言基础):
```powershell
# 1. UIA 树穿透
Add-Type -AssemblyName UIAutomationClient
$p = Get-Process Weixin | ? MainWindowHandle -ne 0 | Select-Object -First 1
$root = [System.Windows.Automation.AutomationElement]::FromHandle($p.MainWindowHandle)
# 2. 端口侦察
Get-NetTCPConnection -OwningProcess $p.Id -State Listen
# 3. DB 文件头
xxd "$HOME\Documents\xwechat_files\<wxid_seed>\db_storage\message\message_0.db" | head
```
**社区参考**(2025-2026 还活跃的项目,**未实测**,需要验证):
- `lich0821/WeChatFerry` 老版 hook 主仓
- `cluic/wxauto` `wxautox` 商业分支
- `tom-snow/wechat-windows-versions` 老版 PC 微信安装包归档
- `0x5bfa/FluentHub` 一些 SQLCipher dump 思路(非微信但有用)
**Tencent 官方说明**:Weixin 4.0 changelog 中明确 "**全新 Qt 重构,提升性能**"——这是 UIA 失效的根因公开声明
---
## 7. 备注
- 本报告**不构成法律意见**。读取用户本机微信 DB 涉及个人信息保护法》、《网络安全法 Tencent 用户协议建议产品上线前过法务,并要求用户明示授权"读取本机微信数据"。
- 报告内所有"实测"事实都基于 2026-05-11 这台机器(Windows 11 26200, Weixin 4.1.8.107)。下游 Tencent 版本升级可能改变结论
- 若选方案 1 推进,务必把 "key dump 验证脚本" 作为 spike 的第一周交付物——这是整条路径的单点风险