吾爱破解 - LCG - LSG |安卓破解|病毒分析|www.52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 9416|回复: 116
收起左侧

[Android 原创] 小游戏 Brain Test 3 大脑测试3 破解付费内容 无限内购

  [复制链接]
芽衣 发表于 2022-3-27 23:20
本帖最后由 芽衣 于 2022-4-9 19:43 编辑

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

软件样品为当前最新版1.50.0。

准备工具
1、IDA32
2、Il2CppDumper



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




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

1.jpg


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

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

1.png 2.png


之前说过这类游戏的数值一般储存在sp里面,位于com.unicostudio.braintest3.v2.playerprefs.xml,打开后他是长这样的:
[Asm] 纯文本查看 复制代码
<?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。


1.png


然后搜索dump.cs里的playerData,只有一个结果,那么这里就是就是破解的关键入口。其中get_Coinsget_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,没有函数引用这个地方,如果修改这里的话十有八九是没什么用的。

1.png


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


1.png


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


il2cpp:01324714 ; ---------------------------------------------------------------------------
il2cpp:01324714                 MOV             R0, #8       //函数地址
il2cpp:01324718                 LDR             R7, [R0]       //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();



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


1.png


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



免费评分

参与人数 33威望 +1 吾爱币 +49 热心值 +26 收起 理由
zpzwz + 1 + 1 用心讨论,共获提升!
qtfreet00 + 1 + 20 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
无时顾及 + 1 热心回复!
独行风云 + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
maza_2000 + 1 + 1 鼓励转贴优秀软件安全工具和文档!
er_nianni + 1 + 1 热心回复!
Jxdm + 1 + 1 谢谢@Thanks!
deep1ndreams + 1 + 1 谢谢@Thanks!
weezyBC + 1 + 1 谢谢@Thanks!
random77 + 1 + 1 鼓励转贴优秀软件安全工具和文档!
z7138910 + 1 + 1 热心回复!
seei + 1 谢谢@Thanks!
longjazz + 1 + 1 谢谢@Thanks!
bilibini + 1 用心讨论,共获提升!
那些年打的飞机 + 1 谢谢@Thanks!
iceSleeping + 1 + 1 谢谢@Thanks!
darst335 + 1 + 1 谢谢@Thanks!
a2314500 + 1 + 1 谢谢@Thanks!
heimianbao + 1 用心讨论,共获提升!
bylking + 1 + 1 谢谢@Thanks!
小小的石头13 + 1 + 1 我很赞同!
xb0wxh + 1 + 1 谢谢@Thanks!
lfm333 + 1 + 1 谢谢@Thanks!
hanlaoshi + 1 + 1 谢谢@Thanks!
Bizhi-1024 + 1 用心讨论,共获提升!
bkzkdetevh + 1 + 1 我很赞同!
夫子点灯 + 1 谢谢@Thanks!
chensu686 + 1 + 1 谢谢@Thanks!
weiguoshun + 1 热心回复!
Quanta + 1 谢谢@Thanks!
lgc81034 + 1 谢谢@Thanks!
raycerlane + 1 + 1 谢谢@Thanks!
夜步城 + 1 + 1 来巩固一下知识

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

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

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

免费评分

参与人数 1吾爱币 +1 热心值 +1 收起 理由
luodeman + 1 + 1 谢谢@Thanks!

查看全部评分

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

几个亿不会有问题,几十亿不好说
灭寂丶 发表于 2022-3-27 23:25
异常马粥 发表于 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
不会汇编的我,看的津津有味
k288 发表于 2022-3-28 02:15
写得很不错,虽然对于程序代码不太了解
意决于心 发表于 2022-3-28 02:20
太牛了,羡慕
cyhcuichao 发表于 2022-3-28 03:17
大佬这工具能发下吗?
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则 警告:本版块禁止灌水或回复与主题无关内容,违者重罚!

快速回复 收藏帖子 返回列表 搜索

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-4-20 23:54

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表