C++ 带有PAGE_GUARD的VirtualProtect不使用局部变量
这正如预期的那样有效。将引发C++ 带有PAGE_GUARD的VirtualProtect不使用局部变量,c++,c,windows,winapi,memory,C++,C,Windows,Winapi,Memory,这正如预期的那样有效。将引发状态\u保护\u页面\u违规 int main() { DWORD oldp; DWORD *pdp = new DWORD; *pdp = 0; if (!VirtualProtect(pdp, sizeof(DWORD), PAGE_READWRITE | PAGE_GUARD, &oldp)) return 1; *pdp = 1000; return 0; } 但是,当运行几乎相同的代码
状态\u保护\u页面\u违规
int main()
{
DWORD oldp;
DWORD *pdp = new DWORD;
*pdp = 0;
if (!VirtualProtect(pdp, sizeof(DWORD), PAGE_READWRITE | PAGE_GUARD, &oldp))
return 1;
*pdp = 1000;
return 0;
}
但是,当运行几乎相同的代码时,程序将毫无例外地退出
int main()
{
DWORD oldp;
DWORD pd = 0;
DWORD *pdp = &pd;
if (!VirtualProtect(pdp, sizeof(DWORD), PAGE_READWRITE | PAGE_GUARD, &oldp))
return 1;
*pdp = 1000;
return 0;
}
两个程序都以代码0退出,因此VirtualProtect
正在成功完成。那么,在第二个示例中,当我尝试访问受保护的内存时,为什么没有出现异常
编辑:
运行此命令会导致访问冲突;从而证明了托恩的假设
int main()
{
DWORD oldp;
DWORD pd = 0;
DWORD *pdp = &pd;
if (!VirtualProtect(pdp, sizeof(DWORD), PAGE_NOACCESS, &oldp))
return 1;
return 0;
}
在第二个示例中,您在应用程序堆栈使用的内存页上设置了一个页面保护。VirtualProtect成功后,首次访问该页面将引发异常。第一次访问不是由“*pdp=1000”代码完成的。这可能是VirtualProtect函数中已经完成的访问。如果这能很好地处理这个(特定的)异常,它将解释您看到的行为。好问题。你能VirtualProtect
堆栈吗?看来我能,因为在第二个例子中,我用PAGE\u NOACCESS
调用VirtualProtect
,而不是PAGE\u READWRITE\PAGE\u GUARD
当我尝试取消引用pdp
时,我得到了一个EXCEPTION\u ACCESS\u违规
。堆栈使用保护页来确定何时需要扩展。访问冲突发生,但被Windows捕获并处理,您永远看不到它。(当然,你不应该一开始就干扰对不属于你的地址空间的权限。)Per:“系统根据需要从保留堆栈内存提交额外的页面,直到堆栈达到保留大小减去一页(用作防止堆栈溢出的保护页)为止或者系统内存不足,导致操作失败。”此外:“堆栈的动态增长是通过保护页执行的:刚刚超过堆栈上最后一个有效页的就是保护页。当堆栈扩展到保护页时,会引发保护页异常,默认异常处理程序通过提交新的堆栈页并将下一页设置为保护页来处理该异常。。。保护页异常完全在内核中处理。用户模式异常处理程序无法查看或拦截它们“