美文网首页
Unity游戏逆向思路

Unity游戏逆向思路

作者: 约你一起偷西瓜 | 来源:发表于2020-05-26 12:17 被阅读0次

拆弹专家,原谷歌游戏
downloadUrl:https://ww.lanzous.com/id06yjc(有广告版本)
本文只作为思路分享文章,无逆向成品,仅供学习交流
拿到apk首先还是解压一下看一下文件目录,看看游戏引擎

Unity游戏.png
这里就先借用一下Perfare大神的工具:Il2CppDumper
该工具用来分析so里面游戏逻辑的方法枚举,虽然没有函数体,但是通过函数名很大程度上还是可以帮助我们分析游戏的逻辑,工具很香,可以配合IDA使用,了解详情的可以自行查看GitHub文档
(7.2版本IDA直接去运行ida.py并加载script.json即可实现方法名的导入)

其次就是对反编译libil2cpp的dll文件可以使用Reflector或者dnSpy来查看(其实和查看dump.cs没有太大的区别,主要的差别在于使用Reflector可以直接去查看空命名空间的代码,过掉一些系统级别代码)

举例一下Reflector结合Frida的使用

Reflector示例.png

这里我们可以知道偏移地址(实际地址=基地址+偏移地址+ thumb指令?1:0))

  • showDilog() → 0x547484
  • showMessage() → 0x547F30

通过这种方式我们就可以轻松的批量断点我们希望断点的方法了
以下为一个简单的批量断点脚本示例:

function start(){
    //com.izyplay.defusethebomb.bazhang
    var arrayAddr = [0x54728C,0x547310,0x54745C,0x547DF8,0x547484,0x548218,0x547F30,0x55DF40
        ,0x679798,0x6798B4,0x687428,0x687350]; 
    var arrayName = ["AndroidDialog Create","AndroidDialog Create1","AndroidDialog init"
        ,"AndroidMessage Create","showDialog","CallStatic","showMessage","SetPressedState"
        ,"NativeDialog","NativeMessage","ToggleButton","OnClick"]; 
    
    var soAddr = Module.findBaseAddress("libil2cpp.so");
    console.error('\nsoAddr:' + soAddr + "\n");

    for (var index = 0; index < arrayAddr.length; index++) {  
        console.log("-------------------------");
        var currentAddr = soAddr.add(arrayAddr[index]);
        console.log('currentAddr:' + currentAddr);
        funcTmp(currentAddr,soAddr,index,arrayName);
        console.log("\t\t---->"+index,arrayAddr[index]+" is prepared ");  
    } 
    console.log("\n")
}

function funcTmp(currentAddr,soAddr,index,arrayName){
    Interceptor.attach(currentAddr, {
        onEnter: function(args){
            console.log("called : "+arrayName[index]+"  ----- addr : " + currentAddr.sub(soAddr) +"\n");
        },
        onLeave: function(retval){

        }
    });
}

已上是对so的一个简单处理分析
我们知道Unity游戏与Java的通信是通过UnitySendMessage()之类的函数来实现的
不同的代码可能写法不一样,但是这里注意几个关键词就是了
“Unity”,“Send”,“Message”,“Reward”,“Video”(拿到国内的谷歌游戏都是添加了广告的,自然是有一个video来展示广告,获取奖励Reward等等)自己排列组合,总能发现点东西

使用Jadx搜索关键字.png

随便点进去一个跟进代码不难发现其实最终就是去调用了Native方法




这里就不继续跟进了,回到初衷是要搞这个游戏的奖励
这里游戏原来的处理逻辑是点击观看广告视频,然后就可以成功获取奖励,上面说了,游戏与unity的通信是通过UnitySendMessage来实现的,这里我们只用再找到在哪里打开视频,打开视频看完了必然也会有一个成功回调,修改smali处理一下这个逻辑就搞定,于是我们又重新搜索关键字Reward,Video ... 发现如下

奖励获取.png

这里可以看到每种广告播放状态都向Unity发了一条消息(UnitySendMessage 是一个 public static方法),简单分析一下逻辑,成功后向Unity发的是什么消息,剩下的就是对这个smali为所欲为了

public static void UnitySendMessage(String str, String str2, String str3) {
        if (!m.c()) {
            f.Log(5, "Native libraries not loaded - dropping message for " + str + "." + str2);
            return;
        }
        try {
            nativeUnitySendMessage(str, str2, str3.getBytes("UTF-8"));
        } catch (UnsupportedEncodingException unused) {
        }
    }

    const-string v0, "onRewardedVideoAdRewarded"

    const-string v1, "123"

    invoke-direct {p0, v0, v1}, Lcom/ironsource/unity/androidbridge/AndroidBridge;->sendUnityEvent(Ljava/lang/String;Ljava/lang/String;)V

