Files
AgentsMeeting/gateway/linux/docs/architecture.md
T
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

9.0 KiB
Raw Blame History

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)
│   └─ 正常扫码登录(无版本封禁问题)
│
├─ 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-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.AppImage276MB,最新版)
  3. 系统依赖已安装:gdbxdotoolXvfb
  4. 原 Windows 版保留不动(gateway/scripts/wechat_agent.py
  5. Git 已初始化并 pushcommit 9c73e8b

待完成(接手后的工作)

Phase 1:验证微信能跑

# 启动虚拟显示器
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

# 伪代码 — 参考 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(最干净)

# 调用微信内部发送函数
call send_message_func("wxid", "消息内容")

需要找到微信的发送消息函数地址。

方案 Bxdotool GUI 自动化

# 找到微信聊天窗口,输入内容,按回车
xdotool search --name "微信" windowfocus
xdotool type "消息内容"
xdotool key Return

缺点是微信窗口需要在前台。

方案 Cxsel/xclip 剪贴板 + 快捷键

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/莫语不语):用户
  • 笑笑(xxmWindows 侧开发者,OpenCode 维护者