Je pense que la suggestion de remplacer dlopen()
utilise LD_PRELOAD
est seulement une solution partielle - vous ne serez pas attraper dépendances d'une bibliothèque chargée de dlopen()
cette façon. En fin de compte, je ne voyais aucun moyen de le faire sans gratter l'état interne du lieur dynamique lui-même. Il a trouvé qu'il y a un symbole _rtld_global
exporté de ld.so
qui a l'information, mais que vous devez utiliser des en-têtes Glibc privés pour l'interpréter. Ce qui suit est un extrait Python qui (en supposant que ma lecture des sources Glibc est correcte) imprime toutes les bibliothèques partagées dans l'espace de noms global dans l'ordre dans lequel elles seront recherchées. Les bibliothèques chargées avec RTLD_LOCAL
ne seront pas imprimées. Le fait qu'il repose sur les détails de mise en œuvre de Glibc signifie que cette approche est lourde de dangers, mais à mes fins de test/d'audit, je pense que tout ira bien.
import ctypes
# Abridged type declarations pillaged from Glibc. See:
# - https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/generic/ldsodefs.h
# - https://sourceware.org/git/?p=glibc.git;a=blob;f=include/link.h
class link_map(ctypes.Structure):
_fields_ = [
("l_addr", ctypes.c_size_t),
("l_name", ctypes.c_char_p),
]
class r_scope_elem(ctypes.Structure):
_fields_ = [
("r_list", ctypes.POINTER(ctypes.POINTER(link_map))),
("r_nlist", ctypes.c_uint),
]
class rtld_global(ctypes.Structure):
_fields_ = [
("_ns_loaded", ctypes.POINTER(link_map)),
("_ns_nloaded", ctypes.c_uint),
("_ns_main_searchlist", ctypes.POINTER(r_scope_elem)),
]
_rtld_global = rtld_global.in_dll(ctypes.CDLL(None), "_rtld_global")
searchlist = _rtld_global._ns_main_searchlist[0]
print [searchlist.r_list[n][0].l_name for n in xrange(searchlist.r_nlist)]
Sur mon CentOS système 7, cette impression:
['', '/lib64/libpython2.7.so.1.0', '/lib64/libpthread.so.0', '/lib64/libdl.so.2',
'/lib64/libutil.so.1', '/lib64/libm.so.6', '/lib64/libc.so.6',
'/lib64/ld-linux-x86-64.so.2']
Eh bien, vous pouvez vérifier si la bibliothèque est déjà chargée (si vous avez la liste) en utilisant par exemple dlopen avec RTLD_NOLOAD, qui renverra nulle ou gérer, selon si elle a déjà été chargée ou non. Quelque chose qui peut vous aider est probablement/proc/PID/maps analyse/analyse. Cela peut aussi vous aider [link] (https://stackoverflow.com/questions/5103443/how-to-check-what-shared-libraries-are-loaded-at-run-time-for-a-given-process) –