识别/逆向工程 lz 压缩

逆向工程 文件格式
2021-07-08 07:01:05

我正在为Prototype(日本公司)发布的游戏的PSP版本做翻译项目,但是我遇到了一些GIM文件(图像文件)的问题。现在实际问题不在于 gim 格式,而是对 gim 文件进行了压缩,但在此之前我将澄清一些事情。GIM 的一些工作,但是有时会出现 puyotools 或 GimConv(将 gim 转换为 png 的软件)都无法处理的 GIM 文件。不起作用的GIM在外观上有点不同。我知道它是一个 GIM 文件,因为它以:MIG.00.1PSP 开头,但确切地说,它有点不同,写成这样:

[integer equals 16, signature?] [integer equals 131792] [MIG.00.1PSP, but where a 00 HEX is placed between each hex byte]

像这样:

10 00 00 00 D0 02 02 00 4D 00 49 00 47 00 2E 00 30 00 30 00 2E 00 31 00 50 00 53 00 50 00 00 00

每个压缩的 GIM 文件都以这两个整数值开头(但是我的分辨率较小的图像具有不同的第二个整数)。我已经尝试删除这两个整数并尝试替换 M(00)I(00)G(00).(00)0(00)0(00).(00)1(00)P(00)S( 00)P(00),简单地使用 MIG.00.1PSP,但这最终让 GIMConv 说:错误的块数据。

我还尝试使用 signrch 和 TrID 分析文件以寻找某种提示,但 signrch 什么也没找到,TrID 只找到:“100 .0% (.) LTAC 压缩音频 (v1.61) (1001/2)”

这是名为:black.gim(黑色图像)的文件 在此处输入图片说明

这是一个随机CG: 在此处输入图片说明

这是一个随机的 gim 文件,用于参考未压缩版本的外观。请注意,第二行的前 4 个字节表示文件大小减去 16。另一个是 MIG.001.PSP 之后的 int,我从不同来源发现它是版本号。因此,所有压缩文件也可能会得到那个 int 。 在此处输入图片说明 更新:我相信这是某种 lz 压缩,但我还没有弄清楚是哪一种。试过 lz01,lz00,lz10,lz11,CXLZ, lzss 。在我看来它像lz一样以10字节开头,它使MIG.001.PSP被00分隔,由于依赖于值,密钥对的压缩,我认为密钥0意味着应该直接发送值到输出。<- 如果您确信它是我尝试过的压缩之一,请也这么说,因为它很可能只是我用来尝试那些有问题的压缩的工具。GZIP 和 deflate 在 C# 中使用 .NET 的 System.IO.Compression 进行了尝试,其他的已经使用称为 Puyo 工具的东西进行了尝试。

更新:看起来我几乎已经弄清楚了,基本上一个键等于解压缩数据的零输出值。如果 key 大于零,则获取 [Value,key-1] 的短值。这个短加 8 乘以 2 给出了它必须写出两次以解压缩数据的字节。换句话说,00 00 08 01 将输出 00 00 00。唯一的问题是第 3 行的 black.gim 示例中的 0f 01。这将指向 15,即位置 (15 + 8)*2 等于字节 46 应该是第二行的 02 00。然而这是不正确的!因为我希望它在那里放置零,而不是输出 02 02..

简而言之,在 black.gim 示例中,我发现: 0C 01 应该输出 00 00 0D 01 应该输出 00 00 00 0F 01 应该输出 00 00

有什么建议?

如果有人能给我一些意见或领导,我会非常高兴:)

1个回答

这里是给大家可能遇到模拟压缩压缩GIM文件的完整答案。基本上文件是这样开始的: [magic number 10 00 00 00] [Integer with uncompressed size of file] 在此之后压缩文件开始。压缩的基本功能如下:(在解压方面)

-> 取接下来的 2 个字节。

-> 第二个字节是否为零?

  • 将第一个字节写入解压输出。

-> 第二个字节是否大于 0?

这是一个指针,其工作是利用以前使用过的字节。它指向的位置等于无符号短值:[第一个字节,第二个字节减1]*2 + 8。当一个指针在它指向的位置读取时,它将读取接下来的4个字节,而不仅仅是下一个2 个字节。如果指向位置的字节是:00 02 0C 01,那么解压后的输出将是 02 ?? 在哪里 ??将是它所指向的前两个字节的结果。换句话说,如果我们指向 0C 01 02 00,那么输出 0C 01 将被其指向的结果替换。假设它指向 08 00 00 00,那么最后一个指针的输出将是 08 00 00 00,它将替换 0C 01 并变成:08 00 00 00 02 00,最后将输出 08 00 02 到解压输出。*请注意,作为第二个字节放置的指针不能被四个字节替换,而只能被通常是结果的前两个字节替换。如果第二个字节指向第一个字节,那么它只会得到第一个字节的结果。

来自第一篇文章 (Black.gim) 的图像示例: 在第一张图像中:0c 01 指向 00 00 0C 01,输出 00 00。在第一张图像中,0d 01 指向 0C 01 0C 01,输出 00 00 00. <- 注意如何只有指向位置的前两个字节有权将指向它的结果扩展两个字节。第一张图中:0F 01指向02 00 0D 01,输出02 00

-> 这样做直到没有字节剩余..

关于建议的 LZJB,我会立即检查。如果它是正确的,我仍然获得了有关逆向工程文件的丰富经验。