究极绿宝石5.3

您所在的位置:网站首页 金手指0x格式 究极绿宝石5.3

究极绿宝石5.3

2024-07-03 05:07| 来源: 网络整理| 查看: 265

说在前面:

    自从第五期专栏开始介绍金手指的使用方法,一直到上一期,专栏涉及到的金手指全都是原始格式的。第五期专栏提到常见的金手指格式还有其它2种:GS码(也被称为V3格式码)和代码断路器。本期和下一期专栏将会对V3格式码进行介绍。

V3格式码的原理

先把第五期专栏里对V3格式码的介绍抄过来:

GameShark,也被称为GS码、V3格式码。格式为:8位十六进制数 8位十六进制数。具体来说,GS码的一行是由单个空格分隔的两个8位十六进制数,这一行除了两个数字、单个空格和结尾那个看不见的回车符,没有任何其他符号。GS码是基于原始代码和其他特定规则,由加密算法生成的代码……

    上面说的“GS码是基于原始代码和其他特定规则,由加密算法生成的代码”里面有两个关键点:其他特定规则、加密算法。对应这两个关键点,我们需要两个工具:

 The Secrets of Professional GameShark(tm) Hacking (专业金手指破解的秘密),这是一个介绍GBA文件各种代码类型破解的文档,网址位于https://gamehacking.org/faqs/hackv500c.html。其内容为全英文,可能对于一些读者来说有阅读困难, 不过对于V3代码来说,只需要看文档中AR V3 Codes Types这个表格(可以在网页上通过Ctrl+F搜索找到这个表格的起始位置),其他那些长篇大论的理论分析可以略过。AR V3 Codes Types介绍的就是上面提到的那个“其他特定规则”。

AR Crypt.exe,2.4B版本(其他版本也可以),这是一个实现了加密算法和解密算法的工具,可以将经过“其他特定规则”转换之后的原始代码加密成V3格式码,也可以反过来,将V3格式码解密成经过“其他特定规则”转换之后的原始代码。为了便于表述,下面将“经过其他特定规则转换之后的原始代码”称为中间代码。

生成一个V3格式码的流程如下图所示:

原始代码到V3格式码的转换

下面我们以一条金手指为例,详细介绍V3格式码的原理和生成过程。

查找金手指例6——精灵全图鉴发现的金手指在哪里?

    究极绿宝石5中,主角会在游戏刚开始没多久得到小田卷博士赠送的精灵图鉴,上面描述了全部精灵的发现和捕捉情况。到了二周目,精灵图鉴会由原先的丰缘图鉴升级为全国图鉴,全国图鉴包含了游戏中所有的898种精灵,尚未发现的精灵在图鉴中只会有一个序号,后面跟着一些横杠,不会显示精灵的名称;发现但尚未捕获的精灵只会显示名称;捕获的精灵在序号前会出现一个精灵球标记,如下图所示:

精灵图鉴

    上图的精灵图鉴中出现了3种情况:尚未发现的132号精灵,已经发现但未捕获的128、131、134、135、136号精灵,和已经捕获的129、130、133号精灵。因此请读者们区分“发现”和“捕获”这两个概念,“全图鉴发现”的金手指指的是让所有精灵在图鉴上都呈现“被发现”的状态,而不是“全图鉴捕获”,那是另一个金手指。

    在给出V3代码格式的“全图鉴发现”金手指之前,我们可以思考一下这个金手指的原始代码应该是什么样子的。

    经过了前面那么多期专栏的分析,我们知道:首先需要找到“图鉴上的精灵是否被发现”的变量地址在什么地方。找变量地址有两种思路,一种是猜测变量取值的结构和取值,然后在“查找金手指”的界面中用精确查找;另一种是上一期介绍的用“查找金手指”界面的模糊查找,通过设置“相等”和“不等”的条件,在游戏中发现或捕捉新的精灵,从而改变图鉴来搜索。

    以第一种思路为例,让我们仔细猜测一下。图鉴上一共有898种精灵,每种精灵都有“未发现”“已发现未捕获”和“已捕获”三种状态,如果让你来设计,你会用什么样的变量来表示图鉴上精灵的这三种状态呢?不妨举几个例子,让我们以游戏设计者的角度来考虑这个问题:

