API для ldd (или objdump)? - PullRequest
       93

API для ldd (или objdump)?

0 голосов
/ 18 марта 2020

Мне нужно программно проверить библиотечные зависимости данного исполняемого файла. Есть ли лучший способ, чем запускать команды ldd (или objdump) и анализировать их вывод? Есть ли API, который дает те же результаты, что и ldd?

1 Ответ

1 голос
/ 23 марта 2020

Мне нужно программно проверить библиотечные зависимости данного исполняемого файла.

Я собираюсь предположить, что вы используете систему ELF (вероятно, Linux).

Динамические c библиотечные зависимости исполняемого файла или общей библиотеки кодируются в виде таблицы на 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 записей в таблице символов Dynami c. Выполнить это программно довольно просто:

  1. Найдите таблицу заголовков программ (заголовок файла ELF .e_phoff сообщает вам, где он начинается).
  2. Переберите их, чтобы найти тот с PT_DYNAMIC .p_type.
  3. Этот сегмент содержит набор Elf{32,64}_Dyn записей фиксированного размера.
  4. Итерируйте их, ища те с .d_tag == DT_NEEDED.

Вуаля.

PS Есть небольшая сложность: строки, такие как libc.so.6, не являются частью PT_DYNAMIC. Но есть указатель на то, где они находятся в записи .d_tag == DT_STRTAB. См. этот ответ , например, код.

...