Files
nixpkgs/pkgs/development/python-modules/angr/tests/smoke.py
Connor Nelson ed3c381359 python3Packages.angr: 9.2.193 -> 10.0.4
Build the bundled Rust Claripy implementation with Nixpkgs' Z3 and
upstream Unicorn. Support the existing cxxheaderparser and LMDB versions.
Add a core analysis smoke test, expose the llm and telemetry optional
dependencies, and retain the upstream MCP launcher.

https://github.com/angr/angr/releases/tag/v10.0.4

Assisted-by: OpenAI Codex (GPT-6)
2026-10-17 21:48:07 +00:00

103 lines
3.1 KiB
Python

import os
import sys
from importlib.metadata import version
import angr
import archinfo
import cle
import pypcode
import pyvex
import sqlalchemy
import unicorn
from angr import claripy
from angr.angrdb import AngrDB
from angr.protos import primitives_pb2
binary = os.path.realpath(sys.argv[1])
expected_version = sys.argv[2]
for distribution in ("angr", "archinfo", "cle", "pyvex"):
assert version(distribution) == expected_version
assert angr.__version__ == expected_version
assert archinfo.ArchAMD64().bits == 64
assert unicorn.__version__
# Native Claripy and Z3.
x = claripy.BVS("x", 32)
solver = claripy.Solver()
solver.add((x * 3) + 1 == 22)
assert solver.eval(x, 1) == [7]
# Native Rust extension and generated protobuf modules.
assert angr.rustylib.__file__.endswith(".so")
edge = primitives_pb2.Edge()
edge_bytes = edge.SerializeToString()
assert primitives_pb2.Edge.FromString(edge_bytes) == edge
# ELF loading, symbol lookup, VEX lifting, disassembly, and CFG recovery.
project = angr.Project(binary, auto_load_libs=False)
assert isinstance(project.loader.main_object, cle.ELF)
choose_symbol = project.loader.find_symbol("choose")
assert choose_symbol is not None
choose_addr = choose_symbol.rebased_addr
block = project.factory.block(choose_addr)
assert isinstance(block.vex, pyvex.IRSB)
assert block.vex.statements
assert block.capstone.insns
cfg = project.analyses.CFGFast(normalize=True)
choose_function = cfg.kb.functions.function(addr=choose_addr)
assert choose_function is not None
assert choose_function.name == "choose"
decompiled = project.analyses.Decompiler(choose_function, cfg=cfg.model)
assert decompiled.codegen is not None
assert "choose" in decompiled.codegen.text
# Execute the recovered function with a symbolic argument and solve for the
# branch returning 42.
symbolic_arg = claripy.BVS("symbolic_arg", 32)
state = project.factory.call_state(choose_addr, symbolic_arg)
simgr = project.factory.simulation_manager(state)
simgr.run()
return_value = project.factory.cc().RETURN_VAL
winning = [
deadended
for deadended in simgr.deadended
if deadended.solver.satisfiable(
extra_constraints=[return_value.get_value(deadended) == 42]
)
]
assert winning
assert (
winning[0].solver.eval(
symbolic_arg, extra_constraints=[return_value.get_value(winning[0]) == 42]
)
== 0x1337
)
# Exercise Unicorn acceleration for a real binary block.
unicorn_state = project.factory.entry_state(add_options=angr.options.unicorn)
unicorn_state.unicorn.cooldown_nonunicorn_blocks = 0
unicorn_simgr = project.factory.simulation_manager(unicorn_state)
unicorn_simgr.run(n=1)
assert unicorn_simgr.active
assert any(
"Unicorn" in description
for description in unicorn_simgr.active[0].history.descriptions
)
# Exercise pypcode independently of the VEX engine.
pcode = pypcode.Context("x86:LE:64:default")
translation = pcode.translate(b"\x90\xc3", 0x1000)
assert translation.ops
# Exercise the optional angrDB dependency used by angr-management.
assert sqlalchemy.__version__
assert AngrDB is not None
print(
"angr loader, VEX, CFG, decompiler, symbolic execution, Unicorn, p-code, "
"Rust, protobuf, and angrDB: OK"
)