Site icon 时鹏亮的Blog

Switch 金手指制作教程三:如何使用 GDB 找出 敌我判断 的特征

请知悉:本文最近一次更新为 3年 前,文中内容可能已经过时。

以下内容完整转载自:Eiffel2018 原创发布:【金手指教程2】使用 GDB 找出 敌我判断 的特徵

继续上次 未完的教程

之前调试发现, 把 main+D2058 改成 NOP, 会令到敌我皆变成 HP不减, 需要进行 敌我判断


基本概念

何谓 敌我判断 ?

游戏开发者在同一个函式, 同时处理我方及敌人的属性。

我们要找出特征, 来分辨 处理中的对象 是我方 还是敌人。

我试用过的解决方法有很多种, 记得的有

1) 用 pointer 指针 可以很轻易的解决, 但每个金手指只能针对单一角色处理, 如果角色多了,有时会变成一个很大的文件。

2) 分析 我方和敌方角色的内存附近范围内容, 做对比, 试验, 找出 程序内建的判别方法 Flag

3) 查看扣减HP的共用函式的寄存器 [X0] 最初的地址, 通常这个就是角色对象的类 Object Class, 敌我所用的Class很多时是不同的, 而且偏移0的 [X0] 是 object地址的最末三个数字 会是固定的。

4) 以上皆不可行时,便要用GDB追踪程序的运行,看看有没有判断敌我的程序 (经常可以看到HP0之后死亡的处理,敌我肯定不一样的)

5) 利用开发引擎的特性进行破解, 例如 Unity的il2cpp 或是 Unreal Engine以函式地址找寻函式的本来名称, 都可以对找出敌我判断大有帮助。

6) 如果你真的找不到, 或许看看 外网 fearless 上 Cheat Engine 的高手 破解PC版本的相同游戏 是怎样分辨敌我的, 虽然平台不同,处理器也不同, 但代码往往是大同小异的!

游戏需要敌我判断, 真的太多了, 真不记得某个游戏用哪一种手法.不用问了


回归正题, 上一次女勇者变成了无敌之后, 竟然打不倒敌人,

先查看一下两边的内存。

女勇者的内存位址,我是知道的,

就是刚才下断点的 heap:00000024B02F1490 附近

