吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 21675|回复: 90
收起左侧

[Android 原创] 某unity游戏逆向破解

    [复制链接]
yellowtail 发表于 2022-5-3 16:42
本帖最后由 yellowtail 于 2022-5-4 09:37 编辑

背景

最近把论坛里一些 unity 游戏的破解帖子看完后,自己也想试一试,于是在各种找游戏,最后找到了一个 xx不高兴 的 rougelike 游戏,尝试了两天,效果还可以,分享一下一些步骤的经验

apk 获取

如果能下载到是最好的,下载不到可以先用模拟器安装,再导出来,比如雷电模拟器

国外的可以用 apkpure
或者 apps.evozi

1. 运行时判断

解压apk之后看一下一些关键目录

  • lib
  • assets\bin\Data\Managed

    如果assets\bin\Data\Managed 出现了 Assembly-CSharp.dll,那么说明是mono类型的,游戏逻辑就在 Assembly-CSharp.dll 和其它同路径下的文件里,此时用 dnspy 逆向

    如果没有看到Assembly-CSharp.dll, 但是在 lib 下看到了 libil2cpp.so 那么说明运行时是 IL2CPP,需要使用 Il2CppDumper + ida + 其它 逆向

这个游戏是 IL2CPP 的,所以接下来我使用的是 Il2CppDumper

2. Il2CppDumper 提取函数签名

执行命令

Il2CppDumper.exe libil2cpp.so global-metadata.dat output

这里需要注意的是,有时候apk解压之后,lib里有多个目录,如

folder

folder
应该选择哪个呢

可以去网上搜索,看一下分别是啥意思,我的思路比较简单粗暴,直接去模拟器里看一下文件 hash

cd /data/data/{包名}/lib
sha1sum *

再和电脑上的文件sha1 做对比,就知道模拟器里的文件是哪一个了

Il2CppDumper 执行之后,得到了一些输出文件

  • dump.cs
    c#类和方法的签名和偏移,无具体代码
  • script.json
    可以导入到ida,进行方法名关联
  • il2cpp.h
    可以导入到ida,进行结构体关联

3. ida 导入、关联

libil2cpp.so 拖到 ida里,等ida 识别完(很慢),再执行 srcipt file -> ida_py3.py -> script.json 进行函数关联

因为ida 分析很慢,此时可以进入到下一步

4. 找到切入点

拿到了各种文件之后,从哪里开始分析呢?

比如这款游戏,有金币、血量hp、技能、伤害数值显示等元素(玩一下就知道了),那么关键字有

  • 金币
    gold、money、jinbi(拼音)等
  • 技能
    skill、 cool、 coolDown 、 cd、reload、buff 等
  • 伤害
    damage、damageValue、hit、attack 等
  • 血量
    hp、mp、maxHp 等

5. 技能cd

比如,我用 cooldown 搜索,就找到了这么一个 文件 SkillComponent

cooldown

cooldown

skill-component

skill-component

里面有

  • GetSkillRemainCD, 剩余cd时间
  • IsSkillCoolDown, 技能是否冷却

这两个,我尝试过去修改 return 的值,发现不生效,不知道为什么,所以继续寻找

对于 damage ,搜索了一下有800多,一个一个地看不现实,看一下头和尾,中间随便看看,在末尾发现了有意思的

damage-head

damage-head

damage-tail

damage-tail

showDamageTips 顾名思义,是显示伤害数值的,那么附近肯定会计算伤害值,再传入到这个方法进行显示

6. 伤害显示

showDamageTips 搜了一下有5个,看后面两个就行

tips-all

tips-all

// RVA: 0x15F038C Offset: 0x15F038C VA: 0x15F038C
public static void ShowDamageTips(DamageResult damageResult) { }

// RVA: 0x15F03F8 Offset: 0x15F03F8 VA: 0x15F03F8
public static void ShowDamageTips(Character entity, int value) { }

第二个,进去看了一下,没什么信息,汇编修改一下入参,没有效果;再看一下 xref (在IDA 里右键,x 可以看到xref),看到了 modifyHp,记下来

tips-xref

tips-xref

第一个,进去看了一下,没什么信息,汇编修改一下入参,改为定值,255,有效果,说明逻辑在这附近

tips-change

tips-change
有两个分支,都需要改,以修改绿色那一行为例举例说明

