Как вы вызываете исполняемый файл из конструктора библиотеки, загруженного с помощью LD_PRELOAD?

Я хочу иметь возможность вызывать исполняемый файл из предварительно загруженной библиотеки. Сделать это -

У меня есть простой исполняемый файл

main.c

#include <stdio.h>

void callme()
{
    printf("callme\n");
}

int main(int argc, char *argv[])
{
    callme();
    return 0;
};

Это скомпилировано с

gcc -m32 main.c

Теперь я хочу предварительно загрузить библиотеку, чтобы callme вызывалась перед main.

предварительная загрузка.c

extern void callme();

void preload_init() __attribute__((constructor));
void preload_fini() __attribute__((destructor));

void preload_init()
{
    callme();
}

void preload_fini()
{
    callme();
}

Это скомпилировано с

gcc -D_GNU_SOURCE -shared -o libpreload.so preload.c -fPIC -m32 -ldl

Так что теперь у меня есть a.out и libpreload.so

Когда я пытаюсь запустить это

LD_PRELOAD=./libpreload.so ./a.out
./a.out: symbol lookup error: ./libpreload.so: undefined symbol: callme

Чтобы отладить это, я попытался

LD_DEBUG=symbols LD_PRELOAD=./libpreload.so ./a.out

Выход из этого включает эту строку

13184:     symbol=callme;  lookup in file=./a.out [0]

Так что похоже, что он ищет правильное место для символа callme.

Вывод из nm a.out включает следующую строку

080483b4 T callme

Должен ли я компилироваться таким образом, чтобы callme был доступен извне из-за пределов a.out ?

Любая помощь будет оценена по достоинству.


person Jon Chambers    schedule 20.03.2014    source источник


Ответы (1)


Добавьте -rdynamic к флагам компиляции вашей программы. По умолчанию только разделяемые библиотеки связаны с таблицей динамических символов (таблицей, которую динамический компоновщик (например, /lib/ld-linux.so.2) использует для поиска адреса функции по ее имени).

Без таблицы динамических символов вы не можете использовать dlsym и на собственном двоичном коде.

person keltar    schedule 20.03.2014