I am adding the PAGE_GUARD
protection to pages of the current thread's stack via VirtualProtect
. However, on accessing the stack, the exception handler I have installed is never executed.
I assume the OS just silently swallows the Guard-Page-Violation Exceptions because it uses guard pages to manage stack growth and stack overflows.
Is it in this case possible to catch these exceptions at all ?
Here is my C-code
#include <stdio.h>
#include <Windows.h>
#include <assert.h>
LONG WINAPI BlanketExceptionHandler(struct _EXCEPTION_POINTERS *ExceptionInfo) {
printf("exception code: %lx\n", ExceptionInfo->ExceptionRecord->ExceptionCode);
return EXCEPTION_CONTINUE_SEARCH;
}
int main(void) {
// Install exception handler
SetUnhandledExceptionFilter(BlanketExceptionHandler);
ULONG_PTR stackBot = 0, stackTop = 0;
GetCurrentThreadStackLimits(&stackBot, &stackTop);
assert(stackBot < stackTop);
// turn all pages in the stack into guard-pages
DWORD savedProtect = 0;
if(!VirtualProtect((LPVOID) stackBot, stackTop - stackBot, PAGE_READWRITE | PAGE_GUARD, &savedProtect)){
fprintf(stderr, "[Error]: Could not add guard pages: %ld\n", GetLastError());
return 1;
}
// access some stack memory page. This should trigger the registered exception handler!
*(DWORD*) (stackTop - 0x1500) = 0xdeadbeef;
return 0;
}
Code needs to be compiled with
cl /nologo main.c /link /STACK:0x100000,0x100000
Running the code gives no output from the BlanketExceptionHandler
. But, using VirtualQuery
, I have observed that the stack pages have the correct protections.
I have also tried installing the exception handler through AddVectoredExceptionHandler
but that did not work either.
CodePudding user response:
Is it in this case possible to catch these exceptions at all ?
no. if you access guard page, exception (as any exception) first will be handle by kernel code. if exception ocur in current thread stack range - the kernel handler remove PAGE_GUARD
from page, where exeception was, ensure that bellow this page - several PAGE_GUARD
exist and adjust StackLimit := PAGE_ALIGN(MemmoryAccessAddress)
in NT_TIB
(you can check this). and not call user mode exception handlers (if this not the last page in stack)