相关的环境变量

  • 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