要检查进程是否使用了调试器启动,你应该检查PEB结构的NtGlobalFlag字段的值。在x32和x64系统中,该字段位于PEB结构的开始处的0x068和0x0bc偏移处。
- 0:000> dt _PEB NtGlobalFlag @$peb
- ntdll!_PEB
- +0x068 NtGlobalFlag : 0x70
Windows X64里的进程如下:
- 0:000> dt _PEB NtGlobalFlag @$peb
- ntdll!_PEB
- +0x0bc NtGlobalFlag : 0x70
以下代码片段就是基于NtGlobalFlag标识检查的反调试保护:
- #define FLG_HEAP_ENABLE_TAIL_CHECK 0x10
- #define FLG_HEAP_ENABLE_FREE_CHECK 0x20
- #define FLG_HEAP_VALIDATE_PARAMETERS 0x40
- #define NT_GLOBAL_FLAG_DEBUGGED (FLG_HEAP_ENABLE_TAIL_CHECK | FLG_HEAP_ENABLE_FREE_CHECK | FLG_HEAP_VALIDATE_PARAMETERS)
- void CheckNtGlobalFlag()
- {
- PVOID pPeb = GetPEB();
- PVOID pPeb64 = GetPEB64();
- DWORD offsetNtGlobalFlag = 0;
- #ifdef _WIN64
- offsetNtGlobalFlag = 0xBC;
- #else
- offsetNtGlobalFlag = 0x68;
- #endif
- DWORD NtGlobalFlag = *(PDWORD)((PBYTE)pPeb + offsetNtGlobalFlag);
- if (NtGlobalFlag & NT_GLOBAL_FLAG_DEBUGGED)
- {
- std::cout << "Stop debugging program!" << std::endl;
- exit(-1);
- }
- if (pPeb64)
- {
- DWORD NtGlobalFlagWow64 = *(PDWORD)((PBYTE)pPeb64 + 0xBC);
- if (NtGlobalFlagWow64 & NT_GLOBAL_FLAG_DEBUGGED)
- {
- std::cout << "Stop debugging program!" << std::endl;
- exit(-1);
- }
- }
- }
如何避开NtGlobalFlag检查
在执行该检查之前,应该在通过反调试保护检查该值之前,将0调整为调试过程中PEB结构的NtGlobalFlag字段。
NtGlobalFlag和IMAGE_LOAD_CONFIG_DIRECTORY
可执行文件既包括IMAGE_LOAD_CONFIG_DIRECTORY结构,也包括系统加载程序的其他配置参数。不过在默认情况下,此结构不会内置到可执行文件中,需要使用补丁添加。此结构具有GlobalFlagsClear字段,对PEB结构中要重置的NtGlobalFlag字段进行了标识。如果最初没有对该结构或GlobalFlagsClear = 0创建可执行文件,那么在磁盘或内存中,该字段就具有非零值,隐藏的调试器就会正常运行。下面就是检查运行进程的内存和磁盘上的GlobalFlagsClear字段的代码,这是一种流行的反调试技术:
- PIMAGE_NT_HEADERS GetImageNtHeaders(PBYTE pImageBase)
- {
- PIMAGE_DOS_HEADER pImageDosHeader = (PIMAGE_DOS_HEADER)pImageBase;
- return (PIMAGE_NT_HEADERS)(pImageBase + pImageDosHeader->e_lfanew);
- }
- PIMAGE_SECTION_HEADER FindRDataSection(PBYTE pImageBase)
- {
- static const std::string rdata = ".rdata";
- PIMAGE_NT_HEADERS pImageNtHeaders = GetImageNtHeaders(pImageBase);
- PIMAGE_SECTION_HEADER pImageSectionHeader = IMAGE_FIRST_SECTION(pImageNtHeaders);
- int n = 0;
- for (; n < pImageNtHeaders->FileHeader.NumberOfSections; ++n)
- {
- if (rdata == (char*)pImageSectionHeader[n].Name)
- {
- break;
- }
- }
- return &pImageSectionHeader[n];
- }
- void CheckGlobalFlagsClearInProcess()
- {
- PBYTE pImageBase = (PBYTE)GetModuleHandle(NULL);
- PIMAGE_NT_HEADERS pImageNtHeaders = GetImageNtHeaders(pImageBase);
- PIMAGE_LOAD_CONFIG_DIRECTORY pImageLoadConfigDirectory = (PIMAGE_LOAD_CONFIG_DIRECTORY)(pImageBase
- + pImageNtHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG].VirtualAddress);
- if (pImageLoadConfigDirectory->GlobalFlagsClear != 0)
- {
- std::cout << "Stop debugging program!" << std::endl;
- exit(-1);
- }
- }
- void CheckGlobalFlagsClearInFile()
- {
- HANDLE hExecutable = INVALID_HANDLE_VALUE;
- HANDLE hExecutableMapping = NULL;
- PBYTE pMappedImageBase = NULL;
- __try
- {
- PBYTE pImageBase = (PBYTE)GetModuleHandle(NULL);
- PIMAGE_SECTION_HEADER pImageSectionHeader = FindRDataSection(pImageBase);
- TCHAR pszExecutablePath[MAX_PATH];
- DWORD dwPathLength = GetModuleFileName(NULL, pszExecutablePath, MAX_PATH);
- if (0 == dwPathLength) __leave;
- hExecutable = CreateFile(pszExecutablePath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
- if (INVALID_HANDLE_VALUE == hExecutable) __leave;
- hExecutableMapping = CreateFileMapping(hExecutable, NULL, PAGE_READONLY, 0, 0, NULL);
- if (NULL == hExecutableMapping) __leave;
- pMappedImageBase = (PBYTE)MapViewOfFile(hExecutableMapping, FILE_MAP_READ, 0, 0,
- pImageSectionHeader->PointerToRawData + pImageSectionHeader->SizeOfRawData);
- if (NULL == pMappedImageBase) __leave;
- PIMAGE_NT_HEADERS pImageNtHeaders = GetImageNtHeaders(pMappedImageBase);
- PIMAGE_LOAD_CONFIG_DIRECTORY pImageLoadConfigDirectory = (PIMAGE_LOAD_CONFIG_DIRECTORY)(pMappedImageBase
- + (pImageSectionHeader->PointerToRawData
- + (pImageNtHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG].VirtualAddress - pImageSectionHeader->VirtualAddress)));
- if (pImageLoadConfigDirectory->GlobalFlagsClear != 0)
- {
- std::cout << "Stop debugging program!" << std::endl;
- exit(-1);
- }
- }
- __finally
- {
- if (NULL != pMappedImageBase)
- UnmapViewOfFile(pMappedImageBase);
- if (NULL != hExecutableMapping)
- CloseHandle(hExecutableMapping);
- if (INVALID_HANDLE_VALUE != hExecutable)
- CloseHandle(hExecutable);
- }
- }
(编辑:广西网)
【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!
|