给定动态链接的ELF二进制文件,例如/bin/less
。
在二进制文件中,调用共享库提供的函数,例如strcpy()
如何从哪个共享库/共享对象中找到strcp
函数?
换句话说,我想获得对func_name / shared_obj_name.so。
回答this post,Michael Slade写道:
ELF文件没有指定哪些符号来自哪些库;它 只需添加一个链接到ELF二进制文件的共享库列表, 并让链接器在库中找到符号。
然而,必须有一种方法来收集所需的信息(使用链接器)。在我的情况下,执行二进制文件并对其进行跟踪不是一个选项。到目前为止我尝试了什么:
我试过objdump -T /bin/less | grep strcpy
给了我:
0000000000000000 DF *UND* 0000000000000000 GLIBC_2.2.5 strcpy
0000000000000000 DF *UND* 0000000000000000 GLIBC_2.3.4 __strcpy_chk
这既不是明确的,也不会给我.so
文件的名称。
正在运行ldd /bin/less
,返回:
linux-vdso.so.1 => (0x00007ffe8b7fa000)
libtinfo.so.5 => /lib/x86_64-linux-gnu/libtinfo.so.5 (0x00007f92c23a5000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f92c1fe0000)
/lib64/ld-linux-x86-64.so.2 (0x00007f92c25ec000))
让我认为“GLIBC_2.2.5”对应libc.so.6
如何以编程方式查找相应的共享对象(.so文件)到(导入)函数?
答案 0 :(得分:3)
如何从哪个共享库/共享对象中找到strcp函数?
一般情况下,您不能:该库可以在运行时更改。例如,如果我编译以下源:
int strcpy(char *a, const char *src) { abort(); }
$ gcc -fPIC -shared -o foo.so foo.c
然后运行你的程序:
LD_PRELOAD=./foo.so /bin/less
然后获得strcpy
的库是foo.so
。使用LD_PRELOAD
这种方式称为库插入,在各种circumstances中都很有用。
除了LD_PRELOAD
之外,还有其他方法将注入不同的库。
如果您不使用任何此类机制,并且正在使用GLIBC,那么您可以要求动态加载程序为您回答该问题。这是一种方式:
LD_DEBUG=bindings ldd -r /bin/less < /dev/null |& egrep '\Wstrcpy\W'
26623: binding file /bin/bash [0] to /lib/x86_64-linux-gnu/libc.so.6 [0]: normal symbol `strcpy' [GLIBC_2.2.5]
26633: binding file /lib/x86_64-linux-gnu/libtinfo.so.5 [0] to /lib/x86_64-linux-gnu/libc.so.6 [0]: normal symbol `strcpy' [GLIBC_2.2.5]
26633: binding file /bin/less [0] to /lib/x86_64-linux-gnu/libc.so.6 [0]: normal symbol `strcpy' [GLIBC_2.2.5]
上面你可以看到ldd
调用bash
和less
作为单独的进程,并且它们都绑定到libc.so.6
这个特定的符号。
如何以编程方式查找相应的共享对象(.so文件)到(导入)函数?
如果您使用的是GLIBC,请使用dladdr“询问”动态链接器。返回的“info”参数将告诉您文件名。