准备工具以及思路
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
{
public void .ctor();
public void writeAllRoleStats(XmlWriter xmlWriter);
public void readToRoleDic(XmlNode xmlNode);
private void addDataString(string origin, string add);
public BasicPlayerData get_CurrentBPData();
public int get_playerLevel();
public void set_playerLevel(int value);
public int get_playerXp();
public void set_playerXp(int value);
public int get_nextXpLevel();
public void set_nextXpLevel(int value);
public int get_maxHealth();
public void set_maxHealth(int value);
public int get_currentHealth();
public void set_currentHealth(int value);
public int get_strengthByLevelUp();
public void set_strengthByLevelUp(int value);
public int get_velByLevelUp();
public void set_velByLevelUp(int value);
public int get_staminaByLevelUp();
public void set_staminaByLevelUp(int value);
public int get_dexterityByLevelUp();
public void set_dexterityByLevelUp(int value);
public int get_mp();
public void set_mp(int value);
public int get_maxMp();
}
还有一个叫GodManager的类= = 我猜是GM方便自己的
public class GodManager : NBMng
{
public void .ctor();
public bool get_ShowAllMap();
public bool get_OpenAllEquip();
public int get_SurviveWave();
public string get_enemyName();
public int get_testMapId();
private void Start();
public override void abs_init();
public override void abs_whenAllMngLoaded();
private void test();
private void Update();
}
方法后面的注释就是方法对应的地址,至于为什么是那个方法= = 看的懂英语就行
当然这里面肯定还有能修改以达到破解目的不过我没发现的方法,大家可以自己尝试
IDA中分析如何修改libil2cpp.so
先附上两篇修改教程
Unity3D--Il2Cpp修改教程--二
这篇教程里已经说了如何修改此游戏的等级我就不在赘述【修改魔力的方法几乎可以说也一样】
UNITY3D Il2Cpp修改教程《电子机器人杀人事件》
因为我自己对ARM也不熟不是很会分析代码,就给大家说一下自己的理解
修改最大血量
可以从上面找函数的图中看到
public int get_maxHealth();
打开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;
v0 = (loc_46564C)();
if ( !v0 )
{
(loc_C186B4)();
JUMPOUT(&loc_477490);
}
return *(v0 + 56);
}
IDA里面伪代码窗口右键 按 Copy to assembly 就会把伪代码和ARM对应起来
出现下图的效果
.text:00467074 STMFD SP!, {R11,LR}
.text:00467078 MOV R11, SP
.text:0046707C
.text:0046707C BL loc_46564C
.text:00467080
.text:00467080 CMP R0, #0
.text:00467084
.text:00467084 LDRNE R0, [R0,#0x38]
.text:00467088 LDMNEFD SP!, {R11,PC}
.text:0046708C
.text:0046708C BL loc_C186B4
.text:00467090
.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
.text:0046707C
.text:00467080 CMP R0, #0
.text:00467084 NOP
.text:00467084
.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;
}
在010editer中修改并保存
打开IDA的HEX窗口 按G跳转到 之前修改过的命令的地址
比如之前修改了
.text:0046707C MOV R0, #0x270F

可以看到被我们修改过的指令对应的HEX都变成了棕色
打开010eidter 按 ctrl+g 跳转到对应地址

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

修改解锁武器
public bool get_OpenAllEquip();
所以IDA中跳转到 0x6138EC 代码如下
.text:006138EC sub_6138EC
.text:006138EC
.text:006138EC MOV R1, R0
.text:006138F0 MOV 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
.text:0061390C BX LR
.text:0061390C
伪代码
signed int __fastcall sub_6138EC(int a1)
{
int v1;
signed int result;
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();
修改后如下
.text:006138EC sub_6138EC
.text:006138EC
.text:006138EC MOV R1, R0
.text:006138F0 NOP
.text:006138F0
.text:006138F4 LDRB R2, [R1,#0xC]
.text:006138F8 CMP R2, #0
.text:006138FC BXEQ LR
.text:00613900 NOP
.text:00613900
.text:00613904 NOP
.text:00613904
.text:00613908 MOV R0, #1
.text:00613908
.text:0061390C BX LR
.text:0061390C
signed int __fastcall sub_6138EC(signed int result)
{
if ( *(_BYTE *)(result + 12) )
result = 1;
return result;
}
然后和修改血量同理在010中修改保存就行
现实地图和这个的修改方式一样不再赘述
替换修改的So文件进安装包
最后一步没啥讲的,怎么解压出来的怎么替换进去
看来还是需要签名的,用Androidkiller签一下名就行了
成品地址:https://www.52pojie.cn/thread-818591-1-1.html