Create a wrapper function for malloc and free in C(hack overflow)
-
GLIBC-specific solution (mostly Linux). If your compilation environment is
glibc
withgcc
, the preferred way is to use malloc hooks. Not only it lets you specify custommalloc
andfree
, but will also identify the caller by the return address on the stack. -
POSIX-specific solution. Define
malloc
andfree
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 originalmalloc
implementation, which you can look up usingdlsym
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; }
-
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
-
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被替換了。