:::warning 二者区别:
- LIBRARYPATH环境变量用于在程序编译期间_查找动态链接库时指定查找共享库的路径
- LDLIBRARY_PATH环境变量用于在程序加载运行期间_查找动态链接库时指定除了系统默认路径之外的其他路径,注意,LD_LIBRARY_PATH中指定的路径会在系统默认路径之前进行查找
:::
LD_PRELOAD
Linux操作系统的动态链接库在加载过程中,动态链接器会先读取LD_PRELOAD环境变量和默认配置文件/etc/ld.so.preload,并将读取到的动态链接库文件进行预加载。即使程序不依赖这些动态链接库,LD_PRELOAD环境变量和/etc/ld.so.preload配置文件中指定的动态链接库依然会被加载,因为它们的优先级比 LD_LIBRARY_PATH 环境变量所定义的链接库查找路径的文件优先级要高,所以能够提前于用户调用的动态库载入。 简单来说LD_PRELOAD的加载是最优先级的我们可以用他来做一些有趣的操作(骚操作).:::warning 一般情况下,ld-linux.so加载动态链接库的顺序为:
LD_PRELOAD > LD_LIBRARY_PATH > /etc/ld.so.cache > /lib > /usr/lib
:::
测试阶段
- 编写 rund.c 程序
该程序的目的是: 随机生成 10 个数字
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
int i;
srand(time(NULL));
for(i=0;i<10;i++){
printf("%d\n",rand()%100);
}
return 0;
}
- 我们正常执行该程序
# gcc -o rund rund.c
# ./rund
18
48
5
32
51
80
89
23
20
26
- 现在我们创建 libmyrand.so 动态链接库
#include<stdio.h>
int rand()
{
return 55;
}
将 myrand.c 编译为 libmyrand.so 文件
# gcc -o libmyrand.so -shared -fPIC myrand.c
# ls
libmyrand.so myrand.c rund rund.c
:::warning gcc 参数介绍:
- -shared : 表明是生成共享库格式
- -fPIC : 选项作用于编译阶段,告诉编译器产生与位置无关代码(Position-Independent Code);这样一来,产生的代码中就没有绝对地址了,全部使用相对地址,所以代码可以被加载器加载到内存的任意位置,都可以正确的执行。这正是共享库所要求的,共享库被加载时,在内存的位置不是固定的。
:::
- 使用 LD_PRELOAD 替换 glibc 中的 rand
# LD_PRELOAD=$PWD/libmyrand.so ./rund
55
55
55
55
55
55
55
55
55
55
从结果中我们可以看到,rand 方法调用的是我们自己编译的 rand 方法,这就是 LD_PRELOAD 优先级,当然我们也可以一些方法将其写入环境变量,并且我们可以使用 ldd 来查看程序在运行时所依赖的动态链接库
# export LD_PRELOAD=$PWD/libmyrand.so
# ldd ./rund
linux-vdso.so.1 => (0x00007ffc0fe1e000)
/root/workdir/libmyrand.so (0x00007f719568b000)
libc.so.6 => /lib64/libc.so.6 (0x00007f71952bd000)
/lib64/ld-linux-x86-64.so.2 (0x00007f719588d000)
# export -n LD_PRELOAD=$PWD/libmyrand.so # 删除变量
LD_LIBRARY_PATH
我们在日常开发中,可能会自己编译一些库文件,然后指定程序去这些相应位置调用,这一切没什么问题,但是如果我们可以覆盖这些配置文件呢?
那么我们就可以执行和 LD_PRELOAD 相同的提权方式,劫持
函数,并执行我们提供的命令
设置
- export LD_LIBRARY_PATH=LD_LIBRARY_PATH:/XXX 但是登出后就失效
- 修改~/.bashrc或~/.bash_profile或系统级别的/etc/profile
- 在其中添加例如export PATH=/opt/ActiveP/lib:$LD_LIBRARY_PATH
- source .bashrc (Source命令也称为“点命令”,也就是一个点符号(.)
source命令通常用于重新执行刚修改的初始化文件,使之立即生效,而不必注销并重新登录)