1

众所周知,使虚拟内存的堆栈和堆区域不可执行可以防止恶意代码(如shellcode)在内存中执行(该技术称为数据执行保护)。而且,将恶意代码注入内存的最简单方法是溢出缓冲区。因此,使内存的这些区域不可执行有助于降低溢出攻击的严重性。

但是,还有许多其他技术可以用来防止此类攻击,例如地址空间随机化、指针保护、使用金丝雀等。我认为大多数系统都使用这些其他方法,而不是使堆栈/堆内存不可执行。(如果我在这里错了,请纠正我)

现在,我的问题是,是否有一些特定的操作或特殊情况需要内存的堆栈/堆部分是可执行的?

4

1 回答 1

1

JIT 映射内存的可写和可执行区域,或者简单地映射mprotect先前分配的内存以使其可执行。

GCC 过去需要一种依赖于系统的方法来标记堆栈的部分可执行文件,以供其蹦床代码使用。这是12年前的事了,不知道今天怎么样了。

许多系统上的动态链接还需要能够写入跳转表以在运行时解决函数调用。如果您想让跳转表在表的更新之间不可写,这可能会非常昂贵。

通常,可以通过尝试强制执行内存可写或可执行的策略来安全地解决这些问题,但不能两者兼而有之。当需要写入时,内存可以重新映射为可写,然后再次保护以使其可执行。它牺牲了一些性能(不是那么多)以获得更好的安全性和稍微复杂的代码。

于 2013-09-25T07:23:45.240 回答