Skip to main content
The Project class is the main entry point for the angr binary analysis framework. It contains a set of binaries and their relationships, and provides access to analyses, symbolic execution, and program manipulation capabilities.

Class Signature

class Project:
    def __init__(
        self,
        thing,
        default_analysis_mode=None,
        ignore_functions=None,
        use_sim_procedures=True,
        exclude_sim_procedures_func=None,
        exclude_sim_procedures_list=(),
        arch=None,
        simos=None,
        engine=None,
        load_options: dict[str, Any] | None = None,
        translation_cache=True,
        selfmodifying_code: bool = False,
        support_selfmodifying_code: bool | None = None,
        store_function=None,
        load_function=None,
        analyses_preset=None,
        concrete_target=None,
        eager_ifunc_resolution=None,
        cache_limits: dict[str, int | None] | None = None,
        **kwargs,
    )

Parameters

thing
str | Path | CLE Loader | IOBase
The path to the main executable object to analyze, or a CLE Loader object, or a file-like object.
default_analysis_mode
str
default:"symbolic"
The mode of analysis to use by default. Defaults to ‘symbolic’.
ignore_functions
list[str]
A list of function names that, when imported from shared libraries, should never be stepped into in analysis (calls will return an unconstrained value).
use_sim_procedures
bool
default:"True"
Whether to replace resolved dependencies for which simprocedures are available with said simprocedures.
exclude_sim_procedures_func
Callable
A function that, when passed a function name, returns whether or not to wrap it with a simprocedure.
exclude_sim_procedures_list
list[str]
default:"()"
A list of functions to not wrap with simprocedures.
arch
str | archinfo.Arch
The target architecture (auto-detected otherwise).
simos
str | SimOS
A SimOS class or name to use for this project.
engine
SimEngine
The SimEngine class to use for this project.
translation_cache
bool
default:"True"
If True, cache translated basic blocks rather than re-translating them.
selfmodifying_code
bool
default:"False"
Whether to aggressively support self-modifying code. When enabled, emulation will try to read code from the current state instead of the original memory.
analyses_preset
PluginPreset
The plugin preset for the analyses provider (i.e. Analyses instance).

Attributes

arch
archinfo.Arch
The architecture of the binary.
analyses
AnalysesHub
The available analyses for this project.
entry
int
The program entrypoint address.
factory
AngrObjectFactory
Provides access to important analysis elements such as simulation managers, states, and blocks.
filename
str
The filename of the executable.
loader
cle.Loader
The CLE program loader containing all loaded objects.
kb
KnowledgeBase
The project’s knowledge base, containing recovered information about the program.
storage
defaultdict[list]
Dictionary of things that should be loaded/stored with the Project.
llm_client
LLMClient
The LLM client for this project (lazy-initialized from environment variables).

Methods

Hooking Methods

Signature:
def hook(self, addr, hook=None, length=0, kwargs=None, replace: bool | None = False)
Hook a section of code with a custom function. This is used internally to provide symbolic summaries of library functions, and can be used to instrument execution or to modify control flow.When hook is not specified, it returns a function decorator that allows easy hooking.Usage:
@proj.hook(proj.entry)
def my_hook(state):
    print("Welcome to execution!")
Parameters:
addr
int
The address to hook.
hook
SimProcedure | Callable
A SimProcedure instance or a function to run at the given address.
length
int
default:"0"
The number of bytes that will be skipped by executing the hook.
kwargs
dict
Keyword arguments passed to the procedure’s run method.
replace
bool | None
default:"False"
Control behavior when address is already hooked. True: silently replace. False: warn and don’t replace. None: warn and replace.
Signature:
def is_hooked(self, addr) -> bool
Returns True if addr is hooked.Parameters:
addr
int
An address to check.
Returns: bool - True if addr is hooked, False otherwise.
Signature:
def hooked_by(self, addr) -> SimProcedure | None
Returns the current hook for addr.Parameters:
addr
int
An address.
Returns: SimProcedure | None - The hook at that address, or None if not hooked.
Signature:
def unhook(self, addr)
Remove a hook.Parameters:
addr
int
The address of the hook to remove.
Signature:
def hook_symbol(self, symbol_name, simproc, kwargs=None, replace: bool | None = None)
Resolve a dependency in a binary by symbol name and hook that address.Parameters:
symbol_name
str | int
The name of the symbol to hook, or an address.
simproc
SimProcedure
The SimProcedure instance to hook with.
kwargs
dict
Keyword arguments for the SimProcedure.
replace
bool | None
Whether to replace existing hooks.
Returns: int - The address of the hooked symbol.
Signature:
def is_symbol_hooked(self, symbol_name) -> bool
Check if a symbol is already hooked.Parameters:
symbol_name
str
Name of the symbol.
Returns: bool - True if the symbol is hooked, False otherwise.
Signature:
def unhook_symbol(self, symbol_name) -> bool
Remove the hook on a symbol.Parameters:
symbol_name
str
Name of the symbol to unhook.
Returns: bool - True if successful, False otherwise.

Execution Methods

Signature:
def execute(self, *args, **kwargs)
A symbolic execution helper in the simple style. Begins symbolic execution and returns when finished or terminated.This function can be run in three ways:
  • With no parameters: begins execution from the entrypoint
  • With a “state” parameter: begins execution from that state
  • With arbitrary kwargs: passed to project.factory.full_init_state
Returns: SimulationManager - The resulting simulation manager.
Signature:
def terminate_execution(self)
Terminates a symbolic execution that was started with Project.execute().

Cache Limit Methods

Signature:
def get_function_cache_limit(self) -> int | None
Get the cache limit for function-level caches.Returns: int | None - The cache limit, or None for disabling the cache.
Signature:
def get_cfg_node_cache_limit(self) -> int | None
Get the cache limit for CFG node caches.Returns: int | None - The cache limit, or None to disable the cache.
Signature:
def get_cfg_edge_cache_limit(self) -> int | None
Get the cache limit for CFG edge caches.Returns: int | None - The cache limit, or None to disable the cache.

Knowledge Base Methods

Signature:
def get_kb(self, name: str) -> KnowledgeBase
Get or create a named knowledge base.Parameters:
name
str
The name of the knowledge base.
Returns: KnowledgeBase - The requested knowledge base.

Helper Function

Signature:
def load_shellcode(
    shellcode: bytes | str,
    arch,
    start_offset=0,
    load_address=0,
    thumb=False,
    **kwargs
) -> Project
Load a new project based on a snippet of assembly or bytecode.Parameters:
shellcode
bytes | str
The data to load, as either a bytestring of instructions or a string of assembly text.
arch
str | archinfo.Arch
The name of the arch to use, or an archinfo class.
start_offset
int
default:"0"
The offset into the data to start analysis.
load_address
int
default:"0"
The address to place the data in memory.
thumb
bool
default:"False"
Whether this is ARM Thumb shellcode.
Returns: Project - A new Project instance.

Example Usage

import angr

# Load a binary
proj = angr.Project('/bin/ls')

# Access basic properties
print(f"Architecture: {proj.arch.name}")
print(f"Entry point: {proj.entry:#x}")
print(f"Filename: {proj.filename}")

# Hook a function
@proj.hook(0x400000)
def my_hook(state):
    print(f"Hit hook at {state.addr:#x}")
    state.regs.rax = 42

# Create a state and simulate execution
state = proj.factory.entry_state()
simgr = proj.factory.simulation_manager(state)
simgr.run()

# Perform analysis
cfg = proj.analyses.CFGFast()
print(f"Found {len(cfg.functions)} functions")

Build docs developers (and LLMs) love