正如我们所知,使堆栈和虚拟内存的堆区域不可执行可以防止在内存中执行恶意代码(如shellcode)(该技术称为Data Execution Prevention)。并且,将恶意代码注入内存的最简单方法是使缓冲区溢出。因此,使这些内存区域不可执行可以帮助降低溢出攻击的严重性。
然而,还有许多其他技术,如地址空间随机化,指针保护,使用金丝雀等,用于防止此类攻击。我认为大多数系统都使用这些其他方法而不是使堆栈/堆内存不可执行。(如果我错了,请纠正我)
现在,我的问题是,是否有一些特定的操作或特殊情况需要内存的堆栈/堆部分可执行?
答案 0 :(得分:1)
JIT映射内存的可写区域和可执行区域,或者只是mprotect
先前分配的内存以使其可执行。
GCC曾经要求一个系统相关的方法来标记其蹦床代码的可执行堆栈部分。这是12年前的事了,我不知道今天是怎么做的。
许多系统上的动态链接还需要能够为运行时解析的函数调用写入跳转表。如果你想让跳转表在表的更新之间不可写,那可能会非常昂贵。
通常,可以通过尝试强制执行内存可写或可执行的策略来安全地解决这些问题,但不能同时解决这两个问题。当需要完成写入然后再次保护以使其可执行时,可以将内存重新映射为可写入。它会牺牲一些性能(不是那么多)以获得更好的安全性和更复杂的代码。