2

Platform - Linux

I have a typical requirement, where I need to give higher priority to my function then system provided function.

Lets say I have a third party library or executable. It calls many system functions such strcpy or strlen etc. I can not modify the executable/library as I do not have access to code.

Now I have implemented my own strlen or strcpy functions. When the third party library or executable is executing it should call my functions instead of system library functions.

Is it possible. If yes, can somebody guide me how to do this.

LD_PRELOAD trial result

As per suggestion here, I tried with LD_PRELOAD. I tried to override malloc function.

    #include <string.h>

    void *malloc(int size)
    {
        void *ptr = NULL;
        printf("Inside my malloc function\n");
        ptr = malloc(size);
        return ptr;
    }

I put the above code in a c file and built mem.so file and executed below command.

export LD_PRELOAD=./mem.so

So now I have overwritten malloc function.

If execute ls or clear command I get below result, which is logical.

Inside my malloc function
Inside my malloc function
Inside my malloc function
Inside my malloc function
Inside my malloc function

It looks my overloaded malloc function is invoked recursively. Only one time call I need. How can I achieve that.

alk
  • 69,737
  • 10
  • 105
  • 255
Austin
  • 1,709
  • 20
  • 40
  • 4
    It is up to the implementation to decide whether you can do what you want. If the implementation inlines (for sake of argument) `strlen()`, you won't be able to substitute your code for that because there isn't a function call to replace. You may or may not be able to deal with actual function calls — it depends. The implementation is under no obligation to cooperate. – Jonathan Leffler Sep 09 '15 at 06:35
  • What you are asking for is very dangerous and if it were possible can cause a lot of havoc and chaos. You can read up on shared libraries and static linking. – sureshvv Sep 09 '15 at 06:36
  • 1
    It's certainly possible to override functions in dynamically linked libraries. How to do it depends on the operating system though. Also, some standard C function calls can be replaced by the compiler to highly optimized internal versions, either statically linked into the executable (and such functions can't be overridden) or they have weird names that can be hard to figure out. – Some programmer dude Sep 09 '15 at 06:36
  • Sometime back I was using purifier memory leak tool. When I start my program (already attached to purifier), I think in place of malloc or free function call, purifier calls its own functions (I am not very sure, I hope so). That way probably it determines memory leak details. If I am correct in above assumption, probably a way exists to overload a function in C at run time. But I am not getting the way to do it. – Austin Sep 09 '15 at 06:43
  • Its linux, updated my question. – Austin Sep 09 '15 at 06:45
  • 1
    Some standard library functions, such as `strlen` and `strcpy`, are typically inlined by the compiler in optimized builds, so you can't reliably override these without recompiling, because there's no function call. Is your question about these functions you mention, or were those given just as an example? – hyde Sep 09 '15 at 06:51
  • It is just a generic example. Lets assume that the library is not built in optimized mode. – Austin Sep 09 '15 at 06:54
  • Best option is probably to set some custom path, so that the compiler/linker does not go off to look at the standard library at all, but at your own library. That might require that you rewrite the whole of string.h though... Possibly you could use the GCC open source implementation and modify it. What is the reason you need to rewrite those functions in the first place? – Lundin Sep 09 '15 at 07:33

1 Answers1

7

Your malloc needs to call the real malloc. Use dlsym(3) to find the symbol. RTLD_NEXT finds the next such reference.

#include <stdio.h>
#include <dlfcn.h>
void *malloc(size_t size)
{
  static void * (*func)();

  if(!func)
     func = (void *(*)()) dlsym(RTLD_NEXT, "malloc");
  printf("malloc(%d) is called\n", size);
  return(func(size));
}
meuh
  • 11,500
  • 2
  • 29
  • 45