开发者

Using dlopen to get handle of libc memory allocation functions

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 开发者_StackOverflowa code snippet of the above 4 steps.


Here's a code snippet, HTH

#include <dlfcn.h>
#include <stdio.h>
int main()
{  
   void *handle; 

   // dlopen will search the path for you
   // /usr/lib/libc.so is a linker script, not an elf file
   // so it won't work with dlopen. 
   handle = dlopen("libc.so.6", 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;
}


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

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