Library pre-loading is most commonly used when you need a
custom version of a library function to be called. You might
want to implement your own malloc(3)
and
free(3)
functions that would perform a rudimentary
leak checking or memory access control for example, or you
might want to extend the I/O calls to dump data when reverse
engineering a binary blob. In this case, the library to be
preloaded would implement the functions you want to override
with prelinking. Only functions of dynamically loaded libraries
can be overridden. You're not able to override a function the
application implements by itself or links statically with.
The library to preload is defined by the environment
variable LD_PRELOAD
, such as
LD_PRELOAD=libwurst.so
. The symbols of the
preloaded library are bound first, before other linked shared
libraries. Lets look into symbol binding in more details. If
your application calls a function, then the linker looks if it
is available in the application itself first. If the symbol is
not found, the linker checks all preloaded libraries and only
then all the libraries which have been linked to your
application. The shared libraries are searched in the order
which has been given during compilation and linking. You can
find out the linking order by calling 'ldd
/path/to/my/applicaton'
. If you're interested how the
linker is searching for the symbols it needs or if you want do
debug if the symbol of your preloaded library is used
correctly, you can do that by enabling tracing in the
linker.
A simple example would be 'LD_DEBUG=symbols ls'
.
You can find more details about debugging with the linker in
the manpage:
'man ld.so'
.
Your application uses the functionopen(2)
.=> The
- Your application doesn't implement it.
LD_PRELOAD=libcwrap.so
providesopen(2)
.- The linked libc.so provides
open(2)
.open(2)
symbol fromlibcwrap.so
gets bound!
The wrappers used for creating complex testing environments of this project use preloading to supply their own variants of several system or library calls suitable for unit testing of networked software or privilege separation. For example, one wrapper includes its version of most of the standard API used to communicate over sockets that routes the communication over local sockets.