1
0
mirror of https://github.com/angr/angr synced 2026-06-08 13:09:39 +00:00
Files
angr-angr/tests/knowledge_plugins/test_dwarf_variables.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

242 lines
8.9 KiB
Python
Executable File

#!/usr/bin/env python3
from __future__ import annotations
__package__ = __package__ or "tests.knowledge_plugins" # pylint:disable=redefined-builtin
import math
import os
from unittest import TestCase, main
import angr
from tests.common import bin_location
test_location = os.path.join(bin_location, "tests")
class TestDwarfVariables(TestCase):
"""
Test dwarf variables import and resolution of these variables
"""
def setUp(self):
self.p = angr.Project(os.path.join(test_location, "x86_64", "various_variables"), load_debug_info=True)
self.p.kb.dvars.load_from_dwarf()
simgr = self.p.factory.simgr()
main_addr = self.p.loader.find_symbol("main").rebased_addr
simgr.explore(find=main_addr)
self.s = simgr.found[0]
self.addr2line = self.p.loader.main_object.addr_to_line
# tests for global variables
def test_resolve_a(self):
a = self.s.dvars["a"]
computed_result = []
for i in range(9):
computed_result.append(a.array(i).mem.concrete)
expected_result = [1, 2, 3, 4, 5, 6, 7, 8, 9]
self.assertEqual(computed_result, expected_result, 'global variable "a" array values is computed wrong')
def test_resolve_pointer(self):
pointer = self.s.dvars["pointer"]
computed_result = pointer.deref.mem.concrete
expected_result = 0
self.assertEqual(
computed_result, expected_result, 'global variable "pointer" dereferences value is computed wrong'
)
def test_resolve_pointer2(self):
pointer2 = self.s.dvars["pointer2"]
computed_result = pointer2.deref.mem.concrete
expected_result = 1
self.assertEqual(
computed_result, expected_result, 'global variable "pointer2" dereferences value is computed wrong'
)
def test_resolve_global_var(self):
global_var = self.s.dvars["global_var"]
computed_result = global_var.mem.concrete
expected_result = 7
self.assertEqual(computed_result, expected_result, 'global variable "global_var" value is computed wrong')
def test_resolve_extern_var(self):
extern_var = self.s.dvars["extern_var"]
computed_result = extern_var.mem.concrete
expected_result = 42
self.assertEqual(computed_result, expected_result, 'global variable "extern_var" value is computed wrong')
def test_resolve_global_struct(self):
global_struct = self.s.dvars["global_struct"]
computed_struct_array = []
a = global_struct.member("struct_array")
for i in range(3):
computed_struct_array.append(a.array(i).mem.concrete)
computed_result = [
global_struct.member("struct_fun").mem.concrete,
global_struct.member("struct_int").mem.concrete,
global_struct.member("struct_ll").mem.concrete,
global_struct.member("struct_char").mem.concrete,
global_struct.member("struct_strref").string.concrete,
global_struct.member("struct_pointer").mem.concrete,
computed_struct_array,
# struct_float is tested below,
# struct_double is tested below,
global_struct.member("struct_my_type").mem.concrete,
]
expected_result = [
self.p.loader.find_symbol("variable_scopes").rebased_addr,
42,
256,
b"a",
b"hello",
self.s.dvars["dummy"].addr,
[9, 8, 7],
# 1.141,
# 1.141,
16,
]
self.assertEqual(
computed_result, expected_result, 'global variable "global_struct" members value is computed wrong'
)
struct_float = global_struct.member("struct_float").mem.concrete
struct_double = global_struct.member("struct_double").mem.concrete
self.assertTrue(
math.isclose(struct_float, 1.141, rel_tol=1e-7) and math.isclose(struct_double, 1.141, rel_tol=1e-7)
)
# tests for local variables
def test_sum_in_global(self):
simgr = self.p.factory.simgr()
addr = self.p.loader.find_symbol("sum_in_global").rebased_addr
simgr.explore(find=addr)
simgr.move(from_stash="found", to_stash="active")
simgr.step()
simgr.step()
s = simgr.active[0]
result = []
for _ in range(9):
result.append(s.dvars["global_var"].mem.concrete)
simgr.step()
s = simgr.active[0]
ref = [7, 8, 10, 13, 17, 22, 28, 35, 43]
self.assertEqual(result, ref)
def test_sum_in_local(self):
simgr = self.p.factory.simgr()
addr = self.p.loader.find_symbol("sum_in_local").rebased_addr
simgr.explore(find=addr)
simgr.move(from_stash="found", to_stash="active")
simgr.step()
s = simgr.active[0]
local_var = s.dvars["local_var"].mem.concrete
ref = 0
self.assertEqual(local_var, ref)
def test_variable_scopes(self):
simgr = self.p.factory.simgr()
filename = "/home/lukas/Software/angr-dev/binaries/tests_src/various_variables.c"
lines_strings = [
(78, b"He"),
(80, b"llo "),
# (84, b"Wor"), # FIXME fails
(88, b"ld!\n"),
]
for line, expected_string in lines_strings:
addr = {addr for addr in self.addr2line if (filename, line) in self.addr2line[addr]}.pop()
simgr.explore(find=addr)
s = simgr.found[0]
computed_string = s.dvars["string"].string.concrete
self.assertEqual(expected_string, computed_string)
simgr.move(from_stash="found", to_stash="active")
def test_sum_in_static(self):
simgr = self.p.factory.simgr()
filename = "/home/lukas/Software/angr-dev/binaries/tests_src/various_variables.c"
line = 47
addr = {addr for addr in self.addr2line if (filename, line) in self.addr2line[addr]}.pop()
simgr.explore(find=addr)
s = simgr.found[0]
computed_value = s.dvars["static_var"].mem.concrete
self.assertEqual(computed_value, 0)
def test_local_in_loop(self):
simgr = self.p.factory.simgr()
filename = "/home/lukas/Software/angr-dev/binaries/tests_src/various_variables.c"
line = 55
addr = {addr for addr in self.addr2line if (filename, line) in self.addr2line[addr]}.pop()
simgr.explore(find=addr)
s = simgr.found[0]
computed_value = s.dvars["local_in_loop"].mem.concrete
self.assertEqual(computed_value, 9)
def test_local_in_if(self):
simgr = self.p.factory.simgr()
filename = "/home/lukas/Software/angr-dev/binaries/tests_src/various_variables.c"
line = 68
addr = {addr for addr in self.addr2line if (filename, line) in self.addr2line[addr]}.pop()
simgr.explore(find=addr)
s = simgr.found[0]
computed_value = s.dvars["local_in_if"].mem.concrete
self.assertEqual(computed_value, 52)
def test_resolve_local_struct(self):
simgr = self.p.factory.simgr()
filename = "/home/lukas/Software/angr-dev/binaries/tests_src/various_variables.c"
line = 144
addr = {addr for addr in self.addr2line if (filename, line) in self.addr2line[addr]}.pop()
simgr.explore(find=addr)
s = simgr.found[0]
local_struct = s.dvars["local_struct"]
computed_struct_array = []
a = local_struct.member("struct_array")
for i in range(3):
computed_struct_array.append(a.array(i).mem.concrete)
computed_result = [
local_struct.member("struct_fun").mem.concrete,
local_struct.member("struct_int").mem.concrete,
local_struct.member("struct_ll").mem.concrete,
local_struct.member("struct_char").mem.concrete,
local_struct.member("struct_strref").string.concrete,
local_struct.member("struct_pointer").mem.concrete,
computed_struct_array,
# struct_float is tested below,
# struct_double is tested below,
local_struct.member("struct_my_type").mem.concrete,
]
expected_result = [
self.p.loader.find_symbol("variable_scopes").rebased_addr,
42,
256,
b"a",
b"hello",
s.dvars["local_pointer"].mem.concrete,
[9, 8, 7],
# 1.141,
# 1.141,
16,
]
self.assertEqual(
computed_result, expected_result, 'local variable "local_struct" members value is computed wrong'
)
struct_float = local_struct.member("struct_float").mem.concrete
struct_double = local_struct.member("struct_double").mem.concrete
self.assertTrue(
math.isclose(struct_float, 1.141, rel_tol=1e-7) and math.isclose(struct_double, 1.141, rel_tol=1e-7)
)
if __name__ == "__main__":
main()