我只是一個(gè)對(duì)逆向有強(qiáng)烈興趣的iOS開(kāi)發(fā)者,并不是專(zhuān)業(yè)做逆向工作的响驴。因?yàn)槎啻螌?duì)實(shí)現(xiàn)微信自動(dòng)搶紅包有過(guò)接觸,并且在一個(gè)初級(jí)都不算的逆向者看來(lái)诗祸,把我們偉大的疼阔,國(guó)民用戶(hù)第一牛掰的App---微信給逆向枕赵,還能實(shí)現(xiàn)自動(dòng)搶紅包這樣的功能剿吻,實(shí)在心潮澎湃譬猫,心向往之拾弃!
這次有幸在一次網(wǎng)絡(luò)公開(kāi)課中學(xué)習(xí)到這項(xiàng)技能值桩。接下來(lái)我會(huì)提供教學(xué)視頻,工具和資料豪椿。供你我這種逆向小白菜去實(shí)現(xiàn)這種高大上的功能奔坟。
免責(zé)聲明:
逆向技術(shù)是可以學(xué)習(xí),共享的搭盾。但是對(duì)技術(shù)的使用決定了你行為好壞咳秉。這個(gè)好壞就看造成了什么結(jié)果。針對(duì)搶紅包這個(gè)功能鸯隅,說(shuō)簡(jiǎn)單了是你搶了幾個(gè)紅包澜建,如果涉嫌金額過(guò)大,便形成了欺騙蝌以。此等行為過(guò)大就會(huì)淪為犯罪炕舵。真的老技術(shù)骨可能武功高強(qiáng),能實(shí)現(xiàn)的會(huì)很多跟畅,但往往更懂這個(gè)道理咽筋,恰恰是初入江湖的小生們應(yīng)當(dāng)注意了。說(shuō)的就是你;布<楣ァ蒜危!
Just do it!
實(shí)現(xiàn)步驟:
1、下載IPA舞箍;
2舰褪、dumpdecrypted(砸殼);
3疏橄、class-dump(導(dǎo)出功能頭文件);
4略就、動(dòng)態(tài)分析(找到接收消息和拆紅包的方法)捎迫;
5、靜態(tài)分析(實(shí)現(xiàn)代碼邏輯)
1表牢、下載IPA
在電腦上打開(kāi)iTunes下載一個(gè)最新版本的微信窄绒,然后連上iPhone,用iTunes裝上剛剛下載的微信崔兴。(建議把原有的微信刪掉再安裝)2彰导、dumpdecrypted(砸殼)
我們的iOS IPA都是被蘋(píng)果加殼的。這個(gè)工作我們開(kāi)發(fā)者不用去做敲茄,因?yàn)樘O(píng)果會(huì)幫我們做位谋,他也不允許我們?nèi)プ觥<热凰o我們加殼了堰燎,現(xiàn)在我們就不得不去砸殼掏父。
砸殼就使用dumpdecrypted這個(gè)工具。別問(wèn)為什么秆剪,因?yàn)樗容^好用赊淑,而且自己搞不出來(lái)。鏈接地址:https://github.com/stefanesser/dumpdecrypted
使用教程下面已經(jīng)寫(xiě)好了仅讽,如果還是有問(wèn)題陶缺,網(wǎng)上還有很多詳細(xì)教程。
如果你覺(jué)得1和2兩步驟有點(diǎn)麻煩洁灵,不想下手饱岸,那就算了吧〈υ……我這里還有一個(gè)很簡(jiǎn)單很簡(jiǎn)單的方法……那就是……用現(xiàn)成的資源伶贰。可以去PP助手上等下載已經(jīng)砸過(guò)殼的IPA包罐栈。如果你還覺(jué)得麻煩……那我給你鏈接黍衙,去下載吧,這是一個(gè)現(xiàn)成的已經(jīng)被砸殼的IPA包:鏈接: https://pan.baidu.com/s/1ax4UWeDSTpPg88uq4HnYIg 密碼: n5a3
3荠诬、class-dump(導(dǎo)出功能頭文件)
恭喜你們拿到了已砸殼的微信IPA包琅翻。那么別啰嗦位仁,讓我們立馬進(jìn)行class-dump,拿到微信頭文件方椎。只要拿到了頭文件聂抢,我們就可以定位到微信中紅包相關(guān)的類(lèi),進(jìn)而找尋方法棠众,最后才有機(jī)會(huì)修改相關(guān)搶紅包代碼琳疏,達(dá)到自動(dòng)拆紅包的目的。
(1)闸拿、將IPA文件直接修改后綴名 zip空盼,解壓。拿到WeChat.app(WeChat.app是一個(gè)可執(zhí)行文件)新荤。
(2)揽趾、拿到可執(zhí)行文件過(guò)后,我們就要從這個(gè)家伙身上取出頭文件了苛骨。
使用class-dump工具:https://github.com/nygard/class-dump
按照教程進(jìn)行class-dump篱瞎,可得到所有頭文件:
一共11601項(xiàng):
(3)、將整個(gè)文件拖到sublime當(dāng)中去痒芝。此時(shí)你可以隨意查看微信所有頭文件了俐筋。(作為一個(gè)第一次逆向微信的人,查看到微信所有的頭文件令我有些許激動(dòng)……原來(lái)這就是那幫牛逼的微信代碼:鹨啊)
4校哎、動(dòng)態(tài)分析(找到接收消息和拆紅包的方法)
動(dòng)態(tài)分析咋回事,肯定要?jiǎng)悠饋?lái)瞳步。怎么動(dòng)闷哆?往左,往右单起,還是左右一個(gè)慢動(dòng)作抱怔?算了,還是直接告訴你吧嘀倒,就是通過(guò)發(fā)送消息屈留,紅包等操作來(lái)定位找到我們需要去處理的類(lèi),甚至是方法测蘑。目前我們已經(jīng)拿到了微信所有代碼中的入口文件灌危,也就是說(shuō)微信所有業(yè)務(wù)的頭文件都被我們拿到了。現(xiàn)在我們要做的就是分析我們搶紅包業(yè)務(wù)會(huì)涉及到什么類(lèi)甚至是方法碳胳。
(1)編譯運(yùn)行起來(lái)微信
下載https://github.com/AloneMonkey/MonkeyDev
使用教程在其正文下清晰寫(xiě)著勇蝙,并且很暖心是中文。這是網(wǎng)易一個(gè)安全工程師的杰作挨约。使用這個(gè)工具我們首先可以運(yùn)行起來(lái)微信App味混,包括開(kāi)發(fā)賬號(hào)授權(quán)等問(wèn)題都幫我們搞定了产雹。
1、安裝好后翁锡,Xcode中會(huì)多出一個(gè)MonkeyApp蔓挖。借助他創(chuàng)建一個(gè)工程。
2馆衔、將WeChat.app 文件添加進(jìn)工程瘟判。然后選擇你的真機(jī),command+R角溃。
3荒适、Run起來(lái)了。我們接下來(lái)需要做的就是通過(guò)發(fā)送紅包开镣,來(lái)動(dòng)態(tài)捕捉方法。
4咽扇、使用monkey邪财,修改配置文件,進(jìn)行方法捕捉
5质欲、收到一條消息树埠,我們點(diǎn)擊進(jìn)入頁(yè)面,可以看到打出了相應(yīng)的Log嘶伟。說(shuō)明我們的頁(yè)面展示就在這里怎憋。這里只是做一個(gè)找頁(yè)面的結(jié)果,因?yàn)檎麄€(gè)找尋方法很復(fù)雜九昧。需要我們了解一些工具绊袋,并且有分析能力,需要iOS成熟的工作經(jīng)驗(yàn)铸鹰。
6癌别、hook方法。語(yǔ)法比較簡(jiǎn)單蹋笼,我們需要hook的方法有很多展姐,為什么這幾個(gè)方法,需要我們一層一層的從Controller剖毯,和消息收發(fā)機(jī)制中去追蹤圾笨。這里我們舉一個(gè)例子:
這個(gè)發(fā)方法中我們可以拿到msgWrag參數(shù),可以找到其中有我們需要的用戶(hù)消息type逊谋,消息發(fā)送者信息等擂达。
5、靜態(tài)分析(實(shí)現(xiàn)代碼邏輯)
整個(gè)分析過(guò)程需要懂得匯編語(yǔ)法涣狗,經(jīng)過(guò)分析谍婉,弄懂了微信搶紅包的方法調(diào)用邏輯舒憾。我們才能知道hook哪些方法。具體就是穗熬,在收到消息镀迂,我們判斷是紅包消息。然后我們直接調(diào)用拆紅包方法唤蔗。收到消息探遵,肯定實(shí)在我們找到的Controller:baseMsgContentViewController中。拆紅包的方法肯定在我們?cè)诩t包動(dòng)畫(huà)執(zhí)行完成后妓柜,點(diǎn)擊“拆”字按鈕中箱季。
其中我們?yōu)榱苏嬲龑?shí)現(xiàn)搶紅包,需要根據(jù)邏輯創(chuàng)建一個(gè)搶紅包Identity棍掐,通過(guò)這個(gè)參數(shù)進(jìn)行搶紅包接口調(diào)用藏雏。服務(wù)器通過(guò)后,我們才能真正的實(shí)現(xiàn)無(wú)障礙搶紅包作煌。
為了不增加過(guò)程中的繁雜說(shuō)明掘殴,我直接上來(lái)需要hook的方法。
// See http://iphonedevwiki.net/index.php/Logos
#import <UIKit/UIKit.h>
#import "WeChatRedEnvelopParamQueue.h"
@interface WCRedEnvelopesReceiveHomeView
{
id m_delegate;
NSDictionary *m_dicBaseInfo;
}
@end
@interface WCPayInfoItem
@property(retain, nonatomic) NSString *m_c2cNativeUrl;
@end
@interface CMessageWrap
@property(retain, nonatomic) WCPayInfoItem *m_oWCPayInfoItem;
@property(retain, nonatomic) NSString *m_nsFromUsr;
@end
@interface WCRedEnvelopesControlData{
CMessageWrap *m_oSelectedMessageWrap;
}
@property(retain, nonatomic) NSDictionary *m_structDicRedEnvelopesBaseInfo;
-(CMessageWrap *)m_oSelectedMessageWrap;
@end
@interface WCRedEnvelopesReceiveControlLogic{
WCRedEnvelopesControlData *m_data;
}
@end
@interface WCBizUtil
+ (id)dictionaryWithDecodedComponets:(id)arg1 separator:(id)arg2;
@end
@interface MMServiceCenter
+ (id)defaultCenter;
- (id)getService:(Class)arg1;
@end
@interface MMMsgLogicManager
- (id)GetCurrentLogicController;
@end
@interface CContactMgr
- (id)getSelfContact;
@end
@interface CContact
- (id)getContactDisplayName;
@property(retain, nonatomic) NSString *m_nsHeadImgUrl; // @synthesize m_nsHeadImgUrl;
@end
@interface CBaseContact
@property(retain, nonatomic) NSString *m_nsUsrName; // @synthesize m_nsUsrName;
@end
@interface WeixinContentLogicController
@property(retain, nonatomic) CBaseContact *m_contact; // @synthesize m_contact;
@end
@interface WCPayLogicMgr{
unsigned int m_uiRealnameReportScene;
}
- (void)checkHongbaoOpenLicense:(id)arg1 acceptCallback:(void(^)())arg2 denyCallback:(void(^)())arg3;
- (void)setRealnameReportScene:(unsigned int)arg1;
@end
@interface SKBuiltinBuffer_t
// Remaining properties
@property(retain, nonatomic) NSData *buffer; // @dynamic buffer;
@property(nonatomic) unsigned int iLen; // @dynamic iLen;
@end
@interface BaseResponse
@property(nonatomic) int ret; // @dynamic ret;
@end
@interface HongBaoRes
// Remaining properties
@property(retain, nonatomic) BaseResponse *baseResponse; // @dynamic baseResponse;
@property(nonatomic) int cgiCmdid; // @dynamic cgiCmdid;
@property(retain, nonatomic) NSString *errorMsg; // @dynamic errorMsg;
@property(nonatomic) int errorType; // @dynamic errorType;
@property(retain, nonatomic) NSString *platMsg; // @dynamic platMsg;
@property(nonatomic) int platRet; // @dynamic platRet;
@property(retain, nonatomic) SKBuiltinBuffer_t *retText; // @dynamic retText;
@end
@interface WCRedEnvelopesLogicMgr
- (void)OnWCToHongbaoCommonResponse:(HongBaoRes *)arg1 Request:(id)arg2;
- (void)ReceiverQueryRedEnvelopesRequest:(id)arg1;
- (void)OpenRedEnvelopesRequest:(id)arg1;
@end
%hook WCRedEnvelopesLogicMgr
- (void)OnWCToHongbaoCommonResponse:(HongBaoRes *)arg1 Request:(id)arg2{
%orig;
NSString* responseString = [[NSString alloc] initWithData:arg1.retText.buffer encoding:NSUTF8StringEncoding];
// NSLog(@"arg1: cgiCmdid = %d, errorMsg = %@, errorType = %d, platMsg = %@, platRet = %d, retText = %@", arg1.cgiCmdid, arg1.errorMsg, arg1.errorType, arg1.platMsg, arg1.platRet, responseString);
NSError* err;
NSDictionary* responseDict = [NSJSONSerialization JSONObjectWithData:arg1.retText.buffer options:NSJSONReadingMutableContainers error:&err];
// NSArray* arr = [responseDict allKeys];
// for( NSInteger i = 0; i < arr.count; ++i){
// NSLog(@"%@ : %@", arr[i], [responseDict objectForKey:arr[i]]);
// }
if(nil != arg1 && nil != arg2 && 3 == arg1.cgiCmdid){
NSString* timingIdentifier = responseDict[@"timingIdentifier"];
//拿到timingIdentifier 開(kāi)始搶紅包
NSMutableDictionary * param = [[WeChatRedEnvelopParamQueue sharedQueue] dequeue];
//然后開(kāi)始拼接
if(param == nil){ return;}
[param setObject:timingIdentifier forKey:@"timingIdentifier"];
sleep(1);
WCRedEnvelopesLogicMgr* redEnvelopesLogicMgr = [[%c(MMServiceCenter) defaultCenter] getService:[%c(WCRedEnvelopesLogicMgr) class]];
//真正打開(kāi)紅包請(qǐng)求的方法!
if(redEnvelopesLogicMgr){
[redEnvelopesLogicMgr OpenRedEnvelopesRequest:param];
}
}
}
%end
%hook CMessageMgr
//收到新消息!
- (void)onNewSyncAddMessage:(CMessageWrap *)msgWrap{
//將WCRedEnvelopesReceiveHomeViewOpenRedEnvelopes邏輯移植過(guò)來(lái)
if(MSHookIvar <unsigned int>(msgWrap,"m_uiMessageType") == 49){
NSString *c2cNativeUrl = [[msgWrap m_oWCPayInfoItem] m_c2cNativeUrl];
NSUInteger len = [@"wxpay://c2cbizmessagehandler/hongbao/receivehongbao?" length];
NSString *nativeUrl2 = [c2cNativeUrl substringFromIndex:len];
NSDictionary* url_dic = [%c(WCBizUtil) dictionaryWithDecodedComponets:nativeUrl2 separator:@"&"];
//搶紅包參數(shù)拼接!!
NSMutableDictionary* mutable_dic = [%c(NSMutableDictionary) dictionary];
[mutable_dic setObject:@"1" forKey:@"msgType"];
[mutable_dic setObject:url_dic[@"sendid"] forKey:@"sendId"];
[mutable_dic setObject:url_dic[@"channelid"] forKey:@"channelId"];
//接下來(lái)
CContactMgr* contactMgr = [[%c(MMServiceCenter) defaultCenter] getService:[%c(CContactMgr) class]];
CContact * selfContact = [contactMgr getSelfContact];
id displayName = [selfContact getContactDisplayName];
[mutable_dic setObject:displayName forKey:@"nickName"];
[mutable_dic setObject:[selfContact m_nsHeadImgUrl] forKey:@"headImg"];
if(msgWrap) {
[mutable_dic setObject:c2cNativeUrl forKey:@"nativeUrl"];
}
//拼接發(fā)送方用戶(hù)名
NSString * nsUsrName = MSHookIvar <NSString *>(msgWrap,"m_nsFromUsr");
if ( nsUsrName ){
NSLog(@"%@",nsUsrName);
[mutable_dic setObject:nsUsrName forKey:@"sessionUserName"];
}
//將參數(shù)保存!!
WeChatRedEnvelopParamQueue * paramQueue = [WeChatRedEnvelopParamQueue sharedQueue];
[paramQueue enqueue:mutable_dic];
//拆紅包
//通過(guò)字段判斷是群紅包還是個(gè)人紅包
BOOL (^isGroupReceiver)() = ^BOOL() {
return [msgWrap.m_nsFromUsr rangeOfString:@"@chatroom"].location != NSNotFound;
};
//拼接參數(shù)
NSMutableDictionary* params = [%c(NSMutableDictionary) dictionary];
[params setObject:@"0" forKey:@"agreeDuty"];
//是否是群紅包!
[params setObject: isGroupReceiver() ? @"0" : @"1" forKey:@"inWay"];
[params setObject:url_dic[@"channelid"] forKey:@"channelId"];
[params setObject:@"1" forKey:@"msgType"];
[params setObject:c2cNativeUrl forKey:@"nativeUrl"];
[params setObject:url_dic[@"sendid"] forKey:@"sendId"];
WCRedEnvelopesLogicMgr* redEnvelopesLogicMgr = [[%c(MMServiceCenter) defaultCenter] getService:[%c(WCRedEnvelopesLogicMgr) class]];
//真正拆開(kāi)紅包請(qǐng)求的方法!
[redEnvelopesLogicMgr ReceiverQueryRedEnvelopesRequest:params];
}else{
NSLog(@"%@",msgWrap);
}
%orig;
}
%end
%hook WCRedEnvelopesReceiveControlLogic
- (void)WCRedEnvelopesReceiveHomeViewOpenRedEnvelopes
{
WCRedEnvelopesControlData *m_data = MSHookIvar <WCRedEnvelopesControlData *>(self,"m_data");
//消息包!
CMessageWrap * msgWrap = [m_data m_oSelectedMessageWrap];
NSLog(@"%@",MSHookIvar <NSString *>(msgWrap,"m_nsFromUsr"));
WCPayInfoItem * payInfoItem = [msgWrap m_oWCPayInfoItem];
NSString *c2cNativeUrl = [payInfoItem m_c2cNativeUrl];
NSUInteger len = [@"wxpay://c2cbizmessagehandler/hongbao/receivehongbao?" length];
NSString *nativeUrl2 = [c2cNativeUrl substringFromIndex:len];
NSDictionary* url_dic = [%c(WCBizUtil) dictionaryWithDecodedComponets:nativeUrl2 separator:@"&"];
NSMutableDictionary* mutable_dic = [%c(NSMutableDictionary) dictionary];
[mutable_dic setObject:@"1" forKey:@"msgType"];
[mutable_dic setObject:url_dic[@"sendid"] forKey:@"sendId"];
[mutable_dic setObject:url_dic[@"channelid"] forKey:@"channelId"];
MMServiceCenter* mmserCent = [%c(MMServiceCenter) defaultCenter];
Class ccmgr = [%c(CContactMgr) class];
CContactMgr* contactMgr = [mmserCent getService:ccmgr];
CContact * selfContact = [contactMgr getSelfContact];
id displayName = [selfContact getContactDisplayName];
[mutable_dic setObject:displayName forKey:@"nickName"];
[mutable_dic setObject:[selfContact m_nsHeadImgUrl] forKey:@"headImg"];
if(msgWrap){
[mutable_dic setObject:c2cNativeUrl forKey:@"nativeUrl"];
}
MMMsgLogicManager * msgLogicManager = [[%c(MMServiceCenter) defaultCenter] getService:[%c(MMMsgLogicManager) class]];
WeixinContentLogicController * currentLogicController = [msgLogicManager GetCurrentLogicController];
if(currentLogicController){
CBaseContact* contact = [currentLogicController m_contact];
if ( contact ){
NSString * nsUsrName = [contact m_nsUsrName];
if ( nsUsrName ){
NSLog(@"%@",nsUsrName);
[mutable_dic setObject:nsUsrName forKey:@"sessionUserName"];
}
}
}
NSDictionary * structDicRedEnvelopesBaseInfo = [m_data m_structDicRedEnvelopesBaseInfo];
NSString *timingIdentifier = [structDicRedEnvelopesBaseInfo objectForKey:@"timingIdentifier"];
NSLog(@"%@",timingIdentifier);
if([timingIdentifier length]){
[mutable_dic setObject:timingIdentifier forKey:@"timingIdentifier"];
WCPayLogicMgr * paylogic = [[%c(MMServiceCenter) defaultCenter] getService:[%c(WCPayLogicMgr) class]];
[paylogic setRealnameReportScene:(unsigned int)1003];
WCPayLogicMgr* payLogicMgr = [[%c(MMServiceCenter) defaultCenter] getService:[%c(WCPayLogicMgr) class]];
id subScript = [structDicRedEnvelopesBaseInfo objectForKeyedSubscript:@"agree_duty"];
[payLogicMgr checkHongbaoOpenLicense:subScript acceptCallback:^{
WCRedEnvelopesLogicMgr* redEnvelopesLogicMgr = [[%c(MMServiceCenter) defaultCenter] getService:[%c(WCRedEnvelopesLogicMgr) class]];
//真正打開(kāi)紅包請(qǐng)求的方法!
[redEnvelopesLogicMgr OpenRedEnvelopesRequest:mutable_dic];
} denyCallback:^{
}];
}
}
%end
/*
%hook WCRedEnvelopesReceiveHomeView
//拆紅包方法
- (void)OnOpenRedEnvelopes{
//MSHookIvar 原理是調(diào)用了class_getInstanceVariable獲取類(lèi)中指定名稱(chēng)實(shí)例成員變量的信息
//目的拿到我的成員變量
NSDictionary * dict = MSHookIvar<NSDictionary *>(self,"m_dicBaseInfo");
NSArray * arr = [dict allKeys];
//打印字典內(nèi)容
for(int i = 0 ;i < arr.count ;i++){
NSLog(@"%@ : %@",arr[i],[dict objectForKey:arr[i]]);
}
//拿到代理類(lèi)型!
id delegate = MSHookIvar<id>(self,"m_delegate");
NSLog(@"delegateClass:%@",[delegate class]);
}
%end
*/
/*
%hook BaseMsgContentViewController
- (void)addMessageNode:(id)arg1 layout:(_Bool)arg2 addMoreMsg:(_Bool)arg3 {
%orig;
}
%end
*/
#line 1 "/Users/JingGuo/Desktop/WeChatRedEnvelope/WeChatRedEnvelopeDylib/Logos/WeChatRedEnvelopeDylib.xm"
#import <UIKit/UIKit.h>
#import "WeChatRedEnvelopParamQueue.h"
@interface WCRedEnvelopesReceiveHomeView
{
id m_delegate;
NSDictionary *m_dicBaseInfo;
}
@end
@interface WCPayInfoItem
@property(retain, nonatomic) NSString *m_c2cNativeUrl;
@end
@interface CMessageWrap
@property(retain, nonatomic) WCPayInfoItem *m_oWCPayInfoItem;
@property(retain, nonatomic) NSString *m_nsFromUsr;
@end
@interface WCRedEnvelopesControlData{
CMessageWrap *m_oSelectedMessageWrap;
}
@property(retain, nonatomic) NSDictionary *m_structDicRedEnvelopesBaseInfo;
-(CMessageWrap *)m_oSelectedMessageWrap;
@end
@interface WCRedEnvelopesReceiveControlLogic{
WCRedEnvelopesControlData *m_data;
}
@end
@interface WCBizUtil
+ (id)dictionaryWithDecodedComponets:(id)arg1 separator:(id)arg2;
@end
@interface MMServiceCenter
+ (id)defaultCenter;
- (id)getService:(Class)arg1;
@end
@interface MMMsgLogicManager
- (id)GetCurrentLogicController;
@end
@interface CContactMgr
- (id)getSelfContact;
@end
@interface CContact
- (id)getContactDisplayName;
@property(retain, nonatomic) NSString *m_nsHeadImgUrl;
@end
@interface CBaseContact
@property(retain, nonatomic) NSString *m_nsUsrName;
@end
@interface WeixinContentLogicController
@property(retain, nonatomic) CBaseContact *m_contact;
@end
@interface WCPayLogicMgr{
unsigned int m_uiRealnameReportScene;
}
- (void)checkHongbaoOpenLicense:(id)arg1 acceptCallback:(void(^)())arg2 denyCallback:(void(^)())arg3;
- (void)setRealnameReportScene:(unsigned int)arg1;
@end
@interface SKBuiltinBuffer_t
@property(retain, nonatomic) NSData *buffer;
@property(nonatomic) unsigned int iLen;
@end
@interface BaseResponse
@property(nonatomic) int ret;
@end
@interface HongBaoRes
@property(retain, nonatomic) BaseResponse *baseResponse;
@property(nonatomic) int cgiCmdid;
@property(retain, nonatomic) NSString *errorMsg;
@property(nonatomic) int errorType;
@property(retain, nonatomic) NSString *platMsg;
@property(nonatomic) int platRet;
@property(retain, nonatomic) SKBuiltinBuffer_t *retText;
@end
@interface WCRedEnvelopesLogicMgr
- (void)OnWCToHongbaoCommonResponse:(HongBaoRes *)arg1 Request:(id)arg2;
- (void)ReceiverQueryRedEnvelopesRequest:(id)arg1;
- (void)OpenRedEnvelopesRequest:(id)arg1;
@end
#include <substrate.h>
#if defined(__clang__)
#if __has_feature(objc_arc)
#define _LOGOS_SELF_TYPE_NORMAL __unsafe_unretained
#define _LOGOS_SELF_TYPE_INIT __attribute__((ns_consumed))
#define _LOGOS_SELF_CONST const
#define _LOGOS_RETURN_RETAINED __attribute__((ns_returns_retained))
#else
#define _LOGOS_SELF_TYPE_NORMAL
#define _LOGOS_SELF_TYPE_INIT
#define _LOGOS_SELF_CONST
#define _LOGOS_RETURN_RETAINED
#endif
#else
#define _LOGOS_SELF_TYPE_NORMAL
#define _LOGOS_SELF_TYPE_INIT
#define _LOGOS_SELF_CONST
#define _LOGOS_RETURN_RETAINED
#endif
@class WCPayLogicMgr; @class WCRedEnvelopesReceiveControlLogic; @class WCRedEnvelopesLogicMgr; @class WCBizUtil; @class NSMutableDictionary; @class CContactMgr; @class MMMsgLogicManager; @class CMessageMgr; @class MMServiceCenter;
static void (*_logos_orig$_ungrouped$WCRedEnvelopesLogicMgr$OnWCToHongbaoCommonResponse$Request$)(_LOGOS_SELF_TYPE_NORMAL WCRedEnvelopesLogicMgr* _LOGOS_SELF_CONST, SEL, HongBaoRes *, id); static void _logos_method$_ungrouped$WCRedEnvelopesLogicMgr$OnWCToHongbaoCommonResponse$Request$(_LOGOS_SELF_TYPE_NORMAL WCRedEnvelopesLogicMgr* _LOGOS_SELF_CONST, SEL, HongBaoRes *, id); static void (*_logos_orig$_ungrouped$CMessageMgr$onNewSyncAddMessage$)(_LOGOS_SELF_TYPE_NORMAL CMessageMgr* _LOGOS_SELF_CONST, SEL, CMessageWrap *); static void _logos_method$_ungrouped$CMessageMgr$onNewSyncAddMessage$(_LOGOS_SELF_TYPE_NORMAL CMessageMgr* _LOGOS_SELF_CONST, SEL, CMessageWrap *); static void (*_logos_orig$_ungrouped$WCRedEnvelopesReceiveControlLogic$WCRedEnvelopesReceiveHomeViewOpenRedEnvelopes)(_LOGOS_SELF_TYPE_NORMAL WCRedEnvelopesReceiveControlLogic* _LOGOS_SELF_CONST, SEL); static void _logos_method$_ungrouped$WCRedEnvelopesReceiveControlLogic$WCRedEnvelopesReceiveHomeViewOpenRedEnvelopes(_LOGOS_SELF_TYPE_NORMAL WCRedEnvelopesReceiveControlLogic* _LOGOS_SELF_CONST, SEL);
static __inline__ __attribute__((always_inline)) __attribute__((unused)) Class _logos_static_class_lookup$MMServiceCenter(void) { static Class _klass; if(!_klass) { _klass = objc_getClass("MMServiceCenter"); } return _klass; }static __inline__ __attribute__((always_inline)) __attribute__((unused)) Class _logos_static_class_lookup$WCBizUtil(void) { static Class _klass; if(!_klass) { _klass = objc_getClass("WCBizUtil"); } return _klass; }static __inline__ __attribute__((always_inline)) __attribute__((unused)) Class _logos_static_class_lookup$WCRedEnvelopesLogicMgr(void) { static Class _klass; if(!_klass) { _klass = objc_getClass("WCRedEnvelopesLogicMgr"); } return _klass; }static __inline__ __attribute__((always_inline)) __attribute__((unused)) Class _logos_static_class_lookup$MMMsgLogicManager(void) { static Class _klass; if(!_klass) { _klass = objc_getClass("MMMsgLogicManager"); } return _klass; }static __inline__ __attribute__((always_inline)) __attribute__((unused)) Class _logos_static_class_lookup$WCPayLogicMgr(void) { static Class _klass; if(!_klass) { _klass = objc_getClass("WCPayLogicMgr"); } return _klass; }static __inline__ __attribute__((always_inline)) __attribute__((unused)) Class _logos_static_class_lookup$CContactMgr(void) { static Class _klass; if(!_klass) { _klass = objc_getClass("CContactMgr"); } return _klass; }static __inline__ __attribute__((always_inline)) __attribute__((unused)) Class _logos_static_class_lookup$NSMutableDictionary(void) { static Class _klass; if(!_klass) { _klass = objc_getClass("NSMutableDictionary"); } return _klass; }
#line 109 "/Users/JingGuo/Desktop/WeChatRedEnvelope/WeChatRedEnvelopeDylib/Logos/WeChatRedEnvelopeDylib.xm"
static void _logos_method$_ungrouped$WCRedEnvelopesLogicMgr$OnWCToHongbaoCommonResponse$Request$(_LOGOS_SELF_TYPE_NORMAL WCRedEnvelopesLogicMgr* _LOGOS_SELF_CONST __unused self, SEL __unused _cmd, HongBaoRes * arg1, id arg2){
_logos_orig$_ungrouped$WCRedEnvelopesLogicMgr$OnWCToHongbaoCommonResponse$Request$(self, _cmd, arg1, arg2);
NSString* responseString = [[NSString alloc] initWithData:arg1.retText.buffer encoding:NSUTF8StringEncoding];
NSError* err;
NSDictionary* responseDict = [NSJSONSerialization JSONObjectWithData:arg1.retText.buffer options:NSJSONReadingMutableContainers error:&err];
if(nil != arg1 && nil != arg2 && 3 == arg1.cgiCmdid){
NSString* timingIdentifier = responseDict[@"timingIdentifier"];
NSMutableDictionary * param = [[WeChatRedEnvelopParamQueue sharedQueue] dequeue];
if(param == nil){ return;}
[param setObject:timingIdentifier forKey:@"timingIdentifier"];
sleep(1);
WCRedEnvelopesLogicMgr* redEnvelopesLogicMgr = [[_logos_static_class_lookup$MMServiceCenter() defaultCenter] getService:[_logos_static_class_lookup$WCRedEnvelopesLogicMgr() class]];
if(redEnvelopesLogicMgr){
[redEnvelopesLogicMgr OpenRedEnvelopesRequest:param];
}
}
}
static void _logos_method$_ungrouped$CMessageMgr$onNewSyncAddMessage$(_LOGOS_SELF_TYPE_NORMAL CMessageMgr* _LOGOS_SELF_CONST __unused self, SEL __unused _cmd, CMessageWrap * msgWrap){
if(MSHookIvar <unsigned int>(msgWrap,"m_uiMessageType") == 49){
NSString *c2cNativeUrl = [[msgWrap m_oWCPayInfoItem] m_c2cNativeUrl];
NSUInteger len = [@"wxpay://c2cbizmessagehandler/hongbao/receivehongbao?" length];
NSString *nativeUrl2 = [c2cNativeUrl substringFromIndex:len];
NSDictionary* url_dic = [_logos_static_class_lookup$WCBizUtil() dictionaryWithDecodedComponets:nativeUrl2 separator:@"&"];
NSMutableDictionary* mutable_dic = [_logos_static_class_lookup$NSMutableDictionary() dictionary];
[mutable_dic setObject:@"1" forKey:@"msgType"];
[mutable_dic setObject:url_dic[@"sendid"] forKey:@"sendId"];
[mutable_dic setObject:url_dic[@"channelid"] forKey:@"channelId"];
CContactMgr* contactMgr = [[_logos_static_class_lookup$MMServiceCenter() defaultCenter] getService:[_logos_static_class_lookup$CContactMgr() class]];
CContact * selfContact = [contactMgr getSelfContact];
id displayName = [selfContact getContactDisplayName];
[mutable_dic setObject:displayName forKey:@"nickName"];
[mutable_dic setObject:[selfContact m_nsHeadImgUrl] forKey:@"headImg"];
if(msgWrap) {
[mutable_dic setObject:c2cNativeUrl forKey:@"nativeUrl"];
}
NSString * nsUsrName = MSHookIvar <NSString *>(msgWrap,"m_nsFromUsr");
if ( nsUsrName ){
NSLog(@"%@",nsUsrName);
[mutable_dic setObject:nsUsrName forKey:@"sessionUserName"];
}
WeChatRedEnvelopParamQueue * paramQueue = [WeChatRedEnvelopParamQueue sharedQueue];
[paramQueue enqueue:mutable_dic];
BOOL (^isGroupReceiver)() = ^BOOL() {
return [msgWrap.m_nsFromUsr rangeOfString:@"@chatroom"].location != NSNotFound;
};
NSMutableDictionary* params = [_logos_static_class_lookup$NSMutableDictionary() dictionary];
[params setObject:@"0" forKey:@"agreeDuty"];
[params setObject: isGroupReceiver() ? @"0" : @"1" forKey:@"inWay"];
[params setObject:url_dic[@"channelid"] forKey:@"channelId"];
[params setObject:@"1" forKey:@"msgType"];
[params setObject:c2cNativeUrl forKey:@"nativeUrl"];
[params setObject:url_dic[@"sendid"] forKey:@"sendId"];
WCRedEnvelopesLogicMgr* redEnvelopesLogicMgr = [[_logos_static_class_lookup$MMServiceCenter() defaultCenter] getService:[_logos_static_class_lookup$WCRedEnvelopesLogicMgr() class]];
[redEnvelopesLogicMgr ReceiverQueryRedEnvelopesRequest:params];
}else{
NSLog(@"%@",msgWrap);
}
_logos_orig$_ungrouped$CMessageMgr$onNewSyncAddMessage$(self, _cmd, msgWrap);
}
static void _logos_method$_ungrouped$WCRedEnvelopesReceiveControlLogic$WCRedEnvelopesReceiveHomeViewOpenRedEnvelopes(_LOGOS_SELF_TYPE_NORMAL WCRedEnvelopesReceiveControlLogic* _LOGOS_SELF_CONST __unused self, SEL __unused _cmd) {
WCRedEnvelopesControlData *m_data = MSHookIvar <WCRedEnvelopesControlData *>(self,"m_data");
CMessageWrap * msgWrap = [m_data m_oSelectedMessageWrap];
NSLog(@"%@",MSHookIvar <NSString *>(msgWrap,"m_nsFromUsr"));
WCPayInfoItem * payInfoItem = [msgWrap m_oWCPayInfoItem];
NSString *c2cNativeUrl = [payInfoItem m_c2cNativeUrl];
NSUInteger len = [@"wxpay://c2cbizmessagehandler/hongbao/receivehongbao?" length];
NSString *nativeUrl2 = [c2cNativeUrl substringFromIndex:len];
NSDictionary* url_dic = [_logos_static_class_lookup$WCBizUtil() dictionaryWithDecodedComponets:nativeUrl2 separator:@"&"];
NSMutableDictionary* mutable_dic = [_logos_static_class_lookup$NSMutableDictionary() dictionary];
[mutable_dic setObject:@"1" forKey:@"msgType"];
[mutable_dic setObject:url_dic[@"sendid"] forKey:@"sendId"];
[mutable_dic setObject:url_dic[@"channelid"] forKey:@"channelId"];
MMServiceCenter* mmserCent = [_logos_static_class_lookup$MMServiceCenter() defaultCenter];
Class ccmgr = [_logos_static_class_lookup$CContactMgr() class];
CContactMgr* contactMgr = [mmserCent getService:ccmgr];
CContact * selfContact = [contactMgr getSelfContact];
id displayName = [selfContact getContactDisplayName];
[mutable_dic setObject:displayName forKey:@"nickName"];
[mutable_dic setObject:[selfContact m_nsHeadImgUrl] forKey:@"headImg"];
if(msgWrap){
[mutable_dic setObject:c2cNativeUrl forKey:@"nativeUrl"];
}
MMMsgLogicManager * msgLogicManager = [[_logos_static_class_lookup$MMServiceCenter() defaultCenter] getService:[_logos_static_class_lookup$MMMsgLogicManager() class]];
WeixinContentLogicController * currentLogicController = [msgLogicManager GetCurrentLogicController];
if(currentLogicController){
CBaseContact* contact = [currentLogicController m_contact];
if ( contact ){
NSString * nsUsrName = [contact m_nsUsrName];
if ( nsUsrName ){
NSLog(@"%@",nsUsrName);
[mutable_dic setObject:nsUsrName forKey:@"sessionUserName"];
}
}
}
NSDictionary * structDicRedEnvelopesBaseInfo = [m_data m_structDicRedEnvelopesBaseInfo];
NSString *timingIdentifier = [structDicRedEnvelopesBaseInfo objectForKey:@"timingIdentifier"];
NSLog(@"%@",timingIdentifier);
if([timingIdentifier length]){
[mutable_dic setObject:timingIdentifier forKey:@"timingIdentifier"];
WCPayLogicMgr * paylogic = [[_logos_static_class_lookup$MMServiceCenter() defaultCenter] getService:[_logos_static_class_lookup$WCPayLogicMgr() class]];
[paylogic setRealnameReportScene:(unsigned int)1003];
WCPayLogicMgr* payLogicMgr = [[_logos_static_class_lookup$MMServiceCenter() defaultCenter] getService:[_logos_static_class_lookup$WCPayLogicMgr() class]];
id subScript = [structDicRedEnvelopesBaseInfo objectForKeyedSubscript:@"agree_duty"];
[payLogicMgr checkHongbaoOpenLicense:subScript acceptCallback:^{
WCRedEnvelopesLogicMgr* redEnvelopesLogicMgr = [[_logos_static_class_lookup$MMServiceCenter() defaultCenter] getService:[_logos_static_class_lookup$WCRedEnvelopesLogicMgr() class]];
[redEnvelopesLogicMgr OpenRedEnvelopesRequest:mutable_dic];
} denyCallback:^{
}];
}
}
static __attribute__((constructor)) void _logosLocalInit() {
{Class _logos_class$_ungrouped$WCRedEnvelopesLogicMgr = objc_getClass("WCRedEnvelopesLogicMgr"); MSHookMessageEx(_logos_class$_ungrouped$WCRedEnvelopesLogicMgr, @selector(OnWCToHongbaoCommonResponse:Request:), (IMP)&_logos_method$_ungrouped$WCRedEnvelopesLogicMgr$OnWCToHongbaoCommonResponse$Request$, (IMP*)&_logos_orig$_ungrouped$WCRedEnvelopesLogicMgr$OnWCToHongbaoCommonResponse$Request$);Class _logos_class$_ungrouped$CMessageMgr = objc_getClass("CMessageMgr"); MSHookMessageEx(_logos_class$_ungrouped$CMessageMgr, @selector(onNewSyncAddMessage:), (IMP)&_logos_method$_ungrouped$CMessageMgr$onNewSyncAddMessage$, (IMP*)&_logos_orig$_ungrouped$CMessageMgr$onNewSyncAddMessage$);Class _logos_class$_ungrouped$WCRedEnvelopesReceiveControlLogic = objc_getClass("WCRedEnvelopesReceiveControlLogic"); MSHookMessageEx(_logos_class$_ungrouped$WCRedEnvelopesReceiveControlLogic, @selector(WCRedEnvelopesReceiveHomeViewOpenRedEnvelopes), (IMP)&_logos_method$_ungrouped$WCRedEnvelopesReceiveControlLogic$WCRedEnvelopesReceiveHomeViewOpenRedEnvelopes, (IMP*)&_logos_orig$_ungrouped$WCRedEnvelopesReceiveControlLogic$WCRedEnvelopesReceiveHomeViewOpenRedEnvelopes);} }
#line 326 "/Users/JingGuo/Desktop/WeChatRedEnvelope/WeChatRedEnvelopeDylib/Logos/WeChatRedEnvelopeDylib.xm"
//
// WeChatRedEnvelopParamQueue.h
// 001--weiChatDemoDylib
//
// Created by H on 2018/4/5.
// Copyright ? 2018年 H. All rights reserved.
//
#import <Foundation/Foundation.h>
@interface WeChatRedEnvelopParamQueue : NSObject
+ (instancetype) sharedQueue;
- (void)enqueue:(NSMutableDictionary*)param;
- (NSMutableDictionary*)dequeue;
@end
//
// WeChatRedEnvelopParamQueue.m
// 001--weiChatDemoDylib
//
// Created by H on 2018/4/5.
// Copyright ? 2018年 H. All rights reserved.
//
#import "WeChatRedEnvelopParamQueue.h"
@interface WeChatRedEnvelopParamQueue ()
@property (strong, nonatomic)NSMutableArray* queue;
@end
@implementation WeChatRedEnvelopParamQueue
+ (instancetype)sharedQueue{
static WeChatRedEnvelopParamQueue* queue = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
queue = [[WeChatRedEnvelopParamQueue alloc] init];
});
return queue;
}
- (instancetype) init{
if(self = [super init]){
_queue = [[NSMutableArray alloc] init];
}
return self;
}
- (void)enqueue:(NSMutableDictionary*) param{
[self.queue addObject:param];
}
- (NSMutableDictionary*)dequeue{
if(0 == self.queue.count && !self.queue.firstObject)
return nil;
NSMutableDictionary* first = self.queue.firstObject;
[self.queue removeObjectAtIndex:0];
return first;
}
@end