前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >CRC校验完整性

CRC校验完整性

作者头像
江湖评谈
发布2024-06-11 17:30:45
1120
发布2024-06-11 17:30:45
举报
文章被收录于专栏:天下风云天下风云

前言

本篇用作技术性研究,一个简单的算法。

设想一个问题,一个程序如果它没有漏洞如何hook(攻击)它呢?答案很简单,人为制造漏洞。比如常用的指令性的更改(je指令更改为jne等属此类)。但是这样就会造成了程序(exe或者dll)里二进制的不一致性,防范这种hook方法,就是检验程序二进制的完整性,CRC算法就是这种校验的体现。

CRC算法

我们可以把程序进行如下CRC算法Result

代码语言:javascript
复制
DWORD CRC32(BYTE* ptr, DWORD Size)
{

  DWORD crcTable[256], crcTmp1;
  for (int i = 0; i < 256; i++)
  {
    crcTmp1 = i;
    for (int j = 8; j > 0; j--)
    {
      if (crcTmp1 & 1) crcTmp1 = (crcTmp1 >> 1) ^ 0xEDB88320L;
      else crcTmp1 >>= 1;
    }

    crcTable[i] = crcTmp1;
  }
  DWORD crcTmp2 = 0xFFFFFFFF;
  while (Size--)
  {
    crcTmp2 = ((crcTmp2 >> 8) & 0x00FFFFFF) ^ crcTable[(crcTmp2 ^ (*ptr)) & 0xFF];
    ptr++;
  }

  return (crcTmp2 ^ 0xFFFFFFFF);
}

ptr参数是二进制文件需要crc校验的起始地址,Size则是校验的二进制字节数。如果想要校验一个exe或者DLL的Result数值,那么我们可以如下:

代码语言:javascript
复制
GetOpenFileName(&ofn);
hFile = CreateFile(
  szFileName,
  GENERIC_READ | GENERIC_WRITE,
  FILE_SHARE_READ,
  NULL,
  OPEN_EXISTING,
  FILE_ATTRIBUTE_NORMAL,
  NULL);
fileSize = GetFileSize(hFile, &szTemp);
pDosHeader = (PIMAGE_DOS_HEADER)pBuffer;
pNtHeader = (PIMAGE_NT_HEADERS64)((DWORD)pDosHeader + pDosHeader->e_lfanew);
fileSize = fileSize - DWORD(pDosHeader->e_lfanew);
szCRC32 = CRC32((BYTE*)(pBuffer + pDosHeader->e_lfanew), fileSize);
DWORD Writeadd = DWORD(pDosHeader->e_lfanew - 4);
SetFilePointer(hFile, Writeadd, NULL, FILE_BEGIN);
if (!WriteFile(hFile, &szCRC32, 4, &szTemp, NULL))
{
  CloseHandle(hFile);
}

当程序开始运行的时候,我们可以校验ptr到size中间的crc result,进行一个判断:

代码语言:javascript
复制
pBuffer = new TCHAR [fileSize];  
ReadFile(hFile,pBuffer, fileSize, &NumberOfBytesRW, NULL);
CloseHandle(hFile); 
pDosHeader=(PIMAGE_DOS_HEADER)pBuffer;
pNtHeader=(PIMAGE_NT_HEADERS32)((DWORD)pDosHeader+pDosHeader->e_lfanew); 
fileSize=fileSize-DWORD(pDosHeader->e_lfanew);
if (CRC32((BYTE*)(pBuffer+pDosHeader->e_lfanew),fileSize) == OriginalCRC32 )
  return TRUE;
else
  return FALSE;

如果返回false则表示,exe或者dll更改了,此时我们就可以退出程序,不作任何运行,以防止被认为破解。

结尾

以上是校验的过程,主要的原理即把二进制进行计算,然后得出的结果进行保存,运行的时候再次进行计算,比较两次计算结果。代码取自《加密与解密》一书。整体来说,这种保护性较弱,但可以作为一种手段升级下。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2024-06-03,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 江湖评谈 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • CRC算法
  • 结尾
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档