This is an old question, but the question itself seems based on a false assumption that dlopen()
must be used to locate objects in the system's standard libc
.
There's no need to use dlopen()
unless you are deliberately loading your functions from a specific shared object that's not the default libc
. As noted in the comments to the other answer, forcing a specific path for what should likely just be the default libc
doesn't always work. Because the default libc
is almost certainly already loaded into your process's address space, and it doesn't have to be in the same location or even have the same name.
Just use dlsym( RTLD_NEXT, "malloc" )
to find malloc()
, for example.
Per the Linux dlsym()
man page:
There are two special pseudo-handles that may be specified in handle:
RTLD_DEFAULT
Find the first occurrence of the desired symbol using the
default shared object search order. The search will
include global symbols in the executable and its
dependencies, as well as symbols in shared objects that
were dynamically loaded with the RTLD_GLOBAL flag.
RTLD_NEXT
Find the next occurrence of the desired symbol in the
search order after the current object. This allows one to
provide a wrapper around a function in another shared
object, so that, for example, the definition of a function
in a preloaded shared object (see LD_PRELOAD in ld.so(8))
can find and invoke the "real" function provided in
another shared object (or for that matter, the "next"
definition of the function in cases where there are
multiple layers of preloading).
The _GNU_SOURCE
feature test macro must be defined in order to
obtain the definitions of RTLD_DEFAULT
and RTLD_NEXT
from
<dlfcn.h>.
This is all that's necessary:
void* (*mallocptr)(size_t);
void (*freeptr)(void*);
// Locate symbols
mallocptr = dlsym(RTLD_NEXT, "malloc");
freeptr = dlsym(RTLD_NEXT, "free");
if(!mallocptr || !freeptr){
printf("%s\n", dlerror());
return 1;
}
// Allocate and use memory
char *ptr = mallocptr(4);
ptr[0] = 'H'; ptr[1] = 'i'; ptr[2] = '\n'; ptr[3] = '\0';
printf(ptr);
// Free it
freeptr(ptr);
Note that I removed the *(void**)(&mallocptr)
casts - those are not needed. If gcc
incorrectly complains about the assignment (gcc
will improperly issue warnings when assigning void *
pointers but the C standard specifies that a void *
pointer can be safely assigned to any pointer...),