【问题标题】:What is the initial value of `ESP`?`ESP` 的初始值是多少?
【发布时间】:2021-11-23 19:25:23
【问题描述】:

在 Visual Studio masm 下:

    mov ecx,270
l1: pop eax
    loop l1
    push eax

这段代码的重点是找出ESP是否存在以及初始值是多少。我在程序启动后立即尝试pop,并实验在多少poppush 之后会产生一些与内存读取相关的错误。实验结果在某种程度上是不稳定的,即使ecx 的数字完全相同。通常,大于 512 总是(在我有限的实验时间内)会产生错误,小于 128 总是“安全”的,而 250 到 400 左右的值有时会产生错误。 ESP似乎没有初始值。如果有,我的实验应该会产生一些稳定的结果。

好的,我再运行 127 次 10 次,现在它开始崩溃。我正在尝试对此进行更多的实验。

我们只说使用 Windows-x86,平均启动像我的实验程序这样的程序的时刻。 Windows 如何确定esp 的初始值是多少?这很难确定吗(因为我可以想象简单地将堆栈段的最后一个地址放在esp 中)?是否有如何做到这一点的常见做法?

【问题讨论】:

  • 什么意思? esp 总是有一个值。您可以使用mov eax, esp 或类似名称阅读。
  • @NateEldredge 我在问esp 是否有初始值。也就是说,esp 会指向程序第一次启动的时间?
  • @NateEldredge 如果我启动一个程序并立即开始弹出,我会弹出一些东西或程序崩溃吗?如果弹出某些东西,这些东西会是什么?
  • @Zackham 这取决于处理器的状态,操作系统,各种东西。它有一个值,除非你推动,否则你不应该弹出。就是这样。
  • @Zackham ...不,它准确地解释了事情的真相。你还没有说哪个操作系统,哪个时刻,哪个情况。这就像问“冰淇淋的价格是多少?”要么你必须实际提供信息,要么这是任何人都可以给你的唯一答案。

标签: windows assembly x86 masm stack-pointer


【解决方案1】:

初始值是操作系统将堆栈放置在进程的虚拟地址空间中的任何位置。在现代操作系统中,它是随机的。

堆栈顶部_start 上方的内容取决于架构。在 Windows 上,您将获得一个实际返回地址,该地址将退出当前线程。在 Linux 上,您可以获得命令行和环境变量。在任何情况下,从堆栈中弹出你没有推送的东西都不会符合 ABI 并且会给你带来麻烦。此时唯一保留的规则是安全规则。

【讨论】:

  • 所以总的来说,确实有人/某事必须为每个程序决定和初始化 ESP,因此程序员不能以危险的方式编辑 ESP(比如在程序开头弹出)。根据我的实验,这个值应该非常接近栈底(小于 512*4=2KB)。开始时堆栈中包含的内容可能会在程序加载/链接的不同时间发生变化,这些是操作系统需要的一些信息。程序员应将操作系统分配的初始值视为堆栈的开头(底部)。我们就这样结束吧
猜你喜欢
  • 2018-03-03
  • 2016-10-28
  • 2023-03-29
  • 1970-01-01
  • 1970-01-01
  • 2012-06-29
  • 2011-01-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多