前言本文主要记录一次Surge或QuantumultX的脚本开发过程, 过程包括抓包、分析、调试、以及编写脚本. 记录内容为哔哩哔哩漫画积分商城自动抢券脚本.
主页归档分类标签2021-07-16发表2021-07-17更新脚本开发28分钟读完(大约4218个字)0次浏览记录一次Surge&QuantumultX脚本开发过程前言
本文主要记录一次Surge或QuantumultX的脚本开发过程,过程包括抓包、分析、调试、以及编写脚本.
记录内容为哔哩哔哩漫画积分商城自动抢券脚本.
背景作为一个合格的二次元迷,漫画当然是少不了🧐
国内日漫大多都被哔哩哔哩漫画拿下版权,然而里面大多数的日漫都需要氪金或使用漫读券才能看;
最近发现使用签到脚本获得的积分囤得差不多了,换漫读券又可以省一笔,无奈老是错过相关商品兑换时间,一气之写了个脚本让它在规定时间内自动抢券.
过程第一步:抓包本文将使用Thor进行抓包,并使用Anubis进行重放演示,简单分析哔哩哔哩漫画的网络请求.
我们进入哔哩哔哩漫画APP后,打开Thor开启抓包,返回APP积分商城随便兑换一个东西,再返回Thor关闭抓包.
Thor有着完备的关键字过滤,刚刚兑换了75积分的商品,我们可以尝试搜索请求体和响应体内的关键字,看看是否有结果.
搜索后一个名为Pointshop/Exchange的请求直接映入眼下,翻译成中文大意为店铺/兑换,很直观.
我们进一步查看该请求的请求体,以及响应体.
可以很直观的看到请求体中的各种参数,product_id表示兑换的商品,product_num表示兑换的数量,point表示消耗的积分.
响应体中code为0表示兑换成功,expire_day表示有效期,remain_amount表示该商品库存.
我们把该请求使用anubis重放,看看该接口是否有效.
可以看到重放后该接口是可用的,商品剩余数量相应减少,返回app查看账号积分也减少了75并收到商品.
之后我们看一下请求体中的product_id的商品id是怎么来的,返回Thor之前抓到的包,筛选器搜索1048关键字.
搜索后有一个叫ListProduct的请求,翻译成中文大意为商品清单,我们点开响应体可以看到一个商品名为”小智怪谈”的商品,商品id为1048,商品库存为3796,正是我之前所兑换的商品.
该接口使用anubis重放后并没有什么问题;
最后还差一个查询账户积分的接口,我们使用Thor筛选器搜索响应关键字,开启抓包之前我的账户有3172积分,则尝试搜索3172
可以看到有一个叫GetUserPoint的请求,翻译成中文大意为获取用户积分,点开响应后我们可以看到查询到的账户积分.
第二步:分析我们抓到接口后使用anubis重放进一步分析:
精简参数,分析url中的device之类的参数是否必须、是否验证Cookie、请求体是否必须,以减少脚本编写工作量.
分析各种情况下接口返回不同响应的可能性,供脚本正确判断.
分析查询积分接口12原接口https://manga.bilibili.com/twirp/pointshop.v1.Pointshop/GetUserPoint?device=h5&platform=web
经过各种重放后可得知
接口可省略url中的参数.
请求体可省略.
必须使用POST方法.
使用请求头中的Cookie字段作为用户鉴权,一些非必要字段也可省略.
带有效Cookie响应体内容为
1234567{"code":0,"msg":"","data":{"point":"用户实际积分数量"}}
Cookie失效后响应体内容为
1234567{"code":0,"msg":"","data":{"point":"0"}}
分析查询商品接口12原接口https://manga.bilibili.com/twirp/pointshop.v1.Pointshop/ListProduct?device=h5&platform=web
经过各种重放后可得知
接口可省略url中的参数.
请求体可省略.
必须使用POST方法.
无需用户鉴权.
响应体:
123456789101112131415161718192021222324252627{"code":0,"msg":"","data":[{"id":195,"type":7,"title":"积分兑换","image":"","amount":15999,"cost":200,"real_cost":100,"remain_amount":0,"comic_id":0,"limits":[],"discount":0,"product_type":1,"pendant_url":"","pendant_expire":0,"exchange_limit":0,"address_deadline":"0001-01-01T00:00:00Z","act_type":0,"has_exchanged":false,"main_coupon_deadline":"0001-01-01T00:00:00Z","deadline":"","point":"0"}]}
以上非实际响应,其他商品过多,已省略.
分析兑换商品接口12原接口https://manga.bilibili.com/twirp/pointshop.v1.Pointshop/Exchange?device=h5&platform=web
经过各种重放后可得知
接口可省略url中的参数.
请求体需带有
12345{"product_id":"商品ID","product_num":"商品兑换数量","point":"总消耗积分数量"}
必须使用POST方法.
使用请求头中的Cookie字段作为用户鉴权,一些非必要字段也可省略.
兑换成功响应体内容为
12345678910{"code":0,"msg":"","data":{"id":"商品使用ID","expire_day":"商品过期剩余天","remain_amount":"商品库存","deadline":"0001-01-01T00:00:00Z"}}
第三步:编写脚本
什么是函数
函数是JavaScript中的基本组件之一,一个函数是JavaScript过程中执行一组任务或计算值的语句.
本文的抢券脚本将定义各种函数以方便统一调用.
查看JavaScript函数详细参考文档了解更多.
应用兼容由于该脚本针对多平台,脚本的写法需要同时兼容Surge或QuanX之类的客户端,那么我们就需要写一个兼容函数让它在不同环境下也能被正确执行.
以下函数兼容Surge、QX、Loon中的部分API,包括持久化读取、通知、POST请求
兼容函数(点击左边箭头展开)>folded123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869//const$=newnobyda();//发送一个通知:$.notify('title','subtitle','message')//持久化读取:$.read('Key')//POST请求:$.post(url