我正在尝试使用PAGE_GUARD挂钩函数,但在调用页面/地址时不会引发任何异常。
void HookMe(){
printf("Not hooked\n");
}
void GoodFnc(){
printf("Hooked!\n");
}
long ExceptionHandler(PEXCEPTION_POINTERS ex){
printf("ExceptionHandler called\n");
}
/*Called by CreateThread in main*/
DWORD WINAPI ExceptionTesting(LPVOID) {
DWORD old = 0;
AddVectoredExceptionHandler(1, ExceptionHandler);
if (VirtualProtect((LPVOID)HookMe, 1, PAGE_EXECUTE_READWRITE | PAGE_GUARD, &old))
printf("PAGE_GUARD set\n");
//This was for testing:
//*(char*)0 = 0;//ExceptionHandler gets called when ACCESS_VIOLATION happens
while (1) {
HookMe();
Sleep(1000);
}
return 0;
}
上面的代码每秒只显示PAGE_GUARD set
然后Not hooked
,而不会引发任何异常。
我还确保HookMe()
位于与ExceptionHandler(...)
和ExceptionTesting(LPVOID)
导致任何类型的异常,例如ACCESS_VIOLATION(如无限循环上方的注释中所示)将导致调用ExceptionHandler。
答案 0 :(得分:2)
根据您的编译器,可能会内联对HookMe
的调用。检查生成的代码。你应该能够在__declspec(noinline)
的声明中用HookMe
之类的东西来打败这个。 (MS VC ++)。请注意,即使在所有调用中内联函数,您也可以获取函数的地址!
答案 1 :(得分:2)
documentation for VirtualProtect表示受保护的地址必须是使用VirtualAlloc
(或VirtualAllocEx
)获取的保留区域的一部分。程序中的代码没有以这种方式分配。
此外,保护是在页面基础上完成的(通常是4K),因此上面示例中代码的所有都可能受到保护,并且当调用时,警卫会立即关闭VirtualProtect
已退回 - 而不是在Hook
被调用时。
答案 2 :(得分:1)
更改对已提交的网页区域的保护 调用进程的虚拟地址空间。
PAGES - 不是单字节。我们至少可以在页面(0x1000)字节上设置PAGE_GUARD
属性。因此,当您尝试将PAGE_GUARD
设置为某个函数时 - 您不仅将保护属性设置为它,而且将其设置为围绕它的许多字节(之前和之后)。如果您的代码是这样的代码(无论如何您的代码是伪代码,甚至不能编译) - 所有保护异常将在VirtualProtect
返回后更快 - 在调用后的下一条指令上。如果您只希望保护页面影响单个功能 - 您需要将其放在单独的exe部分中,例如#pragma code_seg
。也可以注意 - 不需要任何无限循环或单独的线程创建测试
//#pragma code_seg(".guard")
void HookMe(){
MessageBoxW(0, 0, L"HookMe", MB_ICONINFORMATION);
}
#pragma code_seg()
LONG NTAPI ExceptionHandler(::PEXCEPTION_POINTERS pep)
{
if (pep->ExceptionRecord->ExceptionCode == STATUS_GUARD_PAGE_VIOLATION)
{
WCHAR msg[64];
swprintf(msg, L"guard violation at %p (%p)", pep->ExceptionRecord->ExceptionAddress, HookMe);
MessageBoxW(0, msg, L"ExceptionHandler", MB_ICONWARNING);
return EXCEPTION_CONTINUE_EXECUTION;
}
return EXCEPTION_CONTINUE_SEARCH;
}
void gtest()
{
if (PVOID pv = AddVectoredExceptionHandler(TRUE, ExceptionHandler))
{
ULONG op;
if (VirtualProtect(HookMe, 1, PAGE_EXECUTE_READ|PAGE_GUARD, &op))
{
HookMe();
}
RemoveVectoredExceptionHandler(pv);
}
}