README_LOCAL.md
WeChat 本地闭环测试套件 — Pixel Termux 版
目标:在 Pixel 手机本地(Termux / Ubuntu proot)实现微信消息的监控-响应-发送全流程,不依赖 Mac 远程 adb。
文件清单
| 文件 | 用途 | 执行环境 |
|---|---|---|
hermes_wechat_daemon.py |
主守护进程:DB 轮询 → 新消息检测 → LLM 处理 → 发送回复 | Ubuntu proot |
test_env.py |
环境预检:验证所有依赖(su, sqlcipher, sqlite3, am, frida) | Ubuntu proot |
test_db_poll.py |
DB 轮询测试:验证复制+解密+增量读取 | Ubuntu proot |
test_send_msg.py |
发送消息测试:验证 am broadcast 本地触发 LSPosed 模块 |
Ubuntu proot |
test_frida_local.py |
Frida 本地 attach 测试:验证 get_local_device() 捕获 key |
Ubuntu proot |
run_all_tests.sh |
一键运行全部测试 | Ubuntu proot |
test_termux_api.py |
Termux API 测试:通知读取、剪贴板、电量 | Termux / proot |
setup_termux_boot.sh |
Termux Boot 启动脚本(开机自启) | Termux |
NOTIFICATION_STRATEGY.md |
通知监听策略说明 | - |
config.json |
运行时配置(DB 路径、密钥、轮询间隔等) | Ubuntu proot |
快速开始
1. 部署到 Pixel
在 Mac 上:
# 方式 A:adb push 到 Termux home
cd /Users/yibo/Documents/aipcrm/wechat_plain/scripts
adb push local-testkit /sdcard/hermes/local-testkit
# 然后在 Pixel 的 Termux 中:
cp -r /sdcard/hermes/local-testkit ~/local-testkit
cd ~/local-testkit
或者方式 B(直接 zip 上传):
cd /Users/yibo/Documents/aipcrm/wechat_plain/scripts
zip -r local-testkit.zip local-testkit
adb push local-testkit.zip /sdcard/Download/
# 在 Termux 中 unzip
2. 运行环境预检
cd ~/local-testkit
python3 test_env.py
预期输出所有 [OK],如果有 [FAIL] 按提示修复。
3. 运行全部测试
chmod +x run_all_tests.sh
./run_all_tests.sh
4. 启动守护进程(测试全部通过后)
# 编辑配置
nano config.json
# 启动 daemon
python3 hermes_wechat_daemon.py
架构说明
消息监控:DB 轮询(主推方案)
┌─────────────────┐ ┌──────────────┐ ┌──────────────┐
│ 微信 EnMicroMsg │────→│ su -c cp DB │────→│ sqlcipher 解密│
│ (SQLCipher) │ │ + WAL + SHM │ │ │
└─────────────────┘ └──────────────┘ └──────────────┘
│
▼
┌─────────────────┐ ┌──────────────┐ ┌──────────────┐
│ LLM 处理回复 │←────│ 新消息检测 │←────│ sqlite3 查询 │
│ (Kimi/Claude) │ │ (msgId > last)│ │ message 表 │
└─────────────────┘ └──────────────┘ └──────────────┘
│
▼
┌─────────────────┐ ┌──────────────┐ ┌──────────────┐
│ /system/bin/am │────→│ LSPosed 模块 │────→│ NetSceneSendMsg│
│ broadcast │ │ Broadcast RX │ │ 发送消息 │
└─────────────────┘ └──────────────┘ └──────────────┘
轮询间隔默认 10 秒,可配置。
消息发送:am broadcast → LSPosed
已有 LSPosed 模块 HermesWeChatModule 在运行,只需本地触发 broadcast:
/system/bin/am broadcast \
-a com.hermes.wechat.SEND_MSG \
--es toUser "filehelper" \
--es content "测试消息"
Key 更新:Frida 本地 attach
微信重启后 key 可能变化,daemon 内置 key 失效检测和自动重捕获:
device = frida.get_local_device() # 不是 get_usb_device()
pid = device.spawn(["com.tencent.mm"]) # 或 attach 已有进程
配置说明(config.json)
{
"db_src_path": "/data/data/com.tencent.mm/MicroMsg/xxxxxxxx/EnMicroMsg.db",
"db_copy_dir": "/sdcard/hermes/dbs",
"sqlcipher_key": "e03ce81",
"cipher_compatibility": 1,
"cipher_page_size": 1024,
"poll_interval_sec": 10,
"llm_provider": "kimi-coding",
"llm_base_url": "https://api.kimi.com/coding",
"llm_api_key": "sk-...",
"llm_model": "kimi-for-coding",
"auto_reply_enabled": true,
"auto_reply_contacts": ["filehelper"],
"log_level": "INFO"
}
故障排查
Q: su 命令找不到或权限不足?
A: 确保 Magisk 已安装,并在 Magisk Manager → 设置 → SuList 中授予 Termux/proot root 权限。
Q: am broadcast 执行成功但微信没收到?
A: 检查 LSPosed 模块是否启用且作用域包含微信。查看日志:su -c "cat /data/adb/lspd/log/verbose_*.log | grep HermesWX | tail -20"
Q: sqlcipher 解密失败?
A: 确认 key 正确(运行 test_frida_local.py 重新捕获),并检查 WAL 文件是否复制。微信运行时 DB 被锁定,必须通过 cp 复制后再解密。
Q: DB 复制成功但 sqlite3 查询为空?
A: 可能 WAL 文件未复制或未及时 checkpoint。检查 EnMicroMsg.db-wal 是否存在。
Q: Termux API 命令找不到?
A: 在 Termux 中运行 pkg install termux-api,并安装 Termux:API 应用。在 proot 容器内可能需要通过 /data/data/com.termux/files/usr/bin/termux-* 完整路径调用。
Termux API 双通道监听(补充方案)
除了 DB 轮询,还可以利用 Termux:API 的通知读取能力实现实时消息触发:
# 读取通知栏
/data/data/com.termux/files/usr/bin/termux-notification-list
混合策略:
termux-notification-list每 3 秒轮询一次- 发现微信新通知 → 立即触发一次 DB 轮询(获取完整内容)
- LLM 处理 →
am broadcast发送回复
详见 NOTIFICATION_STRATEGY.md。
开机自启(Termux:Boot)
复制启动脚本到 Termux boot 目录:
cp setup_termux_boot.sh ~/.termux/boot/start-hermes-wechat.sh
chmod +x ~/.termux/boot/start-hermes-wechat.sh
重启手机后自动:启动 frida-server → 启动微信 → 启动守护进程。
测试报告模板
运行 run_all_tests.sh 后,会在 test_report.json 生成结构化报告:
{
"timestamp": "2026-05-22T18:00:00",
"env": {"su": true, "sqlcipher": true, "sqlite3": true, "am": true, "frida": true},
"db_poll": {"last_msg_id": 12345, "new_messages": 3, "ok": true},
"send_msg": {"sent": true, "method": "am_broadcast"},
"frida": {"key_captured": true, "key_hex": "65303363653831"},
"overall": "PASS"
}
请将此报告内容贴回给 Claude,用于进一步分析和优化。