原理 / How it works
它是怎么做到的
一句话:被驱动的就是你本机那台已登录的正版微信本体,不是另造一个客户端。服务端看到的,是官方客户端用官方通道发的、版本完全自洽的流量——没有可被风控识别的「机器人」。
一、挂上真微信本体(开一个调试口)
wechat-use 用 macOS 的调试接口(LLDB / task_for_pid)挂上你已经在跑的那个微信进程。它不是一个新客户端,是你现成客户端的一只「外挂手」:不换 bundle、不重新扫码登录、不动 wechat.dylib 和聊天数据,登录态、账号、设备指纹自始至终都是那台官方微信的。这也是它对风控无感的原因——发消息的、收消息的,永远是那台设备上的官方微信本体。
唯一要动的一处:给 WeChat 主可执行文件打一个本地 ad-hoc 重签,把 get-task-allow 打开。腾讯官方签名把它设成 false,明确禁止 debugger 挂载——不重签,LLDB 就 attach 不上。重签只碰主二进制(WeChat.app/Contents/MacOS/WeChat),不动 dylib、不改 bundle id、不动登录态;微信自动更新会覆盖掉这个签名,届时重跑一次 init 会自动补回。
DevToolsSecurity,需 sudo);
② 给 WeChat 主程序 ad-hoc 重签放开 get-task-allow(需 sudo,只此一次;微信自动更新后重跑 init 再补);
③ 仅 send 需要:给终端授「辅助功能」权限(投递按键)。
wechat-use doctor 会逐项自检并弹出对应设置面板。二、抽一次 SQLCipher key
微信本地库是 SQLCipher 加密的。wechat-use init 只在首次挂上去,从真进程内存里把 32 字节 raw key 取出来,写进 ~/.wx-rs/。读内存这步靠上一步放开的 get-task-allow,不用 root(要 root 的只是那次 ad-hoc 重签)。之后所有读命令(会话 / 历史 / 图片)都用这把本地 key 直接解密本地库,不再碰进程。
三、纯后台发送,不走 UI 自动化
发消息不走任何 UI 自动化——不 activate、不抢焦点、不模拟点击。就两步:
- 投递内容:
CGEventPostToPid把按键直接送进目标进程的事件队列,与谁在前台无关,零焦点闪。 - 改路由 + 改内容:在微信自己的发送函数上装 auto-continue 断点,发送那一刻改内存里的收件人;再在应用层加密前的编码点把内容整个换成要发的——所以打字丢不丢字,发出去的永远是准的。
让微信自己的发送逻辑在真进程里跑,我们只在内存里改两个字段。
四、图片解密:key 是算出来的
微信 4.0+ 的图片是 V2 .dat 加密。破解它没去 RE 内存偏移,而是认出 AES key 根本不存在某处等你去读——它是从账号自身的信息按一个固定公式算出来的,跟微信版本无关。所以 wechat image get 微信关着也能离线解;要在线也能直接从内存 heap 捞已经解好的明文 JPEG。
所以
wechat-use = 挂真微信 + 抽一次 key + 纯内存改字段。没有协议模拟、没有第二个登录态、没有 UI 自动化的闪与抢焦点。它就是你的真微信,只是多了一只能被 agent 调的手。接着看 怎么接进你的 agent。