因为该句指令是 [x19,#8]

可以断定这内存的范围是 由 heap:00000024B02F1488 (即是X19) 开始。


然后我顺势把这区块中, 每一个变数 跟 游戏内 女勇者的数据 对比一下。

但战斗还没完, 逃跑吧, 退一步海阔天空…. 这样才看到女勇者的数据

LV3, HP29/29, ATK 18, DEF 12, SPD 9


在内存按n, 把知道的栏位添加名称

剩下最前的 1001 可能是经验, 也可能不是,

后面3个浮点数,暂时也不知是什么, 先不管了


之后我们要记录这个格式结构 define structure. 方便往后使用

选择范围, 滑鼠右击, Create Struct from Selection

按n 给个名称 actor

回到 IDA View-PC, 看到这对象被收起了

按 Ctrl + 便可打开, 变成这样


好了,现在要取得敌人的地址。

在刚才触发断点的地方, main+D2058 按 F2 加一个 software breakpoint (软件断点)

这 软件断点 跟 硬件断点 不同的地方,

就是这个只能在程式码下, 如果你在资料段下的话, 是不能触发的。

另一个特点是, 硬件断点最多只可下4个, 而这软件断点没有限制,只要你的电脑够强劲,下超过100个断点也不成问题.

(我有时就是会这样的,渔翁撒网,看看那一个函式会触发)

下好了F2, 就按F9让游戏继续跑了。


这 软件断点, 能捕捉打击敌人的刹那。

IDA 也停了下来, 不过刚才 main:D2058 原本是好端端的 NOP, 现在变成了 FF FF FF E7

这其实是 大气层GDBstub 的另一个小Bug. 那个地方更新时只用了8位元,而不是32位元,

但不要紧, 这不影响 SWITCH的运作,

如果你需要, 也可以关闭这断点之后, 更新内存 Refresh Memory

这便正常

但无论如何,你必须关闭断点,之后才能进一步操作

否则…. 这大气层会崩溃的, 小心!


刚刚我们让断点触发了.

敌人的内存在什么地方呢?

答案就是 [X19, #8]

在右边 暂存器X19 旁边的箭头点一下

这就是其中一个敌人的内存了


但今次我们不必人手把变数一个一个的改成十进制DoubleWord

因为我们之前定义了一个 Actor 的 物件结构 structure

用 Alt+Q 就可以了

又收起来了, 按 CTRL+ 把它扩张

这就看到了。


还是看不到 敌我分别?

再来一个, 把另一个敌人的内存位置也找出来

不过,你千万不要立刻打开刚才的断点,然后按F9

你需要把浮标(即是PC)移到下一行,才可再次启动之前那个软件断点 (这大气层新功能的缺陷,没办法了)

令PC跳去下一行,方法有几个:

你可以按F8或F7几下, 第一下通常会跳到SDK的区块的,要多按两三下才跳回main;

(这是因为SWITCH进程不是单一的, 而这大气层GDB, 暂时也不能只查看单一进程)

另一个方法是把鼠标移到下一行,然后按F4

这个方便, 我经常用的。

还有,你可以在右边 PC寄存器 上用滑鼠双击, 人手加上4 (像这样)

(不过要留意,你下断点那句,就不会执行了; 现在是NOP没所谓)

比较高阶的方法是在 断点设立时, 在condition 的位置输入 PC=PC+4;1

这就会自动帮你在触发断点时,前进下一个指令 (同样地,你下断点那句就不会执行了; 但你可以连 Break 也取消, 配合 msg 把想知道的东西,全记录下来)


无论如何, 你都可以找到另一个敌人的内存位置, 再 ALT+Q 套用 actor结构。

仍是看不出敌我特征? 把他们打横排列吧!

这很明显吧, 在第一行, 女主角是1001, 两个敌人是2031

这是什么呢? 这都是十进制数, 按道理这里并非 批次判断 的.

1001 / 2031 等, 很有可能是角色的ID 因为两个敌人都叫 苔玉蛙, 而ID相同是2031

按一般游戏规划角色或敌人ID都会分开的, 例如玩家角色是10XX , 敌人ID是由2000开始

暂时这只是推测,要进行多些游戏才知道结果。

不过我们现在已可以做一个敌我分办,

凡是角色是 1001 就是女主角小勇

先试一下吧

反正不试就卡在这里,双方HP不减, 无法继续游戏 (也要给我机会继续讲解啊)


由于刚才 触发点 只得一行 STR W9, [X19,#8]

无法进行敌我判断的, 至少要找一个位置, 让我们

1. 获取 [x19]的值

2. 检查这值是否1001

3. 如果是主角跳过下一句

4. 写入新HP

5. 反回原本地址

需要4至6行代码

一般函式和函式之间的空隙是都不足够的。

我们要找一大块空白的地方来扩充

按一下 CTRL S

留意到 main 区段是去到 0x375000 结束

可以跳到它前面 0x374F00 看看是否空白

这往往是有空间的, 100分之99的机会有充足空间给你用。

(我自己习惯是用E00结尾的, 因为我名字是E字开头的)

今次只是教学, 先用 374F00 写 code cave 吧


未开始写之前, 你最好先把这位置全改成 nop

Keypatch -> Fill Range

然后在上面按一下 C (make code)

变成这样

#本身Keypatch是有BUG的, 如果你见到内存是 ? ? ? ? 般,

就不能用Keypatch直接改了, IDA会崩溃的,

幸好连接GDB时,会自动变成0, 这样用Keypatch没问题


之后,在开始的地方按N,给它一个名称 HP_hack

然后 按 ESC 返回刚才 断点的地方 main+D2058,

把原本的 NOP 改写一句 BL HP_hack

这就做好了呼叫扩充函式的动作.

# 部分情况,原程式没有把X30放到SP (STACK)时, 不能使用BL和RET的, 要改用 B 替代


另外, 我们还要看看有什么寄存器可以使用

主要看后面十多句,

X0 和 X1 应该可以用的, 它们都是会被立即改变的寄存器,

现在, 可以返回刚才的 HP_hack , 开始 Ctrl Alt K 写代码了


我想说明一下这种转跳的输入方法,

PC即是现时运行的位置, 可用一点 “.” 来代替,

+4就是下一行指令, +8就跳过一行去到第三行。

所以 BEQ .+8 的意思是 如果结果相同, 会跳一行 (即是下一行不会执行)

变成这样再继续

好了,写好了


如果你喜欢,更可以把原本的 STR W9,[X19,#8] 改成 STR WZR,[X19,#8]

WZR内容永远是0的 (至少,在大多数情况下是这样), 改成这样就可以秒杀敌人!

秒杀, 我可加快游戏进程, Why not? 就改 WZR吧。

可以再 F9 了


又玩了一会, 没问题

(其实继续玩下去,会有伙伴,到时敌我判断就得稍微改一下, 例如 1001 改成 2000, BEQ 改成 BLE或BCC等)

不过我写稿写了一晚,还没写完, 要先停一下. 以后玩到再改吧。

接下来最后的事, 是教大家如何把CODE CAVE程序变成金手指

其实也很方便, 在Hex View的窗口按一下4, 而且改成 column 1

像这样, 之后选取代码 (留意地址要8个位就够了)

贴到 notepad++, 把中间的两个空白改成一个,再在每行前面加 04000000便可以了

[HP hack]
04000000 00374F00 B9400260
04000000 00374F04 710FA41F
04000000 00374F08 54000040
04000000 00374F0C B9000A7F
04000000 00374F10 D65F03C0
04000000 00374F14 D503201F

之前那句 BL 呼叫 HP_hack 也 照板煮碗 的做一次

加到最末尾

04000000 000D2058 940A8BAA

完成!

恭喜你升级了


特别鸣谢

Eiffel2018 原创发布:【金手指教程2】使用 GDB 找出 敌我判断 的特徵


如您从本文得到了有价值的信息或帮助,请考虑扫描文末二维码捐赠和鼓励。

尊重他人劳动成果。转载请务必附上原文链接,我将感激不尽。


与《Switch 金手指制作教程三:如何使用 GDB 找出 敌我判断 的特征》相关的博文:

Exit mobile version