用一个字节来表示每个精灵的三种状态,全图鉴需要898字节来描述。一个字节共有8位二进制数,描述3个状态绰绰有余,也正是因为“绰绰有余”,让我们不禁去想:这么设计是不是太浪费空间了?描述3种状态,1位二进制数肯定不够(只能表示2种状态),2位二进制数则是足够的(能表示4种状态),所以有了下面这个设计。

用2位二进制数来表示每个精灵的三种状态,1个字节可以表示4只精灵的状态。根据“相似变量紧挨着放”的规律,很有可能就是1号到4号精灵放在一个字节里、5号到8号精灵放在一个字节里……顺序按照“小端序”来。这么做只需要898/4 = 224.5个字节,和上一个方案相比,节省了四分之三的空间。这个方案看起来不错,作者曾经用这种方式去找过,只不过没有结果,因为还有第三种方案。

把“全图鉴发现”和“全图鉴捕获”这两个映射表区分开,每个表就只需要1位二进制数来表示每个精灵的状态,在“全图鉴发现”里面,0表示“未发现”,1表示“已发现”;在“全图鉴捕获”里面,0表示“未捕获”,1表示“已捕获”。这种方案和第二种方案消耗的空间一样多,本质上都是用2位二进制数表示图鉴上的精灵状态,只不过一个是合并起来,一个是拆分开来。这个方案经过验证,的确是游戏中描述图鉴的变量组织方式。

    按照这个思路,下一步是不是应该看一眼我们的图鉴,把1到8号精灵的发现情况,按照“未发现”映射到0、“已发现”映射到1的规律,拼出一个8位二进制数,然后去“金手指界面”用“精确查找”去找了?

    看上去一切正常,可问题就出在了“1到8号精灵”这个地方。如果读者有过编写程序的经验,就会知道很多编程语言里面,描述一些东西的顺序往往是从0开始计数,而不是从1开始,这也是为什么一个二进制数的最低位被叫做“第0位”,除了因为它表示的权重是之外(这是第二期专栏介绍“进制”的时候给出的理由),还跟程序语言的习惯有关:计数从0开始。因此我们不应该把“1到8号精灵”的状态组成一个字节,而是应该把“0到7号精灵”的状态组成一个字节。

    问题又来了:“0号精灵”是什么?就算收集了全图鉴的玩家,在图鉴上也不会找到“0号精灵”,因此“0号精灵”对我们来说,它的状态就是未知的。不过没关系,我们可以找下一个字节“8到15号精灵”的状态,或者再下一个“16到23号精灵”的状态……

    拿上面那张精灵图鉴的图片为例,我们发现“128到135号精灵”的状态恰好对应一个字节,按照图鉴中的情况,依次是:已发现、已发现、已发现、已发现、未发现、已发现、已发现、已发现。映射到字节就是11101111(2),注意这些状态填到字节里面去的顺序是从右向左(遵循小端序)。它是十六进制的EF,此时我们就可以在“查找金手指”的页面,用“精确查找”查找这个8位的数值了。如果结果很多,那我们就继续向下看图鉴,拼出来一个16位乃至32位的变量去找。

    经过一番查找,最后发现“全图鉴发现”的变量地址是02025f60,这里开始的第一个二进制位描述的就是“0号精灵是否被发现”(当然,这在游戏中没有意义,因为没有“0号精灵”)。从第二个二进制位开始,包括它在内的后面898位二进制位(就是图鉴上898只精灵)如果都填充上1,就是全图鉴发现的金手指了,它应该是这个样子:

    第一行的变量取值是fffffffe,它的二进制就是31个1后面跟了一个0,这个单独的0就是描述“0号精灵”的,我们不知道“0号精灵”的状态,那就保持原样就好(这个地址原来的变量取值可以通过“变量地址查看器”来看),我们不去修改它。从下一个地址开始,所有的位置都填充1(十六进制就是填充f),一直到哪里结束呢?我们可以计算一下。

    现在每一行金手指都是32位二进制数,因此第一行就是0到31号精灵,第二行就是32到63号精灵,……,第二十八行就是864到895号精灵,第二十九行不会被填充满,因为只剩下3个精灵了,需要填充3个1,也就是十六进制的7。所以,这个“全图鉴发现”的金手指最后几行是这个样子:

    也就是说,用原始代码描述的“全图鉴发现”金手指,一共需要29行才能写完。

