--- name: wechat-internal-send description: 通过 LSPosed 内部 API 发送微信文字/图片/语音(调用微信自己的发送 API,无 UI 模拟点击) version: 1.0 category: communication --- # WeChat 内部 API 发送(文字 / 图片 / 语音) 通过 LSPosed 模块 `wechathook` 直接调用微信自己的内部发送 API,**不模拟点击、不走无障碍**。 逆向自微信 8.0.74。完整技术文档见 `../WECHAT_SEND_API.md`。 ## When to Use - 用户要求「发微信」「发条消息/图片/语音给某人」 - 需要程序化、无 UI 干扰地发微信(agent 自动发通知、日报、提醒) ## 前置:拿到 wxid 内部 API 认 **wxid(username)不认昵称**。从解密的 `EnMicroMsg.db` 查 `rcontact`: ```bash # key = MD5("1234567890ABCDEF"+uin)[:7];本机 uin=215004919 → key=e03ce81 sqlcipher EnMicroMsg.db <<'EOF' PRAGMA key='e03ce81'; PRAGMA cipher_compatibility=1; PRAGMA cipher_page_size=1024; SELECT username,nickname FROM rcontact WHERE nickname LIKE '%火星人%'; EOF # → yibooo(火星人的 wxid) ``` > ⚠️ 先只对 `filehelper`(文件传输助手,自己)测试,确认无误再发真人,避免账号风险。 ## 能力与用法 ### ✅ 文字(中英文,已验证送达) ```bash # ASCII adb shell su -c 'am broadcast -a com.hermes.wechat.SEND_MSG_INTERNAL --es to yibooo --es text "hello"' # 中文(base64 避免 shell 损坏 UTF-8) B64=$(python3 -c "import base64;print(base64.b64encode('你好'.encode()).decode())") adb shell su -c "am broadcast -a com.hermes.wechat.SEND_MSG_INTERNAL --es to yibooo --es text_b64 '$B64'" ``` 或用封装脚本:`./wechat_send.sh text yibooo "你好火星人"` ### ✅ 图片(全图 CDN 上传打通,已验证全分辨率送达) ```bash adb shell su -c 'am broadcast -a com.hermes.wechat.SEND_IMAGE_INTERNAL --es to yibooo --es path /sdcard/Pictures/x.png' ``` 或用封装脚本:`./wechat_send.sh image yibooo /sdcard/Pictures/x.png` 图片走微信自己的 CDN 上传,接收方点开是全分辨率原图(可保存)。`path` 必须是设备上 `su` 能读到的路径(如 `/sdcard/...`)。发前若图片在 Mac 上,先 `adb push` 到设备。 2026-07-07 真机验证:filehelper + 真人(火星人)均全图收到。详见技术文档 §3。 ### ✅ 语音(TTS→SILK,全合成,无录音/无 hot-swap) ```bash adb shell su -c 'am broadcast -a com.hermes.wechat.SEND_VOICE_CGI --es to yibooo --es src_path <设备上SILK> --ei duration 3000' ``` 或用封装脚本(自动把 SILK stage 进 WeChat 数据目录):`./wechat_send.sh voice yibooo /path/to.silk 3000` 走微信内部 `uploadvoice` cgi:音频内联上传 + 投递给接收方,同时插发送方本地已发送气泡。 真机验证:接收方(火星人/Mac)收到能播 + 发送方本地正常显示。SILK 来源 = edge-tts→ffmpeg 16k mono→silk-wasm。**SILK 须 WeChat 进程可读**——封装脚本已处理(stage 进 `/data/data/com.tencent.mm/files/` + chown WeChat uid + restorecon);直接 `/sdcard` 会 EACCES。 旧的半自动 hot-swap(`../tts_voice_swap.sh` + `ARM_VOICE_SWAP`)已被全合成取代,可弃用。 ## 不要做 - **不要用 `dk5.s5.Ni` 发文字**——那是发名片的(会得到失败的空名片)。 - **不要自己实现编解码 / 缩略图 / CDN 上传**——都是 hook 内部的事。 - **不要假设 base.apk = 正在跑的码**——真实代码在 Tinker 补丁里,hook 要用 `sTinkerCL`。 - **不要用 force-stop 后查库验证送达**——SIGKILL 不 flush 加密 WAL,查不到最新。用实时截图/肉眼确认。 ## 部署 / 重建 hook ```bash export ADB=/opt/homebrew/share/android-commandlinetools/platform-tools/adb export ANDROID_HOME=/opt/homebrew/share/android-commandlinetools export JAVA_HOME=/opt/homebrew/opt/openjdk@17 bash ../rebuild_wechathook.sh # 编译+签名+安装+重启微信 ``` ## 相关 - `../WECHAT_SEND_API.md` — 完整逆向技术文档(内部 API 结构、踩坑、图片链路) - `../wechathook_src/WeChatHook.java` — hook 源码 - memory `wechat-voice-send-internals.md` — 逆向记录 + 踩坑史