余额不足.

一次逆向mac微信过程记录(自动添加群聊好友)

字数统计: 1.1k阅读时长: 4 min
2018/04/17 Share

一次逆向mac微信过程记录

最近产品搞事情,需要逆向mac微信来实现在群聊中自动添加客户的功能,用来爬取这些客户的朋友圈,刚听到这不靠谱的需求是嘴上笑嘻嘻心里mmp的,干些啥不好偏偏要在不是自己的app上搞事情,好在已有前辈给逆向微信铺了一条阳光大道,才能让这次开发顺利进行。

本文内容基于TK前辈的WeChatPlugin-MacOS

OK,牢骚发完了,简单的说说这次逆向过程

寻找切入点

WeChatPlugin-MacOS已经实现了消息自动回复的功能,看到有这个功能我是灰常嗨森的,等于说少了一大堆的分析过程,直接找到调用自动回复的消息同步方法[MessageService OnSyncBatchAddMsgs:isFirstSync:],而且这个插件中也已经hook了该方法,直接在hook方法中添加我们的自动添加好友方法autoAddFriendsWithMsg(),到此方法的入口搞定了,再来分析发送好友申请是怎么实现的。

寻找发送好友申请调用的方法

WeChatPlugin-MacOS已经在很多类中输出了log,但是日志太多了也很麻烦。
点击用户,然后弹出下图,点击添加好友按钮

查看日志寻找我们想要的信息。在密密麻麻的日志中发现了

1
2
3
4
2018-04-17 10:01:37.019405+0800 WeChat[64662:2113668] [FriendRequest] MMFriendRequestMgr.mm __91-[MMFriendRequestMgr sendVerifyUserRequestWithUserName:opCode:verifyMsg:ticket:completion:]_block_invoke INFO: Send verify user cgi succ. opcode: 1 result: -44
2018-04-17 10:01:37.019440+0800 WeChat[64662:2113668] [FriendRequest] MMFriendRequestMgr.mm __91-[MMFriendRequestMgr sendVerifyUserRequestWithUserName:opCode:verifyMsg:ticket:completion:]_block_invoke INFO: Need verify
WeChat 0x10049384d __67-[MMFriendRequestMgr addNewFriendWithContact:verifyMsg:completion:]_block_invoke + 79
WeChat 0x1004949f7 __91-[MMFriendRequestMgr sendVerifyUserRequestWithUserName:opCode:verifyMsg:ticket:completion:]_block_invoke + 1204

[MMFriendRequestMgr addNewFriendWithContact:verifyMsg:completion:] 确认过眼神,我遇上对的人
hook该方法,输出

1
2
arg1:UsrName:wxid_xxxxxxxx, Nickname:XXXXX, Remark:(null), Sex:0, Type:4, imgStatus:IMG_HAS 
arg2:nil

从日志大概就能分析出arg1应该就是WCContactData的数据模型
arg2则是添加好友发送给对方看的验证信息
block干了些啥暂时不用去关心

那么新的问题就出现了,如何在消息同步方法中获取到发送信息用户的WCContactData的数据模型?

上图为AddMsg消息模型

AddMsg中我们能获取到用户的sessionId(也就是UsrName),Nickname,消息内容等信息,但怎样才能通过这些信息拿到我们想要的WCContactData数据模型?

WeChatPlugin-MacOS中自动回复方法有调用

1
2
ContactStorage *contactStorage = [[objc_getClass("MMServiceCenter") defaultCenter] getService:objc_getClass("ContactStorage")];
WCContactData *msgContact = [contactStorage GetContact:addMsg.fromUserName.string];

获取WCContactData数据模型,但在群聊中addMsg.fromUserName.stringxxxxxx@ChatRoom这样形式的字符串,也就说明以上方法并不适用于我们的场景。

回到微信群聊界面,通过点击用户头像是能够获取到用户的WCContactData的,那么通过点击操作是怎么获取到的?

1
2
3
4
5
6
2018-04-17 10:40:42.602165+0800 WeChat[64662:2113668] [Contact] GroupStorage+Internal.mm -[GroupStorage(Internal) OnModGroupMemberContacts_Thread:] DEBUG: onModGroupMemberContacts (
"UsrName:wxid_xxxxxxxx, Nickname:XXXX, Remark:(null), Sex:0, Type:4, imgStatus:IMG_HAS"
)
2018-04-17 10:40:42.602203+0800 WeChat[64662:2113668] [Contact] GroupStorage+Internal.mm -[GroupStorage(Internal) modifyGroupMembersContact:onlyInsertNew:] INFO: modify group member contact onMod. isOnlyInsertNew=0, memberscount=1
2018-04-17 10:40:42.614908+0800 WeChat[64662:2113668] [MMChatDetailPanel] MMChatDetailPanel.mm -[MMChatDetailPanel OnModifyGroupMemberContact:] INFO: Group member contact modified UsrName:wxid_xxxxxxxx, Nickname:XXXX, Remark:(null), Sex:0, Type:4, imgStatus:IMG_HAS
2018-04-17 10:40:42.615624+0800 WeChat[64662:2113668] [Contact] GroupStorage.mm -[GroupStorage GetGroupMemberContactFromSvrWithUsername:groupUserName:] INFO: GetGroupMemberContactFromSvr memberName=wxid_xxxxxxxx

从点击事件中我们发现了以上几个方法可能对我们有用。
打开hooper分析了一通之后,发现并没什么卵用。。
但是GroupStorage还值得我们去探索一哈,打开class-dump之后的GroupStorage.h文件,一头扎进去寻找有返回值的方法。

1
2
3
4
5
6
7
- (id)GetGroupMemberListWithGroupUserName:(id)arg1;
- (id)GetGroupMemberListWithGroupUserName:(id)arg1 limit:(unsigned int)arg2;
- (id)GetGroupContactList:(unsigned int)arg1 ContactType:(unsigned int)arg2;
- (id)GetGroupMemberContact:(id)arg1;
- (id)GetGroupContactsWithUserNames:(id)arg1;
- (id)GetGroupContact:(id)arg1;
···

通过方法名应该能看出些什么了吧,hook- (id)GetGroupMemberContact:(id)arg1;
发现返回值就是我们要找的她!!!

那首歌怎么唱的来着,我要找到你不管南北东西,直觉会给我指引!!!

最后附上代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/**
自动添加好友

@param addMsg 接收的消息
*/
- (void)autoAddFriendsWithMsg:(AddMsg *)addMsg {
if (addMsg.msgType != 1 && addMsg.msgType != 3) return;

NSString *userName = @"";
NSRange range = [addMsg.content.string rangeOfString:@":\n"];
if (range.length > 0) {
userName = [addMsg.content.string substringToIndex:range.location];
}
GroupStorage *groupStorage = [[objc_getClass("MMServiceCenter") defaultCenter] getService:objc_getClass("GroupStorage")];
// 根据sessionId获取联系人contact模型
WCContactData *msgContact = [groupStorage GetGroupMemberContact:userName];
MMFriendRequestMgr *friendReqMgr = [[objc_getClass("MMServiceCenter") defaultCenter] getService:objc_getClass("MMFriendRequestMgr")];
[friendReqMgr addNewFriendWithContact:msgContact verifyMsg:@"兄弟,加个好友" completion:nil];
}
CATALOG
  1. 1. 一次逆向mac微信过程记录
    1. 1.1. 寻找切入点
    2. 1.2. 寻找发送好友申请调用的方法