2

I want to know which dynamic libraries are loaded when executing a C/C++ program on Linux.

For example,

int main()
{
    ...
    list = GetAllSharedLibraryFilePaths();
}

list should contain: libm.so.6, librt.so.1, ... or paths: /lib/x86_64-linux-gnu/libm.so.6, /lib/x86_64-linux-gnu/librt.so.1 ...

Are there any APIs that return all shared library file paths? I know ldd, readelf can do that but I need to do that with C/C++ programming in the executable that loads shared libraries.

Thank you.

freddy
  • 463
  • 1
  • 8
  • 20
  • What do you mean by "I need to do that with C/C++ programming in the executable that loads shared libraries"? If you just need it accessible from the calling program, you could try using `system("ldd")` and then parse the output. – Simon Berens Dec 10 '19 at 01:26

3 Answers3

1

You can use non-standard dl_iterate_phdr(3) function to walk through the list of loaded shared objects.

#define _GNU_SOURCE
#include <link.h>
#include <stdio.h>

int print(struct dl_phdr_info *info, size_t size, void *data) {
  printf("%s\n", info->dlpi_name);
  return 0;
}

int main() {
  dl_iterate_phdr(print, NULL);
  return 0;
}
$ gcc test.c -o test
$ ./test

linux-vdso.so.1
/lib/x86_64-linux-gnu/libc.so.6
/lib64/ld-linux-x86-64.so.2
ofo
  • 1,160
  • 10
  • 21
0

in the executable that loads shared libraries.

I believe to get the current process, reading the /proc/self/maps file is the easiest way to get this information on Linux, and look for all the unique .so files mapped to the processes memory in the last column, e.g.

55e8485f5000-55e8485fd000 r-xp 00000000 fd:01 654093                     /bin/cat
55e8487fc000-55e8487fd000 r--p 00007000 fd:01 654093                     /bin/cat
55e8487fd000-55e8487fe000 rw-p 00008000 fd:01 654093                     /bin/cat
55e84a238000-55e84a259000 rw-p 00000000 00:00 0                          [heap]
7f403d604000-7f403d8e2000 r--p 00000000 fd:01 920600                     /usr/lib/locale/locale-archive
7f403d8e2000-7f403dac9000 r-xp 00000000 fd:01 1439402                    /lib/x86_64-linux-gnu/libc-2.27.so
7f403dac9000-7f403dcc9000 ---p 001e7000 fd:01 1439402                    /lib/x86_64-linux-gnu/libc-2.27.so
...

So you can see there one of the loaded libraries is /lib/x86_64-linux-gnu/libc-2.27.so. It should include anything loaded via dlopen as well as directly linked.

Fire Lancer
  • 29,364
  • 31
  • 116
  • 182
0

You can use the proc filesystem to query shared libraries using /proc/<pid>/maps. Consult the full reference for proc which shows some sample output that you can parse:

address           perms offset  dev   inode       pathname
...
35b1800000-35b1820000 r-xp 00000000 08:02 135522  /usr/lib64/ld-2.15.so
35b1a1f000-35b1a20000 r--p 0001f000 08:02 135522  /usr/lib64/ld-2.15.so
35b1a20000-35b1a21000 rw-p 00020000 08:02 135522  /usr/lib64/ld-2.15.so
35b1a21000-35b1a22000 rw-p 00000000 00:00 0
35b1c00000-35b1dac000 r-xp 00000000 08:02 135870  /usr/lib64/libc-2.15.so
35b1dac000-35b1fac000 ---p 001ac000 08:02 135870  /usr/lib64/libc-2.15.so
35b1fac000-35b1fb0000 r--p 001ac000 08:02 135870  /usr/lib64/libc-2.15.so
35b1fb0000-35b1fb2000 rw-p 001b0000 08:02 135870  /usr/lib64/libc-2.15.so

Taking the unique set of pathnames in the 6th column will give you all the actual shared libraries loaded in the given process.

Note that this will only give you the shared libraries that are active in the process at the time of invocation, and if you call this at startup, you will get the shared libraries that were resolved by the loader using the NEEDED entries in the ELF. If the tool uses dyld you will need to check the list again.

Note that if you are doing this for security purposes, the shared libraries will already be loaded by the time you check this list, so any potentially nefarious actions could have already occurred and been covered up. If you want to check shared libs for security reasons, you would need to parse the ELF NEEDED entries and then resolve using PATH from the environment.

gavinb
  • 19,278
  • 3
  • 45
  • 60