patchelf
2026/5/29工具工具ELFlibcpatchelf大约 3 分钟
patchelf
是什么
patchelf 是修改 ELF 动态链接信息的工具。
Pwn 题中常用于让本地程序使用题目给的 libc.so.6 和 ld-linux,从而复现远程环境。
常见用途:
- 修改解释器 interpreter
- 修改 RPATH / RUNPATH
- 替换动态依赖
- 查看 ELF 动态链接信息
安装与配置
Ubuntu/Kali:
sudo apt update
sudo apt install patchelfmacOS:
brew install patchelf验证:
patchelf --version基本用法
查看解释器
patchelf --print-interpreter ./vuln修改解释器
patchelf --set-interpreter ./ld-linux-x86-64.so.2 ./vuln查看 RPATH
patchelf --print-rpath ./vuln设置 RPATH
patchelf --set-rpath . ./vuln替换依赖库
patchelf --replace-needed libc.so.6 ./libc.so.6 ./vuln更多用法
查看所有动态依赖
patchelf --print-needed ./vuln输出程序依赖的所有共享库。
添加依赖库
patchelf --add-needed libcustom.so ./vuln移除依赖库
patchelf --remove-needed libcustom.so ./vuln设置 RUNPATH(区别于 RPATH)
patchelf --set-rpath . ./vuln
patchelf --force-rpath ./vuln--force-rpath 使用 DT_RPATH 而不是 DT_RUNPATH,优先级更高。
修改 SONAME
patchelf --set-soname libcustom.so ./libcustom.so清除 RPATH
patchelf --shrink-rpath ./vuln移除不必要的 RPATH 条目。
查看 ELF 头信息
readelf -d ./vuln | grep NEEDED
readelf -d ./vuln | grep RPATH
readelf -l ./vuln | grep interpreterCTF常用技巧
使用题目给的 libc
常见目录:
vuln
libc.so.6
ld-linux-x86-64.so.2修补:
cp vuln vuln_patched
patchelf --set-interpreter ./ld-linux-x86-64.so.2 ./vuln_patched
patchelf --set-rpath . ./vuln_patched
./vuln_patched检查:
ldd ./vuln_patched如果 ldd 显示使用当前目录的 libc,说明环境更接近远程。
不想改原文件
永远先复制:
cp vuln vuln_patched不要直接改题目原始附件,避免后续分析混乱。
和 pwntools 配合
from pwn import *
elf = ELF("./vuln_patched")
libc = ELF("./libc.so.6")
p = process(elf.path)自动化 patch 脚本
#!/bin/bash
# patch.sh - 自动 patch ELF 使用题目 libc
VULN=$1
LIBC=$2
LD=$3
if [ -z "$VULN" ] || [ -z "$LIBC" ]; then
echo "Usage: $0 <vuln> <libc> [ld]"
exit 1
fi
cp "$VULN" "${VULN}_patched"
patchelf --set-rpath . "${VULN}_patched"
patchelf --replace-needed libc.so.6 "$LIBC" "${VULN}_patched"
if [ -n "$LD" ]; then
cp "$LD" ./ld-linux-x86-64.so.2
patchelf --set-interpreter ./ld-linux-x86-64.so.2 "${VULN}_patched"
fi
echo "[*] Patched: ${VULN}_patched"
ldd "${VULN}_patched"libc 替换完整流程
1. 获取题目附件: vuln, libc.so.6, ld-linux-x86-64.so.2
2. 备份原文件: cp vuln vuln.bak
3. 复制并修补: cp vuln vuln_patched
4. 修改解释器: patchelf --set-interpreter ./ld-linux-x86-64.so.2 ./vuln_patched
5. 设置 RPATH: patchelf --set-rpath . ./vuln_patched
6. 替换 libc: patchelf --replace-needed libc.so.6 ./libc.so.6 ./vuln_patched
7. 验证: ldd ./vuln_patched
8. 测试: ./vuln_patched32 位程序处理
# 32 位程序需要 32 位的 ld-linux
patchelf --set-interpreter ./ld-linux.so.2 ./vuln_patched
# 确认架构
file ./vuln
file ./ld-linux.so.2静态链接程序
静态链接程序不需要 patchelf,因为它们不依赖外部库:
file ./vuln
# 显示 "statically linked" 则不需要 patchelf常见问题
patched 后程序不能运行
检查 ld-linux 架构是否匹配,文件是否可执行,RPATH 是否指向正确目录。
ldd 看到的 libc 还是系统 libc
说明 RPATH 没生效,或二进制没有按预期使用当前目录的 loader。重新检查 interpreter 和 rpath。
Docker 里还需要 patchelf 吗
如果 Docker 环境已经和远程一致,可以不用。patchelf 适合快速让本机复现题目 libc。
权限问题
chmod +x ./vuln_patched
chmod +x ./ld-linux-x86-64.so.2GLIBC 版本不兼容
错误: GLIBC_2.xx not found
原因: 系统 glibc 版本低于题目 libc 版本
解决: 使用题目提供的 ld-linux 或 Docker 环境解释器路径问题
1. 使用相对路径: ./ld-linux-x86-64.so.2
2. 或使用绝对路径: /path/to/ld-linux-x86-64.so.2
3. 确保文件存在且可执行关联
- ELF、PLT、GOT与libc
- ROP基础
- GDB+pwndbg
- checksec
- pwntools