iOS--逆向

微信抢红包(三)

2018-08-06  本文已影响0人  Superman168

前言

微信抢红包(二) 中,我们已经知道了调用 抢红包时返回的 URL,如下:

image.png

继续分析

通过 微信抢红包(二) 中的分析,看到了 IDA 分析的汇编代码,但是 IDA还有一个强大的功能,就是可以还原源码,快捷键 F5 , 还原后的 WCRedEnvelopesReceiveHomeViewOpenRedEnvelopes 方法如下:(删除部分定义和release),这样看起来就清爽多了,容易分析多了

... 定义

void __cdecl -[WCRedEnvelopesReceiveControlLogic WCRedEnvelopesReceiveHomeViewOpenRedEnvelopes](#9116 *self, SEL a2)
{
  v2 = self;
  v3 = objc_msgSend(*(void **)((char *)self + 57), "m_oSelectedMessageWrap");
  v4 = (void *)objc_retainAutoreleasedReturnValue(v3);
  v5 = v4;
  v6 = objc_msgSend(v4, "m_oWCPayInfoItem");
  v7 = (void *)objc_retainAutoreleasedReturnValue(v6);
  v8 = v7;
  v9 = objc_msgSend(v7, "m_c2cNativeUrl");
  v10 = (void *)objc_retainAutoreleasedReturnValue(v9);
  v11 = objc_msgSend(CFSTR("wxpay://c2cbizmessagehandler/hongbao/receivehongbao?"), "length");
  v12 = objc_msgSend(v10, "substringFromIndex:", v11);
  v13 = (struct objc_object *)objc_retainAutoreleasedReturnValue(v12);
  objc_release(v10);
  objc_release(v8);
  objc_release(v5);
  v90 = v13;
  v14 = ((id (__cdecl *)(#9596 *, SEL, id, id))objc_msgSend)(
          (#9596 *)&OBJC_CLASS___WCBizUtil,
          "dictionaryWithDecodedComponets:separator:",
          v13,
          (id)CFSTR("&"));
  v15 = (void *)objc_retainAutoreleasedReturnValue(v14);
  v16 = objc_msgSend(&OBJC_CLASS___NSMutableDictionary, "dictionary");
  v17 = (void *)objc_retainAutoreleasedReturnValue(v16);
  objc_msgSend(v17, "safeSetObject:forKey:", CFSTR("1"), CFSTR("msgType"));
  v18 = objc_msgSend(v15, "objectForKey:", CFSTR("sendid"));
  v19 = objc_retainAutoreleasedReturnValue(v18);
  objc_msgSend(v17, "safeSetObject:forKey:", v19, CFSTR("sendId"));
  objc_release(v19);
  v89 = v15;
  v20 = objc_msgSend(v15, "objectForKey:", CFSTR("channelid"));
  v21 = objc_retainAutoreleasedReturnValue(v20);
  objc_msgSend(v17, "safeSetObject:forKey:", v21, CFSTR("channelId"));
  objc_release(v21);
  v22 = objc_msgSend(&OBJC_CLASS___MMServiceCenter, "defaultCenter");
  v23 = (void *)objc_retainAutoreleasedReturnValue(v22);
  v24 = objc_msgSend(&OBJC_CLASS___CContactMgr, "class");
  v25 = objc_msgSend(v23, "getService:", v24);
  v26 = (void *)objc_retainAutoreleasedReturnValue(v25);
  v27 = v26;
  v28 = objc_msgSend(v26, "getSelfContact");
  v29 = (void *)objc_retainAutoreleasedReturnValue(v28);
  objc_release(v27);
  objc_release(v23);
  v30 = objc_msgSend(v29, "getContactDisplayName");
  v31 = objc_retainAutoreleasedReturnValue(v30);
  objc_msgSend(v17, "safeSetObject:forKey:", v31, CFSTR("nickName"));
  objc_release(v31);
  v88 = v29;
  v32 = objc_msgSend(v29, "m_nsHeadImgUrl");
  v33 = objc_retainAutoreleasedReturnValue(v32);
  objc_msgSend(v17, "safeSetObject:forKey:", v33, CFSTR("headImg"));
  objc_release(v33);
  v34 = objc_msgSend(*(void **)((char *)v2 + 57), "m_oSelectedMessageWrap");
  v35 = objc_retainAutoreleasedReturnValue(v34);
  objc_release(v35);
  if ( v35 )
  {
    v36 = objc_msgSend(*(void **)((char *)v2 + 57), "m_oSelectedMessageWrap");
    v37 = (void *)objc_retainAutoreleasedReturnValue(v36);
    v38 = v37;
    v39 = objc_msgSend(v37, "m_oWCPayInfoItem");
    v40 = (void *)objc_retainAutoreleasedReturnValue(v39);
    v41 = v40;
    v42 = objc_msgSend(v40, "m_c2cNativeUrl");
    v43 = objc_retainAutoreleasedReturnValue(v42);
    objc_msgSend(v17, "safeSetObject:forKey:", v43, CFSTR("nativeUrl"));
    objc_release(v43);
    objc_release(v41);
    objc_release(v38);
  }
  v44 = objc_msgSend(&OBJC_CLASS___MMServiceCenter, "defaultCenter");
  v45 = (void *)objc_retainAutoreleasedReturnValue(v44);
  v46 = objc_msgSend(&OBJC_CLASS___MMMsgLogicManager, "class");
  v47 = objc_msgSend(v45, "getService:", v46);
  v48 = (void *)objc_retainAutoreleasedReturnValue(v47);
  v49 = v48;
  v50 = objc_msgSend(v48, "GetCurrentLogicController");
  v51 = (void *)objc_retainAutoreleasedReturnValue(v50);
  objc_release(v49);
  objc_release(v45);
  if ( v51 )
  {
    v52 = objc_msgSend(v51, "m_contact");
    v53 = objc_retainAutoreleasedReturnValue(v52);
    if ( v53 )
    {
      v54 = objc_msgSend(v51, "m_contact");
      v55 = (void *)objc_retainAutoreleasedReturnValue(v54);
      v56 = v55;
      v57 = objc_msgSend(v55, "m_nsUsrName");
      v58 = objc_retainAutoreleasedReturnValue(v57);
      objc_release(v58);
      objc_release(v56);
      objc_release(v53);
      if ( v58 )
      {
        v59 = objc_msgSend(v51, "m_contact");
        v60 = (void *)objc_retainAutoreleasedReturnValue(v59);
        v61 = v60;
        v62 = objc_msgSend(v60, "m_nsUsrName");
        v63 = objc_retainAutoreleasedReturnValue(v62);
        objc_msgSend(v17, "safeSetObject:forKey:", v63, CFSTR("sessionUserName"));
        objc_release(v63);
        objc_release(v61);
      }
    }
  }
  v64 = objc_msgSend(*(void **)((char *)v2 + 57), "m_structDicRedEnvelopesBaseInfo");
  v65 = (void *)objc_retainAutoreleasedReturnValue(v64);
  v66 = v65;
  v67 = objc_msgSend(v65, "stringForKey:", CFSTR("timingIdentifier"));
  v68 = (void *)objc_retainAutoreleasedReturnValue(v67);
  objc_release(v66);
  if ( objc_msgSend(v68, "length") )
    objc_msgSend(v17, "safeSetObject:forKey:", v68, CFSTR("timingIdentifier"));
  objc_initWeak(&v103, v2);
  v69 = objc_msgSend(&OBJC_CLASS___MMServiceCenter, "defaultCenter");
  v70 = (void *)objc_retainAutoreleasedReturnValue(v69);
  v71 = v68;
  v72 = v2;
  v73 = objc_msgSend(&OBJC_CLASS___WCPayLogicMgr, "class");
  v74 = objc_msgSend(v70, "getService:", v73);
  v75 = (void *)objc_retainAutoreleasedReturnValue(v74);
  objc_msgSend(v75, "setRealnameReportScene:", 1003LL);
  objc_release(v75);
  objc_release(v70);
  v76 = objc_msgSend(&OBJC_CLASS___MMServiceCenter, "defaultCenter");
  v77 = (void *)objc_retainAutoreleasedReturnValue(v76);
  v78 = objc_msgSend(&OBJC_CLASS___WCPayLogicMgr, "class");
  v79 = objc_msgSend(v77, "getService:", v78);
  v80 = (void *)objc_retainAutoreleasedReturnValue(v79);
  v81 = objc_msgSend(*(void **)((char *)v72 + 57), "m_structDicRedEnvelopesBaseInfo");
  v82 = (void *)objc_retainAutoreleasedReturnValue(v81);
  v83 = v82;
  v84 = objc_msgSend(v82, "objectForKeyedSubscript:", CFSTR("agree_duty"));
  v85 = objc_retainAutoreleasedReturnValue(v84);
  v97 = _NSConcreteStackBlock;
  v98 = 3254779904LL;
  v99 = sub_1015C17E0;
  v100 = &unk_10390BBD0;
  v101 = v17;
  v86 = objc_retain(v17);
  v87 = objc_retain(v72);
  v102 = v87;
  v91 = _NSConcreteStackBlock;
  v92 = 3254779904LL;
  v93 = sub_1015C18F8;
  v94 = &unk_10390BC00;
  objc_copyWeak(&v96, &v103);
  v95 = objc_retain(v87);
  objc_msgSend(v80, "checkHongbaoOpenLicense:acceptCallback:denyCallback:", v85, &v97, &v91);

... release 
}

参数字典:

image.png

一步一步调试,查看真实类型, 这里就不再一一展示了:

image.png

最终还原到这个地方:

image.png

要看到 Block 的名字,就要恢复 Block 的符号表了。

整个抢红包核心汇编代码还原的过程:


void __cdecl -[WCRedEnvelopesReceiveControlLogic WCRedEnvelopesReceiveHomeViewOpenRedEnvelopes](#9116 *self, SEL a2)
{

  v2 = self;
  // m_data = self + 57
  // v3 = objc_msgSend(*(void **)((char *)self + 57), "m_oSelectedMessageWrap");
  // 伪代码
  WCRedEnvelopesControlData *m_data = self.m_data;
  //  v3
  CMessageWrap *mesWrap = [m_data m_oSelectedMessageWrap];

  // v4 = (void *)objc_retainAutoreleasedReturnValue(v3);
  // v4=v3
  // v5 =   objc_msgSend(v4, "m_oWCPayInfoItem");
  // 伪代码 v6
  WCPayInfoItem *infoItem = [mesWrap m_oWCPayInfoItem];

  // v7=v6
  // v7 = (void *)objc_retainAutoreleasedReturnValue(v6);
  // v8 = v7;
  // v9 = objc_msgSend(v7, "m_c2cNativeUrl");
  // 伪代码 v9
  NSString *c2cNativeUrl = [infoItem m_c2cNativeUrl];


  // v10 = (void *)objc_retainAutoreleasedReturnValue(v9);
  // v11 = objc_msgSend(CFSTR("wxpay://c2cbizmessagehandler/hongbao/receivehongbao?"), "length");
  // 伪代码 v11
  NSUInteger length = [urlStr length];

  // v12 = objc_msgSend(v10, "substringFromIndex:", v11);
  // 伪代码:生成一个新的字符串 v12
  NSString *subString = [c2cNativeUrl substringFromIndex:length];

  // v13 = v12
  // v13 = (struct objc_object *)objc_retainAutoreleasedReturnValue(v12);
  // objc_release(v10);
  // objc_release(v8);
  // objc_release(v5);
  // v90 = v13;
  // v14 = ((id (__cdecl *)(#9596 *, SEL, id, id))objc_msgSend)(
  //         (#9596 *)&OBJC_CLASS___WCBizUtil,
  //         "dictionaryWithDecodedComponets:separator:",
  //         v13,
  //         (id)CFSTR("&"));
  
  // 伪代码 v14
  id url_dic = [WCBizUtil dictionaryWithDecodedComponets:subString separator:"&"];


  // v15=v14
  // v15 = (void *)objc_retainAutoreleasedReturnValue(v14);
  // v16 = objc_msgSend(&OBJC_CLASS___NSMutableDictionary, "dictionary");
  // v16  创建一个字典
  NSMutableDictionary *mutableDic = [%c(NSMutableDictionary) dictionary];

  // v17 = v16
  // v17 = (void *)objc_retainAutoreleasedReturnValue(v16);
  // objc_msgSend(v17, "safeSetObject:forKey:", CFSTR("1"), CFSTR("msgType"));
  // "safeSetObject:forKey:" 重写 setObject:forKey:
  [mutableDic setObject:@"1" forKey:@"msgType"];

  // v18 = objc_msgSend(v15, "objectForKey:", CFSTR("sendid"));
  // v18
  [url_dic objectForKey:@"sendid"];

  // v19 = v18
  // v19 = objc_retainAutoreleasedReturnValue(v18);
  // objc_msgSend(v17, "safeSetObject:forKey:", v19, CFSTR("sendId"));
  
  // 伪代码
  [mutableDic setObject:[url_dic objectForKey:@"sendid"] forKey:@"sendId"];


  // objc_release(v19);
  // v89 = v15;
  // v20 = objc_msgSend(v15, "objectForKey:", CFSTR("channelid"));
  // v21 = objc_retainAutoreleasedReturnValue(v20);
  // objc_msgSend(v17, "safeSetObject:forKey:", v21, CFSTR("channelId"));
  // objc_release(v21);

  // 伪代码
  [mutableDic setObject:[url_dic objectForKey:@"channelid"] forKey:@"channelId"];


  // v22 = objc_msgSend(&OBJC_CLASS___MMServiceCenter, "defaultCenter");
  // 伪代码 v22 类方法
  MMServiceCenter *serCenter = [%c(MMServiceCenter) defaultCenter];

  // v23 = (void *)objc_retainAutoreleasedReturnValue(v22);
  // v24 = objc_msgSend(&OBJC_CLASS___CContactMgr, "class");
  // v24
  Class conMgr = [%c(CContactMgr) class];


  // v25 = objc_msgSend(v23, "getService:", v24);
  // v26 = (void *)objc_retainAutoreleasedReturnValue(v25);
  // v27 = v26;
  // v27 = v26 = v25
  id service = [serCenter getService:conMgr];


  // v28 = objc_msgSend(v26, "getSelfContact");
  // v29 = v28
  // v29 = (void *)objc_retainAutoreleasedReturnValue(v28);
  id selfContact = [service getSelfContact];

  // objc_release(v27);
  // objc_release(v23);
  // v30 = objc_msgSend(v29, "getContactDisplayName");

  // v30
  id displayName = [selfContact getContactDisplayName];

  // v31 = objc_retainAutoreleasedReturnValue(v30);
  // objc_msgSend(v17, "safeSetObject:forKey:", v31, CFSTR("nickName"));
  // objc_release(v31);
  [mutableDic setObject:displayName forKey:@"nickName"];

  // v88 = v29;
  // v32 = objc_msgSend(v29, "m_nsHeadImgUrl");
  // v33 = objc_retainAutoreleasedReturnValue(v32);
  id headImgUrl = [selfContact m_nsHeadImgUrl];

  // objc_msgSend(v17, "safeSetObject:forKey:", v33, CFSTR("headImg"));
  [mutableDic setObject:headImgUrl forKey:@"headImg"];

  // objc_release(v33);
  // v34 = objc_msgSend(*(void **)((char *)v2 + 57), "m_oSelectedMessageWrap");
  // v35 = objc_retainAutoreleasedReturnValue(v34);
  // objc_release(v35);
  
  //  v2 = self;
  // self.m_data = self + 57
  // v35 = v34 == mesWrap
  // 就是开始的第一句和第二句
  CMessageWrap *mesWrap = [self.m_data m_oSelectedMessageWrap];


  if ( v35 )// mesWrap
  {
    // v36 = objc_msgSend(*(void **)((char *)v2 + 57), "m_oSelectedMessageWrap");
    // v37 = (void *)objc_retainAutoreleasedReturnValue(v36);
    // v38 = v37;
    // v39 = objc_msgSend(v37, "m_oWCPayInfoItem");
    // v40 = (void *)objc_retainAutoreleasedReturnValue(v39);
    // v41 = v40;
    // v42 = objc_msgSend(v40, "m_c2cNativeUrl");
    // v43 = objc_retainAutoreleasedReturnValue(v42);

    // v43 = v42 就是上面获取的 c2cNativeUrl


    // objc_msgSend(v17, "safeSetObject:forKey:", v43, CFSTR("nativeUrl"));
    [mutableDic setObject:c2cNativeUrl forKey:@"nativeUrl"];


    objc_release(v43);
    objc_release(v41);
    objc_release(v38);
  }

  // v44 = objc_msgSend(&OBJC_CLASS___MMServiceCenter, "defaultCenter");
  // v45 = (void *)objc_retainAutoreleasedReturnValue(v44);

  // v45 = v44
  MMServiceCenter *serCenter2 = [%c(MMServiceCenter) defaultCenter];

  // v46 = objc_msgSend(&OBJC_CLASS___MMMsgLogicManager, "class");
  // v46
  [%c(MMMsgLogicManager) class];

  // v47 = objc_msgSend(v45, "getService:", v46);
  // v48 = (void *)objc_retainAutoreleasedReturnValue(v47);
  // v49 = v48; = v47
  // 红包逻辑管理者对象
  MMMsgLogicManager * redEnvolopesLogicManager = [serCenter2 getService:[%c(MMMsgLogicManager) class]];


  // v50 = objc_msgSend(v48, "GetCurrentLogicController");
  // v51 = (void *)objc_retainAutoreleasedReturnValue(v50);

  // v51 = v50 // WeixinContentLogicController
  WeixinContentLogicController *currentLogicController = [redEnvolopesLogicManager GetCurrentLogicController];

  // objc_release(v49);
  // objc_release(v45);

  if ( v51 ) // currentLogicController
  {
    // v52 = objc_msgSend(v51, "m_contact");
    // v53 = objc_retainAutoreleasedReturnValue(v52);

    // v53 = v52
    // CContact 头文件中寻找
    CBaseContact * m_contact = [currentLogicController m_contact];

    if ( v53 )// m_contact
    {
      // v54 = objc_msgSend(v51, "m_contact");

      // v55 = (void *)objc_retainAutoreleasedReturnValue(v54);
      // v56 = v55;
      // v54/v55/v56 = m_contact
      // CBaseContact * m_contact = [currentLogicController m_contact];

      // v57 = objc_msgSend(v55, "m_nsUsrName");
      // v58 = objc_retainAutoreleasedReturnValue(v57);

      // v58 = v57
      NSString *nsUsrName = [m_contact m_nsUsrName];

      // objc_release(v58);
      // objc_release(v56);
      // objc_release(v53);


      if ( v58 )// nsUsrName
      {
        // v59 = objc_msgSend(v51, "m_contact");
        // v60 = (void *)objc_retainAutoreleasedReturnValue(v59);
        // v61 = v60;
        m_contact

        // v62 = objc_msgSend(v60, "m_nsUsrName");
        nsUsrName
        v63 = objc_retainAutoreleasedReturnValue(v62);

        // objc_msgSend(v17, "safeSetObject:forKey:", v63, CFSTR("sessionUserName"));

        // 其实就这一句代码
        [mutableDic setObject:nsUsrName forKey:@"sessionUserName"];

        // objc_release(v63);
        // objc_release(v61);
      }
    }
  }
  // v64 = objc_msgSend(*(void **)((char *)v2 + 57), "m_structDicRedEnvelopesBaseInfo");
  NSDictionary *m_dicBaseInfo = [m_data m_structDicRedEnvelopesBaseInfo];

  // v65 = (void *)objc_retainAutoreleasedReturnValue(v64);
  // v66 = v65;= v64 
  // v67 = objc_msgSend(v65, "stringForKey:", CFSTR("timingIdentifier"));
  NSString *timingIdentifier = [m_dicBaseInfo stringForKey:@"timingIdentifier"];

  // v68 = (void *)objc_retainAutoreleasedReturnValue(v67);
  // objc_release(v66);
  v68 = v67

  // if ( objc_msgSend(v68, "length") )
    // objc_msgSend(v17, "safeSetObject:forKey:", v68, CFSTR("timingIdentifier"));
  if ([timingIdentifier length]){
    // objc_msgSend(v17, "safeSetObject:forKey:", v68, CFSTR("timingIdentifier"));
    [mutableDic setObject:timingIdentifier forKey:@"timingIdentifier"];
  }
 
  objc_initWeak(&v103, v2);

  // v69 = objc_msgSend(&OBJC_CLASS___MMServiceCenter, "defaultCenter");
    // MMServiceCenter *serCenter = [%c(MMServiceCenter) defaultCenter];

  // v70 = (void *)objc_retainAutoreleasedReturnValue(v69);
  // v71 = v68;
  
  // v72 = v2;

  // v73 = objc_msgSend(&OBJC_CLASS___WCPayLogicMgr, "class");
  // v74 = objc_msgSend(v70, "getService:", v73);

  // 支付逻辑管理者对象
  WCPayLogicMgr * payLogicMgr = [[%c(MMServiceCenter) defaultCenter] getService:[%c(WCPayLogicMgr) class]];


  // v75 = (void *)objc_retainAutoreleasedReturnValue(v74);
  // 不知道参数是什么?可以直接 Hook 这个方法,或者直接看头就可以看出来
  // objc_msgSend(v75, "setRealnameReportScene:", 1003LL);
  [payLogicMgr setRealnameReportScene:(unsign int)1003];

  // objc_release(v75);
  // objc_release(v70);


  // v76 = objc_msgSend(&OBJC_CLASS___MMServiceCenter, "defaultCenter");
  // v77 = (void *)objc_retainAutoreleasedReturnValue(v76);
  // v78 = objc_msgSend(&OBJC_CLASS___WCPayLogicMgr, "class");
  // v79 = objc_msgSend(v77, "getService:", v78);
  WCPayLogicMgr * payLogicMgr2 = payLogicMgr;

  // v80 = v79
  // v80 = (void *)objc_retainAutoreleasedReturnValue(v79);
  // v81 = objc_msgSend(*(void **)((char *)v72 + 57), "m_structDicRedEnvelopesBaseInfo");
  // v82 = (void *)objc_retainAutoreleasedReturnValue(v81);
  // v83 = v82;
  // 同上
  // NSDictionary *m_dicBaseInfo = [m_data m_structDicRedEnvelopesBaseInfo];
  v81 = v82 = v83 = m_dicBaseInfo;

  // v84 = objc_msgSend(v82, "objectForKeyedSubscript:", CFSTR("agree_duty"));
  // v85 = objc_retainAutoreleasedReturnValue(v84);
  // v84
  id subscript = [m_dicBaseInfo objectForKey:@"agree_duty"];


  /* 关键的地方:调用方法*/
  // 要看到 Block 的名字,就要恢复 Block 的符号表
  // Block
  v97 = _NSConcreteStackBlock;
  // 其实可以看到 Block 的名字
  v98 = 3254779904LL;
  // 地址
  v99 = sub_1015C17E0;
  v100 = &unk_10390BBD0;
  v101 = v17;
  v86 = objc_retain(v17);
  v87 = objc_retain(v72);
  v102 = v87;
  v91 = _NSConcreteStackBlock;
  v92 = 3254779904LL;
  v93 = sub_1015C18F8;
  v94 = &unk_10390BC00;
  objc_copyWeak(&v96, &v103);
  v95 = objc_retain(v87);
  objc_msgSend(v80, "checkHongbaoOpenLicense:acceptCallback:denyCallback:", v85, &v97, &v91);

}

恢复 Block 的符号表

与恢复符号表 类似,稍有所不同。

image.png

运行完毕以后,这个过程还好,挺快,文件夹中会多一个 名称为 block_symbol.json 的 json 文件,如图:

image.png

使用上次恢复符号表的 Mach-o 文件,并且添加 Block 的符号表

./restore-symbol WeChat2 -o WeChat_block -j block_symbol.json

恢复完成:

image.png image.png

接着把恢复好的 Mach-o 文件拷贝至原始工程中的 TargetApp 中的 APP 包中,重新 拖入 IDA 分析,F5 转换,(不得不说一句,IDA 在 Mac 下,简直是没法用,恨不得砸了电脑,这个过程非常漫长,也不见得成功,有条件的装 Windows 虚拟机或直接用 PC 可惜目前都不具备)。

恢复 Block 的符号表后代码分析

恢复主要部分代码
/* 关键的地方:调用方法*/
  // 要看到 Block 的名字,就要恢复 Block 的符号表
  // Block
  /*
  v97 = _NSConcreteStackBlock;
  // 其实可以看到 Block 的名字
  v98 = 3254779904LL;
  // 地址
  v99 = sub_1015C17E0;
  v100 = &unk_10390BBD0;
  v101 = v17;
  v86 = objc_retain(v17);
  v87 = objc_retain(v72);
  v102 = v87;
  v91 = _NSConcreteStackBlock;
  v92 = 3254779904LL;
  v93 = sub_1015C18F8;
  v94 = &unk_10390BC00;
  objc_copyWeak(&v96, &v103);
  v95 = objc_retain(v87);
  objc_msgSend(v80, "checkHongbaoOpenLicense:acceptCallback:denyCallback:", v85, &v97, &v91);
  */

  // 恢复 Block 的符号表后转换的内容
  v97 =_ NSConcreteStackBlock;
  v98 = 3254779904LL;
  v99 = - [WCRedEnvelopesReceiveControlLogic WCRedEnvelopesReceiveHmeViewOpenRedEnvelopes]_block;
  v100 = &unk_10390BBD0;

  v86 = objc_retain(v17); I
  v87 = objc_retain(v72);
  v102 = v87;

  v91 =_ NSConcreteStackBlock;
  v92 = 3254779904LL; I
  v93 = - [WCRedEnvelopesReceiveControlLogic WCRedEnvelopesReceiveHomeViewpenRedEnvelopes]_block_0;
  v94 = &unk_10390BC00;

  objc_ copyWeak(&v96, &v103);
  v95 = objc_retain(v87);
  objc_ msgSend(v80, "checkHongbaoOpenLicense:acceptCallback: denyCallback:", v85, &v97, &v91);
  objc_ release(v85);

  // v80 : payLogicMgr 后三个参数:v85, &v97, &v91
  [payLogicMgr checkHongbaoOpenLicense:subscript acceptCallback:^(){
    [WCRedEnvelopesReceiveControlLogic WCRedEnvelopesReceiveHmeViewOpenRedEnvelopes]_block;
  } denyCallback:^(){
    [WCRedEnvelopesReceiveControlLogic WCRedEnvelopesReceiveHomeViewpenRedEnvelopes]_block_0;
  }]

接收的Block:

image.png

继续分析:

[payLogicMgr checkHongbaoOpenLicense:subscript acceptCallback:^(){
    // [WCRedEnvelopesReceiveControlLogic WCRedEnvelopesReceiveHmeViewOpenRedEnvelopes]_block;
    //  - [WCRedEnvelopesReceiveControlLogi WCRedEnvelopesReceivemView0penedEnvelopes]_block(__ int64 a1)

    // v1=a1;
    // objc_ msgSend(&OBJC_ CLASS___ MServiceCenter, "defaultCenter");
    // (void *)objc_ retainAutoreleasedeturu2 ;
    // v4 = objc_ msgSend(&OBJC_ CLASS___ WCRedEnvelopesLogicMgr, "class");
    // v5 = objc_ msgSend(v3,_ "getService:", v4);
    // v6 = (void *)objc_ retainAutoreleasedReturalue(v5)

    // 红包逻辑管理者对象
    WCRedEnvelopesLogicMgr * redEnveLogicMgr = [[%c(MMServiceCenter) defaultCenter] getService:[%c(WCRedEnvelopesLogicMgr) class]];


    // objc_ msgSend(v6, "OpenRedEnvelopesRequest:", *(_ QWORD *)(v1 + 32));
    // objc_ release(v6);
    // objc_ release(v3);

    // - (void)OpenRedEnvelopesRequest:(id)arg1; // v1+32
    // hook 之后可以看出就是上面拼接的 mutableDic
    [redEnveLogicMgr OpenRedEnvelopesRequest:mutableDic];

    // 动画效果,不需要
    // *(_ DWORD *)(*(_ QWORD *)(v1 + 40) + 16LL) = 4; I
    // return objc_ msgSend(*(void **)(*(_ QWORD *)(v1 + 40) + 73LL), "startReceiveAnimation");

  } denyCallback:^(){
    //  拒绝回调,不需要
    [WCRedEnvelopesReceiveControlLogic WCRedEnvelopesReceiveHomeViewpenRedEnvelopes]_block_0;
  }]

hook OpenRedEnvelopesRequest:

image.png

可以看出参数就是上面拼接的 mutableDic

至此,抢红包的核心代码基本上分析完毕,接下来就是手动实现的过程。

手动实现抢红包过程

#pragma mark -- 手动实现抢红包过程

- (void)WCRedEnvelopesReceiveHomeViewOpenRedEnvelopes
{
    WCRedEnvelopesControlData *m_data = self.m_data;
    WCRedEnvelopesControlData *data = MSHookIvar<WCRedEnvelopesControlData *>(self, "m_data");

    CMessageWrap *mesWrap = [m_data m_oSelectedMessageWrap];
    
    WCPayInfoItem *infoItem = [mesWrap m_oWCPayInfoItem];
    
    NSString *c2cNativeUrl = [infoItem m_c2cNativeUrl];
    
    NSUInteger length = [urlStr length];
    
    NSString *subString = [c2cNativeUrl substringFromIndex:length];
    
    
    id url_dic = [WCBizUtil dictionaryWithDecodedComponets:subString separator:"&"];
    
    NSMutableDictionary *mutableDic = [%c(NSMutableDictionary) dictionary];
    [mutableDic setObject:@"1" forKey:@"msgType"];
    
    [url_dic objectForKey:@"sendid"];
    [mutableDic setObject:[url_dic objectForKey:@"sendid"] forKey:@"sendId"];
    [mutableDic setObject:[url_dic objectForKey:@"channelid"] forKey:@"channelId"];
    
    MMServiceCenter *serCenter = [%c(MMServiceCenter) defaultCenter];
    Class conMgr = [%c(CContactMgr) class];
    id service = [serCenter getService:conMgr];
    
    id selfContact = [service getSelfContact];
    id displayName = [selfContact getContactDisplayName];
    [mutableDic setObject:displayName forKey:@"nickName"];
    id headImgUrl = [selfContact m_nsHeadImgUrl];
    [mutableDic setObject:headImgUrl forKey:@"headImg"];
    
    CMessageWrap *mesWrap = [self.m_data m_oSelectedMessageWrap];
    if ( mesWrap )
    {
        [mutableDic setObject:c2cNativeUrl forKey:@"nativeUrl"];
    }
    
    MMServiceCenter *serCenter2 = [%c(MMServiceCenter) defaultCenter];
    [%c(MMMsgLogicManager) class];
    
    // 红包逻辑管理者对象
    MMMsgLogicManager * redEnvolopesLogicManager = [serCenter2 getService:[%c(MMMsgLogicManager) class]];

    WeixinContentLogicController *currentLogicController = [redEnvolopesLogicManager GetCurrentLogicController];
    
    if(currentLogicController){
        CBaseContact * m_contact = [currentLogicController m_contact];
        if(m_contact){
            NSString *nsUsrName = [m_contact m_nsUsrName];
            if ( nsUsrName )//
            {
                [mutableDic setObject:nsUsrName forKey:@"sessionUserName"];
            }
        }
    }
    
    NSDictionary *m_dicBaseInfo = [m_data m_structDicRedEnvelopesBaseInfo];
    NSString *timingIdentifier = [m_dicBaseInfo stringForKey:@"timingIdentifier"];
    if ([timingIdentifier length]){
        [mutableDic setObject:timingIdentifier forKey:@"timingIdentifier"];
    }
    
    // 支付逻辑管理者对象
    WCPayLogicMgr * payLogicMgr = [[%c(MMServiceCenter) defaultCenter] getService:[%c(WCPayLogicMgr) class]];
    [payLogicMgr setRealnameReportScene:(unsign int)1003];
    
    WCPayLogicMgr * payLogicMgr2 = payLogicMgr;
    
    id subscript = [m_dicBaseInfo objectForKey:@"agree_duty"];
    
    [payLogicMgr checkHongbaoOpenLicense:subscript acceptCallback:^(){
        // 红包逻辑管理者对象
        WCRedEnvelopesLogicMgr * redEnveLogicMgr = [[%c(MMServiceCenter) defaultCenter] getService:[%c(WCRedEnvelopesLogicMgr) class]];
        // hook 之后可以看出就是上面拼接的 mutableDic
        [redEnveLogicMgr OpenRedEnvelopesRequest:mutableDic];

    } denyCallback:^(){
        //  拒绝回调,不需要
//        [WCRedEnvelopesReceiveControlLogic WCRedEnvelopesReceiveHomeViewpenRedEnvelopes]_block_0;
    }]  
}

%end

这个会有很多错误,没关系,一个一个解决掉!!!

最终修改完成的代码如下:

#pragma mark -- 手动实现抢红包过程
- (void)WCRedEnvelopesReceiveHomeViewOpenRedEnvelopes
{
    WCRedEnvelopesControlData *m_data = MSHookIvar<WCRedEnvelopesControlData *>(self, "m_data");
    // 消息类
    CMessageWrap *mesWrap = [m_data m_oSelectedMessageWrap];
    
    WCPayInfoItem *infoItem = [mesWrap m_oWCPayInfoItem];
    
    NSString *c2cNativeUrl = [infoItem m_c2cNativeUrl];
    
    NSString *urlStr = @"wxpay://c2cbizmessagehandler/hongbao/receivehongbao?";
    NSUInteger length = [urlStr length];
    // @"msgtype=1&channelid=1&sendid=1000039501201808076017246068172&sendusername=wxid_erhumb6yg9yu22&ver=6&sign=be26a8e8bfc8ac1cf33d5556623803044f234e4bc58fb2d2b634e8d7532f940686498bcfaa51cde8c201cbd0de2f8a12c2f1e39d66c41757826b18004585d9bf975d9a1c66e7fd8c4d75107d28a2a785"
    NSString *subString = [c2cNativeUrl substringFromIndex:length];
    
    /*
     {
     channelid = 1;
     msgtype = 1;
     sendid = 1000039501201808076017246068172;
     sendusername = "wxid_erhumb6yg9yu22";
     sign = be26a8e8bfc8ac1cf33d5556623803044f234e4bc58fb2d2b634e8d7532f940686498bcfaa51cde8c201cbd0de2f8a12c2f1e39d66c41757826b18004585d9bf975d9a1c66e7fd8c4d75107d28a2a785;
     ver = 6;
     }
     */
    id url_dic = [%c(WCBizUtil) dictionaryWithDecodedComponets:subString separator:@"&"];
    
    NSMutableDictionary *mutableDic = [%c(NSMutableDictionary) dictionary];
    [mutableDic setObject:@"1" forKey:@"msgType"];
    
    [url_dic objectForKey:@"sendid"];
    [mutableDic setObject:[url_dic objectForKey:@"sendid"] forKey:@"sendId"];
    [mutableDic setObject:[url_dic objectForKey:@"channelid"] forKey:@"channelId"];
    
    MMServiceCenter *serCenter = [%c(MMServiceCenter) defaultCenter];
   
    Class conMgr = [%c(CContactMgr) class];
    id service = [serCenter getService:conMgr];
    
//    id selfContact = [service getSelfContact];
//    NSLog(@"%@",[selfContact class]);
    CContact *selfContact = [service getSelfContact];
    
    NSString * displayName = [selfContact getContactDisplayName];
    [mutableDic setObject:displayName forKey:@"nickName"];
    
    id headImgUrl = [selfContact m_nsHeadImgUrl];
    [mutableDic setObject:headImgUrl forKey:@"headImg"];

    if (mesWrap)
    {
        [mutableDic setObject:c2cNativeUrl forKey:@"nativeUrl"];
    }

    MMServiceCenter *serCenter2 = [%c(MMServiceCenter) defaultCenter];
    [%c(MMMsgLogicManager) class];

    // 红包逻辑管理者对象
    MMMsgLogicManager * redEnvolopesLogicManager = [serCenter2 getService:[%c(MMMsgLogicManager) class]];

    WeixinContentLogicController *currentLogicController = [redEnvolopesLogicManager GetCurrentLogicController];

    if(currentLogicController){
        CBaseContact * m_contact = [currentLogicController m_contact];
        if(m_contact){
            NSString *nsUsrName = [m_contact m_nsUsrName];
            if (nsUsrName)//
            {
                [mutableDic setObject:nsUsrName forKey:@"sessionUserName"];
            }
        }
    }

    NSDictionary *m_dicBaseInfo = [m_data m_structDicRedEnvelopesBaseInfo];
    NSString *timingIdentifier = m_dicBaseInfo[@"timingIdentifier"];
    if ([timingIdentifier length]){
        [mutableDic setObject:timingIdentifier forKey:@"timingIdentifier"];
    }

    // 支付逻辑管理者对象
    WCPayLogicMgr * payLogicMgr = [[%c(MMServiceCenter) defaultCenter] getService:[%c(WCPayLogicMgr) class]];
    
    [payLogicMgr setRealnameReportScene:(unsigned int)1003];

    id subscript = [m_dicBaseInfo objectForKey:@"agree_duty"];

    [payLogicMgr checkHongbaoOpenLicense:subscript acceptCallback:^(){
        // 红包逻辑管理者对象
        WCRedEnvelopesLogicMgr * redEnveLogicMgr = [[%c(MMServiceCenter) defaultCenter] getService:[%c(WCRedEnvelopesLogicMgr) class]];
        // hook 之后可以看出就是上面拼接的 mutableDic
        [redEnveLogicMgr OpenRedEnvelopesRequest:mutableDic];

    } denyCallback:^(){
        //  拒绝回调,不需要
//        [WCRedEnvelopesReceiveControlLogic WCRedEnvelopesReceiveHomeViewpenRedEnvelopes]_block_0;
    }];
}

运行,抢红包,OK,Very Good!!! 成功抢到红包!

image.png

后记

目前手动抢红包过程已经实现了,那下一步怎么做呢?是不是放到之前节后到消息的方法中执行呢???

具体过程怎么实现呢???

上一篇 下一篇

猜你喜欢

热点阅读