什么是CRC

CRC 即 循环冗余校验码(Cyclic Redundancy Check)
CRC属于密码学一类算法, 常用数据校验, 一般会用来检测程序是否被脱壳或被修改, 达到防破解的目的.
根据网络数据包, 或者计算机文件等数据产生简短固定位数校验码的一种散列函数, 主要用来检测或校验数据传输或着保存后可能出现的错误. 生成的数字在传输或者存储之前计算出来并且附加到数据后面, 然后接收方进行检测确定数据是否发生变化. 一般来说, 循环冗余校验的值都是32位的整数. 由于本函数易用于二进制的计算机硬件使用, 容易进行数学分析并且尤其善于检测传输通道干扰引起的错误, 因此获得广泛应用.

C++实现CRC Demo

#include <Windows.h>
#include <stdio.h>


int crc = NULL;
int have_crc_table = NULL;
unsigned int crc32_table[256];

//生成具有256个元素的CRC32表
void Crc_Make_Table(){
    have_crc_table = 1;

    for (int i = 0; i < 256; i++){
        crc = i;
        for (int j = 0; j < 8; j++){
            if (crc & 1)
                crc = (crc >> 1) ^ 0xEDB88320; //CRC32 多项式的值,也可以是0x04C11DB7
            else
                crc >>= 1;
        }
        crc32_table[i] = crc; //生成并存储CRC32数据表
    }
}

//根据CRC32数据表计算内存或文件CRC校验码
unsigned int Calc_Crc32(unsigned int crc, char* Data, int len){
    crc = 0xFFFFFFFF; //将CRC初始化为-1
    //判断CRC32表是否生成
    if (!have_crc_table) Crc_Make_Table();

    for (int i = 0; i < len; i++){
        crc = (crc >> 8) ^ crc32_table[(crc ^ Data[i]) & 0xff];
    }
    return ~crc;
}

int main(){
    SetConsoleTitleA("CrcDemo");
    printf("尝试修改以下地址的数据: \n");
    printf("0x402000\n\n");

    //初始内存校验值
    unsigned int uMainMoudleSumA = Calc_Crc32(0, (char*)0x400000, 0x1C000);//400000- 41D000


    //while循环开启CRC检测
    while (TRUE){
        //CRC循环检测内存实时校验值
        unsigned int TmpCrcSum = Calc_Crc32(0, (char*)0x400000, 0x1C000);
        if (TmpCrcSum != uMainMoudleSumA){
            MessageBoxA(NULL, "CRC校验: 数据被修改!", "Caption", MB_OK);
            return 0;
        }

        Sleep(2000);
    }

    return 0;
}

r4NsBOnfDSizWx2.png

Last modification:March 3rd, 2020 at 10:19 pm
如果觉得我的文章对你有用,请随意赞赏