Hooking open() with LD_PRELOAD
31 Aug 2025Introduction
Modern Linux systems provide a fascinating feature for overriding shared library behavior at runtime: LD_PRELOAD
.
This environment variable lets you inject a custom shared library before anything else is loaded — meaning you can
intercept and modify calls to common functions like open
, read
, connect
, and more.
In this post, we’ll walk through hooking the open()
function using LD_PRELOAD
and a simple shared object. No extra
tooling required — just a few lines of C, and the ability to compile a .so
file.
Intercepting open()
Let’s write a tiny library that intercepts calls to open()
and prints the file path being accessed. We’ll also
forward the call to the real open()
so the program behaves normally.
Create a file named hook_open.c
with the following:
#define _GNU_SOURCE
#include <stdio.h>
#include <stdarg.h>
#include <dlfcn.h>
#include <fcntl.h>
int open(const char *pathname, int flags, ...) {
static int (*real_open)(const char *, int, ...) = NULL;
if (!real_open)
real_open = dlsym(RTLD_NEXT, "open");
va_list args;
va_start(args, flags);
mode_t mode = va_arg(args, int);
va_end(args);
fprintf(stderr, "[HOOK] open() called with path: %s\n", pathname);
return real_open(pathname, flags, mode);
}
This function matches the signature of open
, grabs the “real” function using dlsym(RTLD_NEXT, ...)
, and then
forwards the call after logging it.
Compiling the Hook
Compile your code into a shared object:
gcc -fPIC -shared -o hook_open.so hook_open.c -ldl
Now you can use this library with any dynamically linked program that calls open
.
Testing with a Simple Program
Try running a standard tool like cat
to confirm that it’s using open()
:
LD_PRELOAD=./hook_open.so cat hook_open.c
You should see:
[HOOK] open() called with path: hook_open.c
#define _GNU_SOURCE
...
Each time the program calls open()
, your hook intercepts it, logs the call, and passes control along.
Notes and Gotchas
- This only works with dynamically linked binaries — statically linked programs don’t go through the dynamic linker.
- Some programs (like
ls
) may useopenat()
instead ofopen()
. You can hook that too, using the same method. - If your hook causes a crash or hangs, it’s often due to incorrect use of
va_arg
or missingdlsym
resolution.
Where to Go From Here
You can expand this basic example to:
- Block access to specific files
- Redirect file paths
- Inject fake contents
- Hook other syscalls like
connect()
,write()
,execve()
LD_PRELOAD
is a powerful mechanism for debugging, sandboxing, and learning how programs interact with the system.
Just don’t forget — you’re rewriting the behavior of fundamental APIs at runtime.
With great power comes great segfaults!