CRC校验技术是用于检测数据传输或存储过程中是否出现了错误的一种方法,校验算法可以通过计算应用与数据的循环冗余校验(CRC)检验值来检测任何数据损坏。通过运用本校验技术我们可以实现对特定内存区域以及磁盘文件进行完整性检测,并以此来判定特定程序内存是否发生了变化,如果发生变化则拒绝执行,通过此种方法来保护内存或磁盘文件不会被非法篡改。总之,内存和磁盘中的校验技术都是用于确保数据和程序的完整性和安全性的重要技术。

磁盘CRC(循环冗余校验)用于检测磁盘数据的完整性,一般而言某些木马专杀工具同样会用到磁盘CRC特征校验技术,该技术的实现原理与内存验证原理完全一致,针对磁盘的验证同样很简单,但此处我们需要将计算到的CRC32值存储到PE文件自身中,通常我们可以存储到PE文件的前一个DWORD的位置上,程序运行后对比这个值,来判断程序是否被打过补丁,如果打过直接结束掉。

// 检查磁盘完整性
BOOL CalculateDiskCRC32()
{
char szFileName[MAX_PATH] = { 0 }; char *pBuffer;
DWORD pNumberOfBytesRead;
int FileSize = 0; // 获取自身文件,并打开文件
GetModuleFileName(0, szFileName, MAX_PATH);
HANDLE hFile = CreateFile(szFileName, GENERIC_READ, 1, 0, 3, FILE_ATTRIBUTE_NORMAL, 0);
if (hFile == INVALID_HANDLE_VALUE)
{
return TRUE;
} // 取文件长度
FileSize = GetFileSize(hFile, 0);
pBuffer = new char[FileSize]; // 读取文件到内存
ReadFile(hFile, pBuffer, FileSize, &pNumberOfBytesRead, 0);
CloseHandle(hFile); PIMAGE_DOS_HEADER pDosHeader = NULL;
PIMAGE_NT_HEADERS32 pNtHeader = NULL; pDosHeader = (PIMAGE_DOS_HEADER)pBuffer; // 获取到NT头
pNtHeader = (PIMAGE_NT_HEADERS32)((DWORD)pDosHeader + pDosHeader->e_lfanew); // 定位到PE文件头前4字节处
DWORD OriginalCRC32 = *(DWORD *)((DWORD)pNtHeader - 4);
printf("[*] 读出节表值 = %x \n", OriginalCRC32); // 我们只需要计算PE结构的CRC32值,不需要计算DOS头
FileSize = FileSize - DWORD(pDosHeader->e_lfanew);
DWORD CheckCRC32 = CRC32((BYTE*)(pBuffer + pDosHeader->e_lfanew), FileSize);
printf("[+] 计算CRC32 = %x \n", CheckCRC32); if (CheckCRC32 == OriginalCRC32)
{
return FALSE;
}
else
{
return TRUE;
}
return TRUE;
} int main(int argc, char* argv[])
{
BOOL ref = CalculateDiskCRC32();
if (ref == TRUE)
{
printf("[-] 程序已被修改 \n");
}
else
{
printf("[+] 程序正常 \n");
} system("pause");
return 0;
}

首先读者运行上述程序,则程序会输出当前的CRC32值be63ac8b我们记下这个HASH值,如下图所示;

并将此值替换到如下图中的黄色位置,当程序运行后会读取该区域内的数据,并与动态计算的CRC32值进行计算,最终判断是否被修改,如下图所示;

通过CRC32数据对比并遍历磁盘文件,我们可以实现一个简单的特征定位查杀程序,用于专门定位某些特殊的程序,如下是修改后的代码片段;

