angr 9.2.114__py3-none-win_amd64.whl → 9.2.116__py3-none-win_amd64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of angr might be problematic. Click here for more details.

Files changed (50) hide show
  1. angr/__init__.py +1 -1
  2. angr/__main__.py +2 -2
  3. angr/analyses/cfg/cfg_fast.py +1 -1
  4. angr/analyses/cfg/indirect_jump_resolvers/jumptable.py +2 -2
  5. angr/analyses/decompiler/decompilation_options.py +2 -12
  6. angr/analyses/decompiler/decompiler.py +14 -3
  7. angr/analyses/decompiler/optimization_passes/const_prop_reverter.py +3 -0
  8. angr/analyses/decompiler/optimization_passes/cross_jump_reverter.py +0 -3
  9. angr/analyses/decompiler/optimization_passes/lowered_switch_simplifier.py +2 -3
  10. angr/analyses/decompiler/optimization_passes/optimization_pass.py +9 -2
  11. angr/analyses/decompiler/optimization_passes/ret_deduplicator.py +2 -0
  12. angr/analyses/decompiler/optimization_passes/return_duplicator_high.py +2 -0
  13. angr/analyses/decompiler/optimization_passes/stack_canary_simplifier.py +5 -1
  14. angr/analyses/decompiler/structured_codegen/c.py +10 -13
  15. angr/analyses/decompiler/structuring/__init__.py +6 -2
  16. angr/analyses/decompiler/structuring/dream.py +3 -4
  17. angr/analyses/decompiler/structuring/phoenix.py +29 -93
  18. angr/analyses/decompiler/structuring/recursive_structurer.py +0 -3
  19. angr/analyses/decompiler/structuring/sailr.py +111 -0
  20. angr/analyses/decompiler/structuring/structurer_base.py +2 -5
  21. angr/analyses/decompiler/structuring/structurer_nodes.py +3 -3
  22. angr/analyses/reaching_definitions/dep_graph.py +62 -5
  23. angr/analyses/reaching_definitions/function_handler.py +11 -1
  24. angr/analyses/reaching_definitions/function_handler_library/__init__.py +11 -0
  25. angr/analyses/reaching_definitions/function_handler_library/stdio.py +262 -0
  26. angr/analyses/reaching_definitions/function_handler_library/stdlib.py +157 -0
  27. angr/analyses/reaching_definitions/function_handler_library/string.py +93 -0
  28. angr/analyses/reaching_definitions/function_handler_library/unistd.py +23 -0
  29. angr/analyses/reaching_definitions/rd_state.py +28 -29
  30. angr/analyses/variable_recovery/engine_vex.py +0 -9
  31. angr/analyses/vfg.py +13 -14
  32. angr/code_location.py +4 -4
  33. angr/engines/pcode/cc.py +2 -0
  34. angr/engines/vex/heavy/heavy.py +1 -1
  35. angr/knowledge_plugins/key_definitions/live_definitions.py +12 -13
  36. angr/lib/angr_native.dll +0 -0
  37. angr/procedures/libc/strlen.py +5 -2
  38. angr/sim_variable.py +3 -18
  39. angr/state_plugins/solver.py +3 -9
  40. angr/storage/memory_mixins/address_concretization_mixin.py +1 -1
  41. angr/storage/memory_mixins/paged_memory/pages/cooperation.py +2 -1
  42. angr/storage/memory_mixins/regioned_memory/abstract_merger_mixin.py +4 -2
  43. angr/storage/memory_mixins/regioned_memory/regioned_memory_mixin.py +5 -5
  44. angr/storage/memory_mixins/regioned_memory/static_find_mixin.py +3 -3
  45. {angr-9.2.114.dist-info → angr-9.2.116.dist-info}/METADATA +7 -7
  46. {angr-9.2.114.dist-info → angr-9.2.116.dist-info}/RECORD +50 -44
  47. {angr-9.2.114.dist-info → angr-9.2.116.dist-info}/WHEEL +1 -1
  48. {angr-9.2.114.dist-info → angr-9.2.116.dist-info}/LICENSE +0 -0
  49. {angr-9.2.114.dist-info → angr-9.2.116.dist-info}/entry_points.txt +0 -0
  50. {angr-9.2.114.dist-info → angr-9.2.116.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,157 @@
1
+ from __future__ import annotations
2
+ from typing import TYPE_CHECKING
3
+ import random
4
+
5
+ import claripy
6
+
7
+ from angr.analyses.reaching_definitions.function_handler import FunctionCallDataUnwrapped, FunctionHandler
8
+ from angr.knowledge_plugins.key_definitions.atoms import Atom
9
+ from angr.knowledge_plugins.key_definitions.live_definitions import DerefSize
10
+
11
+
12
+ if TYPE_CHECKING:
13
+ from angr.analyses.reaching_definitions.rd_state import ReachingDefinitionsState
14
+
15
+ # pylint: disable=no-self-use,missing-class-docstring,unused-argument
16
+
17
+
18
+ class EnvironAtom(Atom):
19
+ def __init__(self, size: int, name: str | None):
20
+ self.name = name
21
+ super().__init__(size)
22
+
23
+ def _identity(self):
24
+ if self.name is not None:
25
+ return (self.name,)
26
+ else:
27
+ return ()
28
+
29
+ def __repr__(self):
30
+ return f'<EnvironAtom {self.name if self.name is not None else "(dynamic)"}>'
31
+
32
+
33
+ class SystemAtom(Atom):
34
+ def __init__(self, size: int = 1):
35
+ self.nonce = random.randint(0, 999999999999)
36
+ super().__init__(size)
37
+
38
+ def _identity(self):
39
+ return (self.nonce,)
40
+
41
+ def __repr__(self):
42
+ return "<SystemAtom>"
43
+
44
+
45
+ class ExecveAtom(Atom):
46
+ def __init__(self, nonce: int, idx: int, size: int):
47
+ self.nonce = nonce
48
+ self.idx = idx
49
+ super().__init__(size)
50
+
51
+ def _identity(self):
52
+ return (self.nonce, self.idx)
53
+
54
+ def __repr__(self):
55
+ return f"<ExecveAtom {self.idx}>"
56
+
57
+
58
+ class LibcStdlibHandlers(FunctionHandler):
59
+ @FunctionCallDataUnwrapped.decorate
60
+ def handle_impl_atoi(self, state: ReachingDefinitionsState, data: FunctionCallDataUnwrapped):
61
+ buf_atoms = state.deref(data.args_atoms[0], DerefSize.NULL_TERMINATE)
62
+ buf_value = state.get_concrete_value(buf_atoms, cast_to=bytes)
63
+ if buf_value is not None:
64
+ try:
65
+ buf_value = int(buf_value.decode().strip("\0"))
66
+ except ValueError:
67
+ buf_value = 0
68
+ data.depends(data.ret_atoms, buf_atoms, value=buf_value)
69
+
70
+ @FunctionCallDataUnwrapped.decorate
71
+ def handle_impl_malloc(self, state: ReachingDefinitionsState, data: FunctionCallDataUnwrapped):
72
+ malloc_size = state.get_concrete_value(data.args_atoms[0]) or 48
73
+ heap_ptr = state.heap_allocator.allocate(malloc_size)
74
+ data.depends(data.ret_atoms, value=state.heap_address(heap_ptr))
75
+
76
+ @FunctionCallDataUnwrapped.decorate
77
+ def handle_impl_calloc(self, state: ReachingDefinitionsState, data: FunctionCallDataUnwrapped):
78
+ nmemb = state.get_concrete_value(data.args_atoms[0]) or 48
79
+ size = state.get_concrete_value(data.args_atoms[0]) or 1
80
+ heap_ptr = state.heap_address(state.heap_allocator.allocate(nmemb * size))
81
+ data.depends(state.deref(heap_ptr, nmemb * size), value=0)
82
+ data.depends(data.ret_atoms, value=heap_ptr)
83
+
84
+ @FunctionCallDataUnwrapped.decorate
85
+ def handle_impl_getenv(self, state: ReachingDefinitionsState, data: FunctionCallDataUnwrapped):
86
+ name_atom = state.deref(data.args_atoms[0], DerefSize.NULL_TERMINATE)
87
+ name_value = state.get_concrete_value(name_atom, cast_to=bytes)
88
+ if name_value is not None:
89
+ name_value = name_value.strip(b"\0").decode()
90
+ data.depends(None, name_atom)
91
+
92
+ # store a buffer, registering it as an output of this function
93
+ # we store this two-byte mixed value because we don't want the value to be picked up by get_concrete_value()
94
+ # but also it should be able to be picked up by NULL_TERMINATE reads
95
+ heap_ptr = state.heap_allocator.allocate(2)
96
+ heap_atom = state.deref(heap_ptr, 2)
97
+ heap_value = claripy.BVS("weh", 8).concat(claripy.BVV(0, 8))
98
+ data.depends(heap_atom, EnvironAtom(2, name_value), value=heap_value)
99
+ data.depends(data.ret_atoms, value=state.heap_address(heap_ptr))
100
+
101
+ @FunctionCallDataUnwrapped.decorate
102
+ def handle_impl_setenv(self, state: ReachingDefinitionsState, data: FunctionCallDataUnwrapped):
103
+ name_atom = state.deref(data.args_atoms[0], DerefSize.NULL_TERMINATE)
104
+ name_value = state.get_concrete_value(name_atom, cast_to=bytes)
105
+ if name_value is not None:
106
+ name_value = name_value.strip(b"\0").decode()
107
+ data.depends(None, name_atom)
108
+
109
+ src_atom = state.deref(data.args_atoms[1], DerefSize.NULL_TERMINATE)
110
+ src_value = state.get_values(src_atom)
111
+ data.depends(
112
+ EnvironAtom(len(src_value) // 8 if src_value is not None else 1, name_value), src_atom, value=src_value
113
+ )
114
+
115
+ @FunctionCallDataUnwrapped.decorate
116
+ def handle_impl_system(self, state: ReachingDefinitionsState, data: FunctionCallDataUnwrapped):
117
+ buf_atom = state.deref(data.args_atoms[0], DerefSize.NULL_TERMINATE)
118
+ buf_value = state.get_values(buf_atom)
119
+ data.depends(SystemAtom(len(buf_value) // 8 if buf_value is not None else 1), buf_atom, value=buf_value)
120
+
121
+ handle_impl_popen = handle_impl_execl = handle_impl_system
122
+
123
+ @FunctionCallDataUnwrapped.decorate
124
+ def handle_impl_execve(self, state: ReachingDefinitionsState, data: FunctionCallDataUnwrapped):
125
+ argv_value = state.get_one_value(data.args_atoms[1])
126
+ if argv_value is None:
127
+ return
128
+
129
+ nonce = random.randint(1, 999999999)
130
+
131
+ # Iterate through each pointer in the array to collect argument strings
132
+ idx = 0
133
+ while True:
134
+ # Read the concrete string pointer value
135
+ argv_deref_atom = state.deref(argv_value, state.arch.bytes, state.arch.memory_endness)
136
+ if argv_deref_atom is None:
137
+ # unknown if array continues
138
+ break
139
+
140
+ argv_deref_concrete = state.get_one_value(argv_deref_atom)
141
+ if argv_deref_concrete is None:
142
+ # unknown if array continues
143
+ break
144
+
145
+ if (argv_deref_concrete == 0).is_true():
146
+ # End of array
147
+ break
148
+
149
+ string_atom = state.deref(argv_deref_concrete, DerefSize.NULL_TERMINATE)
150
+ string_val = None if string_atom is None else state.get_values(string_atom)
151
+
152
+ atom = ExecveAtom(nonce, idx, len(string_val) // 8 if string_val is not None else 1)
153
+ data.depends(atom, [] if string_atom is None else [string_atom], value=string_val)
154
+
155
+ # Increment by size of pointer for this arch
156
+ argv_value += state.arch.bytes
157
+ idx += 1
@@ -0,0 +1,93 @@
1
+ import archinfo
2
+ from angr.analyses.reaching_definitions.function_handler import FunctionCallDataUnwrapped, FunctionHandler
3
+ from angr.analyses.reaching_definitions.rd_state import ReachingDefinitionsState
4
+ from angr.knowledge_plugins.key_definitions.live_definitions import DerefSize
5
+
6
+ # pylint: disable=no-self-use,missing-class-docstring,unused-argument
7
+
8
+
9
+ class LibcStringHandlers(FunctionHandler):
10
+ @FunctionCallDataUnwrapped.decorate
11
+ def handle_impl_strcat(self, state: ReachingDefinitionsState, data: FunctionCallDataUnwrapped):
12
+ src0_atom = state.deref(data.args_atoms[0], DerefSize.NULL_TERMINATE)
13
+ src1_atom = state.deref(data.args_atoms[1], DerefSize.NULL_TERMINATE)
14
+ src0_value = state.get_values(src0_atom)
15
+ src1_value = state.get_values(src1_atom)
16
+ if src0_value is not None and src1_value is not None:
17
+ src0_value = src0_value.extract(0, len(src0_value) // 8 - 1, archinfo.Endness.BE)
18
+ dest_value = src0_value.concat(src1_value)
19
+ dest_atom = state.deref(data.args_atoms[0], len(dest_value) // 8, endness=archinfo.Endness.BE)
20
+ else:
21
+ dest_value = None
22
+ dest_atom = src0_atom
23
+ data.depends(dest_atom, src0_atom, src1_atom, value=dest_value)
24
+ data.depends(data.ret_atoms, data.args_atoms[0], value=src0_value)
25
+
26
+ handle_impl_strncat = handle_impl_strcat
27
+
28
+ @FunctionCallDataUnwrapped.decorate
29
+ def handle_impl_strlen(self, state: ReachingDefinitionsState, data: FunctionCallDataUnwrapped):
30
+ src_atom = state.deref(data.args_atoms[0], DerefSize.NULL_TERMINATE)
31
+ src_str = state.get_values(src_atom)
32
+ if src_str is not None:
33
+ data.depends(data.ret_atoms, src_atom, value=len(src_str) // 8 - 1)
34
+ else:
35
+ data.depends(data.ret_atoms, src_atom)
36
+
37
+ @FunctionCallDataUnwrapped.decorate
38
+ def handle_impl_strcpy(self, state: ReachingDefinitionsState, data: FunctionCallDataUnwrapped):
39
+ src_atom = state.deref(data.args_atoms[1], DerefSize.NULL_TERMINATE)
40
+ src_str = state.get_values(src_atom)
41
+ if src_str is not None:
42
+ dst_atom = state.deref(data.args_atoms[0], len(src_str) // 8)
43
+ data.depends(dst_atom, src_atom, value=src_str)
44
+ data.depends(data.ret_atoms, data.args_atoms[0], value=state.get_values(data.args_atoms[0]))
45
+
46
+ @FunctionCallDataUnwrapped.decorate
47
+ def handle_impl_strncpy(self, state: ReachingDefinitionsState, data: FunctionCallDataUnwrapped):
48
+ n = state.get_concrete_value(data.args_atoms[1])
49
+ src_atom = state.deref(data.args_atoms[2], DerefSize.NULL_TERMINATE if n is None else n)
50
+ src_str = state.get_values(src_atom)
51
+ if src_str is not None:
52
+ dst_atom = state.deref(data.args_atoms[0], len(src_str) // 8)
53
+ data.depends(dst_atom, src_atom, value=src_str)
54
+ data.depends(data.ret_atoms, data.args_atoms[0], value=state.get_values(data.args_atoms[0]))
55
+
56
+ @FunctionCallDataUnwrapped.decorate
57
+ def handle_impl_strdup(self, state: ReachingDefinitionsState, data: FunctionCallDataUnwrapped):
58
+ src_atom = state.deref(data.args_atoms[1], DerefSize.NULL_TERMINATE)
59
+ src_str = state.get_values(src_atom)
60
+ if src_str is not None:
61
+ malloc_size = len(src_str) // 8
62
+ else:
63
+ malloc_size = 1
64
+ heap_ptr = state.heap_allocator.allocate(malloc_size)
65
+ dst_atom = state.deref(heap_ptr, malloc_size)
66
+ data.depends(dst_atom, src_atom, value=src_str)
67
+ data.depends(data.ret_atoms, data.args_atoms[0], value=state.get_values(data.args_atoms[0]))
68
+
69
+ @FunctionCallDataUnwrapped.decorate
70
+ def handle_impl_memcpy(self, state: ReachingDefinitionsState, data: FunctionCallDataUnwrapped):
71
+ size = state.get_concrete_value(data.args_atoms[2])
72
+ if size is not None:
73
+ src_atom = state.deref(data.args_atoms[1], size)
74
+ dst_atom = state.deref(data.args_atoms[0], size)
75
+ data.depends(dst_atom, src_atom, value=state.get_values(src_atom))
76
+ data.depends(data.ret_atoms, data.args_atoms[0], value=state.get_values(data.args_atoms[0]))
77
+
78
+ @FunctionCallDataUnwrapped.decorate
79
+ def handle_impl_memset(self, state: ReachingDefinitionsState, data: FunctionCallDataUnwrapped):
80
+ size = state.get_concrete_value(data.args_atoms[2])
81
+ if size is not None:
82
+ dst_atom = state.deref(data.args_atoms[0], size)
83
+ data.depends(dst_atom, data.args_atoms[1])
84
+ data.depends(data.ret_atoms, data.args_atoms[0], value=state.get_values(data.args_atoms[0]))
85
+
86
+ @FunctionCallDataUnwrapped.decorate
87
+ def handle_impl_strtok(self, state: ReachingDefinitionsState, data: FunctionCallDataUnwrapped):
88
+ # stub: just return the haystack pointer
89
+ data.depends(data.ret_atoms, data.args_atoms[0], value=state.get_values(data.args_atoms[0]))
90
+
91
+ handle_impl_strtok_r = handle_impl_strstr = handle_impl_strcasestr = handle_impl_strchr = handle_imple_strrchr = (
92
+ handle_impl_strchrnul
93
+ ) = handle_impl_strtok
@@ -0,0 +1,23 @@
1
+ from angr.analyses.reaching_definitions.function_handler import FunctionCallDataUnwrapped, FunctionHandler
2
+ from angr.analyses.reaching_definitions.function_handler_library.stdio import StdinAtom, StdoutAtom
3
+ from angr.analyses.reaching_definitions.rd_state import ReachingDefinitionsState
4
+
5
+ # pylint: disable=no-self-use,missing-class-docstring,unused-argument
6
+
7
+
8
+ class LibcUnistdHandlers(FunctionHandler):
9
+ @FunctionCallDataUnwrapped.decorate
10
+ def handle_impl_read(self, state: ReachingDefinitionsState, data: FunctionCallDataUnwrapped):
11
+ size = state.get_concrete_value(data.args_atoms[2]) or 1
12
+ dst_atom = state.deref(data.args_atoms[1], size)
13
+ data.depends(dst_atom, StdinAtom(data.function.name, size))
14
+
15
+ handle_impl_recv = handle_impl_recvfrom = handle_impl_read
16
+
17
+ @FunctionCallDataUnwrapped.decorate
18
+ def handle_impl_write(self, state: ReachingDefinitionsState, data: FunctionCallDataUnwrapped):
19
+ size = state.get_concrete_value(data.args_atoms[2]) or 1
20
+ src_atom = state.deref(data.args_atoms[1], size)
21
+ data.depends(StdoutAtom(data.function.name, size), src_atom, value=state.get_values(src_atom))
22
+
23
+ handle_impl_send = handle_impl_write
@@ -9,6 +9,7 @@ from angr.misc.ux import deprecated
9
9
  from angr.knowledge_plugins.key_definitions.environment import Environment
10
10
  from angr.knowledge_plugins.key_definitions.tag import Tag
11
11
  from angr.knowledge_plugins.key_definitions.heap_address import HeapAddress
12
+ from angr.knowledge_plugins.key_definitions.definition import A
12
13
  from angr.engines.light import SpOffset
13
14
  from angr.code_location import CodeLocation
14
15
  from ...storage.memory_mixins.paged_memory.pages.multi_values import MultiValues
@@ -90,7 +91,7 @@ class ReachingDefinitionsState:
90
91
  heap_allocator: HeapAllocator = None,
91
92
  environment: Environment = None,
92
93
  sp_adjusted: bool = False,
93
- all_definitions: set[Definition] | None = None,
94
+ all_definitions: set[Definition[A]] | None = None,
94
95
  initializer: Optional["RDAStateInitializer"] = None,
95
96
  element_limit: int = 5,
96
97
  merge_into_tops: bool = True,
@@ -106,12 +107,12 @@ class ReachingDefinitionsState:
106
107
  self._sp_adjusted: bool = sp_adjusted
107
108
  self._element_limit: int = element_limit
108
109
 
109
- self.all_definitions: set[Definition] = set() if all_definitions is None else all_definitions
110
+ self.all_definitions: set[Definition[A]] = set() if all_definitions is None else all_definitions
110
111
 
111
112
  self.heap_allocator = heap_allocator or HeapAllocator(canonical_size)
112
113
  self._environment: Environment = environment or Environment()
113
114
 
114
- self.codeloc_uses: set[Definition] = set()
115
+ self.codeloc_uses: set[Definition[A]] = set()
115
116
 
116
117
  # have we observed an exit statement or not during the analysis of the *last instruction* of a block? we should
117
118
  # not perform any sp updates if it is the case. this is for handling conditional returns in ARM binaries.
@@ -189,7 +190,7 @@ class ReachingDefinitionsState:
189
190
  return n - 2**self.arch.bits
190
191
  return n
191
192
 
192
- def annotate_with_def(self, symvar: claripy.ast.Base, definition: Definition) -> claripy.ast.Base:
193
+ def annotate_with_def(self, symvar: claripy.ast.Base, definition: Definition[A]) -> claripy.ast.Base:
193
194
  """
194
195
 
195
196
  :param symvar:
@@ -198,14 +199,14 @@ class ReachingDefinitionsState:
198
199
  """
199
200
  return self.live_definitions.annotate_with_def(symvar, definition)
200
201
 
201
- def annotate_mv_with_def(self, mv: MultiValues, definition: Definition) -> MultiValues:
202
+ def annotate_mv_with_def(self, mv: MultiValues, definition: Definition[A]) -> MultiValues:
202
203
  return MultiValues(
203
204
  offset_to_values={
204
205
  offset: {self.annotate_with_def(value, definition) for value in values} for offset, values in mv.items()
205
206
  }
206
207
  )
207
208
 
208
- def extract_defs(self, symvar: claripy.ast.Base) -> Iterator[Definition]:
209
+ def extract_defs(self, symvar: claripy.ast.Base) -> Iterator[Definition[A]]:
209
210
  yield from self.live_definitions.extract_defs(symvar)
210
211
 
211
212
  #
@@ -364,9 +365,9 @@ class ReachingDefinitionsState:
364
365
  tags: set[Tag] = None,
365
366
  endness=None, # XXX destroy
366
367
  annotated: bool = False,
367
- uses: set[Definition] | None = None,
368
+ uses: set[Definition[A]] | None = None,
368
369
  override_codeloc: CodeLocation | None = None,
369
- ) -> tuple[MultiValues | None, set[Definition]]:
370
+ ) -> tuple[MultiValues | None, set[Definition[A]]]:
370
371
  codeloc = override_codeloc or self.codeloc
371
372
  existing_defs = self.live_definitions.get_definitions(atom)
372
373
  mv = self.live_definitions.kill_and_add_definition(
@@ -446,7 +447,7 @@ class ReachingDefinitionsState:
446
447
  self.codeloc_uses.update(self.get_definitions(atom))
447
448
  self.live_definitions.add_use(atom, self.codeloc, expr=expr)
448
449
 
449
- def add_use_by_def(self, definition: Definition, expr: Any | None = None) -> None:
450
+ def add_use_by_def(self, definition: Definition[A], expr: Any | None = None) -> None:
450
451
  self.codeloc_uses.add(definition)
451
452
  self.live_definitions.add_use_by_def(definition, self.codeloc, expr=expr)
452
453
 
@@ -455,7 +456,7 @@ class ReachingDefinitionsState:
455
456
  self.add_tmp_use_by_defs(defs, expr=expr)
456
457
 
457
458
  def add_tmp_use_by_defs(
458
- self, defs: Iterable[Definition], expr: Any | None = None
459
+ self, defs: Iterable[Definition[A]], expr: Any | None = None
459
460
  ) -> None: # pylint:disable=unused-argument
460
461
  for definition in defs:
461
462
  self.codeloc_uses.add(definition)
@@ -466,7 +467,7 @@ class ReachingDefinitionsState:
466
467
  defs = self.live_definitions.get_register_definitions(reg_offset, size)
467
468
  self.add_register_use_by_defs(defs, expr=expr)
468
469
 
469
- def add_register_use_by_defs(self, defs: Iterable[Definition], expr: Any | None = None) -> None:
470
+ def add_register_use_by_defs(self, defs: Iterable[Definition[A]], expr: Any | None = None) -> None:
470
471
  for definition in defs:
471
472
  self.codeloc_uses.add(definition)
472
473
  self.live_definitions.add_register_use_by_def(definition, self.codeloc, expr=expr)
@@ -475,7 +476,7 @@ class ReachingDefinitionsState:
475
476
  defs = self.live_definitions.get_stack_definitions(stack_offset, size)
476
477
  self.add_stack_use_by_defs(defs, expr=expr)
477
478
 
478
- def add_stack_use_by_defs(self, defs: Iterable[Definition], expr: Any | None = None):
479
+ def add_stack_use_by_defs(self, defs: Iterable[Definition[A]], expr: Any | None = None):
479
480
  for definition in defs:
480
481
  self.codeloc_uses.add(definition)
481
482
  self.live_definitions.add_stack_use_by_def(definition, self.codeloc, expr=expr)
@@ -484,41 +485,39 @@ class ReachingDefinitionsState:
484
485
  defs = self.live_definitions.get_heap_definitions(heap_offset, size)
485
486
  self.add_heap_use_by_defs(defs, expr=expr)
486
487
 
487
- def add_heap_use_by_defs(self, defs: Iterable[Definition], expr: Any | None = None):
488
+ def add_heap_use_by_defs(self, defs: Iterable[Definition[A]], expr: Any | None = None):
488
489
  for definition in defs:
489
490
  self.codeloc_uses.add(definition)
490
491
  self.live_definitions.add_heap_use_by_def(definition, self.codeloc, expr=expr)
491
492
 
492
- def add_memory_use_by_def(self, definition: Definition, expr: Any | None = None):
493
+ def add_memory_use_by_def(self, definition: Definition[A], expr: Any | None = None):
493
494
  self.codeloc_uses.add(definition)
494
495
  self.live_definitions.add_memory_use_by_def(definition, self.codeloc, expr=expr)
495
496
 
496
- def add_memory_use_by_defs(self, defs: Iterable[Definition], expr: Any | None = None):
497
+ def add_memory_use_by_defs(self, defs: Iterable[Definition[A]], expr: Any | None = None):
497
498
  for definition in defs:
498
499
  self.codeloc_uses.add(definition)
499
500
  self.live_definitions.add_memory_use_by_def(definition, self.codeloc, expr=expr)
500
501
 
501
- def get_definitions(self, atom: Atom | Definition | Iterable[Atom] | Iterable[Definition]) -> set[Definition]:
502
+ def get_definitions(self, atom: A | Definition[A] | Iterable[A] | Iterable[Definition[A]]) -> set[Definition[A]]:
502
503
  return self.live_definitions.get_definitions(atom)
503
504
 
504
- def get_values(self, spec: Atom | Definition | Iterable[Atom]) -> MultiValues | None:
505
+ def get_values(self, spec: A | Definition[A] | Iterable[A]) -> MultiValues | None:
505
506
  return self.live_definitions.get_values(spec)
506
507
 
507
- def get_one_value(self, spec: Atom | Definition, strip_annotations: bool = False) -> claripy.ast.bv.BV | None:
508
+ def get_one_value(
509
+ self, spec: A | Definition[A] | Iterable[A] | Iterable[Definition[A]], strip_annotations: bool = False
510
+ ) -> claripy.ast.bv.BV | None:
508
511
  return self.live_definitions.get_one_value(spec, strip_annotations=strip_annotations)
509
512
 
510
513
  @overload
511
- def get_concrete_value(
512
- self, spec: Atom | Definition[Atom] | Iterable[Atom], cast_to: type[int] = ...
513
- ) -> int | None: ...
514
+ def get_concrete_value(self, spec: A | Definition[A] | Iterable[A], cast_to: type[int] = ...) -> int | None: ...
514
515
 
515
516
  @overload
516
- def get_concrete_value(
517
- self, spec: Atom | Definition[Atom] | Iterable[Atom], cast_to: type[bytes] = ...
518
- ) -> bytes | None: ...
517
+ def get_concrete_value(self, spec: A | Definition[A] | Iterable[A], cast_to: type[bytes] = ...) -> bytes | None: ...
519
518
 
520
519
  def get_concrete_value(
521
- self, spec: Atom | Definition[Atom] | Iterable[Atom], cast_to: type[int] | type[bytes] = int
520
+ self, spec: A | Definition[A] | Iterable[A], cast_to: type[int] | type[bytes] = int
522
521
  ) -> int | bytes | None:
523
522
  return self.live_definitions.get_concrete_value(spec, cast_to)
524
523
 
@@ -591,7 +590,7 @@ class ReachingDefinitionsState:
591
590
  @overload
592
591
  def deref(
593
592
  self,
594
- pointer: MultiValues | Atom | Definition | Iterable[Atom] | Iterable[Definition],
593
+ pointer: MultiValues | A | Definition | Iterable[A] | Iterable[Definition[A]],
595
594
  size: int | DerefSize,
596
595
  endness: str = ...,
597
596
  ) -> set[MemoryLocation]: ...
@@ -600,10 +599,10 @@ class ReachingDefinitionsState:
600
599
  self,
601
600
  pointer: (
602
601
  MultiValues
603
- | Atom
602
+ | A
604
603
  | Definition
605
- | Iterable[Atom]
606
- | Iterable[Definition]
604
+ | Iterable[A]
605
+ | Iterable[Definition[A]]
607
606
  | int
608
607
  | claripy.ast.BV
609
608
  | HeapAddress
@@ -563,15 +563,6 @@ class SimEngineVRVEX(
563
563
  return RichR(self.state.top(expr_0.data.size()))
564
564
  return RichR(self.state.top(expr_0.data.size()))
565
565
 
566
- def _handle_Ctz(self, expr):
567
- arg0 = expr.args[0]
568
- expr_0 = self._expr(arg0)
569
- if expr_0 is None:
570
- return None
571
- if self.state.is_top(expr_0.data):
572
- return RichR(self.state.top(expr_0.data.size()))
573
- return RichR(self.state.top(expr_0.data.size()))
574
-
575
566
  _handle_CmpEQ_v = _handle_Cmp_v
576
567
  _handle_CmpNE_v = _handle_Cmp_v
577
568
  _handle_CmpLE_v = _handle_Cmp_v
angr/analyses/vfg.py CHANGED
@@ -1572,11 +1572,11 @@ class VFG(ForwardAnalysis[SimState, VFGNode, VFGJob, BlockID], Analysis): # pyl
1572
1572
  # FIXME: Now we are assuming the sp is restored to its original value
1573
1573
  reg_sp_expr = successor_state.regs.sp
1574
1574
 
1575
- if isinstance(reg_sp_expr._model_vsa, claripy.vsa.StridedInterval): # type: ignore
1576
- reg_sp_si = reg_sp_expr._model_vsa
1575
+ if isinstance(claripy.backends.vsa.convert(reg_sp_expr), claripy.vsa.StridedInterval):
1576
+ reg_sp_si = claripy.backends.vsa.convert(reg_sp_expr)
1577
1577
  # reg_sp_si.min # reg_sp_val
1578
- elif isinstance(reg_sp_expr._model_vsa, claripy.vsa.ValueSet): # type: ignore
1579
- reg_sp_si = next(iter(reg_sp_expr._model_vsa.items()))[1] # type: ignore
1578
+ elif isinstance(claripy.backends.vsa.convert(reg_sp_expr), claripy.vsa.ValueSet):
1579
+ reg_sp_si = next(iter(claripy.backends.vsa.convert(reg_sp_expr).items()))[1]
1580
1580
  # reg_sp_si.min # reg_sp_val
1581
1581
  # TODO: Finish it!
1582
1582
 
@@ -1717,21 +1717,20 @@ class VFG(ForwardAnalysis[SimState, VFGNode, VFGJob, BlockID], Analysis): # pyl
1717
1717
  reg_sp_offset = arch.sp_offset
1718
1718
  reg_sp_expr = successor_state.registers.load(reg_sp_offset, size=arch.bytes, endness=arch.register_endness)
1719
1719
 
1720
- if type(reg_sp_expr._model_vsa) is claripy.BVV: # pylint:disable=unidiomatic-typecheck
1720
+ reg_sp_expr_vsa = claripy.backends.vsa.convert(reg_sp_expr)
1721
+ if isinstance(reg_sp_expr_vsa, claripy.bv.BVV):
1721
1722
  reg_sp_val = successor_state.solver.eval(reg_sp_expr)
1722
1723
  reg_sp_si = successor_state.solver.SI(to_conv=reg_sp_expr)
1723
- reg_sp_si = reg_sp_si._model_vsa
1724
- elif type(reg_sp_expr._model_vsa) is int: # pylint:disable=unidiomatic-typecheck
1725
- reg_sp_val = reg_sp_expr._model_vsa
1724
+ reg_sp_si = claripy.backends.vsa.convert(reg_sp_si)
1725
+ elif isinstance(reg_sp_expr_vsa, int):
1726
+ reg_sp_val = claripy.backends.vsa.convert(reg_sp_expr)
1726
1727
  reg_sp_si = successor_state.solver.SI(bits=successor_state.arch.bits, to_conv=reg_sp_val)
1727
- reg_sp_si = reg_sp_si._model_vsa
1728
- elif (
1729
- type(reg_sp_expr._model_vsa) is claripy.vsa.StridedInterval
1730
- ): # pylint:disable=unidiomatic-typecheck # type: ignore
1731
- reg_sp_si = reg_sp_expr._model_vsa
1728
+ reg_sp_si = claripy.backends.vsa.convert(reg_sp_si)
1729
+ elif isinstance(reg_sp_expr_vsa, claripy.vsa.StridedInterval):
1730
+ reg_sp_si = reg_sp_expr_vsa
1732
1731
  reg_sp_val = reg_sp_si.min
1733
1732
  else:
1734
- reg_sp_si = next(iter(reg_sp_expr._model_vsa.items()))[1]
1733
+ reg_sp_si = next(iter(reg_sp_expr_vsa.items()))[1]
1735
1734
  reg_sp_val = reg_sp_si.min
1736
1735
 
1737
1736
  reg_sp_val = reg_sp_val - arch.bytes # TODO: Is it OK?
angr/code_location.py CHANGED
@@ -20,12 +20,12 @@ class CodeLocation:
20
20
 
21
21
  def __init__(
22
22
  self,
23
- block_addr: int,
23
+ block_addr: int | None,
24
24
  stmt_idx: int | None,
25
25
  sim_procedure=None,
26
26
  ins_addr: int | None = None,
27
27
  context: Any = None,
28
- block_idx: int = None,
28
+ block_idx: int | None = None,
29
29
  **kwargs,
30
30
  ):
31
31
  """
@@ -41,12 +41,12 @@ class CodeLocation:
41
41
  :param kwargs: Optional arguments, will be stored, but not used in __eq__ or __hash__.
42
42
  """
43
43
 
44
- self.block_addr: int = block_addr
44
+ self.block_addr: int | None = block_addr
45
45
  self.stmt_idx: int | None = stmt_idx
46
46
  self.sim_procedure = sim_procedure
47
47
  self.ins_addr: int | None = ins_addr
48
48
  self.context: tuple[int] | None = context
49
- self.block_idx = block_idx
49
+ self.block_idx: int | None = block_idx
50
50
  self._hash = None
51
51
 
52
52
  self.info: dict | None = None
angr/engines/pcode/cc.py CHANGED
@@ -10,6 +10,7 @@ from ...calling_conventions import (
10
10
  register_default_cc,
11
11
  SimCCUnknown,
12
12
  default_cc,
13
+ SimCCO32,
13
14
  )
14
15
 
15
16
 
@@ -107,6 +108,7 @@ def register_pcode_arch_default_cc(arch: ArchPcode):
107
108
  "PowerPC:BE:32:e200": SimCCPowerPC,
108
109
  "PowerPC:BE:32:MPC8270": SimCCPowerPC,
109
110
  "Xtensa:LE:32:default": SimCCXtensa,
111
+ "MIPS:LE:32:default": SimCCO32,
110
112
  }
111
113
  if arch.name in manual_cc_mapping:
112
114
  # first attempt: manually specified mappings
@@ -349,7 +349,7 @@ class HeavyVEXMixin(SuccessorsMixin, ClaripyDataMixin, SimStateStorageMixin, VEX
349
349
  def _perform_vex_expr_Load(self, addr, ty, endness, **kwargs):
350
350
  result = super()._perform_vex_expr_Load(addr, ty, endness, **kwargs)
351
351
  if o.UNINITIALIZED_ACCESS_AWARENESS in self.state.options:
352
- if getattr(addr._model_vsa, "uninitialized", False):
352
+ if getattr(claripy.backends.vsa.convert(addr), "uninitialized", False):
353
353
  raise errors.SimUninitializedAccessError("addr", addr)
354
354
  return result
355
355
 
@@ -14,6 +14,7 @@ from angr.misc.ux import deprecated
14
14
  from angr.errors import SimMemoryMissingError, SimMemoryError
15
15
  from angr.storage.memory_mixins import MultiValuedMemory
16
16
  from angr.storage.memory_mixins.paged_memory.pages.multi_values import MultiValues
17
+ from angr.knowledge_plugins.key_definitions.definition import A
17
18
  from angr.engines.light import SpOffset
18
19
  from angr.code_location import CodeLocation, ExternalCodeLocation
19
20
  from .atoms import Atom, Register, MemoryLocation, Tmp, ConstantSrc
@@ -660,7 +661,7 @@ class LiveDefinitions:
660
661
  self.other_uses.add_use(definition, code_loc, expr)
661
662
 
662
663
  def get_definitions(
663
- self, thing: Atom | Definition[Atom] | Iterable[Atom] | Iterable[Definition[Atom]] | MultiValues
664
+ self, thing: A | Definition[A] | Iterable[A] | Iterable[Definition[A]] | MultiValues
664
665
  ) -> set[Definition[Atom]]:
665
666
  if isinstance(thing, MultiValues):
666
667
  defs = set()
@@ -693,9 +694,9 @@ class LiveDefinitions:
693
694
  return self.get_tmp_definitions(thing.tmp_idx)
694
695
  else:
695
696
  defs = set()
696
- for mvs in self.others.get(thing, {}).values():
697
- for mv in mvs:
698
- defs |= self.get_definitions(mv)
697
+ mv = self.others.get(thing, None)
698
+ if mv is not None:
699
+ defs |= self.get_definitions(mv)
699
700
  return defs
700
701
 
701
702
  def get_tmp_definitions(self, tmp_idx: int) -> set[Definition]:
@@ -749,7 +750,7 @@ class LiveDefinitions:
749
750
  return LiveDefinitions.extract_defs_from_annotations(annotations)
750
751
 
751
752
  @deprecated("get_definitions")
752
- def get_definitions_from_atoms(self, atoms: Iterable[Atom]) -> Iterable[Definition]:
753
+ def get_definitions_from_atoms(self, atoms: Iterable[A]) -> Iterable[Definition]:
753
754
  result = set()
754
755
  for atom in atoms:
755
756
  result |= self.get_definitions(atom)
@@ -813,9 +814,7 @@ class LiveDefinitions:
813
814
  return None
814
815
  return r.concrete_value
815
816
 
816
- def get_values(
817
- self, spec: Atom | Definition[Atom] | Iterable[Atom] | Iterable[Definition[Atom]]
818
- ) -> MultiValues | None:
817
+ def get_values(self, spec: A | Definition[A] | Iterable[A] | Iterable[Definition[A]]) -> MultiValues | None:
819
818
  if isinstance(spec, Definition):
820
819
  atom = spec.atom
821
820
  elif isinstance(spec, Atom):
@@ -874,7 +873,7 @@ class LiveDefinitions:
874
873
 
875
874
  def get_one_value(
876
875
  self,
877
- spec: Atom | Definition | Iterable[Atom] | Iterable[Definition[Atom]],
876
+ spec: A | Definition[A] | Iterable[A] | Iterable[Definition[A]],
878
877
  strip_annotations: bool = False,
879
878
  ) -> claripy.ast.bv.BV | None:
880
879
  r = self.get_values(spec)
@@ -884,19 +883,19 @@ class LiveDefinitions:
884
883
 
885
884
  @overload
886
885
  def get_concrete_value(
887
- self, spec: Atom | Definition[Atom] | Iterable[Atom] | Iterable[Definition[Atom]], cast_to: type[int] = ...
886
+ self, spec: A | Definition[A] | Iterable[A] | Iterable[Definition[A]], cast_to: type[int] = ...
888
887
  ) -> int | None: ...
889
888
 
890
889
  @overload
891
890
  def get_concrete_value(
892
891
  self,
893
- spec: Atom | Definition[Atom] | Iterable[Atom] | Iterable[Definition[Atom]],
892
+ spec: A | Definition[A] | Iterable[A] | Iterable[Definition[A]],
894
893
  cast_to: type[bytes] = ...,
895
894
  ) -> bytes | None: ...
896
895
 
897
896
  def get_concrete_value(
898
897
  self,
899
- spec: Atom | Definition[Atom] | Iterable[Atom] | Iterable[Definition[Atom]],
898
+ spec: A | Definition[A] | Iterable[A] | Iterable[Definition[A]],
900
899
  cast_to: type[int] | type[bytes] = int,
901
900
  ) -> int | bytes | None:
902
901
  r = self.get_one_value(spec, strip_annotations=True)
@@ -983,7 +982,7 @@ class LiveDefinitions:
983
982
  @overload
984
983
  def deref(
985
984
  self,
986
- pointer: MultiValues | Atom | Definition | Iterable[Atom] | Iterable[Definition],
985
+ pointer: MultiValues | A | Definition[A] | Iterable[A] | Iterable[Definition[A]],
987
986
  size: int | DerefSize,
988
987
  endness: archinfo.Endness = ...,
989
988
  ) -> set[MemoryLocation]: ...
angr/lib/angr_native.dll CHANGED
Binary file