8.4 ProcessHeap

编程入门 行业动态 更新时间:2024-10-26 13:33:08

8.4 ProcessHeap

8.4 ProcessHeap

ProcessHeap 是Windows进程的默认堆,每个进程都有一个默认的堆,用于在进程地址空间中分配内存空间。默认情况下ProcessHeap由内核进行初始化,该堆中存在一个未公开的属性,它被设置为加载器为进程分配的第一个堆的位置(进程堆标志),ProcessHeap标志位于PEB结构中偏移为0x18处,第一个堆头部有一个属性字段,这个属性叫做ForceFlags属性偏移为0x44,该属性为0说明程序没有被调试,非0说明被调试,另外的Flags属性为2说明被调试,不为2则说明没有被调试。

0:000> dt !_peb
ntdll!_PEB+0x000 InheritedAddressSpace : UChar+0x001 ReadImageFileExecOptions : UChar+0x002 BeingDebugged    : UChar+0x018 ProcessHeap      : Ptr32 Void       // 找到Process偏移地址0:000> !heap                                  // 找出堆区首地址Heap Address      NT/Segment Heap1270000              NT Heap0:000> !heap -a 1270000                       // 查询heep的内存
Index   Address  Name      Debugging options enabled1:   01270000 Segment at 01270000 to 0136f000 (00006000 bytes committed)Flags:                40000062ForceFlags:           40000060Granularity:          8 bytesSegment Reserve:      00100000Segment Commit:       000020000:000> dt _HEAP 1270000                       // 找到ForceFlags标志的偏移地址
ntdll!_HEAP+0x000 Segment          : _HEAP_SEGMENT+0x000 Entry            : _HEAP_ENTRY+0x040 Flags            : 0x40000062+0x044 ForceFlags       : 0x40000060

这里需要注意一点,堆区在不同系统中偏移值是不同的,在Windows10系统中ForceFlags属性位于堆头部偏移量为0x44处,而默认情况如果被调试则ForceFlags属性为0x40000060,而Flags标志为0x40000062,有了这些参考那么通过汇编语言实现将变得很容易,如下代码则是通过汇编分别读取这两个堆头参数;

#include <stdio.h>
#include <windows.h>// 两种方式输出
int IsDebug(DWORD x)
{DWORD Debug = 0;if (x == 1){__asm{mov eax, fs:[0x18]       // TED基地址mov eax, [eax + 0x30]    // PEB基地址mov eax, [eax + 0x18]    // 定位 ProcessHeapmov eax, [eax + 0x44]    // 定位到 ForceFlagsmov Debug, eax}}if (x == 2){__asm{mov eax, fs:[0x18]       // TED基地址mov eax, [eax + 0x30]    // PEB基地址mov eax, [eax + 0x18]    // 定位 ProcessHeapmov eax, [eax + 0x40]    // 定位到 Flagsmov Debug, eax}}return Debug;
}int main(int argc, char * argv[])
{if (IsDebug(1) && IsDebug(2)){printf("[-] 进程正在被调试 \n");}else{printf("[*] 进程正常 \n");}system("pause");return 0;
}

另一种通过C语言实现的反调试版本,其反调试原理与上方相同,只不过此处我们使用了系统的API来完成检测标志位的。

#include <stdio.h>
#include <windows.h>
#include <winternl.h>typedef NTSTATUS(NTAPI *typedef_ZwQueryInformationProcess)(IN HANDLE ProcessHandle,IN PROCESSINFOCLASS ProcessInformationClass,OUT PVOID ProcessInformation,IN ULONG ProcessInformationLength,OUT PULONG ReturnLength OPTIONAL);BOOL IsDebug()
{HANDLE hProcess = NULL;DWORD ProcessId = 0;PROCESS_BASIC_INFORMATION Pbi;typedef_ZwQueryInformationProcess pZwQueryInformationProcess = NULL;ProcessId = GetCurrentProcessId();hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, ProcessId);if (hProcess != NULL){HMODULE hModule = LoadLibrary("ntdll.dll");pZwQueryInformationProcess = (typedef_ZwQueryInformationProcess)GetProcAddress(hModule, "ZwQueryInformationProcess");NTSTATUS Status = pZwQueryInformationProcess(hProcess, ProcessBasicInformation, &Pbi, sizeof(PROCESS_BASIC_INFORMATION), NULL);if (NT_SUCCESS(Status)){DWORD ByteRead = 0;DWORD ProcessHeap = 0;ULONG PebBase = (ULONG)Pbi.PebBaseAddress;DWORD ForceFlagsValue = 1;ReadProcessMemory(hProcess, (LPCVOID)(PebBase + 0x18), &ProcessHeap, 2, &ByteRead);ReadProcessMemory(hProcess, (LPCVOID)(ProcessHeap + 0x40), &ForceFlagsValue, 4, &ByteRead);if (ForceFlagsValue != 0){return TRUE;}}CloseHandle(hProcess);}return FALSE;
}int main(int argc, char * argv[])
{if (IsDebug()){printf("[-] 正在被调试 \n");}system("pause");return 0;
}

更多推荐

8.4 ProcessHeap

本文发布于:2024-03-12 16:43:27,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1731948.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:ProcessHeap

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!