Python 3.7 zlib解压缩后的大小小于压缩后的大小

时间:2019-01-12 22:00:11

标签: python-3.x reverse-engineering zlib

我写了一个小的python代码,该代码应该解压缩一个约180Mb的大型二进制文件。问题是它只能解压缩约50Mb。 我想知道以前是否有人遇到过类似的奇怪问题,并找到了解决方案。

import zlib, sys
text = open('REG_E.rzp','rb').read()
print(sys.getsizeof(text))
# 187424785


decompressed = zlib.decompress(text)
print(sys.getsizeof(decompressed))
# 50001
open('cecomp.bin','wb').write(decompressed)


recomp = zlib.compress(decompressed)
print(sys.getsizeof(recomp))
# 6227
open('recomp.bin','wb').write(recomp);

另一个奇怪的事情是,根据sys.getsizeof(),当我尝试重新压缩它时,生成的文件只有6Mb。 这是因为我压缩的数据较少。 :stupidme:

其他信息:最初解压缩的50Mb是正确的,并且在十六进制编辑器中可读。所以我想知道,一次可以解压缩多少zlib是否有限制?我没有收到任何错误消息,因此我对此有些疑惑。

我怀疑这是因为内存不足(我有8gig),但是我不知道Python3可以访问多少堆。

更新: 使用zlib.decompress(text,9),我可以正确地取回原始文件! 翻译完成后,重新包装游戏会很有用。 enter image description here

Update2: 我正在尝试对旧的(2011)主机游戏进行逆向工程。我有第一场比赛的英文和日文版本,以及续集的日文版本。 (由于销售不佳,它尚未本地化)。每种文件的格式都相同,我高度赞赏,但是它们全部3个都损坏了。 是否有任何特殊的二进制字符串会停止解压缩,因为解压缩器会将其作为终止符号读取?

整个游戏都包装在此180Mb(续集约为230)文件中。就是说,我的意思是大约有6k文件夹,其中有12k个文件串联在一起。有一个索引文件(称为.RZL),用于记录结构,偏移量,压缩大小和未压缩大小。

我在某处读到,因此,无法立即解压缩该文件,因为每个块的zlib标头都不同。这是真的? 我不知道zlib标头的样子。

What does a zlib header look like? 引用此:

  

实际上,这意味着第一个字节几乎总是78(十六进制)

如果查看我的图像,可以看到文件确实以78开始。

3 个答案:

答案 0 :(得分:2)

您似乎无法正确关闭文件,因此文件可能未完全写入:

import zlib, sys
with open('REG_E.rzp','rb') as f:
    text = f.read()
    print(sys.getsizeof(text))

decompressed = zlib.decompress(text)
print(sys.getsizeof(decompressed))

with open('cecomp.bin','wb') as f:
    f.write(decompressed)

recomp = zlib.compress(decompressed)
print(sys.getsizeof(recomp))
with open('recomp.bin','wb') as f:
    f.write(recomp)

添加with块可确保您正在关闭文件(这也将确保您实际上已完成对磁盘的写入)。

答案 1 :(得分:0)

从文件扩展名来看,它似乎已被rzip而非gzip压缩。 Rzip使用bzip2,而不是zlib的DEFLATE。 Python的zlib模块可能无法读取该格式。

答案 2 :(得分:0)

问题解决了。存档必须逐文件解压缩。 在图像中,您可以看到重新压缩的文件以及原始文件。幸运的是,他们排队。 在下一个zlib标头之前,该行用零填充:78 DA

enter image description here

猜猜我要写一个C程序了。 感谢您的帮助!