Подтвердить что ты не робот

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

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

Лука

Edit:

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

4b9b3361

Ответ 1

nm будет работать только в том случае, если библиотека не была лишена его символов. Однако 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

EDIT:

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

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

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

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

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]

Ответ 2

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

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

Ответ 3

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

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

Ответ 4

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

nm my_binary

Ответ 5

Это может быть достигнуто с помощью техники, называемой статическим анализом в Reverse Engineering

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

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