How to wrap a library function with custom code? - c

I have a library which implements malloc. I want to override this function with a custom malloc function that does something and then calls the malloc function of the library.
How can i redefine the symbol malloc without losing the function from the library?

The GNU linker provides the --wrap symbol flag to wrap a custom function around an existing function.
As you can read here, last flag: http://ieee.uwaterloo.ca/coldfire/gcc-doc/docs/ld_3.html#SEC3
--wrap symbol
Use a wrapper function for symbol. Any undefined reference to symbol will be resolved to __wrap_symbol. Any undefined reference to __real_symbol will be resolved to symbol. This can used to provide a wrapper for a system function. The wrapper function should be called __wrap_symbol. If it wishes to call the system function, it should call __real_symbol. Here is a trivial example:
void *
__wrap_malloc (int c) {
printf ("malloc called with %ld\n", c);
return __real_malloc (c);
}
If you link other code with this file using --wrap malloc, then all calls to malloc will call the function __wrap_malloc instead. The call to __real_malloc in __wrap_malloc will call the real malloc function. You may wish to provide a __real_malloc function as well, so that links without the --wrap option will succeed. If you do this, you should not put the definition of __real_malloc in the same file as __wrap_malloc; if you do, the assembler may resolve the call before the linker has a chance to wrap it to malloc.

it is not a good practice to create new functions with the names of library functions. If at all you want to create such a function, your new function will work fine but you can not use the library function. If you want to create your own version of printf(), you can do so but you can not use the original printf() function as you are overriding.

If both functions have the same prototype, you can use a function pointer
#include <stdlib.h>
void *my_malloc(size_t len) {
return malloc(len);
}
int main(void) {
void *(*malloc_pointer)(size_t);
malloc_pointer = my_malloc;
malloc_pointer(42); // uses my_malloc;
malloc_pointer = malloc;
malloc_pointer(42); // uses malloc;
return 0;
}

Related

libc_hidden_proto macro in gnu library C

in gnu library C source code, man could see some of functions prototype are followed with libc_hidden_proto macro, what is used for.
what is used for.
It's documented in inlcude/libc-symbols.h:
/* The following macros are used for PLT bypassing within libc.so
(and if needed other libraries similarly).
First of all, you need to have the function prototyped somewhere,
say in foo/foo.h:
int foo (int __bar);
If calls to foo within libc.so should always go to foo defined in libc.so,
then in include/foo.h you add:
libc_hidden_proto (foo)
line and after the foo function definition:
int foo (int __bar)
{
return __bar;
}
libc_hidden_def (foo)
or
int foo (int __bar)
{
return __bar;
}
libc_hidden_weak (foo)
In other words, this allows GLIBC to call e.g. __mmap which is defined inside libc.so.6 even if you LD_PRELOADed some other library which defines its own __mmap.

Undefined reference to pointer to a function

I'm new to this topic. I'm trying to dynamically link a shared library in my c code, but I'm getting an error...
undefined reference to `func'
I've searched the web and I can't find anything wrong with my syntax...
void *handle;
int (*func)(char **);
handle = dlopen(argv[0], RTLD_LOCAL | RTLD_LAZY);
*(int **)&func = dlsym(handle, pluggin_method->FunctionName); //I might need to pass a string by first using strcpy
int func_ret_val = (func)(argv); //execute function
I'm banging my head against a wall trying to figure this out. Any help?
does the code have the statement:
#include <dlfcn.h>
Are you including the -ldl library in the link statement>
if the returned value from dlopen() is NULL, then call dlerror() to obtain the resulting error message.
NOTE: dlopen() loads the library and returns a 'opaque' handle for the library, not a pointer to the actual function.
After a successful call to dlopen() then need to call dlsym() to obtain the actual address in memory of the function.
check the returned value from dlsym() (!=NULL) to assure the op was successful

Is there a way to overwrite the malloc/free function in C?

Is there a way to hook the malloc/free function call from a C application it self?
malloc() and free() are defined in the standard library; when linking code, the linker will search the library only for symbols that are not already resolved by eailier encountered object code, and object files generated from compilation are always linked before any libraries.
So you can override any library function simply by defining it in your own code, ensuring that it has the correct signature (same name, same number and types of parameters and same return type).
Yes you can. Here's an example program. It compiles and builds with gcc 4.8.2 but does not do anything useful since the implementations are not functional.
#include <stdlib.h>
int main()
{
int* ip = malloc(sizeof(int));
double* dp = malloc(sizeof(double));
free(ip);
free(dp);
}
void* malloc(size_t s)
{
return NULL;
}
void free(void* p)
{
}
Not sure if this counts as "overwriting', but you can effectively change the behavior of code that calls malloc and free by using a macro:
#define malloc(x) my_malloc(x)
#define free(x) my_free(x)
void * my_malloc(size_t nbytes)
{
/* Do your magic here! */
}
void my_free(void *p)
{
/* Do your magic here! */
}
int main(void)
{
int *p = malloc(sizeof(int) * 4); /* calls my_malloc */
free(p); /* calls my_free */
}
You may need LD_PRELOAD mechanism to replace malloc and free.
As many mentioned already, this is very platform specific. Most "portable" way is described in an accepted answer to this question. A port to non-posix platforms requires finding an appropriate replacement to dlsym.
Since you mention Linux/gcc, hooks for malloc would probably serve you the best.
Depending on the platform you are using, you may be able to remove the default malloc/free from the library and add your own using the linker or librarian tools. I'd suggest you only do this in a private area and make sure you can't corrupt the original library.
On the Windows platform there is a Detour library. It basically patches any given function on the assembler level. This allows interception of any C library or OS call, like CreateThread, HeapAlloc, etc. I used this library for overriding memory allocation functions in a working application.
This library is Windows specific. On other platforms most likely there are similar libraries.
C does not provide function overloading. So you cannot override.

