2009-10-03 10 views
8

Je cherche un moyen de renverser a CRC32 checksum. Il existe des solutions autour, mais ils sont badly written, extremely technical et/ou in Assembly. L'assemblage est (actuellement) au-delà de mon ken, donc j'espère que quelqu'un peut assembler une implémentation dans un langage de plus haut niveau. Ruby est idéal, mais je peux analyser PHP, Python, C, Java, etcInverser CRC32

Les preneurs?

+4

Que voulez-vous dire exactement par « inverse » –

+0

juste une implémentation Ported C à Python: https://github.com/jellever/Pwnage/blob/master/reversecrc.py –

+0

@JelleVergeer Pouvez-vous indiquer à la table nécessaire pour que votre code fonctionne. Que puis-je ajouter ici: # Table CRC personnalisée, remplacez par votre propre table = [] –

Répondre

17

Un CRC32 est uniquement réversible si la chaîne d'origine est de 4 octets ou moins. Cade Roux a raison d'inverser CRC32.

+1

Je doute que crc génère un code 32 bits unique pour chaque chaîne de caractères de 4 octets ou moins ... – Goz

+1

Si vous regardez le mise en œuvre, pour 4 octets il fera 3 décalages de 8 bits avec seulement des opérations XOR, donc oui, il est réversible: http://www.sanity-free.org/12/crc32_implementation_in_csharp.html –

+0

C'est ce que j'avais initialement pensé, et puis les gens ont envoyé les liens mentionnés ci-dessus à ma façon ... évidemment, le fait qu'il est limité à 4 octets a été passé sous silence. Merci pour la clarification. – pat

0

Les liens que vous avez mentionnés fournissent une solution pour corriger un CRC qui est devenu invalide en modifiant le flux d'octets d'origine. Cette correction est obtenue en modifiant certains octets (sans importance) et donc recréer la valeur CRC d'origine.

+1

Ou pirater le flux de sorte que le CRC reste inchangé pendant que les données importantes (comme le code anti-piratage) sont modifiées. –

5

Lecture this fine document.

C'est 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

Vous pouvez inverser en dévissant les bits pour générer les 32 bits d'origine si vous connaissez le poly il a été créé. Mais si vous cherchez à inverser le CRC32 d'un fichier donné et ajouter une série d'octets à la fin du fichier pour correspondre à la CRC d'origine, j'ai posté du code sur ce fil en PHP:

J'ai passé un peu de temps sur J'espère que cela peut aider quelqu'un qui travaille sur des problèmes plus difficiles: Reversing CRC32 Cheers!