EVE 游戏文件分析(三)

ghidra / dosbox / imhex / eve

我们接着上一次,解决遗留的问题,然后遗留新的问题

多次读取

上一期我们的读取程序在四个平面读取完毕后就终止了,然后只画出了一点点图像, 所以一定是没有读完,从 dosbox-x 的日志我们也可以确认这一点:

一万多行就已经读到四个 0xff 了,但是进度条显然文件还有很多内容没读, 但是四个平面都已经读到了终止符,这应该也就是我们只画出一点点内容的原因。 但是 FUN_1427_38af 应该没有值得我们注意的内容了,所以我们要再往上看一层。 找上层代码的位置,最快的方法是看日志中回到了哪里:

1427:0000018F  inc  word cs:[00DC]             cs:[00DC]=00B4          2E FF 06 DC 00        EAX:00003AFF EBX:00003E6D ECX:000000FF EDX:0000434E ESI:0000001E EDI:00006874 EBP:00000F78 ESP:00000F6E DS:434E ES:3A28 FS:0000 GS:0000 SS:218C CF:0 ZF:0 SF:0 OF:0 AF:1 PF:1 IF:1 TF:0 VM:0 FLG:00007212 CR0:00000010

然后在 ghidra 中定位代码:

这里面有两个细节需要我们注意:

  1. 读取是一个有限次数的循环
  2. 每次读取,输出的起始位置都会有一个偏移量

所以需要引入一个偏移量,一个控制循环次数的变量,前面读取时,我默认每平面开始的偏移量都是 0, 那么改成每次读取完成后都加 1,就好了,然后对于循环的次数,这个数字其实是从文件中读取的:

读取出 0x09 位置的 0x28,然后除以 2 得到,事实上用 0x08 位置的 0x14 应该也可以。 因为看上去这三位保持 [0x08] * [0x0a] = [0x09] 的关系。

新的问题

解决了这两个问题,我们得到了这样一个图:

我们跟实际的画面做一个对比:

分析问题

首先我们的大方向肯定是对了,因为图形基本上已经出来了,只是问题也很明显:

  1. 图形有些地方颜色缺失,这应该是我们上一期的 19 个函数(以后简称绘图函数)的实现还有问题。
  2. 颜色的部分就不用说了,我们本来也没有指望调色版会对。
  3. 有些地方的颜色出现了错误,最明显的地方是右上的撇号,应该是纯色,但是我们画出来有两个颜色,这个问题不太好解释,比较合理的说法可能还是绘图函数中的某一个的处理有问题,导致平面数据错误,所以产生了错误的颜色。

所以我们接下来要找到调色板,以及我们之前绘图函数中的问题。

调色板

我们之前的系列,调色板基本无一例外都是猜出来的,这次也不例外,其实前面我们看到的黄色图像, 已经是我们猜测的第一版的结果了,重新看这里:

我们之前提到了 gdt 文件读取完第一行数据后会跳过 24 个字节,这 24 个字节一眼望上去没看出什么规律, 但是写完绘图函数后,再看这组数据可能就有感觉了,因为我们可以发现,这组数据以 000 开头,FFF 结尾。

这就很像是调色板了,为什么说写完绘图函数会理解这个, 是因为绘图函数中就有把 0xAE 展开为 0xAA 0xEE 的操作,这样看来的话,24 个字节, 展开后正好是 16 个颜色。所以如果这是调色板的数据,那么留给我们的问题变成了两个:

  1. RGB 三原色如何排列
  2. 四平面顺序如何排列

RGB 的排列有 6 种,四平面的排列虽然有 24 种,但是估计只会有 [0123] 和 [3210] 两种排法, 我想一般不会有人会设计出类似 [2301] 这种的排列方式,为自己徒增烦恼。对于上面的黄色图案, 我印象是按 RGB + [3210] 的排列方式画出来的,看来运气不是很好,不过很快也就发现,实际的排列方式是 BRG:

这个配色是不是就和实际的配色对上了,不要问我为什么会这样排,另外,四平面的排列方式是 [3210], 也就是第一个平面在最小位,可能也算是 little endian?

休息一下

总结我们已知的内容:

  1. 读取四平面的步骤会执行多次,每执行一次,增加一个字节偏移量
  2. 调色板在文件 0x10..0x28 的位置,以 BRG 的顺序排列,同屏 16 色,最多 4096 色(16x16x16)
  3. 四平面通过 [3210] 的顺序转换为颜色索引

目前我们还剩下绘图函数错误的问题,下次再分析吧,如果你的观察仔细,其实还有一个小问题, 我们也放在下次一起说吧。