反转CRC32

我找到了一个代码来反转CRC32,但我不知道它是如何工作的,因为我在编程方面不是那么好,我刚刚开始。 我只想比较2个文件,旧的和新的,然后在新修复CRC32在文件的末尾添加4个字节,因此2个文件将具有相同的CRC32。 这是代码,在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 > 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 <> (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) < 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; } } } 

这里有一些PHP代码也会做你想要的东西我花了很多时间试图为合法目的这样做,所以我希望它可以帮助某人

这样的function可用于:

  1. 总是有一个validation文件的哈希(例如,某种类型的所有文件都返回一个普通的crc,版本控制等没有数据库)
  2. 修改哈希分布的方式(例如分布式计算密钥平衡)
  3. 反转crc32的原始4个字节

要在线测试crc32字符串,您可以使用: http : //www.lammertbies.nl/comm/info/crc-calculation.html

请参阅http://www.reversing.be/article.php?story=20061209172953555 ,因为我不是原作者,原版在他的文章上花了很多时间,而且它在小路

这是PHP代码,可用于修改给定文件,如下所示:

  AB CD EF 66 Take for CRC register after, f3 f2 f1 f0 -> 56 33 14 78 (wanted value) Here we go: First byte of entries entry value e3=f3 =56 -> 35h=(4) 56B3C423 for e3 e2 e1 e0 d3=f2+e2 =33+B3 =E6 -> 4Fh=(3) E6635C01 for d3 d2 d1 d0 c3=f1+e1+d2 =14+C4+63 =B3 -> F8h=(2) B3667A2E for c3 c2 c1 c0 b3=f0+e0+d1+c2=78+23+5C+66=61 -> DEh=(1) 616BFFD3 for b3 b2 b1 b0 Now we have all needed values, then X=(1)+ a0= DE+66=B8 Y=(2)+ b0+a1= F8+D3+EF=C4 Z=(3)+ c0+b1+a2= 4F+2E+FF+CD=53 W=(4)+d0+c1+b2+a3=35+01+7A+6B+AB=8E (final computation) */ $ExistingCRC = ~$ExistingCRC; $DesiredCRC = ~$DesiredCRC; //a3a2a1a0 $a3 = (($ExistingCRC & 0xFF000000) >> 24) & 0x000000FF; $a2 = ($ExistingCRC & 0x00FF0000) >> 16; $a1 = ($ExistingCRC & 0x0000FF00) >> 8; $a0 = ($ExistingCRC & 0x000000FF); //f3f2f1f0 $f3 = (($DesiredCRC & 0xFF000000) >> 24) & 0x000000FF; $f2 = ($DesiredCRC & 0x00FF0000) >> 16; $f1 = ($DesiredCRC & 0x0000FF00) >> 8; $f0 = ($DesiredCRC & 0x000000FF); //echo "Existing CRC:" . dechex($ExistingCRC) . " DesiredCRC:" . dechex($DesiredCRC) . "
"; //echo "a3:" . dechex($a3) . " a2:" . dechex($a2) . " a1:" . dechex($a1) . " a0:" . dechex($a0) . "
"; //echo "f3:" . dechex($f3) . " f2:" . dechex($f2) . " f1:" . dechex($f1) . " f0:" . dechex($f0) . "
"; //capture e3/e2/e1/e0/(4) values for ($i = 0; $i < 256; $i++) { if (($crc32lookup[$i] & 0xFF000000 ) == ($DesiredCRC & 0xFF000000)){ $e3 = (($crc32lookup[$i] & 0xFF000000) >> 24) & 0x000000FF; $e2 = ($crc32lookup[$i] & 0x00FF0000) >> 16; $e1 = ($crc32lookup[$i] & 0x0000FF00) >> 8; $e0 = ($crc32lookup[$i] & 0x000000FF); $four = $i; break; } } //echo "e3:" . dechex($e3) . " e2:" . dechex($e2) . " e1:" . dechex($e1) . " e0:" . dechex($e0) . "
"; //$d3=f2+e2 =33+B3 =E6 -> 4Fh=(3) E6635C01 for d3 d2 d1 d0 $d3 = $f2^$e2; //lookup $d3 and assign the values for d2/d1/d0/(3) for ($i = 0; $i < 256; $i++) { if (($crc32lookup[$i] & 0xFF000000 ) == ($d3 << 24)){ $d2 = ($crc32lookup[$i] & 0x00FF0000) >> 16; $d1 = ($crc32lookup[$i] & 0x0000FF00) >> 8; $d0 = ($crc32lookup[$i] & 0x000000FF); $three = $i; break; } } //echo "d3:" . dechex($d3) . " d2:" . dechex($d2) . " d1:" . dechex($d1) . " d0:" . dechex($d0) . "
"; //c3=f1+e1+d2 =14+C4+63 =B3 -> F8h=(2) B3667A2E for c3 c2 c1 c0 $c3 = $f1^$e1^$d2; for ($i = 0; $i < 256; $i++) { if (($crc32lookup[$i] & 0xFF000000 ) == ($c3 << 24)){ $c2 = ($crc32lookup[$i] & 0x00FF0000) >> 16; $c1 = ($crc32lookup[$i] & 0x0000FF00) >> 8; $c0 = ($crc32lookup[$i] & 0x000000FF); $two = $i; break; } } //echo "c3:" . dechex($c3) . " c2:" . dechex($c2) . " c1:" . dechex($c1) . " c0:" . dechex($c0) . "
"; //b3=f0+e0+d1+c2=78+23+5C+66=61 -> DEh=(1) 616BFFD3 for b3 b2 b1 b0 $b3 = $f0^$e0^$d1^$c2; for ($i = 0; $i < 256; $i++) { if (($crc32lookup[$i] & 0xFF000000 ) == ($b3 << 24)){ $b2 = ($crc32lookup[$i] & 0x00FF0000) >> 16; $b1 = ($crc32lookup[$i] & 0x0000FF00) >> 8; $b0 = ($crc32lookup[$i] & 0x000000FF); $one = $i; break; } } /* Now we have all needed values, then X=(1)+ a0= DE+66=B8 Y=(2)+ b0+a1= F8+D3+EF=C4 Z=(3)+ c0+b1+a2= 4F+2E+FF+CD=53 W=(4)+d0+c1+b2+a3=35+01+7A+6B+AB=8E (final computation) */ $X = $one ^ $a0; $Y = $two ^ $b0^$a1; $Z = $three ^ $c0^$b1^$a2; $W = $four ^ $d0 ^ $c1 ^ $b2^$a3; //echo "Four:" . dechex($four) . " Three:" .dechex($three)." Two:".dechex($two)."One:" .dechex($one) . "
"; //echo "X:" . dechex($X) . " Y:" . dechex($Y) . " Z:" . dechex($Z) . " W:" . dechex($W) . "
"; return chr($X) . chr($Y) . chr($Z) . chr($W); } ?>

您想知道它是如何工作的,或者如何使用它?

如果是后者,则来自代码签名:

 public void FixChecksum(byte[] bytes, int length, int fixpos, uint wantcrc) 

您似乎将第二个文件的内容放入一个数组(最后在修复的末尾有4个字节),并将其作为bytes参数传递。 您将此数组的length作为length参数传递,您将偏移量传递到插入修复的位置(在本例中为length – 4)作为fixpos参数,并将您想要的CRC作为wantcrc参数,您可以获得该值,通过计算第一个文件的CRC。

FixChecksum方法似乎在您提供的偏移量处提供的数组中写入4个字节的修复。 在调用FixChecksum您只需将结果写入第二个文件即可。