Нахождение символа в моем собственном процессе
Вот настройки:
- Там есть приложение
A
что загружаетliba.so
(связано во время компиляции) liba.so
экспортирует символexpA
- Я тоже не контролирую
A
или жеliba.so
- Приложение A может загрузить указанную мной библиотеку,
libmine.so
в тот же процесс черезdlopen
(думаю, плагин архитектуры) - Мне нужно использовать
expA
отlibmine.so
но не знаю, как найти его без явной ссылки наliba.so
что я и делал до сих пор. Я предполагаю, что это не будет работать в реальном мире, так как этот символ не гарантированно будет находиться по тому же адресу, что и в моей локальной копииliba.so
(либо это?).libmine.so
будет закрытым исходным кодом и не может быть перекомпилирован сA
,
Я никогда не делал ничего подобного, поэтому немного неясен в деталях загрузки библиотеки. Например, если я попытаюсь dlopen("liba.so")
изнутри libmine.so
я получу дескриптор к уже загруженной библиотеке или новой копии?
С точки зрения того, как libmine.so
все, что я знаю, это то, что он будет загружен RTLD_LAZY
(и ничего больше).
Любая помощь и указатели будут с благодарностью!
1 ответ
Если все liba.so
библиотека dlopen
Эд, используя RTLD_GLOBAL
тогда вы можете использовать dlsym(RTLD_DEFAULT, "expA")
чтобы найти символ без необходимости заново открывать библиотеку.
Если liba.so
библиотека dlopen
Эд, используя RTLD_LOCAL
тогда вам нужно будет получить дескриптор библиотеки с помощью dlopen
снова в вашем собственном libmine.so
, Обратите внимание на следующее:
Если та же библиотека загружается снова с помощью dlopen(), возвращается тот же дескриптор файла. Библиотека dl поддерживает количество ссылок для дескрипторов библиотеки, поэтому динамическая библиотека не освобождается до тех пор, пока dlclose() не будет вызвана для нее столько раз, сколько dlopen () преуспел в ней. Процедура _init(), если она есть, вызывается только один раз. Но последующий вызов с RTLD_NOW может вызвать разрешение символов для библиотеки, ранее загруженной с RTLD_LAZY.
то есть это та же самая копия библиотеки.
механизм (псевдо), предполагая, что expA является функцией: int expA(int value)
:
int (*fpointer)(int) = NULL;
void *handle = dlopen("liba.so", RTLD_LAZY | RTLD_LOCAL);
if (handle != NULL) {
void *symbol = dlsym(handle, "expA");
if (symbol != NULL) {
fpointer = (int (*)(int ))symbol;
}
}
Это псевдокод, практически без ошибок.