V3格式码的“全图鉴发现”金手指

    相比之下,V3格式码的“全图鉴发现”金手指只需要3行:

    在VBA模拟器中,输入这条V3格式码的地方和输入原始代码的地方是不一样的!具体在哪里可以去看第五期的专栏。有好多读者对“原始代码”和“V3格式码”没有概念,从网上找到了金手指就尝试往模拟器里输入,结果就是各种格式错误的警告。这里再强调一遍V3格式码的格式:

V3格式码的一行是由单个空格分隔的两个8位十六进制数,这一行除了两个数字、单个空格和结尾那个看不见的回车符,没有任何其他符号。

    这些代码是什么含义呢?我们需要一步一步地“解密”。

    回到本期专栏的第一张图,从左到右的顺序是“原始代码->中间代码->V3格式码”,现在让我们从右向左,看看从这3行V3格式码还原出来的原始代码是什么。

    接下来请出第一个工具:AR Crypt:

AR Crypt程序界面

    AR Crypt是一个可以在V3格式码和中间代码之间进行转换的工具。有了这个工具,我们就无需操心加密解密算法是怎么实现的,直接用它进行转换就好。AR Crypt的界面有很多按钮,现在真正需要的只有中间靠下的那个“Proceed”按钮,它的含义是“处理”或者“转换”。另外我们需要告诉这个程序:我们是要把一种什么格式的代码转换成另一种什么格式。这就是中间偏左下“From”里面的选项,和中间偏右下“To”里面的选项。

    看上图我们的设置。“From”里面选择的是“AR V.3”,意思就是我们想要转换的代码是V3格式码;“To”里面选择的是“RAW”,虽然它的意思是“原始代码”,但其实转换的结果是中间代码。我们把3行V3格式码粘贴到左上角的空白框内,然后点击“Proceed”按钮,转换结果就出现在右上角的输出框内了:

    这个结果,就是转换之后的中间代码。从V3代码到中间代码,代码的行数是不会变化的,V3代码是3行,转换之后的中间代码也就是3行。别忘了,这3行中间代码,和我们刚才得到的29行原始代码应该是等价的。

    在介绍下一步如何将中间代码转换到原始代码之前,我们先看看这3行中间代码,有没有什么规律?

    左边的看上去好像是变量地址,但仔细一看又有区别,第一行的00225f60和原始代码的第一行02025f60错开了一位,有个2位置对不上;第一行右边的fe和原始代码第一行末尾的fe也能对上,但是其它数字都不一样;第三行和原始代码的最后一行最为类似,右半边完全一样,但是左边还是那个问题,错开了1位;第二行完全看不明白,右半边那个6eff在原始代码中根本没出现过。

    接下来请出第二个工具:The Secrets of Professional GameShark(tm) Hacking文档。

    这个文档内容很丰富,但是全文都是英文,英文基础不太好的读者看起来会很费劲。其实如果只是用专栏介绍的功能——从中间代码转换到原始代码,没必要所有的内容都看懂,我们只需要看AR V3 Codes Types这张表格就可以了,下面是这个表格开头的截图:

V3格式码转换规则

    这张表格就是告诉我们:原始代码怎么转换为中间代码,或者反过来。现在我们希望从中间代码逆变换回原始代码,首先需要了解几个概念。

中间代码的类型:每行中间代码的格式和V3格式码相同,都是由单个空格隔开的两个8位十六进制数,看左边的十六进制数,它的最高位和次高位(就是最左边的2位)表示的是中间代码的类型。在上面的表格中,左侧一列的“Type 00”“Type 01”就是指的中间代码的类型,不同的类型,转换规则也不一样。

原始代码转换规则:原始代码的转换规则写在表格右列第一行的括号里。在上图中,(02024EA4 -> 00224EA4)就是类型“Type 00”的转换规则,(02024EA4 -> 02224EA4)就是类型“Type 01”的转换规则。转换规则说明的是原始代码的变量地址部分怎么转换到中间代码左半边的那个十六进制数。

代码含义:每个类型的中间代码含义都不相同,它写在表格右列的第二行。拿“Type 00”类型举例,它的代码含义是:

