Skip to main content

pybingraph

Latest release Development version Python versions

pybingraph is a binary-inspection service and library built on angr. It reads function symbols from a binary and renders per-function control-flow graphs (CFGs) as SVG or DOT.

Supported binary formats include ELF executables, shared libraries and relocatable objects, and Windows PE executables and DLLs. The corpus covers x86/x86-64, ARM/Thumb/AArch64, MIPS, PowerPC, RISC-V and s390x. Instruction decoding and indirect-transfer proofs depend on the architecture and binary; not every format/architecture combination has the same analysis coverage.

The default custom strategy constructs a function-bounded CFG directly from Capstone decoding and VEX control-flow proofs, without a CFGFast seed graph. It resolves proven indirect transfers, recovers ELF exception paths, and keeps unresolved targets and additionally discovered code explicit.

CFG Examples

These are real custom-mode CFGs from the playground binaries. Comments are disabled for compact previews, matching the golden-test configuration; they will be shown in the browser as block annotations. Click a thumbnail to inspect the full-size SVG.

Example Description Preview
Resolved Switch Dispatch func_0 in x86_64/cfg_switches. Red and green edges distinguish the two conditional outcomes; orange edges identify proven indirect-jump targets. Here the cases converge on a shared return block; the same branch colors also make loops and separate return paths visible in other CFGs. x86-64 switch CFG with resolved jump-table targets
Exception Paths and Unresolved Control Flow drop_in_place<ReferenceKind> in x86_64/fmt-rust. Dotted gray edges show exception paths. Dashed orange edges keep unresolved targets and disconnected-code recovery hints explicit rather than claiming proven reachability. Rust CFG with exception paths, an unresolved jump and recovered regions
Vectorized String Search __strchr_evex at 0x42b200 in x86_64/langdetect_clang. AVX-512 vector loads and comparisons, mask registers and a scanning loop remain visible in the disassembly. x86-64 AVX-512 string-search CFG
RISC-V Control Flow sodium_allocarray at 0x3208 in riscv/server_eapp.eapp_riscv. RV64 compressed instructions, allocation-size guards, calls and return paths use the same CFG presentation. RISC-V allocation CFG with compressed instructions and conditional branches

TODOs for this library are:

  • Render call graph (CG) of all functions in a binary.
  • Render data dependency graph (DDG) for instructions in a basic block.
  • Graph coloring from execution counts, after adding support for profile information.

Requirements

For the container option below, only Docker is required on the host. A native Python installation requires:

  • Python 3.12 or later
  • uv
  • The Graphviz dot executable for rendered image formats

On macOS:

brew install graphviz

Setup

Run with Docker

Release images are published to GitHub Container Registry for Linux AMD64 and ARM64. Docker chooses the appropriate platform automatically. They include Python, runtime dependencies and Graphviz, but no playground binaries.

docker run --rm --name bingraph \
  -p 127.0.0.1:9000:8000 \
  --mount type=bind,src=/absolute/path/to/binaries,dst=/binaries,readonly \
  ghcr.io/manelfx/pybingraph:latest

Replace the host directory with your binary directory and 9000 with the local port you want. Open http://127.0.0.1:9000/docs for interactive API documentation, or /symtab?filepath=your-binary for the symbol table. Paths remain relative to the mounted directory. The image runs as a non-root user; mounted files and their parent directories must be readable/searchable by that user.

Use a numeric release tag instead of latest to select a specific version. docker run --rm ghcr.io/manelfx/pybingraph:latest --version reports its version. Configure global settings with environment flags such as -e BINGRAPH_DEMANGLE=true or -e BINGRAPH_COMMENTS=false before the image name. The server listens on 0.0.0.0:8000 inside the container; the example publishes it only on the host's loopback interface. It has no authentication and should not be exposed directly to an untrusted network.

Install a release

Published releases can be installed from PyPI with their Python dependencies:

uv venv --python 3.12
uv pip install pybingraph

On macOS/Linux, activate that environment and run the installed command:

source .venv/bin/activate
bingraph --version
bingraph --root /path/to/your/binaries server

No repository checkout is required. Install the Graphviz dot executable separately; wheels do not bundle system tools or the optional playground corpus. Alternatively, download a wheel (.whl) from a GitHub release and install it with uv pip install ./pybingraph-*.whl in the environment above.

Work from a checkout

Install the runtime dependencies:

uv sync

For development tools such as pytest, Ruff, and Ty:

uv sync --extra dev

Playground binaries

The optional playground corpus is used by unit tests, golden CFG tests and the examples below. Fetch it with:

./scripts/fetch_playground.sh

It is cloned into ./angr-binaries/; the binaries themselves live under ./angr-binaries/tests/. The helper also fetches pinned example fixtures from angr-utils into tests/samples/ within that corpus. Existing samples are verified, not overwritten.

Run Bingraph

All binary paths are relative to --root and are constrained to remain below that directory.

Check the version from the CLI or Python:

uv run bingraph --version
uv run python -c 'import bingraph; print(bingraph.__version__, bingraph.__commit__)'

Server

Start the local web server:

uv run bingraph --root ./angr-binaries/tests server

