一次逆向mac微信过程记录
最近产品搞事情,需要逆向mac微信来实现在群聊中自动添加客户的功能,用来爬取这些客户的朋友圈,刚听到这不靠谱的需求是嘴上笑嘻嘻心里mmp的,干些啥不好偏偏要在不是自己的app上搞事情,好在已有前辈给逆向微信铺了一条阳光大道,才能让这次开发顺利进行。
本文内容基于TK前辈的WeChatPlugin-MacOS
OK,牢骚发完了,简单的说说这次逆向过程
寻找切入点
WeChatPlugin-MacOS
已经实现了消息自动回复的功能,看到有这个功能我是灰常嗨森的,等于说少了一大堆的分析过程,直接找到调用自动回复的消息同步方法[MessageService OnSyncBatchAddMsgs:isFirstSync:]
,而且这个插件中也已经hook了该方法,直接在hook方法中添加我们的自动添加好友方法autoAddFriendsWithMsg()
,到此方法的入口搞定了,再来分析发送好友申请是怎么实现的。
寻找发送好友申请调用的方法
WeChatPlugin-MacOS
已经在很多类中输出了log,但是日志太多了也很麻烦。
点击用户,然后弹出下图,点击添加好友按钮
查看日志寻找我们想要的信息。在密密麻麻的日志中发现了1
2
3
42018-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
2arg1: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
2ContactStorage *contactStorage = [[objc_getClass("MMServiceCenter") defaultCenter] getService:objc_getClass("ContactStorage")];
WCContactData *msgContact = [contactStorage GetContact:addMsg.fromUserName.string];
获取WCContactData
数据模型,但在群聊中addMsg.fromUserName.string
是xxxxxx@ChatRoom
这样形式的字符串,也就说明以上方法并不适用于我们的场景。
回到微信群聊界面,通过点击用户头像是能够获取到用户的WCContactData
的,那么通过点击操作是怎么获取到的?1
2
3
4
5
62018-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 | /** |