反调试——7——CRC检测

CRC32:

CRC的全称是循环冗余校验,作用是为了检测数据的完整性。

CRC32的检测原理:

程序被编译后,代码段是固定的,因为已经被写死了。

我们在调试程序的时候,打断点或者修改代码都会影响CRC32的值,这个时候只需要检测CRC32的某一时刻值和最初的CRC32值是否一致就可以判断代码是否被修改了。

如果装了好压这个软件可以直接通过右键查看到CRC32的值:

这里我找了一个简单的CRC32的代码来测试一下:

  1. #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里的结构体)拿到区段头->然后通过区段头得到区段的信息。

  1. 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文件中的区段头里有一个字段可以判断属性:

  1. 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就可以判断是不是代码段了。

  1. void Crc32Test()
  2. {
  3. char *buffer=(char*)GetModuleHandleA(0);//参数为0就获取当前进程的句柄
  4. PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)buffer;
  5. PIMAGE_NT_HEADERS pNtHeader = (PIMAGE_NT_HEADERS)(pDosHeader->e_lfanew + buffer);
  6. PIMAGE_SECTION_HEADER pSectionHeader = IMAGE_FIRST_SECTION(pNtHeader);
  7. for (int i = 0; i < pNtHeader->FileHeader.NumberOfSections - 1; i++)
  8. {
  9. if (pSectionHeader->Characteristics / 0x10000000 == 6)
  10. {
  11. cout << pSectionHeader->Name << endl;
  12. auto CrcNum = make_crc((unsigned char*)(pSectionHeader->VirtualAddress + buffer), pSectionHeader->Misc.VirtualSize);
  13. cout << CrcNum << endl;
  14. }
  15. pSectionHeader++;
  16. }
  17. }

然后通过ollydbg随便打一个int3断点(因为int3断点会添加一个CC在里面所以肯定的改变了代码段的内容的)再运行来看CRC的值是否改变:

这里果然是改变了。

小结

CRC是一个演算东西的内容,类似于一些hash运行把,就是把一坨东西来计算一个值出来,由于一个程序写好了之后代码段是不会改变的,所以我们可以把它用来计算代码段的内容,然后再程序里面时刻计算这个值有没有改变来判断是否被修改了代码。

  完整代码:反调试--CRC检测 - Sna1lGo - 博客园 (cnblogs.com)

反调试——7——CRC检测的更多相关文章

  1. 基于TLS的反调试技术

    TLS(Thread Local Storage 线程局部存储) 一个进程中的每个线程在访问同一个线程局部存储时,访问到的都是独立的绑定于该线程的数据块.在PEB(进程环境块)中TLS存储槽共64个( ...

  2. 【Python3爬虫】突破反爬之应对前端反调试手段

    一.前言 在我们爬取某些网站的时候,会想要打开 DevTools 查看元素或者抓包分析,但按下 F12 的时候,却出现了下面这一幕:   此时网页暂停加载,自动跳转到 Source 页面并打开了一个 ...

  3. C/C++ 程序反调试的方法

    C/C++ 要实现程序反调试有多种方法,BeingDebugged,NtGlobalFlag,ProcessHeap,CheckRemoteDebuggerPresent,STARTUPINFO,Is ...

  4. 编译Android内核 For nexus 5 以及绕过Android的反调试

    本文博客链接:http://blog.csdn.net/qq1084283172/article/details/54880488 前面的博客中已经记录了Nexus 5手机的Android 4.4.4 ...

  5. 反调试技术常用API,用来对付检测od和自动退出程序

    在调试一些病毒程序的时候,可能会碰到一些反调试技术,也就是说,被调试的程序可以检测到自己是否被调试器附加了,如果探知自己正在被调试,肯定是有人试图反汇编啦之类的方法破解自己.为了了解如何破解反调试技术 ...

  6. 反调试——11——检测TF标志寄存器

    反调试--11--检测TF标志寄存器 在intel的x86寄存器中有一种叫标志寄存器: 标志寄存器中的TF(Trap Flag)位,CPU在执行完一条指令后,如果检测到标志寄存器的TF位为1,则会产生 ...

  7. WinDbg调试流程的学习及对TP反调试的探索

    基础知识推荐阅读<软件调试>的第十八章 内核调试引擎 我在里直接总结一下内核调试引擎的几个关键标志位,也是TP进行反调试检测的关键位. KdPitchDebugger : Boolean ...

  8. JavaScript反调试技巧

    一.函数重定义 这是一种最基本也是最常用的代码反调试技术了.在JavaScript中,我们可以对用于收集信息的函数进行重定义.比如说,console.log()函数可以用来收集函数和变量等信息,并将其 ...

  9. Windows 下常见的反调试方法

    稍稍总结一下在Crack或Rervese中比较常见的一些反调试方法,实现起来也比较简单,之后有写的Demo源码参考,没有太大的难度. ①最简单也是最基础的,Windows提供的API接口:IsDebu ...

随机推荐

  1. Windows上使用Python2.7安装pip

    资料包含: setuptools-33.1.1 pip-18.1 ez_setup.py get-pip.py 方法一 先安装 setuptools: 进入 setuptools 文件夹,运行:pyt ...

  2. Servlet的类加载器

    Java虚拟机中内嵌的一个类加载器:Bootstrap,属于Java虚拟机的内核,负责加载Java核心包中的类(即rt.jar文件中的类):Java核心包中有另外两个类加载器:ExtClassLoad ...

  3. 🏆【Alibaba微服务技术系列】「Dubbo3.0技术专题」回顾Dubbo2.x的技术原理和功能实现及源码分析(温故而知新)

    RPC服务 什么叫RPC? RPC[Remote Procedure Call]是指远程过程调用,是一种进程间通信方式,他是一种技术的思想,而不是规范.它允许程序调用另一个地址空间(通常是共享网络的另 ...

  4. Linux CentOS7 安装配置 IPtables

    2021-08-11 1. 前言 防火墙其实就是实现 Linux 下访问控制功能的,分为硬件和软件的防火墙两种类型.无论在何网络中,防火墙工作的地方一定是网络的边缘.防火墙的策略.规则就是去定义防火墙 ...

  5. linux 查看用户密码

    2021-07-26 1.查看前三个密码 head -3 / etc / passwd # 注解 /etc/passwd 中一行记录对应着一个用户,每行记录又被冒号 (:) 分隔为 7 个字段,其格式 ...

  6. skynet 开启 https 配置

    修改 Makefile Mac 下: # https : turn on TLS_MODULE to add https support TLS_MODULE=ltls TLS_LIB="$ ...

  7. 设置 ajax 同步获取数据

    问题 在处理DataTable的render进行列表渲染的时候发现通过ajax发送请求,返回的值并不正确. {"data":"id","render& ...

  8. com.google.zxing.NotFoundException-识别图片二维码信息错误

    一.问题由来 自己在做一个小程序项目的后台,其中需要使用到识别图片二维码信息,而且是必须在Java后台进行识别二维码操作.去百度里面很快找到一个方法, 可以识别简单的二维码,而且自己生成的简单的二维码 ...

  9. 前端路由原理之 hash 模式和 history 模式

    什么是路由? 个人理解路由就是浏览器 URL 和页面内容的一种映射关系. 比如你看到我这篇博客,博客的链接是一个 URL,而 URL 对应的就是我这篇博客的网页内容,这二者之间的映射关系就是路由. 其 ...

  10. Spring基于XML方式加载Bean定义信息(又名:Spring IOC源码时序图)-图解