Каков адрес, напечатанный printf() с форматом% p в c?

У меня есть простой код:

#include<stdio.h>

int glob;

int main(void)
{
   int a;
   printf("&a is : %p \n", &a);
   printf("glob is : %p \n", &glob);
   return 0;
}

Вывод вышеуказанной программы: Первый запуск:

&a is : 0x7fff70de91ec
glob is : 0x6008f4

Второй запуск:

&a is : 0x7fff38c4c7ac
glob is : 0x6008f4

Я изучаю виртуальные и физические адреса. У меня есть следующий вопрос:

  • Каков печатный адрес (физический/виртуальный) переменной "a"?
  • Если он виртуальный, то как он изменяется в каждом прогоне той же программы? Как я понял, компилятор предоставляет виртуальный адрес переменным во время компиляции?
  • Почему адрес глобальной переменной является постоянным в каждом запуске программы?

В исполнении этой программы на Linux: 2.6.18-308.el5 x86_64 GNU/Linux

Скомпилировано с использованием: gcc версии 4.1.2 20080704 (Red Hat 4.1.2-52)

Ответы

Ответ 1

Адреса, видимые в программе, всегда являются виртуальными, а поведение, описанное OP, является контрмером Linux, чтобы избежать атак переполнения буфера.

Просто, чтобы попробовать, вы можете отключить его с помощью

sysctl -w kernel.randomize_va_space=0

затем снова запустите свою программу и посмотрите.

Глобальный находится в другом пространстве памяти, которое не может быть вредным в хакерской точке зрения. Это потому, что оно не рандомизировано каждый раз.

Ответ 2

Оба адреса являются виртуальными.

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

Ответ 3

Ваша программа будет всегда видеть только виртуальный адрес.

Реальные адреса доступны только для диспетчера виртуальной памяти в режиме ядра.

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

Локальные переменные всегда создаются в стеке.

Ответ 4

Все адреса, просматриваемые программой, являются виртуальными. Однако локальные переменные идут на стек и глобальные на специальную область, называемую сегментом данных. Хотя переменные относительные местоположения решаются при компиляции, стек может меняться при каждом прогоне.