Courtesy of exocus project on github
You can invoke ld-linux with the LD_TRACE_LOADED_OBJECTS environment variable set to 1 and it will list all of the resolved library dependencies for a binary. For example, running
LD_TRACE_LOADED_OBJECTS=1 /lib64/ld-linux-x86-64.so.2 /bin/grep
will output the following.
linux-vdso.so.1 => (0x00007ffc7495c000)
libpcre.so.0 => /lib64/libpcre.so.0 (0x00007f89b2f3e000)
libc.so.6 => /lib64/libc.so.6 (0x00007f89b2b7a000)
libpthread.so.0 => /usr/lib/libpthread.so.0 (0x00007f0e95e8c000)
/lib64/ld-linux-x86-64.so.2 (0x00007f89b3196000)
The linus-vdso.so.1 dependency refers to kernel space routines that are exported to user space, but the other four are shared library files on disk that are required in order to run grep. Notably, one of these dependencies is the /lib64/ld-linux-x86-64.so.2 linker itself. The location of this file is typically hardcoded into an ELF binary's INTERP header and the linker is invoked by the kernel when you run the program. We'll come back to that in a minute, but for now the main point is that we can find a binary's direct dependencies using the linker.
Of course, these direct dependencies might have additional dependencies of their own. We can iteratively find all of the necessary dependencies by following the same approach of invoking the linker again for each of the library dependencies.
Links