Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/70.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/188.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 带有PAGE_GUARD的VirtualProtect不使用局部变量_C++_C_Windows_Winapi_Memory - Fatal编程技术网

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:“系统根据需要从保留堆栈内存提交额外的页面,直到堆栈达到保留大小减去一页(用作防止堆栈溢出的保护页)为止或者系统内存不足,导致操作失败。”此外:“堆栈的动态增长是通过保护页执行的:刚刚超过堆栈上最后一个有效页的就是保护页。当堆栈扩展到保护页时,会引发保护页异常,默认异常处理程序通过提交新的堆栈页并将下一页设置为保护页来处理该异常。。。保护页异常完全在内核中处理。用户模式异常处理程序无法查看或拦截它们“