以下内容完整转载自:Eiffel2018 原创发布的:【金手指教程1】 除错器
前言
GDBstub 是新版大气层的功能之一, 主要用途是跟踪程序的运行, 布置断点(breakpoint), 方便找到相关代码。
之前初步尝鲜测试了一下GDB:最新大气层功能GDBstub开发金手指教学
现已经过了无数试验, 算是深入了解. 可以详细剖说一下 (是时候找数了)
要求工具
- 大气层版本1.2.4以上 (建议保持最新版本)
- EdizonSE (找地址用的, 也可以用其他工具找; 本教学利用到 ==* 功能, 需要版本 v3.8.34a 以上 )
- IDA PRO v7.5 SP3 (如果想深入分析, 还需要加装读取 NSO 和 ELF 的LOADER, 与及方便修改内容的 KEYSTONE 及 KEYPATCH)
- 下载我制作的简单PY:markRegions.rar
使IDA能够自动划分区段 (只支援python3, 所以你可能要把 idapython 2 升级到 idapython 3)
个别安装问题,不在此详细说明。
注意事项
为求运行时稳定, 尽可能减少载入 sysmodule,
那些 Tesla / sys-clk / noexes 等, 可以全部关了 (或者你遇到无法解决的问题时再关吧)
(我只留一个,如果你用DBI的usb传输,连这FTP也可关去)
简单介绍
以下将会以 TitleID 010005C015524000 邪恶国王与出色勇者 作为例子
这游戏是个很容易找到内存的简单RPG,
现在是利用 GDB 的功能找出 ASM代码 来修改。
-
查找HP
这很简单,就是在 EdizonSE 按两下 – 减号, [u64][==*][RAM] (不限形态,自动查找), 再输入现时的HP 27, 开始第一次搜寻
-
改变HP再找
回到游戏, 使主角的HP减少, 然后退到 EdizonSE 再在搜寻的位置按一下ZL, 那个 27 便即时减少为 26, 再搜一次
-
试验
你可以继续重覆步骤2, 直至只剩一个侯选值(candidates),
而我的习惯,在这剩下几个侯选值(candidates)的情况时, 会在每个侯选值按一下R3(即右磨菇), 了解内存内容.
在你认为这个就是HP值的地方,改动一下数值, 再回去游戏看看是否被修改。
修改后, 可确认这个侯选值是正确的,
我们需要把它抄下来 heap+7CF1490 备用。
-
连接 IDA PRO
现在准备退出 EdizonSE 接驳 IDA 的 GDB debugger,
要注意的是, 在EdizonSE 按B或+退出前, 必须确保是 Detach 状态 (右上角写明 dmnt not attached)
否则, 就要按一下 ZL+B , 这样才能接驳 IDA 的。
开启 IDA, 只需要一个空白的新实例, 一开始按 Go 即可
然后, Debugger ->Attach ->Remote GDB debugger
之后, 我们需要先把 处理器 改成 ARM64 (AArch64):
Debug Options ->Set specific options -> Configuration: ARM64 (AArch64)
再把 Hostname 改成你家中的 switch 地址, PORT位预设 22225, 连接。
选择 游戏进程的ID, 通常是最大,最后的一个
成功后,会看到IDA PRO底色变成浅蓝色, SWITCH的游戏画面也会马上冻结(暂停运行)
-
划分区段
现在我们要做的是定义区段 (define segments) 方便探究之后程序及内存
按 ALT+F7 执行 PY 文件, 由于这是 64 位元游戏, 所以要用我附件中的 markRegions64.py (只有少数很旧的游戏,使用那32位元的ARM)
打开执行之后,便会自动定义好各个区段,
但遗憾的是,我只是个py新手,零经验 (附件这PY是我的第一个PY程式),
执行时, 所定义的区段未能做到自动排序, 要人手处理一下
在任意一个区段上,滑鼠右击再编辑edit, 之后按一下ok即可.
排好再按OK。
说了这么多, 总算完成第一阶段了。
这里 4-5 我用了很大篇幅瞄述, 因这有点复杂,容易出错,
实际操作不用10秒已能做好。
事实上,实际操作也要经常 在IDA 退出 Detach from process, 回去edizonSE找地址,
经常来来回回, 此步骤必须要熟练,要快。
(只是当 detach 退出进程, 在第二次进入 IDA 时, 若游戏没有重启, 便不用再设定 processor 及 segments 了)
-
跳到内存位置
按下 G , 然后直接贴上
刚才我们记下的内存地址 heap+7CF1490
看到了, 这个 0x1D, 就是刚才的内存地址
为了清楚好看, 我会再按几下D (或者如图右点,改成Double Word)
之后还要按 H 把它改回十进制。
改变地址的变数形态, 分析附近内存是甚么,
这个也是很有意思的, 要多多练习一下
题外话: 如果你想修改这 29 HP, 或后面 估计是最大HP 的 29, 可以在这里编辑啊,不过你要输入16进制的数字
(但如果你打算做大量修改, 也可以跳到 Hex View 窗口, 改成 所有资料以 32位元形态 十进制数 显示, 然后按 F2 直接编辑)
-
下断点 (breakpoint)
快捷键就是 F2, 在刚才 29HP 的位置上按一下 F2
这画面有很多细节地方要学习的. 有兴趣的朋友应该要根据官方文件逐一测试。
暂时初学, 可以直接取消 Read, 只使用 [Enable][Hardware][Write][Break] 便可以
成功后, 可看见刚才的 29HP 变了红色(正常是深红色,我私下在IDA选项内改了粉红色)
而且,下面 Breakpoint 列表视窗 可看到一个新的断点
这断点的意思就是让程序继续运行直至程序在这内存位置[写入]新的内容
(另有 Read断点 与及 CODE区段中的软断点, 也很常用, 日后也应该要学习的)
现在按 F9, 游戏可继续跑了
-
触发断点
继续玩游戏,尝试使角色扣血
就在准备要扣血时, 游戏突然停止了!
我们再看看IDA, 弹出了讯息, 原来是刚才的断点触发了
之后, IDA View-PC 窗口自动跳到了 触发断点的程序.
所谓 PC, 是32个64位元寄存器(registers)的其中一个。
现在这 IDA View-PC 窗口是会自动追随PC的值跳动的。
PC所记的地址 main+D2058 , 就是现在运行停顿的地方(蓝色底色一句)
如果现时要看其他位置,要按 G 跳去;想退回去看之前断点的地方, 可按ESC
不应该人手改变PC寄存器的值, 这会影响往后运行的结果!
这句 main:00000000000D2058 69 0A 00 B9 STR W9, [X19,#8]
69 0A 00 B9 是机器码 machine code, 平常我们写金手指 B9000A69, 是反转来用的
STR W9, [X19,#8] 是反组译出来的 ARM64v8 指令
意思是 STORE (写入) W9 (寄存器X9 的 32位元 DoubleWord 形态: W9) 到这个位址 [X19, #8] (64位元寄存器X19,加上偏移值(offset)8的位置)
先看看右边 X19是甚么, 它记下了 0x00000024B02F1488 , 在旁的注释看到是属于 heap 区段
所以 [X19, #8] 应该就是 0x00000024B02F1488 + 0x8 = 0x00000024B02F1490 了
正是刚才下的 breakpoint 位置
把 鼠标 移到 [X19, #8] 上面, 可看到 现时这位置的值是 29
把 鼠标 移到 W9 上面, 可看到 准备要写到这位置的值 0x1B, 心算一下, 就是 27
现在, 我们先 关闭了刚才的断点, 因为这个断点如果一直开着, 程序不能够继续跑的。
这是现时 大气层GDBstub 的一个小小问题,
不能在这时按F7/F8跳去下一行,
也不能狂按F9强迫它运行,
这只会令程序崩溃, 希望日后在这种 Single Step Debug 方面可改善
关闭断点方法, 在下面列表, 右点便看到。
-
修改程序
你可以想像一下, 假如这句指令不执行, 那么不就是 [HP不减] 了吗?
这修改能否成功需要尝试才知道. 这也有可能令到HP增加也变成无效的.
不过一试无妨. 简单把这句改成 NOP 便可以了。
假如你安装好 keystone + keypatch 便可以像我一样按 CTRL+ALT+K 跳出这画面
把原本的 STR W9, [X19,#8] 人手输入 改为 NOP, 再按一下Patch便可以
(之后它会跳到下一个指令,你便要cancel)
成功的话, 看到 main+D2058 的指令被改成了 1F 20 03 D5 NOP,
聪明的小伙伴应该知道, 这就是对应金手指的
04000000 000D2058 D503201F
不过, 我们这样用GDB修改了内存或指令后,
暂时是无需要编写金手指代码才可测试的,
直接再按一下F9 运行, 便可继续调试了.
(按F9前,再检查一下你刚才的断点是否已取消或删除,小心,不要一直开着!)
-
进行调试
回到游戏,再玩一下,
即时看到效果, 刚才 HP29 本应变成 27 的, 但现在没有改变.
主角一直保持HP 29 (算是初步成功了)
可惜不妙的是,现在连敌人的HP也不减了!
这确是很多新手会不知所措的问题。
虽然这个HP不减的金手指还未完成, 但已完整说明以GDB找出ASM代码的方法。
希望小伙伴能够触类旁通, 轻易找到其他想要修改的金手指
(例如HP29后面的4,应该是MP吧,你可以同样去用断点改,敌我通用应该也没所谓吧;再后面攻防能力等,因为很少写入,或许可以用Read作为断点,达到修改目的)
后续教程将讲解 敌我判断。
特别鸣谢
Eiffel2018 原创发布:【金手指教程1】 除错器
如您从本文得到了有价值的信息或帮助,请考虑扫描文末二维码捐赠和鼓励。
本站资源,请 注册城通账户 后,使用客户端下载,参考教程:城通网盘如何使用客户端下载文件。
如本文对您有用,捐赠和留言 将是对我最好的支持~(捐赠可转为站内积分)
如愿意,请向朋友推荐本站,谢谢。
尊重他人劳动成果。转载请务必附上原文链接,我将感激不尽。