Fill area (XXXXXXXX) to (XXXXXXXX+YYYYYY) with Byte ZZ.

翻译过来就是:

用字节ZZ,将从(XXXXXXXX)到(XXXXXXXX+YYYYYY)的地址区域填满。

这里XYZ的含义就在表格左列“类型”下面的那个单元格,例如“Type 00”类型的:

XXXXXXXX

YYYYYYZZ

这两行是对中间代码的描述,其实就是左半边的十六进制数是XXXXXXXX,右半边的十六进制数,高6位是YYYYYY,低2位是ZZ,然后这条中间代码的含义就是“字节填充”。在用到地址的时候,需要先将XXXXXXXX逆变换回原始代码的格式,这才是真正的变量地址。

    我们先来看第一行中间代码:

    由于中间代码最左边的2位决定了它的类型,现在是00,正好对应到“Type 00”这个类型,我们就可以按照表格中的规则来进行转换。如果是其他的数字组合,需要到表格中去对应查找。比如说最左边2位是02,对应的就是“Type 01”类型。表格右列第一行括号内的“原始代码转换规则”里,箭头右侧的那个数字就是中间代码的格式样例,可以对照它的最左边2位来查找类型。

    根据“原始代码转换规则”,原始代码的变量地址转换到了00225F60,看一下我们的样例:02024EA4 -> 00224EA4。这个样例告诉我们原始代码转换到中间代码时,8位十六进制的第6位要向右移动到第5位(也就是从左数第二位移动到从左数第三位),那它的逆变换就应该是反过来,把第5位移动回第6位。所以00225F60逆变换回去就是02025F60。

    根据“Type 00”的“代码含义”,我们先把XYZ的含义确定一下,XXXXXXXX是00225F60,YYYYYY是000000,ZZ是FE。XXXXXXXX对应的真正地址是02025F60,我们把它套在“代码含义”里:

    用字节FE,将从(02025F60)到(02025F60+0)的地址区域填满。

    因为YYYYYY是0,这条代码其实就是填充了1个字节,也就是说,第一行中间代码等价于这条原始代码:

    这就和我们给出的29行原始代码的第一行对应上了(虽然从功能上来说,只完成了第一行代码的一部分)。

    再来看第二行中间代码:

    开头00仍然是“Type 00”的类型,00225F61逆变换回去是02025F61这个变量地址,和第一行不同的是,此时YYYYYY是6E,ZZ是FF,套在“代码含义”里:

    用字节FF,将从(02025F61)到(02025F61+6E)的地址区域填满。

    十六进制的6E是十进制的110,而110个字节就是880个二进制位,这一行代码就更改了880个精灵的图鉴状态!这一行代码会填充到哪里结束呢?我们算一下:02025F61+6E=02025FCF,它的下一个字节的地址就是02025FD0。也就是说,第二行中间代码等价于下面29行原始代码:

    最后再看第三行中间代码:

    和第一行相同,它对应的原始代码就是29行原始代码的最后一行:

    由此可见,3行V3格式码确实是完全等价到了我们之前得到的29行原始代码。

说在后面:

    上一期作者提到:“V3格式的金手指功能要比原始代码强大得多”。本期介绍的“全图鉴发现”金手指只是一道“开胃菜”,使用它能大大缩短金手指的行数。会举一反三的读者,应该可以自行探索“全图鉴捕捉”的V3格式码是什么:先得到原始代码,然后通过专栏介绍的两大工具一步一步转换到V3格式码,它的形式和“全图鉴发现”是完全相同的,区别仅在于变量地址而已。

    不知道读者会不会有这种想法:V3格式码看起来好难啊,又是加密又是逆变换的,搞的人头大。29行原始代码行数虽然多,但是每行代码含义都是那么简单明确,长就长吧,用起来的效果不还是和V3格式码一样的吗?事实上,V3格式码能做到的事情远远不止压缩行数这么简单,所以作者才说本期专栏的例子就是一道“开胃菜”,真正的大餐要等待下期——随身携带的精灵中心,这个功能是原始代码做不到的。

    原始格式的金手指只能做到修改变量,而V3格式的金手指可以做到写程序!这才是V3格式码真正强大的地方,让我们下期再见!



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3