Guard Pages

Created the Saturday 23 March 2019. Updated 3 years, 6 months ago.

Memory breakpoints are implemented by using guard pages. Detection of guard pages is based on imitation of debugger behavior - i.e. creation of PAGE_GUARD memory page and accessing it, previously put return address onto the stack. If STATUS_GUARD_PAGE_VIOLATION occurs, it’s assumed no debugging is in place.

Technique Identifier


Technique Tag


Code Snippets

#include "pch.h"

#include "MemoryBreakpoints_PageGuard.h"

In essence, what occurs is that we allocate a dynamic buffer and write a RET to the buffer.
We then mark the page as a guard page and push a potential return address onto the stack. Next, we jump to our page,
and if we're under a debugger, specifically OllyDBG, then we will hit the RET instruction and return to the address we pushed onto
the stack before we jumped to our page. Otherwise, a STATUS_GUARD_PAGE_VIOLATION exception will occur, and we know we're not being
debugged by OllyDBG.

BOOL MemoryBreakpoints_PageGuard()
	UCHAR *pMem = NULL;
	SYSTEM_INFO SystemInfo = { 0 };
	DWORD OldProtect = 0;
	PVOID pAllocation = NULL; // Get the page size for the system 

	// Retrieves information about the current system.

	// Allocate memory 
	pAllocation = VirtualAlloc(NULL, SystemInfo.dwPageSize, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
	if (pAllocation == NULL)
		return FALSE;

	// Write a ret to the buffer (opcode 0xc3)
	RtlFillMemory(pAllocation, 1, 0xC3);

	// Make the page a guard page         
	if (VirtualProtect(pAllocation, SystemInfo.dwPageSize, PAGE_EXECUTE_READWRITE | PAGE_GUARD, &OldProtect) == 0)
		return FALSE;

		((void(*)())pAllocation)(); // Exception or execution, which shall it be :D?
		VirtualFree(pAllocation, 0, MEM_RELEASE);
		return FALSE;

	VirtualFree(pAllocation, 0, MEM_RELEASE);
	return TRUE;

Detection Rules

rule Detect_GuardPages: AntiDebug {
        description = "Detect Guard Pages as anti-debug"
        author = "Unprotect"
        comment = "Experimental rule"
        $1 = "GetSystemInfo" fullword ascii
        $2 = "VirtualAlloc" fullword ascii
        $3 = "RtlFillMemory" fullword ascii
        $4 ="VirtualProtect" fullword ascii
        $5 ="VirtualFree" fullword ascii
       uint16(0) == 0x5A4D and filesize < 1000KB and 4 of them 

Additional Resources

External Links

Subscribe to our Newsletter

The information entered into this form is mandatory. It will be subjected to computer processing. It is processed by computer in order to support our users and readers. The recipients of the data will be :

According to the Data Protection Act of January 6th, 1978, you have at any time, a right of access to and rectification of all of your personal data. If you wish to exercise this right and gain access to your personal data, please write to Thomas Roccia at

You may also oppose, for legitimate reasons, the processing of your personal data.