震惊! macOS 版微信竟可以这样消息防撤回

2017-10-11 ==> 新增窗口置顶 & 会话多选删除
2017-09-17 ==> 新增置底 & 免认证
2017-09-11 ==> 修复聊天记录消失的bug
2017-08-23 ==> 支持多回复
2017-08-16 ==> 新增远程控制 & 微信多开


一、 前言

前一阵子入了 iOS 逆向的坑,整了个微信机器人,不过由于是用自己的证书打包,因此只能用7天,之后还得重新打包,实在麻烦。于是就拿 macOS 动刀了。

本篇主要制作 macOS 版微信的插件,实现消息防撤回与自动回复的功能,从而熟悉 mac OS 插件制作,由于 (lan ai) macOS 逆向分析与 iOS 类似,且不像 iOS 有那么多的工具,因此花费的时间较多,这里暂不阐述。之后有时间再整理 iOS 逆向分析过程。

  • 基本原理:与 iOS 注入动态库类似,通过 app 启动时调用我们注入的库,从而进行 hook。
  • 插件 GitHub 地址: WeChatPlugin-MacOS
  • Demo 演示
消息防撤回.gif

自动回复.gif

二、安装与使用

  • 下载 WeChatPlugin, 先进行 Build (command + B),之后 Run (command + R)即可启动微信,此时插件注入完成。(若出现 Error 请往下看 3.5 注意 部分)

  • 登录微信,可在菜单栏-帮助中看到消息防撤回与自动回复。

  • 消息防撤回:点击开启消息防撤回或者快捷键command + t,即可开启、关闭。
  • 自动回复:点击开启自动回复或者快捷键conmand + k,将弹出自动回复设置的窗口,在窗口中输入关键字与回复内容,点击保存即可。(若无关键字保存,则所有消息都会自动回复)
自动回复设置.png
  • 卸载

    /Applications/WeChat.app/Contents/MacOS 目录中,删除 WeChatWeChatPlugin.framework,将WeChat_backup 重命名为 WeChat 即可。

三、plugin 制作

3.1 创建Framework

使用 Xcode 创建 macOS 的 Cocoa Framework.

创建Cocoa Framework.png

3.2 Edit Scheme…

编辑 Scheme,在 Debug 模式下启动 WeChat。


Edit Scheme.png
choose executable.gif

3.3 添加Run Script

在 Build Phases 中添加 Run Script

add run scripe.gif

Script 内容如下

