某麦演出app分析(二)

文章正文
发布时间:2025-07-06 05:23

在成功修改了倒计时之后,进入选择票档页面还是"提交开售提醒"

这里继续看下有无办法Hook一下,把"立即购买"显示出来

源码分析

从openSkuActivity()可以知道选择票档页面是NcovSkuActivity,沿着这方向一直定位到NcovSkuFragment.updateAllview

NcovSkuActivity->NcovSkuFragment->initData->updateAllview->this.mModel.getSkuBean().observe

每次skuBean有更新都会updateAllview一次.
而其中有一个this.skuBottomInfo,结合界面动作,只有点击了票档才会出现底部的操作栏,所以猜测这里是底部确认按钮显示的关键:

继续往下看有一个叫做this.mSelectedPerform = this.mSkuBean.perform;的变量,应该就是选择了的票档.查找一下mSelectedPerform的引用:

发现了mSkuBottomView,感觉距离终点越来越近了(MMSkuBottomView是我起的别名)

接下来分析mSkuBottomView的基类:

这个类就看得比较困难了,都是混淆后的名字,不过还好有中文哈哈哈,
其中一个函数叫h()找到想要的答案(我重命名为buyBottomUI):

其中用作判断的this.f40114o就是NcovSkuBottomInfo.
经过完整的分析,最后确定只要修改skubean的api返回值,就能令到确认购买按钮显示.
以下是hook代码:

C42703["onSuccess"].overload(   "cn.damai.commonbusiness.seatbiz.sku.qilin.bean.SkuBean" ).implementation = function (skubean) {   console.log("C42703.onSuccess is called:" + skubean);   console.log("class:" + skubean.getClass());   // console.log('class:' + skubean.itemBuyBtn.btnStatus);   showJavaObjectString(skubean);   var result = updateSkuBean(skubean);   this["onSuccess"](result); }; function updateSkuBean(skubean) {   var json = Java.use("com.alibaba.fastjson.JSON");   var a = JSON.parse(json["toJSONString"](skubean));   console.log("skubean data:" + a);   console.log("skubean.itemBuyBtn.btnStatus:" + a.itemBuyBtn.btnStatus);   a.itemBuyBtn.btnStatus = 204;   a.perform.performSalable = true;   a.perform.positive = true;   a.actionControl.renderingControl.renderingType = 1;   a.perform.skuList.forEach((element) => {     element.frontEndStatus = 1;     element.clickable = true;     element.mq = 100;   });   console.log("skubean.itemBuyBtn.btnStatus:" + a.itemBuyBtn.btnStatus);   var result = json["parseObject"](JSON.stringify(a), skubean.getClass());   console.log("toJavaObject result:" + result);   return result; } let C20621 = Java.use(   "cn.damai.commonbusiness.seatbiz.sku.qilin.model.SkuModel$1" ); C20621["onSuccess"].overload(   "cn.damai.commonbusiness.seatbiz.sku.qilin.bean.SkuBean" ).implementation = function (skubean) {   // console.log(`SkuModel..onSuccess is called`);   console.log("SkuModel..onSuccess called:" + skubean);   console.log("class:" + skubean.getClass());   // console.log('class:' + skubean.itemBuyBtn.btnStatus);   showJavaObjectString(skubean);   var result = updateSkuBean(skubean);   this["onSuccess"](result); };

其中hook的函数是skuRequest.request的callback中的onSuccess函数,而不是直接修改api的返回值.
而这样的onSuccess一共有两处:C20621和C42703
这样的话就能在演出未开始正式开售之前,提前进入到选择页面:

虽然如此,也是需要等正式开售了之后才能点击正常进入到订单确认页面,如果提前点击会报错.感觉提前进入的hook到这里已经是极限了,因为订单确认页面是需要调用buildOrder成功之后的数据生成的,所以这里开始就要靠运气了

后续

有抢票经验的朋友应该会留意到一个细节,就捡漏了,当第一次尝试购票失败,就会被踢回上一页,从新选票档再提交