从dlopen()'ed .so

时间:2017-11-10 07:37:22

标签: reverse-engineering dlopen objdump objcopy sprof

我有一组共享库(英特尔MKL),它们只以二进制形式分发。顶级“运行时”库libmkl_rt.so链接到我的可执行文件,可通过ldd显示:

...
libmkl_rt.so => /var/task/lib/libmkl_rt.so (0x00007f8049a1f000)
...

然而,其他的,例如libmkl_avx.so,我假设是用dlopen()动态加载的,因为可执行文件会抛出一个错误,说如果找不到库会丢失,但{{{}}不可见{1}}。

这些库很大(> 100MB),这是我使用它们的容器中唯一的可执行文件。我假设可执行文件没有调用这些库中的每个函数,所以我想减少它们,先确定调用哪些函数,然后只保留它们。

我怎么能:

  1. 确定实际使用动态加载的共享库中的哪些符号?
  2. 只将这些符号提取到库的“苗条”副本中?
  3. 有没有这方面的工具?

1 个答案:

答案 0 :(得分:2)

  

确定实际使用动态加载的共享库中的哪些符号?

您可以在LD_DEBUG=bindings LD_BIND_NOW=1下运行您的程序,并查看libmkl_avx.so中绑定的符号。

  

只将那些符号提取到库的“苗条”副本中?

不幸的是,出于无法重新排列可执行文件中的函数的原因,这是不可能的。链接代码后,所有内部getos和全局变量位置都是固定的,无法更改。即使正确地反汇编链接代码(以确定函数边界和调用图)也是一个无法解决的问题(像IDA这样的工具使用启发式方法来缓解它,但问题仍然存在)。

这不应该是一个大问题,因为操作系统只会加载应用程序实际使用的代码页。