
Using gcc:

gcc -c -fPIC preload.c
ld -o preload.so -G preload.o

Than, to use it:

LD_PRELOAD=<dir>/preload.so
export LD_PRELOAD
<run program>
unset LD_PRELOAD

So when I run sshd with this I get

204.160.72.232.22          *.*                0      0     0      0 LISTEN

instead of

      *.22                 *.*                0      0     0      0 LISTEN

Just change the IP address in the macro and compile away.


This will possibly still break because I didn't do things like copy the
original struct and modify the copy. Just needs to be added if you want
to cover all cases. This works for the vast majority (and then one I needed
the day I wrote it :-)

James


#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <dlfcn.h>

#define LIBRARY "/usr/lib/libsocket.so"
#define ADDRESS "192.216.189.90"
#define TRUE 1
#define FALSE 0

int bind (int s, struct sockaddr *name, int namelen)
{
    void *Handle;
    int (*Fptr)(int, struct sockaddr *, int);
    int Found = FALSE;
    
    /* Look for inet type sockets */

    if (name->sa_family == AF_INET) {
        Found = TRUE;
    }

    /* Open the library */

    Handle = dlopen (LIBRARY, RTLD_LAZY);

    /* Get the function symbol out of the library */

    Fptr = (int (*)(int, struct sockaddr *, int)) dlsym (Handle, "bind");

    /*
     * If this is an inet socket, make it find to the local ip and not
     * all ips on the box
     */
 
    if (Found) {
        if (((struct sockaddr_in *) name)->sin_addr.s_addr ==
            htonl (INADDR_ANY)) {
            ((struct sockaddr_in *) name)->sin_addr.s_addr =
                inet_addr (ADDRESS);
        }
 
        /* Call the real function with the new struct */
 
        (*Fptr)(s, name, namelen);
    }
    else {
 
        /* Call the real function with the original struct */
 
        (*Fptr)(s, name, namelen);
    }
 
    /* Cleanup and close the library */
 
    dlclose (Handle);
}

