PEB结构包含指向进程堆的指针— _HEAPP结构:
- 0:000> dt _PEB ProcessHeap @$peb
- ntdll!_PEB
- +0x018 ProcessHeap : 0x00440000 Void0:000> dt _HEAP Flags ForceFlags 00440000 ntdll!_HEAP
- +0x040 Flags : 0x40000062
- +0x044 ForceFlags : 0x40000060
Windows X64里的进程如下:
- 0:000> dt _PEB ProcessHeap @$peb
- ntdll!_PEB
- +0x030 ProcessHeap : 0x0000009d`94b60000 Void
- 0:000> dt _HEAP Flags ForceFlags 0000009d`94b60000
- ntdll!_HEAP
- +0x070 Flags : 0x40000062
- +0x074 ForceFlags : 0x40000060
如果正在调试进程,则两个字段Flags和ForceFlags都具有特定的调试值:
1.如果Flags字段没有设置HEAP_GROWABLE(0x00000002)标识,则正在调试进程。
2.如果ForceFlags!= 0,则正在调试进程。
不过要注意的是,_HEAP结构并未记录,并且Flags和ForceFlags字段的偏移值可能因操作系统版本而异。以下代码就是基于HeapFlag检查的反调试保护:
- int GetHeapFlagsOffset(bool x64)
- {
- return x64 ?
- IsVistaOrHigher() ? 0x70 : 0x14: //x64 offsets
- IsVistaOrHigher() ? 0x40 : 0x0C; //x86 offsets
- }
- int GetHeapForceFlagsOffset(bool x64)
- {
- return x64 ?
- IsVistaOrHigher() ? 0x74 : 0x18: //x64 offsets
- IsVistaOrHigher() ? 0x44 : 0x10; //x86 offsets
- }
- void CheckHeap()
- {
- PVOID pPeb = GetPEB();
- PVOID pPeb64 = GetPEB64();
- PVOID heap = 0;
- DWORD offsetProcessHeap = 0;
- PDWORD heapFlagsPtr = 0, heapForceFlagsPtr = 0;
- BOOL x64 = FALSE;
- #ifdef _WIN64
- x64 = TRUE;
- offsetProcessHeap = 0x30;
- #else
- offsetProcessHeap = 0x18;
- #endif
- heap = (PVOID)*(PDWORD_PTR)((PBYTE)pPeb + offsetProcessHeap);
- heapFlagsPtr = (PDWORD)((PBYTE)heap + GetHeapFlagsOffset(x64));
- heapForceFlagsPtr = (PDWORD)((PBYTE)heap + GetHeapForceFlagsOffset(x64));
- if (*heapFlagsPtr & ~HEAP_GROWABLE || *heapForceFlagsPtr != 0)
- {
- std::cout << "Stop debugging program!" << std::endl;
- exit(-1);
- }
- if (pPeb64)
- {
- heap = (PVOID)*(PDWORD_PTR)((PBYTE)pPeb64 + 0x30);
- heapFlagsPtr = (PDWORD)((PBYTE)heap + GetHeapFlagsOffset(true));
- heapForceFlagsPtr = (PDWORD)((PBYTE)heap + GetHeapForceFlagsOffset(true));
- if (*heapFlagsPtr & ~HEAP_GROWABLE || *heapForceFlagsPtr != 0)
- {
- std::cout << "Stop debugging program!" << std::endl;
- exit(-1);
- }
- }
- }
如何避开HeapFlag和ForceFlags检查
为了避开基于HeapFlag检查的反调试保护,应该为Flags字段设置HEAP_GROWABLE标识,并将ForceFlags的值设置为0.。但要注意的是,字段值的重新定义应该在HeapFlag检查之前执行。
陷阱标识检查 (编辑:衡阳站长网)
【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!
|