我正在尝试修改的旧游戏有CRC-32检查。我无法访问CRC校验和本身,所以我必须修改文件,同时保持相同的校验和输出。
我有信息
该文件,如果文件本身是CRC-32程序的唯一输入,我可以计算出CRC-32校验和应该是什么。
32位多项式代码。
答案 0 :(得分:4)
正如@ MrSmith42所说,如果你不需要保持文件长度不变,就可以很容易地计算出“碰撞”(两个输入消息的名称导致相同的散列)。
这很繁琐,有点麻烦,但很快。
假设原始文件是十六进制:
1122334455667788
然后使用标准CRC32多项式对其CRC-32校验和进行0x9118E1C2
。如果使用的算法不是标准的,则可以替换它。为了演示目的,我会坚持使用标准。
首先,根据需要更改文件。例如,我在中间更改了一个字节:
11223344FF667788
恢复CRC的第一步是用4个零字节填充文件:
11223344FF66778800000000
CRC校验和现在是0x6BBE83C9
。
第二步,对两个校验和进行异或运行:
0x9118E1C2 XOR 0x6BBE83C9 = 0xFAA6620B
第三步,反转结果:
Bit reverse of 0xFAA6620B = 0xD046655F
第四步,这有点时髦,如下所示,执行逆CRC32计算:
0xD046655F * inverse(x32) mod crc_poly = 0xe4c7d232
第五步,这次按字节顺序反转结果:
0xe4c7d232 bit reversed byte-wise = 0x27E34B4C
第六步,用结果
替换填充的字节11223344FF66778827E34B4C
Voila,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
此算法由this thread中发布的Redditor / u / supersaw7发布。尽管更简单的版本很有可能,但我没有遇到过更好的版本。
答案 1 :(得分:1)
如果文件的大小不需要是常量,您可以根据需要简单地修改其内容,并添加一些字节(4)来修复校验和。
要添加的字节可以是
a)计算,如果您了解使用的CRC算法或
b)尝试蛮力尝试找到合适的字节(可能需要一段时间,但如果你不需要经常这样做,那它仍然是可行的尝试答案 2 :(得分:1)
使用spoof。修改文件后,您需要确定一组位允许更改的位位置以将CRC返回到原始值。您需要提供带有您想要返回的独占或原始CRC的欺骗,以及当前的CRC,以及您不关心的位位置,例如:在字符串中,以及有关CRC本身和文件长度的一些信息。然后, spoof 将解决哪些位要翻转以获得所需的CRC。该文档提供了有关您需要提供多少可变位位置的指导。
您可以保留文件的长度相同,也可以在文件中添加字节以创建您认为可更改的位置。