Ubuntu 20.04 64位系统用32位自定义libc报错的原因与解决办法
解决Ubuntu 20.04 64位下LD_PRELOAD加载32位libc的"wrong ELF class"错误
这个问题我之前帮朋友排查过,本质是Ubuntu 20.04和18.04的动态链接器对跨架构库预加载的处理逻辑不一样,咱们一步步拆解:
报错原因
首先得搞懂这个错误信息:ERROR: ld.so: object './libc.so.6' from LD_PRELOAD cannot be preloaded (wrong ELF class: ELFCLASS32): ignored
- 你全局设置了
LD_PRELOAD指向32位的libc,但当你执行ls这类命令时,调用的是系统默认的64位二进制程序,它需要匹配64位的libc库。动态链接器检查到预加载的库是32位(ELFCLASS32),和当前程序的64位(ELFCLASS64)不兼容,所以直接拒绝加载并抛出错误。 - 为什么Ubuntu 18.04没这个问题?其实18.04的动态链接器也不会把32位libc加载给64位程序,只是旧版本的ld.so不会把这个不匹配的情况打印成错误信息,只会静默忽略,所以你没看到报错而已——本质上两种系统里64位程序都没用到你预加载的32位libc。
解决办法
根据你的CTF场景,我给你三个实用方案:
1. 临时预加载,只针对32位程序
不要全局export LD_PRELOAD,而是在执行目标32位二进制时临时指定环境变量,这样只有目标程序会加载你的32位libc,执行其他64位命令时不会触发错误:
LD_PRELOAD='./libc.so.6' ./your_32bit_ctf_binary
这是CTF里最常用的方式,既能精准控制预加载的范围,又不会干扰系统其他命令。
2. 写个脚本自动区分程序架构
如果需要频繁切换,你可以写个小脚本自动判断目标程序是32位还是64位,决定是否加载32位libc:
#!/bin/bash # 检查目标程序是否为32位ELF if file "$1" | grep -q "ELF 32-bit"; then LD_PRELOAD='./libc.so.6' "$@" else # 64位程序直接执行,不加载32位libc "$@" fi
把脚本存为run_ctf.sh,给它加执行权限:
chmod +x run_ctf.sh
之后用它执行程序:
# 运行32位CTF程序,自动加载自定义libc ./run_ctf.sh ./your_32bit_binary # 执行ls这类64位命令,不会报错 ./run_ctf.sh ls
3. 安装32位版的系统命令(如果需要测试)
如果你确实需要用32位的ls等命令测试预加载效果,可以安装32位的coreutils包:
sudo apt install lib32stdc++6 coreutils:i386
之后执行32位的ls时,预加载32位libc就不会报错了:
LD_PRELOAD='./libc.so.6' /usr/bin/ls.i386
内容的提问来源于stack exchange,提问作者Saurabh
相关产品推荐
相关产品推荐

