on LD_PRELOAD and C++
LD_PRELOAD is a way to intercept system calls issued from glibc and interact with them: modifying args, changing return values, completely exchanging implementations, etc
Some misc. things I learned about implementing preload hooks from C++:
- remember to wrap the calls with extern “C” to prevent function mangling from CPP
- try not to use cout inside preload functions without initializing std::iostream
- you can use c++ overloading instead of C var args, which is cool!
- LD_PRELOAD doesn’t necessarily cover all function invocations (f.e. system calls not invoked via glibc) - ptrace does a better job here
- if you get undefined symbol errors during linking, it could be that you compiled with gcc instead of g++!
- if your hooks aren’t being run, try implementing the 64 version: i.e. open64() vs open()
- openat() may or may not be a systemcall - it likely calls open() or open64()
An example preload in CPY
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif
#include <dlfcn.h>
#include <stdio.h>
#include <stdlib.h>
// we use extern C to prevent symbol mangling for usage in LD_PRELOAD
extern "C":
static void _libhook_init() __attribute__((constructor))
static void _libhook_init():
printf("INIT HOOK\n")
int open(const char *pathname, int flags, mode_t mode=0):
static int(*func_open)(const char *, int, mode_t) = NULL
if(!func_open)
func_open =(int(*)(const char *, int, mode_t)) dlsym(RTLD_NEXT, "open")
printf("OPENING PATH %s\n", pathname)
return func_open(pathname, flags, mode)