芽衣 发表于 2022-3-27 23:20

小游戏 Brain Test 3 大脑测试3 破解付费内容 无限内购

本帖最后由 芽衣 于 2022-4-9 19:43 编辑

游戏属于il2cpp,现在很多的安卓游戏都采用了这个打包。对于这类游戏,常见的改法是修改dex的入口,在入口处添加一个调用代码,每次启动都自动修改sp的long值,这样就达到了无限金币的目的。还有另一种改法就是直接修改so文件,通过修改底层代码,可以实现的玩法也比较多,比如不减反增、定死数值、免费购物、全部解锁等。但是相对的也比较麻烦,对于没有汇编经验的萌新来说,还是写个Java实在。
软件样品为当前最新版1.50.0。

准备工具
1、IDA32
2、Il2CppDumper


想不到这游戏已经出到第三部了,前两部我还发过帖子如何修改无限提示,不过是改dex的。现在换另一种方法,改so破解游戏。
游戏风格比较适合小朋友,有些关卡我实在想不通为什么是这样……

https://static.52pojie.cn/static/image/hrline/5.gif


游戏有广告,怎么去掉我就不说了,用幸运破解器一键搞定就好了,来来去去都是那几个熟面孔。




先看一下游戏界面,第一次玩游戏的时候会送50个电灯泡,正常情况下会越用越少,那么就会有相减的逻辑,修改so的时候可以利用相反的指令让灯泡越来越多,也就是不减反增。

下好Il2CppDumper后,顺序打开相应的文件,libil2cpp、global-metadata.dat。等待分析完成后打开dump.cs文件备用。
接着ida打开so文件,选择左上角运行如下两个脚本文件,静静等待加载完毕即可。电脑差的会比较久,可以先去喝杯奶茶再回来看看{:17_1088:}




之前说过这类游戏的数值一般储存在sp里面,位于com.unicostudio.braintest3.v2.playerprefs.xml,打开后他是长这样的:
<?xml version='1.0' encoding='utf-8' standalone='yes' ?>
<map>
    <int name="cross_promo_id" value="61" />
    <string name="unity.player_session_count">5</string>
    <int name="Screenmanager%20Resolution%20Height" value="2220" />
    <string name="unity.player_sessionid">4976473052650692822</string>
    <int name="Gdpr_Control" value="1" />
    <string name="NotificationHelper.Scheduled">273129443%7C1094985734</string>
    <int name="__UNITY_PLAYERPREFS_VERSION__" value="1" />
    <int name="Screenmanager%20Resolution%20Width" value="1080" />
    <string name="unity.cloud_userid">95a0dbb4b1309fcf094060f513e8d42d</string>
    <string name="playerData">%7B%22coins%22%3A5%2C%22OnCoinsChanged%22%3A%7B%7D%2C%22gems%22%3A0%2C%22OnGemsChanged%22%3A%7B%7D%2C%22hammers%22%3A0%2C%22OnHammersChanged%22%3A%7B%7D%2C%22adsRemoved%22%3Afalse%2C%22OnAdsRemovedChanged%22%3A%7B%7D%2C%22completedLevels%22%3A%5B1%2C2%2C3%2C4%2C5%2C7%2C8%2C9%2C10%2C11%2C12%5D%2C%22lastReachedLevel%22%3A13%2C%22lastPlayedLevel%22%3A13%2C%22hintsOpened%22%3A%7B%226%22%3A%5B0%5D%2C%227%22%3A%5B0%2C1%5D%7D%2C%22OnHintsOpenedChanged%22%3A%7B%7D%2C%22flags%22%3A%5B%22new_level_popup_showed%22%2C%22bonus_Bonus1_skipped%22%2C%22hint_LevelTricky1_0%22%2C%22hint_LevelTricky1_1%22%2C%22tricky_LevelTricky1_played%22%2C%22hint_Make_Potion_1%22%2C%22hint_Alchemy_1%22%5D%2C%22selectedPets%22%3A%7B%22cat%22%3A-1%2C%22dog%22%3A-1%2C%22bird%22%3A-1%2C%22frog%22%3A-1%7D%2C%22unlockedPets%22%3A%7B%22cat%22%3A%5B%5D%2C%22dog%22%3A%5B%5D%2C%22bird%22%3A%5B%5D%2C%22frog%22%3A%5B%5D%7D%2C%22activeActionLevel%22%3A1%2C%22LastReachedLevel%22%3A13%7D</string>
    <int name="Screenmanager%20Fullscreen%20mode" value="-1" />
    <int name="rate_shown" value="1" />
    <int name="shareClaimed" value="1" />
</map>


playerData里的coins就是电灯泡的数量,gems应该是钻石。coins%22%3A5,这个5就是数量,当前为5。





