某麦演出app分析(二)---显示购买按钮
## 前情提要在成功修改了倒计时之后,进入选择票档页面还是"提交开售提醒"
!
这里继续看下有无办法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`成功之后的数据生成的,所以这里开始就要靠运气了
## 后续
有抢票经验的朋友应该会留意到一个细节,就捡漏了,当第一次尝试购票失败,就会被踢回上一页,从新选票档再提交
: https://www.lqcoding.com/usr/uploads/2023/07/2808182322.png
: https://www.lqcoding.com/usr/uploads/2023/07/3097366578.png
: https://www.lqcoding.com/usr/uploads/2023/07/1659778196.png
: https://www.lqcoding.com/usr/uploads/2023/07/4114905755.png
: https://www.lqcoding.com/usr/uploads/2023/07/3761761168.png
: https://www.lqcoding.com/usr/uploads/2023/07/2702808054.png
: https://www.lqcoding.com/usr/uploads/2023/07/3815166255.png
: https://www.lqcoding.com/usr/uploads/2023/07/1204967342.png 本帖最后由 昨日记忆丶 于 2023-8-11 09:28 编辑
cyxnzb 发表于 2023-8-9 16:40
好奇黄牛是怎么抢到的
我之前看过一个黄牛把自己经历说出来,他说大黄牛是不用抢票的,演唱会有人专门给大黄牛提供门票,因为快速清空票库是演唱会目的,不管是小众明星还是大众明星的演唱会都会提供,然后才是我们和小黄牛去抢的票,小黄牛也有可能直接从大黄牛那里买票,之后抬高价格,最后剩一部分是vvvip专座门票是不卖的。楼主这样破解的话如果有用,并且小黄牛也这样抢,那可能更不容易抢票了{:301_999:} 确实恶心 提交失败强制返回 能不能把这个hook掉 就快人一大步了 快把damai破解了吧,根本抢不到票
确实太难抢了{:1_908:}。而你我的朋友{:1_921:} 感觉都是在被当猴耍:@ 我已经hook到最后一步不返回了,一样抢不到 这玩意抢票还要开会员。。。 以前我还买过林俊杰的票的,今年根本抢不到,都被黄牛脚本抢了 {:1_937:}分析一下,抢票老是提示 同一时间XX过多 是不是黑号了 不知道是什么机制 好奇黄牛是怎么抢到的