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 #include #include 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_` * Call to real function inside wrapper: `__real_` * Works for *all* functions * Works only on dynamically linked executables * Intercepts only calls inside the given source file Example (`wrap.c`): ```c #include 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