游戏安全实验室 首页 技术入门 查看内容

 阅读目录

实战篇——第一道习题及答案

发布于:2016-7-12 09:49   |    123437次阅读 作者: 管理员    |   原作者: TP   |   来自: 原创

题目

逆向分析2048游戏生成随机数及通关过程,尝试构思2048游戏能否实现快速通关功能。


习题答案:


游戏功能分析

实现外挂功能过程中前期的游戏分析是必不可少的只有掌握目标功能的游戏逻辑实现,才能快速做出相应需求的外挂。下面将按照常规的分析思路一步步找到目标功能实现点。

1.1功能可行性分析

2048这款游戏玩法比较简单,具体的玩法读者可自行体验目前很多平台上都有这款游戏的踪迹,本章重点关注的是android平台上面的这款游戏。首先确认怎么做才能实现游戏的快速通关。下面列出一些可行的方案:

1. 影响生成牌的逻辑,让随机生成的牌均为同一种如都是生成2。

2. 影响通关的判断逻辑,修改成就算不是达到2048也能通关

3. 影响牌与牌之间的组合逻辑,比如2和4组合马上变成2048。

4. 影响生成牌的逻辑,直接生成一个2048。

着这些想法需要考虑另一个问题,就是这些逻辑会在客户端实现吗?这些生产牌逻辑或者牌之间组成的逻辑等在客户端吗?

虽然依据经验判断2048游戏不会服务器中实现相关逻辑,但是这里还是详细给读者讲一下大概可以用什么方法初步的判断出来。参考下之前游戏系统及开发相关概念介绍里面的强联网和弱联网小节,这种游戏经典模式在玩法上面单机游戏类似,中间游戏过程就算断网也可以玩初步可以认为游戏中间过程游戏逻辑是在客户端处理的。那么基本确定快速通关功能是可以做的。

既然功能存在可行性那么利用上面提到的四种方案中选择一种尝试去分析游戏客户端的实现。了使功能实现得更加稳定初定选择第一种方案。第四种方案属于简单粗暴型的实现方式,由于功能过于高调,存在被游戏安全策略检测到的可能

1.2 游戏引擎确认

游戏的逻辑分析一定程度依赖于对引擎的了解程度,游戏引擎相关的概念和基础知识请参考《游戏引擎基本概念及常见引擎介绍》章节内容

Android版2048手游安装包文件为2048_6.11_50.apk,接下来对2048_6.11_50.apk进行解压,使用Apktool或者直接解压均可以解压之后的文件结构如下图1所示

                   1 2048手游解压之后文件结构

