【回忆杀】对unity3D游戏(跑跑卡丁车2008年韩文单机版)的...
http://blog.chinaunix.net/attachment/201801/2/29764914_1514894952o9cu.png跑跑卡丁车kartriderrush.apk(跑跑卡丁车2008年韩文单机版)是nexon公司在2008年出品的手机单机版类似PC版的赛车游戏,可谓是那时的一代经典,曾经在iOS平台和我那800x480屏幕的小破安卓手机上完美运行。十年时间过去了,如今的手机屏幕分辨率已经达到1920x1080甚至2K、4K,高分屏的安卓手机上运行这个古老的apk,会出现游戏分辨率不能自适应的问题,触摸按钮位置和图标也出现漂移。原因自然是当时这个游戏只适配了800x480屏幕的手机。经过3个多月不懈的努力,我利用unity3D游戏逆向的技术,终于成功让这个古老的游戏换发了生机,完美自适应适配各种屏幕的手机。同时顺便破解了付费跑道、人物和赛车。最后总结一下,这三个月的经验与教训。一、利用apktool或者androidkiller解包apkhttp://blog.chinaunix.net/attachment/201801/2/29764914_1514894962157Y.pngassets文件夹,unity3d的东西基本都在里面android文件夹,所有的跑道assetbundle在里面bin->data文件夹,unity3d的所有关卡(场景)资源和序列化的资源(就是乱码的那些文件)都在里面,可以使用disunity来把资源解包成贴图和shade文件等。bin->data->Managed文件夹,里面都是c#编写的dll动态链接库(或者说是assembly文件),核心文件是Assembly-CSharp.dll,我们主要修改这个文件二、回编译一下apk文件,看有没有签名验证结果游戏闪退,证明存在签名验证,估计在java代码里面,利用jd-gui查看java源码,搜索“sign”,发现在com\nexon\kartriderrush\android\olleh\KartRiderRushActivity.class类中存在判断代码http://blog.chinaunix.net/attachment/201801/2/29764914_15148949929GP3.png然后我们在smali文件中注释掉这个判断就可以了。三、研究c#源码打开Assembly-CSharp.dll,发现有500多个类,真是要命了~我们主要修改GUI开头的类,下面我来分析一下GUIAccomplishPopup.cs,跑完成弹出的一个什么东西,只要是带Popup都是关于弹出的窗口GUIAtlas.cs这个atlas真没搞懂,好像是负责图片资源最初的加载的GUIAtlasCreator.cs,顾名思义,atlas创建器GUIAtlasManager.cs,atlas管理器GUIBackground.cs,显示普通gui界面背景http://blog.chinaunix.net/attachment/201801/2/29764914_1514894974Wb5k.png的类GUIBackgroundHost.cs,显示当为蓝牙房主时的gui界面背景http://blog.chinaunix.net/attachment/201801/2/29764914_1514895013pCUU.png的类GUIBase.cs,gui基类GUIBlackBar.cs,黑条,忘记了GUIBlackBarPanel.cs,黑条面板GUIBoosterGauge.cs,加速计GUIButton.cs,按钮基类GUIController.cs,控制器基类GUIControllerIPad.cs,面板控制器基类GUIControls.cs,管理在进行比赛过程中打开菜单选择gui操纵方式控件的,例如左右方向键和漂移按键,减速按键等GUIFBLoginPopup.cs,facebook相关GUIFontCalculator.cs,字体计算器GUIFontCalculatorEx.cs,字体计算器增强版GUIFontCalculatorEx2.cs,字体计算器增强版2GUIFontCalculatorExParam.csGUIFontManager.cs字体管理器GUIGarage.cs,车库GUIGauge.cs,加速计GUIImage.cs,图片基类GUIInfo.cs,管理选完地图开始游戏的加载界面的小提示的GUIInfoControllers.cs,也是管理选完地图开始游戏的加载界面的小提示的GUIInterface.cs,接口基类GUIIPad.cs,是在玩游戏时的左右漂移减速等操纵面板的类,很关键GUIIPadItemSlot.cs,道具赛和氮气图标管理类GUIIPadPlayerMark.cs,左上角玩家排名相关类GUIIPadPlayerPanel.cs,左上角玩家排名相关类GUIIPadPlayerRank.cs,左上角玩家排名相关类GUIKartViewer.cs,不知道,3d查看器?GUILastItem.cs,最后一个列表项目基类(可用于跑道,赛车、人物等)GUIListCtrl.cs,列表控件基类GUIListCtrlItem.cs,列表项目基类GUILoading.cs,gui界面最初时“点击屏幕继续”的那个界面GUILoadingPopup.csGUILoadingReplay.csGUIMain.cs,主界面,就是选竞速赛还是道具赛的那个界面GUIMinimap.cs,跑车时右上角的小地图GUIMinimapMark.cs,小地图标记GUIMinimapPanel.cs,小地图面板GUIMinimapPanelBehaviour.cs,小地图面板动态控制GUIMode.cs,是控制最上方白条按钮栏的,不管在哪个GUI界面都控制GUIMoreItemType.csGUINewRecord.cs,跑完新纪录产生弹出的那个2s的面板GUIPackagePopup.csGUIPanel.cs,panel基类GUIPanelBuilder.cs panel建造器GUIPanelEx.cs panel扩展版GUIPanelEx3Part.cs panel3部分扩展版(适用于中间那部分可随意伸长变宽)GUIPanelEx3PartHorz.cs panel水平3部分,左中右GUIPanelEx3PartVert.cs panel垂直3部分,上中下GUIPanelExBuilder.cs panel扩展版建造器GUIPanelFactory.cs 负责将贴图dds或tga等格式显示在屏幕上GUIPanelLayout.cs 一个基类GUIPanelManager.cs panel管理器GUIPanelPlayerBuilderForIPad.csGUIPanelPlayerMarkBuilderForIPad.csGUIPanelPlayerRankBuilderForIPad.csGUIPatchSummaryPopup.cs 夏季补丁弹出GUIPause.cs 管理暂停时的一些东西GUIPlayerElem.cs 左上角玩家元素GUIPosMoverWS.csGUIProgramVersion.cs 程序版本GUIPurchaseConfirmPopup.cs购买确认弹出GUIQuestPopup.cs请求弹出GUIQuitPopup.cs 退出弹出GUIRankingBgInSingle.csGUIRankingHeaderInSingle.csGUIRankingListInSingle.cs 这一块rankinglist大概是facebook的排名列表,反正我没看到过GUIRankingListItem.csGUIRankingResetPopup.csGUIRestorePurchasesPopup.csGUIResult.cs 跑完到达终点后负责显示所有人排名和分数的计分板,带一点显示新纪录功能GUIRoomSearchingPopup.cs 房间搜索弹出GUIScrollBar.cs 滚动条基类GUIScrollBarHorz.cs 水平滚动条GUIScrollBarVert.cs 垂直滚动条GUIScrollhelpItem.csGUIScrollImage.cs 滚动图片,在帮助面板里有可以滚动的图片(就是那些链接、物品介绍之类的)GUIScrollImageEx.cs 扩展滚动图片GUIShopList.cs 不是商店,store才是内购商店,这个是车库和人物选择库GUIShopListItem.cs 车库和人物选择库的项目(车或人)GUISingleMode.cs 顾名思义是单人模式,但是就是一个状态切换,没太大作用GUISpeed.cs 速度计GUISpeedArrow.cs 速度计箭头,我都没看到过这个箭头GUISpeedArrowBuilder.csGUIStoreItemInfo.cs 内购商店项目(商品)信息GUIStoreLeftBackground.cs商店左背景GUIStoreList.cs 商店背景GUIStoreListItem.cs 商店项目GUIStoreListRestoreItem.cs以下都是商店的东西GUIStoreListUnlockableItem.csGUIStoreListUnlockAllItem.csGUIStoreListUnlockOneItem.csGUIStorePurchaseButton.csGUIString.cs GUI形式的string(字符串)GUITachometer.cs 按照翻译,还是速度计GUITrackInfoInSingle.cs 单人竞速和道具模式下的跑道信息GUITrackListInSingle.cs单人竞速和道具模式下的跑道列表GUITrackListItem.cs单人竞速和道具模式下的跑道项目类GUITrophyPopup.csGUITutorial.cs 教程(基本没用)GUITutorial2.cs 教程2(也是没用的)GUITutorialMulti.cs 教程多(都不是新手了)GUIType.csGUIUpDownListItem.csGUIURLTouchRegion.cs 好像和帮助里的链接触控区域有关GUIUtil.csGUIUVScrollImage.csGUIWaitingPlayersPopup.cs 等待玩家弹出窗口GUIWifi.cs 其实是蓝牙模式,以下wifi开头的都是蓝牙模式GUIWifiClient.csGUIWifiHost.csGUIWifiRoomList.csGUIWifiRoomListItem.csGUIWifiTrackList.csGUIWifiTrackListItem.csGUIWrongWay.cs 反方向跑时弹出的 四、使图片全屏显示GUIPanelFactory.Instance.CreateByWindowSpace(type, f, tex, 5, GUIFontCalculator.DEFAULT_GAP);注意到显示图片的地方就有这个函数,实际上这个函数就是将tex贴图中我们需要的那部分图片截取出来(缩放)并且显示在屏幕上的。type:类型f:float或者float,如果长度为6则没有缩放,则f,f为图片左上角在屏幕上显示的坐标(横屏以左上角为坐标系原点,水平右方向为x正方向,垂直向下为y正方向)。(f,f)-(f,f)为在贴图tex文件中截取的区域,就是左上角到右下角的对角线。用ps打开,用添加参考线的功能就可以看出实际截图区域。Dds格式的贴图可使用ps-dds插件打开,2345看图王也可以查看,但是按照坐标截取查图片时要将dds格式的图片垂直翻转过来,否则一眼看出就是反的Float的情况就是增加了缩放,(float,float)-(float,float)是在手机屏幕上显示的区域的对角线,相对于float增加了2位,可以实现放大缩小贴图。(float,float)-(float,float)同样是贴图截取位置 有人想既然这个方法是负责显示所有图片的,那么只要改一个方法 让其适应屏幕宽高,不就一劳永逸了吗?结果是悲观的,还存在很多地方有问题,例如在批量显示时,每个图片之间的高度和宽度,还有有些水平3部分或垂直3部分的控件图片,就比较复杂。所以还是得慢慢查看源码,慢慢改。 例如http://blog.chinaunix.net/attachment/201801/2/29764914_1514895053262w.pngGuiloading类是负责显示刚打开游戏那个界面的,这里它获取了mainTex,就是http://blog.chinaunix.net/attachment/201801/2/29764914_1514895064CM5x.png这个文件,这里基本不需要截去,直接用就可以了,所以前4位是显示图片到全屏的意思,后4位微微偏了2个像素截下图片。这是改后的代码,原来的代码是长度为6数组,没有f和f。 例如http://blog.chinaunix.net/attachment/201801/2/29764914_1514895147y4Ir.png这张图,一看就有左右和漂移按键,一定是初始化操纵界面时调用的资源。我们找到对应的类。Ingame_ui_android.dds贴图 对应的类是GUIIPad类(这个类不是专门给iPad准备的,误导我好久),至于怎么找到的,只能告诉你,猜的。http://blog.chinaunix.net/attachment/201801/2/29764914_151489515900ai.png这一样是我修改过后的代码,原来的代码就是没有*Screen.width/800f 类似的缩放代码。要是我们把未修改的屏幕位置标出来,http://blog.chinaunix.net/attachment/201801/2/29764914_1514895169fIpO.jpg就是图上用白线圈出,用红笔标记出的位置,由于操纵方式有3中,所以这三个位置的按键功能是不固定的,所以就采取了先定位,在动态切换功能的方式。要使这5个位置缩放到全屏,只需改一下代码就可以了。不过,这只是贴图的位置全屏了,触摸的位置还是没有变。接下来我们来改触摸位置。五、使触摸区域自适应屏幕一般来说,触摸区域和贴图位置都是绑定的,只有很特殊的情况才需要专门分析修改。但是这个左右漂移减速按键是特殊的。它们的触控区域代码在:IOSControler类(设置漂移和方向按键触控区域的类)中的一个字段的get和set方法里(真。大神才敢这么写,活久见)http://blog.chinaunix.net/attachment/201801/2/29764914_1514895180288Y.png把这么关键的代码放在一个set方法里面,真的让我瑟瑟发抖,工程师厉害了!判断操控方式type的值,有三种,对应三种操控方式,同样我给它加上了自动适应屏幕缩放。六、破解付费跑道这个是顺便做的,主要精力在适应高分屏上。c#:GUITrackListInSingle类InitializeListctrl() : Void函数,this.visibleAssets_.Add(item);删除if判断是否是付费的跑道,结果跑道全部显示,但是要钱的跑道为阴影且无法选择c#:GUITrackListInSingle类InitializeTrackList() : Void函数, if (definition.Lock) { nONE = (GUITrackListItem.enItemLockType) definition.LockType;直接改成了等于GUITrackListItem.enItemLockType.NONE}意思是在加载跑道列表时,不去判断是否跑道锁定或要钱,结果跑道没有阴影了但还是无法选择 到这一步,可以看见跑道,但是付费的就是无法选中,真的很急人。没事,让我们分析一下这个跑道类结构。GUITrackListInSingle类是一个list类,list中的item类对应GUITrackListItem类,item被选中,最后发消息给list类,由list负责处理。所以,关键验证核心代码在GUITrackListInSingle类的ReceiveMessage()方法中,注释掉就可以了。 付费的车辆和人物都是同样的list-item结构,破解的方法也是类似的,就不废话了。 七、拾遗6、GUITrackListInSingle类的方法protected override Rect GetAvailableRegion(){ return GUIBase.ConvertWSToUS(12f, 78f, 458f, 474f);将474f改为(float) Screen.height} 7、GUIControls类是管理在进行比赛过程中打开菜单选择gui操纵方式控件的,例如左右方向键和漂移按键,减速按键等8、对于CreateByWindowSpace(Int32, Single[], FiaTexture, Int32, Vector3) : GUIPanelEx函数,在single数组为6的情况下,singlesingle代表图片左上角在手机屏幕上的起始位置点坐标(以屏幕左上角为坐标系原点,确定),(single ,single)和(single,single)代表在贴图资源上截图的矩形的对角线(似乎都要统一减2才准确,可能是系统偏移修正)。在single数组长度为8的情况下,前四位数代表屏幕上显示的区域对角线两点的坐标(可以比图片实际大,会自动缩放填满),后四位仍然是贴图资源截取位置12、 修改GUIIPad类的srtart()方法的this.panels_.SetTouchRegionByWindowPos((702f * Screen.width) / 800f, 0f, (float) Screen.width, (82f * Screen.height) / 480f);使暂停触摸区域适应屏幕13、修改数组layoutArray1的前两个浮点数,使右上角计时面板位置自适应屏幕14、GUIIPad类中的awake()方法给this.controlInfo赋值,这个this.controlInfo就是屏幕下方最多5个按键的图片显示位置坐标,前4位是左上角和右下角的坐标,我修改成根据屏幕大小缩放图标15、修改GUIIPad类的awake()和start()方法,使操纵按钮图标显示自适应屏幕缩放,修改iOSController类中的type字段的set_Type方法,使操纵按钮触摸位置自适应屏幕缩放。 16、class MinimapCameraControl类中修改小地图的位置 17、GUIMode类是控制最上方按钮栏的,不管在哪个GUI界面都控制18、GameLoadingBack和GameLoadingStage类是管理选择跑道点击开始后的载入界面的。最后的最后,想下载的:链接:https://pan.baidu.com/s/1geWmnPT 密码:1ms1
支持下,很详细的楼主 这排版看的我眼疼 学习下,感谢 正在学习unity3D,谢谢LZ 谢谢楼主,虽然是过时的,但还能学学套路 很给力,逆向论坛有你更精彩!
页:
[1]