测来测去18:使用LD_PRELOAD搞砸一切

LD_PRELOAD

LD_PRELOAD是一个神奇的指令,关于它的介绍可以参考这篇文章,这篇文章

有用的事

LD_PRELOAD可以做很多有用的事情,比如替换mallocfree来检测内存泄露,这里有一个实际的Github开源软件

搞点别的

LD_PRELOAD虽然很强大,但针对不是动态链接的方法就无能为力。检查一个ELF文件中哪些方法是可以被LD_PRELOAD改造的,可以用:

readelf --dyn-syms /path/to/elf/file

比如我这里写了一个很简单的:

1
2
3
4
5
6
7
8
9
10
[root@server-P1 build]# readelf --dyn-syms test

Symbol table '.dynsym' contains 6 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
1: 0000000000000000 0 FUNC GLOBAL DEFAULT UND puts@GLIBC_2.2.5 (2)
2: 0000000000000000 0 FUNC GLOBAL DEFAULT UND printf@GLIBC_2.2.5 (2)
3: 0000000000000000 0 FUNC GLOBAL DEFAULT UND __libc_start_main@GLIBC_2.2.5 (2)
4: 0000000000000000 0 NOTYPE WEAK DEFAULT UND __gmon_start__
5: 0000000000000000 0 FUNC GLOBAL DEFAULT UND fopen@GLIBC_2.2.5 (2)

这里能看到可以被LD_PRELOAD利用的方法包括puts, printf这类glibc提供的动态符号。

这里比较特殊的是这个叫__libc_start_main的方法,如果我们写了一个.so文件去替换这个符号的话…比如:

1
2
3
4
5
6
7
#include <stdlib.h>
#include <stdio.h>

void
__libc_start_main(void) {
printf("Here comes the injected function!\n");
}

gcc -shared -fPIC -o preload.so preload.c

然后

export LD_PRELOAD=$PWD/preload.so

之后就可以抓狂了~

消除的方法也很简单:

unset LD_PRELOAD

现在比较关心的是如何将静态链接的方法也用LD_PRELOAD替换。不过如果它替换不了,用ftrace加Hook应该是可以的。

© 2020 DecodeZ All Rights Reserved. 本站访客数人次 本站总访问量
Theme by hiero