Jak wypisać zależności bibliotek nie-natywnych binarnych?

Podczas tworzenia na platformę natywną, mogę użyć ldd, aby wyświetlić listę wszystkich bibliotek współdzielonych (plików. so), które zbuduję binarny plik wykonywalny, który spróbuje załadować po uruchomieniu. Ale podczas kompilacji krzyżowej Nie wiem, jak uzyskać te same informacje. ldd nie jest normalnym narzędziem binutils, takim jak strip lub ar, które może być budowane wraz z gcc do kompilacji krzyżowej, ale zamiast tego jest to tajemniczy skrypt powłoki, który najwyraźniej może działać tylko na platformie natywnej.

Więc, używając binutili cross-target narzędzia, czy jest jakiś sposób, aby uzyskać listę dynamicznie powiązanych zależności dla obcego pliku binarnego?

Author: lvella, 2012-04-07

9 answers

Czy Jest jakiś sposób, aby uzyskać listę dynamicznie powiązanych zależności dla obcego binarnego

Możesz łatwo wyświetlić bezpośrednie zależności binarne:

readelf -d a.out | grep NEEDED

 0x0000000000000001 (NEEDED)             Shared library: [librt.so.1]
 0x0000000000000001 (NEEDED)             Shared library: [libc.so.6]

Nie wiem, jak rekurencyjnie kontynuować to, aby uzyskać pełną listę (tak jak robi to ldd). Musisz ręcznie powtórzyć proces dla każdej NEEDED biblioteki.

 72
Author: Employed Russian,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-04-07 14:36:22

Możesz zrobić bash -x ldd /bin/ls, aby zrozumieć, co robi ldd. Skrypt ldd nie jest aż tak "tajemniczy". W zasadzie działa

LD_TRACE_LOADED_OBJECTS=1 /lib64/ld-linux-x86-64.so.2 /bin/ls

Używa więc dynamicznego loadera systemu (ponieważ wynik ldd zależy od rzeczywistego środowiska i systemu!). Można jednak sprawdzić za pomocą objdump -x /bin/ls dynamiczną sekcję pliku wykonywalnego, np.

% 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

Ponownie, rzeczywista zależność zależy od systemu, w którym uruchomiony jest Twój binarny (np. ponieważ mogę mieć {[7] } z własnym libc.so.6 gdzieś, co byłoby złym pomysłem).

Więc potrzebujesz krzyżowego wariantu objdump

 12
Author: Basile Starynkevitch,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-04-07 07:12:21

Podczas gdy w gdb, informacje udostępniane są podobne do ldd. Daje pełną czytelną dla człowieka informację o uruchomieniu pliku wykonywalnego.
readelf Czy ominie ścieżkę i inne informacje o bibliotekach .
readelf jest bardzo dobrym narzędziem do badania na gospodarzu. Deweloper może wybrać, że działa.

 5
Author: AjayKumarBasuthkar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-09-25 11:28:01

To mi pomogło

objdump -p /path/to/program | grep NEEDED 
 2
Author: captainchhala,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-01-09 05:46:39

Trochę za późno na ten dodatek, ale ktoś może skorzystać/wyjaśnić. Czy Flaga do readelf nie daje takiego samego wyniku jak 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

Jedyną informacją, której tu brakuje, wydaje się być pełna ścieżka, na której znajdują się te biblioteki.

Z drugiej strony, Narzędzia wymienione do tej pory są przydatne tylko wtedy, gdy instalacja działa. Moje najczęstsze problemy to:

  1. Instalowanie programu (głównie przez rpm), który nie uruchamia się lub ulega awarii podczas uruchamiania. W jakiś sposób myślę, że jest to związane z niekompatybilnością bibliotek, ale nie znalazłem łatwego sposobu sprawdzenia tych rzeczy przed instalacją programu (ani po)
  2. w próbie pokonania (1), Czasami uciekałem się do pobierania źródeł i kompilowania lokalnie. Typowy skrypt configure jest częściowo pomocny, ponieważ informuje, których bibliotek brakuje. Nie wiadomo jednak, jaka jest wymagana najniższa Wersja takich bibliotek

