2009-10-03 13 views
8

Sto cercando un modo per invertire a CRC32 checksum. Ci sono soluzioni in giro, ma sono o badly written, extremely technical e/o in Assembly. Assembly è (al momento) al di fuori del mio ken, quindi spero che qualcuno possa mettere insieme un'implementazione in un linguaggio di livello superiore. Ruby è l'ideale, ma posso analizzare PHP, Python, C, Java, ecc.Inversione CRC32

Chi prende?

+4

Che cosa intendete esattamente con "reverse" –

+0

Ho appena portato a Python un'implementazione C: https://github.com/jellever/Pwnage/blob/master/reversecrc.py –

+0

@JelleVergeer Potete puntare al tavolo necessario perché il tuo codice funzioni. Cosa posso aggiungere qui: #Clabella CRC personalizzata, sostituirla con la propria tabella = [] –

risposta

17

Un CRC32 è reversibile solo se la stringa originale è di 4 byte o meno.

+1

Dubito che crc genererà un codice univoco a 32 bit per ogni stringa combo 4 byte o meno ... – Goz

+1

Se si guarda il implementazione, per 4 byte farà 3 turni a 8 bit con solo operazioni XOR, quindi sì, è reversibile: http://www.sanity-free.org/12/crc32_implementation_in_csharp.html –

+0

Questo è quello che inizialmente avrei Ho pensato, e poi ho chiesto alla gente di mandare i link menzionati sopra a modo mio ... ovviamente, il fatto che sia limitato a 4 byte è stato sorvolato. Grazie per il chiarimento. – pat

0

Cade Roux Ha ragione sull'inversione del CRC32.

I collegamenti citati forniscono una soluzione per correggere un CRC che è diventato invalido alterando il flusso di byte originale. Questa correzione si ottiene modificando alcuni byte (non importanti) e ricreando quindi il valore CRC originale.

+1

Oppure hackerare lo stream in modo che il CRC non venga modificato mentre vengono modificati dati importanti (come il codice antipirateria). –

5

Leggi this fine document.

Questo è 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; 
     } 
    } 
} 
1

È possibile invertire appoggiando i bit per generare le originali 32 bit se si conosce il poli è stato creato con. Ma se stai cercando di invertire il CRC32 da un dato file e aggiungere una serie di byte alla fine del file per abbinarlo al codice CRC originale pubblicato su questo thread in PHP:

Ho trascorso un po 'di tempo su spero quindi che possa aiutare qualcuno che lavora su problemi più difficili: Reversing CRC32 Cheers!