最近旅行的青蛙甚火,便来试一试Android和iOS上面Unity3D游戏C#脚本和C/C++函数的分析与修改,由于Android大部分是mono模式如果C#脚本没有加密的话是直接可以拿过来分析修改的,但是iOS大都使用IL2CPP模式把C#脚本转成C/C++代码了,直接分析的话要难很多,所以本文先从Android开始分析然后结合Android再分析iOS。
首先将Android apk安装包解压,查看assets/bin/Data/Managed
文件夹下面的dll文件,其中Assembly-CSharp.dll
便是游戏中的C#脚本,使用Reflector或者dnSpy进行反编译都可以,如何出现反编译出错的情况,那可能就是脚本被加密了,一般在尝试在libmono.so
中的mono_image_open_from_data_with_name
中获取解密后的dll脚本,而当前分析的游戏C#脚本并没有加密。在dnSpy中的反编译结果如下:
左侧就可以看到对应的类,点击类就可以看到反编译出来的代码,下面先跟游戏里面的一些特征来分析反编译出来的脚本。
首先使用adb install tabikaeru.apk
命令安装apk文件,然后打开游戏可以看到如下界面:
首先来看看怎么修改显示的文字以达到汉化的效果,使用dnSpy点击编辑->搜索程序集
搜索右边选择数字/字符串
然后搜索名前
:
点击CallTutorial
可以找到刚刚在屏幕上面显示的文字:
鼠标点击右键选择编辑IL指令
,修改刚刚看到的文字为汉字:
然后点击应用即可看到修改后的效果:
点击文件->全部保存
替换assets/bin/Data/Managed
文件夹下面对应的文件即可,然后将文件打包成apk使用jarsinger、signapk.jar或Android助手重签名安装到手机就能看到修改后的效果了。
要修改三叶草数可以从购买的时候入手,比如提示三叶草不足的时候:
直接搜索足
找到目标代码:
根据找到的如下代码来分析:
当三叶草的存储小于当前商品的价格的时候就会弹出这个提示,点击SuperGameMaster.CloverPointStock()
得到如下代码:
这里返回的是一个从saveData.CloverPoint
中获取的整数,可以尝试将其修改成返回一个特定的数字每次查询三叶草的数目都是这么多,右键点击编辑IL指令
,然后点击重置并右键删除第一条指令,因为只是返回一个数字的话两条指令就够了:
然后修改第二条指令为一个数字,具体的指令代表的类型可以查看IL指令说明:
点击确定后就能看到修改代码的效果:
重新签名安装之后每次购买商品之后三叶草的数目也不会减少,一直是9999。
修改抽奖券也是同样的套路,搜索足
找到目标代码,其实刚刚搜索的时候就已经看到了。
点击SuperGameMaster.TicketStock()
也是差不多的代码同样修改返回数字即可:
每次抽奖都是抽到白球就不是很开心了,怎么能够提供抽奖的概率呢?抽到其它颜色的球的时候会提示:
搜索白玉
找到如下代码:
右键点击PrizeBallName
选择分析找到在那里被使用的:
双击PrizeBallName
得到如下代码:
从代码来看就是刚刚抽奖结果提示的地方,来分析下这个结果是怎么生成的,可以看到Define.PrizeBallName[this.result]
这个result决定了抽到的是什么颜色的球,那么看看这个result是在哪里生成的。在当前文件中看到了两处赋值:
下面是在UIMaster_raffle.UI_Start
中调用的,判断之前的奖品有没有领取,LotteryCheck
这个刚好是在显示结果之前调用的,猜测就是这里控制的不同颜色的球的出现概率,分析下这段代码:
从上面代码分析PrizeBalls中就定义了不同颜色的球摇出概率:
所以直接修改这里的数字就控制摇出的概率了,比如不出白球,其它球的概率都一样:
农场里面大部分都是三叶草、四叶草的概率是很小的,那么怎么修改这个呢?在界面上面好像不太好找关联,先试试搜索三叶草的英语clover
,点击checkCloverCreate
看起来就是控制生成的函数:
首先看this.NewCloverObject(j, this.cloverList[j], list)
这个内部调用就是四个参数的,只不过第四个参数是false:
也就是第四个参数为true就是四叶草,点进去看看:
那么这里既可以修改四叶草生成的概率也可以修改fourLeafFlag
这个为true,第一种方式和上面一样,看看第二种。右键fourLeafFlag
编辑IL指令:
这里首先取fourLeafFlag
判断然后跳转,所以修改为true即可。修改ldarg.s fourLeafFlag
为ldc.i4 1
,修改后的代码如下:
Android的修改的部分就到这里了,其它的大家可以自己去尝试,总结下分析Unity3D游戏过程,当然这篇文章讲的是最简单的情况,还有使用保护将dll脚本加密的,就需要hook函数或者从内存查找dump,还有通过C#脚本调用lua脚本来实现的,逻辑在lua脚本里面,lua脚本又加密了的情况等等。那么没保护的情况的话,一般可以从界面显示搜索来分析,然后根据一些特定单词去搜索查找关键代码部分。这篇主要是Android上面使用mono模式的情况,如果是使用IL2CPP的话比如iOS上面,C#脚本都转成了cpp文件c代码的形式的话分析起来就会麻烦很多,下面来看看iOS上面修改hook代码。
上面主要也是为下面做铺垫吧,因为在iOS现在都是IL2CPP模式,C#脚本已经被转成了C/C++代码。所以要单独分析iOS的话难度会大很多,如果从Android的C#脚本入手的话,因为iOS和Android脚本都是一样的话,可以从Android分析的函数名来对应iOS的c函数然后进行hook修改。
首先从越狱设备上面提取旅行青蛙的ipa包,使用frida-ios-dump一键提取即可。由于是日文名字,先通过./dump.py -l
把名字列出来,然后复制名字或者通过bundle id去dump就可以了。
由于使用IL2CPP选项编译unity游戏,会生成cpp的代码,直接使用IDA看是看不到函数和函数名的,而且游戏中使用的字符串都被保存在global-metadata.dat的资源文件里。首先要通过提取global-metadata.dat文件里面的字符串对对应的c函数进行符号还原。具体也有现成的文章:还原使用IL2CPP编译的unity游戏的symbol,github上面也有线程的项目也做这件事情Il2CppDumper。下载release的工具,运行Il2CppDumper.exe并依次选择il2cpp的可执行文件和global-metadata.dat文件,然后选择Auto(Plus)模式,将生成dump.cs文件和script.py脚本。使用IDA打开可执行文件然后使用script.py脚本即可还原符号。
还原之后就可以根据之前分析到的函数名来hook对应的代码了,首先是三叶草的数目通过SuperGameMaster.CloverPointStock()
获取的,在IDA搜索CloverPointStock
如下:
接着就可以直接hook这个函数了,由于要inline hook目前是在越狱机器上面,后面会讲到非越狱机器hook的方案。使用MonkeyDev新建一个Logos Tweak
项目,清空.xm
的内容并写入如下内容:
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!
最后于 2019-1-31 09:39
被admin编辑
,原因: