基于unity3d游戏的android版本逆向初探
https://bbs.pediy.com/thread-212532.htm
【文章标题】: 基于unity3d游戏的android版本逆向初探
【文章作者】: dreaman【作者邮箱】: [email]dreaman_163@163.com[/email]
【作者主页】: https://github.com/dreamanlan
【软件名称】: 匿了
【软件大小】: 好几百MB
【下载地址】: 自己搜索下载
【加壳方式】: 梆梆加密
【保护方式】: 梆梆
【编写语言】: unity3d
【使用工具】: 见后面总结
【操作平台】: android
【软件介绍】: 一款MMO游戏
【作者声明】: 只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教!
--------------------------------------------------------------------------------
【详细过程】
0、背景
最近某游戏老厂出了一款MMO手游,听说画面很好,是基于unity3d的,很想看一下都是怎样的效果,但可惜
测试时间太短而且还要激活码,等我装好apk,进去时发现我既没有激活码,而且测试也结束了。。不过登录
的界面看起来确实很好,所以,只好逆向一下看看。
10年前我们在微软的dotnet平台下研究过一些安全相关的东东,10年后由于mono项目与unity3d的流行,dotnet
技术竟然在移动平台流行起来,凭着当年断断续续的记忆与一些文档,我就这么搞了一次游戏逆向,呵呵。
在移动平台,dotnet dll是没有签名的,这在一定程度上让逆向与修改更容易了。
本文简要介绍一下本次逆向的过程,与游戏相关的内容就略去了。
1、apk解包、重打包与签名
使用“Android逆向助手”或ApkStudio都可以,我们使用ApkStudio解包,Android逆向助手重新打包并签名。
2、梆梆加密解密
解包后的一级目录如下:
AndroidManifest.xml
apktool.yml
assets/
build/
lib/
original/
res/
smali/
首先用Reflector或IlSpy打开assets/bin/Data/Managed目录下的Assembly-CSharp.dll这个标准的unity3d游戏模块,
打开失败,文件加密了。。
打开lib/armeabi-v7a目录,可以看到依赖的so文件如下:
libAkSoundEngine.so
libBlueDoveMediaRender.so
libCrasheyeNDK.so
libDexHelper.so
libKGAudio.so
libmain.so
libmono.so
libmsc.so
libslua.so
libunity.so
libuwa.so
libweibosdkcore.so
从文件名看了看,多数是功能性模块,只有libDexHelper.so比较可疑,上网搜了一下知道是梆梆的东东。网上没找到
梆梆用于unity3d游戏的加密原理与方案等信息,只能自己看看了。
这时候得用上ida pro了,我用的是6.6版本,首先看一下libmono.so,这个是mono的运行时库,对dotnet的加载及运行
支持都在这里,直接看一下mono_image_open_from_data_with_name函数,看了一下,没有明显被修改的痕迹,又找了
几个相关的加载相关函数,都没发现修改痕迹。。
怀疑是不是根本没有修改libmono.so,unity3d的版本信息在其资源文件里比较容易查到,随便打开assets/bin/Data下
的某个assets后缀的文件(记得用十六进制编辑器),可以在文件开头看到5.3.3p2,居然用的是一个补丁版本而不是f1
这种正式版本,去unity3d网站下个对应版本的编辑器+android发布包,安装后找到
Unity5.3.3p2\Editor\Data\PlaybackEngines\AndroidPlayer\Variations\mono\Release\Libs\armeabi-v7a\libmono.so
用Beyond Compare等支持二进制比较的工具与游戏里的libmono.so对比一下,完全相同。看来梆梆是不会静态修改
libmono.so的了,想想也是,像unity3d这种版本频繁更新的,梆梆要是每个版本都静态改一下,还是挺被动的。不过
话说某厂的加密就是静态修改的libmono.so(其实是自己修改源码了重新编译的)。
搞不清libDexHelper.so是怎么工作的,我不是专业搞逆向的,用ida pro打开看了看,没发现线索就放弃了
(在ida pro里没找到Assembly-CSharp.dll这样的字符串,不过用十六进制编辑器在libDexHelper.so文件尾是看到有
这个字符串的,有兴趣的同学可以研究下它的加密原理)。
我换了个思路来得到解密后的dll,就是从libmono.so动手,前面已经发现梆梆没有对这个文件进行静态处理,所以我们
想怎么处理都比较容易,看mono的源码知道在mono_image_open_from_data_with_name函数里dll文件的内容会以完整的内
存映像出现。
所以至少有几种办法得到解密后的dll:
1)、断点后dump内存,我用的是电脑上的虚拟机,断不了。。
2)、修改mono源码,加入dump代码再替换游戏的libmono.so,这个理论上是可行的,但为了这么点事有点费劲了
3)、直接修改libmono.so,手动打补丁,看了下mono源码后,发现mono_image_open_from_data_with_name函数的开头有
一段判空检查,正常情况没什么用,看了下ida pro里这段代码占用的字节数,足够打补丁的了:)
我们还需要找一个能放我们补丁代码的地方,这需要一个不怎么被使用的函数,连蒙代猜的,我选择了
mono_load_remote_field,这个函数的空间足够写很多代码了。