吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 51443|回复: 129
收起左侧

[Android 原创] U3D游戏《东方新世界》Il2Cpp破解详细教程

    [复制链接]
CrazyNut 发表于 2018-11-10 17:50
本帖最后由 CrazyNut 于 2018-11-10 23:57 编辑

准备工具以及思路

1.il2cpp反编译工具il2cppdumper
2.010Editor
3.IDA Pro 7.0 绿色版
4.带语言高亮的记事本比如 Notepad++
5.一款支持打开APK的解压工具就行
6.一款U3Dil2cpp打包的游戏

思路:利用il2cppDumper获取到关键函数的地址后,使用IDA找到关键函数,分析汇编语言逻辑后,利用010Editor进行16进制文件编辑来实现修改。

判断是否是U3Dil2cpp打包的游戏

看到这个目录下有libil2cpp.so就是咯

此处注意:我们只分析armeabi-v7a文件夹下的libil2cpp.so,x86为intel架构,用模拟器测试要把x86这个文件夹删掉!不然修改不起作用

il2cppdumper的使用

将il2cpp.so连同assets\bin\Data\Managed\Metadata 目录下的global-metadata.dat 文件一起放进il2cppDumper目录。

运行il2cppDumper.exe,第一步,选择il2cpp.so

第二步,选择global-metadata.dat

进入到il2cppDumper控制台界面,这里按一下3就行

然后就会得到Dump.cs,包含关键函数的偏移信息

寻找关键函数

至于怎么寻找,我也没什么好方法,只能去猜测GameMaker会给什么样的方法名

比如血量可以搜索HP,health这种关键词,魔力值搜索MP,金钱搜索Money等

我通过多次搜索找到了PlayerStats的类,里面包含了很多玩家信息

public class PlayerStats // TypeDefIndex: 3306              //玩家信息
{
        // Methods
        public void .ctor(); // 0x473A24
        public void writeAllRoleStats(XmlWriter xmlWriter); // 0x473BC4
        public void readToRoleDic(XmlNode xmlNode); // 0x474AC0
        private void addDataString(string origin, string add); // 0x47557C
        public BasicPlayerData get_CurrentBPData(); // 0x46564C
        public int get_playerLevel(); // 0x469114                            //获取玩家等级
        public void set_playerLevel(int value); // 0x469140
        public int get_playerXp(); // 0x467024                   //获取玩家经验
        public void set_playerXp(int value); // 0x4690B4
        public int get_nextXpLevel(); // 0x4690E8               //获取玩家升级所需经验
        public void set_nextXpLevel(int value); // 0x469174
        public int get_maxHealth(); // 0x467074               /获取玩家最大血量
        public void set_maxHealth(int value); // 0x47571C
        public int get_currentHealth(); // 0x467050           //获取玩家当前血量
        public void set_currentHealth(int value); // 0x4676E8
        public int get_strengthByLevelUp(); // 0x475744          //获取力量值,其实就是攻击
        public void set_strengthByLevelUp(int value); // 0x475770
        public int get_velByLevelUp(); // 0x4757A4               //获取移动速度
        public void set_velByLevelUp(int value); // 0x4757D0
        public int get_staminaByLevelUp(); // 0x475804           //获取体力值,其实就是血量
        public void set_staminaByLevelUp(int value); // 0x475830
        public int get_dexterityByLevelUp(); // 0x475864
        public void set_dexterityByLevelUp(int value); // 0x475890
        public int get_mp(); // 0x467098
        public void set_mp(int value); // 0x467710
        public int get_maxMp(); // 0x4670BC                    //获取最大魔力值
        }

还有一个叫GodManager的类= = 我猜是GM方便自己的

public class GodManager : NBMng // TypeDefIndex: 3469
{
        // Methods
        public void .ctor(); // 0x6137C0
        public bool get_ShowAllMap(); // 0x6138C8  //开图
        public bool get_OpenAllEquip(); // 0x6138EC //解锁武器
        public int get_SurviveWave(); // 0x613910
        public string get_enemyName(); // 0x613928
        public int get_testMapId(); // 0x6139F0
        private void Start(); // 0x613A08
        public override void abs_init(); // 0x613A0C
        public override void abs_whenAllMngLoaded(); // 0x613A98
        private void test(); // 0x613A9C
        private void Update(); // 0x613B58
}

方法后面的注释就是方法对应的地址,至于为什么是那个方法= = 看的懂英语就行

当然这里面肯定还有能修改以达到破解目的不过我没发现的方法,大家可以自己尝试

IDA中分析如何修改libil2cpp.so

先附上两篇修改教程

Unity3D--Il2Cpp修改教程--二
这篇教程里已经说了如何修改此游戏的等级我就不在赘述【修改魔力的方法几乎可以说也一样】

UNITY3D Il2Cpp修改教程《电子机器人杀人事件》

因为我自己对ARM也不熟不是很会分析代码,就给大家说一下自己的理解

修改最大血量

可以从上面找函数的图中看到

public int get_maxHealth(); // 0x467074              //获取玩家最大血量

