【原创精品】对kartriderrush.apk(跑跑卡丁车2008年韩文单机版)的逆向破解修改

跑跑卡丁车kartriderrush.apk(跑跑卡丁车2008年韩文单机版)是nexon公司在2008年出品的手机单机版类似PC版的赛车游戏,可谓是那时的一代经典,曾经在iOS平台和我那800×480屏幕的小破安卓手机上完美运行。十年时间过去了,如今的手机屏幕分辨率已经达到1920×1080甚至2K、4K,高分屏的安卓手机上运行这个古老的apk,会出现游戏分辨率不能自适应的问题,触摸按钮位置和图标也出现漂移。原因自然是当时这个游戏只适配了800×480屏幕的手机。

经过3个多月不懈的努力,我利用unity3D游戏逆向的技术,终于成功让这个古老的游戏换发了生机,完美自适应适配各种屏幕的手机。同时顺便破解了付费跑道、人物和赛车。

最后总结一下,这三个月的经验与教训。

  1. 利用apktool或者androidkiller解包apk

assets文件夹,unity3d的东西基本都在里面

android文件夹,所有的跑道assetbundle在里面

bin->data文件夹,unity3d的所有关卡(场景)资源和序列化的资源(就是乱码的那些文件)都在里面,可以使用disunity来把资源解包成贴图和shade文件等。

bin->data->Managed文件夹,里面都是c#编写的dll动态链接库(或者说是assembly文件),核心文件是Assembly-CSharp.dll,我们主要修改这个文件

  1. 回编译一下apk文件,看有没有签名验证

结果游戏闪退,证明存在签名验证,估计在java代码里面,利用jd-gui查看java源码,搜索“sign”,发现在comnexonkartriderrushandroidollehKartRiderRushActivity.class类中存在判断代码

然后我们在smali文件中注释掉这个判断就可以了。

  1. 研究c#源码

打开Assembly-CSharp.dll,发现有500多个类,真是要命了~

我们主要修改GUI开头的类,下面我来分析一下

  • GUIAccomplishPopup.cs,跑完成弹出的一个什么东西,只要是带Popup都是关于弹出的窗口

  • GUIAtlas.cs这个atlas真没搞懂,好像是负责图片资源最初的加载的

  • GUIAtlasCreator.cs,顾名思义,atlas创建器

  • GUIAtlasManager.cs,atlas管理器

  • GUIBackground.cs,显示普通gui界面背景  的类

  • GUIBackgroundHost.cs,显示当为蓝牙房主时的gui界面背景  的类

  • GUIBase.cs,gui基类

  • 等等

  1. 使图片全屏显示

GUIPanelFactory.Instance.CreateByWindowSpace(type, f, tex, 5, GUIFontCalculator.DEFAULT_GAP);

注意到显示图片的地方就有这个函数,实际上这个函数就是将tex贴图中我们需要的那部分图片截取出来(缩放)并且显示在屏幕上的。

type:类型

f:float[6]或者float[8],如果长度为6则没有缩放,则f[0],f[1]为图片左上角在屏幕上显示的坐标(横屏以左上角为坐标系原点,水平右方向为x正方向,垂直向下为y正方向)。(f[2],f[3])-(f[4],f[5])为在贴图tex文件中截取的区域,就是左上角到右下角的对角线。用ps打开,用添加参考线的功能就可以看出实际截图区域。

Dds格式的贴图可使用ps-dds插件打开,2345看图王也可以查看,但是按照坐标截取查图片时要将dds格式的图片垂直翻转过来,否则一眼看出就是反的

Float[8]的情况就是增加了缩放,(float[0],float[1])-(float[2],float[3])是在手机屏幕上显示的区域的对角线,相对于float[6]增加了2位,可以实现放大缩小贴图。(float[4],float[5])-(float[6],float[7])同样是贴图截取位置

有人想既然这个方法是负责显示所有图片的,那么只要改一个方法 让其适应屏幕宽高,不就一劳永逸了吗?结果是悲观的,还存在很多地方有问题,例如在批量显示时,每个图片之间的高度和宽度,还有有些水平3部分或垂直3部分的控件图片,就比较复杂。所以还是得慢慢查看源码,慢慢改。

例如

Guiloading类是负责显示刚打开游戏那个界面的,这里它获取了mainTex,就是

 这个文件,这里基本不需要截去,直接用就可以了,所以前4位是显示图片到全屏的意思,后4位微微偏了2个像素截下图片。

这是改后的代码,原来的代码是长度为6数组,没有f[2]和f[3]。

例如

 这张图,一看就有左右和漂移按键,一定是初始化操纵界面时调用的资源。我们找到对应的类。Ingame_ui_android.dds贴图 对应的类是GUIIPad类(这个类不是专门给iPad准备的,误导我好久),至于怎么找到的,只能告诉你,猜的。

 这一样是我修改过后的代码,原来的代码就是没有*Screen.width/800f 类似的缩放代码。

要是我们把未修改的屏幕位置标出来,