如何修改文件同时保留其 CRC-32 校验和?

1 algorithm crc32 crc

我正在尝试修改的一款旧游戏有 CRC-32 检查。我无权访问 CRC 校验和本身,因此我必须修改文件,同时保持相同的校验和输出。

我有的信息

  • 文件,如果文件本身是CRC-32程序的唯一输入,我可以计算出CRC-32校验和应该是什么。

  • 32 位多项式代码。

Hea*_*ery 7

正如 @MrSmith42 所说,只要您不需要保持文件长度恒定,就可以轻松计算“冲突”(为产生相同哈希的两个输入消息指定的名称)。

它很繁琐,有很多麻烦,但速度很快。

假设原始文件是十六进制的:

1122334455667788
Run Code Online (Sandbox Code Playgroud)

那么它的 CRC-32 校验和将0x9118E1C2使用标准 CRC32 多项式。如果使用的算法不标准,可以替换。为了演示目的,我将坚持使用该标准。

首先,根据需要更改文件。例如,我改变中间的一个字节:

11223344FF667788
Run Code Online (Sandbox Code Playgroud)

恢复 CRC 的第一步是用 4 个零字节填充文件:

11223344FF66778800000000
Run Code Online (Sandbox Code Playgroud)

CRC 校验和现在为0x6BBE83C9

第二步,对两个校验和进行异或:

0x9118E1C2 XOR 0x6BBE83C9 = 0xFAA6620B
Run Code Online (Sandbox Code Playgroud)

第三步,对结果进行位反转:

Bit reverse of 0xFAA6620B = 0xD046655F
Run Code Online (Sandbox Code Playgroud)

第四步,这有点奇怪,所以请参见下面,执行逆 CRC32 计算:

0xD046655F * inverse(x32) mod crc_poly = 0xe4c7d232
Run Code Online (Sandbox Code Playgroud)

第五步,这次按字节对结果进行位反转:

0xe4c7d232 bit reversed byte-wise = 0x27E34B4C
Run Code Online (Sandbox Code Playgroud)

第六步,用结果替换填充字节

11223344FF66778827E34B4C
Run Code Online (Sandbox Code Playgroud)

瞧,CRC32 校验和值现在又回到了 0x9118E1C2。

据我所知,进行逆 CRC 计算的最简单方法是使用 Python 中的 BitVector 包:

>>> import BitVector as bv
>>> poly = bv.BitVector(intVal = 0x104C11DB7) # "standard" CRC32 polynomial
>>> inv = bv.BitVector(intVal = 0x100000000).gf_MI(poly, 32)
>>> k = 0xD046655F
>>> p = bv.BitVector(intVal = k).gf_multiply_modular(inv, poly, 32)
>>> print(p.getHexStringFromBitVector())
e4c7d232
Run Code Online (Sandbox Code Playgroud)

该算法是由 Redditor /u/supersaw7 在此线程中发布的。尽管更简单的版本是非常可能的,但我还没有遇到更好的版本。