歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux編程 >> Linux編程

CRC32 逆向算法的C語言實現

CRC32:

CRC32校驗應用很廣泛。本文提供一種算法添加4個字節實現任意的crc32校驗值轉換,逆向計算crc32的值。可以隨意修改文件任意4個字節實現任意的crc32校驗值。

原理:

下面是一組CRC32計算過程:

添加了四個字節00ba ff 30, 原crc32值2be0dd1d變成eee8a9a6。

src32val:2be0dd1d ^ 00 -->x=1d

src32val:002be0dd ^

T(x) : 63066cd9

src32val:632d8c04 (現在計算的CRC值)

src32val:632d8c04 ^ 00-->x=04 x[4]

src32val:00632d8c ^

T(x) : 076dc419

src32val:070ee995

src32val:070ee995 ^ ba-->x=2f x[3]

src32val:00070ee9 ^

T(x) : abd13d59

src32val:abd633b0

src32val:abd633b0 ^ ff-->x=4f x[1]

src32val:00abd633 ^

T(x) : e6635c01

src32val:e6c88a32

src32val:e6c88a32 ^ 30-->x=02 x[0]

src32val:00e6c88a ^

T(x) : ee0e612c tx

src32val:eee8a9a6 (添加4個字節後的目標CRC值)

事實上,crc32的table裡256個元素的最高位是唯一的。

可以通過crc32值倒推前四個crctable值,如圖綠色部分。

1.由最終的crc值推導出前4個T(x)值,即:T(x) x 已知。

2.由原CRC32值結合x值,推導出4個所要添加的未知字節。

以下是C語言的一個實現:

程序輸出:

www.linuxidc.com @ www.linuxidc.com :~/sniffer/fw_tool$ ./a.out
crc32: reverse 4 bytes
crc32: enter 2 CRC value: src dst
632d8c04 eee8a9a6
Add those 4 bytes: ( 00 ba ff 30 ) to change CRC 632d8c04 to eee8a9a6
change  crc: 632d8c04 ==> eee8a9a6
reserve crc: eee8a9a6 ==> 632d8c04

頭文件:

//==========================================================================
//
//      crc.h
//
//      Interface for the CRC algorithms.
//==========================================================================

#ifndef __CRC32_H__
#define __CRC32_H__

// Gary S. Brown's 32 bit CRC

unsigned int cyg_crc32(unsigned char *s, int len);

// Gary S. Brown's 32 bit CRC, but accumulate the result from a
// previous CRC calculation

unsigned int cyg_crc32_accumulate(unsigned int crc, unsigned char *s, int len);

// Ethernet FCS Algorithm

unsigned int cyg_ether_crc32(unsigned char *s, int len);

// Ethernet FCS algorithm, but accumulate the result from a previous
// CRC calculation.

unsigned int cyg_ether_crc32_accumulate(unsigned int crc, unsigned char *s,
  int len);

/**
 * add 4 bytes num[4] to change crc32 value from crc_src to crc_dst
 * @return: 0 on success, -1 on error.
 */
int cyg_crc32_change(unsigned int crc_dst, unsigned int crc_src, uint8_t num[4]);

/**
 * cyg_crc32_reserve - reserve CRC32 value by dropping data[len]
 * @return: return the CRC value before data[len]
 */
unsigned int cyg_crc32_reserve(unsigned int crc, void *data, int len);

#endif // __CRC32_H__

Copyright © Linux教程網 All Rights Reserved