API 对于 ldd(或 objdump)?

API for ldd (or objdump)?

我需要以编程方式检查给定可执行文件的库依赖项。有没有比 运行 ldd(或 objdump)命令和解析它们的输出更好的方法?是否有可用的 API 给出与 ldd 相同的结果?

I need to programmatically inspect the library dependencies of a given executable.

我假设您使用的是 ELF 系统(可能 Linux)。

executable 或共享库的动态库依赖项在库或 execuPT_DYNAMIC 段的 Elf{32_,64}_Dyn 条目上编码为 table =62=]。 ldd(间接地,但这是一个实现细节)解释这些条目,然后使用系统配置的各种细节and/or LD_LIBRARY_PATH环境变量来定位所需的库。

可以用readelf -d a.out打印PT_DYNAMIC的内容。例如:

$ 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.6NEEDED 条目)。

如果您真正的问题是"what other libraries does this ELF binary require",那么这很容易获得:只需在动态符号 [=62] 中查找 DT_NEEDED 条目=].以编程方式执行此操作相当简单:

  1. 找到程序头的table(ELF文件头.e_phoff告诉你它从哪里开始)。
  2. 遍历它们以找到具有 PT_DYNAMIC .p_type 的那个。
  3. 该段包含一组固定大小的 Elf{32,64}_Dyn 记录。
  4. 遍历它们,寻找 .d_tag == DT_NEEDED.

瞧。

P.S。有一点复杂:字符串,例如 libc.so.6 不是 PT_DYNAMIC 的一部分。但是有一个指针指向它们在 .d_tag == DT_STRTAB 条目中的位置。请参阅 this answer 示例代码。