// 计算文件CRC过程
BOOL CalcCRC32(char *FilePath)
{
// 打开文件
HANDLE hFile = CreateFile(FilePath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile == INVALID_HANDLE_VALUE)
{
return FALSE;
} // 获取文件大小
DWORD dwSize = GetFileSize(hFile, NULL);
if (dwSize == 0xFFFFFFFF)
{
return FALSE;
} // 分配内存
BYTE *pFile = (BYTE*)malloc(dwSize);
if (pFile == NULL)
{
return FALSE;
} // 读取内存
DWORD dwNum = 0;
ReadFile(hFile, pFile, dwSize, &dwNum, NULL); // 计算CRC32
DWORD dwCRC32 = CRC32(pFile, dwSize);
if (pFile != NULL)
{
free(pFile);
pFile = NULL;
} CloseHandle(hFile);
return dwCRC32;
} int main(int argc, char* argv[])
{
WIN32_FIND_DATA stFindFile;
HANDLE hFindFile;
char *szFilter = "*.exe"; // 筛选所有的.exe结尾的文件
char szFindFile[MAX_PATH]; // 保存欲检测程序的路径
char szSearch[MAX_PATH]; // 保存完整的筛选路径
int ret = 0; // 搜索状态返回值 lstrcpy(szFindFile, "D:\\"); // 搜索D盘目录下的所有exe结尾的文件
lstrcpy(szSearch, "D:\\");
lstrcat(szSearch, szFilter);
DWORD dwTmpCRC32; hFindFile = FindFirstFile(szSearch, &stFindFile);
if (hFindFile != INVALID_HANDLE_VALUE)
{
do
{
lstrcat(szFindFile, stFindFile.cFileName);
dwTmpCRC32 = CalcCRC32(szFindFile); // 比较判断
if (dwTmpCRC32 == 0xbe63ac8b)
{
printf("[*] CRC32 = %x 发现病毒 %s \n", dwTmpCRC32, szFindFile);
}
else
{
printf("[-] CRC32 = %x 正常程序 %s \n", dwTmpCRC32, szFindFile);
}
// 删除程序名称只保留"C:\"
szFindFile[3] = '\0';
ret = FindNextFile(hFindFile, &stFindFile);
} while (ret != 0);
} FindClose(hFindFile); system("pause");
return 0;
}

运行程序输出效果如下图所示;

本文作者: 王瑞

本文链接: https://www.lyshark.com/post/7a9a55f0.html

版权声明: 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!

5.2 磁盘CRC32完整性检测的更多相关文章

  1. 利用SHELL脚本实现文件完整性检测程序(1.2版更新)

    一..开发背景 因时势所逼,需要对服务器的文件系统实行监控.虽然linux下有不少入侵检测和防窜改系统,但都比较麻烦,用起来也不是很称手.自己琢磨着也不需要什么多复杂的功能,写个脚本应该就可以满足基本 ...

  2. Linux AIDE(文件完整性检测)

    一.AIDE的概念 AIDE:Advanced Intrusion Detection Environment,是一款入侵检测工具,主要用途是检查文档的完整性.AIDE在本地构造了一个基准的数据库,一 ...

  3. Linux 磁盘坏道检测和修复

    今天在实验室碰到一台机器,根分区和/upgrade分区变成了read-only system.当碰到这个问题的时候,我的第一反应很可能硬件出现了故障,我使用了如下的方法来检测和排除故障: 使用dmes ...

  4. CRC32是什么?

    CRC32:CRC本身是“冗余校验码”的意思,CRC32则表示会产生一个32bit(8位十六进制数)的校验值.由于CRC32产生校验值时源数据块的每一个bit(位)都参与了计算,所以数据块中即使只有一 ...

  5. 反调试——7——CRC检测

    反调试--7--CRC检测 CRC32: CRC的全称是循环冗余校验,作用是为了检测数据的完整性. CRC32的检测原理: 程序被编译后,代码段是固定的,因为已经被写死了. 我们在调试程序的时候,打断 ...

  6. SQL Server自动化运维系列——监控磁盘剩余空间及SQL Server错误日志(Power Shell)

    需求描述 在我们的生产环境中,大部分情况下需要有自己的运维体制,包括自己健康状态的检测等.如果发生异常,需要提前预警的,通知形式一般为发邮件告知. 在所有的自检流程中最基础的一个就是磁盘剩余空间检测. ...

  7. FME之于规划CAD数据质量检测

    最近琢磨规划CAD数据转换入库GIS方面的技术问题,看过一些前辈的文章/文献,对于使用FME WorkBench方面,有了一些了解,往往直接转换数据丢失比较严重,而且GIS对图形属性和空间拓扑比较严格 ...

  8. Metasploit是一款开源的安全漏洞检测工具,

    Metasploit是一款开源的安全漏洞检测工具,可以帮助安全和IT专业人士识别安全性问题,验证漏洞的缓解措施,并管理专家驱动的安全性进行评估,适合于需要核实漏洞的安全专家,同时也适合于强大进攻能力的 ...

  9. linux工具类之硬盘检测

    软raidmount /dev/md0 /opt                [root@localhost root]# cp /usr/share/doc/raidtools-1.00.3/ra ...

  10. 开源入侵检测系统OSSEC搭建之二:客户端安装

    上一篇文章中已经将OSSEC服务端的安装以及客户端的Key导出操作做了解说,接下来在另一台虚拟机中安装客户端,与安装服务端类似同样需要安装ossec,步骤如下. 一.下载ossec-hids-2.8. ...