il2cpp:015F03D4 14 20 94 E5                   LDR             R2, [R4,#0x14]              // 把 r4+0x14 的值复制到 r2 上,r2 就是方法的参数 value
il2cpp:015F03D8 00 00 52 E3                   CMP             R2, #0                      // 比较 r2 和0的大小
il2cpp:015F03DC 04 00 00 0A                   BEQ             locret_15F03F4              // r2==0 的话,跳到 locret_15F03F4,就在下面,不是继续执行
il2cpp:015F03DC
il2cpp:015F03E0 0C 10 94 E5                   LDR             R1, [R4,#0xC]                                        
il2cpp:015F03E4 05 00 A0 E1                   MOV             R0, R5
il2cpp:015F03E8 00 30 A0 E3                   MOV             R3, #0                                                
il2cpp:015F03EC 30 48 BD E8                   POP             {R4,R5,R11,LR}
il2cpp:015F03F0 6C B8 1A EA                   B               Unhappy.HudManager$$ShowHud   // 参数构造好了,去执行
il2cpp:015F03F0
il2cpp:015F03F4                               ; ---------------------------------------------------------------------------
il2cpp:015F03F4
il2cpp:015F03F4                               locret_15F03F4                          // r2==0 的时候,跳到这里
il2cpp:015F03F4 30 88 BD E8                   POP             {R4,R5,R11,PC}

改为定值就是 把 LDR   R2, [R4,#0x14] 改为 mov r2,#255 就可以,

用 网站 armconverter  转换一下

arm2hdex

arm2hdex

16 进制就是 FF 20 A0 E3
用 010Editor 修改一下,打包、签名、安装运行,有效果,不过是自欺欺人的,不管打出多少的伤害都显示255  

255

255

自欺欺人不是我想要的结果,接续分析
看一下 xref,有好几个引用,有一块代码看起来比较像,在这里改了好久,一直没有效果,放弃

代码位置是 int __fastcall Unhappy_BuffResultSkillChargeBeDamagedFeedBack__OnTriggerFeedBack(int a1, _DWORD *a2, int damageValue)

code-1

code-1

7. 修改血量更新的逻辑(失败)

再回头看一下之前找到的 modifyHp,顾名思义,应该是战斗中更新血量的地方,加血、扣血什么的,如果我们一下子把血量扣完,是不是就可以秒杀了(实际是我失败了)
搜一下,有两个地方

modify-hp

modify-hp

其中第二个看名字应该是对第一个的包装,

两个都看了一下,第二个也是调用的第一个,那就着重看第一个

// RVA: 0x1870400 Offset: 0x1870400 VA: 0x1870400
public void ModifyHP(Character entity, int delta, bool isShowTips, int casterGID = 0) { }

hp-code

hp-code

      Unhappy_AttrManager__SetHP(a1, a2, v15[0] + a3, a5);// 设置hp
      if ( a4 )
        Unhappy_FightUtility__ShowDamageTips_23004152(a2, -a3);// 显示伤害信息

进去 setHp 看一下

sethp.png

大概意思是 先从 SpecialAttrManager 取出一个什么属性,再做对比,再操作什么的(这里改了没效果,过程就不写了)

既然有一个什么数据是从 SpecialAttrManager 取出来的, 那就看一下 SpecialAttrManager 里面有什么东西

special

special

可以看到

  • GetFinalMaxHP
    - GetFinalMoveSpeed

    一个是最大hp,一个是移动速度

8. 设置 maxHp

maxHp 顾名思义,应该是战斗初始化的时候,设置最大血量的
先改一下 GetFinalMaxHP 试一下

签名为

// RVA: 0x1EC2A64 Offset: 0x1EC2A64 VA: 0x1EC2A64
private static int GetFinalMaxHP(Dictionary<AttrType, int> attrs) { }

ida 按G 跳到  0x1EC2A64, F5 看一下代码

max

max

int __fastcall Unhappy_SpecialAttrManager__GetFinalMaxHP(int a1, int a2, int a3)
{
  int Attr; // r5
  int v5; // r2
  __int64 v6; // kr10_8

  Attr = Unhappy_SpecialAttrManager__GetAttr(a1, 3, a3);
  v6 = Unhappy_SpecialAttrManager__GetAttr(a1, 4, v5) + 10000LL;
  v7 = v6 * Attr / 10000;
  return Math.max(1, v7);
}

结果是 1和 v7 的最大值,那我们可以把 v7 给改掉
注意,我们这里不用改 v7,改了没有意义,我们改的应该是 传给 max 函数的第二个入参,也就是寄存器 R1

所以把 01EC2AB8 00 10 A0 E1                   MOV             R1, R0
改为 20 10 A0 E3  mov r1, #x21,   0x21 是我瞎写的,10进制是 33

maxhp-arm

maxhp-arm

maxhp-code

maxhp-code

改了之后,有效果了,效果是:

  • 怪物最大 hp 为 33,boss 也是
  • 主角最大hp 是33,不过可以选技能,如盾牌、护盾什么的,所以虽然只有33点血,但是被打几下没事的
  • 主角血量其实是两条,上面黄色的是护盾值,优先掉这个,掉完了才掉下面的血量(33滴血)
  • 因为主角的初始是伤害是50,所以 没有一个 怪物顶得住(有盾牌的怪物除外),怪物被打到就是死,boss 一样

因为英雄先进场景,怪物后刷出来,所以基本有惊无险,快速通关

大家也可以把血量改为其它值,看看效果

附几张图

boss血量

boss血量

boss-2.png
boss-3.png

免费评分

参与人数 28威望 +2 吾爱币 +126 热心值 +26 收起 理由
A-tom + 1 我很赞同!
流浪的猫 + 1 用心讨论,共获提升!
gunxsword + 1 + 1 热心回复!
shadowfalI + 1 我很赞同!
split1130 + 1 + 1 写的嘎嘎好
wangchanchan + 1 + 1 我很赞同!
叮当东东当当 + 1 + 1 谢谢@Thanks!
bjznhxy + 1 + 1 我很赞同!
zhx79 + 1 + 1 用心讨论,共获提升!
Conight + 1 + 1 我很赞同!
TonyKing + 1 热心回复!
towser + 1 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
procurve + 1 + 1 谢谢@Thanks!
fengbolee + 2 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
MHCANDHS + 1 + 1 我很赞同!
gaosld + 1 + 1 谢谢@Thanks!
4nfu + 1 + 1 热心回复+我很赞同!
MatrixLau + 1 + 1 谢谢@Thanks!
yxpp + 1 + 1 谢谢@Thanks!
jolin7714 + 1 + 1 热心回复!
鹤舞九月天 + 1 + 1 谢谢@Thanks!
CChilde + 1 + 1 我很赞同!
bobo53051 + 1 + 1 谢谢@Thanks!
夜步城 + 1 + 1 我很赞同!
kakaxi0071 + 1 + 1 我很赞同!
LoveHack + 1 + 1 我很赞同!
Quanta + 1 + 1 热心回复!
qtfreet00 + 2 + 100 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!

查看全部评分

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

 楼主| yellowtail 发表于 2022-5-10 10:08
bobo53051 发表于 2022-5-10 00:22
你用的什么打包和签名软件   我用的apk.2.6.1打包  用的MT管理器签名V1+V2    进不了游戏

因为是 unity 游戏,不改java代码,所以没必要用 apktool, 直接 zip 解压就行

改好文件,再zip压缩(注意ida 临时文件),用 MT 签名,

我是在模拟器里运行的,所以签名用的 V1 ,

你可以参考我的步骤,试一下
Noren 发表于 2022-5-5 21:55
zdell 发表于 2022-5-5 22:26
pincers 发表于 2022-5-7 20:45
感谢分享
Ghy410 发表于 2022-5-8 00:07
感谢分享学到了
Quanta 发表于 2022-5-8 02:40
学习了 感谢分享
sji 发表于 2022-5-8 11:27
学习了 感谢分享
kakaxi0071 发表于 2022-5-8 12:32
楼主.cs文件你是用什么工具查看呢
 楼主| yellowtail 发表于 2022-5-8 15:59
kakaxi0071 发表于 2022-5-8 12:32
楼主.cs文件你是用什么工具查看呢

就是 notepad++

2022-05-08_15-58.png
 楼主| yellowtail 发表于 2022-5-8 20:32
kakaxi0071 发表于 2022-5-8 12:32
楼主.cs文件你是用什么工具查看呢

2022-05-08_15-58.png
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

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

GMT+8, 2024-11-21 19:48

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

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