逆向微信自动抢红包

我只是一个对逆向有强烈兴趣的iOS开发者,并不是专业做逆向工作的。因为多次对实现微信自动抢红包有过接触,并且在一个初级都不算的逆向者看来,把我们伟大的,国民用户第一牛掰的App---微信给逆向,还能实现自动抢红包这样的功能,实在心潮澎湃,心向往之!
这次有幸在一次网络公开课中学习到这项技能。接下来我会提供教学视频,工具和资料。供你我这种逆向小白菜去实现这种高大上的功能。

免责声明:

逆向技术是可以学习,共享的。但是对技术的使用决定了你行为好坏。这个好坏就看造成了什么结果。针对抢红包这个功能,说简单了是你抢了几个红包,如果涉嫌金额过大,便形成了欺骗。此等行为过大就会沦为犯罪。真的老技术骨可能武功高强,能实现的会很多,但往往更懂这个道理,恰恰是初入江湖的小生们应当注意了。说的就是你!!!

Just do it!
实现步骤:

1、下载IPA;
2、dumpdecrypted(砸壳);
3、class-dump(导出功能头文件);
4、动态分析(找到接收消息和拆红包的方法);
5、静态分析(实现代码逻辑)

1、下载IPA

在电脑上打开iTunes下载一个最新版本的微信,然后连上iPhone,用iTunes装上刚刚下载的微信。(建议把原有的微信删掉再安装)
iTunes.png
2、dumpdecrypted(砸壳)

我们的iOS IPA都是被苹果加壳的。这个工作我们开发者不用去做,因为苹果会帮我们做,他也不允许我们去做。既然他给我们加壳了,现在我们就不得不去砸壳。
砸壳就使用dumpdecrypted这个工具。别问为什么,因为他比较好用,而且自己搞不出来。链接地址:https://github.com/stefanesser/dumpdecrypted
使用教程下面已经写好了,如果还是有问题,网上还有很多详细教程。

如果你觉得1和2两步骤有点麻烦,不想下手,那就算了吧。……我这里还有一个很简单很简单的方法……那就是……用现成的资源。可以去PP助手上等下载已经砸过壳的IPA包。如果你还觉得麻烦……那我给你链接,去下载吧,这是一个现成的已经被砸壳的IPA包:链接: https://pan.baidu.com/s/1ax4UWeDSTpPg88uq4HnYIg 密码: n5a3
3、class-dump(导出功能头文件)

恭喜你们拿到了已砸壳的微信IPA包。那么别啰嗦,让我们立马进行class-dump,拿到微信头文件。只要拿到了头文件,我们就可以定位到微信中红包相关的类,进而找寻方法,最后才有机会修改相关抢红包代码,达到自动拆红包的目的。

(1)、将IPA文件直接修改后缀名 zip,解压。拿到WeChat.app(WeChat.app是一个可执行文件)。
image.png
(2)、拿到可执行文件过后,我们就要从这个家伙身上取出头文件了。

使用class-dump工具:https://github.com/nygard/class-dump
按照教程进行class-dump,可得到所有头文件:

image.png

一共11601项:
image.png

(3)、将整个文件拖到sublime当中去。此时你可以随意查看微信所有头文件了。(作为一个第一次逆向微信的人,查看到微信所有的头文件令我有些许激动……原来这就是那帮牛逼的微信代码!)
image.png
4、动态分析(找到接收消息和拆红包的方法)

动态分析咋回事,肯定要动起来。怎么动?往左,往右,还是左右一个慢动作?算了,还是直接告诉你吧,就是通过发送消息,红包等操作来定位找到我们需要去处理的类,甚至是方法。目前我们已经拿到了微信所有代码中的入口文件,也就是说微信所有业务的头文件都被我们拿到了。现在我们要做的就是分析我们抢红包业务会涉及到什么类甚至是方法。

(1)编译运行起来微信

下载https://github.com/AloneMonkey/MonkeyDev
使用教程在其正文下清晰写着,并且很暖心是中文。这是网易一个安全工程师的杰作。使用这个工具我们首先可以运行起来微信App,包括开发账号授权等问题都帮我们搞定了。


1、安装好后,Xcode中会多出一个MonkeyApp。借助他创建一个工程。


image.png

