*nix 工具 ldd 介绍
-
ldd
ldd = List Dynamic Dependencies
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
命令查找到脚本所在位置。使用如下指令可以打开ldd
脚本。vim `which ldd`
脚本中最主要的函数为
try_trace()
。try_trace() ( output=
add_env '" $@"' 2>&1; rc=$?; printf 'x'; exit ? 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
是由 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 2>&1` if test {rtld} --verify " $file"` ret=$? case {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:+,}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
-
如果使用
export LD_TRACE_LOADED_OBJECTS=1
,则会进入“依赖查询模式”,所有可执行文件都会变为执行对应的ldd
。需要注意的是,当
LD_TRACE_LOADED_OBJECTS
变为空的时候才会结束,即执行export LD_TRACE_LOADED_OBJECTS=0
或export LD_TRACE_LOADED_OBJECTS=
并不会将其置空。应该使用unset LD_TRACE_LOADED_OBJECTS
-
根据官方文档,为了保证安全性,可以使用如下命令检查未知安全性的代码,
objdump -p /path/binfile | grep NEEDED