Introduction
angr is a platform-agnostic binary analysis framework built in Python by the Computer Security Lab at UC Santa Barbara. It combines static analysis, dynamic symbolic execution, and control flow graph recovery to enable automated reasoning about compiled programs. angr is widely used in academic research, CTF competitions, and professional vulnerability analysis.
What angr Does
- Performs symbolic execution to explore program paths and find inputs that reach specific code locations
- Recovers control flow graphs from stripped binaries without source code or debug symbols
- Lifts machine code to an intermediate representation (VEX IR) for architecture-independent analysis
- Solves path constraints using integrated SMT solvers to generate concrete test inputs
- Supports analysis of binaries for x86, x64, ARM, AARCH64, MIPS, and PowerPC architectures
Architecture Overview
angr is built on a layered architecture. CLE (CLE Loads Everything) handles binary loading and memory mapping for multiple executable formats. The archinfo library provides architecture specifications. PyVEX lifts native machine code to the VEX intermediate representation used by Valgrind. The SimEngine layer executes VEX IR symbolically, maintaining a symbolic state that tracks registers, memory, and path constraints. Claripy provides the constraint solving backend, interfacing with Z3 and other SMT solvers. On top of these, angr provides high-level analyses including CFG recovery, data dependency tracking, and vulnerability pattern detection.
Self-Hosting & Configuration
- Install in an isolated virtual environment to avoid dependency conflicts with system packages
- Use
auto_load_libs=Falsewhen loading projects to avoid analyzing shared library code - Configure the SimulationManager exploration strategy (BFS, DFS, or custom) based on the analysis goal
- Extend angr with custom SimProcedures to model library functions or system calls
- The angr-management GUI provides a visual interface for interactive binary exploration
Key Features
- Symbolic execution engine with configurable exploration strategies for automated path finding
- Value-set analysis and reaching definition analysis for data flow tracking
- SimProcedures framework for modeling library calls without analyzing library binaries
- Integration with the Firmalice and Karonte frameworks for firmware analysis
- Extensive Python API allowing custom analysis scripts and tool integration
Comparison with Similar Tools
- Ghidra: Focuses on interactive disassembly and decompilation with a GUI; angr emphasizes automated analysis and symbolic execution via Python scripting
- Binary Ninja: A commercial reverse engineering platform with its own IL; angr is open-source and centered on symbolic execution rather than manual RE
- KLEE: A symbolic execution engine that operates on LLVM bitcode; angr works directly on compiled binaries without requiring source code
- Manticore (Trail of Bits): Another symbolic execution tool for binaries and smart contracts; angr offers broader architecture support and a larger research community
- Triton: A dynamic binary analysis library with concolic execution; angr provides a more complete platform with CFG recovery and higher-level analyses
FAQ
Q: What architectures does angr support? A: angr supports x86, x86-64, ARM, AARCH64, MIPS, MIPS64, PPC, PPC64, and S390X through its VEX IR lifting layer.
Q: How does angr handle the path explosion problem in symbolic execution? A: angr provides multiple exploration strategies (DFS, BFS, directed exploration) and supports state merging techniques. Users can also constrain exploration by hooking functions, setting avoid addresses, or limiting loop iterations.
Q: Can angr analyze firmware images? A: Yes. angr can load raw binary blobs with manually specified base addresses and architectures. The angr-platforms project adds support for additional embedded architectures.
Q: Is angr suitable for large-scale production binaries? A: angr works best for targeted analysis of specific functions or paths. Full symbolic exploration of large binaries can be resource-intensive, so most practical uses involve constraining the analysis scope.
Sources
- Repository: https://github.com/angr/angr
- Documentation: https://docs.angr.io/