Каков адрес, напечатанный 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
Все адреса, просматриваемые программой, являются виртуальными.
Однако локальные переменные идут на стек и глобальные на специальную область, называемую сегментом данных.
Хотя переменные относительные местоположения решаются при компиляции, стек может меняться при каждом прогоне.