简体   繁体   中英

Intercept and forward C calls to a third-party library

I have an application (A) which calls a third-party shared library (C). I want to write a library of my own (B) that intercepts calls from A to C, and in some cases replace the calls with my own code, in some cases do some extra processing, then call the matching function in C, and in some cases just forward the calls to C directly.

The application is open-source, so I could just change each call site to call a similarly-named function in B, then call the corresponding function in C when required, but that would be a lot of work and would make merging upstream changes in the application difficult. I do not have the source to the third-party library. If it was header-only then I could just use namespaces to achieve this but I'm not sure how to go about it when both my library and the third-party library seemingly need the exact same symbols defined.

Is there even any way to make this work? I'm primarily targeting OS X, but would like it to work on linux and then eventually Windows as well.

You can use LD_PRELOAD to point to your own shared library. With LD_PRELOAD all functions in your shared library will be called instead of functions with the same name in those other libraries.

If you wish to inject code and then call the original functions you will need to call dlsym to get the original function from the third party library.

There are some examples here: https://rafalcieslak.wordpress.com/2013/04/02/dynamic-linker-tricks-using-ld_preload-to-cheat-inject-features-and-investigate-programs/

One solution is as follows.

In a header file, #define all functions you want to intercept to your wrapper functions.

#define foo wrap_foo
#define bar wrap_bar

Stick this in some header file that is included everywhere, so that all of the code includes this header. This header should get included before the header for the library that you are intercepting. gcc also has an -include option that causes a header file to be included in all sources.

The goal here is to replace all calls to actual functions with calls to the wrapper functions.

Now define your wrapper functions somewhere, and intercept the calls as you wish. This file should not include the wrapper header that you created earlier.

int wrap_foo() {
    return foo();
}

int wrap_bar() {
    return bar();
}

Link it all together.

Note that this will let you intercept calls to foo() and bar() etc. only in the code that is compiled including the wrapper header. Any pre-compiled code (in libraries or objects) will link to foo() and bar() etc. directly.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM