前言
上一篇文章《用了这个,我追到了自己的女神:Mac版QQ半自动发送情话》 发布后,有几个朋友私信问说QQ过时了女神不用了,能不能整个微信的?有别的大神已经开发了微信网页版的自动发消息,可以登录网页版微信的朋友可以去试一试把发送部分改掉就可以了,我因为不能登录网页版微信所以用不了,今天来尝试用逆向Mac微信解决一下这个问题。
最新版的插件直接看这篇文章逆向Mac版微信-情话助手终版(女神邀请我恰饭了~)
最新版的插件直接看这篇文章逆向Mac版微信-情话助手终版(女神邀请我恰饭了~)
最新版的插件直接看这篇文章逆向Mac版微信-情话助手终版(女神邀请我恰饭了~)
想学习逆向过程的可以往下看
开始
工具
- Xcode(苹果开发工具)
- IDA (逆向神器,反编译工具 )
- Class-dump (导出可执行文件的Class Header)
过程
1.Dump 出头文件
首先利用Class-Dump拿到微信的头文件
打开终端执行:
class-dump -H 微信.app的路径 -o 头文件保存路径
执行之后就能获取到很多头文件了
英文好的都知道消息是Message,我就搜索一下,直接就找到了一个MessageService文件。
打开发现,发送消息的方法是在这个文件
有发送文本,发送定位,发送GIF等等方法,我们使用发送文本的方法就可以了。
2.反编译
选择微信APP文件,右键显示包内容,找到图中二进制可执行文件
扔Hopper Disassembler里边开始反编译,在漫长的等待后得到编译结果。
配合第一步中的头文件一顿常规查找分析之后,得到以下几个方法:
- 登录按钮事件: MMLoginOneClickViewController 中的
-(void)onLoginButtonClicked:(id)arg1; - 授权状态查询 WeChat 下的
-(BOOL)IsAuthOK; - 服务层处理中心-获取消息服务 : MMServiceCenter中的
-(id)getService:(Class)arg1; - 发送信息服务: MessageService中的
-(id)SendTextMessage:(id)arg1 toUsrName:(id)arg2 msgText (id)arg3 atUserList:(id)arg4;
3.hook 微信
注入Mac App 的步骤和注入iOS步骤差不多,会iOS的可以直接跳下去看最后的Hook代码。
- 在xcode中新建一个framework项目,取名hookWeChat
- 添加一个FQHelper.h 和一个FQHelper.m文件 ,写入runtime 交换对象方法。
FQHelper.h
内容如下:
#import <Foundation/Foundation.h>
#import <objc/runtime.h>
NS_ASSUME_NONNULL_BEGIN
@interface FQHelper : NSObject
/**
替换对象方法
@param originalClass 原始类
@param originalSelector 原始类的方法
@param swizzledClass 替换类
@param swizzledSelector 替换类的方法
*/
void hookMethod(Class originalClass, SEL originalSelector, Class swizzledClass, SEL swizzledSelector);
/**
替换类方法
@param originalClass 原始类
@param originalSelector 原始类的类方法
@param swizzledClass 替换类
@param swizzledSelector 替换类的类方法
*/
void hookClassMethod(Class originalClass, SEL originalSelector, Class swizzledClass, SEL swizzledSelector);
@end
FQHelper.m
内容如下:
#import "FQHelper.h"
@implementation FQHelper
/**
替换对象方法
*/
void hookMethod(Class originalClass, SEL originalSelector, Class swizzledClass, SEL swizzledSelector) {
Method originalMethod = class_getInstanceMethod(originalClass, originalSelector);
Method swizzledMethod = class_getInstanceMethod(swizzledClass, swizzledSelector);
if (originalMethod && swizzledMethod) {
method_exchangeImplementations(originalMethod, swizzledMethod);
}
}
/**
替换类方法
*/
void hookClassMethod(Class originalClass, SEL originalSelector, Class swizzledClass, SEL swizzledSelector) {
Method originalMethod = class_getClassMethod(originalClass, originalSelector);
Method swizzledMethod = class_getClassMethod(swizzledClass, swizzledSelector);
if (originalMethod && swizzledMethod) {
method_exchangeImplementations(originalMethod, swizzledMethod);
}
}
@end
- 添加一个Main.mm文件,内容如下:
#import <Foundation/Foundation.h>
#import "Wechat+hook.h"
static void __attribute__((constructor)) initialize(void) {
NSLog(@"开始加载");
// CBHookClassMethod();
[NSObject hookWeChat];
}
- 添加一个WeChatHeader.h文件,声明刚才找到的那些方法,内容如下:
#import <Cocoa/Cocoa.h>
@interface MMLoginOneClickViewController : NSViewController
- (void)onLoginButtonClicked:(id)arg1;
@end
@interface WeChat : NSObject
- (BOOL)IsAuthOK;
@end
@interface CUtility : NSObject
+ (id)GetCurrentUserName;
@end
@interface MMServiceCenter : NSObject
+ (id)defaultCenter;
- (id)getService:(Class)arg1;
@end
@interface MessageService : NSObject
- (id)SendTextMessage:(id)arg1 toUsrName:(id)arg2 msgText:(id)arg3 atUserList:(id)arg4;
@end
-
hook 代码
原理就是:替换登录按钮事件,点击登录按钮事件之后,每5秒查询一次授权状态,授权成功的时候发送消息Wechat+hook.h
#import <Cocoa/Cocoa.h>
@interface NSObject (WeChatHook)
+ (void)hookWeChat;
@end
Wechat+hook.m
#import "Wechat+hook.h"
#import "WeChatHeader.h"
#import "FQHelper.h"
#import <CommonCrypto/CommonDigest.h>
#import <AppKit/AppKit.h>
#import <objc/runtime.h>
@implementation NSObject (WeChatHook)
+ (void)hookWeChat{
hookMethod(objc_getClass("MMLoginOneClickViewController"), @selector(onLoginButtonClicked:), [self class], @selector(hook_onLoginButtonClicked:));
}
- (void)hook_onLoginButtonClicked:(NSButton *)btn {
NSLog(@"点击了登录按钮");
[self hook_onLoginButtonClicked:btn];
[self getAuthState];
}
- (void)getAuthState{
WeChat *wechat = [objc_getClass("WeChat") sharedInstance];
if ([wechat IsAuthOK]) {
NSLog(@"授权成功");
dispatch_async(dispatch_get_main_queue(), ^{
// 获取发送用户
NSString *currentUserName = [objc_getClass("CUtility") GetCurrentUserName];
// 获取发送消息服务
MessageService *service = [[objc_getClass("MMServiceCenter") defaultCenter] getService:objc_getClass("MessageService")];
NSPasteboard *pb = [NSPasteboard generalPasteboard];
if ([[pb types] containsObject:NSPasteboardTypeString]) {
NSString *s = [pb stringForType:NSPasteboardTypeString];
// do something
[service SendTextMessage:currentUserName toUsrName:@"你女神的微信号" msgText:s atUserList:nil];
}
});
}else{
NSLog(@"授权失败");
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
dispatch_async(dispatch_get_main_queue(), ^{
[self getAuthState];
});
});
}
}
@end
- 自动注入
在xcode的targets->BuildPhases里添加一个脚本。
脚本内容:
#!/bin/bash
app_name="WeChat"
framework_name="hookWeChat"
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"
定义好目标app的路径,备份好原有二进制文件。将编译好的framework文件拷贝到目标app目录,用insert_dylib这个工具进行注入。insert_dylib工具我放在demo项目根目录中
7.编辑schema的excutable,选择应用程序里的微信
8.运行程序,测试一下。
登录微信后,立即发送成功。运行一次后,已经注入成功,以后打开微信都会发送,剪贴板第一条信息。
使用教程
使用教程大致和QQ差不多,请参考上一篇文章《用了这个,我追到了自己的女神:Mac版QQ半自动发送情话》,执行过程:开机自动启动情话执行脚本.app->执行python获取一句情话并启动微信->点击微信登录按钮后->遍历查询是否登录完成->登录完成发送情话
按照上一篇文章步骤,以下只叙述修改点。
- 爬取情话- 参考上一篇文章步骤1
- 调起QQ改调起微信 - 参考上一篇文章步骤2并做以下修改
os.system("open 'tencent://message/?uin=992436880&Site=&Service=201&sigT=2cf2671557dd'")
改为:
os.system("open /Applications/WeChat.app")
- .选择实用工具,运行脚本- 参考上一篇文章步骤3
- 写入shell语句 - 参考上一篇文章步骤4 ,因为有授权检测这里不需要加seelp
- 设置开机自启 – 参考上一篇文章步骤5
- 下载上面的hookWeCha工程:https://github.com/FORMAT-qi/hookWeChat-Mac 修改工程里Wechat+hook.m文件,并填入你女神的微信号,当然,如果你有好几个女神,你可以把发送消息的那句话在下边多复制几遍,只需要修改不同的微信号,就可以同时发送多个女神。
- 安装插件 :打开终端,执行 hookWeCha工程中other文件夹里的Install.sh脚本,卸载的话执行Uninstall.sh脚本。例如
sh /Users/jiashiqi/Downloads/hookWeChat-Mac-master/hookWeChat/other/Install.sh
- 然后就配置完了,可以关机开机测试一波了。
结束语
因为是自动发送,爬取完情话最好自己先看一遍,把不合适的话删掉,不然小心女神拉黑你。
看完的朋友麻烦点个关注,点个赞,需要的朋友可以点个收藏。这个教程感觉还是写的麻烦了,写的过程也有了点新的想法,回边再研究研究看看能不能把教程再精简一下,下一篇出一个使用方法更简单的终极版插件。
如有问题可留言解决。