Search code examples
cmacosinterposing

Interposing on OSX, my function not being called


So, I'm messing around with some interposing code on OSX (gcc 4.2.1) and I'm trying to get the following to work:

When I call ./login using the DYLD_INSERT_LIBRARIES=my.dylib, it should override the default login implementation and use my custom implementation. Granted this is a contrived example, but its just to help me understand the point.

My source:

cat libinterposers.c

#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include "login.h"

typedef struct interpose_s
{
  void *new_func;
  void *orig_func;
} interpose_t;

int my_open(const char *, int, mode_t);
int my_close(int);
int my_login();


static const interpose_t interposers[] __attribute__ ((section("__DATA, __interpose"))) = 
{
     { (void *)my_open,  (void *)open  },
     { (void *)my_close, (void *)close },
     { (void *)my_login, (void *)login },
};

int my_login()
{
  printf("--> my_login()\n");
  return 1;
}

int my_open(const char *path, int flags, mode_t mode)
{
  int ret = open(path, flags, mode);
  printf("--> %d = open(%s, %x, %x)\n", ret, path, flags, mode);
  return ret;
}

int my_close(int d)
{
  int ret = close(d);
  printf("--> %d = close(%d)\n", ret, d);
  return ret;
}

cat login.c

#include <stdio.h>
#include "login.h"

int login()
{
  return -1;
}

int main()
{
  if (login() == 1)
  {
    printf("login successful\n");
  }
  else
  {
    printf("login failed\n");
  }
}

And finally, login.h

int login();

Now when I execute with something like "cat /dev/null" it works fine ...

DYLD_INSERT_LIBRARIES=/tmp/libinterposers.dylib cat /dev/null
--> 3 = open(/dev/null, 0, 0)
--> 0 = close(3

However, when I run with my ./login example

DYLD_INSERT_LIBRARIES=/tmp/libinterposers.dylib ./login
login failed

As you can see, it just prints login failed, my custom "my_login" function never runs ... any ideas? Thanks in advance!


Solution

  • Your login function is linked statically, not dynamically, so there's nothing to interpose. You can't interpose statically linked functions. If you want this to work, you'll need to move login to its own dynamic library.