先用file命令确认类型:含“dynamically linked”才可用ldd;若为statically linked、relocatable文件或内核模块,则ldd不适用,应改用readelf -d binary | grep needed安全分析。

直接用 ldd 查可执行文件或 .so 文件的静态声明依赖,但必须先确认它是动态链接的;否则会报 not a dynamic executable,这不是命令错了,是目标本身没走动态链接路径。
怎么判断一个文件能不能用 ldd?
别急着跑 ldd,先用 file 看类型:
- 输出含
dynamically linked→ 可以安全用ldd - 输出是
statically linked→ldd无意义,改用readelf -d binary | grep NEEDED,如果空输出就真没动态依赖 - 输出是
relocatable(比如.o文件)或core或.ko(内核模块)→ldd完全不适用,得靠readelf -d或专用工具
ldd 显示 “not found” 但程序能跑,怎么回事?
因为 ldd 不读运行时环境:它忽略 LD_LIBRARY_PATH、不查二进制里硬编码的 RUNPATH、也不加载 /etc/ld.so.conf.d/ 缓存。真实加载由 ld-linux.so 按完整规则走。
- 查是否设了
LD_LIBRARY_PATH:echo $LD_LIBRARY_PATH - 看二进制自带路径:
readelf -d /path/to/binary | grep -E "(RUNPATH|RPATH)" - 确认缓存已更新:
sudo ldconfig -v | grep yourlib,没输出就说明系统还不知道这个库 - 容器或 chroot 下,
ldd更容易“看不见”你手动加的路径
不想执行程序,又想看它声明了哪些库?
对不可信二进制,绝对别用 ldd —— 它在旧版 glibc 中会真实加载初始化代码,可能触发恶意 payload。
- 用
readelf -d binary | grep NEEDED,只读 ELF 结构,零风险 - 等效命令:
objdump -p binary | grep NEEDED - 两者都只输出库名(如
libc.so.6),不给路径;要定位实际文件,得配合ldconfig -p | grep libc.so.6或手动搜/lib64/、/usr/lib/x86_64-linux-gnu/ - 注意:musl 编译、PIE 或静态链接的程序,这两条命令也完全不输出
NEEDED条目——不是漏了,是压根没动态依赖
查正在运行的进程实际加载了哪些库?
ldd 查的是磁盘上写死的依赖,pldd 才是看内存里真正在用的:
- 必须
sudo pldd <pid></pid>,因为要读/proc/<pid>/mem</pid> - 能看到
dlopen动态加载的库(比如libcuda.so.1)、LD_PRELOAD注入的库、甚至被覆盖的同名库路径 - 如果
pldd报Operation not permitted,通常是进程处于T(stopped)状态或被 ptrace 保护 - 替代方案(无需 root):
awk '/\.so/{print $6}' /proc/<pid>/maps | sort -u</pid>,但不如pldd可靠,可能漏掉未映射到内存的库
真正难的从来不是“找得到库”,而是“找到的刚好是想要的那个版本”——ldd 不校验符号,pldd 不告诉你符号冲突,这些得靠 nm -D 或 readelf -s 往下挖。











