本文为360无线安全研究院投稿。
随着用户移动支付习惯的形成,手机游戏付费收入也逐年增长,但在看似繁荣的大好形势下,手游盗版问题一直相伴而生,并且有愈演愈烈之势。所以各大游戏厂商也开始注重手游的安全性,本文和大家一起探讨手机游戏的相关保护方案及效果分析。
一、手游安全现状
1. 盗版游戏现状
根据360加固保年初发表《2015年 Android 手机应用盗版情况调研报告》显示:平均每款正版游戏类 App 对应66.4个盗版和1.1个盗版签名,比2014年增长了2倍之多,盗版现象十分严峻。
2. 盗版数量与游戏类型的关系
不同游戏类型的盗版数量也有所不同,当下最流行、长期经典的游戏都是盗版重灾区。下图是9类不同的正版游戏和盗版游戏数量之间的关系。可以看出,休闲益智类的盗版数量最多,占总体盗版游戏总数的44%;其次为跑酷竞速类占比15%;解谜冒险类占比12%。
二、游戏保护现有手段与优缺点分析
1. Top10 游戏使用哪些安全保护措施
手机游戏面对如此严峻盗版问题,游戏厂商又有哪些保护措施呢?
对360手机助手、豌豆荚、应用宝与百度手机助手10月份下载前10的游戏应用进行分析(共40款 App),其中有进行加固保护的有5款,有做签名校验的18款(其中有5款 App 签名校验不通过后会直接杀死进程),有防调试功能的游戏仅有3款。
也就是说在下载的40最多款 App 里,大部分的游戏是不需要经过任何技术对抗,就能直接将其轻松破解并重打包的。此时破解者可以去掉游戏内的支付环节,篡改游戏规则限制、加入自己的广告等等操作。这样一款盗版 App 一旦分发出去后,对游戏开发者和用户都将造成巨大损失。
2. 游戏开源引擎的隐患
开源引擎给开发者提供很大的开发便利,同时也带来了诸多安全隐患。Cocos2d 与 Unity3D 游戏引擎是时下比较流行的游戏开源引擎,由于使用的是开源源码,有心的破解者能够阅读源码并找出稳定可靠的破解点,无论是编写自动化破解工具还是降低破解成本都是很有利的。所以接下来我们对使用这两个开源引擎的游戏进行简单的分析。
1) Top10 游戏中 Unity3D 游戏的保护措施
Unity3D 游戏是基于 .net 语言的一个 3D 引擎。游戏逻辑是使用 .net 语言编写,并在 Windows 系统编译生成 dll 格式文件。所以 Android 平台运行 Unity3D 游戏引擎需要依赖一个 .net 的虚拟机。目前主流的虚拟机就是 Mono,一个开源的引擎。通常编译共享库名为 libmono.so。
Unity3D 的保护主要遵循两条思路:
(1)修改 Mono 源码,对需要解析 opcode 重新做做映射。修改完 opcode 映射的 Mono 相当于一种新的语言,保护力度相当大的。劣势是修改源码工作量大,还是需要对 dll 文件做处理。兼容性稳定性也是很难保障的。
(2)另一种思路就是对 dll 文件进行加密。无论是对文件部分加密还是全部加密,最终 Mono 解析文件时还是得还原成明文。这也是现在普遍使用的一种保护手段。
对于 Mono 的破解点的选择,函数mono_image_open_from_data_with_name
提供了脚本文件的内存地址,文件长度与文件名。是一个很好的破解点。针对思路2,可以在此破解点入口,直接 dump 或动态跟踪,按部就班问题都不大。
按照思路(2),我们调研了一下 Top10 各个 Unity3D 游戏的保护力度。提高游戏 platformVersion,反签名校验与反调试等保护手段不在本文讨论范围,故不提及。由于涉及游戏厂商的利益,在此就不说明具体游戏应用名。对被保护过 Unity3D 游戏中的 Top10 进行了逆向,发现主要有几类保护:
A:游戏脚本在mono_image_open_from_data_with_name
函数前已经被解密,这类脚本保护较弱。直接 Hook 目标函数,以脚本文件内存地址为首地址,文件长度为内存连续空间,把数据写到文件上既能拿到脚本明文。
B:游戏脚本改写mono_image_open_from_data_with_name
函数,在函数中做解密操作。在目标函数下断点,动态跟踪参数脚本内存地址的值,脚本最终还是会在内存中被解密。
C:游戏脚本在mono_image_open_from_data_with_name
函数,重定向到本地其他文件并做解密,破解该类保护的解决办法和2方法是一样的。
2) Top10 游戏中 Cocos2D-Lua 游戏的保护措施
Cocos2d-x 游戏引擎是一个支持多脚本语言的开源游戏引擎。这里只对 Lua 游戏引擎做分析。Cocos2d-Lua 使用的 Lua 虚拟机也是一个开源项目。和一般脚本虚拟机一样 Lua 虚拟机也是先加载 Lua 脚本并做解析执行。同时 Lua 虚拟机也可以编译成 Luac 文件,Lua 虚拟机同样也能识别。
Lua 保护常见的思路有:
(1) 把 Lua 脚本编译成 Luac 格式文件,这样解包拿到的是一些二进制文件。虽然这对破解造成一定的难度,但是随着 Luac 反编译工具的成熟,这种方法也不怎么盛行了。
(2) 通过修改Lua的opcode也能很好地保护游戏。同样也存在工作量,与修改虚拟机源码问题,由于Lua虚拟机版本迭代快速,这种方法很少见被采纳。
(3) 打包时加密 Lua 文件,在 Lua 函数中添加解密的代码,在运行时解密脚本文件是现在较为流行的一种方案。
由于内存加解密安全系数比较高,一般开发者会选择在luaL_loadbuffer
这个函数做解密。同样这个函数也提供了脚本内存地址,脚本文件大小与脚本文件名这三个重要的参数。
按照思路(3),我们也对几个游戏的保护力度做了对比。
Top10 Cocos2d-lua 游戏,发现保护方案有以下几种:
A:重新编译 libcocos2dlua.so,修改共享库名称与隐藏共享库符号。该保护虽然给破解者批量破解造成麻烦,但是保护力度不大。
B:对脚本进行全文件加密,在加载前进行解密。参照Unity3D游戏,动态调试也能破解。
3. 开源引擎如何更好保护
对比 Unity3D 与 Cocos2D-lua 游戏引擎保护力度,我们可以得出结论尽管开发者有针对性地对自己的游戏做保护对抗,还是轻易地被破解者破解。
三、 游戏保护方案解析
那么,针对以上问题,有没有更好的解决办法呢?在此,360 加固保安全研究员分享了他们目前对于开源引擎游戏研究出的全新技术方案。
- 游戏脚本保护:获取开发者发布前的正式游戏包,经过加固处理,对游戏脚本文件进行加密。开发者的程序代码保持不变。游戏运行时,所加载的脚本文件在内存中会被解密成原文,进而被程序执行。
- 防挂机辅助工具
- 防内存修改器与加速器:添加了防内存修改器与防加速器功能。由于现在辅助的工具使用的技术方案都是大同小异,市面上主流的辅助工具例如八门神器、叉叉助手、烧饼修改器与胡芦侠都能进行防护。
以上就是关于手机游戏安全保护的一些研究和分析,欢迎和有兴趣的人进行技术交流。也呼吁广大手游开发者,提高应用安全意识,不让破解者有机可乘。
了解最新移动开发相关信息和技术,请关注 mobilehub 公众微信号(ID: mobilehub)。