[原创]Android逆向之旅——GG大玩家应用破解实战分析

fxbfxb 2017-12-6 22:48 534

第一次在神级论坛“看雪论坛”发表技术文章,距离本文章首发已有两天时间了,终于还是鼓起了勇气。  纯手机端分析,技术含量不高但重在分享 ,献丑了! 

1.前言

相信提起手游辅助界一免ROOT辅助神器——GG大玩家大家都不陌生,在本人印象中他应该是业界第一个推出沙盒机制修改游戏的应用。他提供诸多游戏专用MOD辅助模块,运行时动态注入,实现无ROOT情况下HOOK游戏进程,达到破解效果(本人有一款同样原理的辅助软件——破解沙盒,基于VA二次开发的)。我们今天的主角也是他,我们发现他的所有MOD的使用都是要消耗积分的,而积分需要充值购买,另外有VIP机制,VIP免积分但一年需要120元。这肯定让广大游戏爱好者又爱又恨。同时对于我们这些逆向爱好者,简直是一种折磨。在本文发布前市面上是有GG大玩家某些模块的免积分版的,但只能需要哪一个替换哪一个,根本不能满足需求。同时CRACKer都是追求完美破解的,不能停步于此。扯了这么多本文正式开始,本文将会带着大家完全利用手机端完成GG大玩家离线VIP版的修改!


2. 工具

MT管理器

ROOT抓包


3. 模块破解初探

在正式开始VIP版制作前,本着授人以渔的至高理念,先带领大家完成市面已有的GG大玩家MOD模块破解。

我们先来到GG的内部存储路径(/data/data/com.iplay.assistant/),一阵扫荡之后我们发现”/files/localsandboxgame/localgame”文件存放着重要信息,我们这里找个了在线json格式化工具来更清楚的观察。


