加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c – 是否可以保护WinAPI的内存区域?

发布时间:2020-12-16 09:42:16 所属栏目:百科 来源:网络整理
导读:阅读了 this interesting article概述了一种调试堆损坏的技术,我开始想知道如何根据自己的需要调整它.基本思想是提供一个自定义的malloc()来分配整个内存页面,然后为这些页面启用一些内存保护位,这样程序在写入时会崩溃,并且可以在行为中捕获有问题的写入指
阅读了 this interesting article概述了一种调试堆损坏的技术,我开始想知道如何根据自己的需要调整它.基本思想是提供一个自定义的malloc()来分配整个内存页面,然后为这些页面启用一些内存保护位,这样程序在写入时会崩溃,并且可以在行为中捕获有问题的写入指令.示例代码是Linux下的C(mprotect()用于启用保护),我很好奇如何将其应用于本机C和Windows. VirtualAlloc()和/或VirtualProtect()看起来很有前途,但我不确定使用场景会是什么样子.

Fred *p = new Fred[100];
ProtectBuffer(p);
p[10] = Fred(); // like this to crash please

我知道在Windows中存在用于调试内存损坏的专用工具,但我仍然很好奇是否可以使用这种方法“手动”执行此操作.

编辑:此外,这是一个在Windows下的好主意,还是只是一个有趣的智力练习?

解决方法

是的,您可以使用VirtualAlloc和VirtualProtect来设置受读/写操作保护的内存部分.

您必须重新实现operator new和operator delete(以及它们的[]亲属),以便您的内存分配由您的代码控制.

请记住,它只会在每页的基础上,并且每个分配您将使用(至少)三页虚拟内存 – 这在64位系统上不是一个大问题,但如果是你在32位系统中有很多分配.

大概你需要做什么(你应该找到构建Windows的页面大小 – 我太懒了,所以我会用4096和4095来表示pagesize和pagesize-1 – 你还需要做更多错误检查比这个代码确实!!!):

void *operator new(size_t size)
{
    Round size up to size in pages + 2 pages extra.
    size_t bigsize = (size + 2*4096 + 4095) & ~4095; 

    // Make a reservation of "size" bytes. 
    void *addr = VirtualAlloc(NULL,bigsize,PAGE_NOACCESS,MEM_RESERVE);

    addr = reinterpret_cast<void *>(reinterpret_cast<char *>(addr) + 4096);

    void *new_addr = VirtualAlloc(addr,size,PAGE_READWRITE,MEM_COMMIT); 

    return new_addr;
}

void operator delete(void *ptr)
{
    char *tmp = reinterpret_cast<char *>(ptr) - 4096;

    VirtualFree(reinterpret_cast<void*>(tmp)); 
}

正如我所说的那样 – 我还没有尝试编译这个代码,因为我只有一个Windows VM,我不能打扰下载编译器并查看它是否实际编译. [我知道这个原则是有效的,因为我们在几年前的工作中做了类似的事情].

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读