Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a reliable way to know what libraries could be dlopen()ed in an elf binary?

Tags:

c

posix

gnu

elf

Basically, I want to get a list of libraries a binary might load.

The unreliable way I came up with that seems to work (with possible false-positives):

comm -13 <(ldd elf_file | sed 's|\s*\([^ ]*\)\s.*|\1|'| sort -u) <(strings -a elf_file | egrep '^(|.*/)lib[^:/]*\.so(|\.[0-9]+)$' | sort -u)

This is not reliable. But it gives useful information, even if the binary was stripped.

Is there a reliable way to get this information without possible false-positives?

EDIT: More context.

Firefox is transitioning from using gstreamer to using ffmpeg. I was wondering what versions of libavcodec.so will work. libxul.so uses dlopen() for many optional features. And the library names are hard-coded. So, the above command helps in this case.

I also have a general interest in package management and binary dependencies. I know you can get direct dependencies with readelf -d, dependencies of dependencies with ldd. And I was wondering about optional dependencies, hence the question.

like image 657
Not Important Avatar asked Dec 18 '15 17:12

Not Important


1 Answers

ldd tells you the libraries your binary has been linked against. These are not those that the program could open with dlopen.

The signature for dlopen is

void *dlopen(const char *filename, int flag);

So you could, still unreliably, run strings on the binary, but this could still fail if the library name is not a static string, but built or read from somewhere during program execution -- and this last situation means that the answer to your question is "no"... Not reliably. (The name of the library file could be read from the network, from a Unix socket, or even uncompressed on the fly, for example. Anything is possible! -- although I wouldn't recommend any of these ideas myself...)

edit: also, as John Bollinger mentioned, the library names could be read from a config file.

edit: you could also try substituting the dlopen system call with one of yours (this is done by the Boehm garbage collector with malloc, for example), so it would open the library, but also log its name somewhere. But if the program didn't open a specific library during execution, you still won't know about it.

like image 182
Jay Avatar answered Oct 19 '22 23:10

Jay