如何破解 B 站版头小游戏?

事情的缘由

晚上吃饭的时候,和往常一样打开 b 站打算找点下饭视频,却无意中发现原来版头还是个小游戏:

动画.gif

于是放下手中的外卖玩了一会,仿佛回到了当初在电脑课上玩 chrome 小恐龙的日子,遂将其分享给好友:

这属实是戳到我的软肋了,精通蔚蓝空洞骑士的我岂能咽的下这口气?马上提枪再战。只可惜时运不济,晚饭都放凉了也不过刚打到近百的分数。气的我直接按下了 F12,于是大家就看到了这篇文章。

下面的内容,咱们从零开始一步步的介绍下如何开启“作弊模式”,并不复杂,可能是很多朋友的日常工作,这里权当复习 web 知识了。

寻找突破口

首先第一步我们肯定是要定位到小游戏的源码,稍微一观察,我们就可以发现游戏的结束界面有这么几个按钮:

image.png

打开 F12 瞅一瞅,原来是用 html 画出来的,这下就好办了:

image.png

Element 面板找到这个元素,然后在 Element 面板右侧的 Event Listeners 就可以找到其上绑定的事件,也就是说应该可以在 onClick 事件里找到游戏重新开始的回调:

image.png

果不其然,我们点进去看一下:

image.png

格式化之后大致一看就找到了几个按钮分别对应的事件,说明我们已经找到了游戏的源码。

小试牛刀

接下来先搞个简单的练练手,改出一个高分的分享截图:

share (7).png

由于最后的分数统计都是 html,过于好改这里就不提了,而上面这个分享图是用 canvas 画的,我们就以此为例。

我们在分享这里打上断点:

image.png

然后点击一下分享按钮,断点进来了,跟着断点走一会可以找到生成分享图片的两个核心值:分数介绍文案

动画6.gif

现在我们在右侧 Scope 中定位到对应的值修改一下就行了:

image.png

image.png

没什么难度,但是我敏锐的嗅觉告诉我,右边的文本应该是和左侧的分数挂钩的。我们乱改一气必然做不到以假乱真,还需要再深入的调查一下,于是乎全文搜索一下 scoreTextRef,果然看到了来源:

image.png

原来是从接口拿的百分比数据,get 请求的话直接浏览器试一下,然后就可以发现:从 96 分开始就打败了 99% 的人,再往上无论多少分都不会到 100% 了,这里实名怀疑一下后端同学是不是摸鱼写死了:

image.png

下面的胡诌文案也很好搜,注意其中的 scorePercent,意思是分数百分比到多少时使用第几句话:

image.png

关键数据都拿到了,剩下的按照上面介绍的方法改一点断点字段值就 OK 了。

破解游戏

热身完毕,接下来我们来处理游戏本身。首先是最简单的方式:如果我们可以在控制台直接访问到游戏实例本体,就可以对其进行修改,chrome 小恐龙的作弊方法就是这样,下面简单提一下:

chrome 小恐龙无敌方法

Runner.instance_.gameOver = function () {}

可以看到,chrome 将游戏实例暴露在了全局变量 Runnerinstance_ 属性上,所以我们就可以通过将其游戏结束条件函数设置为空来让游戏永远达不到结束的真实。

但是很遗憾,我们在 b 站小游戏的代码里可以看到,创建游戏实例的时候并没有将其挂到全局或者某个 dom 下:

image.png

并且由于整个代码都是放在闭包内创建的,所以此路暂时不通。

尝试2:Overrides

既然我们没法修改游戏实例,那就退而求其次改代码好了。提到改代码自然就想到了 chrome devtool 的 Overrides 功能,它可以用本地覆盖线上的文件。那么首先我们要找到游戏的源码是从哪下载的,很好找,只需要在 Network 里搜一下文件名,就可以发现代码是在点击 b 站 header 的时候下载的:

image.png

那剩下的就好办了,在 Source 面板中启用 Overrides,然后回到 Network 面板右键代码请求选择save for overrides。

image.png

image.png

这样下载请求的时候浏览器就会从本地加载代码而不是从线上下载。现在刷新下页面看一看:

image.png

被跨域拦下了,不愧是你阿B,看来这条路也行不通了。

