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

26种对付反调试的方法

发布时间:2019-03-22 18:26:36 所属栏目:策划 来源:luochicun
导读:目前主要有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. { 
  7.     PVOID pPeb = GetPEB(); 
  8.     PVOID pPeb64 = GetPEB64(); 
  9.     DWORD offsetNtGlobalFlag = 0; 
  10. #ifdef _WIN64 
  11.     offsetNtGlobalFlag = 0xBC; 
  12. #else 
  13.     offsetNtGlobalFlag = 0x68; 
  14. #endif 
  15.     DWORD NtGlobalFlag = *(PDWORD)((PBYTE)pPeb + offsetNtGlobalFlag); 
  16.     if (NtGlobalFlag & NT_GLOBAL_FLAG_DEBUGGED) 
  17.     { 
  18.         std::cout << "Stop debugging program!" << std::endl; 
  19.         exit(-1); 
  20.     } 
  21.     if (pPeb64) 
  22.     { 
  23.         DWORD NtGlobalFlagWow64 = *(PDWORD)((PBYTE)pPeb64 + 0xBC); 
  24.         if (NtGlobalFlagWow64 & NT_GLOBAL_FLAG_DEBUGGED) 
  25.         { 
  26.             std::cout << "Stop debugging program!" << std::endl; 
  27.             exit(-1); 
  28.         } 
  29.     } 
  30. } 

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

(编辑:文山站长网)

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

热点阅读