Is it possible to dynamically modify symbol table at runtime in C (in elf format on Linux)?
My eventual goal is the following:
Inside certain function say foo
, I want to override malloc
function to my custom handler my_malloc
. But outside foo
, any malloc
should still call to malloc as in glibc.
Note: this is different from LD_PRELOAD
which would override malloc
during the entire program execution.
Is it possible to dynamically modify symbol table at runtime in C (in elf format on Linux)?
In theory this is possible, but in practice it's too hard to do.
Inside certain function say foo
, I want to override malloc
function to my custom handler my_malloc
. But outside foo
, any malloc
should still call to malloc
as in glibc.
Modifying symbol table (even if it were possible) would not get you to your desired goal.
All calls from anywhere inside your ELF binary (let's assume foo
is in the main executable), resolve to the same PLT import slot malloc@plt
. That slot is resolved to glibc malloc
on the first call (from anywhere in your program, assuming you are not using LD_BIND_NOW=1
or similar). After that slot has been resolved, any further modification to the symbol table will have no effect.
You didn't say how much control over foo
you have.
If you can recompile it, the problem becomes trivial:
#define malloc my_malloc
int foo() {
// same code as before
}
#undef malloc
If you are handed a precompiled foo.o
, you are linking it with my_malloc.o
, and you want to redirect all calls from inside foo.o
from malloc
to my_malloc
, that's actually quite simple to do at the object level (i.e. before final link).
All you have to do is go through foo.o
relocation records, and change the ones that say "put address of external malloc
here" to "put address of external my_malloc
here".
If foo.o
contains additional functions besides foo
, it's quite simple to limit the relocation rewrite to just the relocations inside foo
.