相关的环境变量
- LD_LIBRARY_PATH ld-linux.so 寻找 shared object 的路径,优先加载出现在路径前面的 shared object。如,export LD_LIBRARY_PATH=/home/user/lib:$LD_LIBRARY_PATH
- LD_PRELOAD 指定优先供 ld-linux.so 加载的 shared object。如,export LD_PRELAOD=/home/user/lib/glibc.so,可以使用这个变量来改变加载顺序,例如我们自定义的 glibc.so 中实现了新的 strcmp 之类的函数,那么可以使用这个变量来实现函数的替换,实现注入
- LD_DEBUG 使用这个环境变量来 debug 载入 shared object 的情况。如,export LD_DEBUG=files,这样会打印所有所有加载 shared object 的记录
一些工具
- 如何查看一个程序或者 shared object 加载哪些 shared object
ldd,可以查看程序或者.so,如,
$ ldd ./foo_test
$ ldd ./libfoo.so
- 对于已经运行的程序,可以这样
$ cat /proc/PID/maps | awk '{print $6}'| grep '\.so'| sort | uniq
$ lsof -p PID | awk '{print $9}' | grep '\.so'
- 没有启动的程序可以这样
$ strace ./foo_test 2>&1 | grep '^open(".*\.so'
也可以用上面提到的环境变量来看 shared object 的加载顺序
$ export LD_DEBUG=files
$ ./foo_test
顺便介绍下 lsof
查看占用端口的进程
le@SH:~$ sudo lsof -i TCP:80
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
nginx 1309 root 7u IPv4 8740 0t0 TCP *:http (LISTEN)
nginx 1310 www-data 7u IPv4 8740 0t0 TCP *:http (LISTEN)
nginx 1311 www-data 7u IPv4 8740 0t0 TCP *:http (LISTEN)
nginx 1312 www-data 7u IPv4 8740 0t0 TCP *:http (LISTEN)
nginx 1313 www-data 7u IPv4 8740 0t0 TCP *:http (LISTEN)
具体的请man lsof
objdump 和 readelf
- objdump 查看 object 的信息
$ objdump -t libfoo.so
$ objdump -s -j .rodata -t libfoo.so
- readelf 读 elf 的信息
readelf -r libfoo.so