arcaea是一款画风和玩法都非常出色的音乐类手游,那么这款游戏不氪金能够玩吗,里面的音乐包到底怎么解锁呢,给大家分析一下技术方案吧!
游戏五花八门,游戏吸引玩家的方式也五花八门。比如笔者就喜欢玩一个名为Arcaea的音游。它制作良心,质量靠谱,定价也可以接受,实在是一款不错的游戏。但是个人认为美中不足的是,它里面有些内容需要反复游玩才能解锁,在解锁时,还有体力限制。这使你每天都要登录,有些甚至解锁条件十分苛刻。
没办法,在如今的手游市场环境下,只靠买断制盈利,并让开发者生存下去,是一件十分困难的事。要想盈利,就要抓住玩家的心,增加用户黏度,就要用各种办法使玩家先感到痛苦,并用各种奖励去引诱。所以各种体力制,抽卡机制,签到啊月卡啊就被加入游戏了。它们的本质都是让你难以得到你想要的,从而使你心中有个念想,你就会在这种念想下不停地刷刷刷。
我个人是十分不喜欢这种游戏推进方式的,生活本来就已经很不容易了,打个游戏还要伤肝掉发,太痛苦了。所以就说到今天的主题了,我们是否可以找到一种方法,让游戏变得更轻松呢?
在文章的开始,我要先澄清一下:我支持并建议大家游玩正版游戏,本文不会涉及破解游戏的应用内购买,游戏本身也有相应的保护:你需要真的付费才能从开发者的服务器下载到游玩付费内容必需的文件。我个人也是真正付费了的——比起抽卡,买断明显便宜多了。
在进行修改之前,我们要先找到目标,第一步是解包apk文件。这里就要先提一下Android的分层了。
Android可大致分四层,分别是Java应用层,Java框架层,native层和Linux内核层。详细的介绍可以在网上搜到,这里为了不偏离主题我们不做过多展开,主要谈谈native层。Native层是应用中较为底层的部分,常用于一些库,本地服务。这一层是用C/C++实现的,所以相对Java层有着更高的效率。大多数游戏引擎都是使用C/C++制作的,将游戏核心代码放在native层,这是非常普遍的,一些知名引擎比如Unity、虚幻都是这么做的。Java层呢,就负责一些框架的工作,比如与应用市场交互,拉起支付软件等。今天我们下手的目标游戏是使用Cocos2dx引擎,C++语言制作的。所以,我们今天的修改目标就处于native层。在apk文件中,native层主要以.so文件存放于lib/[架构]/中,apk文件可以用压缩包管理器打开。
我们可以看到它的文件夹中有4个so文件,其中一个是崩溃分析,两个是音频处理,剩下的libcocos2dcpp.so就是引擎的核心,我们要修改的游戏逻辑也在这个文件里,将这个文件解压到一个新文件夹里备用。
找到了目标,接下来就是准备工具。我们这次使用的工具是IDA Pro。IDA是一款十分强大的工具,集反编译与调试一体,还有着强大的分析能力,是逆向工具中当之无愧的行业标杆。这是一个非常非常复杂的软件,复杂到开发公司通过提供技术培训就能赚不少,我只是比一窍不通稍微好一点点,今天的修改只涉及到一些简单的操作,所以不用担心看不懂,有手就会。(若不是生活和学业所迫,谁又想去搞汇编呢?)IDA可以从吾爱破解下载到,个人不建议下载绿色版,会缺一些功能,不过那些功能本文也用不到就是了。至于汉化版,好像仍停留在6.8版本,我不确定支不支持ARM64,可以试试,不推荐。
安装好IDA就到了激动人心的实操环节了。第一步是打开IDA,你可能会想这打开IDA还有什么好讲的,还真有。32位的IDA无法处理64位的可执行文件,而64位的IDA呢,虽然能打开32位的文件,但是在生成伪代码时会报错,给分析加大难度。32位和64位的so文件分别存放于armeabi-v7a和arm64-v8a文件夹中。鉴于现在都0202年了,生化危机冷饭也炒到3了,我就默认大家都是64位了。打开64位的IDA,首先看到Quick Start界面,这里我们点击New,打开刚刚解压的libcocos2dcpp.so
然后IDA会弹出加载文件对话框,这里什么都不用改,直接点OK
点OK后IDA就开始分析文件了,你会看到这样的界面:
看到这里,你可能就想退软件了,先别慌!IDA还在分析这个文件,我们要先等它分析完,在分析完之前我们什么也不用干。
IDA会分析文件中的机器码,将其转为ARM指令,并分析函数的结构。
可以在左下角的分析指示器看到分析的进度。
IDA的分析是单线程的,如果处理器单核性能不行,这里就会耗时比较久,可能会有20-30分钟。
当分析完后,指示器会显示idle(空闲),这时主界面也会产生变化
主界面的汇编界面会变成比较容易理解的图形分支界面(图中未体现),左侧的函数列表也会多出很多在分析中发现的函数。对于逆向,这个引擎还是比较友好的,函数名基本都有意义。如果函数名没有意义,那可能就要上动态调试了,本文不讲。如果因为一些原因,你的IDA-view仍然不是图形界面,你可以右键然后选择Graph view手动切换成图形界面。
接下来我们要做的就是分析了,分析是整个修改过程中最耗时的部分,我们要尝试理解游戏的一些逻辑,并定位修改的目标。得益于有意义的函数名,我们可以通过名称大致判断其的作用,这里,我们的目标是解锁歌曲,所以可以先在函数窗口中搜索关键词来定位控制解锁的函数。在函数窗口右键,选择“Quick filter”,然后在下方输入框中输入关键词“unlocked”
有一些函数名出现了两次,但是它们在不同的分段(Segment),这里不介绍,只用知道要改的是.text分段的函数就好。从这里我们可以大致猜测歌曲解锁与SongDifficulty::isUnlocked()这个函数有关,所以我们双击它。
右边变成了这样。对着这个东西,我们也不急着看,先按F5。
然后神奇的IDA会帮我们把汇编翻译成C,这样就更好分析了。
往下拉,我们看到这个函数又调用了一个函数
看着也挺可疑的,那我们就跟进这个isFullyComplete呗
哎呀,又是一大串
由于是翻译来的,所以无法100%还原,在转换过程中,所有变量名都失去了意义,而且结构也是贴近汇编的,看看那一堆goto,一旦长了,看起来就会十分混乱。我们要是这么写程序,是要被老师吊起来批的。
保护眼睛,也保护头发,对于这类返回一个值的函数,如果没必要,就不要深究这个函数的逻辑了。这里有一个偷懒的办法:在看这类函数时,我们大可以从下往上看。
看这个函数,它不是返回1就是返回0,从函数名判断,我们可以合理猜测:返回1是满足解锁条件,返回0是不满足。那我们就把返回0改为返回1。不出意外的话,返回值会给0号寄存器,我们返回IDA View从下往上找和0号寄存器有关的语句。
从图形界面上,我们很容易就能看出分支结构,一边是给W0寄存器赋值1,另一边是赋值0(WZR),那么修改的地方就很明确了,我们只要把MOV W0,WZR改成MOV W0,#1就行了。接下来就是修改了,鼠标点击MOV W0,WZR这个语句,会在窗口下方显示这个语句在文件中的地址,再点击HEX View。
点击的语句已经在文件中被标示出来了,接下来就是改它了,我们要通过直接修改文件的16进制来改变语句。如何知道自己要怎么改呢?这里就要推荐一个方便的在线工具Online ARM To Hex Converter(http://armconverter.com/)。顾名思义,这个工具可以将ARM指令转换为16进制机器码。
在转换器中输入我们需要的语句按回车就可以看到结果了,我们需要的MOV W0,#1转换后就是20008052了,回到HEX View,右键→edit或者按F2,将那里的E0031F2A改掉就可以了。改完后,右键→Apply changes或者再次按F2应用修改。
改完之后颜色会变化,这时切回IDA View,我们看到语句已经成功被更改了
还有一种取巧的方法是抄,隔壁不是已经有一个MOV W0,#1了嘛,定位到那里看看它是怎么写的然后直接抄过去就行了,因为那个转换器网站在国外,可能访问不是很顺畅,用抄的就能省不少时间。
这个游戏会在上传成绩时同时上传游戏文件的md5,如果校验不通过,你号就没了。
为了避免账号风险,游玩修改版时应该保持登出状态。但购买记录应该是与账号绑定的,为了达到离线游玩的效果,我们还需要修改购买验证。这里就要改两个函数了,一个是PurchaseManager::isPurchased,另一个是PurchaseManager::isWorldUnlocked。一样的套路,同样是修改函数返回值。重申一遍,本教程目的不是破解应用内的购买!如果不购买,你将无法从开发者的服务器下载到进行游戏必需的文件。
这游戏还有故事情节,要查看剧情,仍然需要刷刷刷,那就顺便解锁一下故事好了。通过搜索名称,我们确定要对线的函数是StoryEntry::isUnlocked,点开它,按F5,一气呵成~吗?
哎哟,这次从下往上看好像不好使了,这是个void函数哇,不返回值的。咋整呢?总之先拉到伪代码(PseudoCode)的顶部看看变量声明吧。
可以看到在int和char之中藏着一个bool变量v7,布尔值不就是0和1嘛,开始显得可疑了!再回看底部,底部也对v7进行了操作,更可疑了,那v7应该就是我们下手的地方了。在变量声明中,IDA将v7所用的寄存器w19注释在了旁边。那就让我们返回IDA View看看w19吧。
有不少操作W19的地方,看起来还真复杂,而且操作W19的地方也不少。这就有点难下手了,本着从下往上的偷懒原则,我们先看看那个AND语句:这是一个与运算,比较W19和1,将结果放进W0——哎哟,有点可疑,那我们就把这个与运算改成或运算,让W0始终为1试试?一样的通过转换器生成指令进行修改,这里我们将AND(与)改成ORR(或)
修改本身就是不断尝试理解,试错的过程,如果改错了,我们也能通过View菜单→Open subviews→patched bytes(或按Ctrl+Alt+P)查看并撤回更改。
完成修改后,我们就可以通过Edit→Patch program→Apply patches to input file将修改保存了,如果觉得有必要还可以备份一下
接下来就是测试修改是否有效了,将修改过的libcocos2dcpp.so覆盖原文件安装。使用修改版WinRAR可以无视锁定直接把修改后的文件拖入源apk,没有修改版WinRAR也可以直接将apk文件解压缩,覆盖文件后压缩回zip再把扩展名改成apk。然后将apk文件传输至手机安装即可。
如果你的手机没有应用过核心破解,那么你还需要对修改过的apk文件重新签名,关于这个的工具网上很多,就不详细讲了。签名后也不能直接覆盖安装,要先卸载原版,为了防止存档和下载好的游戏数据丢失,这里可以使用adb进行保留应用数据的卸载,或使用钛备份铁备份这备份那备份之类的工具,反正方法很多,八仙过海,各显神通。
安装完游戏打开测试,如果游戏没有直接崩溃退出,说明你已经成功一半了,那再看看我们的修改效果吧。
解锁条件十分苛刻的关卡可以直接游玩了
需要肝才能玩到的曲目也都解锁了
故事也可以直接查看了
这篇文章不短,感谢你耐心地看到这里。从读这篇文章,到按照流程一步步做下来,可能会花费30-60分钟。这个耗时,说长也不算太长,因为需要改的地方,文中都告诉你了。实际上修改一个游戏时,最难的不是不是修改这个行为,而是得知改哪里、怎么改的过程。在分析这个游戏,测试修改的过程中,我花费的时间远远不止1小时。但是这一步恰恰是难以在文章中写出来的,只能通过多看,多想,多试来一步步确定方向。希望你能在读完这篇文章后有所启发,要是能对逆向产生兴趣那就更好了。最好是再找一个小(软)游(柿)戏(子)自己尝试分析修改,能够将自己不满意的事物改造成自己满意的模样,我觉得还是很有成就感的。也希望大家在打开一个游戏时,心里想的是这个游戏真棒,我现在想玩;而不是今天的体力还没用,任务还没做。(当然,支持正版也很重要)