Мне нужно программно проверить зависимости библиотеки данного исполняемого файла. Есть ли лучший способ, чем запускать команды ldd
(или objdump
) и анализировать их вывод? Есть ли API, дающий те же результаты, что и ldd
?
API для ldd (или objdump)?
Ответы (1)
Мне нужно программно проверить зависимости библиотеки данного исполняемого файла.
Я предполагаю, что вы используете систему ELF (возможно, Linux).
Зависимости динамических библиотек исполняемого файла или разделяемой библиотеки кодируются в виде таблицы на Elf{32_,64}_Dyn
записях в PT_DYNAMIC
сегменте библиотеки или исполняемого файла. ldd
(косвенно, но это деталь реализации) интерпретирует эти записи, а затем использует различные детали конфигурации системы и / или LD_LIBRARY_PATH
переменную среды для поиска необходимых библиотек.
Вы можете распечатать содержимое PT_DYNAMIC
с помощью readelf -d a.out
. Например:
$ readelf -d /bin/date
Dynamic section at offset 0x19df8 contains 26 entries:
Tag Type Name/Value
0x0000000000000001 (NEEDED) Shared library: [libc.so.6]
0x000000000000000c (INIT) 0x3000
0x000000000000000d (FINI) 0x12780
0x0000000000000019 (INIT_ARRAY) 0x1a250
0x000000000000001b (INIT_ARRAYSZ) 8 (bytes)
0x000000000000001a (FINI_ARRAY) 0x1a258
0x000000000000001c (FINI_ARRAYSZ) 8 (bytes)
0x000000006ffffef5 (GNU_HASH) 0x308
0x0000000000000005 (STRTAB) 0xb38
0x0000000000000006 (SYMTAB) 0x358
0x000000000000000a (STRSZ) 946 (bytes)
0x000000000000000b (SYMENT) 24 (bytes)
0x0000000000000015 (DEBUG) 0x0
0x0000000000000003 (PLTGOT) 0x1b000
0x0000000000000002 (PLTRELSZ) 1656 (bytes)
0x0000000000000014 (PLTREL) RELA
0x0000000000000017 (JMPREL) 0x2118
0x0000000000000007 (RELA) 0x1008
0x0000000000000008 (RELASZ) 4368 (bytes)
0x0000000000000009 (RELAENT) 24 (bytes)
0x000000006ffffffb (FLAGS_1) Flags: PIE
0x000000006ffffffe (VERNEED) 0xf98
0x000000006fffffff (VERNEEDNUM) 1
0x000000006ffffff0 (VERSYM) 0xeea
0x000000006ffffff9 (RELACOUNT) 170
0x0000000000000000 (NULL) 0x0
Это говорит о том, что единственная библиотека, необходимая для этого двоичного файла, - это libc.so.6
(запись NEEDED
).
Если ваш реальный вопрос заключается в том, «какие еще библиотеки требуются для этого двоичного файла ELF», то это довольно легко получить: просто найдите DT_NEEDED
записей в динамической таблице символов. Сделать это программно довольно просто:
- Найдите таблицу заголовков программ (заголовок файла ELF
.e_phoff
сообщает вам, где он начинается). - Просмотрите их, чтобы найти тот, у которого есть
PT_DYNAMIC
.p_type
. - Этот сегмент содержит набор
Elf{32,64}_Dyn
записей фиксированного размера. - Перебирайте их, ищите те, у которых есть
.d_tag == DT_NEEDED
.
Вуаля.
P.S. Есть небольшая сложность: строки, такие как libc.so.6
, не являются частью PT_DYNAMIC
. Но есть указатель на то, где они находятся в записи .d_tag == DT_STRTAB
. См. Пример кода в этом ответе.
readelf
, верно? Я делаю это в Haskell и нашел hackage.haskell .org / package / elf-0.30 / docs / Data-Elf.html, который выполняет работу по синтаксическому анализу двоичного файла ELF.
- person Saurabh Nanda; 29.03.2020
elfSegmentType==PT_DYNAMIC
, но что дальше? Похоже, что данные для всех эльфийских сегментов представлены непрозрачным ByteString
. Правильно ли я заключил, что библиотека не анализирует данные каждого сегмента (в зависимости от типа сегмента)?
- person Saurabh Nanda; 29.03.2020
PT_DYNAMIC
? Кроме того, как вы упомянули в своем ответе, этот раздел не будет содержать буквальных строк, а будет содержать ссылки на строки. Это похоже на hackage.haskell.org/ package / elf-0.30 / docs / уже разбирает все такие строки?
- person Saurabh Nanda; 29.03.2020
PT_DYNAMIC
: это набор записей ElfXX_Dyn фиксированного размера. Строки - это просто буквальные строки ASCII, упакованные одна за другой в один из PT_LOAD
сегментов. Вам нужно будет найти этот сегмент нагрузки, сначала декодировав PT_DYNAMIC
.
- person Employed Russian; 29.03.2020