{
    "localGames": {
        "com.cmcm.arrowio": {
            "dependCheck": false,
            "dependGooglePlay": false,
            "desc": "游戏玩法类似于球球大作战 弓箭模式更有趣",
            "downloadType": 0,
            "gameId": "e1d36a49",
            "gameName": "弓箭手大作战",
            "iconUrl": "http://7xleaj.com1.z0.glb.clouddn.com/-54f7d4a10e7bab8a",
            "installLocalPluginInfo": {
                "pluginFile": {
                    "path": "/storage/emulated/0/Android/data/com.iplay.assistant/files/Download/plugins/com.gameassist.plugin.arrowio"
                },
                "pluginId": "557",
                "pluginName": "厉害了MOD",
                "pluginPkgName": "com.gameassist.plugin.arrowio",
                "pluginPrice": 0,
                "pluginVerCode": 17,
                "pluginVerName": "1.17"
            }.....省略

不过多的介绍其他无用键值信息,我们看到pluginFile中path标注的便是当前游戏MOD存放位置,那么废话不多说,直接找到他,因为没有后缀名我们不能直观的判断他的格式,使用HEX编辑器打开看看




我们一眼便可以看出它是ZIP压缩文件,那么APK安装包其实也是ZIP格式的,直接用MT管理器以“APK查看”




   因此MOD其实就是APK文件,毫无疑问直接打开classes.dex




结构非常简单,而且没有加固保护,也没有混淆,那么看到trial试用这个扎眼的包,直接去看看,因为类实在少的可怜,所以不需要什么技巧,一个个看呗。




如此直白,修改不掉都对不起九年义务教育,直接让该方法始终返回真即可,smali代码如下:

    const/4 v0 1
    return v0

大功告成,这就是直接破解MOD的思路,但破解完毫无成就感,那么多MOD我就算搞个批处理工具最终也只能单个替换,简直是鸡肋。


4.离线VIP版初探

说完上面鸡肋的破解方式,我们有了个大胆的想法,能不能直接破解GG大玩家本体,实现无限积分或者VIP的功能呢?但我的心里同时也没底,因为如果MODGG大玩家验证分离,MOD单独完成会员信息验证,我们破解GG大玩家是南辕北辙的。但即便如此,不去尝试肯定是失败,不如试一试。

我们考虑到gg那个小悬浮窗,包括界面上提示的信息,而我们在MOD中是找不到的,因此断定悬浮窗的界面肯定GG大玩家中。首先GG大玩家也没有加固保护,我们尝试搜索关键字,但无论是dex文件还是arsc资源文件都找不到。当然不排除在so文件或者加密存储在dex文件中再或者是layout和图片资源中,毕竟是手机端破解,我们暂时不考虑加密存储和so这些因素,尝试在资源目录assets中寻找,果不其然里面有个plugin-center.apk文件。成功锁定目标后,那些关键字符串我们也陆续找到了。

同样是没有任何保护(真的不得不说GG大玩家开发者心真大呀,天天搞别人就不想想会不会有人搞他),这也是值得我们窃喜的地方。




  首先在不登录的情况点击红色位置会提示“需要登陆”,搜索字符串常量定位到以下一个结果




   看一下关键的smali代码




首先发现这个Toast是在一个switch分支中的,之后是获取PluginEntry类的usrProfile字段,如果为空将会弹出提示。我们同时注意看到第84行会调用OnPluginUIShow方法,推测这个就是显示MOD界面的方法。综上所述,将第一个if跳转改为goto语句才有机会加载MOD view。果然,修改这里之后我们成功的在没有登录的情况下显示了MOD界面。




同时如图也遇到了新的问题,我们的金币不够该怎么办,看到有关键提示“试玩机会已用完”,回到dex中搜索字符串常量,搜索到唯一一个方法。




找到关键的smali代码如下




发现一个关键的字符串信息“尊敬的vip用户,您可以免费解锁此功能”,并且上图的第一行smali代码就是取PluginEntry类的freePermission字段来判断是否为vip。那么修改思路主要有两个,一是简单粗暴直接修改本句smali下的if语句,二是来到PluginEntry中为freePermission属性重新初始化为真,在本例中两者都可以,但在更大型的app中推荐第二种,因为检测vip权限的地方不唯一的话要修改N条跳转。修改完效果如下:




是不是已经成功了呢?兴致勃勃的点了一下解锁。。。。。。然后,




果然开发者还不至于这么low,肯定在完成这些敏感操作时还会有验证,那么继续搜索字符串吧,结果我们搜遍了整个GG大玩家也没有找到。不仅心里咯噔一下,莫不是在MOD中检测的,这就日了狗,刚刚的工作岂不是白做了,赶紧去MOD的路径下搜索一番,也没有!瞬间心里爽多了——有戏。那么这个弹窗哪冒出来的呢?


5.联网自校验

带着上面的疑问我们下载了手机抓包软件——Packet Capture,这是一款利用安卓自身VPNService框架来实现在无ROOT环境下捕捉封包的软件,要注意的是当你想抓取https协议时需要安装软件里面提供的证书,但本例子中不需要。抓包截图如下




    只展示一下请求头,请求体中包括我的设备信息,插件信息什么的就不截了




这是服务器响应信息,其中Unicode编码的字符串“\u767b\u5f55\u65e0\u6548”转为中文就是“登录无效”,而code键对应的值“10003”便是提示的错误码。

    现在一切都很清晰了,服务器的校验,我们可以搜索请求的uri  “/api/v1/commodity/free_get”来定位校验方法。找到如下两个类:




竟然有两个,那么是两种不同的检测方法还是这两个类存在某种合作关系呢?

首先尝试查看z类的关键方法


 


如上图是z类中关键smali代码,原来是他调用了aj类,那么两个类的关系就很明确了,aj类可能是为了完成各种网络请求而封装的,这样我们只需考虑z类就好了。不过问题又来了,z类的这个方法也没有处理服务器响应的结果呀,不能再这里修改逻辑怎么办?这就需要我们找到调用z类的地方了。

那么我们在手机上如何查找交叉引用信息呢?这时smali语法不负众望作为我们的坚实后盾。

方法的表示形式:


 Lpackage/name/ObjectName;->methodName(III)Z         
    Lpackage/name/ObjectName  表示类名         
    methodName   表示方法名 
        III   表示参数(这里表示为3个整型参数)说明:方法的参数是一个接一个的,中间没有隔开

   我们尝试构造一下这z类的o方法的smali形式(在此不需要考虑调用时的invoke-XXX指令)


Lcom/gameassist/plugin/z;->o(Ljava/lang/String;)Ljava/lang/String;

   直接点击MT管理器中的搜索代码功能,成功定位了调用zo方法的方法。




学过安卓开发的都知道,如图中的doInBackground属于安卓异步加载任务AsyncTask中用于处理耗时操作的方法,不出所料这个方法里面还是没有什么逻辑(只是单纯的调用,不附图了)。而当后台操作结束时,onPostExecute(Result result)方法将会被调用,计算结果将做为参数传递到此方法中,直接将结果显示到UI组件上。因为我们打开同类下的onPostExecute方法寻找逻辑。




如上图就是解析服务器返回的json文本,而当code键的值为-1时就会执行成功逻辑,否则跳转到label_171弹出错误提示,修改很简单,删掉if跳转即可。


6.总结

    至此离线VIPGG大玩家完成,不需要登录就可以有VIP身份免积分享用任意MOD。最后也是对GG大玩家的保护机制深表遗憾,谨以“常在河边走哪有不湿鞋”送给其开发者团队!

    郑重声明:本文仅供学习交流,如果有人利用本文知识和技术进行非法操作以此牟利,后果由操作者本人承担,与本文作者无任何关系!

BinCrack原创发布,转载请注明作者!




最新回复 (0)
返回