Breeze 配合 IDA 修改游戏逻辑
2024-03-17 17:33:41

上一次 学习了如何制作金手指文件。不过那个例子是改的游戏数据而非代码,这次学习如何修改游戏代码。

查找游戏数据

还是以塞尔达传说:旷野之息为例。游戏信息:

1
2
TID:01007EF00011E000
BID:8E9978D50BDD20B4

这次修改精力值,因为精力值不显示具体的数字,所以需要用模糊搜索。Breeze 中的模糊搜索功能是 Memory Dump。
模糊搜索过程就不细讲了,无非就是让林克跑动一下让精力值不停变化、查找,如此循环。。。
最后确认精力数据地址:

1
2
当前精力:heap + A74F9EDC
最大精力:heap + A74F9EE0

数据类型为float,占 4 字节。测试发现每一圈精力值对应值是 1000。那么在这个游戏中精力最大为三圈,也就是 3000。
虽然我们可以锁定这个值达到无限精力的目的,但是直接改数据会造成精力圈闪烁,游戏体验不好。
我期望的是跑步时不会出现精力圈,也就是修改游戏逻辑,让跑步所消耗的精力为零。

查找数据写入位置

利用 Breeze 的断点功能,对精力值位置 heap + A74F9EDC 处设置写入断点

回到游戏,跑动一下减少精力值,再切回修改器。发现一处写入位置 main + 0x00F70024

虽然 Breeze 中也可以看到汇编代码,但是远不如 IDA 显示的多,操作起来也不方便。

所以我们需要到 IDA 中来查看相关代码。

提取游戏 NSO 文件

NSO 文件类似于 Windows 系统上的 EXE/DLL 文件,其中包含着游戏逻辑代码。我们需要提取出来然后在 IDA 中查看它。
准备工具:

  1. 游戏文件管理工具 NSGame Manager。用于提取游戏NSO文件。
  2. IDA 插件 SwitchIDAProLoader。用于静态分析NSO文件。

在 NSGame Manager 中加载游戏文件(nsp、xci),找到版本最新且 ROM 为 UPD 的包(对于没有补丁的游戏那就只有一个 ROM 为 APP 的包),选择右侧“工具”页面,然后选择容量最大的 NCA,点击“提取并解包NCA”即可,如图:

会提取出一个没有扩展名的名为main的文件,它就是 NSO 文件。用 SwitchIDAProLoader 插件加载它

分析程序

前面分析发现写入精力的地方是 main + 0x00F70024。我们在 IDA 中来到偏移 0x00F70024 的地方。可以看到汇编代码和 Breeze 捕捉到的地方是一样的,说明找对地方了。

此时用 IDA 强大的 F5 还原成伪代码

把这条语句 NOP 掉就可以达到锁定精力值的目的了。但有个不算是问题的问题,精力值虽然不会减少,但也不会增加,而我希望可以恢复精力,而不减少精力。
接着就是在 IDA 中静态分析这个函数,同时在 Breeze 中修改指令。来回几轮测试后找到关键语句:

精力是从这个地址取的,是一个固定的地址

1
qword_7102CA1140 + 0xA4

所以,精力的金手指格式就是

1
[main + 2CA1140] + 0xA4

写入精力值这一行代码在偏移 0x00F6FF50 处,看看汇编代码

将汇编改为 fmov s8, s0可以避免进行减法操作

现在可以制作金手指了。注意,金手指中的机器码要用大端方式。可以在 ARM to HEX Converter 这样的网站中计算转换后的机器码。
勾选右上角,以大端方式转换。

最终金手指文件如下:

1
2
3
4
5
[精力不减 开]
04000000 00F6FF50 1E204008

[精力不减 关]
04000000 00F6FF50 1E202908

相关资料

使用Breeze在switch实机上对游戏进行汇编修改