打开IDA拖入libil2cpp.so

按G跳转到对应地址  血量  0x467074

.text:00467074                 STMFD           SP!, {R11,LR}
.text:00467078                 MOV             R11, SP
.text:0046707C                 BL              loc_46564C
.text:00467080                 CMP             R0, #0
.text:00467084                 LDRNE           R0, [R0,#0x38]
.text:00467088                 LDMNEFD         SP!, {R11,PC}
.text:0046708C                 BL              loc_C186B4
.text:00467090                 MOV             LR, PC
.text:00467094                 B               loc_477490

按下F5看一下伪代码

int sub_467074()
{
  int v0; // r0

  v0 = (loc_46564C)();
  if ( !v0 )
  {
    (loc_C186B4)();
    JUMPOUT(&loc_477490);
  }
  return *(v0 + 56); 
    // 可以看到这里最后返回了一个INT 
        //既然这个方法是 get_maxHealth,返回值肯定就是最大血量
        //所以我们只需要修改返回值就行
}

IDA里面伪代码窗口右键 按 Copy to assembly 就会把伪代码和ARM对应起来
出现下图的效果

.text:00467074                 STMFD           SP!, {R11,LR}
.text:00467078                 MOV             R11, SP
.text:0046707C ; 4:   v0 = (loc_46564C)();
.text:0046707C                 BL              loc_46564C           //可以在这里给R0的值进心修改
.text:00467080 ; 5:   if ( !v0 )
.text:00467080                 CMP             R0, #0
.text:00467084 ; 10:   return *(v0 + 56); //这里可以看出来下面两句就在返回,而ARM中返回值一般是R0,我们在上面给R0一个自己想要的值就行
.text:00467084                 LDRNE           R0, [R0,#0x38]  //将R0+#0x38赋值给R0 ,我们把这句给 NOP 掉                                              
.text:00467088                 LDMNEFD         SP!, {R11,PC}
.text:0046708C ; 7:     (loc_C186B4)();
.text:0046708C                 BL              loc_C186B4
.text:00467090 ; 8:     JUMPOUT(&loc_477490);
.text:00467090                 MOV             LR, PC
.text:00467094                 B               loc_477490

IDA中点击想修改的命令按ctrl+alk+K就可以直接修改指令

修改完成后的效果

.text:00467074                 STMFD           SP!, {R11,LR}
.text:00467078                 MOV             R11, SP
.text:0046707C                 MOV             R0, #0x270F ; Keypatch modified this from:
.text:0046707C                                         ;   BL loc_46564C
.text:00467080                 CMP             R0, #0
.text:00467084                 NOP                     ; Keypatch modified this from:
.text:00467084                                         ;   LDRNE R0, [R0,#(stru_273C.st_size+3 - 0x270F)]
.text:00467088                 LDMNEFD         SP!, {R11,PC}
.text:0046708C                 BL              loc_C186B4
.text:00467090                 MOV             LR, PC
.text:00467094                 B               loc_477490

伪代码

signed int sub_467074()
{
  return 9999;    //现在直接就返回9999,血量就算修改好了
}

在010editer中修改并保存

打开IDA的HEX窗口 按G跳转到 之前修改过的命令的地址   

比如之前修改了

.text:0046707C                 MOV             R0, #0x270F ;  //下图就跳转到0046707C 

可以看到被我们修改过的指令对应的HEX都变成了棕色

打开010eidter  按 ctrl+g 跳转到对应地址

然后改成和IDA中一样的保存就行

修改解锁武器

public bool get_OpenAllEquip(); // 0x6138EC //解锁武器

所以IDA中跳转到 0x6138EC   代码如下

.text:006138EC sub_6138EC                              ; CODE XREF: .text:006EF8B4↓p
.text:006138EC                                         ; DATA XREF: .data.rel.ro:00EA0CD0↓o
.text:006138EC                 MOV             R1, R0
.text:006138F0                 MOV             R0, #0              //r0 = 0 
.text:006138F4                 LDRB            R2, [R1,#0xC]
.text:006138F8                 CMP             R2, #0
.text:006138FC                 BXEQ            LR
.text:00613900                 LDRB            R0, [R1,#0x25]
.text:00613904                 CMP             R0, #0
.text:00613908                 MOVNE           R0, #1     //通过上面的判断 决定是否让R0=1
.text:0061390C                 BX              LR
.text:0061390C ; End of function sub_6138EC

伪代码

signed int __fastcall sub_6138EC(int a1)
{
  int v1; // r1
  signed int result; // r0

  v1 = a1;
  result = 0;
  if ( *(_BYTE *)(v1 + 12) )
  {
    result = *(unsigned __int8 *)(v1 + 37);
    if ( *(_BYTE *)(v1 + 37) )
      result = 1;
  }
  return result;
}
public bool get_OpenAllEquip(); // 0x6138EC 
//通过这个可以知道 返回值是一个bool
//而上面伪代码的返回值却是一个INT
//这个时候用屁股就应该想到0代表False而1代表True
//所以我们需要把返回值也就是R0改成1

修改后如下

.text:006138EC sub_6138EC                              ; CODE XREF: .text:006EF8B4↓p
.text:006138EC                                         ; DATA XREF: .data.rel.ro:00EA0CD0↓o
.text:006138EC                 MOV             R1, R0
.text:006138F0                 NOP                     ; Keypatch modified this from:
.text:006138F0                                         ;   MOV R0, #0
.text:006138F4                 LDRB            R2, [R1,#0xC]
.text:006138F8                 CMP             R2, #0
.text:006138FC                 BXEQ            LR
.text:00613900                 NOP                     ; Keypatch modified this from:
.text:00613900                                         ;   LDRB R0, [R1,#0x25]
.text:00613904                 NOP                     ; Keypatch modified this from:
.text:00613904                                         ;   CMP R0, #0
.text:00613908                 MOV             R0, #1  ; Keypatch modified this from:
.text:00613908                                         ;   MOVNE R0, #1
.text:0061390C                 BX              LR
.text:0061390C ; End of function sub_6138EC
signed int __fastcall sub_6138EC(signed int result)
{
  if ( *(_BYTE *)(result + 12) ) //这个判断其实也可以nop掉   已经没用了
    result = 1;            //反正下面 让返回值 为1 返回的为TRUE就行
  return result;
}

然后和修改血量同理在010中修改保存就行
现实地图和这个的修改方式一样不再赘述

替换修改的So文件进安装包

最后一步没啥讲的,怎么解压出来的怎么替换进去

看来还是需要签名的,用Androidkiller签一下名就行了

成品地址:https://www.52pojie.cn/thread-818591-1-1.html



**有兴趣的自己去改攻击力魔力什么的   有帮助到你给个免费评分噢 谢谢**[/md]

免费评分

参与人数 30吾爱币 +31 热心值 +27 收起 理由
zerglurker + 1 + 1 我很赞同!
千百度° + 1 用心讨论,共获提升!
lily2997 + 1 + 1 热心回复!
kang061369 + 1 我很赞同!
sunnylds7 + 1 + 1 热心回复!
Justin_filed + 1 我很赞同!
天涯星客 + 1 + 1 我很赞同!
cdr007 + 1 + 1 谢谢@Thanks!
693613898 + 2 + 1 我很赞同!
章魚葛格 + 1 新技能get。。。雖然還沒搞懂(滑稽)
onething + 1 + 1 热心回复!
z14mian + 1 + 1 我很赞同!
ltr0030 + 1 + 1 我很赞同!
gongyong728125 + 1 + 1 谢谢@Thanks!
SoHuDrgon + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
peter336620 + 1 + 1 我很赞同!
dozx + 1 + 1 谢谢@Thanks!
审判者压缩 + 1 + 1 热心回复!
Towneast + 1 + 1 谢谢@Thanks!
dream_hat + 1 + 1 我很赞同!
Scien辉煌 + 1 谢谢@Thanks!
好难注册呀 + 1 + 1 用心讨论,共获提升!
漫漫羽化 + 1 + 1 用心讨论,共获提升!
lzc090 + 3 + 1 我很赞同!
soyiC + 1 + 1 谢谢@Thanks!
diberway + 1 谢谢@Thanks!
singhou + 1 + 1 热心回复!
1000Y + 1 + 1 用心讨论,共获提升!
lin_xop + 1 + 1 热心回复!
╰Tang + 2 + 1 用心讨论,共获提升!

查看全部评分

本帖被以下淘专辑推荐:

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

 楼主| CrazyNut 发表于 2018-11-12 01:24
txf446989400 发表于 2018-11-11 13:57
COCOS2djs.so 你有办法能获得包含关键函数的偏移信息吗?

这个都不是u3d的游戏= = 我没去了解过- - 不过似乎还是有这个东西的反编译工具
txf446989400 发表于 2018-11-12 12:34
CrazyNut 发表于 2018-11-12 01:24
这个都不是u3d的游戏= = 我没去了解过- - 不过似乎还是有这个东西的反编译工具

有吗?我没找到,你有的话能不能发给我一份,万分感谢!!
头像被屏蔽
╰Tang 发表于 2018-11-10 20:51
 楼主| CrazyNut 发表于 2018-11-10 21:09
╰Tang 发表于 2018-11-10 20:51
辛苦了,大佬终于编辑完了

试了下那个MarkDown编辑器 不是很好用
Windows10 发表于 2018-11-10 22:25
感谢分享教程
cqom 发表于 2018-11-10 23:12
这个必须顶
pananhui 发表于 2018-11-10 23:58
辛苦了,大佬终于编辑完了
天地任纵横 发表于 2018-11-11 07:40
感谢分享
fengzhi-1 发表于 2018-11-11 08:11
感谢分享
yangkim126 发表于 2018-11-11 09:07
受教了,虚心学习
wzlazjt 发表于 2018-11-11 09:31
路过帮大神顶一下。。。。
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

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

GMT+8, 2024-12-22 16:22

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

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