包裝malloc的一些方法

    Create a wrapper function for malloc and free in C(hack overflow)

  1. GLIBC-specific solution (mostly Linux). If your compilation environment is glibc with gcc, the preferred way is to use malloc hooks. Not only it lets you specify custom malloc and free, but will also identify the caller by the return address on the stack.

  2. POSIX-specific solution. Define malloc and free as wrappers to the original allocation routines in your executable, which will "override" the version from libc. Inside the wrapper you can call into the original malloc implementation, which you can look up using dlsym withRTLD_NEXT handle. Your application or library that defines wrapper functions needs to link with -ldl.

    #define _GNU_SOURCE
    #include <dlfcn.h>
    #include <stdio.h>
    
    void* malloc(size_t sz)
    {
        void *(*libc_malloc)(size_t) = dlsym(RTLD_NEXT, "malloc");
        printf("malloc\n");
        return libc_malloc(sz);
    }
    
    void free(void *p)
    {
        void (*libc_free)(void*) = dlsym(RTLD_NEXT, "free");
        printf("free\n");
        libc_free(p);
    }
    
    int main()
    {
        free(malloc(10));
        return 0;
    }
  3. Linux specific. You can override functions from dynamic libraries non-invasively by specifying them in the LD_PRELOAD environment variable.

    LD_PRELOAD=mymalloc.so ./exe
  4. Mac OSX specific.

    Same as Linux, except you will be using DYLD_INSERT_LIBRARIES environment variable.


LINUX下基於LIBC提供的hook機制實現的框架包裝函數。


#include <stdio.h>
#include <malloc.h>


static void *(*old_malloc_hook)(size_t, const void *);
static void (*old_free_hook)(void *,const void *);
static void *new_malloc_hook(size_t size, const void *caller);
static void new_free_hook (void *ptr, const void *caller);


static void *new_malloc_hook(size_t size, const void *caller) {
void *mem;
__malloc_hook = old_malloc_hook;
        __free_hook = old_free_hook;
mem = malloc(size);
fprintf(stderr, "%p: malloc(%zu) = %p\n", caller, size, mem);
__malloc_hook = new_malloc_hook;
__free_hook = new_free_hook;
return mem;
}




static void new_free_hook (void *ptr, const void *caller)
{
/* Restore all old hooks */
__malloc_hook = old_malloc_hook;
__free_hook = old_free_hook;
/* Call recursively */
free (ptr);
/* Save underlying hooks */
//old_malloc_hook = __malloc_hook;
//old_free_hook = __free_hook;
/* printf might call free, so protect it too. */
printf ("freed pointer %p\n", ptr);
/* Restore our own hooks */
__malloc_hook = new_malloc_hook;
__free_hook = new_free_hook;
}


static void init_my_hooks(void) {
old_malloc_hook = __malloc_hook;
old_free_hook = __free_hook;
__malloc_hook = new_malloc_hook;
        __free_hook = new_free_hook;
}


void (* volatile __malloc_initialize_hook)(void)= init_my_hooks;


將以上代碼包含到代碼主文件中,便可以看到malloc被替換了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章