反调试——7——CRC检测
反调试——7——CRC检测
CRC32:
CRC的全称是循环冗余校验,作用是为了检测数据的完整性。
CRC32的检测原理:
程序被编译后,代码段是固定的,因为已经被写死了。
我们在调试程序的时候,打断点或者修改代码都会影响CRC32的值,这个时候只需要检测CRC32的某一时刻值和最初的CRC32值是否一致就可以判断代码是否被修改了。
如果装了好压这个软件可以直接通过右键查看到CRC32的值:

这里我找了一个简单的CRC32的代码来测试一下:
#include<iostream>
uint32_t crc32_table[256];
int make_crc32_table()
{
uint32_t c;
int i = 0;
int bit = 0;
for (i = 0; i < 256; i++)
{
c = (uint32_t)i;
for (bit = 0; bit < 8; bit++)
{
if (c & 1)
{
c = (c >> 1) ^ (0xEDB88320);
}
else
{
c = c >> 1;
}
}
crc32_table[i] = c;
}
return 1;
}
uint32_t make_crc(unsigned char* string, uint32_t size)
{
uint32_t crc= 0xFFFFFFFF;
make_crc32_table();
while (size--)
crc = (crc >> 8) ^ (crc32_table[(crc ^ *string++) & 0xff]);
return crc;
}
利用CRC32检测自己程序是否被修改:
通过对代码段进行CRC32判断来处理。首先要拿到代码段,通过Windows 的PE文件的结构体 Dos头->NT头->(采用VS里的结构体)拿到区段头->然后通过区段头得到区段的信息。
char *buffer=(char*)GetModuleHandleA(0);//参数为0就获取当前进程的句柄
PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)buffer;
PIMAGE_NT_HEADERS pNtHeader = (PIMAGE_NT_HEADERS)(pDosHeader->e_lfanew + buffer);
PIMAGE_SECTION_HEADER pSectionHeader = IMAGE_FIRST_SECTION(pNtHeader);
for (int i = 0; i < pNtHeader->FileHeader.NumberOfSections - 1; i++)
{
}
判断是否是代码段:
代码段顾名思义,就是执行代码的东西。在PE文件中的区段头里有一个字段可以判断属性:
typedef struct _IMAGE_SECTION_HEADER {
BYTE Name[IMAGE_SIZEOF_SHORT_NAME];
union {
DWORD PhysicalAddress;
DWORD VirtualSize;
} Misc;
DWORD VirtualAddress;
DWORD SizeOfRawData;
DWORD PointerToRawData;
DWORD PointerToRelocations;
DWORD PointerToLinenumbers;
WORD NumberOfRelocations;
WORD NumberOfLinenumbers;
DWORD Characteristics;//这个
} IMAGE_SECTION_HEADER, *PIMAGE_SECTION_HEADER
Characteristics这个字段标识了是否是可执行。在CFF里面查看:


这里通过我的测试,在修改可读可写的属性时会修改最高字段的值,如果有就加2,然后别的就修改别的值,所以这里我们判断首位是不是6就可以判断是不是代码段了。
void Crc32Test()
{
char *buffer=(char*)GetModuleHandleA(0);//参数为0就获取当前进程的句柄
PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)buffer;
PIMAGE_NT_HEADERS pNtHeader = (PIMAGE_NT_HEADERS)(pDosHeader->e_lfanew + buffer);
PIMAGE_SECTION_HEADER pSectionHeader = IMAGE_FIRST_SECTION(pNtHeader);
for (int i = 0; i < pNtHeader->FileHeader.NumberOfSections - 1; i++)
{
if (pSectionHeader->Characteristics / 0x10000000 == 6)
{
cout << pSectionHeader->Name << endl;
auto CrcNum = make_crc((unsigned char*)(pSectionHeader->VirtualAddress + buffer), pSectionHeader->Misc.VirtualSize);
cout << CrcNum << endl;
}
pSectionHeader++;
}
}
然后通过ollydbg随便打一个int3断点(因为int3断点会添加一个CC在里面所以肯定的改变了代码段的内容的)再运行来看CRC的值是否改变:

