能否生成静态链接含未定义符号、依赖LD_PRELOAD运行的ELF可执行文件?
实现方法:生成带合法PLT重定位的欠链接ELF文件
完全可以实现你的需求——生成一个保留未定义符号、同时包含合法PLT重定位的ELF可执行文件,通过LD_PRELOAD加载对应库即可正常运行。以下是具体操作步骤:
1. 编译目标文件
先将主程序源码编译为目标文件,保留符号信息:
gcc -c -fPIC binary.c -o binary.o
-fPIC确保生成位置无关代码,让PLT结构的生成更规范(对可执行文件非强制,但能避免潜在问题)。
2. 用ld生成欠链接的动态可执行文件
默认ld遇到未定义符号会直接报错终止链接,我们需要通过参数允许未定义符号,并指定动态链接器以触发PLT生成:
ld -z nodefs --dynamic-linker /lib64/ld-linux-x86-64.so.2 binary.o -o binary
-z nodefs:允许可执行文件保留未定义符号,跳过链接时的符号解析检查--dynamic-linker:指定系统动态链接器路径,确保生成的是动态可执行文件,这样ld才会为未定义符号生成PLT和R_X86_64_JUMP_SLOT类型的合法重定位项
3. 编译共享库
将实现符号的源码编译为共享库:
gcc -shared -fPIC liblib.c -o liblib.so
4. 测试运行
- 直接运行会因找不到符号报错:
./binary # 输出:error while loading shared libraries: ./binary: undefined symbol: f
- 通过
LD_PRELOAD加载库后正常执行:
LD_PRELOAD=./liblib.so ./binary # 输出:OK
验证重定位类型
用readelf查看可执行文件的重定位项,能看到f()对应的是合法的PLT重定位:
readelf -r binary | grep f # 输出示例:0000000000201018 0000000000000007 R_X86_64_JUMP_SLOT 0000000000000000 f + 0
关键注意点
- 不能直接用
gcc链接主程序,因为gcc默认会添加-z defs参数,强制链接时解析所有符号 - 必须指定动态链接器,否则
ld会生成静态可执行文件,无法生成PLT结构
内容的提问来源于stack exchange,提问作者Alek
相关产品推荐
相关产品推荐

