mirror of
https://github.com/NixOS/nixpkgs.git
synced 2026-10-30 16:10:36 +00:00
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)
103 lines
3.1 KiB
Python
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"
|
|
)
|