- 即时通讯
- 桌面应用
- 逆向工程
【免费下载链接】WeChatPlugin-MacOS
微信小助手
导读:本文以 CHANGELOG.md 为骨架,系统梳理微信小助手 WeChatPlugin-MacOS 从 2017 年 v1.0.0 到 2023 年 v2.0 的完整版本演进脉络,逐一还原每次版本迭代引入的核心功能及其底层实现。读者将理解防撤回、自动回复、远程控制、免认证登录、Alfred 集成等核心能力的 Hook 实现原理,掌握每个功能对应的源码位置与配置项,从而快速定位、理解乃至二次开发这个基于 Objective-C Runtime 的微信 macOS 插件项目。
一、项目背景:一款基于 Runtime Hook 的 macOS 微信增强插件
WeChatPlugin-MacOS(微信小助手)是一款通过 Objective-C Runtime 消息转发机制(Method Swizzling)与 fishhook 符号重绑定技术,在运行时注入并拦截微信 macOS 客户端方法的插件。所有能力的统一入口位于 WeChat+hook.m 的hookWeChat方法,它会针对微信内部类(如FFProcessReqsvrZZ、CUtility、AccountService、MMURLHandler等)批量替换方法实现,并通过 TKWeChatPluginConfig 集中管理各功能的开关状态。
从 v1.0.0(2017-08-09)到 v2.0(2023-03-12),项目历经十余次版本迭代,覆盖微信 2.3.x 到 3.7.0 多个版本。CHANGELOG 忠实记录了这一过程,下面按版本逐一展开。
二、v1.0.0(2017-08-09):奠定四大核心能力
首个正式版本便确立了插件最核心的四项能力:
- 远程控制:通过向自己的微信账号发送特定指令关键字,远程执行 macOS 系统命令。
- 微信多开:Hook 微信的实例检测逻辑,绕过"微信已在运行"限制。
- 消息防撤回:拦截撤回消息,把被撤回的内容以本地消息形式重新展示。
- 自动回复:收到消息后按关键字匹配规则自动回复。
其中微信多开的实现非常典型,见 WeChat+hook.m:
+ (BOOL)hook_HasWechatInstance { return NO; // 永远返回"无实例",从而允许再开一个新微信 }hookWeChat中通过tk_hookClassMethod(objc_getClass("CUtility"), hasWechatInstanceMethod, ...)替换CUtility的实例检测类方法(2.3.22 之后方法名变为FFSvrChatInfoMsgWithImgZZ),使每个新进程都认为自己没有实例在运行,实现多开。
防撤回的核心在 hook_FFToNameFavChatZZ:sessionMsgList::拦截撤回指令后,用XMLDictionaryParser解析<sysmsg>撤回 XML,取出newmsgid与session,通过FFProcessReqsvrZZ服务反查原始消息MessageData,再以本地消息(msgType: 0x2710)重新插入会话,并把撤回内容转为带定位锚点的可点击文本。
三、v1.1.0(2017-08-23)与 v1.2.0(2017-09-11):自动回复重构与修复
v1.1.0重构了自动回复模块,实现"多回复"能力:不再是一条规则一条回复,而是一个关键字可以配置多条回复内容,随机取一条发送。对应模型 TKAutoReplyModel 中的replyContent字段——多条回复用|分隔,发送时随机挑选:
NSArray *replyArray = [model.replyContent componentsSeparatedByString:@"|"]; int index = arc4random() % replyArray.count; NSString *randomReplyContent = replyArray[index];见 WeChat+hook.m。
v1.2.0进一步为自动回复增加正则匹配与私聊开关,同时修复了两个痛点 bug:
- 聊天记录在部分场景下消失的问题;
- 插件在用户
~/Documents目录生成MMappedKV、JietuSDKStat.plist等沙盒残留文件的问题。
后者的修复思路极具参考价值:在 WeChat+hook.m 中通过 fishhook 的rebind_symbols替换NSSearchPathForDirectoriesInDomains与NSHomeDirectory两个 C 函数,把主目录统一重定向到~/Library/Containers/com.tencent.xinWeChat/Data(见 swizzled_NSHomeDirectory),从根源上避免污染用户文档目录。
四、v1.3.0(2017-09-17):置底与免认证登录
- 最近联系人置底:将指定会话固定在列表底部(与置顶相对),对应配置中的
ignoreSessionModels数组。 - 免认证登录:第二次登录时免扫码认证。实现上 Hook
AccountService的onAuthOKOfUser:withSessionKey:withServerId:autoAuthKey:isAutoAuth:方法(见 WeChat+hook.m),并支持在登录界面勾选自动登录(selectAutoLogin:,WeChat+hook.m),开关状态由 TKWeChatPluginConfig.h 中的autoAuthEnable/autoLoginEnable控制。
五、v1.4.0(2017-10-11):窗口置顶与远程控制回调
- 微信窗口置顶:Hook
NSWindow的makeKeyAndOrderFront:(WeChat+hook.m),把窗口层级提升为NSNormalWindowLevel + 2;同时在窗口最小化时恢复层级,避免置顶窗口遮挡其他应用。 - 最近联系人多选删除:对应
multipleSelectionEnable开关与selectSessions选中集合。 - 远程控制信息回调:执行完远程指令后,通过 TKRemoteControlManager 向自己账号回发一条"执行完成"确认消息(
assistant.remoteControl.recall本地化文案),并清空自己的未读数。 - 手机端获取指令信息:向自己账号发送获取指令列表的关键字,插件会返回所有可用的远程指令及其开关状态,实现见 remoteControlCommandsString。
六、v1.5.0(2018-02-24):自动登录开关、检测更新与通知中心快捷回复
- 优化防撤回提醒:撤回提示中显示撤回人昵称与消息类型,见 WeChat+hook.m 中对撤回人消息内容的拼接逻辑。
- 新增自动登录开关:可在登录界面手动开关。
- 新增小助手检测更新:checkPluginVersion 启动时调用 TKVersionManager 检测远端版本,发现新版本时弹出
NSAlert提示,可选择直接打开下载窗口或忽略。 - 通知中心快捷回复:将微信通知接入 macOS 通知中心的可回复按钮,收到通知即可直接回复(对应 README 中的
notification_quick_reply.gif演示)。 - 表情包复制 & 存储:由 TKEmoticonManager 提供,
copyEmoticonWithMd5:按表情 MD5 复制到剪贴板,exportEmoticonWithMd5:window:弹窗导出保存。 - 自动回复 & 远程控制设置存储到本地:配置由内存模型升级为本地持久化,
TKWeChatPluginConfig提供saveAutoReplyModels/saveRemoteControlModels等方法落盘。
七、v1.5.1(2018-03-03):语音远程控制 macOS
这是远程控制能力的重大升级——不再局限于文字指令,可直接发送语音消息控制 Mac。两条路径并存:
- 文字路径:remoteControlWithMsg: 收到
msgType == 34(语音)的消息时,自动调用MMVoiceTranslateMgr doTranslate:isAuto:把语音转成文字; - 语音回调路径:Hook
MMVoiceTranslateMgr的updateTranscribeVoiceMessage:voiceText:voiceToTextStatus:(WeChat+hook.m),语音转写完成后直接交给executeRemoteControlCommandWithVoiceMsg:执行。
语音指令的匹配比文字宽松:文字指令要求完全相等,语音指令只要包含关键字即可命中(shouldExecuteRemoteControlWithModel:msg:msgType:)。
同时 v1.5.1 还修复了快捷回复后未读数不更新的问题,并把防撤回提醒优化为展示撤回人昵称与消息类型。语音远程控制需要麦克风转写权限,README 明确提示:使用网易云音乐远程控制时,需在"系统偏好设置 → 安全性与隐私 → 隐私 → 辅助功能"中添加微信与脚本编辑器。
八、v1.6(2018-03-18)与 v1.6.1(2018-04-07):Alfred 集成与延迟回复
v1.6新增 Alfred 快捷发送消息与打开聊天窗口。插件通过 TKWebServerManager 启动本地 HTTP 服务(基于 GCDWebServer),Alfred Workflow(配套项目 wechat-alfred-workflow)调用该接口实现搜索最近聊天列表、查看聊天记录、快捷发消息。服务在登录成功后自动启动,见 hook_onAuthOKOfUser:... 中if ([[TKWeChatPluginConfig sharedConfig] alfredEnable]) { [[TKWebServerManager shareManager] startServer]; },由alfredEnable开关控制。
v1.6.1为自动回复新增延迟回复能力,对应模型字段enableDelay与delayTime(单位秒,TKAutoReplyModel.h),发送时通过 TKMessageManager 的sendTextMessage:toUsrName:delay:延迟投递。同时调整置顶窗口快捷键、更新 README 文档。
九、v1.7(2018-05-12):最重磅的功能聚合版本
这是功能数量最多的一次迭代,核心亮点:
- 不同账户设置不同的自动回复 & 远程控制:配置按账号隔离,多开场景下每个微信账号可独立配置。
- 自动回复新增总开关 & 指定联系人:新增
enableSpecificReply与specificContacts字段——开启特定联系人回复后,原本的群聊/私聊回复规则对该联系人失效,匹配逻辑见 autoReplyWithMsg:。 - 远程控制新增控制小助手配置:可通过指令远程切换小助手自身的开关,
executePluginCommand:(TKRemoteControlManager.m)支持getDirectiveList(获取指令)、AutoReplySwitch(自动回复开关)、PreventRevokeSwitch(防撤回开关)、AutoAuthSwitch(免认证开关),切换后通过NSNotificationCenter广播NOTIFY_AUTO_REPLY_CHANGE等通知同步 UI 状态。 - 一键已读:调用 TKMessageManager 的
clearUnRead:清空所有会话未读数。 - 一键清除空会话:批量清理无消息的空会话。
- 国际化:支持英文、简体、繁体,多语言文案由各语言目录的
Localizable.strings提供(如 en.lproj/Localizable.strings、zh-Hans.lproj/Localizable.strings)。 - 关于小助手:新增关于窗口,展示插件版本与信息。
- 在线更新小助手:检测到新版本后直接下载安装。
- 去除微信 URL 转链:
hook_startGetA8KeyWithURL:拦截微信的 A8 跳转链,改为直接用默认浏览器打开目标链接,从而可以直达抖音等被微信转链"洗"过的链接(CHANGELOG 原文的"从此直接打开抖音链接"即指此)。 - 修复免认证登录 & 多开等 bug。
远程控制在 v1.7 同时正式定型为四大类指令(见remoteControlCommandsString中的分组,TKRemoteControlManager.m):
| 指令分组 | 典型能力 |
|---|---|
| Mac 系统 | 屏幕保护、锁屏、休眠、关机、重启、清空废纸篓 |
| 应用 | 退出 QQ、WeChat、Chrome、Safari、所有程序 |
| 网易云音乐 | 播放、暂停、下一首、上一首、喜欢、取消喜欢 |
| 小助手 | 获取指令、防撤回开关、自动回复开关、免认证开关 |
指令模型 TKRemoteControlModel 定义了type(Shell / AppleScript / 插件指令三种执行方式)、keyword(触发关键字)、executeCommand(具体命令)等字段;Shell 指令通过NSTask执行/bin/bash -c,AppleScript 指令则调用osascript .../TKRemoteControlScript.scpt(TKRemoteControlManager.m),预置脚本位于 TKRemoteControlScript.scpt,可编辑的指令清单见 TKRemoteControlCommands.plist。
十、v1.7.1(2018-07-24):Alfred 搜索加强
适配微信 2.3.17,新增:
- Alfred 搜索最近聊天列表;
- Alfred 查看用户聊天记录。
能力由配套的 wechat-alfred-workflow 配合插件本地 HTTP 服务完成,聊天记录读取走 TKMessageManager 的getMsgListWithChatName:minMesLocalId:limitCnt:接口。
十一、v1.7.3(2018-10-23):安全修复与浏览器开关
- 修复安全漏洞:适配微信 2.3.19,同时修复了随 2.3.19 引入的注入问题。
- 菜单栏新增 alfred 开关:在"微信小助手"菜单中可直接开关 Alfred 服务(
alfredEnable)。 - 更改更新弹窗逻辑:更新提示弹窗由强制改为可关闭,并新增"禁止检测版本"选项(
forbidCheckVersion)。 - 新增自带浏览器浏览开关:
systemBrowserEnable开关控制是否使用微信内置浏览器打开链接。关闭后hook_preHandleUrlStr:withMessage:会调用openURLWithDefault:改用系统默认浏览器(WeChat+hook.m)。
十二、v1.7.5(2019-01-13):最后的功能性更新与优化
- 适配微信 2.3.22:多开检测方法同步更换为
FFSvrChatInfoMsgWithImgZZ,消息同步方法更换为FFImgToOnFavInfoInfoVCZZ:isFirstSync:,代码中通过LargerOrEqualVersion(@"2.3.22")做版本分支(WeChat+hook.m)。 - 新增禁止微信检测更新开关:
checkUpdateWechatEnable控制微信自身(非 App Store 版本)的启动更新检测,HookcheckForUpdatesInBackground后按开关决定是否放行(WeChat+hook.m)。 - 优化 XML 解析:防撤回模块改用
XMLDictionaryParser统一解析撤回 XML,提升兼容性。
十三、v2.0(2023-03-12):适配微信 3.7.0 的收官迭代
v2.0 是 CHANGELOG 记录的最后一个版本,时隔四年后针对微信 3.7.0 进行适配,并带来两项新能力:
- 新增撤回消息定位:撤回提示中的被撤回内容变为可点击超链接,点击后自动滚动定位到原始消息位置。实现位于 hook_populateWithMessage: 与 hook_textView:clickedOnLink:atIndex::撤回消息以
kTKRevokeLocationKey锚点标记mesLocalID,渲染时转为NSLinkAttributeName链接,点击后调用showLocatedMessage:定位到对应消息。 - 新增群聊监控:
memberExitMonitoringEnable开关控制退群监控。HookGroupStorage的notifyModifyGroupContactsOnMainThread:(WeChat+hook.m),对比群成员变更,检测到有人退群后以本地消息提示"XX 退出群聊",并记录退群成员与时间(quitChatRoomMemberDict,同一成员 30 天内不重复提示,间隔常量kTKMemberQuitDayInterval)。退群提示中的成员昵称同样做成可点击链接,点击可查看该成员资料页。 - 移除官方已支持的功能:自动登录、移除会话、标为未读等官方原生支持的功能被移除,插件回归差异化价值。
此外 v2.0 还延续了 v1.7.3/v1.7.5 的"不支持消息展示优化":小程序、转账、未支持消息等卡片会在内容后追加来源应用与标题信息(hook_makeAppBrandTableItemWithItem:、hook_makePayTransferTableItemWithItem:等,WeChat+hook.m),转账消息还会额外展示金额,提升信息可读性。
十四、版本演进全景与源码索引
结合 CHANGELOG 与源码,可将各版本核心能力映射到对应实现文件:
| 版本 | 核心能力 | 关键源码 |
|---|---|---|
| v1.0.0 | 防撤回 / 自动回复 / 远程控制 / 多开 | WeChat+hook.m |
| v1.1.0 | 多回复、代码重构 | TKAutoReplyModel.h |
| v1.2.0 | 正则匹配、沙盒路径修复 | WeChat+hook.m |
| v1.3.0 | 置底、免认证登录 | TKWeChatPluginConfig.h |
| v1.4.0 | 窗口置顶、远程回调 | WeChat+hook.m |
| v1.5.x | 语音控制、检测更新、快捷回复、表情管理 | TKRemoteControlManager.m、TKEmoticonManager.h |
| v1.6.x | Alfred 集成、延迟回复 | TKWebServerManager.h、TKMessageManager.h |
| v1.7 | 多账号配置、一键已读、国际化、URL 直开 | TKRemoteControlManager.m |
| v1.7.5 | 禁止微信检测更新、XML 解析优化 | WeChat+hook.m |
| v2.0 | 撤回定位、退群监控、适配 3.7.0 | WeChat+hook.m |
十五、总结:从 CHANGELOG 反推工程演化规律
纵观 CHANGELOG 的版本记录,可以提炼出该项目三条清晰的工程演化主线:
- 安全与体验优先:v1.2.0 修复沙盒污染、v1.2.0/v1.5.1 修复聊天记录与未读数 bug、v1.7.3 修复安全漏洞——稳定性修复贯穿始终;
- 能力渐进叠加而非推翻重构:自动回复从单回复(v1.0)到多回复(v1.1)到正则/私聊开关(v1.2)到指定联系人(v1.7)再到延迟回复(v1.6.1),是同一模型字段不断扩展的典型增量演进;远程控制同样从纯文字指令逐步叠加语音、回调与插件自身开关控制;
- 与微信版本强耦合:几乎每个版本都对应一个微信版本适配(2.3.17 → 2.3.19 → 2.3.22 → 3.7.0),微信侧方法签名变化会直接触发
LargerOrEqualVersion:分支兼容,这也解释了为何 v2.0 会移除已被官方支持的功能——插件的生命周期始终跟随微信客户端的迭代。
对于希望深入理解该项目的开发者,建议按 main.mm → WeChat+hook.m → TKWeChatPluginConfig → 各功能 Manager 的顺序阅读,即可完整还原 CHANGELOG 中每个条目背后的实现细节。
- 即时通讯
- 桌面应用
- 逆向工程
【免费下载链接】WeChatPlugin-MacOS
微信小助手
相关推荐
SmartRefreshLayout版本迭代史:从v1.0到v2.0的技术演进之路
SmartRefreshLayout版本迭代史:从v1.0到v2.0的技术演进之路 引言:下拉刷新的技术痛点与解决方案 你是否还在为Android应用中的下拉刷
移动开发UI组件FunClip版本更新解析:从v1.0到v2.0的功能演进与改进
FunClip版本更新解析:从v1.0到v2.0的功能演进与改进 FunClip作为基于阿里巴巴通义实验室FunASR工具包开发的智能视频剪辑工具,在从v1.0
音视频语音人工智能AI 应用本地部署Whispering版本迭代解析:v1.0到最新版的功能演进与改进
Whispering版本迭代解析:v1.0到最新版的功能演进与改进 你还在为语音转文字工具的卡顿和复杂操作烦恼吗?Whispering从v1.0到最新版的进化,
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考