How to list library dependencies of a non-native binary?

后端 未结 9 871
孤城傲影
孤城傲影 2020-12-12 16:03

When developing for native platform, I can use ldd to list all the shared libraries (.so files) a binary executable I build will try to load upon start-up. But when cross-co

9条回答
  •  情歌与酒
    2020-12-12 16:45

    Sorry to make a zombie thread, but I am working on some things for my OpenWRT router and wanted this to check some dependencies to see if I had enough space on my jffs2 partition to copy over just e2fsck. Short answer: nope.avi.

    Anyhoo, I made a little script that uses the accepted answer plus some (probably overly verbose) grep calls and with a little hand waving and some unicorn tears (no worries, they were happy tears!) I managed to put together the following script that gives you all the dependencies. I'm sure there's lots of room for improvement especially RE: the loops and recursion, as well as the fact that it's all bashisms all the time (i.e. indexed arrays) but this is at least nominally working for me:

    #!/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  [ --supress-header ] [  ... ]\n' "$(basename $0)"
        printf '\twhere\n'
        printf '\t\t is the name of a file to find the dependencies of.\n'
        printf '\t\t[  ... ] 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:
    # 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. ♥
    

    So, there ya go. Hope it helps someone. Egads it's taken me a long time to even get good enough with shell scripting to be able to pull something like this off, nevermind the fact that it took me much longer than it probably should have, so please forgive what has likely shaken some of you script gurus out there to the very core of your being. :)

提交回复
热议问题