Then open a symbol table or CFG in a browser:

http://127.0.0.1:8000/symtab?filepath=samples/ais3_crackme
http://127.0.0.1:8000/cfg?filepath=samples/ais3_crackme&function=0x40043c

Useful server options include --port, --debug, --no-comments, and --cfg-mode none|custom. Run uv run bingraph --help for the full CLI.

Use the global --demangle option (or BINGRAPH_DEMANGLE=true) to display demangled C++ and Rust names in symbol tables, CFG headers, and comments. It defaults to false. CFG names are shortened after demangling, keeping block offsets; symbol-table names remain full. Addresses, assembly operands, and analysis metadata are unchanged. Unsupported names are kept as-is.

Client

The client subcommand makes an in-process request, so it is useful for scripting and does not require a separately running server:

uv run bingraph --no-comments --root ./angr-binaries/tests \
  client --endpoint /cfg --filepath samples/ais3_crackme \
  --function 0x40043c --format raw

HTTP API

The HTML routes are intended for browser use, while /api/... routes return JSON.

Route Result
GET /symtab?filepath=<path> HTML table of function symbols
GET /api/symtab?filepath=<path> {"items": [...]} function-symbol response
GET /cfg?filepath=<path>&function=<addr> SVG CFG
GET /api/cfg?filepath=<path>&function=<addr>&format=dot {"graph": "..."} CFG response

function accepts either decimal or 0x-prefixed hexadecimal addresses. CFG JSON responses support format=svg|dot|raw|xdot; raw is unprocessed DOT, dot runs Graphviz's DOT output backend, and xdot includes drawing metadata. Binary formats such as PNG/PDF are not supported by the string-returning API.

CFG routes also accept optional mode=none|custom, comments=true|false, dfs=true|false, and exits=never|jump|always query parameters. A request value overrides the corresponding application setting for that render only. Both symbol-table and CFG routes also accept demangle=true|false, overriding the global setting for that request. Symbol-table links retain this override.

Configuration

Settings are Pydantic settings: they can be supplied as CLI options, BINGRAPH_-prefixed environment variables, or values in .bingraphenv.

For example:

BINGRAPH_ROOT=./angr-binaries/tests \
BINGRAPH_CFG_MODE=custom \
BINGRAPH_COMMENTS=false \
uv run bingraph server

CFG modes:

  • custom (default): independently decode and prove bounded control flow, then recover eligible disconnected code without treating it as proven entry-reachable code.
  • none: return the bounded CFGFast graph without custom construction; useful for comparison and diagnostics.

Disconnected-code recovery is part of custom mode. It scans only eligible explicitly sized functions with unresolved jumps, rejects padding and known data, and shows selected rejoining or validated return/trap/non-returning-exit regions behind dashed-orange UnresolvableEntrySource edges. These are discovery hints, not proven jump targets. Custom summaries separate discovered, entry-connected, and disconnected instruction counts.

Development

The Makefile wraps the standard development commands:

make                 # fast unit tests
make format          # rewrite source and tests with Ruff formatting
make check           # formatting, linting, type checking, and unit tests

The commands behind make check are also available independently:

make format-check
make lint
make typecheck
make units
make coverage

make coverage runs both unit tests and curated golden checkpoints, prints a terminal summary, and writes a browsable report to htmlcov/index.html.

License

pybingraph's original code is licensed under the BSD 2-Clause License. Copied or adapted code retains the upstream copyright and license notices in NOTICE. Dependencies, playground binaries and their disassembly examples remain subject to their respective upstream terms.

Troubleshooting

Optional Unicorn warning on macOS

If startup reports:

angr.state_plugins.unicorn_engine | failed loading "unicornlib.dylib"

Unicorn is an optional angr acceleration dependency. The bounded CFGFast and custom CFG workflows used by Bingraph still work without it. Install a compatible Unicorn build only if you specifically need Unicorn-backed symbolic execution.

Metadata

Release files for pybingraph 0.2.5

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for pybingraph 0.2.5
File Size Uploaded
pybingraph-0.2.5.tar.gz 162.2 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for pybingraph 0.2.5
File Interpreter ABI Platform
pybingraph-0.2.5-py3-none-any.whl Python 3 none any Details

Total release size: 356.1 kB

Release files / pybingraph-0.2.5.tar.gz

Download URL pybingraph-0.2.5.tar.gz
Size 162.2 kB
Tags Source
SHA-256 checksum
How to use checksums
d31ed1b3981588ee5d9ffd86aed1246472bf4cf87a2ca0a7d591735b85f9ddf4
BLAKE2b-256 checksum
How to use checksums
302779637bd565e299f1d274e8bfc8329d92e033640bd5aefe5c435237f47876
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 17, 2026.

Transparency log

Release files / pybingraph-0.2.5-py3-none-any.whl

Download URL pybingraph-0.2.5-py3-none-any.whl
Size 193.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
d72d2c0484c207a401269251b10ae9d4e385fc1f736117090eba4c26d42ff13a
BLAKE2b-256 checksum
How to use checksums
b63aaa35210b8fbf465af802c01fc008e85bcea1317d12ffc85c320a9eca2f8d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 17, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.2.5 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page