How to Show All Shared Libraries Used by Executables in Linux

How to show all shared libraries used by executables in Linux?

  1. Use ldd to list shared libraries for each executable.
  2. Cleanup the output
  3. Sort, compute counts, sort by count

To find the answer for all executables in the "/bin" directory:

find /bin -type f -perm /a+x -exec ldd {} \; \
| grep so \
| sed -e '/^[^\t]/ d' \
| sed -e 's/\t//' \
| sed -e 's/.*=..//' \
| sed -e 's/ (0.*)//' \
| sort \
| uniq -c \
| sort -n

Change "/bin" above to "/" to search all directories.

Output (for just the /bin directory) will look something like this:

  1 /lib64/libexpat.so.0
1 /lib64/libgcc_s.so.1
1 /lib64/libnsl.so.1
1 /lib64/libpcre.so.0
1 /lib64/libproc-3.2.7.so
1 /usr/lib64/libbeecrypt.so.6
1 /usr/lib64/libbz2.so.1
1 /usr/lib64/libelf.so.1
1 /usr/lib64/libpopt.so.0
1 /usr/lib64/librpm-4.4.so
1 /usr/lib64/librpmdb-4.4.so
1 /usr/lib64/librpmio-4.4.so
1 /usr/lib64/libsqlite3.so.0
1 /usr/lib64/libstdc++.so.6
1 /usr/lib64/libz.so.1
2 /lib64/libasound.so.2
2 /lib64/libblkid.so.1
2 /lib64/libdevmapper.so.1.02
2 /lib64/libpam_misc.so.0
2 /lib64/libpam.so.0
2 /lib64/libuuid.so.1
3 /lib64/libaudit.so.0
3 /lib64/libcrypt.so.1
3 /lib64/libdbus-1.so.3
4 /lib64/libresolv.so.2
4 /lib64/libtermcap.so.2
5 /lib64/libacl.so.1
5 /lib64/libattr.so.1
5 /lib64/libcap.so.1
6 /lib64/librt.so.1
7 /lib64/libm.so.6
9 /lib64/libpthread.so.0
13 /lib64/libselinux.so.1
13 /lib64/libsepol.so.1
22 /lib64/libdl.so.2
83 /lib64/ld-linux-x86-64.so.2
83 /lib64/libc.so.6

Edit - Removed "grep -P"

How to find all shared libraries actually used during execution in Linux?

You can use ltrace(1) for this:

$ PROG='ls -l'
# Collect call info
$ ltrace -o calls.txt -l '*' $PROG &> /dev/null
# Analyze collected data
$ cat calls.txt | sed -ne '/->/{ s/^\(.*\)->.*/\1/; p }' | sort -u
libacl.so.1
libcap.so.2
libc.so.6
libselinux.so.1
ls
# Compare with ldd
$ ldd /bin/ls | wc -l
10

Get a list of all shared libraries that a running service is using in Ubuntu

libc.so.6 is present in the output of solutions 1, 2 and 4 but not in 3.

libc.so.6 is a symlink to libc-2.23.so so it is present, albeit in a different form.

and /lib64/ld-linux-x86-64.so.2 as well which no other solution reports.

Ditto, it's ld-2.23.so.

Also the output of solution 1 above reports inux-vdso.so.1

This is a dummy shared lib which does not exist but is emulated by kernel to increase performance of some library functions. I guess 3 has it in

ffffffffff600000 4K r-x-- [ anon ]

but it's not annotated.

which of these solutions should be taken as the accurate one.

2 and 4 are equivalent. They are inferior to 1 and 3 because they report only direct dependencies of your app (not transitive dependencies of it's dependants). Further, 1 is inferior to 3 because it won't report dynamically loaded libs (via dlopen).

Also, on demand a process can load any more shared libraries
when ever needed. Am I right or wrong here ?

Yup, that's used to implement e.g. plugins.

So, if I really need to know the shared libraries
being used by a process, will I need to poll the process
all the time to figure this out ?
(Am sure there is much better /elegant solution to this)

No, there is no easier solution. You could check whether app calls dlopen (by scanning output of readelf --dyn-syms -W) - if it doesn't you are most probably fine (some really clever apps may load libs themselves via mmap, etc. but this is so rare that is fine to ignore).

If app does call dlopen than the best thing you can do is use solution 3. This is obviously incomplete as app may load new libs at any time, depending on it's algorithm (and there's generally no way to figure it out statically as that would be equivalent to solving the halting problem).

One approximate solution for finding potentially dlopen-ed libs would be to scan all strings in app (by running strings on it) and extracting everything that looks like a library name. Of course this won't catch the situations where library name is generated dynamically (e.g. read from some config file).

Solution 1, the ldd approach, is something I would want
to avoid because of the inherent security risk it has
(depending on the version of the ldd being used) of
starting an executable itself to figure out it's shared libraries.

I don't think executable is started i.e. no app or libs code gets run.

So what is the best approach to figure out the shared libraries being
used by a process?

I'd got with no. 3 (which has many equivalent variants e.g. scanning /proc/PID/maps or lsof as suggested in other post). Depending on how inclined you are about dlopen, you can also scan strings for potentially loaded libs but IMHO that's an overkill in majority of cases.

Get list of static libraries used in an executable

ldd <exe filename> shows dynamically linked libraries

nm <exe filename> shows the symbols in the file.

To see which symbols come from static libraries requires running nm against those libraries to get a list of the symbols (functions, etc.) in them, then comparing them to what your list of symbols from nm <exe filename>.

You compare lists with the comm command. See man comm for details.

This was taken from this forum here.

How to check if a shared library is linked with -Bsymbolic?

You can examine dynamic section of the library:

$ readelf -d a.out | grep SYMBOLIC
0x0000000000000010 (SYMBOLIC) 0x0
0x000000000000001e (FLAGS) SYMBOLIC

Why string shown up in Shared Library file like .so file in Linux?

-fvisibility=hidden only affects the linker visibility, i.e. whether symbols are visible when a linker tries to link against your file. It does not specify any active obfuscation.

Your strings are still placed inside a data section and need to be loaded into the memory space of the process when your library is loaded, so they will still need to be visible when inspecting the file. If you need them to be obfuscated, you will need to obfuscate them yourself and decode them at runtime (knowing that a sufficiently determined attacker can still reverse engineer or debug your library).



Related Topics



Leave a reply



Submit