I am looking for a C library/framework that allows me to replace functions in memory and redirect them to my own implementations, while still allowing my implementation to call the original implementation.
This seems to be a rather rare need on Linux-y systems, presumably because LD_PRELOAD covers most aspects of runtime-function-replacing-thingies.
The following approach seems to work on applications I have. I don't like proprietary blobs on my machines, so I don't know if it works with e.g. Steam. I'd be very interested to know, though; I don't see any reason why it shouldn't.
The following approach uses
_dl_vsym()to look up correctly versioneddlsym()anddlvsym()fromlibdl.soprior tomain()being executed. During application execution, the interposeddlsym()anddlvsym()call their original versions (not_dl_vsym()); I believe that should avoid any application-specific woes.In case other dynamic libraries get initialized before this one, very careful initial versions of those functions are used. They use
_dl_vsym()to obtain the references to the libdldlsym()ordlvsym()function; any subsequent call will use the libdldlsym()ordlvsym(). This limits the fragile time to the first call during library initialization -- but the priority 101 hopefully gets this library initialized first.If you save the above as
example.c, you can compile it intolibexample.sousingIn some cases, you need to modify the
LIBDL_VERSION. Useto check which API version your libdl uses. (I've seen
GLIBC_2.0andGLIBC_2.2.5; it does not reflect the actual version of the library, but the API version of thedlsym()anddlvsym()calls.)The
interposed[]array contains the modified results for the interposed functions.I have verified that the above example does not crash with any applications I tried -- including a simple
dlsym()anddlvsym()stress test I wrote --, and that it also interposes theglXSwapBuffers()correctly (inglxgearsandmpv).Questions? Comments?