我需要以编程方式检查给定可执行文件的库依赖关系。是否有比运行ldd
(或objdump
)命令并解析其输出更好的方法?是否有可用的API提供与ldd
相同的结果?
我需要以编程方式检查给定可执行文件的库依赖关系。
我将假设您使用的是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
条目)。
If您真正的问题是“此ELF二进制文件还需要其他哪些库”,那么这很容易获得:只需在动态符号表中查找DT_NEEDED
条目。以编程方式执行此操作非常容易:
.e_phoff
告诉您从哪里开始)。PT_DYNAMIC
.p_type
的那个。Elf{32,64}_Dyn
记录。.d_tag == DT_NEEDED
查找它们。Voila。
P.S。有点复杂:字符串,例如libc.so.6
不属于PT_DYNAMIC
。但是有一个指向它们在.d_tag == DT_STRTAB
条目中的位置的指针。有关示例代码,请参见this answer。