Linux ELF文件:如何获取属于导入函数的共享对象
Linux ELF file: How to get the shared object belonging to an imported function
给定一个动态链接的 ELF 二进制文件,例如 /bin/less
。
在二进制文件中,调用了共享库提供的函数,例如strcpy()
如何知道strcp
函数是从哪个共享library/shared对象中获取的?
换句话说,我想得到对 func_name/shared_obj_name.so.
回答 this post,Michael Slade 写道:
ELF files don't specify which symbols come from which libraries; it
just adds a list of shared libraries to link to into the ELF binary,
and lets the linker find the symbols in the libraries.
然而必须有一种方法来收集所需的信息(使用链接器)。在我的情况下,执行二进制文件和 ltrace-ing 不是一个选项。到目前为止我尝试了什么:
我试过 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 文件)?
How can I find out from which shared library/shared object the strcp function is obtained?
一般情况下您不能:该库可以在 运行 时更改。例如,如果我编译以下源代码:
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
这个特定符号。
How can I programmatically find the corresponding shared object (.so file) to an (imported) function?
如果您使用的是 GLIBC,请使用 dladdr 到 "ask" 动态链接器。返回的 "info" 参数将告诉您文件名。
给定一个动态链接的 ELF 二进制文件,例如 /bin/less
。
在二进制文件中,调用了共享库提供的函数,例如strcpy()
如何知道strcp
函数是从哪个共享library/shared对象中获取的?
换句话说,我想得到对 func_name/shared_obj_name.so.
回答 this post,Michael Slade 写道:
ELF files don't specify which symbols come from which libraries; it just adds a list of shared libraries to link to into the ELF binary, and lets the linker find the symbols in the libraries.
然而必须有一种方法来收集所需的信息(使用链接器)。在我的情况下,执行二进制文件和 ltrace-ing 不是一个选项。到目前为止我尝试了什么:
我试过 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 文件)?
How can I find out from which shared library/shared object the strcp function is obtained?
一般情况下您不能:该库可以在 运行 时更改。例如,如果我编译以下源代码:
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
这个特定符号。
How can I programmatically find the corresponding shared object (.so file) to an (imported) function?
如果您使用的是 GLIBC,请使用 dladdr 到 "ask" 动态链接器。返回的 "info" 参数将告诉您文件名。