My goal is to wrap malloc()
with my own implementation and then inject that implementation into executables using LD_PRELOAD
trick for educational purposes.
I've made two files, test.c
for testing the injection and wrapper.c
which wraps malloc()
and is compiled as a shared library.
What seems to be happening is dlsym()
is calling malloc()
under the hood, causing the infinite recursion until the stack runs out, at which point a segfault occurs.
I've had to use write()
instead of fprintf()
for the same reason, but I can't figure out the workaround for dlsym()
.
This approach seems to be inline with other implementations, so I'm a confused why this isn't working for me.
// test.c
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
int main(void)
{
const char* string = "test start\n";
write(2, string, strlen(string));
(void)malloc(1);
return 0;
}
Built with:
gcc -o test test.c
// wrapper.c
#define _GNU_SOURCE
#include <stdlib.h>
#include <dlfcn.h>
#include <stddef.h>
#include <string.h>
#include <unistd.h>
static void* (*real_malloc)(size_t size) = NULL;
void* malloc(size_t size)
{
const char* string = "malloc()\n";
write(2, string, strlen(string));
if (real_malloc == NULL) {
real_malloc = dlsym(RTLD_NEXT, "malloc");
}
return 0;
}
Built with:
gcc -c -fPIC -o wrapper.o wrapper.c
gcc -shared -o wrapper.so wrapper.o
Ran with:
LD_PRELOAD=wrapper.so ./test
Returns:
test start
malloc()
...
malloc()
Segmentation fault (core dumped)
EDIT:
Using the suggested solution revealed that I wasn't linking the wrapper
correctly. I was still getting getting:
./test: symbol lookup error: wrapper.so: undefined symbol: dlsym
Adding -ldl
solved the problem:
gcc -shared -o wrapper.so wrapper.o -ldl
Based on this question.