iOS逆向实战与工具使用(微信添加好友自动确认)
iOS逆向实战与工具使用(微信添加好友自动确认)
原文链接
源码地址
WeChatPlugin-iOS
Mac OS 版微信小助手(远程控制、消息防撤回、自动回复、微信多开)
一、前言
本篇主要实现在微信上自动添加好友,从而熟悉 iOS 逆向分析的过程。
二、 工具
2.1 MacBook 软件
- theos
- 制作 Tweak 的工具
- hopper disassembler
- 用于静态分析
- usbmuxd
- 端口转发,可以让我们通过usb连接手机进行ssh、lldb调试等。主要使用python-client目录下的文件
- class-dump
- dump 目标对象的 class 信息的工具.
- lldb
- 调试神器,用过的都说好。默认自带,在/Applications/Xcode.app/Contents/Developer/usr/bin/lldb 中。
2.2 越狱iPhone 软件
以下软件在 Cydia 中即可下载
- OpenSSH
- 实现在越狱手机上远程进行 ssh 服务
iOS 工具大部分都需要在 ssh 环境中使用
- Cycript
- 脚本语言,用于 hook 正在运行的进程,并实时注入代码。
- ondeviceconsole
- 用于在 Terminal 中查看手机的 log
- debugserver
- 用于连接手机进行 lldb 调试的工具。用 Xcode 在手机上进行 app 调试即可生成,在手机目录的 /Developer/usr/bin/ 中。
- 使用 debugserver 需要先进行处理。因为缺少task_for_pid权限,所以调试不了其他的 app。
debugserver + lldb环境搭建
三、 分析
- 思路:想要实现自动添加好友,则要拿到获取好友请求的方法,以及添加好友的方法。hook 获取好友请求的方法,在接收到好友请求的时候,执行添加好友的方法。
- 而这些主要逻辑在“新的朋友”界面。
3.1 定位好友请求的方法
3.1.1 UI 分析
想要拿到好友请求的方法,要先拿到方法实现的 ViewController。而这时候可以通过 UI 分析获得。
- 先打开新的朋友界面。
- 使用 usbmuxd 进行端口的转发
- usbmuxd进行ssh连接-iOS逆向工程
// 1. 端口的转发,(手机22 端口转到Mac 2222 端口)
python tcprelay.py -t 22:2222// 2. 再使用ssh连接至手机(举例 手机ip为 192.168.31.94)
ssh root@192.168.31.94 -p 2222
- 查看微信的进程信息
ps -e |grep WeChat
- cycript 注入
cycript -p WeChat
- 查看当前 UI 布局(或者用Reveal工具)
UIApp.keyWindow.recursiveDescription().toString()
- 因为知道当前的视图有tableview,所以找到tableview的对象。从上图可以看到该对象的地址为0x18c4be00。
- 在使用 nextResponder()根据响应者往上找当前的控制器。
- 找到当前的控制器,为SayHelloViewController
3.1.2 Log 分析
使用
class-dump
dump 出微信的 class 信息。class-dump -H WeChat -o ~/Document/headers/ // 保存在 ~/Document/headers/ 目录中
再使用 theos 的 logify 工具,该工具用来注入NSLog来打印方法的入参和出参。(就是在所有的方法里面加 log)
logify.pl ~/Document/headers/SayHelloViewController.h > ~/Desktop/Tweak.xm
- 注意:一般该Tweak.xm仍然无法执行,需要进行修改:
- 去掉.cxx destruct 方法
- 将HBLogDebug 改为NSLog
- 去掉所有的delegate
- 将所有的参数对象类型改成id
- 去掉所有的weak
- 在ssh中使用ondeviceconsole打印手机的 log。ondeviceconsole使用
- 这时操作添加自己好友。触发好友请求的方法。可以看到以下的 log
- 说明有好友添加请求的时候,会调用
[SayHelloViewController OnSayHelloDataChange]
3.1.3 动态分析
既然已经知道了当前控制器会调用OnSayHelloDataChange,那么我们可以想如何查看是哪些方法触发了OnSayHelloDataChange,这时候就要用到 lldb + hopper 神器了。
- 先用 hopper 打开微信的二进制文件。搜索-[SayHelloViewController OnSayHelloDataChange]方法。
- 可以看到当前方法在微信中的偏移地址0x14a4824。
- 再使用 usbmuxd 转换端口
python tcprelay.py -t 1234:1234
- 在 ssh 到手机上,开启 debugserver
debugserver *:1234 -a "WeChat"
使用新的 terminal 窗口,打开 lldb,连接1234端口,并查看当前所有进程。
// 打开lldb /Applications/Xcode.app/Contents/Developer/usr/bin/lldb // 连接端口调试 (lldb) process connect connect://localhost:1234 // 打印所有进程 (lldb) image list -o -f
- 找到微信在当前手机上的进程内存基地址为0x000b2000(
这个值不是不变的) - 通过以上可以找到 [SayHelloViewController OnSayHelloDataChange]方法在手机上的内存地址。即
内存地址 = 进程内存基地址 + 方法偏移地址
- 使用 br 打断点查看
br s -a "0x000b2000 + 0x14a4824"
- 接着输入 c 继续运行,重新使用另一微信账号添加好友,会触发该断点。
- 使用 bt 查看调用栈信息,即哪些方法调用了当前的方法,找到方法的上游。(异步调用的话没办法查看)
- 第一个表示当前的方法,可以看到在调用此方法前,该进程总共调用了3个方法。
- 分别计算出这三个方法在微信中的偏移量。
将这三个地址在 hopper 中查看,找到了对应的方法为
// 调用的顺序为从下到上 [SayHelloViewController OnSayHelloDataChange] [SayHelloDataLogic onFriendAssistAddMsg:] [FriendAsistSessionMgr OnAddMsgForSpecialSession:MsgList:] [CMessageMgr MainThreadNotifyToExt:]
从以上方法名可以猜测
[FriendAsistSessionMgr OnAddMsgForSpecialSession:MsgList:] //是用来接收添加好友消息的函数处理,其中MsgList:后面的参数可能为消息的数组,为了证明我们可以打个断点查看下。
看出r3确实是个数组,同时也得到了消息的对象为CMessageWrap 证明我们是对的。
解释下为什么要看r3,因为在 armv7 中,一个方法的调用,一般寄存器都是这么存储的。前四个参数放在r0~r3,剩下的存放在堆栈中。查看堆栈的话使用x/10 $sp 查看前10个堆栈里的对象地址。(在 armv64 中 ,前八个参数放在r0~r7,剩下的存放在堆栈中。)
然而FriendAsistSessionMgr这个类可能需要一些初始化,且放在SayHelloViewController中,而我们想要的是不管在哪个控制器里都可以 hook 住上面的消息数组对象。因此我们往上找,[CMessageMgr MainThreadNotifyToExt:],然而里面并没有我们需要的信息。而根据类名我们推测CMessageMgr是用来管理消息的。有可能是在异步执行了消息数组的获取。
- 因此,重复以上步骤,使用 logify 对CMessageMgr进行 Log 分析。最终锁定了
CMessageMgr MessageReturn: MessageInfo:Event:
3.2 定位 通过好友请求的方法
3.2.1 动态分析
- 我们知道,通过好友请求的方法,是在新的朋友界面,点击查看的时候触发的。(可以通过 Log 分析,然而这里还有另一个比较快速的方法)找到“查看”按钮的对象
- 而我们知道 UIButton 是继承 UIControl 的,而 UIControl 的话可以通过allTargets 与 allControlEvents查看所有的对象与事件,再使用actionsForTarget:forControlEvent:从而找到触发的方法。
- 看出所触发的方法为[ContactsItemView onRightBtnAction]
3.2.2 静态分析
- 既然拿到了方法名,那我们怎么看他具体的实现呢?
- 接下来就是大名鼎鼎的hopper 登场了。
- 用 hopper 打开微信的二进制文件,并进行汇编与伪代码的转换。
- 由于汇编读起来比较晦涩,所以还是进行伪代码的转换,这样效率比较快。点击该按钮进行转换
上图我们看到了
r10 = self; r5 = r10 + *0x33befe8; r4 = objc_loadWeakRetained(r5); r8 = @selector(onContactsItemViewRightButtonClick:); r11 = [r4 respondsToSelector:r8];
- 可以得出,r11 = [r5 onContactsItemViewRightButtonClick:btn],
而 r5 我们判断为 self 的代{过}{滤}理,这个我们也可以通过在之前用 class-dump 的头文件里面搜索onContactsItemViewRightButtonClick,会发现在ContactsItemViewDelegate中。
也就是[ContactsItemView onRightBtnAction]内部调用了[self.delegate onContactsItemViewRightButtonClick:].
而 ContactsItemView 的delegate为 SayHelloViewController。
- 再用 hopper 定位onContactsItemViewRightButtonClick。
- 看到这里估计会很蒙不知道从何下手。这时候只要加以推测就可以了。
上图中进行了两个if判断,第一个为
r10 = @selector(class);r2 = loc_1c099bc(@class(CPushContact), r10);r1 = @selector(isKindOfClass:);r5 = loc_1c099bc(r4, r1, r2);loc_1c099d4(r4);if ((r5 & 0xff) != 0x0) {
- 可以得出其实是执行了 if([r4 isKindOfClass:[CPushContact class]]);
而r4是什么呢?可以肯定是 CPushContact 对象,不然下面的代码都不执行了。我们可以根据3.1的动态分析,通过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:方法。
主要的部分如下所示。 - 通过分析,我们可以得到,确认好友申请,显示构造了CContactVerifyLogic对象。再构造了一个CVerifyContactWrap对象,并设置了相关属性,比如
m_nsUsrName
m_uiScene
m_nsTicket
.然后通过添加到数组中,通过CContactVerifyLogic
对象的startWithVerifyContactWrap:opCode:parentView:fromChatRoom:
方法发送。- 代码如下:
CContactVerifyLogic *verifyLogic = [[CContactVerifyLogic alloc] init];
CVerifyContactWrap *wrap = [[CVerifyContactWrap alloc] init];
[wrap setM_nsUsrName:contact.m_nsEncodeUserName];
[wrap setM_uiScene:contact.m_uiFriendScene];
[wrap setM_nsTicket:contact.m_nsTicket];
[wrap setM_nsChatRoomUserName:contact.m_nsChatRoomUserName];
wrap.m_oVerifyContact = contact;AutoSetRemarkMgr *mgr = [[MMServiceCenter defaultCenter] getService:[AutoSetRemarkMgr class]];
id attr = [mgr GetStrangerAttribute:contact AttributeName:1001];if([attr boolValue]) {[wrap setM_uiWCFlag:(wrap.m_uiWCFlag | 1)];
}
[verifyLogic startWithVerifyContactWrap:[NSArray arrayWithObject:wrap] opCode:3 parentView:[UIView new] fromChatRoom:NO];
- 这样我们就得到了 获取好友请求的方法与添加好友的方法。
- 而这里还有一个问题,就是添加好友的对象是CPushContact,而获得好友请求的对象的CMessageWrap。这里需要进行转换,而转换的方法也在SayHelloViewController中,可以重复上面的分析方法获得。
五、编写Tweak
- 通过以上的分析,将代码合并起来
%hook CMessageMgr
- (void)MessageReturn:(unsigned int)arg1 MessageInfo:(NSDictionary *)info Event:(unsigned int)arg3 {%orig;if (arg1 == 332) { // 收到添加好友消息NSString *keyStr = [info objectForKey:@"5"];if ([keyStr isEqualToString:@"fmessage"]) {NSArray *wrapArray = [info objectForKey:@"27"];[self addAutoVerifyWithArray:wrapArray];}}
}%new
- (void)addAutoVerifyWithArray:(NSArray *)ary {[ary enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {CPushContact *contact = [%c(SayHelloDataLogic) getContactFrom:obj];if (![contact isMyContact] && [contact.m_nsDes isEqualToString:autoVerifyKeyword]) {CContactVerifyLogic *verifyLogic = [[%c(CContactVerifyLogic) alloc] init];CVerifyContactWrap *wrap = [[%c(CVerifyContactWrap) alloc] init];[wrap setM_nsUsrName:contact.m_nsEncodeUserName];[wrap setM_uiScene:contact.m_uiFriendScene];[wrap setM_nsTicket:contact.m_nsTicket];[wrap setM_nsChatRoomUserName:contact.m_nsChatRoomUserName];wrap.m_oVerifyContact = contact;AutoSetRemarkMgr *mgr = [[%c(MMServiceCenter) defaultCenter] getService:%c(AutoSetRemarkMgr)];id attr = [mgr GetStrangerAttribute:contact AttributeName:1001];if([attr boolValue]) {[wrap setM_uiWCFlag:(wrap.m_uiWCFlag | 1)];}[verifyLogic startWithVerifyContactWrap:[NSArray arrayWithObject:wrap] opCode:3 parentView:[UIView new] fromChatRoom:NO];}}];
}
五、总结
- 由于整个逆向流程有点繁琐,有时候也不是只要分析一次就可以成功的,需要反反复复的进行UI分析、LOG分析、lldb分析。因此可能在过程中,有些知识没有漏掉,希望大家可以指出。
转载于:https://www.cnblogs.com/ShaoYinling/p/8735393.html
iOS逆向实战与工具使用(微信添加好友自动确认)相关推荐
- iOS逆向重签名(三):微信重签名
目录: 1. iOS逆向重签名(一):签名原理 2. iOS逆向重签名(二):IPA重签名 3. iOS逆向重签名(三):微信重签名 学习了IPA包的重签名技术,下面将这项技术运用到实战中,尝试对微信 ...
- iOS逆向之脱壳工具creakerXI+,最简单、最适合新手的脱壳工具
在学习iOS逆向中,脱壳是必备技能之一,在网上看教程有使用 Clutch 和 dumpdecrypted 但是,不知道 是我操作问题,还是手机版本,以及APP版本更新问题 尝试了几次,都无法成功脱壳 ...
- android微信逆向工程,iOS逆向 - 微信自动添加好友
相关源码:Github地址 一.前言 本篇主要实现在微信上自动添加好友,从而熟悉 iOS 逆向分析的过程. 二. 工具 2.1 MacBook 软件 制作 Tweak 的工具 端口转发,可以让我们通过 ...
- iOS逆向-微信自动添加好友
前言 上次完成了 macOS 版微信小助手,现在终于有(xian)时(de)间(huang)来说说 iOS 逆向了.本篇主要实现在微信上自动添加好友(即自动验证新的朋友申请),从而熟悉 iOS 逆向分 ...
- iOS逆向(1)——利用ipa重签名,3分钟iPhone安装多个微信
本文要达成如图效果,在一台iPhone上安装第二个微信: 准备: Xcode 微信ipa(可通过iTool进行下载) 重签名脚本 步骤 打开Xcode,新建Single View App项目,名字可以 ...
- 微信怎么自动加好友java_iOS逆向开发之微信自动添加好友功能
这一次,小程演示怎么让一个APP自动地运行,从而代替手工的操作.同样以"微信"以例,实现在一个微信群里面,对所有的成员,自动地一个一个地发出添加好友的请求. 知识点还是之前介绍的东 ...
- iOS逆向:微信逆向及动态库开发过程中的坑
最近对 iOS 逆向很感兴趣,想学习下如何通过逆向app.分析源码.注入动态库的方式来给别人的软件增加些酷炫的功能.决定拿微信练手. 先上几个教程: 移动App入侵与逆向破解技术-iOS篇 给微信加 ...
- iOS逆向开发,突破微信强制升级,让低版本的iPhone也能正常使用
(1)安装与运行 在网上搜索微信的历史版本,下载一个兼容多开的版本(实际上是bundleID不一样),比如5.0版本.当然也可以通charles等,在AppStore上下载微信旧版本,再重签名. 通过 ...
- iOS逆向 开发工具
iOS逆向开发交流群 iOS逆向开发所需要的一些工具集合
最新文章
- 从Netflix的Hystrix框架理解服务熔断和服务降级
- 本年扩增子、宏基因组课程报名已满,想要学最早等明年
- MySQL命令及使用技巧以及当前时间字段默认值设置
- STM32串行通信USART解说笔记
- java web 的标准目录结构(zz)
- 从Encoder到Decoder实现Seq2Seq模型
- 南邮linux期末考试试题,南邮操作系统试卷及答案.doc
- 简单解决XP共享连接数10限制(转)
- 墨天轮章芋文:用十年打造中国的数据库生态体系
- 远程桌面服务器怎么重启计算机,电脑怎么样远程重新启动
- Android学习目录
- 分布式技术追踪 2017年第四十二期
- 解决ojdbc14库引用问题
- linux添加fuji打印机,Ubuntu16.04下添加打印机FujiXerox CP116w
- Google浏览器插件推荐
- python矩阵运算算法_Python常用库Numpy进行矩阵运算详解
- Centos7操作系统搭建Snipe-IT资产管理系统
- 编译原理实验(三)词法语法分析综合设计
- 逻辑思维能力测试题归纳总结之计算题
- WOS(Web of Science)检索规则