检查非默认装载机共享库(checking shared libraries for non defa

2019-07-29 02:10发布

ldd是一个好简单的方法来检查共享库给定的可执行文件或将被使用。 然而,它预期并不总是奏效。 例如,请参见下面的外壳片段演示了如何“失败”来发现libreadline“依赖”到Python二进制

我尝试过许多其他的发行版,但我从Tikanga复制

$ lsb_release -a
LSB Version:    :core-4.0-amd64:core-4.0-ia32:core-4.0-noarch:graphics-4.0-amd64:graphics-4.0-ia32:graphics-4.0-noarch:printing-4.0-amd64:printing-4.0-ia32:printing-4.0-noarch
Distributor ID: RedHatEnterpriseServer
Description:    Red Hat Enterprise Linux Server release 5.6 (Tikanga)
Release:        5.6
Codename:       Tikanga

看看ldd确实在默认安装python (来自官方仓库)。

$ which python
/usr/bin/python
$ ldd `which python`
    libpython2.4.so.1.0 => /usr/lib64/libpython2.4.so.1.0 (0x00000030e6200000)
    libpthread.so.0 => /lib64/libpthread.so.0 (0x00000030e0e00000)
    libdl.so.2 => /lib64/libdl.so.2 (0x00000030e0a00000)
    libutil.so.1 => /lib64/libutil.so.1 (0x00000030ee800000)
    libm.so.6 => /lib64/libm.so.6 (0x00000030e0600000)
    libc.so.6 => /lib64/libc.so.6 (0x00000030e0200000)
    /lib64/ld-linux-x86-64.so.2 (0x00000030dfe00000)
$ ldd `which python` | grep readline
$

没有发现有关的ReadLine。 现在我从这个二进制文件确实有realine功能交互式用法知道,所以let't尝试看到它的来源。

$ python &
[1] 21003
$ Python 2.4.3 (#1, Dec 10 2010, 17:24:35) 
[GCC 4.1.2 20080704 (Red Hat 4.1.2-50)] on linux2
Type "help", "copyright", "credits" or "license" for more information.

[1]+  Stopped                 python

在后台启动一个交互式的Python会话(PID 21003)

$ lsof -p 21003
COMMAND   PID    USER   FD   TYPE DEVICE     SIZE    NODE NAME
python  21003 ddvento  cwd    DIR   0,33    16384  164304 /glade/home/ddvento/loader-test
python  21003 ddvento  rtd    DIR    8,3     4096       2 /
python  21003 ddvento  txt    REG    8,3     8304 6813419 /usr/bin/python
python  21003 ddvento  mem    REG    8,3   143600 8699326 /lib64/ld-2.5.so
python  21003 ddvento  mem    REG    8,3  1722304 8699327 /lib64/libc-2.5.so
python  21003 ddvento  mem    REG    8,3   615136 8699490 /lib64/libm-2.5.so
python  21003 ddvento  mem    REG    8,3    23360 8699458 /lib64/libdl-2.5.so
python  21003 ddvento  mem    REG    8,3   145824 8699445 /lib64/libpthread-2.5.so
python  21003 ddvento  mem    REG    8,3   247544 6821551 /usr/lib64/libreadline.so.5.1
python  21003 ddvento  mem    REG    8,3    15840 8699446 /lib64/libtermcap.so.2.0.8
python  21003 ddvento  mem    REG    8,3  1244792 6833317 /usr/lib64/libpython2.4.so.1.0
python  21003 ddvento  mem    REG    8,3    18152 8699626 /lib64/libutil-2.5.so
python  21003 ddvento  mem    REG    8,3 56446448 6832889 /usr/lib/locale/locale-archive
python  21003 ddvento  mem    REG    8,3    21808 6965997 /usr/lib64/python2.4/lib-dynload/readline.so
python  21003 ddvento  mem    REG    8,3    25464 6901074 /usr/lib64/gconv/gconv-modules.cache
python  21003 ddvento    0u   CHR  136,1                3 /dev/pts/1
python  21003 ddvento    1u   CHR  136,1                3 /dev/pts/1
python  21003 ddvento    2u   CHR  136,1                3 /dev/pts/1
$ lsof -p 21003 | grep readline
python  21003 ddvento  mem    REG    8,3   247544 6821551 /usr/lib64/libreadline.so.5.1
python  21003 ddvento  mem    REG    8,3    21808 6965997 /usr/lib64/python2.4/lib-dynload/readline.so

答对了! 这是readline的!

但是,这种技术只有当库加载有效的,因此,例如它没有找到/usr/lib64/libtcl8.4.so直到蟒蛇过程中不运行像from Tkinter import *

所以,我有两个问题:

  1. 我相信这个问题ldd是它假设的标准装载机的使用,而很可能Python是利用自身的特殊加载(这样你就不必每次都重新链接可执行文件安装新的Python模块,是不是纯Python但有一些C / C ++ / FORTRAN代码)。 它是否正确?

  2. 显然,如果一个可执行文件正在使用自己的装载机,没有明显的答案的问题:“如何找到这一切可执行文件可以加载可能库”:这取决于装载机做什么。 但是,有没有办法找出哪些库可以被蟒蛇被加载?

PS:关于1.如果您降落在这个问题上,你应该已经知道以下,但如果你不应该:看看如何简单就是要彻底搞砸ldd输出(搞乱它只有部分是有点困难):

$ cat hello.c 
#include <stdio.h>

int main() {
  printf("Hello world.\n");
  return 0;
}

$ gcc -static hello.c -o loader
$ gcc -Wl,--dynamic-linker,./loader hello.c -o hello
$ ./hello 
Hello world.
$ ldd ./hello
Hello world.

Answer 1:

Python和Perl和其他解释性语言做负载动态的事情使用dlopen() (这是不一样的东西作为代替标准装载机;它们仍在使用,事实上dlopen()是一个钩入在基于ELF-系统的标准装载器。)

没有为动态加载模块是标准的注册表。 Python使用其自己的规则来确定,其中扩展模块可从被加载(看sys.path ),包括那些具有相关联的共享对象。 Perl使用不同的规则。 Apache使用仍然是不同的规则,等等。

因此,要的答案概括您的问题:

  1. 不完全是

  2. 没有



Answer 2:

作为一个方面说明,一个可行的办法来完成我的问题2。将想要的东西:

  • 创建一个空的chroot环境

  • 重新编译有蟒蛇,手动添加任何缺失,一个接一个

根据您的目标,这可能是也可能不是一个很好的解决方案(实际上原来是什么我的目标都差不太多 - 很奇怪,因为它可以从问题的声音)



文章来源: checking shared libraries for non default loaders