1
0
mirror of https://github.com/angr/angr synced 2026-06-08 13:09:39 +00:00
Files
angr-angr/tests/sim/test_simulation_manager.py
pre-commit-ci[bot] 563fb5f862 [pre-commit.ci] pre-commit autoupdate (#6025)
* [pre-commit.ci] pre-commit autoupdate

updates:
- [github.com/astral-sh/ruff-pre-commit: v0.14.11 → v0.14.13](https://github.com/astral-sh/ruff-pre-commit/compare/v0.14.11...v0.14.13)
- [github.com/psf/black-pre-commit-mirror: 25.12.0 → 26.1.0](https://github.com/psf/black-pre-commit-mirror/compare/25.12.0...26.1.0)

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2026-01-19 13:37:06 -07:00

149 lines
5.1 KiB
Python
Executable File

#!/usr/bin/env python3
from __future__ import annotations
__package__ = __package__ or "tests.sim" # pylint:disable=redefined-builtin
import os
import unittest
import angr
from tests.common import bin_location
test_location = os.path.join(bin_location, "tests")
addresses_fauxware = {
"armel": 0x8524,
"armhf": 0x104C9, # addr+1 to force thumb
#'i386': 0x8048524, # commenting out because of the freaking stack check
"mips": 0x400710,
"mipsel": 0x4006D0,
"ppc": 0x1000054C,
"ppc64": 0x10000698,
"x86_64": 0x400664,
}
class TestSimulationManager(unittest.TestCase):
def _run_fauxware(self, arch, threads):
p = angr.Project(os.path.join(test_location, arch, "fauxware"), load_options={"auto_load_libs": False})
pg = p.factory.simulation_manager(threads=threads)
assert len(pg.active) == 1
assert pg.active[0].history.depth == 0
# step until the backdoor split occurs
pg2 = pg.step(until=lambda lpg: len(lpg.active) > 1, step_func=lambda lpg: lpg.prune())
assert len(pg2.active) == 2
assert any(b"SOSNEAKY" in s for s in pg2.mp_active.posix.dumps(0).mp_items)
assert not all(b"SOSNEAKY" in s for s in pg2.mp_active.posix.dumps(0).mp_items)
# separate out the backdoor and normal paths
pg3 = pg2.stash(lambda path: b"SOSNEAKY" in path.posix.dumps(0), to_stash="backdoor").move("active", "auth")
assert len(pg3.active) == 0
assert len(pg3.backdoor) == 1
assert len(pg3.auth) == 1
# step the backdoor path until it returns to main
pg4 = pg3.step(until=lambda lpg: lpg.backdoor[0].history.jumpkinds[-1] == "Ijk_Ret", stash="backdoor")
main_addr = pg4.backdoor[0].addr
assert len(pg4.active) == 0
assert len(pg4.backdoor) == 1
assert len(pg4.auth) == 1
# now step the real path until the real authentication paths return to the same place
pg5 = pg4.explore(find=main_addr, num_find=2, stash="auth").move("found", "auth")
assert len(pg5.active) == 0
assert len(pg5.backdoor) == 1
assert len(pg5.auth) == 2
# now unstash everything
pg6 = pg5.unstash(from_stash="backdoor").unstash(from_stash="auth")
assert len(pg6.active) == 3
assert len(pg6.backdoor) == 0
assert len(pg6.auth) == 0
assert len(set(pg6.mp_active.addr.mp_items)) == 1
# now merge them!
pg7 = pg6.merge()
assert len(pg7.active) == 2
assert len(pg7.backdoor) == 0
assert len(pg7.auth) == 0
# test selecting paths to step
pg8 = p.factory.simulation_manager()
pg8.step(until=lambda lpg: len(lpg.active) > 1, step_func=lambda lpg: lpg.prune().drop(stash="pruned"))
st1, st2 = pg8.active
pg8.step(selector_func=lambda p: p is st1, step_func=lambda lpg: lpg.prune().drop(stash="pruned"))
assert st2 is pg8.active[1]
assert st1 is not pg8.active[0]
total_active = len(pg8.active)
# test special stashes
assert len(pg8.stashes["stashed"]) == 0
pg8.stash(filter_func=lambda p: p is pg8.active[1], to_stash="asdf")
assert len(pg8.stashes["stashed"]) == 0
assert len(pg8.asdf) == 1
assert len(pg8.active) == total_active - 1
pg8.stash(from_stash=pg8.ALL, to_stash="fdsa")
assert len(pg8.asdf) == 0
assert len(pg8.active) == 0
assert len(pg8.fdsa) == total_active
pg8.stash(from_stash=pg8.ALL, to_stash=pg8.DROP)
assert all(len(s) == 0 for s in pg8.stashes.values())
def test_fauxware_armel(self):
self._run_fauxware("armel", None)
def test_fauxware_armhf(self):
self._run_fauxware("armhf", None)
def test_fauxware_mips(self):
self._run_fauxware("mips", None)
def test_fauxware_mipsel(self):
self._run_fauxware("mipsel", None)
def test_fauxware_ppc(self):
self._run_fauxware("ppc", None)
def test_fauxware_ppc64(self):
self._run_fauxware("ppc64", None)
def test_fauxware_x86_64(self):
self._run_fauxware("x86_64", None)
def test_find_to_middle(self):
# Test the ability of PathGroup to execute until an instruction in the middle of a basic block
p = angr.Project(os.path.join(test_location, "x86_64", "fauxware"), load_options={"auto_load_libs": False})
pg = p.factory.simulation_manager()
pg.explore(find=(0x4006EE,))
assert len(pg.found) == 1
assert pg.found[0].addr == 0x4006EE
def test_explore_with_cfg(self):
p = angr.Project(os.path.join(test_location, "x86_64", "fauxware"), load_options={"auto_load_libs": False})
cfg = p.analyses.CFGEmulated()
pg = p.factory.simulation_manager()
pg.use_technique(angr.exploration_techniques.Explorer(find=0x4006ED, cfg=cfg, num_find=3))
pg.run()
assert len(pg.active) == 0
assert len(pg.avoid) == 1
assert len(pg.found) == 2
assert pg.found[0].addr == 0x4006ED
assert pg.found[1].addr == 0x4006ED
assert pg.avoid[0].addr == 0x4007C9
if __name__ == "__main__":
unittest.main()