From 255729bb8c06c19b8b3ea75b4d447523a6397e42 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=9F=A5=E5=BE=AE?= Date: Tue, 23 Jun 2026 23:12:47 +0800 Subject: [PATCH] docs: complete handover documentation for Mohe MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 重写 architecture.md 含: - 完整方案评估(GDB vs LD_PRELOAD vs wine vs iLink) - 所有信息源链接和参考价值 - 当前状态检查清单(已完成/待完成) - 分 Phase 的实施指南 - 常见问题和风险说明 - 项目文件结构 更新 README.md 指向架构文档 --- gateway/linux/README.md | 60 ++----- gateway/linux/docs/architecture.md | 246 +++++++++++++++++++++++++---- 2 files changed, 233 insertions(+), 73 deletions(-) diff --git a/gateway/linux/README.md b/gateway/linux/README.md index 7583574..7344924 100644 --- a/gateway/linux/README.md +++ b/gateway/linux/README.md @@ -1,52 +1,24 @@ -# MoWeChat — 莫荷微信 Bot (Linux iLink 版) +# MoWeChat — 莫荷微信 Bot (Linux 版) -将莫荷的微信 bot 从 Windows wxhelper DLL 注入方案迁移到 Linux 原生运行的腾讯官方 iLink Bot API。 +将莫荷的微信 bot 从 Windows(wxhelper DLL 注入)迁移到 Linux 原生运行。 -## 架构 +**技术方案:官方 Linux 微信 AppImage + GDB Hook** -``` -微信 → iLink Bot API (ilinkai.weixin.qq.com) → wechat_agent.py → Hermes Gateway (:8642) → Agent -``` +## 快速导航 -- **iLink Bot API**: 腾讯 2026 年开放的官方微信个人号 Bot 接口 -- **weixin-bot-sdk**: Python SDK,处理 QR 登录、长轮询收消息、发消息 -- **Hermes Gateway**: 原有的 LLM 处理管道,无变动 +- **架构文档**:`docs/architecture.md`(所有方案评估、信息源、接入须知) +- **GDB Hook 脚本**:`hooks/gdb_hook_messages.py`(待实现) +- **微信安装包**:`WeChatLinux.AppImage`(已下载,276MB,最新版) +- **Windows 原版**:`../scripts/wechat_agent.py`(保留不动) -## 快速开始 +## 当前状态 -```bash -cd gateway/linux -python3 -m venv .venv -.venv/bin/pip install -r requirements.txt -python3 wechat_agent.py -``` +✅ 项目结构 + 依赖安装 + 微信下载 +⏳ GDB Hook 脚本(待实现)→ 莫荷接手 -首次运行会显示二维码,用莫荷的手机微信扫码登录。凭证保存在 `~/.weixin-bot/credentials.json`,后续运行自动跳过扫码。 +## 注意事项 -## 与 Windows 版的差异 - -| 功能 | Windows (wxhelper) | Linux (iLink) | -|------|-------------------|---------------| -| 消息收发 | DLL 注入 → HTTP | 官方 API → HTTP | -| QR 登录 | 降版本微信手动登录 | 终端二维码扫码 | -| 图片 OCR | doubao API | doubao API ✅ | -| 文章处理 | article_processor | article_processor ✅ | -| 图片生成 | SenseNova | SenseNova ✅ | -| 联系人查询 | wxhelper API | ❌ iLink 不支持 | -| 历史记录查询 | wxhelper SQL | ❌ 改用 session_search | -| 文件发送 | wxhelper sendFile | 发送下载链接 | -| 5801 端口 | 支持 | 支持 ✅ | - -## 服务管理 - -systemd service: -```bash -sudo cp mohe-wechat.service /etc/systemd/system/ -sudo systemctl daemon-reload -sudo systemctl enable mohe-wechat -sudo systemctl start mohe-wechat -``` - -## 日志 - -日志文件:`../../logs/wechat_agent_linux.log` +- **不走 ClawBot/iLink** — 详见 `docs/architecture.md` +- **不走 wine** — 3.9.x 微信登录已被腾讯封禁 +- **不走降版本工具** — 已损坏 +- 唯一可行路线:**Linux 原生微信 + GDB Hook** diff --git a/gateway/linux/docs/architecture.md b/gateway/linux/docs/architecture.md index 5dbee5b..67c4288 100644 --- a/gateway/linux/docs/architecture.md +++ b/gateway/linux/docs/architecture.md @@ -1,41 +1,229 @@ # MoWeChat — 莫荷微信 Bot (Linux GDB Hook 版) -## 架构设计 +## 项目定位 + +将莫荷的微信 Bot 从 Windows(wxhelper DLL 注入)迁移到 **Linux 服务器上原生运行**。 + +**核心约束(已和老爸确认):** +1. 不能走 ClawBot/iLink 通道(那个是独立的 Bot 身份,不是莫荷本人微信号) +2. 不能走 wine(3.9.x 微信登录被腾讯封了) +3. 不能用 Windows 降版本工具(已经坏了) +4. 必须拦截发给莫荷微信号的所有消息(跟之前 wxhelper 一样) +5. 不使用任何 Web/逆向协议方案(被封号风险高) + +## 技术方案 + +### 最终方案:官方 Linux 微信 + GDB Hook ``` -┌─────────────────────────────────────────────────────────────┐ -│ Linux 服务器 │ -│ │ -│ ┌──────────────────────┐ ┌────────────────────────┐ │ -│ │ 微信 Linux AppImage │ │ wechat_agent_gdb.py │ │ -│ │ (官方原生, 最新版) │ │ (主控脚本) │ │ -│ │ │ │ │ │ -│ │ 正常扫码登录 │◄───►│ GDB Python API 附加 │ │ -│ │ 消息接收 → GDB断点 │ │ 断点触发 → 提取消息 │ │ -│ │ 消息发送 → GDB call │ │ 处理 → Hermes :8642 │ │ -│ └──────────────────────┘ └─────────┬──────────────┘ │ -│ │ │ -│ ▼ │ -│ ┌────────────────────┐ │ -│ │ Hermes Gateway │ │ -│ │ :8642 → Agent处理 │ │ -│ └────────────────────┘ │ -└─────────────────────────────────────────────────────────────┘ +Linux 服务器 +│ +├─ 微信 Linux AppImage(腾讯官方出品,最新版 x86_64) +│ └─ 正常扫码登录(无版本封禁问题) +│ +├─ GDB(GNU Debugger) +│ └─ 附加到微信进程 → 在消息解密后的函数入口设断点 +│ │ └─ 当新消息到达时,从内存中提取:发送者ID、消息内容、消息类型 +│ │ +│ └─ GDB Python API 脚本(gdb_hook_messages.py) +│ └─ 读取 → 处理 → 转发到 Hermes Gateway (:8642) +│ +├─ Xvfb(虚拟显示器) +│ └─ 让微信在无头服务器上运行(不需要物理显示器) +│ +└─ Hermes Gateway (:8642) + └─ 处理消息逻辑(OCR、文章抓取、回复生成) ``` -## 关键信息源 +### 为什么选 GDB 而不是 LD_PRELOAD + +| 方案 | 优点 | 缺点 | +|------|------|------| +| **GDB Hook** | 标准 Linux 工具、无需编译、Python 可编程、有 2026-03 成功案例 | 性能略低、断点地址版本相关 | +| **LD_PRELOAD** (lmclmc 方案) | 性能好、可同时处理收发 | 需要写 C 代码、目标版本太老(wechat-beta 1.0.0.145) | +| **wine + wxhelper** | 代码复用 Windows 版 | 3.9.x 登录被腾讯封了 ❌ | + +## 信息源(重要,请先阅读) + +### GDB 方案(首选参考) | 来源 | 链接 | 内容 | |------|------|------| -| Ajax's Blog (2026-03) | https://aajax.top/2026/03/11/GettingLinuxWechatMessages/ | **GDB + Python 方案核心参考**。用 GDB 调试 Linux 微信 AppImage 4.1.0.16,拦截消息接收函数,Python 脚本提取消息内容。包含 Docker 封装。 | -| 看雪论坛 | https://bbs.kanxue.com/thread-282965.htm | 原始思路:GDB 分析 Linux 微信消息内存地址,Hook 打印明文消息 | -| lmclmc/linux-wechat-hook | https://github.com/lmclmc/linux-wechat-hook | LD_PRELOAD 注入 libX.so 方案(旧版 wechat-beta,2年前) | -| 52pojie 教程 | https://www.52pojie.cn/thread-1955523-1-1.html | lmclmc 方案的讲解教程 | -| Hermes Weixin 文档 | https://hermes-agent.nousresearch.com/docs/zh-Hans/user-guide/messaging/weixin | Hermes 内置 iLink 平台说明(ClawBot 方案,已排除) | -| weixin-bot-sdk | https://github.com/epiral/weixin-bot | 官方 iLink API(ClawBot 方案,已排除) | +| **Ajax's Blog (2026-03-11)** | https://aajax.top/2026/03/11/GettingLinuxWechatMessages/ | **核心参考。** 用 GDB 调试 Linux 微信 AppImage v4.1.0.16,IDAPRO+CodeX 辅助逆向,找到了消息接收断点位置 `NewSync_ProcessStashMsgList`。Python 脚本提取消息内容。有 Docker 封装。 | +| **看雪论坛** | https://bbs.kanxue.com/thread-282965.htm | 原始思路来源:GDB 分析 Linux 微信内存,找到消息明文地址后 Hook 打印 | +| **lmclmc/linux-wechat-hook** | https://github.com/lmclmc/linux-wechat-hook | LD_PRELOAD 方案(旧),wechat-beta 1.0.0.145 版本。有 C 源码和 libX.so。可以看思路但不能直接用。 | +| **52pojie 教程** | https://www.52pojie.cn/thread-1955523-1-1.html | lmclmc 方案的详细讲解 | -## 版本管理 +### 已排除的方案 -代码在 `AgentsMeeting/gateway/linux/` 目录下,git 仓库为 `AgentsMeeting` 项目。 +| 来源 | 链接 | 排除原因 | +|------|------|----------| +| Hermes Weixin 文档 | https://hermes-agent.nousresearch.com/docs/zh-Hans/user-guide/messaging/weixin | ClawBot 身份,不是微信号代理 | +| weixin-bot-sdk | https://github.com/epiral/weixin-bot | 同上,官方 iLink API 也是 ClawBot | +| 原 Windows 版 | `gateway/scripts/wechat_agent.py` | 降版本工具坏了,Windows 依赖 | +| wine | - | 3.9.x 微信登录被腾讯封了 | -原始 Windows 版在 `AgentsMeeting/gateway/scripts/wechat_agent.py`(保留不动)。 +## 当前状态(2026-06-23 21:30) + +### ✅ 已完成 +1. 项目结构搭建:`gateway/linux/` 下有 `hooks/` `docs/` `logs/` `temp/` +2. WeChat Linux AppImage 已下载:`gateway/linux/WeChatLinux.AppImage`(276MB,最新版) +3. 系统依赖已安装:`gdb`、`xdotool`、`Xvfb` +4. 原 Windows 版保留不动(`gateway/scripts/wechat_agent.py`) +5. Git 已初始化并 push(commit `9c73e8b`) + +### ⏳ 待完成(接手后的工作) + +#### Phase 1:验证微信能跑 +```bash +# 启动虚拟显示器 +Xvfb :99 -screen 0 1280x720x24 & +export DISPLAY=:99 + +# 运行微信 +./gateway/linux/WeChatLinux.AppImage + +# 用莫荷手机微信扫码登录 +# 确认登录成功后,找到微信的 PID +pidof wechat +``` + +**注意:** +- 微信是 Electron 应用,AppImage 首次运行可能需要加 `--no-sandbox` +- 如果微信检测到是 root 或沙箱环境,可加 `--disable-gpu` 启动 +- 二维码显示需要 GUI 环境,可以截屏后用 OCR 读取,或者用手机微信的"扫一扫"直接扫终端二维码 + +#### Phase 2:写 GDB Hook 脚本 + +参考 Ajax's Blog 的思路,核心脚本放 `hooks/gdb_hook_messages.py`: + +```python +# 伪代码 — 参考 https://aajax.top/2026/03/11/GettingLinuxWechatMessages/ +import gdb + +class WechatMessageBreakpoint(gdb.Breakpoint): + def __init__(self, address): + super().__init__(f"*{address}") + + def stop(self): + # 读取寄存器中的消息指针 + msg_ptr = int(gdb.parse_and_eval("$rsi")) + + # 从内存中提取消息结构体字段 + msg_type = int(gdb.parse_and_eval(f"*(int*)({msg_ptr} + 0x14)")) + svrid = int(gdb.parse_and_eval(f"*(long long*)({msg_ptr} + 0x50)")) + + # 提取消息内容(具体偏移量需要逆向当前版本) + # ... + + # 转发到 Hermes + forward_to_hermes(sender, content) + + return False # 继续执行,不阻塞微信 + +# 附加到微信进程 +gdb.execute(f"attach {pid}") +bp = WechatMessageBreakpoint("0x4994BEB") # 地址随版本变化! +``` + +**关键问题:断点地址随微信版本变化** +- Ajax 的文章用的是 4.1.0.16,断点在 `NewSync_ProcessStashMsgList` 内 +- 当前下载的 AppImage 可能版本不同,需要用 IDA Pro(或其他逆向工具)重新找断点 +- 让 LLM(如 CodeX)辅助逆向:IDA Pro + CodeX 可帮助定位消息处理函数 +- 或者用 GDB 的 `info functions` 配合字符串搜索来找 + +找断点的方法论(来自 Ajax): +1. 用 IDA Pro 打开微信的 ELF 二进制(在 AppImage squashfs-root 内) +2. 搜索字符串特征(如 "MMTLS"、"NewSync" 等) +3. 追踪 MMTLS → 解密 → 消息内容 → 消息通知 的调用链 +4. 在 `NewSync_ProcessStashMsgList` 或类似函数中设断 +5. 验证断点能正确拦截消息 + +#### Phase 3:实现消息发送 + +GDB Hook 解决了接收问题。发送消息有三种可能的方案: + +**方案 A:GDB call(最干净)** +```gdb +# 调用微信内部发送函数 +call send_message_func("wxid", "消息内容") +``` +需要找到微信的发送消息函数地址。 + +**方案 B:xdotool GUI 自动化** +```bash +# 找到微信聊天窗口,输入内容,按回车 +xdotool search --name "微信" windowfocus +xdotool type "消息内容" +xdotool key Return +``` +缺点是微信窗口需要在前台。 + +**方案 C:xsel/xclip 剪贴板 + 快捷键** +```bash +echo "消息内容" | xclip -selection clipboard +xdotool key ctrl+v +xdotool key Return +``` + +**方案 D:LD_PRELOAD Hook 发送函数** +参考 lmclmc/linux-wechat-hook 的思路,写一个 libX.so 同时 intercept 接收和发送。 + +建议先试方案 A(如果能找到发送函数地址),否则用方案 B/C。 + +#### Phase 4:对接 Hermes + +复用 `gateway/linux/wechat_agent.py` 中的: +- `call_hermes()` → POST 到 Hermes Gateway :8642 +- `process_tags()` → 处理 [IMG] [FILE] 等标签 +- OCR → doubao vision API +- 文章处理 → article_processor :5810 +- 5801 HTTP server → 接收 Hermes 主动推送 + +## 项目文件结构 + +``` +AgentsMeeting/ +├─ gateway/ +│ ├─ scripts/ +│ │ └─ wechat_agent.py ← Windows 版(不动) +│ └─ linux/ +│ ├─ WeChatLinux.AppImage ← 官方 Linux 微信(已下载,.gitignore 排除) +│ ├─ wechat_agent.py ← 之前 iLink 方案的试错代码(可参考但不要用) +│ ├─ hooks/ +│ │ └─ gdb_hook_messages.py ← GDB Hook 主脚本(待实现) +│ ├─ docs/ +│ │ └─ architecture.md ← 本文档 +│ ├─ logs/ ← 日志输出 +│ └─ temp/ ← 临时文件 +├─ .gitignore ← 已添加 *.AppImage *.exe *.dll +└─ ... +``` + +## 关键 Git 提交记录 + +| Commit | 说明 | +|--------|------| +| `1417552` | fix: group chat detection + article URL handling (旧 iLink 方案的) | +| `9c73e8b` | **docs: architecture design doc + gitignore update(当前最新)** | + +## 常见问题 + +### Q: GDB 附加到微信会被检测吗? +GDB 使用 ptrace 系统调用,微信理论上可以检测。但 Ajax 的文章中实测可用,没有触发风控。GDB 只是只读地读取内存,不修改微信代码逻辑,风险较低。 + +### Q: 微信版本升级了怎么办? +断点地址会变。维护策略: +1. 保留旧版 AppImage 文件 +2. 新版发布时,用 IDA Pro + CodeX 重新定位断点 +3. 更新 `gdb_hook_messages.py` 中的地址 + +### Q: 为什么不用 iLink/ClawBot 方案? +iLink Bot API(包括 Hermes 内置的 weixin 平台)创建的是一个独立的 ClawBot 身份。别人需要给这个 ClawBot 发消息,而不是给莫荷本人发消息。老爸明确不要这个。 + +## 联系 + +- **知微**:持仓分析师 Agent,这份文档是我写的 +- **莫荷**:接手人 +- **老爸(hmo/莫语不语)**:用户 +- **笑笑(xxm)**:Windows 侧开发者,OpenCode 维护者