I want to use LDR_PRELOAD to hook dlsym, but I could not find a way to get the dlsym address in libc.a. I try to use nlist with libc.a, but it did not work.
Is that any way to get the dlsym by symbol table?
Related
I'm using a wrapper library to trace functions using LD_PRELOAD which does work when the functions I'm tracing are referenced in the application.
The wrapper library uses dlsym to populate symbols it wraps.
But this is not working if the application doesn't reference functions directly but through dlopen.
Should the wrapper library work with dynamically loaded libraries? If not, is there a way to make it work?
But this is not working if the application doesn't reference functions directly but through dlopen.
If the application performs:
void *h = dlopen("libfoo.so", ...);
void *sym = dlsym(h, "symbol");
then the symbol will be resolved to libfoo.so, regardless of any LD_PRELOADs (and indeed regardless of any other instances of symbol in other already loaded libraries). This is working as intended.
Should the wrapper library work with dynamically loaded libraries?
No.
If not, is there a way to make it work?
Yes, you can make it work. You would need to provide a replacement.so which provides all the symbols which the application looks up in libfoo.so, and then make it so the replacement.so is dlopend()ed by the application.
One way to do that is to rename libfoo.so -> libfoo.so.orig, copy replacement.so -> libfoo.so, and have replacement.so itself dlopen("libfoo.so.orig", ...).
If the application dlopens libfoo.so without absolute path, you may be able to arrange so replacement.so is earlier in the search path, e.g.
mkdir /tmp/replacement
ln -s /path/to/replacement.so /tmp/replacement/liboo.so
LD_LIBRARY_PATH=/tmp/replacement /path/to/a.out
If you go that route, replacement.so would still need to know how to dlopen the original libfoo.so (could use hard-coded absolute path for that).
I need to change the sk_rcvlowat of program applications to to performance test. Is there a way to change the socket options from command line? Otherwise, we have to change all the source code of application program and re-compile them. I guess that each socket is associated with an inode, so that we can change the socket option via the inode.
By the way, please can anyone show me where the "socket file" located when the process created it. I have already checked /proc/<pid>/fd/<fd[X]> but they are only symbolic links like this one 10 -> socket:[13895]
Any suggestions are appreciated. Thanks in advance.
You can create a wrapper library, which will intercept all calls to setsockopt and will be able to change some parameters. This works if your application have the call to setsockopt. In another case, you can wrap different function, e.g. socket using the same approach. In wrapper of socket you need to create a socket with __socket and then change any parameter you want.
Wrapper library must be a dynamic one, with setsockopt function. This function is allowed to be overloaded by glibc. Then, start your programm as follows:
LD_PRELOAD=path_to_wrapper_library/libwrap.so ./you_program
The library will be injected (linked) into programm and will replace the setsockopt function.
This works only with dynamically linked programms (check it with ldd ./you_program - there will be some /lib/*.so if it is dynamically linked).
Original function can be called from your code with __ prefix: __setsockopt or using dlsym(RTLD_NEXT, "setsockopt");.
Some examples (not a setsockopt, but the idea of preload wrapper): http://scaryreasoner.wordpress.com/2007/11/17/using-ld_preload-libraries-and-glibc-backtrace-function-for-debugging/ or http://developers.sun.com/solaris/articles/lib_interposers_code.html
Compile to dynamic library with:
gcc wrap.c -fPIC -shared -ldl -o libwrap.so
I am using a third party shared library and I need to check whether a function is exported by shared library programatically.
How to do this. I need this because if function does not exist I need to run some other function locally.
You could probably use dlsym for this.
If you load the library with dlopen, you will use the handle that it returns.
If you're linked against this library you may use special pseudo-handles (10x to caf for pointing it out):
From dlsym man:
There are two special pseudo-handles, RTLD_DEFAULT and RTLD_NEXT. The former will find the first occurrence of the desired symbol using the default library search order. The latter will find the next occurrence of a function in the search order after the current library. This allows one to provide a wrapper around a function in another shared library.
Check the header file of the intended library to get the function signature.
Using dlopen you can load the library dynamically and fetch the symbol if it is exposed in the library with subsequent calls to dlsym and dlclose.
may be you can use objdump command to check all symbol exposed like this
objdump -T libtest.so
I know that using dlopen with RLTD_NOLOAD one can find out whether a shared object is already loaded or not. This, however, doesn't seem to work if a so is linked to the executable and loaded by the linker during application startup.
I mean, lets say I have mylib.so and load it with dlopen. Later, if I make dlopen with RLTD_NOLOAD, I get the handle as expected.
However, if I link mylib.so to the application ( -lmylib at the makefile ) dlopen returns NULL.
How can I get a handle to the shared object if it is directly linked to the exec. and not loaded explicitly?
Thanks in Advance
This is way too late, but -
dlopen(NULL, RTLD_LAZY/*Any load option u want*/) will get a handle to the binary. And it is supposed to be able to find any symbol in the binary or shared libs it has loaded. I think that is a good place to start.
I'm writing some code that uses dynamic shared libraries as plugins.
My command line for building the shared libraries looks like:
cc -shared -fPIC -o module.so -g -Wall module.c
Within the module, I can call functions that are in any other shared library that has been loaded within the main executable.
However I cannot access (exported) functions that are in the executable itself (I get undefined symbol errors).
My call to dlopen looks like this:
void *handle = dlopen(plugin, RTLD_NOW);
Can anyone please advise how my module can call back to my executable, without having to put all of the executable's utility functions into yet another shared library?
Correct solution is to add -rdynamic to the link command of the main executable. This will add appropriate option to ld (which, when using GNU ld, happens to be --export-dynamic).
Adding --export-dynamic directly is technically incorrect: it's a linker option, and so should be added as -Wl,--export-dynamic, or -Wl,-E. This is also less portable than -rdynamic (other linkers have an equivalent, but the option itself is different).
I've found the answer myself.
I had to add the --export-dynamic flags to the link options for the main executable.
When creating a dynamically linked
executable, add all symbols to the
dynamic symbol table. The dynamic
symbol table is the set of symbols
which are visible from dynamic objects
at run time.
If you do not use this option, the
dynamic symbol table will normally
contain only those symbols which are
referenced by some dynamic object
mentioned in the link.
If you use "dlopen" to load a dynamic
object which needs to refer back to
the symbols defined by the program,
rather than some other dynamic object,
then you will probably need to use
this option when linking the program
itself.
When I encountered the same problem, I just used the following solution. Before loading any plugin, just load the program itself, bringing its symbols to dynamic tables:
dlopen(NULL,RTLD_NOW|RTLD_GLOBAL);
I think the solution is better. The reason is that, it also solves the same problem if you
a) your program (or a trird-party module) is linked (not in runtime) against the shared library, which symbols need to be in dynamic table;
b) can not recompile that module with -rdynamic flag.