二,分析
2.25 打印log
重新启动微信进入新的朋友界面,在ssh中使用ondeviceconsole打印设备的log
ondeviceconsole
这时用另一个微信号添加自己好友,触发好友请求的方法,可以看到以下的 log
log表明有好友添加请求的时候,会调用
-[SayHelloViewController OnSayHelloDataChange]
2.3 动态分析 lldb + hopper disassembler
hopper disassembler打开前面砸壳后的二进制文件
有个小插曲,我的i7 mba分析用了58min 期间cpu利用率保持25%
搜索-[SayHelloViewController OnSayHelloDataChange]方法,可以看到当前方法在微信中的偏移地址,开始动态分析
pythontcprelay.py-t1234:1234 //再使用 usbmuxd 转换端口
debugserver*:1234-a"WeChat" //设备开启 debugserver
打开 lldb
/Applications/Xcode.app/Contents/Developer/usr/bin/lldb //lldb位置
(lldb) process connect connect://localhost:1234 //连接1234端口
(lldb) imagelist-o -f // 打印所有进程
可找到微信在当前手机上的进程内存基地址
内存地址 = 进程内存基地址 + 方法偏移地址
下断
(lldb) br s -a “0x十六进制地址”
输入 c 继续,使用另一微信账号添加好友,会触发该断点
(lldb) c
使用bt查看调用栈信息,即哪些方法调用了当前的方法,找到方法的上游
(lldb) bt
异步调用没办法查看
第一个表示当前的方法,可以看到在调用此方法前,该进程总共调用了3个方法。分别计算出这三个方法在微信中的偏移量
(lldb) p/x -0x基地址 + 0x方法地址
这三个地址在 hopper disassembler 中查看,找到了对应的方法为
[SayHelloViewController OnSayHelloDataChange]
[SayHelloDataLogic onFriendAssistAddMsg:]
[FriendAsistSessionMgr OnAddMsgForSpecialSession:MsgList:] //猜测这个
[CMessageMgr MainThreadNotifyToExt:]
MsgList:后面的参数可能为消息的数组,可下断测试
(lldb) br s -a "0x地址"
(lldb) c
(lldb) register read
(lldb) po $2
(lldb) po $r3
(lldb) po [[$r3 firstObject] class]
看出r3确实是个数组,同时也得到了消息的对象为CMessageWrap证明猜测正确
然而FriendAsistSessionMgr这个类可能需要一些初始化,且放在SayHelloViewController中,而想要的是不管在哪个控制器里都可以 hook 住上面的消息数组对象。往上找,[CMessageMgr MainThreadNotifyToExt:],里面并没有需要的信息。根据类名推测CMessageMgr是用来管理消息的,可能是在异步执行了消息数组的获取。
因此,重复以上步骤,使用 logify 对CMessageMgr进行 Log 分析。最终锁定了
CMessageMgr MessageReturn: MessageInfo:Event:
定位通过好友请求方法
2.4 UI动态分析
通过好友请求的方法,是在新的朋友界面,点击接受的时候触发的,所以找到“接受”对象
打印所有UI层级
cy# [[UIApp keyWindow] _autolayoutTrace].toString() //简化显示
可发现 FixTitleColorButton:0x17af1e90'\u63a5\u53d7'
UIButtonLabel:0x17a28a40'\u63a5\u53d7'
UI把该对象的 hidden = 1,看是否隐藏
cy# #0x17af1e90.hidden = 1
效果图可以看到已经隐藏
UIButton 是继承 UIControl 的,而 UIControl 可以通过allTargets与allControlEvents查看所有的对象与事件,再使用actionsForTarget:forControlEvent: 找到触发的方法
再次UI调试我在UI调试中出了一些问题,重启调试后内存地址有所变化
最终找到了触发的方法为[ContactsItemView onRightBtnAction]
2.5 hopper disassembler静态分析
用 hopper 打开微信的二进制文件,进行汇编与伪代码的转换
我的测试设备架构armv7
void -[ContactsItemView onRightBtnAction](void * self, void * _cmd) {
r10 = self;
r5 = r10 + *0x32be440;
r6 = objc_loadWeakRetained(r5);
if (r6 != 0x0) {
r4 = objc_loadWeakRetained(r5);
r8 = @selector(onContactsItemViewRightButtonClick:);
r11 = [r4 respondsToSelector:r8];
[r4 release];
[r6 release];
if (r11 != 0x0) {
r0 = objc_loadWeakRetained(r5);
r4 = r0;
objc_msgSend(r0, r8);
loc_27593d8(r4, r8, r10);
}
}
return;
}
可以得出,r11 = [r5 onContactsItemViewRightButtonClick:btn],而 r5 判断为 self 的*代*理*,也可以通过在之前用 class-dump 的头文件里面搜索onContactsItemViewRightButtonClick,会发现在ContactsItemViewDelegate中
也就是[ContactsItemView onRightBtnAction]内部调用了[self.delegate onContactsItemViewRightButtonClick:]
而ContactsItemView的delegate为SayHelloViewController
定位方法 onContactsItemViewRightButtonClick
onContactsItemViewRightButtonClick其实是执行了if([r4 isKindOfClass:[CPushContact class]]);
而r4是CPushContact 对象,不然下面的代码都不执行了。通过lldb打断点,并查看r3寄存器的对象类型,可以看到该对象为 CPushContact 对象。因此r4就是 CPushContact 对象,字面意思得到联系人对象。
可以看到也进行了一次判断if (((loc_1c099bc(r6, @selector(m_bSuspiciousUser)) & 0xff) != 0x0) && ((loc_1c099bc(r6, @selector(isMMContact)) & 0xff) == 0x0)),看到了MMUIAlertView 推测是弹窗的 view ,推测如果是当前申请的好友已经是自己的好友,那就进行弹窗。另一部分为verifyContactWithOpCode:opcode:,推测该部分为添加好友的方法。
可以通过Log 分析或者通过 lldb 打断点,会看到都会进入该方法。且参数分别为 CPushContact 对象与 3。
接着继续分析verifyContactWithOpCode:opcode:方法
verifyContactWithOpCode:opcode主要内容可以得到,确认好友申请,显示构造了CContactVerifyLogic对象。再构造了一个CVerifyContactWrap对象,并设置了相关属性,比如m_nsUsrNamem_uiScenem_nsTicket.然后通过添加到数组中,通过CContactVerifyLogic对象的startWithVerifyContactWrap:opCode:parentView:fromChatRoom:方法发送
startWithVerifyContactWrap:opCode:parentView:fromChatRoom添加好友的对象是CPushContact,而获得好友请求的对象的CMessageWrap。这里需要进行转换,而转换的方法也在SayHelloViewController中,可以重复上面的分析方法获得
分析完成
四,Tweak
此处引用tkkk大大的成品
至此iOS逆向复现全部完成
网友评论