2、将WeChat.app 文件添加进工程。然后选择你的真机,command+R。


image.png

3、Run起来了。我们接下来需要做的就是通过发送红包,来动态捕捉方法。
image.png

4、使用monkey,修改配置文件,进行方法捕捉


image.png

5、收到一条消息,我们点击进入页面,可以看到打出了相应的Log。说明我们的页面展示就在这里。这里只是做一个找页面的结果,因为整个找寻方法很复杂。需要我们了解一些工具,并且有分析能力,需要iOS成熟的工作经验。
image.png
image.png

6、hook方法。语法比较简单,我们需要hook的方法有很多,为什么这几个方法,需要我们一层一层的从Controller,和消息收发机制中去追踪。这里我们举一个例子:
image.png

这个发方法中我们可以拿到msgWrag参数,可以找到其中有我们需要的用户消息type,消息发送者信息等。

5、静态分析(实现代码逻辑)

整个分析过程需要懂得汇编语法,经过分析,弄懂了微信抢红包的方法调用逻辑。我们才能知道hook哪些方法。具体就是,在收到消息,我们判断是红包消息。然后我们直接调用拆红包方法。收到消息,肯定实在我们找到的Controller:baseMsgContentViewController中。拆红包的方法肯定在我们在红包动画执行完成后,点击“拆”字按钮中。
其中我们为了真正实现抢红包,需要根据逻辑创建一个抢红包Identity,通过这个参数进行抢红包接口调用。服务器通过后,我们才能真正的实现无障碍抢红包。
为了不增加过程中的繁杂说明,我直接上来需要hook的方法。


image.png

// 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 开始抢红包
        NSMutableDictionary * param = [[WeChatRedEnvelopParamQueue sharedQueue] dequeue];
        //然后开始拼接
        if(param == nil){    return;}
        [param setObject:timingIdentifier forKey:@"timingIdentifier"];
        
        sleep(1);
        WCRedEnvelopesLogicMgr* redEnvelopesLogicMgr  = [[%c(MMServiceCenter) defaultCenter] getService:[%c(WCRedEnvelopesLogicMgr) class]];
        //真正打开红包请求的方法!
        if(redEnvelopesLogicMgr){
            [redEnvelopesLogicMgr OpenRedEnvelopesRequest:param];
        }
    }
    
}
%end

%hook CMessageMgr

//收到新消息!
- (void)onNewSyncAddMessage:(CMessageWrap *)msgWrap{
    //将WCRedEnvelopesReceiveHomeViewOpenRedEnvelopes逻辑移植过来
    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:@"&"];
        
        
        
        //抢红包参数拼接!!
        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"];
        
        //接下来
        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"];
        }
        //拼接发送方用户名
        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 =  [%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]];
        //真正拆开红包请求的方法!
        [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]];
            //真正打开红包请求的方法!
            [redEnvelopesLogicMgr OpenRedEnvelopesRequest:mutable_dic];
            
        } denyCallback:^{
            
        }];
    }
}
%end






/*
 %hook WCRedEnvelopesReceiveHomeView
 //拆红包方法
 - (void)OnOpenRedEnvelopes{
 //MSHookIvar 原理是调用了class_getInstanceVariable获取类中指定名称实例成员变量的信息
 //目的拿到我的成员变量
 NSDictionary * dict  = MSHookIvar<NSDictionary *>(self,"m_dicBaseInfo");
 NSArray * arr = [dict allKeys];
 //打印字典内容
 for(int i = 0 ;i < arr.count ;i++){
 NSLog(@"%@ : %@",arr[i],[dict objectForKey:arr[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
按照上面的方法,将hook和方法和静态编写的代码Run一下:消息是未读,而此时已经自动抢了红包了!!!
image.png
最后附上项目源码地址(可直接装包使用):链接: https://pan.baidu.com/s/11CQTryI4nE1Zrf7vwm0KBQ 密码: i7fh
以及教学视频地址:链接: https://pan.baidu.com/s/1OQT4pG-hXkqZYR3kK9LHbQ 密码: tdm6
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,033评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,725评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,473评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,846评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,848评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,691评论 1 282
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,053评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,700评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,856评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,676评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,787评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,430评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,034评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,990评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,218评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,174评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,526评论 2 343

推荐阅读更多精彩内容