2009-10-03 26 views
8

Szukam sposobu na odwrócenie a CRC32 checksum. Istnieją rozwiązania, ale są one albo badly written, extremely technical i/lub in Assembly. Zgromadzenie jest (obecnie) poza moim ken, więc mam nadzieję, że ktoś może ułożyć implementację w języku wyższego poziomu. Ruby jest idealna, ale mogę parsować PHP, Python, C, Java itp.Cofanie CRC32

Czy ktoś tak lubi?

+4

Co dokładnie masz na myśli, mówiąc o "odwrocie" –

+0

Po prostu przeniesiono implementację C do Pythona: https://github.com/jellever/Pwnage/blob/master/reversecrc.py –

+0

@JelleVergeer Czy możesz wskazać tabelę aby twój kod zadziałał. Co mogę dodać tutaj: # Niestandardowy stół CRC, zamień na własny table = [] –

Odpowiedz

17

CRC32 jest odwracalny tylko wtedy, gdy oryginalny ciąg ma 4 bajty lub mniej.

+1

Wątpię, crc wygeneruje unikalny 32-bitowy kod dla każdego łańcucha znaków 4 bajty lub mniej ... – Goz

+1

Jeśli spojrzysz na implementacja, na 4 bajty wykona 3 8-bitowe zmiany tylko z operacjami XOR, więc tak, jest odwracalna: http://www.sanity-free.org/12/crc32_implementation_in_csharp.html –

+0

To jest to, co początkowo pomyślałem, a potem ludzie wysłali linki wspomniane powyżej na mojej drodze ... oczywiście, fakt, że jest ograniczony do 4 bajtów został przemilczony. Dzięki za wyjaśnienia. – pat

0

Cade Roux Ma rację co do cofania CRC32.

Wymienione łącza zapewniają rozwiązanie problemu z korekcją CRC, która stała się nieaktywna poprzez zmianę oryginalnego strumienia bajtów. Ta poprawka jest osiągana przez zmianę niektórych (nieważnych) bajtów i odtworzenie oryginalnej wartości CRC.

+1

Lub hakowanie strumienia, aby CRC pozostało niezmienione, podczas gdy ważne dane (np. Kod antypiracki) zostały zmienione. –

5

Przeczytaj this fine document.

Jest to 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

Można odwrócić go przez wycofanie się bity do generowania oryginalnych 32 bity jeśli znasz poli został utworzony. Ale jeśli szukasz odwrócić CRC32 z danego pliku i dołączyć serię bajtów na końcu pliku, aby dopasować oryginalny CRC, napisałem kod na ten wątek w PHP:

Spędziłem trochę czasu na tak więc mam nadzieję, że może to pomóc osobie pracującej przy trudniejszych problemach: Reversing CRC32 Pozdrawiam!

Powiązane problemy