2015-04-29 3 views
2

Учитывая динамически связанный двоичный файл ELF, скажем, например, /bin/less.Linux ELF-файл: как получить общий объект, принадлежащий импортированной функции

Внутри двоичном, есть вызов функции, представленной в общей библиотеке, например strcpy()

Как я могу узнать, из которых разделяемой библиотеки/разделяемый объект получается функция strcp? Другими словами, я хочу получить пары func_name/shared_obj_name.so.

Ответ this post, Майкл Слэйд пишет:

ELF-файлы не указать, какие символы приходят из которых библиотек; он просто добавляет список разделяемых библиотек для связывания в двоичный файл ELF, и позволяет компоновщику находить символы в библиотеках.

Однако должен быть способ собрать необходимую информацию (используя компоновщик). Выполнение двоичного и ltrace-ing это не вариант в моем случае. То, что я пытался до сих пор:

Я попытался objdump -T /bin/less | grep strcpy, который дает мне:

0000000000000000  DF *UND* 0000000000000000 GLIBC_2.2.5 strcpy 
0000000000000000  DF *UND* 0000000000000000 GLIBC_2.3.4 __strcpy_chk 

Это не является ни unambigious и не дает мне имя .so файла.

Запуск ldd /bin/less, возвращаясь:

linux-vdso.so.1 => (0x00007ffe8b7fa000) 
libtinfo.so.5 => /lib/x86_64-linux-gnu/libtinfo.so.5 (0x00007f92c23a5000) 
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f92c1fe0000) 
/lib64/ld-linux-x86-64.so.2 (0x00007f92c25ec000)) 

позволяет мне думать, что "GLIBC_2.2.5" соответствует libc.so.6

Как программно найти соответствующий общий объект (.so файл) до (импорт) функция?

ответ

2

Как узнать, из какой общей библиотеки/общего объекта была получена функция strcp?

В целом вы не можете: эта библиотека может измениться во время выполнения. Например, если я скомпилировать следующий источник:

int strcpy(char *a, const char *src) { abort(); } 

$ gcc -fPIC -shared -o foo.so foo.c 

, а затем запустить программу следующим образом:

LD_PRELOAD=./foo.so /bin/less 

тогда библиотека, из которой получают strcpy является foo.so. Используя LD_PRELOAD, этот способ называется интерполяцией библиотеки и полезен во всех видах circumstances.

Есть другие способы: ввести другую библиотеку в процесс, кроме LD_PRELOAD.

Если вы используете не с использованием любых таких механизмов и используете GLIBC, вы можете попросить динамический загрузчик ответить на этот вопрос.Вот один из способов:

LD_DEBUG=bindings ldd -r /bin/less < /dev/null |& egrep '\Wstrcpy\W' 
    26623: binding file /bin/bash [0] to /lib/x86_64-linux-gnu/libc.so.6 [0]: normal symbol `strcpy' [GLIBC_2.2.5] 
    26633: binding file /lib/x86_64-linux-gnu/libtinfo.so.5 [0] to /lib/x86_64-linux-gnu/libc.so.6 [0]: normal symbol `strcpy' [GLIBC_2.2.5] 
    26633: binding file /bin/less [0] to /lib/x86_64-linux-gnu/libc.so.6 [0]: normal symbol `strcpy' [GLIBC_2.2.5] 

Выше вы можете видеть, что ldd вызывает bash и less как отдельные процессы, и оба они связываются с libc.so.6 для этого конкретного символа.

Смежные вопросы