LINUX 动态库的版本控制

Linux库文件名的描述版本信息

library filename = lib + <libaray name> + .so + <libarary version information>

库版本信息通常使用以下格式:

dynamic libarary version information = <M>.<m>.<p>

其中,M用一位或多位数字表示库文件的主版本号,m用一位或多位数字表示库文件的次版本号,而p用一位或多位数字来表示库文件的修订版本号。

库的soname与库的文件名

库的文件名定义:

library filename = lib + <libaray name> + .so + <libarary version information>

库的soname定义:

library soname = lib + <libaray name> +.so + <(only the)library major version digit(s)>

很显然只要有了soname,我们就基本上可以定位某个特定的库文件名了,唯一的问题在于soname只有动态库的主版本号,并不包含完整的版本控制信息。

升级动态库时使用软链接和soname

下面列出升级动态库的过程:

1:当软链接和实际的动态库放置在一个目录下时,将软链接指向实际的动态库文件。

2:软链接的文件名与指向的动态库soname相同,这样一来,软链接实际包含的库文件名会具有松散的版本控制信息。(也就是只包含主版本信息。

3:一般来说,客户二进制文件从来不会链接文件名包含完整版本信息的动态库,相反,你会看到客户二进制文件的构建过程只会有目的性地和文件名包含库soname的文件进行链接

4:采取这种方法的原因很简单:链接时指定完整且精确的动态库版本控制信息将使我们日后无法链接同一个库的新版本,从而引发太对不必要的限制。

但在实际链接的过程中:只将库文件名传递给连接器,而不提供版本控制信息

比如:

gcc -shared <inputs> -lm -ldl -lpthread -lxmlz -lzyz -o <clientBinary>

链接过程如图所示:

soname详解

soname嵌入了二进制文件中,ELF格式预留了一块存储动态库soname信息的字段,在链接阶段,链接器将这个特殊的soname字符串写入ELF格式指定的区域中。

在构建动态库时,你可以使用一条特定的链接器选项来指定库文件的soname

gcc -shared <list of linker inputs> -wl, -soname,<soname> -o <library filename>

链接器会将指定的sonme嵌入二进制文件的DT_SONAME字段中。


gcc -fPIC -c test.c -o test.o
gcc -shared test.o -wl.-soname,libtest.so.1 -o libtest.so.1.0.0

readelf -d libtest.so.1.0.0

###################################################################
tag         type         Name/Value
0x00000001 (NEEDED)  shared  library:[libc.so.6]
0x0000000e (SONAME)  Librara soname :[libtest.so.1]
###################################################################

链接器版本控制脚本

来看下基于动态库libsimple.so 的简单示例,该动态库提供了3个函数如下

simple.c


int first_function(int x)
{
   return (x+1);
}
int second_function(int x)
{
   return (x+2);
}
int third_function(int x)
{
  return (x+3);
}

simpleVersionScript


LIBSIMPLE_1.0{
   global:
       first_function;second_function;
   local:
       *
};

最后构建动态库文件,我们可以通过以下链接器选线将版本控制器脚本文件传递给链接器使用:


gcc -fPIC -c simple.c
gcc -shared simple.o -wl,--version-script,simpleVersionScript -o libsimple.1.0.0

若后面增次版本号:只需要对前面的做细微的改动,如下图,在新的此版本号中增加了fourth_function,只需要在.c和.h增加定义声明后,在版本控制脚本加如下内容:

simpleVersionScript:


LIBSIMPLE_1.0{
   global:
       first_function;second_function;
   local:
       *
};

LIBSIMPLE_1.1{
   global:
       fourth_function;
   local:
       *
};

此时版本控制信息中不仅包含了原来的1.0版本还包含了最新的1.1版本,如图:


readelf -v libsimple.so

#####################################################################
version definition section ‘.gnu.version_d’ contains 3 enteries
0000: rec:1   Flags:BASE  Index:1   Cnt:1    Name:libsimple.so.1.1
001c: rev:1   Flags:none  Index:2   Cnt:1    Name:LIBSIMPLE_1.0
001c: rev:1   Flags:none  Index:3   Cnt:1    Name:LIBSIMPLE_1.1
#####################################################################

若后面增改了主版本函数,如first_function

对应的代码修改如下:

simpleVersionScript:


LIBSIMPLE_1.0{
   global:
       first_function;second_function;
   local:
       *
};

LIBSIMPLE_1.1{
   global:
       fourth_function;
   local:
       *
};
LIBSIMPLE_2.0{
   global:
       first_function;
   local:
       *
};

simple.c 修改内容如下:


...
__asm__(".symver first_function_1_0,first_function@LIBSIMPLE_1.0");
int first_function(int x)
{
   printf("lib:%s\n",__FUNCTION__);
   return (x+1);
}

__asm__(".symver first_function_1_0,first_function@LIBSIMPLE_2.0");
int first_function(int x)
{
   printf("lib:%s\n",__FUNCTION__);
   return 1000*(x+1);
}
...

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
动态链接库劫持(Dynamic Link Library Hijacking),也称为DLL劫持,是一种恶意攻击技术,利用系统在加载可执行文件时搜索和加载动态链接库的方式进行攻击。攻击者通过在系统中放置恶意的动态链接库文件,并将其命名为被目标程序所依赖的动态链接库文件名,从而使目标程序在加载动态链接库时加载到了恶意代码。 当目标程序启动时,系统会按照一定的搜索顺序查找和加载所需的动态链接库。攻击者利用这个搜索顺序的漏洞,将恶意的动态链接库文件放置在搜索路径上,并命名为被目标程序所依赖的动态链接库文件名,使得目标程序加载到了恶意代码。 通过DLL劫持攻击,攻击者可以执行恶意代码,获取目标系统的敏感信息,甚至完全控制目标系统。为了防止DLL劫持攻击,开发者需要注意使用绝对路径或者强制使用指定版本的动态链接库来加载,以避免加载到恶意的动态链接库文件。 在Linux系统中,可以采取以下几种方式来防止DLL劫持攻击: 1. 使用绝对路径加载动态链接库:在程序中指定动态链接库的绝对路径,确保只加载指定路径下的动态链接库。 2. 使用rpath或rpath-link选项:在编译链接时,可以使用rpath或rpath-link选项指定动态链接库的搜索路径,避免使用默认搜索路径。 3. 使用LD_LIBRARY_PATH环境变量:通过设置LD_LIBRARY_PATH环境变量,指定动态链接库的搜索路径,使得程序只加载指定路径下的动态链接库。 4. 使用静态链接库:将动态链接库编译为静态链接库,以避免加载动态链接库时的搜索过程。 请注意,以上方法只是一些常见的防御措施,但并不能完全防止DLL劫持攻击。开发者在编写代码时应该考虑到安全性,并采取适当的防御措施来减少风险。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

水火汪

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值