ChatGPT解决这个技术问题 Extra ChatGPT

What is the LD_PRELOAD trick?

I came across a reference to it recently on proggit and (as of now) it is not explained.

I suspect this might be it, but I don't know for sure.

Not really an answer so I won't post it as one but... Stephen Kell is using LD_PRELOAD for his liballocs library in this video and if you watch the previous bits you may get a better understanding of how/why. liballocs appears to be being used so other dynamic languages can talk to each other. This talk has some deep internals explained in it. youtu.be/LwicN2u6Dro?t=24m10s

u
user

If you set LD_PRELOAD to the path of a shared object, that file will be loaded before any other library (including the C runtime, libc.so). So to run ls with your special malloc() implementation, do this:

$ LD_PRELOAD=/path/to/my/malloc.so /bin/ls

I had no idea this existed... it seems like it would be a major vector for security attacks. Any idea how it is secured?
It is secured by the fact the loader will ignore LD_PRELOAD if ruid != euid -- Joshua
@Joshua: what are ruid and euid?
@heinrich5991 Real and effective user ids: lst.de/~okir/blackhats/node23.html
One important thing to keep in mind: you usually want to specify an absolute path to LD_PRELOAD. The reason is that it being an environment variable, it's inherited by child processes - which may have a different working directory than the parent process. So any relative path would fail to locate the library to preload.
K
Kalle Richter

You can override symbols in the stock libraries by creating a library with the same symbols and specifying the library in LD_PRELOAD.

Some people use it to specify libraries in nonstandard locations, but LD_LIBRARY_PATH is better for that purpose.


"Some people use it to specify libraries in nonstandard locations"... Really? Sounds like "Some people use it wrong"!
LD_PRELOAD can by virtue of load order intercept application-specified hardcoded paths.
Would it be a misuse to preload a different version of a library - assuming they are compatible?
I've seen it used to load a debug or instrumented variant, or to load a library that does something completely radically different from the base library as though to emulate some other system.
In the case where libraries aren't compiled correctly (used to run into this with mysql all the time where it had a loose coupling to a generic libmysql_client which overwrote an older version's symlink - depending on which version of perl you used you had to specify / force it with LD_PRELOAD.. useful trick. If I remember correctly, valgrind uses this technique to provide debugging ability to binaries without needing to recompile.. it's quite useful.
Y
Yun

As many people mentioned, using LD_PRELOAD to preload library. By the way, you can CHECK if the setting is available by ldd command.

Example: Suppose you need to preload your own 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)

Thus, set your preload environment:

export LD_PRELOAD=/home/patric/libselinux.so.1

Check your library again:

>ldd /bin/ls
    ...
    libselinux.so.1 =>
    /home/patric/libselinux.so.1 (0x00007fb9245d8000)
    ...

Y
Yu Hao

With LD_PRELOAD you can give libraries precedence.

For example you can write a library which implement malloc and free. And by loading these with LD_PRELOAD your malloc and free will be executed rather than the standard ones.


but what if the program uses calloc? wouldn't that mess up everything?
@JanusTroelsen if the library you write doesn't implement a certain part, that part would be loaded from the original library.
@JanusTroelsen, In other words, LD_PRELOAD allows you to specify which implementation of a specific symbol gets used. If the preloaded library does not export a symbol, it will be found elsehwere.
@JanusTroelsen: It turns out that malloc and free are specifically designed in glibc to allow this and the stock calloc manages to call your imported malloc. Don't try this with any other functions. It won't work so good.
K
Kalle Richter

LD_PRELOAD lists shared libraries with functions that override the standard set, just as /etc/ld.so.preload does. These are implemented by the loader /lib/ld-linux.so. If you want to override just a few selected functions, you can do this by creating an overriding object file and setting LD_PRELOAD; the functions in this object file will override just those functions leaving others as they were.

For more information on shared libraries visit http://tldp.org/HOWTO/Program-Library-HOWTO/shared-libraries.html


J
JulienGenoud

To export mylib.so to env:

$ export LD_PRELOAD=/path/mylib.so
$ ./mybin

To disable it:

$ unset LD_PRELOAD

or unset LD_PRELOAD
unset and export VAR= aren't exactly the same thing. unset is the way to go.
a
asn

Here is a detailed blog post about preloading:

https://blog.cryptomilk.org/2014/07/21/what-is-preloading/


Thanks for posting your answer! Please note that you should post the essential parts of the answer here, on this site, or your post risks being deleted See the FAQ where it mentions answers that are 'barely more than a link'. You may still include the link if you wish, but only as a 'reference'. The answer should stand on its own without needing the link.
d
dnahc araknayirp

Using LD_PRELOAD path, you can force the application loader to load provided shared object, over the default provided.

Developers uses this to debug their applications by providing different versions of the shared objects.

We've used it to hack certain applications, by overriding existing functions using prepared shared objects.


Y
Yun

When LD_PRELOAD is used, that file will be loaded before any other. Use $export LD_PRELOAD=/path/lib for lib to be pre-loaded. This can even be used in programs too.