Question

I'm looking for a way to reverse a CRC32 checksum. There are solutions around, but they are either badly written, extremely technical and/or in Assembly. Assembly is (currently) beyond my ken, so I'm hoping someone can piece together an implementation in a higher level language. Ruby is ideal, but I can parse PHP, Python, C, Java, etc.

Any takers?

Was it helpful?

Solution

A CRC32 is only reversible if the original string is 4 bytes or less.

OTHER TIPS

Read the document called "Reversing CRC Theory and Practice".

This is C#:

public class Crc32
{
    public const uint poly = 0xedb88320;
    public const uint startxor = 0xffffffff;

    static uint[] table = null;
    static uint[] revtable = null;

    public void FixChecksum(byte[] bytes, int length, int fixpos, uint wantcrc)
    {
        if (fixpos + 4 > length) return;

        uint crc = startxor;
        for (int i = 0; i < fixpos; i++) {
            crc = (crc >> 8) ^ table[(crc ^ bytes[i]) & 0xff];
        }

        Array.Copy(BitConverter.GetBytes(crc), 0, bytes, fixpos, 4);

        crc = wantcrc ^ startxor;
        for (int i = length - 1; i >= fixpos; i--) {
            crc = (crc << 8) ^ revtable[crc >> (3 * 8)] ^ bytes[i];
        }

        Array.Copy(BitConverter.GetBytes(crc), 0, bytes, fixpos, 4);
    }

    public Crc32()
    {
        if (Crc32.table == null) {
            uint[] table = new uint[256];
            uint[] revtable = new uint[256];

            uint fwd, rev;
            for (int i = 0; i < table.Length; i++) {
                fwd = (uint)i;
                rev = (uint)(i) << (3 * 8);
                for (int j = 8; j > 0; j--) {
                    if ((fwd & 1) == 1) {
                        fwd = (uint)((fwd >> 1) ^ poly);
                    } else {
                        fwd >>= 1;
                    }

                    if ((rev & 0x80000000) != 0) {
                        rev = ((rev ^ poly) << 1) | 1;
                    } else {
                        rev <<= 1;
                    }
                }
                table[i] = fwd;
                revtable[i] = rev;
            }

            Crc32.table = table;
            Crc32.revtable = revtable;
        }
    }
}

You can reverse it by backing out the bits to generate the original 32 bits if you know the poly it was created with. But if you are looking to reverse the CRC32 from a given file and append a series of bytes at the end of the file to match the original CRC I posted code on this thread in PHP:

I spent a bit of time on it so I hope it can assist someone working on tougher problems: Reversing CRC32 Cheers!

Cade Roux Is right about reversing CRC32.

The links you mentioned provide a solution to fix a CRC that has become invalide by altering the original byte stream. This fix is achieved by changing some (unimportant) bytes and so recreate the original CRC value.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top