前言
关联相关类一起猜:例如,CMessageMgr 这个类,它是个管理消息的单例,而消息被包装成 CMessageWrap 对象来传递
熟悉 image 加载过程和 Hook 概念很重要,后面会用到。可以参考这篇文章:优化 App 的启动时间。
如果是自己用 Method Swizzling 写的 Hook 逻辑,很容易拿到原始方法的 IMP。
但这里是使用 CaptainHook,是对 Method Swizzling 的宏定义封装而已,创建了很多内联函数。
所谓的 Method Swizzling 其实也就是 Objective-C Runtime 的一种应用而已。
初步思路
获取到方法的调用栈,然后查找上一层的方法,并将方法调用的地址换算成 Hopper 反汇编后的地址,这样就能获取到方法名了,然后进行 Hook。
将地址翻译成 Selector
分步骤计算适合对操作系统原理不太熟悉的新手,老司机可以直接进入『快速计算方法』。
分步详细剖析计算方法
已知条件:
-[CMessageMgr GetMsg:LocalID:] 在 Hopper 反汇编后的地址 0x10280e1d4
-[CMessageMgr GetMsg:LocalID:] 方法内存地址为 0x1028821d4
-[CMessageMgr GetMsg:LocalID:] 在内存中 0x102afb960 处被调用
求 0x102afb960 对应 Hopper 反汇编后的地址?
因为方法间的相对地址是不变的,所以:
A 方法反汇编地址 – B 方法反汇编地址 = A 方法真实地址 – B 方法真实地址
还原 Selector
根据反汇编地址在 Hopper 中定位方法名,快捷键 G。
获取群成员ID
NSString *m_nsFromUsr = wrap.m_nsFromUsr; //微信群号
CContactMgr *contactManager = [[objc_getClass("MMServiceCenter") defaultCenter] getService:[objc_getClass("CContactMgr") class]];
CContact *groupContact = [contactManager getContactByName:m_nsFromUsr];
NSString *group_name = groupContact.m_nsNickName;
NSLog(@"groupContact1:%@.", groupContact);
NSString *m_nsChatRoomMemList = groupContact.m_nsChatRoomMemList;
NSLog(@"m_nsChatRoomMemList:%@", m_nsChatRoomMemList);
NSArray *wx_Ids = [m_nsChatRoomMemList componentsSeparatedByString:@";"]; //群成员的微信ID
NSString *gHelperUser = [objc_getClass("SettingUtil") getCurUsrDisplayName];
得到通讯录信息
//得到通讯录的信息
FTSContactMgr *ftsContactMgr = [[[NSClassFromString(@"MMServiceCenter") defaultCenter] getService:NSClassFromString(@"FTSFacade")] ftsContactMgr];
// [ftsContactMgr tryLoadContacts];//- (id)getGroupContacts;
NSMutableDictionary *dicContact = [ftsContactMgr getContactDictionary];
拉人
Nov 3 17:39:16 iPhone WeChat[5579] <Warning>: KNHooklog :-(c)AddGroupMember:withMemberList:withDesp:(have 3 value)
return:0
value1:__NSCFString-->5565244@chatroom
value2:__NSArrayM-->(
"{m_nsMemberName=z928967, m_uiMemberStatus=0, m_nsNickName=(null)}"
)
value3:(null)-->(null)
object:<CGroupMgr: 0x195f1850>