前言
我们继续之前的29-项目实战(1),接着破解分析拆
红包的相关逻辑。
一、IDA初使用
IDA
是windows平台上的反编译插件,如果在mac电脑上使用,首先得装个虚拟机,虚拟机上安装windows操作系统,现成的软件有Parallels Desktop
,可自行百度搜索安装。安装完成后,打开微信的Mach-O二进制文件👇🏻
⚠️注意:恢复符号表,这个时间段会很长(可能
3h
以上),我们等待就行。
二、静态分析拆红包
在静态分析之前,我们应该知道,Wechat的二进制文件是去符号
的,即很多OC的方法
被干掉
了,因此需要恢复,这样对IDA
反编译也有很大的帮助,此时我们可以使用Monkey
来做恢复符号这项工作。
2.1 Monkey恢复符号演示
其实很简单,就是修改Monkey的配置项👇🏻
恢复符号后的app包,再把里面的Mach-O
文件丢给IDA
进行反编译。
2.2 开始静态分析
目前,我们定位到拆红包
的方法是OnOpenRedEnvelopes
,这是一个实例方法
,而且这个实例是个view(WCRedEnvelopesReceiveHomeView
),那么触发它就必须有个前提 👉🏻 模拟构造一个WCRedEnvelopesReceiveHomeView
对象,很显然,这么做会很难。
我们只有想另外一条途径 👇🏻
OnOpenRedEnvelopes
内部的逻辑是什么?
我们只要能弄清楚拆红包的内部做的事情,然后将这个逻辑写到CheckMessageStatus:Msg
方法中,不就等于自动拆红包
了么。那么接下来的重点 👉🏻 反汇编OnOpenRedEnvelopes
内部的逻辑。
- 打开反汇编完成后的ida文件,搜索
OnOpenRedEnvelopes
👇🏻
-
WARedEnvelopesReceiveHomeView
头文件👇🏻
-
WCRedEnvelopesReceiveHomeView
头文件👇🏻
可见,WARedEnvelopesReceiveHomeView
和WCRedEnvelopesReceiveHomeView
大部分的属性和方法都一样,WA
这个应该是旧版本
的红包View类,里面的属性没有WC
的多。
- 分析汇编代码👇🏻
以上,其实分析下来,流程不怎么难,即获取一个字典m_dicBaseInfo
,获取key分别是isSender
和hbType
的value,再拿到m_delegate
对象,调用其WCRedEnvelopesReceiveHomeViewOpenRedEnvelope
方法。
三、动态调试拆红包
接下来,我们通过logos语法,hookWCRedEnvelopesReceiveHomeView
中的上面的关键信息,打印看看具体有什么。
- 成员变量
m_dicBaseInfo
和m_delegate
👇🏻
- 编写logos代码👇🏻
⚠️注意:针对成员变量的获取方式 👉🏻
MSHookIvar
首先要声明一下类
@interface WCRedEnvelopesReceiveHomeView
{
id m_delegate;// 具体delegate不需要指明
NSDictionary *m_dicBaseInfo;
}
@end
然后hook拆红包
方法,我们在拆
的时机点,打印信息
%hook WCRedEnvelopesReceiveHomeView
- (void)OnOpenRedEnvelopes {
// BaseInfo
NSDictionary *dict = MSHookIvar<NSDictionary *>(self, "m_dicBaseInfo");
NSArray *keys = [dict allKeys];
for (int i = 0; i < keys.count; i++) {
NSLog(@"%@ : %@", keys[i], [dict objectForKey:keys[i]]);
}
// delegate
id delegate = MSHookIvar<id>(self, "m_delegate");
NSLog(@"delegateClass:%@", [delegate class]);
%orig;
}
%end
- 编译安装,接收一个红包消息,点击
拆开
,查看控制台输出👇🏻
上图可见,m_dicBaseInfo
中的信息就是红包相关的信息,m_delegate
的类就是WCRedEnvelopesReceiveControlLogic
,那么拆红包
最终就是调用WCRedEnvelopesReceiveControlLogic
类的方法WCRedEnvelopesReceiveHomeViewOpenRedEnvelope
。
四、静态分析delegate
接下来,我们静态分析下WCRedEnvelopesReceiveControlLogic
的WCRedEnvelopesReceiveHomeViewOpenRedEnvelope
方法👇🏻
我们去WCRedEnvelopesReceiveControlLogic.h
头文件中看看👇🏻
果然有带参数
的方法,且参数类型是id
类型👇🏻
- (void)WCRedEnvelopesReceiveHomeViewOpenRedEnvelopes:(id)arg1;
那么,我们可以理解它的执行流程 的伪代码就是👇🏻
- (void)WCRedEnvelopesReceiveHomeViewOpenRedEnvelopes {
[self WCRedEnvelopesReceiveHomeViewOpenRedEnvelopes:0];
}
接着继续分析带参数的WCRedEnvelopesReceiveHomeViewOpenRedEnvelopes
👇🏻
接着我们看看m_data是什么👇🏻
m_data
的类是WCRedEnvelopesControlData
。那么上面的流程伪代码可以这么写👇🏻
- (void)WCRedEnvelopesReceiveHomeViewOpenRedEnvelopes:(id)arg1 {
[self reportReveiveHomeViewEmoticon];
WCRedEnvelopesControlData *data = self.m_data;
[data m_oSelectedMessageWrap];
}
继续,看看WCRedEnvelopesControlData
类的m_oSelectedMessageWrap
方法👇🏻
m_oSelectedMessageWrap
是一个属性,类是CMessageWrap
。
接着看CMessageWrap
👇🏻
m_oWCPayInfoItem
也是一个属性,类是WCPayInfoItem
,继续👇🏻
果然,m_c2cNativeUrl
也是一个属性。
综上,完善上面的伪代码👇🏻
- (void)WCRedEnvelopesReceiveHomeViewOpenRedEnvelopes:(id)arg1 {
[self reportReveiveHomeViewEmoticon];
WCRedEnvelopesControlData *data = self.m_data;
CMessageWrap *msgWrap = [data m_oSelectedMessageWrap];
WCPayInfoItem *payInfoItem = [msgWrap m_oWCPayInfoItem];
NSString *url = [payInfoItem m_c2cNativeUrl];
}
五、动态调试delegate
还是一样,根据上面的伪代码,接下来我们动态调试一下👇🏻
- 编写logos hook代码👇🏻
// 声明需要的类及属性
@interface WCPayInfoItem
@property(retain, nonatomic) NSString *m_c2cNativeUrl;
@end
@interface CMessageWrap
@property(retain, nonatomic) WCPayInfoItem *m_oWCPayInfoItem;
@end
@interface WCRedEnvelopesControlData
@property(retain, nonatomic) CMessageWrap *m_oSelectedMessageWrap;
@end
%hook WCRedEnvelopesReceiveControlLogic
- (void)WCRedEnvelopesReceiveHomeViewOpenRedEnvelopes:(id)arg1 {
// 这个流程是UIView相关的,不是拆红包的重点,可以注释掉
// [self reportReveiveHomeViewEmoticon];
// 不能直接.m_data获取,可通过MSHookIvar这种方式获取
// WCRedEnvelopesControlData *data = self.m_data;
WCRedEnvelopesControlData *data = MSHookIvar<WCRedEnvelopesControlData *>(self, "m_data");
// 以下3句可以简化成1句
// CMessageWrap *msgWrap = [data m_oSelectedMessageWrap];
// WCPayInfoItem *payInfoItem = [msgWrap m_oWCPayInfoItem];
// NSString *url = [payInfoItem m_c2cNativeUrl];
NSString *url = data.m_oSelectedMessageWrap.m_oWCPayInfoItem.m_c2cNativeUrl;
NSLog(@"m_c2cNativeUrl:%@", url);
// 也不需要继续走原有的流程,这样就不会真正的“拆”红包了
// %orig;
}
%end
- 编译安装,接收红包消息,查看控制台信息👇🏻
m_c2cNativeUrl:wxpay://c2cbizmessagehandler/hongbao/receivehongbao?msgtype=1&channelid=1&sendid=1000039901202108267308122328105&sendusername=Aron1101&ver=6&sign=39c4f82a43ecd7ae7154169e7c69ff70c71e43a1ace7bb9b9b35486c18e99b302cece5fa7544a479021db71856a3936182bc6dc7cf1d86267cbfba952b67bd4673e4751447d5bb1c76b2a52c7e7e32a1
我们拿到了url,其中包含有签名信息sign
。
- 我们继续往下静态分析
- (void)WCRedEnvelopesReceiveHomeViewOpenRedEnvelopes:(id)arg1
剩下的汇编代码流程👇🏻
-
cfstr_WxpayC2cbizmes
其实只需看WxpayC2cbizmes
,我们可以直接鼠标点进去
查看👇🏻
可见,cfstr_WxpayC2cbizmes
其实是个简化字符串,即👇🏻
wxpay://c2cbizmessagehandler/hongbao/receivehongbao?
和前面控制台打印输出的url
的前半部分一模一样,再回过头看汇编,就能明白cfstr_WxpayC2cbizmes
那块处理做的事情👇🏻
至此,我们分析到截取wxpay://c2cbizmessagehandler/hongbao/receivehongbao?
之后,得到的子串👇🏻
msgtype=1&channelid=1&sendid=1000039901202108267308122328105&sendusername=Aron1101&ver=6&sign=39c4f82a43ecd7ae7154169e7c69ff70c71e43a1ace7bb9b9b35486c18e99b302cece5fa7544a479021db71856a3936182bc6dc7cf1d86267cbfba952b67bd4673e4751447d5bb1c76b2a52c7e7e32a1
总结
本篇文章,使用IDA
逆向软件,针对WCRedEnvelopesReceiveHomeViewOpenRedEnvelopes
,通过静态分析
汇编代码,加上hook动态调试
打印关键信息,一步步得到关键的字串
。
我们先告一段落,后面文章将继续讲解WCRedEnvelopesReceiveHomeViewOpenRedEnvelopes
的重点 👉🏻 31-项目实战(3)还原红包方法
。