Files
zhiwei 255729bb8c docs: complete handover documentation for Mohe
重写 architecture.md 含:
- 完整方案评估(GDB vs LD_PRELOAD vs wine vs iLink)
- 所有信息源链接和参考价值
- 当前状态检查清单(已完成/待完成)
- 分 Phase 的实施指南
- 常见问题和风险说明
- 项目文件结构

更新 README.md 指向架构文档
2026-06-23 23:12:47 +08:00

230 lines
9.0 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# MoWeChat — 莫荷微信 Bot (Linux GDB Hook 版)
## 项目定位
将莫荷的微信 Bot 从 Windowswxhelper DLL 注入)迁移到 **Linux 服务器上原生运行**
**核心约束(已和老爸确认):**
1. 不能走 ClawBot/iLink 通道(那个是独立的 Bot 身份,不是莫荷本人微信号)
2. 不能走 wine(3.9.x 微信登录被腾讯封了)
3. 不能用 Windows 降版本工具(已经坏了)
4. 必须拦截发给莫荷微信号的所有消息(跟之前 wxhelper 一样)
5. 不使用任何 Web/逆向协议方案(被封号风险高)
## 技术方案
### 最终方案:官方 Linux 微信 + GDB Hook
```
Linux 服务器
├─ 微信 Linux AppImage(腾讯官方出品,最新版 x86_64)
│ └─ 正常扫码登录(无版本封禁问题)
├─ GDBGNU 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-11)** | https://aajax.top/2026/03/11/GettingLinuxWechatMessages/ | **核心参考。** 用 GDB 调试 Linux 微信 AppImage v4.1.0.16IDAPRO+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 方案的详细讲解 |
### 已排除的方案
| 来源 | 链接 | 排除原因 |
|------|------|----------|
| 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 微信登录被腾讯封了 |
## 当前状态(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 已初始化并 pushcommit `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 解决了接收问题。发送消息有三种可能的方案:
**方案 AGDB call(最干净)**
```gdb
# 调用微信内部发送函数
call send_message_func("wxid", "消息内容")
```
需要找到微信的发送消息函数地址。
**方案 Bxdotool GUI 自动化**
```bash
# 找到微信聊天窗口,输入内容,按回车
xdotool search --name "微信" windowfocus
xdotool type "消息内容"
xdotool key Return
```
缺点是微信窗口需要在前台。
**方案 Cxsel/xclip 剪贴板 + 快捷键**
```bash
echo "消息内容" | xclip -selection clipboard
xdotool key ctrl+v
xdotool key Return
```
**方案 DLD_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 维护者