c - 在使用完整页堆的 buf = malloc(1) 后,为什么直到 buf[16] 被覆盖时才抛出保护页异常?

标签 c windows heap-memory windbg pageheap

  1. 错误中的代码

    int main()
    {
        void *ptr = 0;    
        int overrun = 1;
        ptr = malloc(overrun);
        while(overrun++)
        {
            if(!ptr)
                while(1) Sleep(500);
            *((char*)ptr + (overrun+1)) = 'a';
            printf("\n%d\n",overrun);
        }
        return 0;
    }
    
  2. 从 Visual Studio 2010 的项目菜单中确保构建版本为“Release”和“x64”(机器为 x64)

  3. 启用全页堆

    gflags /p /enable test.exe /full
    
  4. 将 Windbg 设置为默认调试器

    E:\installed\Debugging Tools for Windows (x64)>windbg -I
    
  5. 将代码作为独立于 cmd 的 exe 运行,无需调试器

    输出:

    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    

    之后,可以看到 Windbg 捕获了损坏。我认为整页堆应该能够立即捕获损坏。

    对于为什么整页堆很糟糕有什么评论吗?

最佳答案

由于堆分配需要对齐,因此在发生溢出时无法捕获未跨越对齐边界的溢出,因为内存保护是页粒度的,而不是字节粒度的。这是硬件限制。当您释放内存时,将检测到溢出,并检查尾部字节是否被篡改。

(顺便说一句,说某件事很糟糕会让你被指控的人不太可能费心帮助你解决问题。只是一个提示。)

关于c - 在使用完整页堆的 buf = malloc(1) 后,为什么直到 buf[16] 被覆盖时才抛出保护页异常?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13313587/

相关文章:

c - Doxygen 有没有办法在函数原型(prototype)中使用宏?

c - 我如何知道指针是否指向特定结构?

c - 接受非 ASCII 字符

go - 准确测量堆增长

java-8 - 如何在没有java堆内存错误的情况下将csv读入pyspark

C : how can I change from file descriptor to FILE struct and vice versa?

c - LR Merc_timer_handle_t

c++ - 如何在 C++ MFC 中同时打开两个对话框?

windows - 如何检测 Windows 终端服务器是否处于安装模式

c++ - 我的 park_car 功能有什么问题?