Chrome 的小恐龙游戏,被我破解了...

Stella981
• 阅读 821

一个阳光明媚的周末,透光的窗帘把我从睡梦中叫醒,大脑说今天是周六,可以慵懒个一上午,于是开心地打开我的 Mac 准备看两集 Rick and Morty 再起床洗漱。

我迫不及待打开了对应的网站,发现浏览器提示 No internet,这才发现因为我的动作太过于行云流水,电脑还没来得及连上 wifi 

Chrome 的小恐龙游戏,被我破解了...

Fine,那就等 wifi 自己重连吧,等待的这段时间刚好回味一下 Chrome 自带的这款小恐龙游戏。

科普:Chrome 浏览器是 Google 家的官方浏览器,使用体验全世界南波万。当用户在无网络时访问某一网址,浏览器会提示“无网络链接”(也就是上面这张图),按下空格键,就会唤醒一个小恐龙跑步刷分的游戏。

如果在有网络连接时也想玩的话,可以直接在地址栏输入: chrome://dino

出于职业本身的敏感和好奇,我突然心生疑问:这应该是用 JS 做的吧?

我顺势打开控制台,不如先看一下所有的全局变量?

Chrome 的小恐龙游戏,被我破解了...

239 个...太多了,我可没这个耐心

我停止了操作,开始思考这一切的可行性:

  1. 我在干什么? 尝试自定义这个游戏

  2. 为什么要看全局变量? 因为假设关于游戏的对象被暴露在了全局

  3. 如果没暴露在全局?行,那我就放弃了(周末的早晨我可不想在 sources 里面扒源码)

也就是说,如果没有在全局变量里找到那个对象,我就可以选择性放弃了。

再看一下上面这张图,不难发现,这 239 个全局变量,有很多都是老朋友了,name、history、location、onclick、onerror... 这些变量明显和这只小恐龙没啥关系,打印出来纯粹是来充个数,还浪费了我找目标的时间,所以我遇到了第一个问题:如何快速找到由开发者自定义的全局变量?

Chrome 的小恐龙游戏,被我破解了...

假如我有一个正常的 window...不对,不用假如,新开一个空窗口不就得了  在新打开窗口的控制台,我得到了这样的结果:

Chrome 的小恐龙游戏,被我破解了...

也就是说,在这个恐龙快跑的小游戏里,Google 的前端工程师向 window 注入了 43 个全局变量(239-196)...

Chrome 的小恐龙游戏,被我破解了...

怎么把这 196 个原生的全局变量拿过来呢?复制粘贴就太 low 了,让我想想...

Chrome 的小恐龙游戏,被我破解了...

在原有窗口的基础上,再搞一个新窗口...这不就是 iframe 吗!iframe 虽然没有  window ,但是它有  contentWindow ,原则上来说,属性差别应该不大。所以现在只需要创建一个 iframe,拿它里面  contentWindow  的全局变量去过滤当前  window  的全局变量,就可以筛选出那多余的 43 个嫌疑人了。

于是我在控制台敲出了下面这些代码

Chrome 的小恐龙游戏,被我破解了...

回车!

Chrome 的小恐龙游戏,被我破解了...

诶,怎么是 45 个?比预期的多了 2 个,难道  window  里面还包含哪些  contentWindow  里面没有的变量吗?于是我把相同的代码拿去 url 为  about:blank  的窗口下执行了一遍,发现了罪魁祸首:

Chrome 的小恐龙游戏,被我破解了...

哦...原来是我给 Chrome 安装的 React 开发者工具干的好事...忽略!

我打开了先前检索到的 45(43+2) 个多余全局变量,大致扫了一眼,很快就发现了一个很可疑的选手:

Chrome 的小恐龙游戏,被我破解了...

Runner ,不就是这个一直在跑步的小恐龙吗

看看它是个什么货色,无脑  typeof  一下:

Chrome 的小恐龙游戏,被我破解了...

emmm居然是函数,哦?函数,首字母还大写,这熟悉的味道,这不就是个构造函数吗!正所谓,构造函数的宝藏都在  prototype  里,在观察了一遍这个宝藏之后,我发现了一个名为  gameOver  的方法,

Chrome 的小恐龙游戏,被我破解了...

这个函数名,难不成它就是那个让小恐龙去死的方法?既然这样,呵,我反手就把它用空函数覆盖了。于是...

真的是...

Chrome 的小恐龙游戏,被我破解了...

然后我又发现了另一个有趣的方法:

Chrome 的小恐龙游戏,被我破解了...

顾名思义,这是用来给小恐龙设置奔跑速度的方法,但是怎么调用呢?由构造函数创建的实例对象,可通过原型链访问构造函数 prototype 上的变量和方法,也就是说,如果能找到这个小恐龙对应的实例,那么就能直接调用这个  setSpeed  方法了。既然 Google 的前端工程师已经把这么多变量搞到全局了,那么...会不会也在全局存储了这个小恐龙实例?我重新审视了一遍那 43 个多出来的全局变量,并没有找到。我下意识地随手输入了一下这个  Runner  构造函数,真是山重水复疑无路柳暗花明又一村呐:

Chrome 的小恐龙游戏,被我破解了...

我甚至都不需要看  Runner  函数的全部代码,就知道原来实例被保存在一个名叫 instance_  的  Runner  自身属性里,论起好变量名的重要性,行,那我就不客气了,直接调用!

Chrome 的小恐龙游戏,被我破解了...

于是...

当我凝视着这个飞奔的无敌小恐龙时,我突然觉得...一切变得...

Chrome 的小恐龙游戏,被我破解了...

推荐:

  1. 总结了 90 条写 Python 程序的建议

  2. 卧槽,做程序员,这几句口头禅全中

Chrome 的小恐龙游戏,被我破解了...

============================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================

本文分享自微信公众号 - Python之禅(VTtalk)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。

点赞
收藏
评论区
推荐文章
blmius blmius
2年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
Jacquelyn38 Jacquelyn38
2年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
Stella981 Stella981
2年前
Android So动态加载 优雅实现与原理分析
背景:漫品Android客户端集成适配转换功能(基于目标识别(So库35M)和人脸识别库(5M)),导致apk体积50M左右,为优化客户端体验,决定实现So文件动态加载.!(https://oscimg.oschina.net/oscnet/00d1ff90e4b34869664fef59e3ec3fdd20b.png)点击上方“蓝字”关注我
Wesley13 Wesley13
2年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Wesley13 Wesley13
2年前
Java日期时间API系列36
  十二时辰,古代劳动人民把一昼夜划分成十二个时段,每一个时段叫一个时辰。二十四小时和十二时辰对照表:时辰时间24时制子时深夜11:00凌晨01:0023:0001:00丑时上午01:00上午03:0001:0003:00寅时上午03:00上午0
Wesley13 Wesley13
2年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Stella981 Stella981
2年前
Django中Admin中的一些参数配置
设置在列表中显示的字段,id为django模型默认的主键list_display('id','name','sex','profession','email','qq','phone','status','create_time')设置在列表可编辑字段list_editable
Wesley13 Wesley13
2年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Python进阶者 Python进阶者
3个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这