Open In App

Function Interposition in C with an example of user defined malloc()

Improve
Improve
Improve
Like Article
Like
Save Article
Save
Share
Report issue
Report

Function interposition is the concept of replacing calls to functions in dynamic libraries with calls to user-defined wrappers.

What are applications?

  1. We can count number of calls to function.
  2. Store caller’s information and arguments passed to function to track usage.
  3. Detect memory leak, we can override malloc() and keep track of allocated spaces.
  4. We can add our own security policies. For example, we can add a policy that fork cannot be called with more that specified recursion depth.

How to do function interposition?
The task is to write our own malloc() and make sure our own malloc() is called inplace of library malloc(). Below is a driver program to test different types of interpositions of malloc().




// File Name : hello.c
  
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
  
int main(void)
{
    // Call to user defined malloc
    void *ptr = malloc(4);
      
    printf("Hello World\n");
    return 0;
}


  1. Compile time : Replace library call with our own function when the source code is compiled.




    /* Compile-time interposition of malloc using C preprocessor. 
       A local malloc.h file defines malloc as wrapper */
      
    // A file that contains our own malloc function
    // File Name : mymalloc.c
    #include <stdio.h>
    #include <malloc.h>
    void *mymalloc(size_t s)
    {
       printf("My malloc called");
       return NULL;
    }

    
    




    // filename : malloc.h
    // To replace all calls to malloc with mymalloc
    #define malloc(size) mymalloc(size)
    void *mymalloc(size_t size);

    
    

    Steps to execute above on Linux:

    // Compile the file containing user defined malloc()
    :~$ gcc  -c mymalloc.c
    
    // Compile hello.c with output file name as helloc. 
    // -I. is used to include current folder (.) for header
    // files to make sure our malloc.h is becomes available.
    :~$ gcc  -I. -o helloc hello.c mymalloc.o
    
    // Run the generated executable
    :~$ ./helloc
    My malloc called
    Hello World 
  2. .

  3. Link time : When the relocatable object files are statically linked to form an executable object file.




    // filename : mymalloc.c
    /* Link-time interposition of malloc using the
       static linker’s (ld) "--wrap symbol" flag. */
    #include <stdio.h>
      
    // __real_malloc() is used to called actual library
    // malloc()
    void *__real_malloc(size_t size);
      
    // User defined wrapper for malloc()
    void *__wrap_malloc(size_t size)
    {
       printf("My malloc called");
       return NULL;
    }

    
    

    Steps to execute above on Linux:

    // Compile the file containing user defined malloc()
    :~$ gcc  -c mymalloc.c
    
    // Compile hello.c with output name as hellol  
    // "-Wl,--wrap=malloc" is used tell the linker to use
    //  malloc() to call __wrap_malloc(). And to use 
    // __real_malloc() to actual library malloc() 
    :~$ gcc  -Wl,--wrap=malloc -o hellol hello.c mymalloc.o
    
    // Run the generated executable
    :~$ ./hellol
    My malloc called
    Hello World 
  4. .

  5. Load/run time : When an executable object file is loaded into memory, dynamically linked, and then executed.

    The environment variable LD_PRELOAD gives the loader a list of libraries to load be loaded before a command or executable.
    We make a dynamic library and make sure it is loaded before our executable for hello.c.




    /* Run-time interposition of malloc based on dynamic linker’s
       (ld-linux.so) LD_PRELOAD mechanism */
    #define _GNU_SOURCE
    #include <stdio.h>
      
    void *malloc(size_t s)
    {
       printf("My malloc called\n");
       return NULL;
    }

    
    

    Steps to execute above on Linux:

    
    // Compile hello.c with output name as helloc
    :~$ gcc -o hellor hello.c
    
    // Generate a shared library myalloc.so. Refer
    // https://www.geeksforgeeks.org/working-with-shared-libraries-set-2/
    // for details.
    :~$ gcc -shared -fPIC -o mymalloc.so mymalloc.c
    
    // Make sure shared library is loaded and run before .
    :~$ LD_PRELOAD=./mymalloc.so ./hellor
    My malloc called
    Hello World
    
  6. .

    The code for user defined malloc is kept small for better readability. Ideally, it should allocate memory by making a call to library malloc().

    Source:
    https://www.utdallas.edu/~zxl111930/spring2012/public/lec18-handout.pdf



    Last Updated : 29 May, 2017
    Like Article
    Save Article
    Previous
    Next
    Share your thoughts in the comments
Similar Reads