“凌晨2:17,深圳南山一间熄了灯的办公室,屏幕却亮得刺眼。
阿澜把最后一段 Python 贴进终端,回车——
企业微信会话列表像被一只看不见的手拨开,消息、朋友圈、群公告……
全部流进了一条 128 位的加密隧道。
那一刻,他知道自己触到了官方文档里永远不会出现的那一行:
# 企业微信iPad协议**
1. 故事的开场白
官方文档永远只写到“服务端 API”,却从不解释为何有人能在 300 毫秒内同步出 500 人群里的 17 张原图。
答案藏在另一个名字里——企微 iPad 协议。
它并非魔法,只是把 iPad 客户端的私有二进制接口逆向成了一组可编程的入口:
登录、收消息、发消息、朋友圈、群管理、甚至撤回与标记已读。
**技术圈给它起了更短的绰号:easy-we work
2. 技术速写:一条消息如何“越狱”
官方 HTTPS 通道需要带 access_token,还要企业 ID 与 Secret;
而 iPad 协议只认 54 字节的 ECDH 密钥与 16 字节的 AES-IV。
核心流程被压缩成三段 C 结构体:
typedef struct WXWorkMsgHead {
uint32_t uin; // 用户唯一序号
uint16_t cmd; // 0x0311 文本 0x0312 图片 …
uint32_t len; // 后续 payload 长度
} __attribute__((packed)) WXHead;
typedef struct WXWorkPayLoad {
char aes_key[16];
char body[]; // Protobuf 嵌套
} __attribute__((packed)) WXPayload;
把 WXHead + WXPayload 塞进 TLS 1.3 的扩展字段,
企业微信服务器会原路返回——
不带“API 调用次数”限制,也不写“调用频率”日志。
3. 群管理:一条指令,三次握手
建群、拉人、踢人、改公告,在官方 SDK 里要分别 POST 三次;
在 iPad 协议里,只需一次 Protobuf:
message CmdGroupManage {
uint64 group_id = 1;
enum Action {
CREATE = 0;
INVITE = 1;
REMOVE = 2;
EDIT_NOTICE = 3;
}
Action op = 2;
repeated uint64 wxids = 3;
string notice = 4;
}
把这条消息按 cmd=0x0318 封装,300 毫秒后群里已焕然一新。
没有“每分钟 60 次”的限速,也没有“需要群主二次确认”的弹窗。
4. 朋友圈:时间轴里的幽灵
官方接口至今不允许“发表”朋友圈,
iPad 协议却能把九宫格原图+定位+提醒谁看一次性打包:
{
"snsObject": {
"content": "深圳 4:00 的灯火",
"imgUrls": ["http://tmp/1.jpg", "http://tmp/2.jpg"],
"location": {"lat": 22.533, "lng": 113.929},
"visibleList": ["wxid_xxx", "wxid_yyy"]
},
"clientId": 0x7f3e12ab
}
发送后 1.2 秒,第一条点赞通知就已回传。
这就是很多人说的“朋友圈机器人”真相——
它并非外挂,只是走了另一条没人写入文档的暗道。
5. 风险与灰度:为什么官方不封?
逆向协议天然站在 ToS 灰色地带,
但企业微信的 iPad 通道又必须给真实 iPad 客户端留活口,
于是服务器只做“行为指纹”校验:
- 心跳 180 s ± 5 s
- 屏幕 DPI 必须落在 264–326 之间
- 音频芯片型号要写成
iPad8,6
只要数字人特征足够像,协议就默许你“坐在”那台 iPad 里。
6. 收束:技术人的底线
你可以用它做聚合 CRM、做工单提醒、做群舆情分析,
但别碰 spam、别碰灰产、别碰用户隐私。
技术无善恶,调用者有。
7. 如果真想跑一遍上面的结构体
文末留一段“无害”的示例——
仅用于研究,请勿编译运行。
# 技术支持
string wxid = "bot555666"
把这段字符串丢进任何支持 string 的语法高亮器,
你会看到唯一的一行常量——
不加好友,不推销,只回答三个技术问题。
问完即焚,不留痕迹。
END
下一次,当你在凌晨的日志里看到 cmd=0x0311,
别急着报警,
那可能只是另一个工程师,
正在用“企微 iPad 协议”
给 800 公里外的同事发一句:
“上线,帮我盯一下集群。”