加入收藏 | 设为首页 | 会员中心 | 我要投稿 源码网 (https://www.900php.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 运营中心 > 建站资源 > 策划 > 正文

26种对付反调试的方法

发布时间:2019-03-22 16:38:38 所属栏目:策划 来源:luochicun
导读:副标题#e# 目前主要有3种分析软件的方法: 1.数据交换分析,研究人员使用数据包嗅探工具来分析网络数据交换。 2.对软件的二进制代码进行反汇编,然后以汇编语言列出。 3.字节码解码或二进制解码,然后以高级编程语言重新创建源代码。 本文针对的是Windows操

要检查进程是否使用了调试器启动,你应该检查PEB结构的NtGlobalFlag字段的值。在x32和x64系统中,该字段位于PEB结构的开始处的0x068和0x0bc偏移处。

  1. 0:000> dt _PEB NtGlobalFlag @$peb  
  2. ntdll!_PEB 
  3.    +0x068 NtGlobalFlag : 0x70 

Windows X64里的进程如下:

  1. 0:000> dt _PEB NtGlobalFlag @$peb 
  2. ntdll!_PEB 
  3.    +0x0bc NtGlobalFlag : 0x70 

以下代码片段就是基于NtGlobalFlag标识检查的反调试保护:

  1. #define FLG_HEAP_ENABLE_TAIL_CHECK   0x10 
  2. #define FLG_HEAP_ENABLE_FREE_CHECK   0x20 
  3. #define FLG_HEAP_VALIDATE_PARAMETERS 0x40 
  4. #define NT_GLOBAL_FLAG_DEBUGGED (FLG_HEAP_ENABLE_TAIL_CHECK | FLG_HEAP_ENABLE_FREE_CHECK | FLG_HEAP_VALIDATE_PARAMETERS) 
  5. void CheckNtGlobalFlag() 
  6.     PVOID pPeb = GetPEB(); 
  7.     PVOID pPeb64 = GetPEB64(); 
  8.     DWORD offsetNtGlobalFlag = 0; 
  9. #ifdef _WIN64 
  10.     offsetNtGlobalFlag = 0xBC; 
  11. #else 
  12.     offsetNtGlobalFlag = 0x68; 
  13. #endif 
  14.     DWORD NtGlobalFlag = *(PDWORD)((PBYTE)pPeb + offsetNtGlobalFlag); 
  15.     if (NtGlobalFlag & NT_GLOBAL_FLAG_DEBUGGED) 
  16.     { 
  17.         std::cout << "Stop debugging program!" << std::endl; 
  18.         exit(-1); 
  19.     } 
  20.     if (pPeb64) 
  21.     { 
  22.         DWORD NtGlobalFlagWow64 = *(PDWORD)((PBYTE)pPeb64 + 0xBC); 
  23.         if (NtGlobalFlagWow64 & NT_GLOBAL_FLAG_DEBUGGED) 
  24.         { 
  25.             std::cout << "Stop debugging program!" << std::endl; 
  26.             exit(-1); 
  27.         } 
  28.     } 

如何避开NtGlobalFlag检查

在执行该检查之前,应该在通过反调试保护检查该值之前,将0调整为调试过程中PEB结构的NtGlobalFlag字段。

NtGlobalFlag和IMAGE_LOAD_CONFIG_DIRECTORY

可执行文件既包括IMAGE_LOAD_CONFIG_DIRECTORY结构,也包括系统加载程序的其他配置参数。不过在默认情况下,此结构不会内置到可执行文件中,需要使用补丁添加。此结构具有GlobalFlagsClear字段,对PEB结构中要重置的NtGlobalFlag字段进行了标识。如果最初没有对该结构或GlobalFlagsClear = 0创建可执行文件,那么在磁盘或内存中,该字段就具有非零值,隐藏的调试器就会正常运行。下面就是检查运行进程的内存和磁盘上的GlobalFlagsClear字段的代码,这是一种流行的反调试技术:

  1. PIMAGE_NT_HEADERS GetImageNtHeaders(PBYTE pImageBase) 
  2.     PIMAGE_DOS_HEADER pImageDosHeader = (PIMAGE_DOS_HEADER)pImageBase; 
  3.     return (PIMAGE_NT_HEADERS)(pImageBase + pImageDosHeader->e_lfanew); 
  4. PIMAGE_SECTION_HEADER FindRDataSection(PBYTE pImageBase) 
  5.     static const std::string rdata = ".rdata"; 
  6.     PIMAGE_NT_HEADERS pImageNtHeaders = GetImageNtHeaders(pImageBase); 
  7.     PIMAGE_SECTION_HEADER pImageSectionHeader = IMAGE_FIRST_SECTION(pImageNtHeaders); 
  8.     int n = 0; 
  9.     for (; n < pImageNtHeaders->FileHeader.NumberOfSections; ++n) 
  10.     { 
  11.         if (rdata == (char*)pImageSectionHeader[n].Name) 
  12.         { 
  13.             break; 
  14.         } 
  15.     } 
  16.     return &pImageSectionHeader[n]; 
  17. void CheckGlobalFlagsClearInProcess() 
  18.     PBYTE pImageBase = (PBYTE)GetModuleHandle(NULL); 
  19.     PIMAGE_NT_HEADERS pImageNtHeaders = GetImageNtHeaders(pImageBase); 
  20.     PIMAGE_LOAD_CONFIG_DIRECTORY pImageLoadConfigDirectory = (PIMAGE_LOAD_CONFIG_DIRECTORY)(pImageBase 
  21.         + pImageNtHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG].VirtualAddress); 
  22.     if (pImageLoadConfigDirectory->GlobalFlagsClear != 0) 
  23.     { 
  24.         std::cout << "Stop debugging program!" << std::endl; 
  25.         exit(-1); 
  26.     } 
  27. void CheckGlobalFlagsClearInFile() 
  28.     HANDLE hExecutable = INVALID_HANDLE_VALUE; 
  29.     HANDLE hExecutableMapping = NULL; 
  30.     PBYTE pMappedImageBase = NULL; 
  31.     __try 
  32.     { 
  33.         PBYTE pImageBase = (PBYTE)GetModuleHandle(NULL); 
  34.         PIMAGE_SECTION_HEADER pImageSectionHeader = FindRDataSection(pImageBase); 
  35.         TCHAR pszExecutablePath[MAX_PATH]; 
  36.         DWORD dwPathLength = GetModuleFileName(NULL, pszExecutablePath, MAX_PATH); 
  37.         if (0 == dwPathLength) __leave; 
  38.         hExecutable = CreateFile(pszExecutablePath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); 
  39.         if (INVALID_HANDLE_VALUE == hExecutable) __leave; 
  40.         hExecutableMapping = CreateFileMapping(hExecutable, NULL, PAGE_READONLY, 0, 0, NULL); 
  41.         if (NULL == hExecutableMapping) __leave; 
  42.         pMappedImageBase = (PBYTE)MapViewOfFile(hExecutableMapping, FILE_MAP_READ, 0, 0, 
  43.             pImageSectionHeader->PointerToRawData + pImageSectionHeader->SizeOfRawData); 
  44.         if (NULL == pMappedImageBase) __leave; 
  45.         PIMAGE_NT_HEADERS pImageNtHeaders = GetImageNtHeaders(pMappedImageBase); 
  46.         PIMAGE_LOAD_CONFIG_DIRECTORY pImageLoadConfigDirectory = (PIMAGE_LOAD_CONFIG_DIRECTORY)(pMappedImageBase  
  47.             + (pImageSectionHeader->PointerToRawData 
  48.                 + (pImageNtHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG].VirtualAddress - pImageSectionHeader->VirtualAddress))); 
  49.         if (pImageLoadConfigDirectory->GlobalFlagsClear != 0) 
  50.         { 
  51.             std::cout << "Stop debugging program!" << std::endl; 
  52.             exit(-1); 
  53.         } 
  54.     } 
  55.     __finally 
  56.     { 
  57.         if (NULL != pMappedImageBase) 
  58.             UnmapViewOfFile(pMappedImageBase); 
  59.         if (NULL != hExecutableMapping) 
  60.             CloseHandle(hExecutableMapping); 
  61.         if (INVALID_HANDLE_VALUE != hExecutable) 
  62.             CloseHandle(hExecutable); 
  63.     }  

(编辑:源码网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

热点阅读