2
votes

There's a well-known technique for interposing dynamically linked binaries: creating a shared library and and using LD_PRELOAD variable. But it doesn't work for statically-linked binaries.

One way is to write a static library that interpose the functions and link it with the application at compile time. But this isn't practical because re-compiling isn't always possible (think of third-party binaries, libraries, etc).

So I am wondering if there's a way to interpose statically linked binaries in the same LD_PRELOAD works for dynamically linked binaries i.e., with no code changes or re-compilation of existing binaries.

I am only interested in ELF on Linux. So it's not an issue if a potential solution is not "portable".

3

3 Answers

3
votes

One way is to write a static library that interpose the functions and link it with the application at compile time.

One difficulty with such an interposer is that it can't easily call the original function (since it has the same name).

The linker --wrap=<symbol> option can help here.

But this isn't practical because re-compiling

Re-compiling is not necessary here, only re-linking.

isn't always possible (think of third-party binaries, libraries, etc).

Third-party libraries work fine (relinking), but binaries are trickier.

It is still possible to do using displaced execution technique, but the implementation is quite tricky to get right.

1
votes

I'll assume you want to interpose symbols in main executable which came from a static library which is equivalent to interposing a symbol defined in executable. The question thus reduces to whether it's possible to intercept a function defined in executable.

This is not possible (EDIT: at least not without a lot of work - see comments to this answer) for two reasons:

  • by default symbols defined in executable are not exported so not accessible to dynamic linker (you can alter this via -export-dynamic or export lists but this has unpleasant performance or maintenance side effects)
  • even if you export necessary symbols, ELF requires executable's dynamic symtab to be always searched first during symbol resolution (see section 1.5.4 "Lookup Scope" in dsohowto); symtab of LD_PRELOAD-ed library will always follow that of executable and thus won't have a chance to intercept the symbols
0
votes

What you are looking for is called binary instrumentation (e.g., using Dyninst or ptrace). The idea is you write a mutator program that attaches to (or statically rewrites) your original program (called mutatee) and inserts code of your choice at specific points in the mutatee. The main challenge usually revolves around finding those insertion points using the API provided by the instrumentation engine. In your case, since you are mainly looking for static symbols, this can be quite challenging and would likely require heuristics if the mutatee is stripped of non-dynamic symbols.