Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

introduces bap dependencies command #1294

Merged
merged 12 commits into from
Apr 15, 2021
Merged

Conversation

ivg
Copy link
Member

@ivg ivg commented Apr 15, 2021

The command outputs program dependencies such as libraries and symbols. The information is collected recursively with various output options, including dependency graph, YAML, JSON, and SEXP.

The information includes the list of imported libraries as well as sets of imported and exported symbols. The information could be collected recursively when the --recursive option is specified. In a recursive mode, the list of paths where to search for libraries could be specified with the --library-path option that accepts a list of paths. It is also possible to use the host ldconfig cache (or specify custom library config) via the ldconfig parameter. Information about each individual dependency is cached, so consecutive calls to bap will reuse the available information and terminate quickly.

EXAMPLES

The default format is YAML, which suits best for human consumption. Additionally it possible to use JSON or SEXP, as well as Graphviz DOT format. The tool is designed to be used together with YAML and JSON query tools, such as yq and jq, e.g.,

Getting the list of imported libraries

$ bap dependencies /bin/ls | yq e .ls.libraries -
- libc.so.6
- libselinux.so.1

Running recursively

$ bap dependencies /bin/ls --recursive

Using ldconfig for getting the local (host) library cache

$ bap dependencies /bin/ls --recursive --ldconfig

Running in a rooted environment

$ bap dependencies /bin/ls --root=/mnt/image --ldconfig='cat libs'

Note, in the example above, all paths will be prefixed with the specified root,
e.g., /bin/ls will be taken from /mnt/image/bin/ls and all paths from the
cache (or paths stored in the binary itself, like rpaths or MachO full paths to libraries) will be prefixed as well with /mnt/image effectively creating a chrooted environment.

Building the dependency graph

$ bap dependencies `which ping` -ograph | graph-easy --as boxart
                     ┌────────────────┐
                     │ libresolv.so.2 │
                     └────────────────┘
                       ▲
                       │
                       │
┌──────────────┐     ┌───────────────────────────────┐     ┌────────────────┐
│ libidn.so.11 │ ◀── │             ping              │ ──▶ │ libnettle.so.6 │
└──────────────┘     └───────────────────────────────┘     └────────────────┘
                       │                 │
                       │                 │
                       ▼                 ▼
                     ┌────────────────┐┌─────────────┐
                     │   libc.so.6    ││ libcap.so.2 │
                     └────────────────┘└─────────────┘

Getting the transitive closure of the dependency graph

$ bap dependencies `which ping` --recursive --ldconfig -ograph | graph-easy --as boxart
                     ┌────────────────┐
                     │ libresolv.so.2 │ ──────────────────────────────────┐
                     └────────────────┘                                   │
                       ▲                                                  │
                       │                                                  │
                       │                                                  │
┌──────────────┐     ┌──────────────────────────┐     ┌────────────────┐  │
│ libidn.so.11 │ ◀── │           ping           │ ──▶ │ libnettle.so.6 │  │
└──────────────┘     └──────────────────────────┘     └────────────────┘  │
  │                    │                 │              │                 │
  │                    │                 │              │                 │
  │                    ▼                 │              │                 │
  │                  ┌────────────────┐  │              │                 │
  │                  │  libcap.so.2   │  │              │                 │
  │                  └────────────────┘  │              │                 │
  │                    │                 │              │                 │
  │                    │                 │              │                 │
  │                    ▼                 ▼              │                 │
  │                  ┌──────────────────────────┐       │                 │
  └────────────────▶ │        libc.so.6         │ ◀─────┘                 │
                     └──────────────────────────┘                         │
                       │                      ▲                           │
                       │                      └───────────────────────────┘
                       ▼
                     ┌────────────────┐
                     │ ld-linux.so.2  │
                     └────────────────┘

Counting the number of imported symbols

$ bap dependencies /bin/ls | yq e '.ls.imports | length' -
115

Outputting all imported symbols

bap dependencies /bin/ls --recursive --ldconfig | yq ea '.*.imports' -

ivg added 12 commits April 13, 2021 09:19
The command will recursively analyze program dependencies (imported
names and libraries).

Right now no recursion and only elves (but other architectures should
go easier as they, unlike elf, are supported by llvm).
we are now nearly feature complete, the next step is to add support
for ldconfig and add some documentation.
@ivg ivg merged commit ab38ce6 into BinaryAnalysisPlatform:master Apr 15, 2021
@ivg ivg deleted the dependencies branch December 1, 2021 19:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant