我正在尝试对包含精灵的文件进行反向工程。我想从文件中提取精灵。到目前为止,我已经设法找到了某种行尾序列,并以此可以确定精灵是否位于文件中:我正在使用C ++和SDL。我将文件加载为一系列字符,如果char> 128则绘制白色像素,如果char <128则绘制黑色像素。这非常粗糙,我不知道该如何进行。如何找到颜色存储的位置?还是Alpha通道?还是标题中有什么?等。

如果您知道任何在线资源可能会有所帮助,请告诉我。我有点不知所措。这些是我尝试进行反向工程的文件中的前几个字节,也许会有所帮助:写这个游戏的翻版是我小时候的梦想。我目前正在重制图像,但是我使用的是占位符图形。那就是为什么我需要精灵。我不会将其用于商业目的。

有2种sprite文件。 * .tsp文件,以及一个大的sprites.data和sprites.info文件。我在这里上传了一些文件。

#1 楼

您开始得很好;将未知数据绘制为像素会立即向您显示这确实是图形数据,没有压缩(至少不是按钮),并且是可用的RGB顺序。我想缺少的RGB格式会让您退缩。现在您知道了,您可以编写一个简单的程序来绘制颜色并显示图像的偏移量和宽度。有了这些信息,您就可以检查图像之前(或之后)的未知字节,并得出它们的含义。由一系列图像组成,没有通用文件头,但每个图像都有一个头。

该头的第一个长字(4字节,小端格式)是以下数据的大小。字节,不包括标头本身(此长度可能是001_buttons.tsp)。然后按照字的宽度和高度。接下来的12个字节是3个字长的x,y对。第一对是图像的中心。坐标是带符号的单词,它们在0处环绕。其他的对仍然起着未知的作用。

之后,您的高度是下一个图像扫描行的偏移量(以字为单位),与起始位置的偏移量为4(所以4 + 2 * offset =下一行)。

这些偏移量所指向的每条扫描线均经过行程编码(RLE)压缩。透明行程仅由要跳过的水平像素数表示;不透明的运行可以直接复制到屏幕上。这些图像中没有Alpha透明度。每条扫描线在解压缩后会精确填充宽度的像素。 />
putpixel (x,y, (((val >> 8) & 0xf8)<<16) | (((val >> 3) & 0xfc)<<8) | ((val & 0x1f)<<3) );


其中0xFFFF/2只是下一个单词:RRRR.RGGG.GGGB.BBBB。格式



下文提到的所有值均为字大小(2字节,小端)。
每条扫描线均以该行的命令数开头,并带有指示以“跳过”还是“复制”开头的标志。如果命令数后的标记词为val,则该行以“ skip”开头;如果为data[c]+(data[c+1]<<8),则该行以“ copy”开头。命令交替进行,直到整个扫描线填满。每个命令都是要跳过或复制的像素数;对于“复制”,实际像素值紧随其后。

所有行均应完全填充-如有必要,命令列表以许多“空”像素结尾。




并非0000中的所有对象都是这种格式的子画面。至少有两种不同的类型:使用相同的RLE压缩方案但没有像素数据的单色蒙版对象-仅包含每次运行的长度。这可能是绘制遮罩,叠加颜色或帮助选择像素完美的对象。
未知用途的带符号单词对列表。

