Android破解进阶之:元气骑士
( 原文地址:https://0xffff.one/d/482 )
更新:0xffff上的原文由于论坛用户变多后为了规避版权问题被删了,不过反正都是完全搬运的(而且反正也是我写的)所以问题不大(逃
上次在Android破解初探之:Synthesia介绍(shui)了下Android应用的破解方法,这次继续来搞事情。
环境搭建·
由于元气骑士是一个Unity做的游戏,所以需要一些解Unity的工具(大部分工具的用法都参照了kjkjkAIStudio的教程):
- Il2CppDumper:Unity游戏代码的一些信息会放在一个metadata文件里,如用到的字符串的值、用到的函数名字等,il2cppdumper是用来帮助把这些信息在逆向时添加进库文件里(指的是ida文件)。在github就可以下载。
- IDA:上次说过了,但这次需要用到python支持,所以要先配好。
- dnSpy:上面说的matadata恢复出的信息用这个东西看会更方便一点,不得不说它的搜索功能真好用。。。同样github上就有。
- AssetStudio:可以提取Unity的asset数据,因为需要用到asset中的一个文件。github下载。
- C#环境:il2cpp.so里面的东西是C#写的,由于我太菜了所以解它的加密时直接照着它的函数写了个- -
解包·
首先说一下我搞的版本时GooglePlay下的v2.5.1版本,在国内应用商店下的强制我登录,还要实名- -
用AndroidKiller可以解包,但在重打包时发现凉屋好像对签名做了检查,如果发现包被改过的话进入游戏时会直接跳转到官网,绕签名的方法到现在我还没搞出来(咕咕咕)。所以如果没有AK或者不想搞AK的话可以直接把后缀改成.zip解包,或用7-zip等解。
解包后关注两个文件:一个是lib里的libil2cpp.so,在 lib/对应arm版本/libil2cpp.so,至于arm版本,32位的就是armeabi-v7a文件夹,64位的就是arm64-v8a文件夹,实在不知道版本的可以看一下安装完后手机(或虚拟机吧)里的 /data/app/com.ChillyRoom…的那个目录里的lib目录里是arm还是arm64。
另一个是matadata文件,在解包后的目录里的 assets/bin/Data/Managed/Metadata/global-metadata.dat。
拿到两个文件后要用il2cppdumper提取数据,但这个要先知道Unity版本,Unity版本可以打开 assets/bin/Data/level0 文件看,文件开头一堆二进制中会有一串数字,那个就是Unity版本(v2.5.1用的是2018.4):
il2cppdumper的用法在github上有介绍了,输入命令+so文件路径+metadata文件路径后输入Unity版本,再输3(Auto Plus)就好:
使用后会在使用目录里多了四个文件/文件夹(看日期就可以看出来是哪些了),把这些文件放好,一会会用到。
还有asset文件可以先解出来,AssetStudio打开解包出来的asset文件夹,然后Export All提取。
看源码·
首先是把il2cpp.so用IDA打开(文件比较大,会解比较久- -,记得32/64位对应好),解完后通过IDA中的 file->Script file ,然后选择刚才metadata提取的scripy.py,等一会就会把符号/名字等贴上去了(注意IDA要支持python,不会的可以看kjkjkAIStudio的视频)。
另外由于IDA的搜索功能(跟dnSpy比)实在一般,所以可以通过dnSpy把metadata提取出来的 DummyDll/Assembly-CSharp.dll 用dnSpy打开,然后 编辑->搜索程序集 调出搜索窗口。搜到的函数对应的RVA值就是函数在il2cpp.so的地址,在IDA里跳到这地址就是对应函数(快捷键g)。
破解过程·
1. 内购破解·
说起内购破解,在很久(大概一年多或更久前吧)以前,元气骑士的角色是否解锁、钱的多少都是由一个xml文件决定的,只要改掉这个文件里对应的数据就是破解完了。但是,在最近(大概几个月前吧)改的时候发现游戏会把我的xml删掉然后建个新的,所以这次才和元气骑士搞上了(知道昨天才发现原来是我把数据改错了,游戏解析不到数据才会删档,让我还patch了这么久- -)。
xml文件的路径在 /data/data/com.ChillyRoom.DungeonShooter/shared_prefs/com.ChillyRoom.DungeonShooter.v2.playerprefs.xml ,里面的东西都有名字的,猜出大概意思然后改掉就好了,比如"c1_unlock"就是character1的解锁情况,”gems“就是钱。(下面会贴一下改好的)
但改的时候要注意数值不能太大(不然删档),“unity.player_sessionid”、"unity.cloud_userid"等最好保留原来的(不然会发生什么我也不知道)
2. 合成材料破解·
内购因为是明文存储的所以好处理,合成材料则放在另一个文件 (/data/data/com.ChillyRoom.DungeonShooter/files/item_data.data ,几乎元气出花园后更新的东西都放这里了),是加密数据。
材料的存取跟一个叫 ItemData 的类有关,重点关注它的Save和Load方法。
IDA中可以大约看到,Save函数从游戏中获取到data后是通过函数JsonUtil__SaveJsonWithCrypt存储数据
SaveJsonWithCrypt会先把数据转换成JSON格式,然后调用EncryptHandler__Encrypt加密存储
EncryptHandler__Encrypt中可以看到是用了C#的DESCryptoServiceProvider进行DES加密,key和data是外部传进去的,iv是由CryptUtil__DecryptXor函数计算出来,key和iv都要通过il2cpp_array_new_specific_0函数进行padding
CryptUtil__DecryptXor逆向一下大概就是(把那些范围检测的都去掉了):
1 | string XorDecrypt(string s1, string s2){ |
而il2cpp_array_new_specific_0逆了一下大概就是如果传进去的string少于8bytes(其实是a2,只是在这里是8)的话就在后面补0补到8bytes(由于key和iv都小于8bytes,所以剩下的就没追进去了)。
然后key的值从函数调用来看是StringLiteral_11064,iv就是StringLiteral_8948和StringLiteral_8949进行CryptUtil__DecryptXor的结果。关于StringLiteral其实差不多是个常量,它的值可以在metadata提出出来的stringliteral.json文件里找,但要注意下下标,IDA的StringLiteral是从1开始的。得到的key是"iambo",iv xor前的两个值是”\x11(55(#“和"PASSWORD",xor后得到iv是”Ahbool“。
由于密码学学艺不精,花了一个下午入门了C#然后才照着原程序把加解密程序撸了出来- -,最后把JSON文件解密了出来,因为太长了就不图了。关注一下里面的东西:
- plants:现在花园里种的植物,想改什么把plantName改了就好,state就是生长状况。
- commodities:应该就是在卖的商品。
- itemUnlock:一些解锁了的东西,现在我只知道填"plant_pot3"~"plant_pot7"的话可以把所有花圃都解锁了。
- forgeWeapons:现在在研究台的武器。
- blueprints:蓝图及拥有状态,状态:None(就是空着)是没有,Got是拥有,Researched是已经研究出来了。要改的话建议先改成Got,游戏中再进行研究。
- seeds:种子及其数量。
- materials:材料及其数量。
- 其他:我也没搞清楚是什么。。。
可以看出要改的话大部分东西都是需要先知道名字的,至于物品名字,是放在asset解出来的 TextAsset/ItemInfo.txt 文件里,是个JSON文件,有了修改item所需的全部名字。写个python把名字全部提取出来:
1 | import json |
把JSON文件填好后重新加密放回原来位置就好。
注意一点是xml文件和data文件放的时候都需要先把游戏关闭,不然游戏会把内存中的数据放到文件中(就是改了等于没改)。
秀下结果·
最后的最后·
破解只是为了玩一下/学一下,请勿用于非法用途(逃)(源码的话发出来也不太好,可以在下面留言或群里私我,逃)