以下内容完整转载自:超绝可爱陆陆酱 原创发布:【工具教程4】Breeze高阶技巧:逆向追踪寻找内存中的敌我差异
私信我最多的问题的就是,敌我区分该怎么做,有的人看了E大的教程还是不太懂的,那么我再展开补充一下吧。
区分这个技巧在第三篇已经详细解释过了,无论是正负区分、敌我区分、类型区分。首先它本质就是区分,修改原理是一样的,只是要找出来当做判断的依据不一样。
敌我区分的原理
通常游戏一个角色,多项属性,是连着放在一起的,比如说血量的内存地址附近,或许可以找得到攻击力、防御力等等之类的内存地址。
很多种属性,都是按一定规律排列的,而这种按规律排列的属性的总称就是结构体。
如果以面向对象编程的方式来解释的话,就是有一个代表角色属性的抽象类,敌方单位和我方单位,都继承了这个抽象类之中的属性,是这个父类的子类对象。
因此敌方单位和我方单位,在属性排列上有非常高的相似度,但也不是完全相同。
做敌我区分,就是找出,敌方单位与我方单位在结构体上,存在明显差异的地方。这个差异可以是,内存中代表人物ID的数值,也可以是,我方单位有,敌方单位无,或者我方单位无,敌方单位有的属性…………总之非常多的东西可以拿来做判断,解并不是唯一的,存在好几处不同,而我们只需要其中一两处,来当做判断的依据即可。
简单来说,就是大家来找茬,找不同。就这么简单,可能需要一点熟练度、眼力、耐心、直觉、运气。
逆向追踪
之前讲过了,Breeze可以在内存数值地址上设置断点,追踪到什么程序,改写或者加载了它。
也可以在程序上设置断点,逆向追踪这行程序,改写或者加载了哪个数值地址,这个功能在做敌我区分上非常好用的,省去了你要通过搜索,去查找另一个我方单位或者敌方单位的麻烦。
并且Breeze设置断点的功能是比ida pro要好用一点,因为不会真正中断程序,可以一次性把很多东西同时抓出来。不用像ida pro设置断点后,要小心翼翼的了。
接下来我会以《机甲战魔》这个游戏,来讲解敌我区分,修改我方血量不减、敌方秒杀的一个过程。
在尝试整数搜索不出来血量(VP)后,用模糊搜索将它搜出来了,之后就是,设置断点→追踪程序。
这些东西之前讲过,这里不再讲一遍。
直接来到程序分析的部分。
抓出来两行程序
稍微看了下[M+0x5b00d4]这一行应该是计算,血量自然恢复的程序,如果想改恢复加速的话,可以改这个。但与本篇内容无关,这里就无视了。
直接来看[M+0x5ad6c8]这一行
就是这一段,从LDR到STR之间的这一段,整个用来结算血量扣减的程序。
emmmm……非常复杂的程序,太长不看。
反正这游戏加法和减法是用两段程序分开计算的,知道它是用来做减法的就够了。
左边光标移动到输出指令那一行 str s1,[x20,#0x1bc]
按L ,或者右边光标选中watch instruction按A。
此时自动返回gen2界面,同时左边地址后面多了x20 offste 01bc,跟上面那个输出指令[]里面的位置是一样的。
跟之前设置断点的方法一样,按+,R 设置好断点。
主页键返回游戏,此时需要做的就是,让我方单位掉血,敌方多个单位掉血,但不要把敌方单位打死,因为打死之后某些属性会变0,就不具备比较的意义了。(PS:正常来说,这里先修改成不减会比较好,多找几个敌人来做参考,准确度就会比较高,主要是我懒)
抓出来三个代表血量的地址,就以地址最后四位来表示吧。
d9c0,是敌方单位1的血量
2740,是敌方单位2的血量
0100,是我方单位1的血量,尽管转换不出来float数,但问题不大。
那就先挑一个敌方单位的属性来看,转换了看得舒服一点。
在敌方的那一行按X,打开看看,主要是我想先找,血量上限的位置,一会修改血量需要用到的。
找到了,就在血量往后算两格单位,一格单位是4个字节,所以。
当前血量的位置是[x20,#0x1bc]
血量上限的位置是1bc+8,也就是[x20,#0x1c4]
如果有的人觉得,默认的内存视图看不懂,多按几次左摇杆,切换成10进制、16进制,总之用你能看得懂的方式就好。
然后就开始,大家一起来找茬的部分了。
[x20,#0x1bc]这个东西代表的意思是,在这个单位的结构体中,从第一行往下算,算到第1bc行(1bc是十六进制的),就可以找得到对应代表血量的地址,1bc这个数值转换成十进制的话,数值还是比较大的,说明这个结构体行数比较多,前面还有很多行属性,先往上翻翻看。
(如果你找的游戏,血量是0x1c,说明前面都没有几行,你就要往下去找,这个要因游戏而异的。)
怎么去做对比呢,推荐每翻一页,截一下图,然后用switch自带的相册,瞪大眼睛,一行一行,去进行对比。
找的敌人数越多,消耗时间越多,但精准度也会比较可靠,毕竟这个东西做不好,金手指也是不好用的,前面的关卡没问题,后面的关卡又有问题了。
往上翻了一页,找到了一处明显的差异。
在这个位置上,敌方单位为0,而我方单位是有值的。
根本懒得去猜它的值是什么……
那么这个位置是哪里,口算也可以,Breeze这个视图还是很好看的。
就把一开始找到的血量当做坐标的起点。
X轴往右移,就是+4,往左移,就是-4
Y轴往上移,就是-10,往下移,就是+10 (十六进制的)
我找到的地方,在血量往上,一第九行的位置。
所以这个位置,就是1bc-90,也就是[x20,#0x12c],口算实在不熟就用计算器算吧。
那么找到了差异,就来开始写程序修改了。
回到gen2菜单,右边光标选中Pre results
找到刚才设置断点找到的程序
把str s1,[x20,#0x1bc]这一行
还有ldr s9,[x20,#0x1bc]这一行
添加到金手指
程序压根没怎么看,当开发者把程序写得很绕,或者你改着改着心烦了,根本不想看。那么就不必管它怎么写,其实这并不妨碍你写自己的程序,抓住头或者尾巴,就能控制整个程序最终的计算结果。
先来改尾巴,也就是str这一行,做一个血量不减的效果。上面找过代表血量上限的位置,现在就用得上了。
因为找到的这个差异位置上的值,是整数型,所以用W寄存器来加载,如果是浮点数型,就需要S寄存器来加载了。
模板的话,就这样写
ldr w1,[x20,#0x12c]
cbz w1,.+8
ldr s1,[x20,#0x1bc+8]
{original}
b code1+4
Breeze加载之后就是这样子
到这里肯定不会再事无巨细每一行都要去讲是什么意思,希望各位能自行理解,程序并不复杂。原理是,在执行输出指令前,先用w1加载之前找到的敌我差异的位置,用cbz指令进行判断。
当w1的值为0,判断为敌方单位,向下跳转两行,执行原来的输出指令,随后跳出code cave,返回原程序。
当w1不为0时,判断为我方单位,不进行跳转,先将血量上限值加载到s1,再将s1输出到当前血量对应的地址上,跳出code cave。以这样的方式,完成血量不减的修改。
然后再来进行头的修改,也就是ldr这一行,用来制作秒杀的修改。
模板这样写
ldr w1,[x20,#0x12c]
cbnz w1,.+12
fmov s9,1.0
b code1+4
{original}
b code1+4
Breeze加载之后,就是这个样子
加载程序,本身是加载内存中当前血量的值,来做计算用的。
修改原理和上面的差不多,在执行加载指令前,先做敌我区分。
cbnz是cbz的反义,cbz是为0时跳转,cbnz是不为0时跳转。
当w1不为0,判断为我方单位,向下跳转三行,还是执行原来的加载程序,跳出code cave。
当w1为0,不进行跳转,不再从内存加载血量,而是直接给了一个假数,由于血量是浮点数,所以要用fmov指令来赋值。
这里给了一个很小的数,1.0,应该不管减什么,最后程序运行的结果都是负数,也就不必管它原来的程序是怎么计算的了。我不怎么喜欢改为0,因为有些游戏改为0会出问题。
之后,测试半个小时,没有什么大问题,那就这样吧,把金手指代码从机器里复制出来。
[player_hp_hack](还原码、修改码、Code cave)
04000000 005AD6C8 BD01BE81
04000000 005AD6C8 14FEB136
04000000 04559BA0 B9412E81
04000000 04559BA4 34000041
04000000 04559BA8 BD41C681
04000000 04559BAC BD01BE81
04000000 04559BB0 17014EC7
04000000 04559BB4 D503201F (由于这个位置只写了5行,用一个nop指令来补充成双数,之后缩减会好看一点)
[enemy_hp_hack]
04000000 005AD6A8 BD41BE89
04000000 005AD6A8 14FEB144
04000000 04559BB8 B9412E81
04000000 04559BBC 35000061
04000000 04559BC0 1E2E1009
04000000 04559BC4 17014EBA
04000000 04559BC8 BD41BE89
04000000 04559BCC 17014EB8
稍微修改一下格式,一般我是喜欢把还原码和code cave用{}包括起来,当做默认程序执行。
把还原码当做默认程序方便的是,可以直接从金手指软件里,关闭金手指选项,即可还原修改效果。
把code cave放在里面,一排连在一起的程序,看起来比较舒服,只是我个人的强迫症。然后把4字节缩减成8字节,减少txt文件的大小。
最后发出去的,会是这个样子。
{master code&estore code//必须码与还原码}
04000000 005AD6C8 BD01BE81
04000000 005AD6A8 BD41BE89
08000000 04559BA0 34000041 B9412E81
08000000 04559BA8 BD01BE81 BD41C681
08000000 04559BB0 D503201F 17014EC7
08000000 04559BB8 35000061 B9412E81
08000000 04559BC0 17014EBA 1E2E1009
08000000 04559BC8 17014EB8 BD41BE89
[血量不减]
04000000 005AD6C8 14FEB136
[秒杀]
04000000 005AD6A8 14FEB144
到这敌我区分的东西就讲完了,并不是很复杂,多一点耐心,总能找得到。
写code cave也不复杂。所以说一定要学好code cave,就算你看不懂开发者写的程序,也不影响你写自己的程序进去对其进行修改。
有些新手朋友基本的程序修改已经会了,改个钱倍率、道具,没什么问题。但一到需要写code cave就慌,没什么担心的,最多就把游戏改崩,还能怎么样呢,每个大佬都是这么过来的吧,把游戏改崩个上百次,该会的你就都会了。
这个东西并没有固定格式改法,想怎么改都是你的自由,找到专属于自己、最适合自己的改法,那就是最好的。实在不懂怎么改,就多看看论坛里几位大佬的代码,或者gbatemp上看看国外大佬的代码,从抄作业到逐渐理解,就是学得最快的方法。
Breeze这款新的金手指软件真的非常好用,就属于躺在床上玩游戏玩着玩着,顺手把金手指做好了。
就算你不想做金手指,只使用金手指,Breeze也很比更好用,可以加载多套不一样的金手指代码,多位大佬的作品随时切换,也可以做简单的改写。
而edizon-se连在机器上修改代码都做不到,你要换一套代码,都要关游戏,重新从电脑上拉进机器里。
很推荐使用
如您从本文得到了有价值的信息或帮助,请考虑扫描文末二维码捐赠和鼓励。
如本文对您有用,捐赠和留言 将是对我最好的支持~(捐赠可转为站内积分)
如愿意,请向朋友推荐本站,谢谢。
尊重他人劳动成果。转载请务必附上原文链接,我将感激不尽。
留言