【发布时间】:2014-08-17 10:27:24
【问题描述】:
虽然系统上有很多函数在运行,但是堆栈指针(ESP)的值怎么可能每次都相同,因为每个函数都在堆栈上运行(因为每个函数都有不同的地址)????尤其是当 ASLR 关闭时????
【问题讨论】:
-
我怀疑堆栈指针是“每个函数每次都相同”。
-
“相同”跨越什么?从不同深度的调用栈调用函数时就不一样了。
标签: buffer-overflow aslr
虽然系统上有很多函数在运行,但是堆栈指针(ESP)的值怎么可能每次都相同,因为每个函数都在堆栈上运行(因为每个函数都有不同的地址)????尤其是当 ASLR 关闭时????
【问题讨论】:
标签: buffer-overflow aslr
实际上开启 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。
【讨论】:
每个函数的堆栈指针的值都不相同,并且不依赖于 ASLR 设置。堆栈指针在创建执行线程时设置在某个位置,并且函数在程序执行时递增或递减它以用于数据存储。特别是,函数代码通常不存储在堆栈中;函数代码的指针是。
如果没有 ASLR,一旦遇到堆栈缓冲区溢出错误,您可以插入一个“代码块”来调用被利用应用程序中的其他函数,因为您知道这些函数在哪里。使用 ASLR,您无法轻松做到这一点,因为您不知道该代码位于何处。
【讨论】: