mirror of
https://github.com/angr/angr
synced 2026-06-08 13:09:39 +00:00
563fb5f862
* [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>
149 lines
5.1 KiB
Python
Executable File
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()
|