Can ktoś rzucił trochę światła na te problemy? BTW, próbowałem czytać instrukcje instalacji i uwagi do wydania, ale prawie zawsze nie są wystarczające.

Dobry przykład może umieścić wszystko w kontekście, więc spróbuj skompilować Cinelerra.

 1
Author: juan-pensante,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-03-24 09:22:45

Według projektu ldd może być wykonywane tylko na obiekcie docelowym. Możliwe jest jednak naśladowanie zachowania ldd za pomocą readelf. Skrypt o nazwie `xldd' został opracowany w projekcie crosstool-ng. Niezależna wersja tego skryptu jest dostępna tutaj:

Https://gist.github.com/jerome-pouiller/c403786c1394f53f44a3b61214489e6f

 1
Author: Jezz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-11-17 16:25:15

Aby wyświetlić zależność bibliotek współdzielonych od nie natywnego pliku binarnego, możesz wypróbować następujące narzędzie: http://www.mathembedded.com/component/k2/item/1-cross-ldd.html

Używam go na SH4 i MIPS. Jak podano w innej odpowiedzi, możesz osiągnąć to samo za pomocą wyjścia readelf i pętli rekurencyjnej, ale nigdy nie próbowałem sam od czasu istnienia cross-ldd.

 0
Author: Patrice Tisserand,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-05-12 09:03:06

Przepraszam, że robię wątek zombie, ale pracuję nad kilkoma rzeczami dla mojego routera OpenWRT i chciałem sprawdzić niektóre zależności, aby sprawdzić, czy mam wystarczająco dużo miejsca na partycji jffs2, aby skopiować tylko e2fsck. Krótka odpowiedź: nie.avi .

Anyhoo, zrobiłem mały skrypt, który wykorzystuje zaakceptowaną odpowiedź plus niektóre (prawdopodobnie zbyt słowne) grep rozmowy i z małym machaniem ręką i łzami jednorożca (nie martw się, to były łzy szczęścia!) Udało mi się ułożyć następujący skrypt, który daje wszystkie zależności. Jestem pewien, że jest dużo miejsca na poprawę zwłaszcza re: pętle i rekurencja, a także fakt, że to wszystko jest cały czas bashisms (tj. indeksowane tablice), ale to przynajmniej nominalnie działa dla mnie: {]}

#!/bin/bash

declare -a search_path
declare -a found_deps

find_dependencies() {
    local file="$1"
    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 $0)"
    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="$1"
    shift 1

    show_header=true

    if [ "$1" = "--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:
# [email protected]

# 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 [email protected], as I imagine it
# will be rare enough to make my day, every time. ♥
No i proszę. Mam nadzieję, że to komuś pomoże. Egady Zajęło mi dużo czasu, aby nawet uzyskać wystarczająco dobry z shell scripting, aby być w stanie wyciągnąć coś takiego off, nieważne, że zajęło mi znacznie dłużej niż to prawdopodobnie powinienem, więc proszę wybaczyć to, co wstrząsnęło niektórymi z was Guru scenariuszy do samego rdzenia waszej istoty. :)
 0
Author: shelleybutterfly,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 11:54:50

Some depends idiot just uploaded this. jestem pewien, że pokazuje rzeczy, których LDD nie ma, ale nie jest jeszcze dobrze przetestowany. poniżej pokazano mały fragment wyjścia.

Http://sourceforge.net/p/dep-trace/

Http://sourceforge.net/projects/dep-trace/files/libdeps

Powinna pokazywać całkowitą tabelę zależności tego, co ldconfig (1) załaduje (lub już załadował) i pokazuje, które biblioteki nie są_found (tzn. brak wersji lub pliku), a następnie również to, co jest wykonywane.

Spróbuj, smacznego. jest bardzo nowy, więc nie mów, że Ci nie powiedziałem. po prostu znalazłem kilka rzeczy, których nie wiedziałem o moim systemie lib - właśnie idę to naprawić.

# 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
 -3
Author: slackguy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-12-05 03:57:25