这里果然是改变了。
小结
CRC是一个演算东西的内容,类似于一些hash运行把,就是把一坨东西来计算一个值出来,由于一个程序写好了之后代码段是不会改变的,所以我们可以把它用来计算代码段的内容,然后再程序里面时刻计算这个值有没有改变来判断是否被修改了代码。
完整代码:反调试--CRC检测 - Sna1lGo - 博客园 (cnblogs.com)
反调试——7——CRC检测的更多相关文章
- 基于TLS的反调试技术
TLS(Thread Local Storage 线程局部存储) 一个进程中的每个线程在访问同一个线程局部存储时,访问到的都是独立的绑定于该线程的数据块.在PEB(进程环境块)中TLS存储槽共64个( ...
- 【Python3爬虫】突破反爬之应对前端反调试手段
一.前言 在我们爬取某些网站的时候,会想要打开 DevTools 查看元素或者抓包分析,但按下 F12 的时候,却出现了下面这一幕: 此时网页暂停加载,自动跳转到 Source 页面并打开了一个 ...
- C/C++ 程序反调试的方法
C/C++ 要实现程序反调试有多种方法,BeingDebugged,NtGlobalFlag,ProcessHeap,CheckRemoteDebuggerPresent,STARTUPINFO,Is ...
- 编译Android内核 For nexus 5 以及绕过Android的反调试
本文博客链接:http://blog.csdn.net/qq1084283172/article/details/54880488 前面的博客中已经记录了Nexus 5手机的Android 4.4.4 ...
- 反调试技术常用API,用来对付检测od和自动退出程序
在调试一些病毒程序的时候,可能会碰到一些反调试技术,也就是说,被调试的程序可以检测到自己是否被调试器附加了,如果探知自己正在被调试,肯定是有人试图反汇编啦之类的方法破解自己.为了了解如何破解反调试技术 ...
- 反调试——11——检测TF标志寄存器
反调试--11--检测TF标志寄存器 在intel的x86寄存器中有一种叫标志寄存器: 标志寄存器中的TF(Trap Flag)位,CPU在执行完一条指令后,如果检测到标志寄存器的TF位为1,则会产生 ...
- WinDbg调试流程的学习及对TP反调试的探索
基础知识推荐阅读<软件调试>的第十八章 内核调试引擎 我在里直接总结一下内核调试引擎的几个关键标志位,也是TP进行反调试检测的关键位. KdPitchDebugger : Boolean ...
- JavaScript反调试技巧
一.函数重定义 这是一种最基本也是最常用的代码反调试技术了.在JavaScript中,我们可以对用于收集信息的函数进行重定义.比如说,console.log()函数可以用来收集函数和变量等信息,并将其 ...
- Windows 下常见的反调试方法
稍稍总结一下在Crack或Rervese中比较常见的一些反调试方法,实现起来也比较简单,之后有写的Demo源码参考,没有太大的难度. ①最简单也是最基础的,Windows提供的API接口:IsDebu ...
随机推荐
- PQGrid商业化的表格组件
官网地址https://paramquery.com/pro/grid 右侧导航条有目录哟,看着更方便 快速入门 表格构建 API简单介绍 主要研究功能介绍 快速入门 ParamQuery Grid ...
- linux备份恢复命令
dump 发行版不自带,需要 yum 或 apt 安装.安装时 restore 也会自动安装. 支持分区和增量备份(仅支持分区增量,目录备份不支持增量).(第一次完全备份,第二次及以后只备份增加和修改 ...
- unity优化 — UGUI纹理格式的选择
首次界面打开加载的资源(如 贴图)会被缓存在内存中,再次打开界面由于内存中已有了资源 所以会更快.如何让首次打开界面会更快呢? 图片是否进行了有效的压缩.Android 平台下不带透明通道 优先使用E ...
- docker容器 如何精简镜像减小体积
写在前面 我们在上篇<Docker容器 关于镜像构建的安全问题>一起学习了如何构建一个基于安全的镜像,这篇小作文我们会学习镜像构建的另一个关键性问题,为何别人打造的镜像只有10MB而我的有 ...
- Linux系统的ssh与sshd服务
当主机中开启openssh服务,那么就对外开放了远程连接的接口 ssh为openssh服务的客户端,sshd为openssh服务的服务端 远程管理工具ssh具有数据加密传输.网络开销小以及应用平台范围 ...
- 菜鸟入门Linux之路(方法论浅谈)
Linux是为人熟知的OS之王,已"统治"世界.要想学好绝非易事. 作为菜鸟,可以与Linux亲密接触的方法很多,如视频.书籍.各种企培资料等等,如今的在线教育也如火如荼. 总结说 ...
- 性能测试工具JMeter 基础(六)—— 测试元件: 线程组
线程组的定义: 线程组是测试计划执行的入口,所有的逻辑控制器和取样器都必须在线程组下,其他的元件根据位置的不同作用域是不同的. 线程组是每个线程都是独立运行测试脚本,一个线程组就等于一个用户,通过多个 ...
- Dockerfile简介及基于centos7的jdk镜像制作
Dockerfile简介 dockerfile 是一个文本格式的配置文件, 用户可以使用 Dockerfile 来快速创建自定义的镜像, 另外,使用Dockerfile去构建镜像好比使用pom去构建m ...
- GIS常用算法
目录 1.常用算法 1.1.计算两经纬度点之间的距离 1.2.根据已知线段以及到起点距离,求目标点坐标 1.3.已知点.线段,求垂足 1.4.线段上距离目标点最近的点 1.5.点缓冲 1.6.点和面关 ...
- adb 常用命令大全(6)- 模拟按键输入
语法格式 input [<source>] <command> [<arg>...] 物理键 # 电源键 adb shell input keyevent 26 # ...