Introduction of Function Hijacking in C
Thanks to the symbol-lazy-loading ability in Unix environment, we can do many interesting thing on functions from some shared library when executing some executables.
All we need to do are
- Implement a shared library that contains the functions we want to hijack.
- Run the executable with our magic library inserted.
Make a Shared Library
If we want to replace some function with stub / fake implementation. we can just implement a function with the same name and the same signature.
For example, if we want to fixed the clock during unit test …
1 | // in hijack.c |
If we want do observation about some function call, but still delegate the call to the original function, we can implement a function that load corresponding function at runtime and pass the function call.
For example, if we want to monitor the call sequence of file open action.
1 | // in hijack.c |
After finish our implementation, compile them as a shared library,
called hijack.so
here.
1 | cc -fPIC -shared -o hijack.so hijack.c |
Hijack during Actual Execution
We can use LD_PRELOAD
environment variable to do insert our special
shared library for any executable during execution.
1 | LD_PRELOAD="path-to-shared-lib" executable |
For example, if we want to use the implementations in last section in
our executable, called app
here.
1 | // app.c |
(Compile and) run the executable
1 | cc -o app app.c |
Output
1 | open file [1]: "output.txt" |
The open-file action is traced, and the time is fixed to the epoch.
If we need to overwrite functions with more than one shared library,
just use :
to separate them in LD_PRELOAD
.
Conclusion
It’s a powerful feature, it allows we to do observation, to replace with mock/fake implementation, or sometime even to apply emergency patch.
And all make this possible are the dynamic linking mechanism, and the one-to-one mapping from symbol from sources to libraries/binaries.
Although development in C is somehow inconvenient, but it’s still a interesting experience when seeing this kind of usage. :D