为什么每次ASLR关闭时堆栈指针的值都相同?

时间:2014-08-17 10:27:24

标签: buffer-overflow aslr

虽然在系统上运行了很多函数,但堆栈指针(ESP)的值如何在堆栈上运行的每个函数每次都相同(因为每个函数都有不同的地址)????特别是当ASLR关闭时????

2 个答案:

答案 0 :(得分:1)

ASLR实际上可能会影响每个单独线程的堆栈基址。以下是来自" Windows Internals,第六版,第2部分",第249-250页的引用:

  

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

     

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

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

一些例子demonstrating this concept

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

答案 1 :(得分:0)

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

如果没有ASLR,一旦你遇到堆栈缓冲区溢出错误,就可以插入一个"代码blob"在被利用的app中调用其他函数,因为你知道这些函数在哪里。使用ASLR,您无法轻易做到这一点,因为您不知道代码的位置。