随机推荐

  1. DB事物

    1.事物概念:一组逻辑操作单元 始数据从一种状态变换到另一种状态事物处理:所有事物 都作为一个工作单元来执行 , 即使出现了故障 都不能改变这种执行方式, commint提交之后 这些修改就永久的保存 ...

  2. 02.详解盒子模型&选择器初识

    1.Div盒子 用div做圆 能否优化,去掉div之间的距离?margin属性 用表格做圆 2.CSS样式 总结:需要注意的是行级标签设置宽高不会生效 小练习:使用span标签 3.CSS选择器演示及 ...

  3. 【pandas基础】--目录(完结)

    pandas 基础内容的目录: 概述 pandas 主要功能和应用场景的介绍. 数据读取 数据读取是第一步,只有成功加载数据之后,后续的操作才有可能. pandas 可以读取和导入各种数据格式的数据, ...

  4. Kubernetes(k8s)网络策略NetworkPolicy

    目录 一.系统环境 二.前言 三.网络策略(NetworkPolicy)简介 四.创建pod和svc 五.没有网络策略的条件下访问pod 六.给pod添加网络策略 6.1 入站网络策略 6.1.1 入 ...

  5. 22.04.1 wine8.10 完美安装同花顺最新版THS_9.20.40_20230613

    Linux luma 5.19.0-45-generic #46~22.04.1-Ubuntu SMP PREEMPT_DYNAMIC Wed Jun 7 15:06:04 UTC 20 x86_64 ...

  6. Java String、StringBuilder、StringBuffer类

    1.String类 创建字符串对象后,字符串对象不可以发生改变,并且这个字符串对象存储在方法区中的字符串常量池中. 即使想改变字符串对象,那么也只是在字符串常量池中重新创建了一个字符串对象而已. 2. ...

  7. Python运维开发之路《WEB框架:Django》

    一.Web框架的本质 所有的web框架.web请求:本质上都是:socket 浏览器:socket客户端 服务器:socket服务端 1. socket服务端 import socket def ha ...

  8. 【Oracle】行转列的函数wm_concat,listagg,xmlagg,pivot以及动态行转列

    [Oracle]行转列的几种情况 表的数据如下 朴实无华的函数 1.wm_concat 使用格式: select 分组字段,wm_concat(要转换的列名) from 表名 group by 分组字 ...

  9. python学习笔记:继承与超类

    与java类似,继承的出现是为了提高代码的重复利用率,避免多次输入同样的代码.而超类就是java中的父类. 1.继承 要指定超类,可在定义类时,在class语句中的类名后加上超类名 基类就是超类,派生 ...

  10. 在VS Code 中调试远程服务器的PHP代码

    背景 对于PHP的调试,一般来说我们用 echo 和 var_dump 就够用了. 有时会碰到要解决复杂的逻辑或需要确认代码的运行顺序,这里用var_dump效率就比较低了,这时建议用断点的方式进行代 ...