以下是 patchelf 工具(功能同chrpath)的详细用法说明,基于其核心功能及常见应用场景:
一、核心功能与命令
功能 | 命令示例 | 说明 | 引用来源 |
---|---|---|---|
修改 RPATH | patchelf --set-rpath "/new/lib/path" program | 替换目标文件(可执行文件或共享库)的 RPATH 路径,指定运行时动态库的搜索路径 | |
修改 RUNPATH | patchelf --set-runpath "/another/lib/path" program | 设置 RUNPATH,功能类似 RPATH,但优先级不同(允许 LD_LIBRARY_PATH 覆盖) | |
设置解释器 | patchelf --set-interpreter "/lib/ld-linux-x86-64.so.2" program | 指定程序使用的动态链接器(interpreter),常用于跨平台或调试场景 | |
添加/移除依赖库 | patchelf --add-needed libnew.so program patchelf --remove-needed libold.so program | 动态增删程序依赖的共享库列表 | |
查看路径信息 | patchelf --print-rpath program patchelf --print-interpreter program | 查看当前 RPATH 或解释器路径 | |
清除 RPATH | patchelf --remove-rpath program | 删除现有的 RPATH 配置 |
类似的工具:chrpath。
二、典型应用场景
1. 修复动态库路径问题
当程序运行时无法找到依赖的共享库时,通过修改 RPATH 指定正确的库路径:
patchelf --set-rpath "$ORIGIN/../lib" myapp # 使用 $ORIGIN 表示程序所在目录的相对路径
2. 跨环境调试(如 Glibc 版本管理)
在安全研究(如 pwn)中,强制程序使用指定版本的 Glibc:
patchelf --set-interpreter ./glibc/ld-2.27.so \ --set-rpath ./glibc ./target_program # 指定自定义动态链接器和库路径
3. 精简或替换依赖库
移除不必要的依赖或替换为兼容库:
patchelf --replace-needed libold.so.1 libnew.so.2 program # 替换依赖库
三、高级操作
1. 同时设置多个路径
patchelf --set-rpath "/lib:/usr/lib:/custom/lib" program # 用冒号分隔多个路径
2. 保留默认库路径
patchelf --add-rpath "/custom/lib" program # 在现有 RPATH 基础上追加路径(需版本支持)
3. 修改共享库的 SONAME
patchelf --set-soname libmylib.so.1 libmylib.so # 调整共享库的标识名称
四、注意事项
- 权限要求:修改系统级程序需
root
权限,建议优先处理用户级程序。 - 路径验证:确保设置的路径存在且可访问,否则程序将无法运行。
- 备份文件:修改前建议备份原始文件,避免不可逆错误。
五、调试与验证
- 检查修改结果:
readelf -d program | grep PATH # 查看 RPATH/RUNPATH ldd program # 验证动态库加载路径
- 错误排查:
若程序启动失败,可通过strace ./program
跟踪动态链接器报错。
通过上述操作,patchelf 可灵活管理 ELF 文件的动态链接行为,适用于环境隔离、依赖修复及安全研究等场景。