dlopen issue(OSX)

I have a main application which dynamically loads a dylib, from inside that dylib I would like to call exported functions from my main program. I'm using dlopen(NULL,flag) to retrieve my main applications handle and dlsym(handle, symbol) to get the function.
dlopen gives no error but when I try to dlsym my function I get the following error:
dlerror dlsym(RTLD_NEXT, CallMe): symbol not found
The symbol is exported corrected confirmed by nm
I'm not sure why RTLD_NEXT is there? is this the result of dlopen(NULL,flag)?
How can I solve this problem or achieve my goal?
Or are there other ways to call the main application (preferably not by passing on function pointers to the dylib)?
Thanks in advance!
Added:
Export:
extern "C" {
void CallMe(char* test);
}
__attribute__((visibility("default")))
void CallMe(char* test)
{
NSLog(#"CallMe with: %s",test);
}
Result of nm
...
0000000000001922 T _CallMe
..
Code in dylib:
void * m_Handle;
typedef void CallMe(char* test);
CallMe* m_Function;
m_Handle = dlopen(NULL,RTLD_LAZY); //Also tried RTLD_NOW|RTLD_GLOBAL
if(!m_Handle)
return EC_ERROR;
m_Function = (CallMe*)dlsym(m_Handle, "CallMe");
if(!m_Function)
return EC_ERROR;
m_Function("Hallo");
I think a better approach might be to establish a proprietary protocol with your dynamic library where you initialise it by passing it a struct of function pointers. The dynamic library needs to simply provide some sort of init(const struct *myfuncs), or some such, function and this makes it simpler to implement the dynamic library.
This would also make the implementation more portable.

C functions before mainCRTStartup on Mingw?

void start() {
stuff(); //code before mainCRTStartup
mainCRTStartup();
}
int main()
{
//other code
}
In Visual C++,it compiles fine and function "stuff()" gets called before main. How would call "stuff()" before "mainCRTStartup()"? on Mingw(OS:Windows NT)? it seems to ignore "void start()".
You could use the -e argument to ld (the linker) to specify start as your entry point.
I'm not sure how to feed arguments to ld using mingw; perhaps someone can edit my answer to provide that.
The real entry point is always start().
start() calls mainCRTStartup() that initializes CRT functions and call main(), so in stuff(), you can not use CRT functions.

Resources