Где начинается стек для каждой программы в памяти? - PullRequest
2 голосов
/ 04 октября 2009

Где начинается стек каждой программы в памяти?

Я понимаю, что существует опция рандомизации адресного пространства, которая случайным образом выбирает адрес. Если опция отключена, запускается ли каждая программа с одного и того же адреса?

Что, если мы откроем два терминала и запустим две программы одновременно; Будет ли система использовать один и тот же начальный адрес для стеков двух программ (путем перезаписи стека предыдущей программы и загрузки стека текущей программы в то же место во время переключения контекста)?

Что делать, если я запускаю программу, вызывая функцию 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 ]

5 голосов
/ 04 октября 2009

Вам необходимо узнать о Виртуальной памяти . Да, вполне вероятно, что если ОС не имеет рандомизации разметки адресного пространства (ASLR), все программы будут иметь свой стек по одному и тому же виртуальному адресу. но это не означает, что ОС должна перемещать стек предыдущей программы просто для переключения контекста на другую программу, потому что через виртуальную память нужно просто убедиться, что две программы имеют одинаковый базовый виртуальный адрес, но каждый виртуальный адрес может иметь другое физическое местоположение. (это целый абзац целиком и полностью зависит от ОС),

Что касается вашего второго вопроса, execve заменяет текущую запущенную программу исполняемой программой, это включает в себя замену текущих сегментов текста / данных, а также стека, поэтому выполненная программа не увидит стек предыдущей программы.

2 голосов
/ 04 октября 2009

Ответ действительно зависит от используемой вами ОС и арки. Если отображается , вы используете вариант * nix, и, скорее всего, это означает, что Linux.

Для Linux до того, как рандомизация стала стандартной, по умолчанию не хватало места начала ядра. В моей системе x86 для стека используется регион (с отключенным ASLR): bffea000 - c0000000

ПРИМЕЧАНИЕ: предоставленное мною значение не обязательно является точным для всех систем, но это то же самое, что и для моей системы.

В современных системах Linux стек будет по довольно случайному адресу. Вы можете убедиться в этом, выполнив это несколько раз подряд:

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

Если опция отключена, я ожидаю, что все программы по умолчанию будут находиться в одном и том же месте (конец пользовательского пространства).

Запуск программы с exec заменяет ваше адресное пространство новой программой; это будет включать в себя стек, поэтому он окажется в том же месте, что и любая другая программа. Подумайте об этом: ваша оболочка должна сделать fork/exec, чтобы запустить программу так же, как ваша программа ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...