前情提要
在成功修改了倒计时之后,进入选择票档页面还是"提交开售提醒"
这里继续看下有无办法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
成功之后的数据生成的,所以这里开始就要靠运气了
后续
有抢票经验的朋友应该会留意到一个细节,就捡漏了,当第一次尝试购票失败,就会被踢回上一页,从新选票档再提交