Library / SDK
angr/angr avatar
angr/angr

angr: A Python Framework for Automated Binary Analysis and Symbolic Execution

A powerful and user-friendly binary analysis platform!

9,114 stars1,192 forksPythonBSD-2-Clause

At a glance

What is it?
angr is a Python library from the Computer Security Lab at UC Santa Barbara and SEFCOM at Arizona State University that lets you load any binary and perform disassembly, symbolic execution, control-flow analysis, value-set analysis, and decompilation through a scripting API. It is aimed at security researchers, CTF competitors, and automated vulnerability-finding tools.
Who is it for?
angr is the right tool for security researchers and CTF competitors who need to automate reasoning over binary programs: finding inputs that reach a target code path, recovering control flow, or automatically identifying reachable vulnerability states. It is not designed for manual reverse engineering workflows; tools like Ghidra are better suited for that.
Can I use it commercially?
Yes. BSD-2-Clause is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 2 days ago.
What is it written in?
Mainly Python, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 27, 2026, and from our analysis. They are not legal advice.

Editorial analysis

What angr Is and the Problems It Solves

angr is a platform-agnostic binary analysis framework. The core use case is automated reasoning over compiled programs without access to source code. A security researcher who wants to know what input causes a binary to reach a specific address, or whether a buffer overflow is reachable from a given program point, can express that question as an angr script and let the framework explore the program states.

The framework comes from academic research: it was developed at the Computer Security Lab at UC Santa Barbara and at SEFCOM at Arizona State University, with contributions from Shellphish (a competitive CTF team) and the open source community. CTF competition challenges that involve reverse engineering or binary exploitation are a common use case, and the documentation includes examples of using angr to solve CTF challenges.

The framework offers seven main capabilities: disassembly and IR lifting, program instrumentation, symbolic execution, control-flow analysis, data-dependency analysis, value-set analysis (VSA), and decompilation.

Installing angr: Python, Rust, and the Build Step

The quickest install path uses mkvirtualenv to create an isolated environment, then installs from PyPI:

code
mkvirtualenv --python=$(which python3) angr && python -m pip install angr

angr requires Python 3.12 or higher. It does not support earlier Python versions as of the pyproject.toml configuration. The package has a significant build step because it includes Rust extensions. The Cargo.toml defines a workspace with five Rust crates: native/angr, native/clarirs-core, native/clarirs-num, native/clarirs-vsa, and native/clarirs-z3. These crates handle the constraint solving integration (z3-solver is pinned at version 5.1.0.0) and parts of the symbolic reasoning engine.

The setup also builds unicornlib, a shared library for emulation, from a C source directory (native/unicornlib) using make or nmake. The setup.py inspects the platform (darwin for macOS, win32 for Windows, otherwise Linux) to determine the library filename. This means the install on a clean system requires a working C compiler and Rust toolchain in addition to Python.

Full install instructions are documented at https://docs.angr.io/introductory-errata/install.

Loading a Binary and Running Symbolic Execution

The most common angr operation is loading a binary with angr.Project. In an enhanced REPL like IPython, tab-autocomplete shows the available top-level methods:

python
import angr

project = angr.Project("angr-doc/examples/defcamp_r100/r100", auto_load_libs=False)

@project.hook(0x400844)
def print_flag(state):
    print("FLAG SHOULD BE:", state.posix.dumps(0))
    project.terminate_execution()

project.execute()

This example from the README hooks a specific address (0x400844) in a CTF binary called r100. When symbolic execution reaches that address, the hook function runs and prints the symbolic value of stdin (file descriptor 0) as a concrete value that would satisfy the path constraints leading to that point. The auto_load_libs=False flag prevents angr from loading the shared libraries the binary depends on, which would dramatically increase the analysis scope.

The auto_load_libs parameter is one of the most important tuning choices in a typical angr script. Loading dependent libraries increases coverage but also increases the number of execution paths to explore.

Architecture and Core Dependencies

angr's analysis pipeline lifts the target binary into VEX IR (an intermediate representation) using the pyvex library before doing any analysis. This IR lifting is what makes angr platform-agnostic: the same symbolic execution engine works on x86, x86-64, ARM, MIPS, and other architectures, because all of them are lifted to the same IR before analysis.