其中 app_name为要注入的app名称,framework_name`为插件名称。

#!/bin/bash
# 要注入的的app
app_name="WeChat"
# 此framework名字
framework_name="WeChatPlugin"
app_bundle_path="/Applications/${app_name}.app/Contents/MacOS"
app_executable_path="${app_bundle_path}/${app_name}"
app_executable_backup_path="${app_executable_path}_backup"
framework_path="${app_bundle_path}/${framework_name}.framework"
# 备份WeChat原始可执行文件
if [ ! -f "$app_executable_backup_path" ]
then
cp "$app_executable_path" "$app_executable_backup_path"
fi
cp -r "${BUILT_PRODUCTS_DIR}/${framework_name}.framework" ${app_bundle_path}
# 注入动态库
./insert_dylib --all-yes "${framework_path}/${framework_name}" "$app_executable_backup_path" "$app_executable_path"

其中insert_dylib来源于github(与iOS的insert_dylib不同)

3.4 创建 main.mm

创建 main.mm 文件,添加构造方法。

main.mm.png

此时,一运行,即可执行initalize中的方法,并启动微信。

因此,我们就可以在这里愉快的进行hook!!!

3.5 注意

  • 若 Error,提示无权限,请对 WeChat 赋予权限。
    sudo chmod -R 777 /Applications/WeChat.app
  • 若 Error,提示找不到 Framework,先进行 Build。

四、愉快的 hook (以撤回消息为例)

4.1 创建 NSObject 分类

新建 NSObject 分类,加入类方法+(void)hookWeChat;并在 main.mm 中执行该方法。之后所有的 hook 都可以在该类方法中进行。

#import "WeChat+hook.h"

static void __attribute__((constructor)) initialize(void) {
    NSLog(@"++++++++ WeChatPlugin loaded ++++++++");
    [NSObject hook_WeChat];
}

4.2 寻找注入点

首先使用class-dump,dump 出微信的头文件信息。(如何使用请左转iOS 逆向 - 微信 helloWorld)
因为在 iOS 中,微信撤回的函数为- (void)onRevokeMsg:(id)arg1;因此,我们在微信的头文件中搜索该方法,最终在MessageService.h中找到。

4.3 runtime 登场

到这里就要开始进行 hook 了,在+(void)hookWeChat;中进行methodExchange
MessageService- (void)onRevokeMsg:(id)arg1;方法实现替换成NSObject- (void)hook_onRevokeMsg:(id)msg方法。

+ (void)hookWeChat {
    //      微信撤回消息
    Method originalMethod = class_getInstanceMethod(objc_getClass("MessageService"), @selector(onRevokeMsg:));
    Method swizzledMethod = class_getInstanceMethod([self class], @selector(hook_onRevokeMsg:));
    if(originalMethod && swizzledMethod) {
        method_exchangeImplementations(originalMethod, swizzledMethod);
    }
}

- (void)hook_onRevokeMsg:(id)msg {
    NSLog(@"=== TK-LOG-msg = %@===",msg);
    [self hook_onRevokeMsg:msg];
}

4.4 验证

由于是使用 Xcode,就不用像 iOS 逆向那样只能用 lldb 调试了。可以在- (void)hook_onRevokeMsg:(id)msg中打个断点,然后撤回消息看是否会触发。结果证明该方法确实是微信消息撤回的处理方法。

4.5 使用 Hopper Disassembler

接着我们在- (void)hook_onRevokeMsg:(id)msg中直接return就可以了。
然而这时候看不到到底是撤回了哪一条信息。我们可以在用户撤回的时候将下面的内容改成"拦截 xx 的一条撤回消息:xxxx"。

撤回.png

这时候就要使用神器 Hopper Disassembler.用hopper Disassembler 进行分析,分析- (void)onRevokeMsg:(id)arg1;的实现。(分析过程与 iOS 类似,这里暂不阐述)
最终得到了主要的代码实现。(完整代码在工程中)

MessageService *msgService = [[objc_getClass("MMServiceCenter") defaultCenter] getService:objc_getClass("MessageService")];
MessageData *revokeMsgData = [msgService GetMsgData:session svrId:[newmsgid integerValue]];
MessageData *newMsgData = ({
        MessageData *msg = [[objc_getClass("MessageData") alloc] initWithMsgType:0x2710];
        [msg setFromUsrName:revokeMsgData.toUsrName];
        [msg setToUsrName:revokeMsgData.fromUsrName];
        [msg setMsgStatus:4];
        [msg setMsgContent:newMsgContent];
        [msg setMsgCreateTime:[revokeMsgData msgCreateTime]];
        [msg setMesLocalID:[revokeMsgData mesLocalID]];
        
        msg;
    });
    
[msgService AddLocalMsg:session msgData:newMsgData];

五、效果

点击菜单栏-帮助-开启消息防撤回,当好友撤回消息是可以看到提示。

消息防撤回.gif

六、小结

最终我们得到了拥有消息防撤回与自动回复的 macOS 版微信,虽然整个过程挺简单的,但主要目标是为了熟悉了如何制作 macOS 插件的过程,这样以后就可以给 macOS 上的 app 增加点小功能了。

由于本人还只是个逆向新手,难免会有所疏漏,还请大牛们指正。
本项目仅供学习参考。

七、参考

如何愉快地在Mac上刷朋友圈

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,968评论 6 482
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,601评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 153,220评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,416评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,425评论 5 374
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,144评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,432评论 3 401
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,088评论 0 261
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,586评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,028评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,137评论 1 334
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,783评论 4 324
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,343评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,333评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,559评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,595评论 2 355
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,901评论 2 345

推荐阅读更多精彩内容