【问题标题】:Need of executable stack and heap memory需要可执行堆栈和堆内存
【发布时间】:2013-09-25 05:30:31
【问题描述】:

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

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

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

【问题讨论】:

  • 如果堆是可执行的,JIT 很容易实现。不过,不确定它是如何完成的。
  • GCC's nested functions 的蹦床代码需要一个可执行堆栈 AFAIK。

标签: c security memory buffer-overflow


【解决方案1】:

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

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

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

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

【讨论】:

    猜你喜欢
    • 2011-10-21
    • 2011-06-13
    • 2019-01-05
    • 1970-01-01
    • 1970-01-01
    • 2018-09-27
    • 2020-04-19
    • 2020-02-28
    • 2019-05-17
    相关资源
    最近更新 更多