В системах ELF, таких как Linux, адреса, на которых загружаются сегменты обычных исполняемых файлов (ELF type ET_EXEC
), во время компиляции. Общие объекты (тип ELF ET_DYN
), такие как библиотеки, построены независимо от положения, причем их сегменты загружаются в любом месте адресного пространства (возможно, с некоторыми ограничениями на некоторые архитектуры). Можно создать исполняемые файлы таким образом, чтобы они были фактически ET_DYN
- они известны как «независимые от позиции исполняемые файлы» (PIE), но не являются общепринятой техникой.
Что вы видите, так это то, что ваша функция main()
находится в текстовом сегменте фиксированного адреса вашего скомпилированного исполняемого файла. Попробуйте также распечатать адрес библиотечной функции, такой как printf()
, после ее определения через dlsym()
- если ваша система поддерживает и включает рандомизацию размещения адресного пространства (ASLR), тогда вы должны увидеть адрес изменения этой функции от запуска до запуска вашей программы. (Если вы просто печатаете адрес библиотечной функции, помещая ссылку непосредственно в свой код, то на самом деле вы можете получить адрес батута функции поиска процедуры (PLT), который статически компилируется по фиксированному адресу в исполняемом файле .)
Переменная, которую вы видите, меняет адрес из run-to-run, потому что это автоматическая переменная, созданная в стеке, а не в статически выделенной памяти. В зависимости от ОС и версии адрес базы стека может переходить от запуска к run даже без ASLR. Если вы переместите объявление переменной глобально вне своей функции, вы увидите, что оно ведет себя так же, как и ваша функция main()
.
Вот полный пример - компилировать с чем-то вроде gcc -o example example.c -dl
:
#include <stdio.h>
#include <dlfcn.h>
int a = 0;
int main(int argc, char **argv)
{
int b = 0;
void *handle = dlopen(NULL, RTLD_LAZY);
printf("&main: %p; &a: %p\n", &main, &a);
printf("&printf: %p; &b: %p\n", dlsym(handle, "printf"), &b);
return 0;
}
http://xkcd.com/221/ – pmg
Эта ссылка может быть полезно: http://en.wikipedia.org/wiki/Address_space_layout_randomization. Я думаю, что адрес точки входа не рандомизирован. – PeterK
@pmg: +1 для этого xkcd linky ...:) – t0mm13b