【问题标题】:Why does the value of stack pointer is same every time when ASLR is turned off?为什么每次关闭 ASLR 时堆栈指针的值都相同?
【发布时间】:2014-08-17 10:27:24
【问题描述】:

虽然系统上有很多函数在运行,但是堆栈指针(ESP)的值怎么可能每次都相同,因为每个函数都在堆栈上运行(因为每个函数都有不同的地址)????尤其是当 ASLR 关闭时????

【问题讨论】:

  • 我怀疑堆栈指针是“每个函数每次都相同”。
  • “相同”跨越什么?从不同深度的调用栈调用函数时就不一样了。

标签: buffer-overflow aslr


【解决方案1】:

实际上开启 ASLR 可能会影响每个单独线程的堆栈基地址。这是来自“Windows Internals,第六版,第 2 部分”,pp.249-250 的引述:

“ASLR 的下一步是随机化初始线程堆栈的位置(以及随后每个新线程的位置)。除非为进程启用了标志 StackRandomizationDisabled 并且包括首先选择由 64 KB 或 256 KB 分隔的 32 个可能的堆栈位置之一。通过找到第一个适当的空闲内存区域,然后选择第 x 个可用区域来选择此基地址,其中 x 再次根据当前处理器的 TSC 移位生成,并且掩码为 5 位值(允许 32 个可能的位置)。

一旦选择了这个基地址,就会计算一个新的 TSC 派生值,这个 9 位长。然后将该值乘以 4 以保持对齐,这意味着它可以大到 2,048 字节(半页)。与基地址相加得到最终的栈基”。

上面提到的标志(StackRandomizationDisabled)驻留在内核空间结构EPROCESS中,不能从用户空间显式设置。但是,如果关闭 ASLR,则应用程序中主线程的堆栈基地址将与不同的重新运行相同。实际上,这意味着如果您每次运行应用程序时都在同一行的同一函数中,那么 ESP/RSP 将是相同的。

一些例子demonstrating this concept

请注意,操作系统中的每个进程都有自己的虚拟地址空间,但它与物理地址空间不同。因此,如果您同时运行应用程序的两个实例(ASLR 关闭)并在同一个地方执行,您将看到相同的 ESP/RSP 值。每个值都属于自己进程的虚拟地址空间,与其他进程没有关联。例如,您可以参考此链接for more info on memory layout

【讨论】:

    【解决方案2】:

    每个函数的堆栈指针的值都不相同,并且不依赖于 ASLR 设置。堆栈指针在创建执行线程时设置在某个位置,并且函数在程序执行时递增或递减它以用于数据存储。特别是,函数代码通常不存储在堆栈中;函数代码的指针是。

    如果没有 ASLR,一旦遇到堆栈缓冲区溢出错误,您可以插入一个“代码块”来调用被利用应用程序中的其他函数,因为您知道这些函数在哪里。使用 ASLR,您无法轻松做到这一点,因为您不知道该代码位于何处。

    【讨论】:

    • 假设我们已经关闭了 ASLR。然后当我们打印出 esp 时,它每次都显示相同的值。那么 esp 怎么可能总是指向同一个地址。很多功能每次都在系统上运行。
    • @user:ASLR 不移动堆栈。 ASLR 移动代码。堆栈不包含代码;它只包含指向代码的指针。如果您要在堆栈上打印返回地址的值,您会期望它们在运行时会有所不同,但堆栈本身是已知的。将 ASLR 应用到堆栈没有任何优势——shellcode 可以随时通过询问 ESP 来获取它的位置 :)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-30
    • 2019-11-23
    • 2010-12-19
    • 1970-01-01
    相关资源
    最近更新 更多