I create a .dylib file and compile it:
#define _GNU_SOURCE
#include
#include
static void* (*real_malloc)(size_t);
void *mal
If you can recompile the executable being hooked, then I think a simpler solution is to recompile the executable with -force_flat_namespace
:
➜ clang slow_leak.c -force_flat_namespace -o slow_leak
➜ DYLD_INSERT_LIBRARIES=malloc_hook.dylib ./slow_leak
leaking
in hooked malloc
More info. This is on OSX 10.12.2 MacOS Sierra.
A comment on HN (2 years later) mentioned DYLD_FORCE_FLAT_NAMESPACE=1
can help in cases where it's not feasible to recompile. I haven't tried it yet, so YMMV.
From dyld
docs:
DYLD_INSERT_LIBRARIES This is a colon separated list of dynamic libraries to load before the ones specified in the program. This lets you test new modules of existing dynamic shared libraries that are used in flat-namespace images by loading a temporary dynamic shared library with just the new modules. Note that this has no effect on images built a two-level namespace images using a dynamic shared library unless DYLD_FORCE_FLAT_NAMESPACE is also used.
DYLD_FORCE_FLAT_NAMESPACE Force all images in the program to be linked as flat-namespace images and ignore any two-level namespace bindings. This may cause programs to fail to execute with a multiply defined symbol error if two-level namespace images are used to allow the images to have multiply defined symbols.
So your code needed DYLD_FORCE_FLAT_NAMESPACE=1. Anyway, my implementation works for /usr/local/bin/git
only with this option enabled.
Please try to export any DYLD environment variable, f.e.:
export DYLD_LIBRARY_PATH=.
Check env:
env
If variable wasn't exported, try to disable system integrity protection (also this link may be useful if you are running on MacOS virtual machine)
The code in my original post used to work on Yosemite. On El Capitan, it does NOT work. I ended up doing the following approach (DYLD_INTERPOSE
+ DYLD_INSERT_LIBRARIES
):
#define _GNU_SOURCE
#include <dlfcn.h>
#include <stdio.h>
#include <stdlib.h>
#define DYLD_INTERPOSE(_replacment,_replacee) \
__attribute__((used)) static struct{ const void* replacment; const void* replacee; } _interpose_##_replacee \
__attribute__ ((section ("__DATA,__interpose"))) = { (const void*)(unsigned long)&_replacment, (const void*)(unsigned long)&_replacee };
void* pMalloc(size_t size) //would be nice if I didn't have to rename my function..
{
printf("Allocated: %zu\n", size);
return malloc(size);
}
DYLD_INTERPOSE(pMalloc, malloc);