Disassembly uses capstone, which is pinned at version 5.0.9. Symbolic constraint solving uses z3-solver, pinned at version 5.1.0.0. The binary loading layer is handled by cle. The archinfo library provides architecture definitions. The dependency pinning is precise because the constraint solver's behavior and the VEX lifting must match the generated protobuf code; the build system generates angr/protos/*_pb2.py from .proto files at build time using grpcio-tools (pinned at ~1.80.0).

The overall dependency list in pyproject.toml is long and specific. Engineers who hit dependency conflicts on an existing Python environment will find that the recommended virtualenv approach is not merely a best practice but a practical necessity, since the pinned versions conflict with many other packages.

Path Explosion: The Core Limitation of Symbolic Execution

Symbolic execution can explore all possible paths through a program simultaneously by treating inputs as symbolic (unknown) values and tracking the constraints that each execution path accumulates. The fundamental problem is that the number of paths grows exponentially with the number of branches in the program.

A loop that runs N times with a conditional branch inside it produces 2^N possible paths. A realistic binary with thousands of branches can produce more paths than any computer can explore in a tractable time. This path explosion problem is inherent to symbolic execution and is not specific to angr. The README acknowledges this by framing angr as a tool for specific analysis tasks (reaching a target address, finding an input that triggers a crash) rather than as an exhaustive verifier.

Practical angr usage requires analysis-specific tuning: setting exploration limits, using the avoid parameter to exclude uninteresting code paths, and using concolic execution (a hybrid that mixes concrete and symbolic values) to reduce the state space. The angr documentation covers these techniques, but the README itself does not.

Comparison with Ghidra and Maintenance

Ghidra is a widely known binary analysis and reverse engineering tool released as open source by the NSA. The difference in approach is fundamental: Ghidra is a graphical workbench designed for manual reverse engineering, where a human analyst explores the disassembly, adds comments, renames functions, and builds understanding of the binary incrementally. angr is a Python scripting library designed for automated analysis, where a researcher writes a script that programs the framework to explore states and answer a specific question.

Ghidra is better suited for understanding what an unknown binary does. angr is better suited for answering a specific question about a binary's behavior automatically. The two tools are frequently used together: Ghidra to understand the binary structure, angr to automate the exploitation or verification step.

The last push to angr was on 2026-09-27. The project is released under BSD-2-Clause. The repository has no GitHub releases; development uses rolling pushes from the master branch.

Editorial conclusion

angr is the right tool for security researchers and CTF competitors who need to automate reasoning over binary programs: finding inputs that reach a target code path, recovering control flow, or automatically identifying reachable vulnerability states. It is not designed for manual reverse engineering workflows; tools like Ghidra are better suited for that. Before installing, confirm Python 3.12 or higher and allocate time for the build step, which compiles Rust extensions and builds unicornlib from source.

Frequently asked questions

What does angr mean?

The README does not document what 'angr' stands for as an abbreviation. The project is named after the framework itself, which originated at the Computer Security Lab at UC Santa Barbara and SEFCOM at Arizona State University.

How do I install angr?

The README recommends creating a virtualenv first: mkvirtualenv --python=$(which python3) angr, then running python -m pip install angr. Full install instructions are at https://docs.angr.io/introductory-errata/install. The install builds Rust extensions and a C shared library, so a compiler and Rust toolchain must be available.

Is angr hard to learn?

The README does not assess the learning curve. The framework covers several advanced concepts including symbolic execution, VEX IR, and constraint solving. The documentation at https://docs.angr.io includes introductory concepts and CTF examples that are a practical starting point, and the repository has an awesome-angr list of community resources.

How does angr work?

angr lifts binary code into VEX intermediate representation using pyvex, then uses symbolic execution to explore program states. Inputs are treated as symbolic (unknown) values; the constraint solver (z3) tracks what constraints must hold for each execution path. When a target condition is reached, z3 solves the constraints to produce a concrete input that satisfies them.

Official sources

  1. angr/angr on GitHub
  2. Issues
  3. License: BSD-2-Clause
  4. Project website
  5. README
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/angr-angr.svg)](https://hysenlabs.com/projects/angr-angr)