点击进入目录lib\armeabi\中,可观察到该目录中存在唯一一个so,名字为libcocos2dcpp.so,基本确认游戏使用cocos2d-x引擎开发并且以c++ 作为主逻辑编写的核心语言主逻辑在so文件中该类型游戏反编译得到smali代码(java代码在android中间码一般不存在游戏逻辑相关的代码因为java代码只负责界面显示。(此处特别说明:游戏解压如果没有lib目录的,那么游戏逻辑极有可能通过java代码实现,此类java的实现方式一般适用于玩法特别简单的游戏,如flappy bird)

1.3寻找关键逻辑

通过上面的介绍,确定游戏逻辑通过C++语言实现,游戏的逻辑客户端控制,接下来需要实际分析相关逻辑实现方式读者可回顾游戏逆向分析实战篇中关于C++游戏分析的相关内容下面将会在IDA中使用字符串定位法静态分析游戏逻辑实现方式。

libcocos2dcpp.so拖入IDA中暂且不关注游戏有没有符号信息IDA中按下“Shift + F12”快捷键便可获取游戏所有字符串信息,在IDA的字符串窗口可执行搜索相关的操作。实例中将搜索create字符串因为快速通关功能将修改创建牌的数字实现可通过搜索“create”获取创建牌信息IDA中“create”相关字符串显示如图2所示。

图2 IDA搜索create字符串

双击图2中“Create 2048 tile to win the game!”字符串之后跳转至字符串定义的位置此时可获取到字符串的交叉引用,交叉引用的框中内容如图3所示3中存在PlaygroundController类函数信息由此推断游戏没有抹除字符串(如函数名字符串)

3  aCreate2048Tile的交叉引用窗口

可猜测PlaygroundController类游戏控制相关IDA的函数窗口搜索“PlaygroundController”字符串之后显示信息如图4所示:

4 PlaygroundController成员函数

 

4中存在分数相关的函数信息(对应函数名为:increaseScore),双击PlaygroundController分数相关函数,可获取到该函数交叉引用如图5所示:

5 PlaygroundController::increaseScore的交叉引用窗口

PlaygroundController::increaseScore函数负责增加场景的分数,该函数上层调用函数Playground::pushToIncreaseScorePlaygroundPlaygroundController的基类IDA的函数窗口中搜索Playground类成员函数此时显示重要的逻辑处理函数信息

通过IDAImports窗口搜索“rand”关键字,显示的信息如6所示

6  Imports窗口rand”关键结果

2048游戏生成数字阶段会用随机函数,一般的编程思路为:通过调用API函数生成随机数利用生成的随机数再结合一些算法去生成随机值那么随机值处理方式可作为分析的线索事实证明猜想是正确的6中arc4random函数的交叉引用信息如7所示

7  导入函数arc4random交叉引用

7中存在Playground类,可推测通过Playground类定位到随机值生成的相关函数。Playground类中存在Playground::addBoxRandom 函数通过函数名可推测与随机数的生成有关,函数实现如下8所示

 

8  Playground::addBoxRandom函数实现

游戏的玩法如图9所示

9  游戏过程截图 

此时可通过动态调试验证之前静态分析的结论是否正确动态调试具体的操作方法可参考《动态分析》章节中Android平台IDA动态调试相关内容,先通过“ aapt dump badging 2048_6.11_50.apk | grep package获取到这个游戏的包名为“com.estoty.game2048”,IDA调试器附加游戏进程之后便可调试程序

每次滑动方向,Playground::addBoxRandom函数就会被调用一次,验证静态分析的结论完全正确BoxPointArray::count()返回值处设置断点如图10所示当断点触发时R0数值为0x10,十进制16。意味着传入Playground::addBoxAtIndex的第二个参数区间[0,15]。

10  BoxPointArray::count()返回处断截图

因为游戏中有16个空格,Index的区间是[0,15],那么Box是什么?推测为每次滑动后生成的正方形,游戏定义为Box也可理解Playground:: addBoxAtIndex函数实现如下11所示

     

11  Playground::addBoxAtIndex函数实现

11中首先调用arc4random()函数,然后调用的Playground:: addBoxAtIndexWithLevel 函数中r2只有1和2两种可能按概率计算1出现的可能性非常大。接下来通过动态调试分析参数的作用。首先动一次屏幕,然后让游戏在断点位置,如图12所示修改R2寄存器为5。

12 修改addBoxAtIndexWithLevel 函数R2参数

12 Playground::addBoxAtIndex 函数Playground::addBox AtIndexWithLevel函数R2寄存器修改为5,继续执行后,屏幕中反馈出一个有趣的信息生成了一个值为32的Box,如图13所示:

13 修改R25继续运行游戏截图

聪明的读者一定想到了2的5次方32。那么2048是2的多少次方?11次方,也就是十六进制的0xB。尝试修改R2为0x0B试试,修改后执行效果如图14所示

14 修改R2值0x0B后继续运行游戏截图

14 提示的信息表明已顺利通关。下面讲解功能实现思路。


*转载请注明来自游戏安全实验室(GSLAB.QQ.COM)

分享到:
踩0 赞0

收藏

上一篇:天天风之旅IOS神奇助手新版本无敌功能分析

下一篇:实战篇——第二道习题及答案

最新评论
B Color Image Link Quote Code Smilies

发表评论