最终尝试:抓包改请求

既然没办法直接覆盖请求内容,那咱们就更直接一点,在请求到达之前抓包把内容改掉。这里我用的是 AnyProxy,其他的诸如 Fiddler 之内支持修改请求的抓包工具都可以。

首先简单介绍一下,AnyProxy 就是一个 npm 包,安装很简单,支持 HTTP / HTTPS / WebSocket 代理,可以通过 js 脚本修改请求内容。更多介绍可以去 简介 · AnyProxy 查看。

接下来咱们开始干活,首先找个空文件夹,执行安装:

npm install anyproxy
复制代码

生成 https 证书:

npx anyproxy-ca
复制代码

然后信任生成好的的 ca 证书,具体操作可以看这里 AnyProxy - 证书配置。接下来就可以启动代理了:

npx anyproxy --intercept
复制代码

启动完成之后会在 8001 端口开放代理,记得设置一下:

image.png

OK,现在访问 localhost:8002 ,然后刷新一下 b 站就可以找到我们的目标请求了:

image.png

测试成功,可以拿到目标请求,接下来就是修改它的内容,方法也很简单,新建一个 js 文件(我这里名为 game.js)并填入以下内容:

const fs = require('fs')

module.exports = {
    summary: 'bilibili banner game cheat',
    *beforeSendResponse(requestDetail, responseDetail) {
        if (!requestDetail.url.endsWith('odXH9yzdsj.js')) return

        const newResponse = responseDetail.response
        fs.writeFileSync('body.txt', newResponse.body.toString())
    },
};
复制代码

这里代码的意思是:AnyProxy 会把 beforeSendResponse 回调的返回值当成请求的 response 返回给浏览器,我们就可以在这里对响应的内容进行修改,上面的内容就是获取到对应源码文件的响应内容并保存到 body.txt 里。

现在重新打开一个代理并加载我们上面的规则脚本:

npx anyproxy --intercept --rule game.js
复制代码

回到浏览器打开游戏后看一下我们的文件夹,果然拿到了对应的游戏源码:

image.png

接下来的事情就好办了,我们只需要花一点点时间来阅读源码,就可以写出来如下作弊脚本:

module.exports = {
    summary: 'bilibili banner game cheat',
    *beforeSendResponse(requestDetail, responseDetail) {
        if (!requestDetail.url.endsWith('odXH9yzdsj.js')) return

        const newResponse = responseDetail.response
        const originBody = newResponse.body.toString()
        const cheatBody = originBody
            // 无敌模式
            .replace('t[0]<-980||t[1]<-220', 'false')
            // 十倍起跳速度
            .replace('{x:e.body.velocity.x,y:12}', '{x:e.body.velocity.x,y:120}')
            // 停止世界向左滚动
            .replace(',o.Composite.translate(s.YB.engine.world,{x:-.18*r.HT.deltaT,y:0})', '')
            // 锁分数到 999
            .replace('s.XH.score=0,', 's.XH.score=999,')
            // 按下 x 键后结束游戏
            .replace('j:n,k:a,w:n,s:l', 'j:n,k:a,w:n,s:l,x:()=>this.gameState.changeState("EndPage")')
            // 将在叶子上才能起跳改为在空中才能起跳
            .replace('n=()=>{({Ground', 'n=()=>{({Air')
        newResponse.body = Buffer.from(cheatBody)

        return { response: newResponse }
    },
};
复制代码

本质上就是找到一些关键的游戏逻辑,然后用 replace 将其替换成我们想要的代码来达成作弊,这里我们不对小游戏的源码做过多分析,有兴趣的同学可以自行研究一下。

脚本完成了,现在重新启动一下代理让我们的修改可以生效,然后回到 b 站打开游戏,enjoy it!

注意打开控制台并在 Network 界面勾选 Disable Cache 哦,不然浏览器可能会直接用之前的缓存。

写在最后

本文的内容仅作为分享,请一定不要做任何有害的操作。b 站做这个小游戏本质还是为了带来快乐,作为码农破解这个游戏也是另一种的快乐,请不要越线哦。

猜你喜欢

转载自juejin.im/post/7082606407576469518