Linux/Unix 工具 ldd 介绍
ldd(1) 用于列出程序运行时需要依赖的动态链接库。
SYNOPSIS
ldd [option]... binfile...
OPTIONS
--version
Print the version number of ldd.
-v, --verbose
Print all information, including, for example, symbol
versioning information.
-u, --unused
Print unused direct dependencies. (Since glibc 2.3.4.)
-d, --data-relocs
Perform relocations and report any missing objects (ELF only).
-r, --function-relocs
Perform relocations for both data objects and functions, and
report any missing objects or functions (ELF only).
--help Usage information.
源码分析
此命令为一个 shell
脚本。可以使用 which
命令查找到脚本所在位置。使用 vim
打开 ldd
脚本。
vim `which ldd`
脚本中最主要的函数为 try_trace()
。
try_trace() (
output=$(eval $add_env '"$@"' 2>&1; rc=$?; printf 'x'; exit $rc)
rc=$?
printf '%s' "${output%x}"
return $rc
)
其中 $add_env
的关键值为 LD_TRACE_LOADED_OBJECTS=1
。该环境变量非空时,进入“依赖查询模式”,任何可执行程序在运行时本身并不真正执行,而只显示依赖。所以 ldd
相当于以下命令(不带其他参数时),
export add_env="LD_TRACE_LOADED_OBJECTS=1";
$add_env /path/binfile
需要注意的是,当 LD_TRACE_LOADED_OBJECTS
变为空的时候才会结束,即执行 export LD_TRACE_LOADED_OBJECTS=0
或 export LD_TRACE_LOADED_OBJECTS=
并不会将其置空。应该使用
unset LD_TRACE_LOADED_OBJECTS
取消该环境变量。
LD_TRACE_LOADED_OBJECTS
是由 ld.so(8)(elf动态库装载器)实现的。ld.so(8)
在发行版中一般为 ld-linux.so(2)
。ldd
源码中使用数组 $RTLDLIST
索引 ld-linux.so(2)
:
RTLDLIST="/lib/ld-linux.so.2 /lib64/ld-linux-x86-64.so.2 /libx32/ld-linux-x32.so.2"
RTLD=
ret=1
for rtld in ${RTLDLIST}; do
if test -x $rtld; then
dummy=`$rtld 2>&1`
if test $? = 127; then
verify_out=`${rtld} --verify "$file"`
ret=$?
case $ret in
[02]) RTLD=${rtld}; break;;
esac
fi
fi
done
即当系统存在 /lib/ld-linux.so.2
时,调用其作为依赖加载库,若没有则依次索引 /lib64/ld-linux-x86-64.so.2
和 /libx32/ld-linux-x32.so.2
。一般的 64 位 SELinux 中都有 /lib64/ld-linux-x86-64.so.2
,所以使用如下命令也可以达到相同的效果:
export RTLD=/lib64/ld-linux-x86-64.so.2
$RTLD --list /path/binfile
这也可以解释为什么 /lib64/ld-linux-x86-64.so.2
几乎出现在所有依赖动态库程序的依赖中。(没有装载器,无法装载动态库)
最后再来看一下 ldd
脚本中实现的其它功能。(环境变量非空时使能,即 LD_WARN=yes
或 LD_WARN=1
都可)
option | addtional $add_env |
description |
---|---|---|
-v, --verbose |
LD_VERBOSE=yes |
打印所有附加信息 |
-u, --unused |
LD_DEBUG="$LD_DEBUG${LD_DEBUG:+,}unused" |
打印编译需要但未使用的库 |
-d, --data-relocs |
LD_WARN=yes |
打印丢失的库 |
-r, --function-relocs |
LD_WARN=yes LD_BIND_NOW=yes |
打印丢失的库和函数 |
总结
ldd
脚本相当于以下命令,
LD_TRACE_LOADED_OBJECTS=1 /path/binfile
或者使用 ld-linux.so(2)
,
/lib64/ld-linux-x86-64.so.2 --list /path/binfile
补充
据官方文档,为了保证安全性,可以使用如下命令检查未知安全性的代码,
objdump -p /path/binfile | grep NEEDED
Shommunny
there is a family history of testicular torsion comparaison levitra viagra