Comment lister les dépendances de bibliothèque d'un binaire non-natif?
lors du développement pour la plate-forme native, je peux utiliser ldd pour lister toutes les bibliothèques partagées (.donc les fichiers) un exécutable binaire que je construis essayera de charger au démarrage. Mais lors de la compilation croisée, je ne sais pas comment obtenir la même information. Le ldd
n'est pas un utilitaire binutils normal, comme strip
ou ar
, qui peut être construit à côté de gcc
pour la compilation croisée, mais à la place, c'est un script shell cryptique qui ne peut apparemment fonctionner que sur une plate-forme native.
donc, en utilisant les outils binutils multi-cibles, y a-t-il un moyen d'obtenir une liste de la dépendance liée dynamiquement pour un binaire étranger?
9 réponses
est-il possible d'obtenir une liste de la liée de façon dynamique de la dépendance de l'étranger binaire
vous pouvez lister dépendances directes d'un binaire assez facilement:
readelf -d a.out | grep NEEDED
0x0000000000000001 (NEEDED) Shared library: [librt.so.1]
0x0000000000000001 (NEEDED) Shared library: [libc.so.6]
Je ne connais aucun moyen de continuer récursivement ceci pour obtenir la liste complète (comme ldd
le fait). Vous devrez répéter le processus pour chaque bibliothèque NEEDED
à la main.
Vous pouvez le faire bash -x ldd /bin/ls
pour comprendre ce que ldd
est en train de faire. Le script ldd
n'est pas si "cryptique". Il fonctionne essentiellement
LD_TRACE_LOADED_OBJECTS=1 /lib64/ld-linux-x86-64.so.2 /bin/ls
donc il utilise le chargeur dynamique du système (parce que le résultat de ldd
dépend de votre environnement et système réel!). Mais vous pouvez examiner avec objdump -x /bin/ls
la section dynamique d'un exécutable, par exemple
% objdump -x /bin/ls
/bin/ls: file format elf64-x86-64
/bin/ls
architecture: i386:x86-64, flags 0x00000112:
EXEC_P, HAS_SYMS, D_PAGED
start address 0x00000000004046d4
Program Header:
PHDR off 0x0000000000000040 vaddr 0x0000000000400040 paddr 0x0000000000400040 align 2**3
filesz 0x00000000000001c0 memsz 0x00000000000001c0 flags r-x
INTERP off 0x0000000000000200 vaddr 0x0000000000400200 paddr 0x0000000000400200 align 2**0
filesz 0x000000000000001c memsz 0x000000000000001c flags r--
LOAD off 0x0000000000000000 vaddr 0x0000000000400000 paddr 0x0000000000400000 align 2**21
filesz 0x0000000000019ef4 memsz 0x0000000000019ef4 flags r-x
LOAD off 0x000000000001a000 vaddr 0x000000000061a000 paddr 0x000000000061a000 align 2**21
filesz 0x000000000000077c memsz 0x0000000000001500 flags rw-
DYNAMIC off 0x000000000001a028 vaddr 0x000000000061a028 paddr 0x000000000061a028 align 2**3
filesz 0x00000000000001d0 memsz 0x00000000000001d0 flags rw-
NOTE off 0x000000000000021c vaddr 0x000000000040021c paddr 0x000000000040021c align 2**2
filesz 0x0000000000000044 memsz 0x0000000000000044 flags r--
EH_FRAME off 0x0000000000017768 vaddr 0x0000000000417768 paddr 0x0000000000417768 align 2**2
filesz 0x00000000000006fc memsz 0x00000000000006fc flags r--
STACK off 0x0000000000000000 vaddr 0x0000000000000000 paddr 0x0000000000000000 align 2**3
filesz 0x0000000000000000 memsz 0x0000000000000000 flags rw-
Dynamic Section:
NEEDED libselinux.so.1
NEEDED librt.so.1
NEEDED libacl.so.1
NEEDED libc.so.6
INIT 0x0000000000402148
FINI 0x00000000004125f8
HASH 0x0000000000400260
GNU_HASH 0x00000000004005c0
STRTAB 0x0000000000401100
SYMTAB 0x0000000000400620
STRSZ 0x00000000000004d7
SYMENT 0x0000000000000018
DEBUG 0x0000000000000000
PLTGOT 0x000000000061a208
PLTRELSZ 0x0000000000000990
PLTREL 0x0000000000000007
JMPREL 0x00000000004017b8
RELA 0x0000000000401740
RELASZ 0x0000000000000078
RELAENT 0x0000000000000018
VERNEED 0x00000000004016c0
VERNEEDNUM 0x0000000000000003
VERSYM 0x00000000004015d8
Version References:
required from librt.so.1:
0x09691a75 0x00 05 GLIBC_2.2.5
required from libacl.so.1:
0x05822452 0x00 06 ACL_1.2
0x05822450 0x00 04 ACL_1.0
required from libc.so.6:
0x09691a75 0x00 03 GLIBC_2.2.5
0x0d696913 0x00 02 GLIBC_2.3
encore une fois, la dépendance réelle dépend de le système où votre binaire est exécuté (par exemple parce que je pourrais avoir un LD_LIBRARY_PATH
avec mon propre libc.so.6
quelque part, ce qui serait une mauvaise idée).
vous avez donc besoin d'une variante croisée de objdump
alors que dans gdb
, info partagé est similaire à ldd
. Il fournit des informations complètes d'exécution lisible par l'utilisateur de l'exécutable.
readelf
serait miss chemin et les autres bibliothèques de l'information .
readelf
est un très bon outil pour l'hôte de l'étude. Le développeur peut choisir qui fonctionne.
un peu en retard pour cet ajout mais quelqu'un pourrait en bénéficier/clarifier. Le drapeau à lire ne donne-t-il pas le même résultat que le ldd?
$ readelf -AW /bin/vi
Library list section '.gnu.liblist' contains 8 entries:
Library Time Stamp Checksum Version Flags
0: libselinux.so.1 2011-07-25T08:02:58 0x17a7d5f7 0 0
1: libtermcap.so.2 2011-07-25T08:02:59 0x29ae9ff7 0 0
2: libacl.so.1 2011-07-25T08:02:58 0x60748842 0 0
3: libc.so.6 2011-07-25T08:02:58 0x0c2c7eeb 0 0
4: libdl.so.2 2011-07-25T08:02:58 0xdfbfc467 0 0
5: libsepol.so.1 2011-07-25T08:02:58 0x857499cb 0 0
6: /lib64/ld-linux-x86-64.so.2 2011-07-25T08:02:58 0x9e6549b7 0 0
7: libattr.so.1 2011-07-25T08:02:58 0x862f1546 0 0
la seule information manquante ici semble être le chemin complet où se trouvent ces bibliothèques.
d'autre part, les outils mentionnés jusqu'à présent ne sont utiles que si vous avez une installation connue pour fonctionner. Mes problèmes les plus courants sont:
- installation d'un programme (la plupart du temps à la vitesse de rotation) qui ne démarre pas ou s'écrase pendant le démarrage. D'une certaine façon, je pense que c'est lié aux incompatibilités de bibliothèques mais je n'ai pas trouvé un moyen facile de vérifier ces choses avant d'installer un programme (ni en effet après)
- dans un attemtp to overcome (1), j'ai parfois eu recours au téléchargement des sources et à la compilation locale. Le script de configuration typique est en partie utile parce qu'il vous dit quelles bibliothèques vous manquez. Cependant, il ne parvient pas à vous dire quelle est la version la plus basse de telles bibliothèques sont nécessaires
qui peut nous éclairer sur ces questions? BTW, j'ai essayé de lire des instructions d'installation et des notes de publication, mais elles sont presque toujours loin d'être suffisantes.
un bel exemple peut tout mettre en contexte, alors essayez de compiler Cinelerra .
par conception ldd ne peut être exécuté que sur la cible. Cependant, il est possible d'imiter le comportement ldd en utilisant readelf. Un script appelé `xldd' a été développé dans le projet crosstool-ng. Une version indépendante de ce script est disponible ici:
https://gist.github.com/jerome-pouiller/c403786c1394f53f44a3b61214489e6f
pour lister la dépendance des bibliothèques partagées d'un binaire non natif, vous pouvez essayer l'outil suivant: http://www.mathembedded.com/component/k2/item/1-cross-ldd.html
Je l'utilise sur SH4 et MIPS. Comme indiqué dans d'autres réponses, vous pouvez obtenir la même chose en utilisant la sortie readelf et une boucle récursive, mais je n'ai jamais essayé par moi-même depuis cross-ldd existent.
Désolé de faire un thread zombie, mais je travaille sur certaines choses pour mon routeur OpenWRT et je voulais vérifier certaines dépendances pour voir si j'avais assez d'espace sur ma partition jffs2 pour copier plus que e2fsck
. Réponse courte: Non.avi .
Anyhoo, j'ai fait un petit script qui utilise le réponse acceptée plus certains (probablement trop verbeux) grep
appels et avec une petite main agitant et certains unicorn les larmes (pas de soucis, c'étaient des larmes de joie!) J'ai réussi à réunir le script suivant qui vous donne toutes les dépendances. Je suis sûr qu'il y a beaucoup de place à l'amélioration, surtout en ce qui concerne les boucles et la récursion, ainsi que le fait que ce sont des bashismes tout le temps (c'est-à-dire des tableaux indexés) mais cela fonctionne au moins nominalement pour moi:
#!/bin/bash
declare -a search_path
declare -a found_deps
find_dependencies() {
local file=""
local -a deps
local -a deps_to_process
deps=( $( readelf -d "$file" | grep "NEEDED" | \
grep -o -E "\[[^]]*\]" | grep -o -E "[^][]*" ) )
local add_this_dep=true
# always assume we've found $file and add it to the $found_deps list
# if it's not there
for found_dep in "${found_deps[@]}"
do
if [ "$found_dep" = "$(basename $file)" ]
then
add_this_dep=false
break
fi
done
# if $add_this_dep is true, go ahead and add to the found_deps list
if $add_this_dep
then
found_deps+=("$(basename $file)")
fi
# for every dependency found by readelf (no path)
for dep in "${deps[@]}"
do
local process_dep=true
# if the basename of the file passed into the function is
# this dep, skip processing altogether
if [ "$dep" = "$(basename $file)" ]
then
break
else
# otherwise, if it's one of the 'found deps' don't process it
for found_dep in "${found_deps[@]}"
do
if [ "$dep" = "$found_dep" ]
then
process_dep=false
break
fi
done
# it wasn't one of the 'found deps' so add
# it to the found_deps list
if $process_dep
then
found_deps+=($dep)
fi
fi
# if we are supposed to process this dep
if $process_dep
then
local file_path=
# check each search path for a file named $dep underneath it
for dir in $search_path
do
file_path=$( find "$dir" -name "$dep" | head -n 1 )
# if the $file_path is not empty, then we found
# a copy of it, so break out of the loop
if [ -n "$file_path" ]; then break; fi;
done
# if the $file_path is not empty, then we found a copy
# of the file, place it the list of deps to be processed
if [ -n "$file_path" ]
then
deps_to_process+=($file_path)
fi
fi
done
# now, go through all of our $deps_to_process (with path)
# and run "find_dependencies" on them
for dep_to_process in "${deps_to_process[@]}"
do
find_dependencies "$dep_to_process"
done
}
argc=$#
if [ $argc -eq 0 ]
then
printf '%s: prints dependencies of a (potentially) non-native elf executable, recursively\n'
printf '\n'
printf 'usage:\n'
printf '\t%s <non-native elf executable> [ --supress-header ] [ <path> ... ]\n' "$(basename "151900920")"
printf '\twhere\n'
printf '\t\t<non-native elf executable> is the name of a file to find the dependencies of.\n'
printf '\t\t[ <path> ... ] is an optional list of directories under which to search for libraries.\n'
printf '\t\t[ --supress-header ] is an optional flag that prints nothing other than the list of files to stdout.\n'
printf '\t\t\t(without the parameter a banner is sent to stderr)'
printf '\n'
else
file=""
shift 1
show_header=true
if [ "" = "--supress-header" ]; then show_header=false; shift 1; fi;
if $show_header
then
printf ' -------------------------------------------------------------------------------------------------------------\n' 1>&2
printf ' ldd-nonnative: find all dependencies of a (potentially) non-native binary %s\n' "$file" 1>&2
printf ' -------------------------------------------------------------------------------------------------------------\n' 1>&2
fi
search_path="$@"
find_dependencies $file
printf '\t%s\n' "${found_deps[@]}"
fi
# ❤ copyheart, shelleybutterfly, 2014
# love is never subject to the low; please copy and share with love :)
# contact information:
# shelleybutterfly@mojoprocode.com
# I hereby dedicate this software to the public domain in all jurisdictions
# where possible. In other jurisdictions, I license it to you under your
# choice of permissive license, as defined by the Open Source Institute (OSI),
# found at URL http://opensource.org. Should such a license be unavailable in
# your jurisdiection, you may use any copyleft open source license, again as
# defined by OSI; and if that too is unavailable, then you are licensed this
# software under the least restrictive possible terms allowed in your
# jurisdiction.
# I request but do not require that you give credit to me, shelleybutterfly,
# which I will accept in cases of licensing other than the public domain as
# valuable consideration for your use of my software. (I love to know that
# my name is plastered all over some obscure piece of code that's at least
# appreciated by those who do see it, and I consider that more than enough
# consideration. :D) This software is provided completely as-is, and I take
# absolutely no responsibility for any damages that it may cause. It has
# not been fully tested and should be considered pre-alpha release quality,
# (that is to say, it is likely unstable and unsafe to use without your own
# validation to ensure that it meets some or any your needs without: among
# other things: melting your computer, calling your grandma at midnight,
# telling your girlfriend she's fat, and throwing your computer in the
# dishwasher to make sure it's clean, and you take full responsibility for
# doing your own testing to ensure that it suits your needs, and operates
# properly int the conditions under which you intend to use it.
# Should you not be willing to take this risk, it is highly recommended
# that you do not use this software at all, ever, and that you instead find
# a real commercial piece of software, or other warranted piece of software,
# as I can not and do not and shall not provide any warranty of fitness for
# any purpose whatsoever, even to scrub your toilet, and it's provided with
# the understanding that it will be used primarily as an educational tool
# rather than any sort of production code. I disclaim any responsibility for
# anything that may happen to you due to your use of software, even if it
# causes huge zits, a rash under your boobs that wont go away, or a burning
# sensation when you pee. Sorry, **especially** for a burning sensation when
# you pee.
# Your use of this software implies acceptance of these terms as well as
# any painful urination or other issues it may cause in your life.
# [deep breath]
# my love to you all; I hope this software was useful to you in some way; if
# you end up using it despite the dire warnings against doing so, feel free
# to drop me a note at shelleybutterfly@mojoprocode.com, as I imagine it
# will be rare enough to make my day, every time. ♥
voilà. Espérons que cela aide quelqu'un. Egads il m'a fallu beaucoup de temps pour même obtenir assez bon avec shell scripting pour être en mesure de tirer quelque chose comme ça, peu importe le fait que cela m'a pris beaucoup plus de temps que cela aurait probablement dû, alors s'il vous plaît pardonnez ce qui a probablement secoué certains d'entre vous gourous du script là-bas au cœur même de votre être. :)
un idiot a téléchargé ça. je suis sûr que ça montre des choses que la LDD ne fait pas mais ce n'est pas encore bien testé. un petit morceau de sortie est montré ci-dessous.
http://sourceforge.net/p/dep-trace /
http://sourceforge.net/projects/dep-trace/files/libdeps
devrait montrer la table de dépendance totale de ce que ldconfig (1) chargera (ou a déjà chargé) et montrer quels libs sont NOT_FOUND (c'est-à-dire pas de version ou de fichier) et ensuite aussi ce qui est effectué.
essayez, profitez. c'est très nouveau alors ne dis pas que je ne te l'ai pas dit. il a juste trouvé quelques choses ci - dessous que je ne savais pas au sujet de mon système de lib-je suis sur le point d'aller réparer cela.
# libdeps objdump -h
Experimental - see help
libdeps [objdump | ldd] [-l | file]
-l use find *.so is used on ldconfig dirs
file one file.so per line
snip...
# libdeps objdump -d
LIBTABLE
ld-linux.so.2(file)
ld-linux.so.2(GLIBC_2.0)(file)
ld-linux.so.2(GLIBC_2.1)(file)
ld-linux.so.2(GLIBC_2.0)(file)
ld-linux.so.2(GLIBC_2.3)(file)
ld-linux.so.2(GLIBC_2.1)(file)
ld-linux.so.2(GLIBC_PRIVATE)(file)
ld-linux.so.2(GLIBC_2.3)(file)
libBrokenLocale.so.1(file)
snip ...
libc.so.6 libc.so.6(file) ld-linux.so.2 ld-linux.so.2(GLIBC_2.0) ld-linux.so.2(GLIBC_2.1) ld-linux.so.2(GLIBC_PRIVATE)
snip ...
libanl.so.1 libanl.so.1(file) ld-linux.so.2 ld-linux.so.2(GLIBC_2.0) ld-linux.so.2(GLIBC_2.1) ld-linux.so.2(GLIBC_PRIVATE) libc.so.6(GLIBC_2.1.3) libc.so.6(GLIBC_2.0) libc.so.6 libc.so.6(GLIBC_2.1) libc.so.6(GLIBC_2.3) libc.so.6(GLIBC_2.2) libc.so.6(GLIBC_PRIVATE) libc.so.6(GLIBC_2.3.2) libc.so.6(GLIBC_2.1.2) libpthread.so.0(GLIBC_2.1) libpthread.so.0
libnss_db.so.2 libnss_db.so.2(file) ld-linux.so.2 ld-linux.so.2(GLIBC_2.0) ld-linux.so.2(GLIBC_2.1) ld-linux.so.2(GLIBC_PRIVATE) libc.so.6(GLIBC_2.1.3) libc.so.6(GLIBC_2.0) libc.so.6 libc.so.6(GLIBC_2.1) libc.so.6(GLIBC_2.3) libc.so.6(GLIBC_2.2) libc.so.6(GLIBC_PRIVATE) libnss_files.so.2 libnss_files.so.2(GLIBC_PRIVATE) libdb3.so.3(NOT_FOUND) libdb3.so.3(DB3_2)(NOT_FOUND)
snip...
NOT_FOUND
libctutils.so.0
libdb3.so.3
libdb3.so.3(DB3_2)
EFFECTED
libctutils.so.0 libconsole.so.0
libdb3.so.3 libnss_db.so.2
libdb3.so.3(DB3_2) libnss_db.so.2
libconsole.so.0
libnss_db.so.2
12/04/14 21:56 -0500 Thursday, December 04, 2014, 09:56:35 PM EST