然后搜索dump.cs里的playerData,只有一个结果,那么这里就是就是破解的关键入口。其中get_Coins、get_Gems这两个都是比较常见的代码,如果你不知道关键字可以先搜这两个,看看有没有相关信息。


      // Methods

      // RVA: 0x13D954C Offset: 0x13D954C VA: 0x13D954C
      public int get_Coins() { }

      // RVA: 0x13D14DC Offset: 0x13D14DC VA: 0x13D14DC
      public void set_Coins(int value) { }

      // RVA: 0x13D9554 Offset: 0x13D9554 VA: 0x13D9554
      public int get_Gems() { }

      // RVA: 0x13D75B4 Offset: 0x13D75B4 VA: 0x13D75B4
      public void set_Gems(int value) { }

      // RVA: 0x13D955C Offset: 0x13D955C VA: 0x13D955C
      public int get_Hammers() { }

      // RVA: 0x13D9564 Offset: 0x13D9564 VA: 0x13D9564
      public void set_Hammers(int value) { }

      // RVA: 0x13D9604 Offset: 0x13D9604 VA: 0x13D9604
      public bool get_AdsRemoved() { }

      // RVA: 0x13D960C Offset: 0x13D960C VA: 0x13D960C
      public void set_AdsRemoved(bool value) { }

      // RVA: 0x13D96B8 Offset: 0x13D96B8 VA: 0x13D96B8
      public int get_LastReachedLevel() { }

      // RVA: 0x13D96C0 Offset: 0x13D96C0 VA: 0x13D96C0
      public void set_LastReachedLevel(int value) { }

      // RVA: 0x13D974C Offset: 0x13D974C VA: 0x13D974C
      public void SetHintOpen(int level, int hintIndex) { }

      // RVA: 0x13D998C Offset: 0x13D998C VA: 0x13D998C
      public bool GetHintOpen(int level, int hintIndex) { }

      // RVA: 0x13D9A88 Offset: 0x13D9A88 VA: 0x13D9A88
      public void .ctor() { }



先来看Coins(),有两个结果,public int get_Coins()和public void set_Coins(int value),get_Coins根据地址跳转到0x13D954C,我查看了一下引用,结果为0,没有函数引用这个地方,如果修改这里的话十有八九是没什么用的。




接着继续看set_Coins,跳转到地址0x13D14DC。英文意思是设置、显示数值。破解过java的应该知道,方法名中有set_xx,get_xx,应该是改get,而不是set,set这个函数基本上有传入参数,所以不能直接修改这里,这里只是用来显示数值的。但是刚才的get找不到引用,所以只能另寻方法。





通过查看set_Coins的交叉引用,可以确定是哪里调用了显示,如上图红框,分别是几种扣费地址。随便选一个,汇编如下:


```
il2cpp:01324714 ; ---------------------------------------------------------------------------
il2cpp:01324714               MOV             R0, #8       //函数地址
il2cpp:01324718               LDR             R7,        //r0地址读取放入r7,此时r7是剩余的电灯泡
il2cpp:0132471C               BL            HintPanel$$get_cost       //获取商品价格,需要花费多少电灯泡
il2cpp:01324720               MOV             R6, R0       //把价格存入r6
il2cpp:01324724               BL            sub_2B6FD4
il2cpp:01324728 ; ---------------------------------------------------------------------------
il2cpp:01324728
il2cpp:01324728 loc_1324728                           ; CODE XREF: sub_1324350+C4↑j
il2cpp:01324728               SUB             R1, R7, R6       //r1=r7-r6,此时r1是剩余的电灯泡
il2cpp:0132472C               MOV             R0, R5       //r5传入r0,然后进入BL
il2cpp:01324730               MOV             R2, #0       //初始化
il2cpp:01324734               BL            PlayerData$$set_Coins       //进行显示
il2cpp:01324738               MOV             R0, #0
il2cpp:0132473C               BL            DataManager$$get_playerData
il2cpp:01324740               MOV             R5, R0
il2cpp:01324744               CMP             R0, #0
il2cpp:01324748               BNE             loc_1324750
il2cpp:0132474C               BL            sub_2B6FD4
```


```
v13 = DataManager__get_playerData(0);
v14 = v13;
if ( !v13 )
    sub_2B6FD4();
v15 = *(v13 + 8);
cost = HintPanel__get_cost();
PlayerData__set_Coins(v14, v15 - cost, 0);
v17 = DataManager__get_playerData(0);
if ( !v17 )
    sub_2B6FD4();
```


伪代码比较容易理解,有个减号,很容易看出这是扣费的地方。





所以把5个函数的调用,全部由减法改成加法指令(add)即可越用越多,其它的货币也是一样的思路,就不一一举例了。



芽衣 发表于 2022-3-28 10:39

luodeman 发表于 2022-3-28 10:37
大佬,求个《 Brain Test 3 大脑测试3》原始版本,我也想试试,谢谢

这是谷歌市场的游戏,apk包你去apkpure下载

芽衣 发表于 2022-3-28 14:48

Gavin5661 发表于 2022-3-28 14:38
那么提示的数量会不会有上限啊?到了上限会报错吗

几个亿不会有问题,几十亿不好说{:17_1088:}

灭寂丶 发表于 2022-3-27 23:25

抢个沙发。{:1_918:}{:1_918:}

异常马粥 发表于 2022-3-27 23:27

大佬厉害啊

zhengxinjun 发表于 2022-3-28 00:33

大神,收藏慢慢学习

Y先生 发表于 2022-3-28 00:52

有改好的吗?下载试试

ayxc 发表于 2022-3-28 01:10

大神,666

嘿i你的益达 发表于 2022-3-28 01:15

不会汇编的我,看的津津有味{:301_1009:}

k288 发表于 2022-3-28 02:15

写得很不错,虽然对于程序代码不太了解{:1_921:}

意决于心 发表于 2022-3-28 02:20

太牛了,羡慕

cyhcuichao 发表于 2022-3-28 03:17

大佬这工具能发下吗?
页: [1] 2 3 4 5 6 7 8 9 10
查看完整版本: 小游戏 Brain Test 3 大脑测试3 破解付费内容 无限内购