I'm familiar with using dlopen()
to check if a shared library has been loaded into a process using a prior call to dlopen()
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 dlopen()
returns NULL
.
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 dlopen()
always returns NULL
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 dlopen
with the absolute path to one of the reloaded shared objects, but dlopen
in this case still returns NULL despite the shared object being preloaded.
So my question is twofold:
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With