75 lines
1.5 KiB
Markdown
75 lines
1.5 KiB
Markdown
|
|
Intercepting Function/System Calls in Linux
|
|
===========================================
|
|
|
|
Option 1: `LD_PRELOAD`
|
|
----------------------
|
|
|
|
* No need to re-link
|
|
* Works for *all* functions
|
|
* Works only on dynamically linked executables
|
|
* Intercepts all calls (including stack allocations etc.)
|
|
|
|
Example (`preload.c`):
|
|
```c
|
|
#include <stdlib.h>
|
|
#include <dlfcn.h>
|
|
#include <errno.h>
|
|
|
|
void *malloc(size_t size) {
|
|
// before call to malloc
|
|
void *(*_malloc)(size_t);
|
|
if ((_malloc = dlsym(RTLD_NEXT, "malloc")) == NULL) {
|
|
errno = ENOSYS;
|
|
return NULL;
|
|
}
|
|
void *ret = _malloc(size);
|
|
// after call to malloc
|
|
return ret;
|
|
}
|
|
```
|
|
|
|
```shell
|
|
# ./main is already compiled and ready
|
|
gcc -shared -fPIC -o preload.so preload.c
|
|
LD_PRELOAD="$(pwd)/preload.so" ./main
|
|
```
|
|
|
|
|
|
Option 2: `gcc --wrap`
|
|
----------------------
|
|
|
|
* Need to re-link(/-comiple)
|
|
* Relatively simple code:
|
|
* Function name: `__wrap_<symbol>`
|
|
* Call to real function inside wrapper: `__real_<symbol>`
|
|
* Works for *all* functions
|
|
* Works only on dynamically linked executables
|
|
* Intercepts only calls inside the given source file
|
|
|
|
Example (`wrap.c`):
|
|
```c
|
|
#include <stdlib.h>
|
|
|
|
extern void *__real_malloc(size_t size);
|
|
|
|
void *__wrap_malloc(size_t size) {
|
|
// before call to malloc
|
|
void *ret = __real_malloc(size);
|
|
// after call to malloc
|
|
return ret;
|
|
}
|
|
```
|
|
|
|
```shell
|
|
gcc -o main_wrapped main.c wrap.c -Wl,--wrap=malloc
|
|
./main_wrapped
|
|
```
|
|
|
|
|
|
Option 3: Linux kernel
|
|
----------------------
|
|
|
|
* Only works with Linux system calls
|
|
* Also works with statically linked executables
|