至于以上我们是怎么找到这些关键点的话,我们还是使用我们的Frida大法,使用基于Frida的Objection来完成Class批量断点,非常好用,当然你也可以选择手写Frida批量下断脚本

Objection批量断点.png

想进行方法调用的测试,我们可以使用Frida的远程方法调用,静态变量值的获取等等

        Java.choose("com.ironsource.unity.androidbridge.AndroidBridge",{
            onMatch: function(obj){
               var ss = {"reward_amount":1,"placement_name":"DefaultRewardedVideo","reward_name":"Virtual Item"};
                obj.sendUnityEvent("onRewardedVideoAdRewarded","onRewardedVideoAdRewarded");
            },
            onComplete: function(){

            }
        });

        Java.choose("com.ironsource.mediationsdk.model.RewardedVideoConfigurations",{
            onMatch: function(obj){
                console.log("主动调用onRewardedVideoAdRewarded")
                var mRVPlacements = obj.mRVPlacements.value;
                console.log(mRVPlacements.size());
                console.log(mRVPlacements.get(0));
            },
            onComplete: function(){

            }
        });

最后来一个小tips:想不看广告只用对app重新签名就是,但是广告播放成功的回调自然也是失效了,所以还是需要稍微改改smali

以上就是这个Unity游戏的简单逆向过程

总结一下:
一般游戏逆向分为unity游戏,cocos游戏,或者一些自己写的游戏

unity主要可以看成两类,dll游戏和libil2cpp游戏,dll游戏比较简单,由于c#类似Js的语言特性,几乎就是可以明文随便篡改(dpy/),为了安全性的提升,所以才应运而生了libil2cpp用来转换dll to so ,但实际上逆向的时候使用ida分析libil2cpp的时候也差不多吧,有点汇编基础基本不难看懂,或者是结合frida去动态短点一些位置,或者是使用dwarf去动态调试一些位置,so我们只能修改不能新增指令,解决这个问题我们可以考虑用inlinehook完成新增。对于libil2cpp的情况,咋们可以用我分享的工具dps.py查找关键词函数,使用dpoint.js批量断点我们想查看的函数,动态断点方便我们快速找到想要hook的关键点后,使用inlinehook对其实现本地化为所欲为。对于一些自己写的游戏没有了dumper,但是我们可以考虑使用frida脚本枚举导出函数进行批批量hook,同时筛选函数名实现上述类似工作,至于cocos游戏也可以参照上述思路,咋们就简单分个类 cocos js 和 cocos lua,由于这篇文章主要介绍unity游戏,这里就不多说cocos,大概就这样哇 ~

相关文章

  • Unity游戏逆向思路

    拆弹专家,原谷歌游戏downloadUrl:https://ww.lanzous.com/id06yjc(有广告版...

  • iOS逆向-Unity3D游戏辅助开发

    Unity3D(iOS)游戏辅助开发 前言: 看了庆哥 旅行的青蛙Unity游戏逆向修改--iOS篇之后,着手撸了...

  • Rewind-Time

    游戏回放:思路通过记录transform Quaternion 逆向

  • android Unity3D 游戏修改基础篇

    视频里的东西,整理成文章, Unity3D逆向系列(基础)大纲 基础介绍篇 1.unity逆向环境搭建 1..Ne...

  • iOS逆向之旅 — 总纲

    逆向杂谈 因为我大学期间开发游戏外挂,对于逆向的强大有过不小的认识。能让别人的代码照着自己的思路去走,感觉是蛮好玩...

  • 逆向思路

    界面分析 Cycript、Reveal 代码分析 对Mach-O文件的静态分析 MachOView、class-d...

  • Unity3d游戏开发实战案例视频教程

    Unity3d游戏开发实战案例视频教程,通过课程一和课程二详细展示了2个游戏的制作方法和思路、学习游戏制作的思维,...

  • iOS逆向-思路及常用工具

    iOS逆向wiki 逆向APP思路 Cycript Reveal class-dump Hopper MachOV...

  • 小白如何学习unity3d-思路整理

    很多朋友想要学习游戏开发却苦于没有思路,下面是千锋教育的游戏开发学习总结,希望能够对你有所帮助。 Unity3D作...

  • Unity 5种视图

    Unity 5种视图: Unity 资源的分类: Unity GameObject Unity 游戏场景: Uni...

网友评论

      本文标题:Unity游戏逆向思路

      本文链接:https://www.haomeiwen.com/subject/gesmahtx.html