Как узнать, какие функции общего объекта используются программой или другой библиотекой? - PullRequest
23 голосов
/ 24 февраля 2011

Как узнать, какие функции общего объекта используются программой или другой библиотекой?В этом конкретном случае я хотел бы увидеть, какие функции в /lib/libgcc1_s.so.1 используются другой динамической библиотекой.Поскольку они динамически связаны, objdump -d не разрешает адреса вызовов функций.Есть ли способ запустить программу в отладчике или перекомпоновать статически?Спасибо,

Luca

Edit:

nm и readelf не подойдет, мне не нужно видеть, какие символы присутствуют в общем объекте, но какиефактически используется в другом объекте, который ссылается на него.

Ответы [ 5 ]

41 голосов
/ 24 февраля 2011

нм будет работать, только если библиотека не лишена своих символов.Тем не менее, nm -D может показать вам некоторую информацию:

nm -D /lib/libgcc_s.so.1

Но есть еще один инструмент, который может вам помочь: readelf

readelf - отображает информацию оELF-файлы.

А если вы проверите справочные страницы, опция -s : Displays the entries in symbol table section of the file, if it has one.

readelf -s /lib/libgcc_s.so.1

РЕДАКТИРОВАТЬ:

Ну, символы, которые не реализованы внутри объекта, который вы проверяете с помощью nm, появятся с флагом U перед ним, но nm не скажет вам, какая библиотека в вашей системереализует этот символ.

Так что то, что вы ищете, может быть достигнуто с помощью смеси ldd и nm .ldd сообщает, с какими библиотеками связано ваше приложение, а nm сообщает, какие символы не определены ( U flag) или реализованы локально ( T flag).

После перечисления всехнеопределенные символы (с nm) в целевом приложении, вы должны перебирать все библиотеки, о которых сообщает ldd, в поисках этих символов (снова используя nm).Если вы нашли символ и ему предшествует флаг T, вы его нашли.

Кстати, я просто написал этот однострочный для bash , чтобы проиллюстрировать мою идею.Он анализирует приложение с именем win и пытается найти библиотеки, которые реализуют все символы, указанные как неопределенные.

target="win"; for symbol in $(nm -D $target | grep "U " | cut -b12-); do for library in $(ldd $target | cut -d ' ' -f3- | cut -d' ' -f1); do for lib_symbol in $(nm -D $library | grep "T " | cut -b12-); do if [ $symbol == $lib_symbol ]; then echo "Found symbol: $symbol at [$library]"; fi ; done; done; done;

Или, если ваш терминал поддерживает цвета:

target="win"; for symbol in $(nm -D $target | grep "U " | cut -b12-); do for library in $(ldd $target | cut -d ' ' -f3- | cut -d' ' -f1); do for lib_symbol in $(nm -D $library | grep "T " | cut -b12-); do if [ $symbol == $lib_symbol ]; then echo -e "Found symbol: \e[1;36m$symbol\033[0m at \e[1;34m$library\033[0m"; fi ; done; done; done;

Я уверен, что кто-то найдет улучшение производительности.

Выходы:

Found symbol: XCreateColormap at [/usr/lib/libX11.so.6]
Found symbol: XCreateWindow at [/usr/lib/libX11.so.6]
Found symbol: XIfEvent at [/usr/lib/libX11.so.6]
Found symbol: XMapWindow at [/usr/lib/libX11.so.6]
Found symbol: XOpenDisplay at [/usr/lib/libX11.so.6]
Found symbol: __libc_start_main at [/lib/tls/i686/cmov/libc.so.6]
Found symbol: __stack_chk_fail at [/lib/tls/i686/cmov/libc.so.6]
Found symbol: glClear at [/usr/lib/mesa/libGL.so.1]
Found symbol: glClearColor at [/usr/lib/mesa/libGL.so.1]
Found symbol: glFlush at [/usr/lib/mesa/libGL.so.1]
Found symbol: glXChooseFBConfig at [/usr/lib/mesa/libGL.so.1]
Found symbol: glXChooseVisual at [/usr/lib/mesa/libGL.so.1]
Found symbol: glXCreateContext at [/usr/lib/mesa/libGL.so.1]
Found symbol: glXCreateNewContext at [/usr/lib/mesa/libGL.so.1]
Found symbol: glXCreateWindow at [/usr/lib/mesa/libGL.so.1]
Found symbol: glXGetVisualFromFBConfig at [/usr/lib/mesa/libGL.so.1]
Found symbol: glXMakeContextCurrent at [/usr/lib/mesa/libGL.so.1]
Found symbol: glXMakeCurrent at [/usr/lib/mesa/libGL.so.1]
Found symbol: glXQueryVersion at [/usr/lib/mesa/libGL.so.1]
4 голосов
/ 24 февраля 2011

Вы смотрели на ltrace ?Он перехватывает вызовы функций совместно используемой библиотеки во время выполнения и печатает информацию о них по мере их возникновения.

Поскольку это динамическое решение, он не будет выводить информацию для вызова библиотеки, сделанного в части вашей программы, которая никогдаисполняется.Но это может быть полезно в зависимости от ваших потребностей.

1 голос
/ 24 февраля 2011

Я не знаю ни одного, даже nm имеет ограниченное применение для того, что вы, похоже, намереваетесь. Кроме того, предварительная загрузка (компоновщика GNU) может сделать недействительными любые предположения, которые вы сделаете после использования инструмента, который якобы мог это сделать. См. Справочную страницу ld.so . LD_PRELOAD может использоваться любым пользователем для переопределения разрешения символов, как это происходит при обычных обстоятельствах.

Однако даже без отладчика вы можете использовать LD_DEBUG, чтобы увидеть, какая функция в конечном итоге используется.

0 голосов
/ 19 марта 2012

Этого можно достичь, используя метод статического анализа в Reverse Engineering

Для этого вам нужен дизассемблер. Смотри http://en.wikipedia.org/wiki/Disassembler

IDA PRO - хорошая дизассемблерная ведьма, которая ответит на ваш вопрос. Она умеет читать файлы формата ELF, но, к сожалению, она не бесплатная.

0 голосов
/ 24 февраля 2011

Может быть, инструмент nm может помочь вам, поскольку он отображает имена символов, содержащиеся в двоичном файле.
Это так же просто, как использовать ABC:

nm my_binary
...