【问题标题】:How do I modify a file while maintaining its CRC-32 checksum?如何在保持 CRC-32 校验和的同时修改文件?
【发布时间】:2018-06-23 04:16:48
【问题描述】:

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

我有的信息

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

  • 32 位多项式代码。

【问题讨论】:

    标签: algorithm crc crc32


    【解决方案1】:

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

    它很繁琐,有很多小技巧,但很快。

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

    1122334455667788
    

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

    首先,根据需要对文件进行更改。例如,我在中间更改一个字节:

    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
    

    瞧,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
    

    此算法由 Redditor /u/supersaw7 发布于this thread。我还没有遇到过更好的版本,尽管更简单的版本很有可能。

    【讨论】:

    • 太棒了,看来它会起作用。我让它工作到第 6 步。我不明白应该怎么做才能进行位反转?逐字节。 .
    • Nvm,想通了。您必须反转每个字节的位。 bytes([int('{:08b}'.format(v)[::-1], 2) for v in binascii.unhexlify(format(0xe4c7d232, 'x'))])
    【解决方案2】:

    使用spoof。修改文件后,您需要确定一组允许更改的位位置,以将 CRC 恢复为原始值。您需要提供要返回的原始 CRC 和当前 CRC 的异或异或,以及您不关心的位位置,例如在字符串中,以及有关 CRC 本身和文件长度的一些信息。 spoof 然后将解决要翻转哪些位以获得所需的 CRC。该文档提供了有关您需要提供多少可变位位置的指导。

    您可以使文件保持相同的长度,也可以向文件中添加字节以创建您认为可以更改的位置。

    【讨论】:

    • 谢谢,我无法运行 Spoof。所以我搜索了类似的 github 项目并找到了CRC manipulator。命令行工具完美运行。
    • 您能否详细说明“我无法运行 Spoof”?
    • 欺骗没有问题。我只是不知道编译一个 C 程序。
    【解决方案3】:

    如果文件的大小不需要保持不变,您可以随意修改其内容,并添加一些字节 (4) 来修复校验和。

    可以添加哪些字节

    a) 计算,如果您了解使用的 CRC 算法或

    b)尝试蛮力尝试找到合适的字节(可能需要一段时间,但如果您不需要经常这样做,它仍然是一个可行的尝试

    【讨论】:

    • 谢谢,这游戏2个方向进去。4294967296排列,想着重启游戏很多次给我绝望的感觉。由于我知道 CRC 算法的代码,希望我能在一两天内弄明白。要么通过对级联数学的系统理解,要么通过算法进行强力检查。
    • CRC 计算是线性的,所以可以研究一下单比特翻转对 CRC 的影响,然后通过 XOR 组合结果。高斯消元过程允许您计算正确的组合。
    最近更新 更多