iOS钉钉自动抢红包(非越狱环境)

作者: 朱亦鸣 | 来源:发表于2018-02-10 16:58 被阅读4833次

    马上就要过年了相信大家已经在钉钉里抢过一波红包了,也有些同学可能没有抢到比如说我。那除夕夜的红包大家应该不能再错过了吧,钉钉的自动抢红包之前也有很多大神写过了,比如说这里虽然版本有些旧了,我就在这个基础上又研究了一下。至于准备工具之类的我就不多说了,看我之前的文章里面有的。下面开始。

    步骤

    • 找到打开红包的方法
    • 获取到最新红包的消息,调用打开红包的方法

    分析

    屏幕快照 2018-02-10 下午4.11.19.png
    我们可以看到红包的类DTRedEnvelopPickView我们现在就到这个类里去寻找打开红包的方法。我们可以找到unpack的方法,但是这个是执行的一个block 屏幕快照 2018-02-10 下午4.20.47.png
    我们直接hook到unpack方法利用xcode调试看看到底里面执行了什么方法。
    CHOptimizedMethod(0, self,void,DTRedEnvelopPickView,unpack){
        CHSuper(0, DTRedEnvelopPickView,unpack);
    }
    

    点击打开红包后断点到这里,我们执行下一步就会看到

    屏幕快照 2018-02-11 下午5.32.12.png
    我们进入这个DTRedEnvelopServiceIMP头文件可以搜索到- (void)pickRedEnvelopCluster:(long long)arg1 clusterId:(id)arg2 successBlock:(CDUnknownBlockType)arg3这个方法。现在我们就清楚了这个就是打开红包的方法。然后我们继续分析最新消息的方法,我们通过xcode调试可以知道消息页面是DTBizConversation我们进入这个类可以看到setLastMessage方法,可以猜到这个应该是设置最新一条消息的,我们可以hook这个方法加一个断点,然后找同事给我们发一个消息,断点到了后我们就能看到 屏幕快照 2018-02-11 下午5.37.45.png
    我们根据方法名就能猜出- (void)controller:(id)arg1 didChangeObject:(id)arg2 atIndex:(unsigned long long)arg3 forChangeType:(long long)arg4 newIndex:(unsigned long long)arg5;这个方法就是监听新消息的方法。我们hook到这个方法同样打断点。然后让同事发个红包给我们,就能找到第二个参数是一个聊天对象 屏幕快照 2018-02-11 下午5.39.54.png
    我们打印_latestMessage可以看到一个消息的数据,然后我们打开红包断点到- (void)pickRedEnvelopCluster:(long long)arg1 clusterId:(id)arg2 successBlock:(CDUnknownBlockType)arg3这个打开红包方法里,看下传过去的参数,分析后就能找到是senderId和clusterId这两个我们在消息数据里可以拿到。现在就明确了,我们hook消息改变的方法判断是红包类型(红包类型为901和902)然后发送打开红包消息。
    CHDeclareClass(DTConversationListDataSource)
    CHOptimizedMethod(5, self,void,DTConversationListDataSource,controller,id,arg1,didChangeObject,id,arg2,atIndex,unsigned long long,arg3,forChangeType,long long,arg4,newIndex,unsigned long long,arg5){
        CHSuper(5, DTConversationListDataSource,controller,arg1,didChangeObject,arg2,atIndex,arg3,forChangeType,arg4,newIndex,arg5);
        NSLog(@"%@",arg2);
        NSString *json = CHIvar(arg2, _latestMessageJson, __strong NSString *);
        NSDictionary *data = [NSJSONSerialization JSONObjectWithData:[json dataUsingEncoding:NSUTF8StringEncoding] options:NSJSONReadingAllowFragments error:nil];
        NSInteger type = [[data valueForKey:@"attachmentsType"] intValue];
        if(type == 902 || type == 901){
            if(![data[@"isRead"] boolValue]){
                NSString *clusterId = data[@"safeExtension"][@"clusterId"];
                long long sendId = [data[@"senderId"] longLongValue];
    //            id (*typed_msgSend)(id, SEL) = (void *)objc_msgSend;
                id imp = [NSClassFromString(@"DTRedEnvelopServiceIMP") new];
    //            id protocl = CHIvar(imp, _networkIMP, __weak id);
                if (clusterId.length > 0){
    //                pickRedEnvelopCluster:(long long)arg1 clusterId:(id)arg2 successBlock:(CDUnknownBlockType)arg3 failureBlock:(CDUnknownBlockType)arg4
                    //拆红包
                    id (*openRed_msgSend)(id, SEL,long long,id,id,id) = (void *)objc_msgSend;
                    openRed_msgSend(imp,NSSelectorFromString(@"pickRedEnvelopCluster:clusterId:successBlock:failureBlock:"),sendId,clusterId,nil,nil);
                }
            }
        }
        
    }
    

    我们打好断点让同事发个红包,我们可以看到方法都执行了但是好像红包没有被领取,我们可以猜测我们创建的DTRedEnvelopServiceIMP对象是不是有问题,我们hook这个类的init方法打上断点看看它是怎么被创建的,重新运行,断点到了后我们可以看到

    屏幕快照 2018-02-11 下午6.15.59.png
    是这个类调用了DTRedEnvelopServiceFactory我们直接进这个类的头文件发现如下代码
    #import <Foundation/NSObject.h>
    
    @interface DTRedEnvelopServiceFactory : NSObject
    {
    }
    
    + (id)createServiceIMPWithPersistence:(id)arg1 network:(id)arg2;
    + (id)defaultServiceIMP;
    
    @end
    

    看到defaultServiceIMP我们应该就知道了我们调用这个方法创建出来就可以了

    编码

    方法我们都找到了要传什么参数也知道了这样就可以编写了,最终代码如下
    //消息改变 拿到最新消息

    CHOptimizedMethod(5, self,void,DTConversationListDataSource,controller,id,arg1,didChangeObject,id,arg2,atIndex,unsigned long long,arg3,forChangeType,long long,arg4,newIndex,unsigned long long,arg5){
        CHSuper(5, DTConversationListDataSource,controller,arg1,didChangeObject,arg2,atIndex,arg3,forChangeType,arg4,newIndex,arg5);
        NSLog(@"%@",arg2);
        NSString *json = CHIvar(arg2, _latestMessageJson, __strong NSString *);
        NSDictionary *data = [NSJSONSerialization JSONObjectWithData:[json dataUsingEncoding:NSUTF8StringEncoding] options:NSJSONReadingAllowFragments error:nil];
        NSInteger type = [[data valueForKey:@"attachmentsType"] intValue];
        if(type == 902 || type == 901){
            if(![data[@"isRead"] boolValue]){
                NSString *clusterId = data[@"safeExtension"][@"clusterId"];
                long long sendId = [data[@"senderId"] longLongValue];
                id (*typed_msgSend)(id, SEL) = (void *)objc_msgSend;
                id imp = typed_msgSend(objc_getClass("DTRedEnvelopServiceFactory"),NSSelectorFromString(@"defaultServiceIMP"));
    //            id protocl = CHIvar(imp, _networkIMP, __weak id);
                if (clusterId.length > 0){
    //                pickRedEnvelopCluster:(long long)arg1 clusterId:(id)arg2 successBlock:(CDUnknownBlockType)arg3 failureBlock:(CDUnknownBlockType)arg4
                    //拆红包
                    id (*openRed_msgSend)(id, SEL,long long,id,id,id) = (void *)objc_msgSend;
                    openRed_msgSend(imp,NSSelectorFromString(@"pickRedEnvelopCluster:clusterId:successBlock:failureBlock:"),sendId,clusterId,nil,nil);
                }
            }
        }
    }
    

    逆向就是一步一步分析的过程,也要有比较敏锐的“嗅觉”,看到一个方法就能猜测到是做什么的。这个时候你编译运行到自己设备上让别人给你发个红包应该就会秒抢到了。有个问题就是这样用自己证书打包的话推送就收不到了。不过不影响我们抢红包。
    代码在这里

    相关文章

      网友评论

        本文标题:iOS钉钉自动抢红包(非越狱环境)

        本文链接:https://www.haomeiwen.com/subject/dvzctftx.html