解决 bin 文件在低版本 glibc 运行问题


一、问题描述

问题:GLIBC 的兼容性问题
环境:Ubuntu20.04 gcc-9 / Ubuntu16.04 gcc-5
错误信息描述:某三方合作公司提供的稀疏化库 sparse.bin 是在 Ubuntu20 中编译的,在低版本服务器中运行出现/lib/x86_64-linux-gnu/libm.so.6: version GLIBC_2.29' not found。

二、解决方案

1. 主要思路:

解决此类问题主要途径有:1. 升级glibc;2. docker 容器;3.通过修改文件的elf强制依赖加载低版本;4.打包原有环境依赖并修改elf依赖。

2. 方案与分析:

方案1 升级 glibc

升级风险较大,而且涉及服务器较多,在docker中尝试了一下升级失败,导致系统命令无法使用;

方案2 docker 容器

同样由于涉及服务器较多,每台 服务器都需要部署docker并迁移数据,工作量仍然比较大;

方案3 修改文件强制降低版本

检查一下程序使用的GLIBC:

objdump -T sparse.bin |grep GLIB
	0000000000000000      DF *UND*	0000000000000000  GLIBC_2.2.5 localtime
	0000000000000000      DF *UND*	0000000000000000  GLIBC_2.2.5 atof
	0000000000000000      DF *UND*	0000000000000000  GLIBC_2.4   __stack_chk_fail
	0000000000000000      DF *UND*	0000000000000000  GLIBC_2.2.5 printf
	0000000000000000      DF *UND*	0000000000000000  GLIBC_2.2.5 __libc_start_main
	0000000000000000      DF *UND*	0000000000000000  GLIBC_2.2.5 time
	0000000000000000      DF *UND*	0000000000000000  GLIBC_2.2.5 atoi
	0000000000000000      DF *UND*	0000000000000000  GLIBC_2.29  exp
	0000000000000000  w   DF *UND*	0000000000000000  GLIBC_2.2.5 __cxa_finalize

可以看到使用了 exp 计算指令,而目标系统中使用的 glibc 环境最高版本为:

strings /lib/x86_64-linux-gnu/libc.so.6 | grep GLIBC
	......
	GLIBC_2.22
	GLIBC_2.23
	GLIBC_PRIVATE
	GNU C Library (Ubuntu GLIBC 2.23-0ubuntu11.3) stable release version 2.23, by Roland McGrath et al.

我们可以通过修改EFL符号表来修改依赖,强制将GLIBC_2.29修改为GLIBC_2.23,但是强制修改为低版本依赖,可能发生未知计算错误。

方案4 打包库并修改依赖路径

最终采用了这一方案,我们需要将原环境下依赖打包并修改依赖路径。

三、方案实施

打包代码 tar_lib.sh:

	#!/bin/bash
	DST_DIR=$PWD"/lib"
	BIN_FILE=$1
	libs=($(ldd $BIN_FILE | grep -o "/.*" | awk '{print $1}'))
	mkdir $DST_DIR
	for lib in ${libs[@]}
	do
	    cp "$lib" $DST_DIR
	done

可以看到ldd 依赖的库均被打包:

	├── ld-linux-x86-64.so.2
	├── libc.so.6
	└── libm.so.6

将 bin 文件和 libs 拷贝到相应服务器,这时候,需要修改 bin 文件中对库的依赖为 libs 目录,主要方法是用 PatchELF修改依赖,该工具由 NixOS 团队开发,可以直接增加、删除、替换 ELF 文件依赖的库文件。需要修改的主要有2 项:

  1. 修改可执行程序的动态库搜索路径rpath为当前libs

    patchelf --set-rpath `pwd`/libs sparse.bin
    
  2. 修改动态库加载器ELF interpreter

    patchelf --set-interpreter `pwd`/libs/ld-linux-x86-64.so.2 sparse.bin
    

四、参考

https://blog.csdn.net/itas109/article/details/106751869
https://zohead.com/archives/mod-elf-glibc/
https://www.cnblogs.com/oloroso/p/12877210.html

  • 0
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值