Timo Geusch Timo Geusch - 2 years ago 189
Linux Question

How to check if a linux shared library has been preloaded using LD_PRELOAD

I'm familiar with using

to check if a shared library has been loaded into a process using a prior call to
without triggering a load if it isn't present, like so:

void* lib = dlopen(lib_name, RTLD_NOLOAD);
if (lib != NULL) {

I've recently tried to apply the same pattern to determine if one of a handful of shared libraries have been loaded into a process space using LD_PRELOAD. However in all the cases, the above mentioned call to

So basically, if I start the process using this command line

LD_PRELOAD=libawesome.so ./mycoolprocess

and then run the following check in the code in mycoolprocess.c

void* has_awesome = dlopen("libawesome.so", RTLD_NOLOAD);
if (has_awesome != NULL) {
printf("libawesome is available\n");

the call to
always returns
no matter if the shared library has been loaded using LD_PRELOAD or not. Based on Andrew Henle's comment below I also tried calling
with the absolute path to one of the reloaded shared objects, but
in this case still returns NULL despite the shared object being preloaded.

So my question is twofold:

  1. Should the above pattern work for a library that's been loaded using LD_PRELOAD?

  2. Is there another way to have a process determine if a specific shared library has been preloaded?

Answer Source

No and yes, respectively.

dlopen() and the LD_PRELOAD trick, although they both deal with shared libraries, operate in fundamentally different ways.

The LD_PRELOAD environment variable is handled by the dynamic linker/loader (ld-linux.so), and affects the resolution of relocation records in the executable binary itself. In a nutshell, at every point in your code where there's a call to a function that's defined in a dynamic library, the linker (at build time) will insert a placeholder for the memory address to jump to. At runtime, those placeholders are replaced by real addresses based on the shared libraries loaded into memory, which are themselves named in the executable, but may be overridden if LD_PRELOAD is used.

So once the executable is loaded into memory and all those placeholders have been filled in with real addresses, there's no simple (or portable) way of telling what came from where. However...

You could examine the running process' memory map. On Linux, this would mean parsing through /proc/<pid>/maps. The file contents are fairly self-explanatory, so just pick one at random and take a look.

No idea how you'd do it on other systems, but I believe most modern unixen have a /proc filesystem of some sort.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download