码迷,mamicode.com
首页 > 其他好文 > 详细

怪物农场2修改日志5 - 极乐净土

时间:2016-08-14 07:29:13      阅读:184      评论:0      收藏:0      [点我收藏+]

标签:

接上篇,怪物农场2修改日志4 - 决战前夜

bgm,最近血洗B站的极乐净土

上篇中,我们成功的找到了从光盘中读取的数据得到的怪物种族Id和副种族Id在内存中存储的位置.

通过修改该内存位置,可以直接决定最后生成的怪物,包括特殊怪物都能直接生成.

接下来我们会看下这些数据是如何通过CDROM中读取的数据计算得到的,顺便会挖掘下其他受CDROM影响的初始怪物数据.

通过查询外文攻略站得到如下信息.

  • CD中最后一条音轨的分钟数决定了怪物的主种族Id.
  • CD中除去最后一条音轨,剩余的总时间的秒数部分,决定了怪物的副种族Id.
  • 根据CD中第一条音轨的秒数部分对怪物属性进行修正.
  • 根据CD中全部音轨的秒数部分对怪物属性进行再次修正.
  • 特殊怪物的主种族Id和副种族Id似乎是根据数据硬编码得到的,不使用通用的规则.

可以推测出,从CD中读取的信息应该是这些.

我们仍然先使用寄生前夜2的B盘来做测试,外站上看到这个盘的音轨数据如下,

0+3667秒(全部音轨长度61:07、最后一条音轨长度61:07)

 

继续调试看看,仍然在0x001ffc98处下个数据写入断点,看看数据是如何从CD到这个内存位置的.发现断在了如下位置,

技术分享

从调用栈可以看到上层函数是0xd9a04,我们执行到返回看看.

技术分享

可以看到这里会一直拷数据,将0x76868(r6)到0x76888(r9)拷贝到0x1ffc98开始的内存.

之后函数就返回到了上层.

技术分享

可以看到上面有句jal 0xda0a4,因此返回前的那个函数的入口地址是0xda0a4.

我们在0xda0a4下个断点,重新调试看看具体做了哪些事情.

技术分享

可以看到我们成功来到了这个函数的入口处.

首先addiu r29,r29,0xffb0,这里把r29的值减少了0x50,查了下资料发现r29是stack pointer,这里开辟了0x50的栈空间,从0x76858到0x768a8.

sw r17,0x44(r29) 这里把0x1ffe70存到了r29+0x44处.

sw r31,0x48(r29) 这里把返回地址保存到了r29+0x48处.

sw r16,0x40(r29) 这里把0x1ffd30保存到了r29+0x40处.

lbu r2,0x48(r17) 这里读取0x1ffe70+0x48=0x1ffeb8

beq r2,r0,0xda120 这里r2为0,跳转到0xda120.之后发现,如果生成时直接使用怪物农场2的盘,则这里r2为1,不会跳转

0xda120处直接跳到了0x34228

技术分享

技术分享

0x34228入口处,这里分配了0x20的栈空间.

sw r17,0x0014(r29) 将0x1ffe70存到栈上+0x14的地址.

r4 = 64

r5 = 4

之后将r31存到r29+14处,跳到0x3cf08

0x3cf08中暂时不容易看出太多信息,我们回到上一层继续执行.

技术分享

从0x34264开始似乎在把0x1fcdd0处的数据搬到0x76890,继续执行看看.

技术分享

这个时间点,从0x34228返回,由于r2为0,将跳转到0xda188.可以看到0x76890处的内存此时为0x61,0x09.

技术分享

来到0xda188处.

技术分享

r2 = r5 = r7 = 0x800c0000  r6 = 0x800c646c r16 = 0

接下来又做了一些意义不明的赋值.

技术分享

r10 = 2  r9 = 0x76888  r4 = 0x800c6472  r2 = [0x800c6468] = 0x100

技术分享

如果r16大于等于r2,则跳转到0xda2b8.否则继续执行,r3为之前保存的0x61,这个0x61看起来很像前面提到的61分钟.

直接改r3的值试了下,确实能改变怪物的种族,数值也会和外网攻略站上的一样,只是这边不知道为什么把61分钟存成了0x61.

技术分享

r2,r3不相等,则会跳转到0xda2a8

技术分享

这里将r4和r6增加8,又跳回0xda1a8处.此外跳转下面一条语句也会执行,所以r16每次会自增1.

再调试下,发现这里这个循环,是从1到100,根据从CD中读取的那些数据查找匹配的项.然后根据项中记录的某个整数作为偏移查找到指定的数据.

通过调试发现最终是从0xc80fc拷的数据到0x76868附近的内存,0xc80fc这里的数据是静态的,似乎记录了所有可能生成的怪物的数据,每段数据的长度是0x28,怪物属性也可以在这段数据中找到.

 

我们用怪物农场2的盘做实验看看现象,

技术分享

使用怪物农场2的盘后发现,这里r2为1,不会跳转,所以这时的流程和读CD中的数据来生成怪物是完全不一样的.

调试发现这里检测到是怪物农场2的盘,就直接硬编码生成了种族Id为19的モッチー.

这边在0xda0ec处,我们patch这里的代码,直接改成addiu r2,r0,0x261C,就能生成前面的那只特殊的液体终结者了,其中0x26和0x1C对应了液体终结者的副种族Id和主种族Id.

 

简单做了个金手指用于测试,只要修改#Summon Specified Monster的前两行,不用换盘就能任意生成所有的怪物,包括野外训练中遇到的怪物.(大成功?)

#Summon Specified Monster
300DA0EC 0011
300DA0ED 0027
300DA0EE 0002
300DA0EF 0024
#Undo Summon Specified Monster
300DA0EC 0000
300DA0ED 0000
300DA0EE 00E2
300DA0EF 008C

 

但是这个方式并不能保证生成的怪物的数据正确,而且是直接patch代码,首先不确定这个地址是不是每次都一样,也很难保证不会有其他问题.

接下来,准备仔细的再分析下这边的几个函数,尝试找到更好的修改点,或者制作修改器.

To be continued...

怪物农场2修改日志5 - 极乐净土

标签:

原文地址:http://www.cnblogs.com/unigauldoth/p/5745833.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!