Answers:
如果设置LD_PRELOAD
为共享库的路径,则该文件将在任何其他库(包括C运行时libc.so
)之前加载。因此,要运行ls
您的特殊malloc()
实现,请执行以下操作:
$ LD_PRELOAD=/path/to/my/malloc.so /bin/ls
LD_PRELOAD
。原因是它是一个环境变量,由子进程继承-子进程的工作目录可能不同于父进程。因此,任何相对路径都将无法找到要预加载的库。
通过创建具有相同符号的库并在中指定库,可以覆盖库存库中的符号LD_PRELOAD
。
有人用它在非标准位置指定库,但是这样LD_LIBRARY_PATH
做更好。
有了LD_PRELOAD
您就可以赋予图书馆优先权。
例如,您可以编写一个实现malloc
和的库free
。并且通过将这些加载到LD_PRELOAD
您的中malloc
,free
将执行它们而不是标准的。
calloc
怎么办?那会不会把一切搞砸了?
malloc
free是在glibc中专门设计的,以允许这样做,并且库存calloc
设法调用了import malloc
。不要将其与其他任何功能一起尝试。它不会那么好用。
正如很多人提到的,LD_PRELOAD
用于预加载库。顺便说一句,您可以通过命令检查设置是否可用ldd
。
示例:假设您需要预载自己的libselinux.so.1
。
> ldd /bin/ls
...
libselinux.so.1 => /lib/x86_64-linux-gnu/libselinux.so.1 (0x00007f3927b1d000)
libacl.so.1 => /lib/x86_64-linux-gnu/libacl.so.1 (0x00007f3927914000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f392754f000)
libpcre.so.3 => /lib/x86_64-linux-gnu/libpcre.so.3 (0x00007f3927311000)
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f392710c000)
/lib64/ld-linux-x86-64.so.2 (0x00007f3927d65000)
libattr.so.1 => /lib/x86_64-linux-gnu/libattr.so.1 (0x00007f3926f07000)
因此,设置您的预加载环境:
export LD_PRELOAD=/home/patric/libselinux.so.1
再次检查您的图书馆:
>ldd /bin/ls
...
libselinux.so.1 =>
/home/patric/libselinux.so.1 (0x00007fb9245d8000)
...
LD_PRELOAD
列出共享库,其功能会覆盖标准集,就像这样/etc/ld.so.preload
做一样。这些由加载程序实现/lib/ld-linux.so
。如果您只想覆盖几个选定的函数,则可以通过创建一个覆盖对象文件并设置LD_PRELOAD
;来实现。该对象文件中的函数将仅覆盖那些保留其他函数的函数。
有关共享库的更多信息,请访问 http://tldp.org/HOWTO/Program-Library-HOWTO/shared-libraries.html
这是有关预加载的详细博客文章:
当使用LD_PRELOAD时,该文件将在任何其他$export LD_PRELOAD=/path/lib
lib被预加载之前
被加载,即使它也可以在程序中使用
使用LD_PRELOAD
路径,您可以强制应用程序加载器加载提供的共享对象,而不是提供的默认对象。
开发人员使用它通过提供不同版本的共享库来调试其应用程序。
通过使用准备好的共享对象覆盖现有功能,我们已使用它来入侵某些应用程序。