gpt4 book ai didi

c++ - 是否可以保护内存区域免受 WinAPI 的影响?

转载 作者:太空狗 更新时间:2023-10-29 20:15:01 26 4
gpt4 key购买 nike

已阅读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 newoperator delete(以及它们的 [] 亲戚),以便您的内存分配由您的代码控制。

请记住,它只会以每页为基础,每次分配您将使用(至少)三页值(value)的虚拟内存 - 在 64 位系统上不是一个大问题,但可能如果您在 32 位系统中有很多分配,则会导致问题。

大致需要做的事情(您实际上应该找到构建 Windows 的页面大小 - 我太懒了,所以我将使用 4096 和 4095 来表示页面大小和页面大小-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 虚拟机,而且我懒得下载编译器并查看它是否真的编译。 [我知道这个原理是有效的,因为我们在几年前的工作中做过类似的事情]。

关于c++ - 是否可以保护内存区域免受 WinAPI 的影响?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14595989/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com