这些对象和实际的Sprite都不开头有一个可识别的标识符,因此您只能通过反复尝试找出哪个标识符(例如:如果报告的图像“大小”为负数或大于整个数据文件,则您知道它不能是毕竟是RLE压缩的图像。它具有以下格式:

4 x some byte flag (all `01` in this file)
long  total number of objects (377, in this file)
377 x
      0-terminated "filename" (obfuscated)
      long offset in 'sprite.data'
      long length in 'sprite.data'


通过向每个字符添加常量0001来混淆文件名。对此进行解码,您将获得377个项目的列表:

__extras\compplay.ps6                | 00000000 000000C0
__extras\dim1.ps6                    | 000000C0 00000BC4
__extras\dim2.ps6                    | 00000C84 00000EB4
...
units\tur_05_blue.ps6                | 01FAC346 00013E12
units\tur_05_gren.ps6                | 01FC0158 00013E12
units\turrets_shadow.ps6             | 01FD3F6A 00013C9C


这是某种通用索引,因为显然未列出所有图像。它必须只列出动画集中的第一个。那么,“长度”就是该特定集中所有文件的总长度。文件扩展名暗示了它们的内容:以sprites.data结尾的文件都至少包含一个图像(并且可能包含更多图像),以sprite.info结尾的文件可能是单色蒙版,而10则可能是阴影。 .ps6文件包含坐标对。

评论


哇。我对人们在互联网上的帮助程度感到惊讶。我以为我永远不会得到有用的答复。这很有帮助!非常感谢你。我仍在努力整合您所说的一切。快速提问,SDL与Uint8 r,Uint8 g,Uint8 b一起使用。如何将24位rgb值转换为这8位值?我也会自己处理。

– DnDiene
15年1月28日在12:07



我想到了!现在,我将处理您所说的其他事情

– DnDiene
15年1月28日在12:22

仅供参考,我对那些行偏移量是正确的。 RLE有点复杂。

–杂件
15年1月28日在12:27

使用您建议的偏移量,我似乎正在从sprites.data获取图像,但是它们像这样失真。我会继续尝试,但这也许会提供一些线索。我觉得我好亲近!

– DnDiene
15年1月28日在13:16



那是因为RLE压缩,我已经提到了。

–杂件
15年1月28日在14:57

#2 楼

如果您真的想了解文件的每个字节,那么正如Jason所指出的,您将必须获得读取该文件的程序并对它进行反向工程。

当然,这可能在某个地方在困难与不可能之间,也非常耗时。所以问题是你想做什么。从文件中提取某个精灵?更改某些子画面的颜色?将游戏翻译成其他语言?可能您不需要出于自己的目的而理解整个文件。还是那两个字节?十六进制转储包含很多00,所以也许这是16位字,其中仅使用低字节。您可以尝试用相同的值替换其中一个精灵的每个像素(=十六进制值)。启动游戏,检查精灵的颜色。用其他值重复。您也许可以算出哪个值对应哪种颜色。

该图像表明这些精灵具有不同的宽度。您可以计算像素(宽度和高度),然后在十六进制转储中搜索这些计数。这可能有助于您确定每个子画面前面的标头的结构。

如果您知道每个子画面的大小(以字节为单位),则可以在十六进制转储或文件头。或者,标头可能包含子画面数和文件中的起始位置数组。

所以,总结一下:


写下可以用整数表示的所有内容。在文件中搜索这些整数。
当您认为自己知道文件中某个字节的内容时,请考虑一下如果将该字节更改为其他内容会发生什么。更改该字节,启动原始程序,然后检查其更改后的行为是否符合您的假设。
根据需要重复。

另一个建议:将任何内容发布到此处时,请尽可能多地添加信息。例如,在允许版权的情况下,发布整个sprite文件,而不是其十六进制转储的图像-您可以假设,如果有人感兴趣,他们可以自己将文件下载到十六进制查看器。如果您有部分源代码,请发布指向该源代码的链接。关于逆向工程的经验很多,比如“我以前见过类似的东西-那时是XXX”。有人可能只是看着您的出处并记住了一些东西。或者,某人可能有一个主意,并将问题视为“难题挑战”。如果您可以使用当前的源代码,则测试此想法会容易得多。做了一些研究,发表了他的结果,没有得到进一步的发展,并失去了兴趣。那帮助了我入门,我联系了那个家伙,我们在一起终于取得了一些成果。因此,即使现在没有人可以为您提供帮助,您也不知道未来会发生什么。

(当然,如果您发布了游戏名称...)