1

Can someone help me to know how can i use dlopen to get handle of libc memory allocation functions? Especially, something like searching the libc path and then taking the handle. What modes should be used to invoke dlsym?

Idea is:

  1. Search libc path
  2. Invoke dlopen on it
  3. Use dlsym to access the memory functions (malloc, calloc etc) and
  4. use the functions

Please help me with a code snippet of the above 4 steps.

Wenfang Du
  • 8,804
  • 9
  • 59
  • 90
RajSanpui
  • 11,556
  • 32
  • 79
  • 146

2 Answers2

5

Here's a code snippet, HTH

#include <dlfcn.h>
#include <stdio.h>

// For LIBC_SO which expands to proper libc name
#include <gnu/lib-names.h>

int main()
{  
   void *handle; 
   
   // dlopen will search the path for you
   // LIBC_SO expands to shared library name
   // for libc
   handle = dlopen(LIBC_SO, RTLD_LAZY); 

   if(handle){
         void* (*mallocptr)(size_t);
         void (*freeptr)(void*);

         // Locate symbols
         *(void**)(&mallocptr) = dlsym(handle, "malloc");
         *(void**)(&freeptr) = dlsym(handle, "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);
   }
   else{
      printf("%s\n", dlerror());
      return 1;
   }
   return 0;
}
Blanket Fox
  • 377
  • 4
  • 15
  • -bash-3.2# ./a.out dlopen failed – RajSanpui Jul 27 '11 at 09:15
  • Note that I'm using libc.so.6 in my code - if you're using a different version of libc, you have to change it. Have a look in your /lib folder, is there a file named libc.so.? –  Jul 27 '11 at 09:18
  • I have libc.so.6, and i have exported it...don't know why still dlopen is failing. – RajSanpui Jul 27 '11 at 09:21
  • I mean it is exported in LD_LIBRARY_PATH – RajSanpui Jul 27 '11 at 09:22
  • Weird, did you modify the code I posted? Is the message "dlopen failed" produced by dlerror? –  Jul 27 '11 at 09:22
  • No, the code is "as is" compiled. Just added header for stdlib. In native it is compiling fine, but in my target it is failing. Target is ARM. It has libc.so.6 in /devel/usr/lib, which i exported in LD_LIBRARY_PATH. – RajSanpui Jul 27 '11 at 09:24
  • is libc.so.6 in /devel/usr/lib on your machine or on the target device? try running your executable like this: env LD_LIBRARY_PATH=/path/to/folder/containing/libc ./a.out –  Jul 27 '11 at 09:31
  • I tried the same...anyways your code is fine. I will try it out, may be some issues with our distro installation in target. Thank you. – RajSanpui Jul 27 '11 at 09:32
  • This answer helped someone 10 years later as well. Thanks! – uerceg Apr 14 '21 at 11:27
  • 1
    [RTM](https://man7.org/linux/man-pages/man3/dlsym.3.html). There is no need to call `dlopen()` and pass the resulting handle to `dlsym()`. `dlsym( RTLD_NEXT, "malloc" );` will find the "next occurrence" of `malloc()` "in the search order". – Andrew Henle Jul 15 '21 at 12:16
2

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...),

Andrew Henle
  • 32,625
  • 3
  • 24
  • 56
  • Can this be used to find local symbols in shared objects? Or will it only find global ones? – SRobertJames Nov 25 '21 at 06:37
  • @SRobertJames Maybe - it depends on how the shared object was built and linked, and if the shared object [has been stripped](https://pubs.opengroup.org/onlinepubs/9699919799/utilities/strip.html). On Linux, you might see a significant difference in the output from `nm -D libXXX.so` and `nm -a libXXX.so`. See https://stackoverflow.com/questions/435352/limiting-visibility-of-symbols-when-linking-shared-libraries – Andrew Henle Nov 25 '21 at 13:33