Я пытаюсь понять разницу в механизмах, лежащих в основе привязки времени загрузки (используя gcc -l
) по сравнению с привязкой во время выполнения (используя dlopen(), dlsym()
) динамических библиотек в Linux и как эти механизмы влияют на состояние библиотеки и адреса его символов.
Эксперимент
У меня есть три простых файла:
libhello.c:
int var;
int func() {
return 7;
}
libhello.h:
extern int var;
int func();
main.c:
#include <inttypes.h>
#include <stdio.h>
#include <stdint.h>
#include <dlfcn.h>
#include "libhello.h"
int main() {
void* h = dlopen("libhello.so", RTLD_NOW);
printf("Address Load-time linking Run-time linking\n");
printf("------- ----------------- ----------------\n");
printf("&var 0x%016" PRIxPTR " 0x%016" PRIxPTR "\n", (uintptr_t)&var , (uintptr_t)dlsym(h, "var" ));
printf("&func 0x%016" PRIxPTR " 0x%016" PRIxPTR "\n", (uintptr_t)&func, (uintptr_t)dlsym(h, "func"));
}
Я компилирую libhello.c командой gcc -shared -o libhello.so -fPIC libhello.c
Я компилирую main.c командой gcc main.c -L. -lhello -ldl
Наблюдение
Запуск исполняемого файла main.c печатает примерно так:
Address Load-time linking Run-time linking
------- ----------------- ----------------
&var 0x0000000000601060 0x00007fdb4acb1034
&func 0x0000000000400700 0x00007fdb4aab0695
Адресаты ссылок на загрузку остаются неизменными, но адреса ссылок во время выполнения меняют каждый прогон.
Вопросы
- Почему во время запуска меняются адреса времени выполнения? Изменяются ли они из-за рандомизация размещения адресного пространства?
- Если это так, почему адреса не меняются для привязки времени загрузки? Является ли привязка времени загрузки уязвимой к тем же атакам, которые направлены на рандомизацию для защиты от?
- В приведенной выше программе одна и та же библиотека загружается дважды - один раз во время загрузки, а затем во время выполнения с помощью
dlopen()
. Второй груз не копирует состояние первой загрузки. То есть если значениеvar
изменено доdlopen()
, это значение не отражается в версииvar
, загруженной черезdlsym()
. Есть ли способ сохранить это состояние во время второй загрузки?