
Awesome-ld-preload: List of resources related to LD_PRELOAD - gaul
https://github.com/gaul/awesome-ld-preload
======
zwp
I have another that I sometimes use: overriding getenv(3). (I typically just
printf() the variable name and return NULL).

Most of the time you can spot environment variable usage in binaries using
strings(1) (folks still like to use upper case env vars in non-system
applications even though this goes against POSIX).

But by using LD_PRELOAD you can easily see if the program is actually hitting
the codepath reads that variable without debuggers or grovelling about in the
assembly.

------
f-
Disappointed that my LD_PRELOAD exploit - still unpatched after 20 years! -
did not make the list:

[http://lcamtuf.coredump.cx/soft/ld-expl](http://lcamtuf.coredump.cx/soft/ld-
expl)

~~~
enriquto
But you are not really root, after that, you only think that you are.

~~~
f-
Does objective reality exist, my friend?

~~~
monocasa
I mean, in this case other calls will fail with EACCESS, so here, yes.

And I've done a similar thing for an integration test framework for low level
daemons, so I know very well how much of a pain it is to get close to
emulating "oh yeah, you're totally root" to processes via LD_PRELOAD.

------
nonesuchluck
Nice list of fun hacks. My personal favorite preload is [stderr in
red]([https://github.com/sickill/stderred](https://github.com/sickill/stderred)).
(Not my github, but I've used this for a long time on my macbook)

~~~
woodruffw
I linked this the last time LD_PRELOAD/stderred came up on HN, but be careful
with your shell configuration/user changes when using it:

[https://github.com/sickill/stderred/issues/63](https://github.com/sickill/stderred/issues/63)

------
dixie_land
I actually recently worked on an LD_PRELOAD wrapper to enable TLS for existing
plain sockets.

[https://github.com/zliuva/ktlswrapper](https://github.com/zliuva/ktlswrapper)

Did it for fun to get my Transmission daemon behind TLS without socat or
nginx.

------
adrianmonk
> _drop files content from page cache after closing, useful for backups_

It took me a minute to understand why this is useful for backups. It prevents
your backup tool from leaving a bunch of stuff in cache that isn't needed.
It's a performance thing. (And it's not a data integrity thing, which came to
mind because one reason for flushing a cache is to be sure writes to the
underlying layer been done.)

This leads to an interesting question: do most backup tools not already have
this optimization built in? From a quick perusal of the GNU tar manual page
and source and running it under strace, it doesn't seem like it supports it.
(Though tar is really more of an archive tool than a backup tool, which isn't
precisely the same thing.)

------
terminaljunkid
It reminds me my experiments to get a debian rootfs running on a plain Android
terminal emulator without something like termux.

I remember I used LD_PRELOAD along with fakechroot and fakeroot packages to
get most things working. Those days' android allowed running statically linked
binaries among other things.

(except DNS resolution and argv[0] was always ${some_large_path}/ld-linux-
armhf.so, as I invoked glibc dynamic loader)..

Those days I didn't have a laptop and learned some C programming and unix
stuff through termux. I sometimes think, as a CSE student, I lack the
enthusiasm I had in those 12th grade days..

------
est
the most crazy LD_PRELOAD was using 4.X kernel on a centos6 machine with LKL

[https://github.com/lkl/linux](https://github.com/lkl/linux)

There are tons of extremely OpenVZ hostings on the interweb but with an
ancient 2.6 kernel like centos5.

With LKL you can enjoy the benefits of modern kernel with minimal performance
penalty.

Submitted an issue here: [https://github.com/gaul/awesome-ld-
preload/issues/1](https://github.com/gaul/awesome-ld-preload/issues/1)

------
EvilTerran
Neat! I can see myself using several of these.

Erratum: the link meant for "openssl-hook" actually takes you to "otherport".

~~~
gaul
Fixed; thanks for the feedback.

------
huksley
As far as I know LD_PRELOAD does not allows overriding syscalls, for example
mmap. I believe also open call can not be overriden to (because it is a
syscall too), so I wonder how ld-preload-open works?

[https://stackoverflow.com/a/31439038](https://stackoverflow.com/a/31439038)

~~~
woodruffw
> As far as I know LD_PRELOAD does not allows overriding syscalls, for example
> mmap. I believe also open call can not be overriden to (because it is a
> syscall too), so I wonder how ld-preload-open works?

LD_PRELOAD does not override syscalls themselves. It can be used to override
the _wrapper_ of a syscall.

Depending on your libc implementation, kernel version, and architecture, your
`mmap` might not be implemented in terms of the `mmap` syscalls. It might be
`mmap64` or `mmap2`. Similarly for `open` -- it's currently implemented with
`openat` in glibc.

~~~
sigjuice
I don't see mmap(3) or open(3) on FreeBSD, macOS and Linux. Section 2 man
pages describe the libc wrappers themselves. See intro(2).

~~~
woodruffw
Yeah, it looks like I've misremembered. I'll remove the misleading manual
sections.

------
scottlamb
[https://github.com/libhugetlbfs/libhugetlbfs](https://github.com/libhugetlbfs/libhugetlbfs)
can use LD_PRELOAD to remap segments onto huge pages for a performance boost
(via fewer TLB misses).

------
mrob
Here's another that I've found useful:

[https://github.com/mariusae/trickle](https://github.com/mariusae/trickle)

"Trickle is a userland bandwidth shaper for Unix-like systems."

------
_nalply
LD_PRELOAD is powerful. For example run pacman4console, but hide that with a
LD_PRELOAD calling prctl() and overwriting the argv array. So even if your
boss knows ps he will not know you're playing.

------
ComputerGuru
> Copyright Google LLC?

There’s no such thing...

Edit: I stand corrected. I thought it was a C-Corp.

~~~
detaro
[https://en.wikipedia.org/wiki/Google](https://en.wikipedia.org/wiki/Google)

------
codesections
Is the existence of LD_PRELOAD a _strong_ argument in favor of static linking?

I hadn't heard of LD_PRELOAD before now, but my first reaction was "oh wow,
better static link _all the things_!". Is that wrong?

~~~
dig1
> "oh wow, better static link all the things!". Is that wrong?

Depends. Sadly, current trend is to keep everything static in big binary or
bundle own set of dependencies. Let's assume your program is using libpng.
Now, every program is keeping own libpng in RAM. That is not even the worst
case; imagine particular libpng has security issue. The only way to update all
those static programs is to recompile everything or download everything; which
is trend, again.

I image we will have shared library approach "rediscovered" and commercialized
with some cool buzzword.

~~~
nicoburns
How much RAM does libpng use? It surely can't more than a couple of megabytes
at most (much less I'd imagine, given typical binary sizes). This is rapidly
becoming a non-issue.

Regarding security issues. I imagine that we will gradually rewrite everything
in memory-safe languages such as Rust. It'll take a while - there's a lot of
value in the code that's already been written. But once a library for a given
task has been rewritten into a safe language, it's going to be hard to justify
using the equivalent C library.

Of course this won't completely eliminate security issues. But I'd guess that
along with a bit of fuzzing, it could easily reduce the frequency to <10% of
what we have today. That, along with the fact that modern languages have
package managers, and updating a library to the latest patch version is a one-
line change, will make keeping on top of security issues well within the reach
of the average app developer.

Shared libraries were a necessary tool in a world with limited computing
resources, but I suspect the current trend will continue until they're used
only in niche circumstances (plugins? libc?)

~~~
zzzcpan
_> How much RAM does libpng use?_

The assumption here is likely that read-only mapped pages of libpng could be
shared across different running programs that link with it. But it ignores all
the extra read-write pages as a consequence of dynamic linking and that there
is basically just libc that is shared across different running programs. So
it's mostly wrong, you can probably even reduce memory usage by switching to
static linking.

~~~
cycloptic
Libpng is not a good example. Often in real-world applications there are
dozens of libraries that are dynamically linked, and they can get quite large.
The other argument is that having them dynamically linked increases cache
coherency. For example if all applications share the same GUI library, the
core rendering loop of that library will be likely to get kept in the cache.
However, I have not tested this theory and it seems like the library would
have to be designed for it to get any real benefit.

