themattrix / musings

Like a blog, but easier.
15 stars 1 forks source link

Another way to do it under Mac OS X #1

Open atopuzov opened 12 years ago

atopuzov commented 12 years ago

Hi,

I've been looking around on how to do interposition and found your code on github. I have also found another way to do the interposition and I thought you might be interested.

cat libuname.c
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/utsname.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 }; 

int my_uname(struct utsname *name);

DYLD_INTERPOSE(my_uname, uname)

int my_uname(struct utsname *name)
{
  int ret = uname(name);
  strncpy(name->version, "Johnny 5", sizeof(name->version));
  return ret;
}
> clang -c libuname.c
> clang -dynamiclib -o libuname.dylib -install_name libuname.dylib libuname.o
> DYLD_INSERT_LIBRARIES=./libuname.dylib uname -v
Johnny 5
themattrix commented 12 years ago

I like it; this approach is much different (and perhaps simpler) than the one I've presented. If you don't mind, I'd like to include it in an "Alternative Approaches" section. Thanks!

atopuzov commented 12 years ago

Hi,

Yup include it, that's why I wrote to you. It's simpler because you don't have to 'remember' the pointer to the old function, and compared to linux it's totally different. One of the nicer things is that you don't have to force flat namespace thingy. The macro itself is from <mach-o/dyld-interposing.h> http://www.opensource.apple.com/source/dyld/dyld-97.1/include/mach-o/dyld-interposing.h