每个程序的堆栈在内存中从哪里开始?

时间:2009-10-03 23:33:36

标签: memory-management

每个程序的堆栈在内存中的哪个位置?

我知道有随机地址空间选项会随机选择一个地址。如果禁用该选项,每个程序是否从同一地址开始?

如果我们打开两个终端并同时运行两个程序怎么办?系统是否会对两个程序的堆栈使用相同的起始地址(通过覆盖先前程序的堆栈并在上下文切换期间将当前程序的堆栈加载到同一位置)?

如果我通过调用exec() - 族函数运行程序,如下例所示,该怎么办?这个程序会有不同的堆栈和“易受攻击”程序的不同堆栈吗?或者在调用程序的堆栈之上只有一个不同的堆栈框架易受攻击?

int main(int argc, char *argv[]) {
  char *buff, *ptr;
  int i;
  bsize  = atoi(argv[1]);

  if (!(buff = malloc(bsize))) {
    printf("Can't allocate memory.\n");
    exit(0);
  }
  for (i = 0; i < bsize; i+=4)
    buff[i] = '0';

  execl("/home/amulya/Desktop/CMPE209/HWs/HW2/vulnerable","vulnerable", buff, NULL);
  return(-1);
}

2 个答案:

答案 0 :(得分:5)

您需要了解Virtual Memory。是的,如果操作系统没有地址空间布局随机化(ASLR),则所有程序的堆栈都可能位于相同的虚拟地址。但这并不意味着操作系统必须将上一个程序的堆栈移动到上下文切换到另一个程序,因为通过虚拟内存它只需要确保两个程序具有相同的基本VIRTUAL地址,但每个虚拟地址可以有一个不同的物理位置。 (这是完整的段落完全取决于操作系统),

关于你的第二个问题,execve将当前正在运行的程序替换为要执行的程序,这包括替换当前的文本/数据段以及堆栈,因此执行的程序将看不到前一个程序的堆栈。 / p>

答案 1 :(得分:2)

答案实际上取决于您使用的操作系统和拱门。 显示您正在使用* nix变体,而赔率则意味着Linux。

对于Linux,在随机化成为标准之前,默认值只是内核空间开始的地方。在我的x86系统上,默认使用堆栈的区域(默认情况下禁用ASLR):bffea000 - c0000000

注意:我提供的值不一定对所有系统都准确,但这就是我的系统。

在现代Linux系统上,堆栈将处于相当随机的地址。您可以通过连续多次运行来验证这一点:

cat /proc/self/maps | grep "\[stack\]"

如果禁用该选项,我希望所有程序堆栈默认为相同位置(用户空间结束)。

使用exec 运行程序会用新程序替换您的地址空间;这将包括堆栈,因此它将最终与任何其他程序运行在同一位置。想一想:你的shell程序必须执行fork/exec来运行程序,就像你的程序一样......