如何在C+;中找到ELF二进制文件所需的动态库+;? 如何获取C++中的ELF二进制文件所需的所有动态库的列表?p>
一旦我成功地从二进制文件中提取了信息(文件名?),我就可以通过搜索如何在C+;中找到ELF二进制文件所需的动态库+;? 如何获取C++中的ELF二进制文件所需的所有动态库的列表?p>,c++,linux,binary,elf,decompiling,C++,Linux,Binary,Elf,Decompiling,一旦我成功地从二进制文件中提取了信息(文件名?),我就可以通过搜索路径找到实际的文件,但是我无法找到任何关于从ELF二进制文件中提取未混合信息的信息 想法?您可以调用“readelf-d”程序并解析输出: readelf -d /usr/bin/readelf | grep NEEDED 0x0000000000000001 (NEEDED) Shared library: [libz.so.1] 0x0000000000000001 (NEEDED)
路径
找到实际的文件,但是我无法找到任何关于从ELF二进制文件中提取未混合信息的信息
想法?您可以调用“readelf-d”程序并解析输出:
readelf -d /usr/bin/readelf | grep NEEDED
0x0000000000000001 (NEEDED) Shared library: [libz.so.1]
0x0000000000000001 (NEEDED) Shared library: [libc.so.6]
所需共享对象的列表存储在所谓的可执行文件列表中。获取必要信息的粗略算法如下:
ET_EXEC
或ET_DYN
)e_phoff/e_phnum/e_phentsize
),检查它们是否为非零且有效PT\u动态
one。还要记住PT\u加载
段的虚拟地址->文件偏移量映射DT_
和DT_STRTAB
条目DT_NEEDED
条目的d_val
字段是DT_STRTAB
字符串表的偏移量,它将是所需库的SONAME。请注意,由于DT_STRTAB
条目是运行时地址,而不是字符串表的偏移量,因此需要使用步骤3中存储的信息将其映射回文件偏移量。您可以使用此操作。请注意,libelf
有一个C API
从他们的教程中,看一看第4.2节(或)中关于如何获取程序头表的示例。找到dtu DYNAMIC
部分,并从字符串表中读取依赖项,如第5.4节(或)中的示例
--编辑--
实际上我有机会写代码。以下是我所做的:
#include <assert.h>
#include <fcntl.h>
#include <gelf.h>
#include <stdio.h>
#include <unistd.h>
void print_dt_needed(const char *elf_path) {
assert(elf_version(EV_CURRENT) != EV_NONE);
int fd = open(elf_path, O_RDWR, 0);
assert(fd >= 0);
Elf *elf = elf_begin(fd, ELF_C_READ, NULL);
assert(elf != NULL);
assert(elf_kind(elf) == ELF_K_ELF);
Elf_Scn *scn = NULL;
while ((scn = elf_nextscn(elf, scn)) != NULL) {
GElf_Shdr shdr = {};
assert(gelf_getshdr(scn, &shdr) == &shdr);
if (shdr.sh_type == SHT_DYNAMIC) {
Elf_Data *data = NULL;
data = elf_getdata(scn, data);
assert(data != NULL);
size_t sh_entsize = gelf_fsize(elf, ELF_T_DYN, 1, EV_CURRENT);
for (size_t i = 0; i < shdr.sh_size / sh_entsize; i++) {
GElf_Dyn dyn = {};
assert(gelf_getdyn(data, i, &dyn) == &dyn);
if (dyn.d_tag == DT_NEEDED) {
printf("DT_NEEDED detected: %s\n",
elf_strptr(elf, shdr.sh_link, dyn.d_un.d_val));
}
}
}
}
assert(elf_end(elf) == 0);
assert(close(fd) == 0);
}
int main(int argc, char const *argv[]) {
print_dt_needed(argv[1]);
return 0;
}
#包括
#包括
#包括
#包括
#包括
需要无效打印(常量字符*elf路径){
断言(elf_版本(EV_当前)!=EV_无);
int fd=打开(elf_路径,O_RDWR,0);
断言(fd>=0);
Elf*Elf=Elf_begin(fd,Elf_C_READ,NULL);
断言(elf!=NULL);
断言(elf_kind(elf)=elf_K_elf);
Elf_Scn*Scn=NULL;
while((scn=elf_nextscn(elf,scn))!=NULL){
GElf_Shdr Shdr={};
断言(gelf_getshdr(scn和shdr)=&shdr);
如果(shdr.sh_类型==SHT_动态){
Elf_数据*数据=NULL;
数据=elf_getdata(scn,数据);
断言(数据!=NULL);
大小\u t sh\u entsize=gelf\u fsize(elf,elf\u t\u DYN,1,EV\u电流);
对于(size\u t i=0;i
如果您使用的是基于RHEL的发行版(rpm是软件包管理的基础),那么您可以尝试解决二进制文件对*.so文件以及提供这些文件的软件包的依赖关系。为什么要问这个问题?您是否关心间接依赖关系(即可执行文件foo
动态链接libbar.so
,它本身是动态链接libgee.so
,因此ldd foo
将说明libbar.so
和libgee.so
)?我这样问是因为我使用的是静态分析工具,我需要从目标二进制文件以及它所依赖的任何动态库中提取CFG。直接使用readelf-d
,间接使用ldd
:可能重复谢谢,我认为这是一个相当常见的问题,从二进制文件访问信息,该二进制文件是。是否有任何库、开源项目或类似项目可以提供此功能而无需我自己实现和维护?大多数人在程序中不需要它,因此他们依赖于readelf
、objdump
或ldd
来编写脚本。对于编程访问,这里有libelf
,但它没有为这个特定任务提供现成的API—您仍然需要手动解析动态部分。