Anti-Analysisintermediate
Heap Flags
Malware inspects the Flags and ForceFlags fields of the process heap header (via PEB.ProcessHeap) to detect debugger-modified heap metadata.
Windows modifies the heap header of a debugged process to enable extra validation. Two fields in the first heap block, reachable through PEB.ProcessHeap, reveal this: Flags and ForceFlags.
Under normal execution:
Flags=HEAP_GROWABLE(0x00000002)ForceFlags=0x00000000
When a process is created under a debugger (on Vista and later) the loader ORs in several checking bits:
| Added flag | Value |
|---|---|
HEAP_TAIL_CHECKING_ENABLED | 0x00000020 |
HEAP_FREE_CHECKING_ENABLED | 0x00000040 |
HEAP_VALIDATE_PARAMETERS_ENABLED | 0x40000000 |
ForceFlags additionally carries 0x40000060. Checking for ForceFlags != 0 is the most portable test.
How it works
Offsets for the Flags and ForceFlags fields vary by bitness and Windows version. On 64-bit Vista+:
- Heap
Flags→ heap base +0x14 - Heap
ForceFlags→ heap base +0x18
#include <windows.h>
BOOL HeapFlagsDebugged(void)
{
#ifdef _WIN64
PPEB pPeb = (PPEB)__readgsqword(0x60);
PVOID heap = *(PVOID *)((BYTE *)pPeb + 0x30); // PEB.ProcessHeap
DWORD flags = *(DWORD *)((BYTE *)heap + 0x14);
DWORD forceflags = *(DWORD *)((BYTE *)heap + 0x18);
#else
PPEB pPeb = (PPEB)__readfsdword(0x30);
PVOID heap = *(PVOID *)((BYTE *)pPeb + 0x18);
DWORD flags = *(DWORD *)((BYTE *)heap + 0x0C);
DWORD forceflags = *(DWORD *)((BYTE *)heap + 0x10);
#endif
// ForceFlags should always be 0 without a debugger
if (forceflags != 0) return TRUE;
// Flags should only have HEAP_GROWABLE set
if (flags & ~0x00000002) return TRUE;
return FALSE;
}Detection & bypass
During debugging:
- ScyllaHide patches heap flags automatically — ensure the "Heap Flags" option is ticked in its configuration.
- Manual fix: locate
PEB.ProcessHeapin the dump, setFlags = 0x00000002andForceFlags = 0x00000000. - NOP out or redirect the conditional jump following the comparison.
Static / automated detection:
- YARA: pattern-match on the byte offsets
0x14/0x0Ccombined with PEB access. - Emulators and sandboxes should initialise heap flags to their non-debug values to avoid false-positive evasion.
- Unprotect technique ID: U0112 / CAPA rule B0001.021.
Votes