I encountered a problem with a piece of software. It seemed it based some calculations on the information it retrieved about a couple of directories. Unfortunately its output changed whenever you made modifications to the OS, which was not desirable. And of course it is a closed source piece of code. Using strace I could identify which directories it was accessing and which function it was using: lstat64 So looking into a solution for this I quickly came to using LD_PRELOAD to overload the stat call and return modified information. My first attempts failed as the stat call isn’t a published symbol by libc: nm -D /lib/libc.so.6 | grep stat64
000bbfe0 T __fxstat64
000bbfe0 T __fxstat64
000bc020 T __lxstat64
000bc020 T __lxstat64
000bbfa0 T __xstat64
000bbfa0 T __xstat64 It looks like the stat call is a wrapper for the __ versions of the call. As I found out later, this has to do with compatibility of the structure stat uses. So, after a few attempts I created a working prototype. Below is an example which intercepts the lstat64 call which ls makes to get information on a file. The code below changes the returned size of the file if it is test.c to 0. #define _GNU_SOURCE 1 Compile the code with: gcc -Wall -fPIC -shared -o test.so test.c -ldl Now we’ll do a test with and without preloading the library. Without: $ ls -al test.*
-rw-r--r-- 1 mark mark 443 Jul 20 19:59 test.c
-rwxr-xr-x 1 mark mark 4416 Jul 20 19:59 test.so* With: $ LD_PRELOAD=./test.so ls -al test.*
-rw-r--r-- 1 mark mark 0 Jul 20 19:59 test.c
-rwxr-xr-x 1 mark mark 4416 Jul 20 19:59 test.so* As you can see the library matches the test.c and sets the filesize to zero. Not a very useful example, but a very useful technique. |