2009-10-03 27 views
8

Estoy buscando una manera de revertir a CRC32 checksum. Existen soluciones, pero son badly written, extremely technical y/o in Assembly. El ensamblaje está (actualmente) más allá de mi conocimiento, así que espero que alguien pueda armar una implementación en un lenguaje de nivel superior. Ruby es ideal, pero puedo analizar PHP, Python, C, Java, etc.Invertir CRC32

¿Alguna opinión?

+4

¿Qué quiere decir exactamente con 'reverse' –

+0

Acaba de portar una implementación de C a Python: https://github.com/jellever/Pwnage/blob/master/reversecrc.py –

+0

@JelleVergeer ¿Puede señalar la tabla necesaria? para que tu código funcione Qué puedo agregar aquí: #Calendario CRC personalizado, reemplace con su propia tabla = [] –

Respuesta

17

Un CRC32 solo es reversible si la cadena original tiene 4 bytes o menos.

+1

Dudo que crc genere un código único de 32 bits para cada cadena combo de 4 bytes o menos ... – Goz

+1

Si mira el implementación, para 4 bytes hará 3 cambios de 8 bits con solo operaciones XOR, entonces sí, es reversible: http://www.sanity-free.org/12/crc32_implementation_in_csharp.html –

+0

Esto es lo que inicialmente pensé, y luego la gente envió los enlaces mencionados arriba a mi manera ... obviamente, el hecho de que está limitado a 4 bytes se pasó por alto. Gracias por la aclaración. – pat

0

Cade Roux Tiene razón sobre la inversión de CRC32.

Los enlaces que mencionas proporcionan una solución para corregir un CRC que se ha invalidado al alterar el flujo de bytes original. Esta solución se logra al cambiar algunos bytes (sin importancia) y así recrear el valor original de CRC.

+1

O piratear la secuencia para que el CRC no cambie mientras se cambian los datos importantes (como el código antipiratería). –

5

Lea this fine document.

Ésta es 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

Puede revertirla sacando totalmente los bits para generar los originales de 32 bits si se conoce el poli que fue creado con. Pero si está buscando invertir el CRC32 de un archivo dado y anexar una serie de bytes al final del archivo para que coincida con el CRC original que publiqué código en este hilo en PHP:

Pasé un poco de tiempo en así que espero que pueda ayudar a alguien que esté trabajando en problemas más difíciles: Reversing CRC32 ¡Salud!