angr 9.2.130__py3-none-win_amd64.whl → 9.2.132__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 (128) hide show
  1. angr/__init__.py +1 -1
  2. angr/analyses/analysis.py +6 -2
  3. angr/analyses/cfg/cfg_emulated.py +5 -5
  4. angr/analyses/cfg/cfg_fast.py +2 -2
  5. angr/analyses/cfg/indirect_jump_resolvers/jumptable.py +139 -94
  6. angr/analyses/cfg/indirect_jump_resolvers/x86_elf_pic_plt.py +1 -1
  7. angr/analyses/ddg.py +14 -11
  8. angr/analyses/decompiler/ail_simplifier.py +3 -2
  9. angr/analyses/decompiler/block_simplifier.py +10 -21
  10. angr/analyses/decompiler/clinic.py +361 -8
  11. angr/analyses/decompiler/condition_processor.py +12 -10
  12. angr/analyses/decompiler/dephication/graph_rewriting.py +1 -1
  13. angr/analyses/decompiler/dephication/rewriting_engine.py +169 -45
  14. angr/analyses/decompiler/dephication/seqnode_dephication.py +5 -4
  15. angr/analyses/decompiler/optimization_passes/__init__.py +0 -3
  16. angr/analyses/decompiler/optimization_passes/const_derefs.py +1 -0
  17. angr/analyses/decompiler/optimization_passes/div_simplifier.py +41 -16
  18. angr/analyses/decompiler/optimization_passes/engine_base.py +261 -83
  19. angr/analyses/decompiler/optimization_passes/inlined_string_transformation_simplifier.py +173 -35
  20. angr/analyses/decompiler/optimization_passes/mod_simplifier.py +5 -2
  21. angr/analyses/decompiler/optimization_passes/optimization_pass.py +39 -19
  22. angr/analyses/decompiler/peephole_optimizations/__init__.py +5 -1
  23. angr/analyses/decompiler/peephole_optimizations/a_mul_const_sub_a.py +34 -0
  24. angr/analyses/decompiler/peephole_optimizations/a_shl_const_sub_a.py +3 -1
  25. angr/analyses/decompiler/peephole_optimizations/bswap.py +10 -6
  26. angr/analyses/decompiler/peephole_optimizations/eager_eval.py +100 -19
  27. angr/analyses/decompiler/peephole_optimizations/remove_noop_conversions.py +17 -0
  28. angr/analyses/decompiler/peephole_optimizations/remove_redundant_conversions.py +42 -3
  29. angr/analyses/decompiler/peephole_optimizations/remove_redundant_shifts.py +4 -2
  30. angr/analyses/decompiler/peephole_optimizations/rol_ror.py +37 -10
  31. angr/analyses/decompiler/peephole_optimizations/shl_to_mul.py +25 -0
  32. angr/analyses/decompiler/peephole_optimizations/utils.py +18 -0
  33. angr/analyses/decompiler/presets/fast.py +0 -2
  34. angr/analyses/decompiler/presets/full.py +0 -2
  35. angr/analyses/decompiler/ssailification/rewriting.py +1 -2
  36. angr/analyses/decompiler/ssailification/rewriting_engine.py +140 -57
  37. angr/analyses/decompiler/ssailification/ssailification.py +2 -1
  38. angr/analyses/decompiler/ssailification/traversal.py +4 -6
  39. angr/analyses/decompiler/ssailification/traversal_engine.py +125 -42
  40. angr/analyses/decompiler/structured_codegen/c.py +79 -16
  41. angr/analyses/decompiler/structuring/phoenix.py +40 -14
  42. angr/analyses/decompiler/structuring/structurer_nodes.py +9 -0
  43. angr/analyses/deobfuscator/irsb_reg_collector.py +29 -60
  44. angr/analyses/deobfuscator/string_obf_finder.py +2 -2
  45. angr/analyses/init_finder.py +47 -22
  46. angr/analyses/propagator/engine_base.py +21 -14
  47. angr/analyses/propagator/engine_vex.py +149 -179
  48. angr/analyses/propagator/propagator.py +10 -28
  49. angr/analyses/propagator/top_checker_mixin.py +211 -5
  50. angr/analyses/propagator/vex_vars.py +1 -1
  51. angr/analyses/reaching_definitions/dep_graph.py +1 -1
  52. angr/analyses/reaching_definitions/engine_ail.py +304 -329
  53. angr/analyses/reaching_definitions/engine_vex.py +243 -229
  54. angr/analyses/reaching_definitions/function_handler.py +3 -3
  55. angr/analyses/reaching_definitions/rd_state.py +37 -32
  56. angr/analyses/s_propagator.py +38 -5
  57. angr/analyses/s_reaching_definitions/s_reaching_definitions.py +9 -5
  58. angr/analyses/typehoon/simple_solver.py +16 -7
  59. angr/analyses/typehoon/translator.py +8 -0
  60. angr/analyses/typehoon/typeconsts.py +10 -2
  61. angr/analyses/typehoon/typehoon.py +4 -1
  62. angr/analyses/typehoon/typevars.py +9 -7
  63. angr/analyses/variable_recovery/engine_ail.py +296 -256
  64. angr/analyses/variable_recovery/engine_base.py +137 -116
  65. angr/analyses/variable_recovery/engine_vex.py +175 -185
  66. angr/analyses/variable_recovery/irsb_scanner.py +49 -38
  67. angr/analyses/variable_recovery/variable_recovery.py +28 -5
  68. angr/analyses/variable_recovery/variable_recovery_base.py +32 -33
  69. angr/analyses/variable_recovery/variable_recovery_fast.py +2 -2
  70. angr/analyses/xrefs.py +46 -19
  71. angr/annocfg.py +19 -14
  72. angr/block.py +4 -9
  73. angr/calling_conventions.py +1 -1
  74. angr/engines/engine.py +30 -14
  75. angr/engines/light/__init__.py +11 -3
  76. angr/engines/light/engine.py +1003 -1185
  77. angr/engines/pcode/cc.py +2 -0
  78. angr/engines/successors.py +13 -9
  79. angr/engines/vex/claripy/datalayer.py +1 -1
  80. angr/engines/vex/claripy/irop.py +14 -3
  81. angr/engines/vex/light/slicing.py +2 -2
  82. angr/exploration_techniques/__init__.py +1 -124
  83. angr/exploration_techniques/base.py +126 -0
  84. angr/exploration_techniques/bucketizer.py +1 -1
  85. angr/exploration_techniques/dfs.py +3 -1
  86. angr/exploration_techniques/director.py +2 -3
  87. angr/exploration_techniques/driller_core.py +1 -1
  88. angr/exploration_techniques/explorer.py +4 -2
  89. angr/exploration_techniques/lengthlimiter.py +2 -1
  90. angr/exploration_techniques/local_loop_seer.py +2 -1
  91. angr/exploration_techniques/loop_seer.py +5 -5
  92. angr/exploration_techniques/manual_mergepoint.py +2 -1
  93. angr/exploration_techniques/memory_watcher.py +3 -1
  94. angr/exploration_techniques/oppologist.py +4 -5
  95. angr/exploration_techniques/slicecutor.py +4 -2
  96. angr/exploration_techniques/spiller.py +1 -1
  97. angr/exploration_techniques/stochastic.py +2 -1
  98. angr/exploration_techniques/stub_stasher.py +2 -1
  99. angr/exploration_techniques/suggestions.py +3 -1
  100. angr/exploration_techniques/symbion.py +3 -1
  101. angr/exploration_techniques/tech_builder.py +2 -1
  102. angr/exploration_techniques/threading.py +4 -7
  103. angr/exploration_techniques/timeout.py +4 -2
  104. angr/exploration_techniques/tracer.py +4 -3
  105. angr/exploration_techniques/unique.py +3 -2
  106. angr/exploration_techniques/veritesting.py +1 -1
  107. angr/knowledge_plugins/key_definitions/atoms.py +2 -2
  108. angr/knowledge_plugins/key_definitions/live_definitions.py +16 -13
  109. angr/knowledge_plugins/propagations/states.py +13 -8
  110. angr/knowledge_plugins/variables/variable_manager.py +23 -9
  111. angr/lib/angr_native.dll +0 -0
  112. angr/sim_manager.py +1 -3
  113. angr/sim_state.py +39 -41
  114. angr/sim_type.py +5 -0
  115. angr/sim_variable.py +29 -28
  116. angr/utils/bits.py +17 -0
  117. angr/utils/formatting.py +4 -1
  118. angr/utils/orderedset.py +4 -1
  119. angr/utils/ssa/__init__.py +21 -3
  120. {angr-9.2.130.dist-info → angr-9.2.132.dist-info}/METADATA +6 -6
  121. {angr-9.2.130.dist-info → angr-9.2.132.dist-info}/RECORD +125 -124
  122. angr/analyses/decompiler/optimization_passes/multi_simplifier.py +0 -223
  123. angr/analyses/propagator/engine_ail.py +0 -1562
  124. angr/storage/memory_mixins/__init__.pyi +0 -48
  125. {angr-9.2.130.dist-info → angr-9.2.132.dist-info}/LICENSE +0 -0
  126. {angr-9.2.130.dist-info → angr-9.2.132.dist-info}/WHEEL +0 -0
  127. {angr-9.2.130.dist-info → angr-9.2.132.dist-info}/entry_points.txt +0 -0
  128. {angr-9.2.130.dist-info → angr-9.2.132.dist-info}/top_level.txt +0 -0
@@ -1,7 +1,9 @@
1
1
  from __future__ import annotations
2
- import time
2
+
3
3
  import logging
4
- from . import ExplorationTechnique
4
+ import time
5
+
6
+ from .base import ExplorationTechnique
5
7
 
6
8
  l = logging.getLogger(name=__name__)
7
9
 
@@ -1,14 +1,15 @@
1
1
  from __future__ import annotations
2
- from typing import TYPE_CHECKING
2
+
3
3
  import logging
4
- import cle
4
+ from typing import TYPE_CHECKING
5
5
 
6
6
  import claripy
7
+ import cle
7
8
  from capstone import CS_GRP_CALL, CS_GRP_IRET, CS_GRP_JUMP, CS_GRP_RET
8
9
 
9
- from . import ExplorationTechnique
10
10
  from angr import BP_BEFORE, BP_AFTER, sim_options
11
11
  from angr.errors import AngrTracerError, SimIRSBNoDecodeError
12
+ from .base import ExplorationTechnique
12
13
 
13
14
  if TYPE_CHECKING:
14
15
  from angr.sim_state import SimState
@@ -1,8 +1,9 @@
1
1
  from __future__ import annotations
2
- from difflib import SequenceMatcher
2
+
3
3
  from collections import Counter
4
+ from difflib import SequenceMatcher
4
5
 
5
- from . import ExplorationTechnique
6
+ from .base import ExplorationTechnique
6
7
 
7
8
 
8
9
  class UniqueSearch(ExplorationTechnique):
@@ -1,7 +1,7 @@
1
1
  from __future__ import annotations
2
- from . import ExplorationTechnique
3
2
 
4
3
  from angr.sim_options import EFFICIENT_STATE_MERGING
4
+ from .base import ExplorationTechnique
5
5
 
6
6
 
7
7
  class Veritesting(ExplorationTechnique):
@@ -220,10 +220,10 @@ class Register(Atom):
220
220
  "arch",
221
221
  )
222
222
 
223
- def __init__(self, reg_offset: RegisterOffset, size: int, arch: Arch | None = None):
223
+ def __init__(self, reg_offset: RegisterOffset | int, size: int, arch: Arch | None = None):
224
224
  super().__init__(size)
225
225
 
226
- self.reg_offset = reg_offset
226
+ self.reg_offset = RegisterOffset(reg_offset)
227
227
  self.arch = arch
228
228
 
229
229
  def __repr__(self):
@@ -1,5 +1,5 @@
1
1
  from __future__ import annotations
2
- from typing import Any, TYPE_CHECKING, overload
2
+ from typing import Any, TYPE_CHECKING, cast, overload
3
3
  from collections.abc import Iterable, Generator
4
4
  import weakref
5
5
  import logging
@@ -14,7 +14,7 @@ import archinfo
14
14
  from angr.misc.ux import deprecated
15
15
  from angr.errors import SimMemoryMissingError, SimMemoryError
16
16
  from angr.storage.memory_mixins import MultiValuedMemory
17
- from angr.storage.memory_mixins.paged_memory.pages.multi_values import MultiValues
17
+ from angr.storage.memory_mixins.paged_memory.pages.multi_values import MVType, MultiValues
18
18
  from angr.knowledge_plugins.key_definitions.definition import A
19
19
  from angr.engines.light import SpOffset
20
20
  from angr.code_location import CodeLocation, ExternalCodeLocation
@@ -324,7 +324,7 @@ class LiveDefinitions:
324
324
  return True
325
325
  return False
326
326
 
327
- def stack_address(self, offset: int) -> claripy.ast.bv.BV | None:
327
+ def stack_address(self, offset: int) -> claripy.ast.bv.BV:
328
328
  base = claripy.BVS("stack_base", self.arch.bits, explicit_name=True)
329
329
  if offset:
330
330
  return base + offset
@@ -346,21 +346,21 @@ class LiveDefinitions:
346
346
  return 0
347
347
  if addr.op == "__add__":
348
348
  if len(addr.args) == 2:
349
- off0 = LiveDefinitions.get_stack_offset(addr.args[0], had_stack_base=True)
350
- off1 = LiveDefinitions.get_stack_offset(addr.args[1], had_stack_base=True)
349
+ off0 = LiveDefinitions.get_stack_offset(cast(claripy.ast.BV, addr.args[0]), had_stack_base=True)
350
+ off1 = LiveDefinitions.get_stack_offset(cast(claripy.ast.BV, addr.args[1]), had_stack_base=True)
351
351
  if off0 is not None and off1 is not None:
352
352
  return off0 + off1
353
353
  elif len(addr.args) == 1:
354
354
  return 0
355
355
  elif addr.op == "__sub__" and len(addr.args) == 2:
356
- off0 = LiveDefinitions.get_stack_offset(addr.args[0], had_stack_base=True)
357
- off1 = LiveDefinitions.get_stack_offset(addr.args[1], had_stack_base=True)
356
+ off0 = LiveDefinitions.get_stack_offset(cast(claripy.ast.BV, addr.args[0]), had_stack_base=True)
357
+ off1 = LiveDefinitions.get_stack_offset(cast(claripy.ast.BV, addr.args[1]), had_stack_base=True)
358
358
  if off0 is not None and off1 is not None:
359
359
  return off0 - off1
360
360
  return None
361
361
 
362
362
  @staticmethod
363
- def annotate_with_def(symvar: claripy.ast.BV, definition: Definition) -> claripy.ast.BV:
363
+ def annotate_with_def(symvar: MVType, definition: Definition) -> MVType:
364
364
  """
365
365
 
366
366
  :param symvar:
@@ -562,9 +562,12 @@ class LiveDefinitions:
562
562
  else:
563
563
  definition: Definition = Definition(atom, code_loc, dummy=dummy, tags=tags)
564
564
  d = MultiValues()
565
+ count = 0
565
566
  for offset, vs in data.items():
566
567
  for v in vs:
568
+ count += 1
567
569
  d.add_value(offset, self.annotate_with_def(v, definition))
570
+ assert count != 0, "MV may not be empty, use TOP instead"
568
571
 
569
572
  # set_object() replaces kill (not implemented) and add (add) in one step
570
573
  if isinstance(atom, Register):
@@ -659,7 +662,7 @@ class LiveDefinitions:
659
662
  self.other_uses.add_use(definition, code_loc, expr)
660
663
 
661
664
  def get_definitions(
662
- self, thing: A | Definition[A] | Iterable[A] | Iterable[Definition[A]] | MultiValues
665
+ self, thing: Atom | Definition[Atom] | Iterable[Atom] | Iterable[Definition[Atom]] | MultiValues
663
666
  ) -> set[Definition[Atom]]:
664
667
  if isinstance(thing, MultiValues):
665
668
  defs = set()
@@ -973,7 +976,7 @@ class LiveDefinitions:
973
976
  @overload
974
977
  def deref(
975
978
  self,
976
- pointer: MultiValues | A | Definition[A] | Iterable[A] | Iterable[Definition[A]],
979
+ pointer: MultiValues[claripy.ast.BV] | Atom | Definition[Atom] | Iterable[Atom] | Iterable[Definition[Atom]],
977
980
  size: int | DerefSize,
978
981
  endness: archinfo.Endness = ...,
979
982
  ) -> set[MemoryLocation]: ...
@@ -1023,7 +1026,7 @@ class LiveDefinitions:
1023
1026
  if heap_offset is not None:
1024
1027
  addr = HeapAddress(heap_offset)
1025
1028
  elif pointer.op == "BVV":
1026
- addr = pointer.args[0]
1029
+ addr = cast(int, pointer.args[0])
1027
1030
  else:
1028
1031
  # cannot resolve
1029
1032
  return None
@@ -1054,8 +1057,8 @@ class LiveDefinitions:
1054
1057
  if "heap_base" in addr.variables:
1055
1058
  if addr.op == "BVS":
1056
1059
  return 0
1057
- if addr.op == "__add__" and len(addr.args) == 2 and addr.args[1].op == "BVV":
1058
- return addr.args[1].concrete_value
1060
+ if addr.op == "__add__" and len(addr.args) == 2 and cast(claripy.ast.BV, addr.args[1]).op == "BVV":
1061
+ return cast(claripy.ast.BV, addr.args[1]).concrete_value
1059
1062
  return None
1060
1063
 
1061
1064
  def heap_address(self, offset: int | HeapAddress) -> claripy.ast.BV:
@@ -1,9 +1,12 @@
1
1
  # pylint:disable=too-many-boolean-expressions
2
2
  from __future__ import annotations
3
+ from abc import abstractmethod
3
4
  from typing import Any, TYPE_CHECKING
4
5
  from collections import defaultdict
5
6
  import weakref
6
7
 
8
+ from typing_extensions import Self
9
+
7
10
  import ailment
8
11
  import claripy
9
12
  import archinfo
@@ -114,7 +117,7 @@ class PropagatorState:
114
117
  self.model = model
115
118
  self.rda = rda
116
119
 
117
- def __repr__(self):
120
+ def __repr__(self) -> str:
118
121
  return "<PropagatorState>"
119
122
 
120
123
  @classmethod
@@ -155,6 +158,7 @@ class PropagatorState:
155
158
  # comparing bytes from two sets of memory objects
156
159
  # we don't need to resort to byte-level comparison. object-level is good enough.
157
160
 
161
+ # TODO what if object is bytes?
158
162
  if mo_self.object.symbolic or mo_other.object.symbolic:
159
163
  if type(mo_self) is SimLabeledMemoryObject and type(mo_other) is SimLabeledMemoryObject:
160
164
  return mo_self.label == mo_other.label and mo_self.object is mo_other.object
@@ -165,7 +169,7 @@ class PropagatorState:
165
169
  return None
166
170
 
167
171
  @staticmethod
168
- def top(bits: int) -> claripy.ast.Bits:
172
+ def top(bits: int) -> claripy.ast.BV:
169
173
  """
170
174
  Get a TOP value.
171
175
 
@@ -243,10 +247,11 @@ class PropagatorState:
243
247
  merge_occurred = True
244
248
  return merge_occurred
245
249
 
246
- def copy(self) -> PropagatorState:
250
+ @abstractmethod
251
+ def copy(self) -> Self:
247
252
  raise NotImplementedError
248
253
 
249
- def merge(self, *others):
254
+ def merge(self, *others: Self) -> tuple[Self, bool]:
250
255
  state = self.copy()
251
256
  merge_occurred = False
252
257
 
@@ -263,8 +268,8 @@ class PropagatorState:
263
268
  self._replacements = defaultdict(dict)
264
269
 
265
270
  def add_replacement(
266
- self, codeloc: CodeLocation, old, new, force_replace: bool = False
267
- ) -> bool: # pylint:disable=unused-argument
271
+ self, codeloc: CodeLocation, old, new, force_replace: bool = False # pylint:disable=unused-argument
272
+ ) -> bool:
268
273
  """
269
274
  Add a replacement record: Replacing expression `old` with `new` at program location `codeloc`.
270
275
  If the self._only_consts flag is set to true, only constant values will be set.
@@ -331,7 +336,7 @@ class RegisterComparisonAnnotation(claripy.Annotation):
331
336
  Annotate TOP values that are the result of register values comparing against constant values.
332
337
  """
333
338
 
334
- def __init__(self, offset, size, cmp_op, value):
339
+ def __init__(self, offset: int, size: int, cmp_op: str, value: int):
335
340
  self.offset = offset
336
341
  self.size = size
337
342
  self.cmp_op = cmp_op
@@ -504,7 +509,7 @@ class PropagatorVEXState(PropagatorState):
504
509
  # TODO: Handle size
505
510
  self._stack_variables.store(offset, value, size=size, endness=endness)
506
511
 
507
- def load_local_variable(self, offset, size, endness): # pylint:disable=unused-argument
512
+ def load_local_variable(self, offset, size, endness) -> claripy.ast.BV: # pylint:disable=unused-argument
508
513
  # TODO: Handle size
509
514
  try:
510
515
  return self._stack_variables.load(offset, size=size, endness=endness)
@@ -1,5 +1,5 @@
1
1
  from __future__ import annotations
2
- from typing import Literal, TYPE_CHECKING
2
+ from typing import Literal, TYPE_CHECKING, overload
3
3
  import logging
4
4
  from collections import defaultdict
5
5
  from itertools import count, chain
@@ -77,14 +77,14 @@ class VariableManagerInternal(Serializable):
77
77
 
78
78
  self.func_addr = func_addr
79
79
 
80
- self._variables: set[SimVariable] = OrderedSet() # all variables that are added to any region
80
+ self._variables: OrderedSet[SimVariable] = OrderedSet() # all variables that are added to any region
81
81
  self._global_region = KeyedRegion()
82
82
  self._stack_region = KeyedRegion()
83
83
  self._register_region = KeyedRegion()
84
84
  self._live_variables = {} # a mapping between addresses of program points and live variable collections
85
85
 
86
86
  self._variable_accesses: dict[SimVariable, set[VariableAccess]] = defaultdict(set)
87
- self._insn_to_variable: dict[int, set[tuple[SimVariable, int]]] = defaultdict(set)
87
+ self._insn_to_variable: dict[int, set[tuple[SimVariable, int | None]]] = defaultdict(set)
88
88
  self._stmt_to_variable: dict[tuple[int, int] | tuple[int, int, int], set[tuple[SimVariable, int]]] = (
89
89
  defaultdict(set)
90
90
  )
@@ -115,7 +115,7 @@ class VariableManagerInternal(Serializable):
115
115
  # optimization
116
116
  self._variables_without_writes = set()
117
117
 
118
- self.stack_offset_to_struct_member_info: dict[SimStackVariable, (int, SimStackVariable, SimStruct)] = {}
118
+ self.stack_offset_to_struct_member_info: dict[SimStackVariable, tuple[int, SimStackVariable, SimStruct]] = {}
119
119
 
120
120
  self.ret_val_size = None
121
121
 
@@ -291,9 +291,11 @@ class VariableManagerInternal(Serializable):
291
291
  variable_access = VariableAccess.parse_from_cmessage(varaccess_pb2, variable_by_ident=variable_by_ident)
292
292
  variable = variable_access.variable
293
293
  offset = variable_access.offset
294
+ assert variable is not None
294
295
  tpl = (variable, offset)
295
296
 
296
297
  model._variable_accesses[variable_access.variable].add(variable_access)
298
+ assert variable_access.location.ins_addr is not None
297
299
  model._insn_to_variable[variable_access.location.ins_addr].add(tpl)
298
300
  loc = (
299
301
  (variable_access.location.block_addr, variable_access.location.stmt_idx)
@@ -670,9 +672,16 @@ class VariableManagerInternal(Serializable):
670
672
 
671
673
  return accesses
672
674
 
675
+ @overload
676
+ def get_variables(self, sort: Literal["stack"], collapse_same_ident: bool = False) -> list[SimStackVariable]: ...
677
+ @overload
678
+ def get_variables(self, sort: Literal["reg"], collapse_same_ident: bool = False) -> list[SimRegisterVariable]: ...
679
+ @overload
673
680
  def get_variables(
674
- self, sort: Literal["stack", "reg"] | None = None, collapse_same_ident=False
675
- ) -> list[SimStackVariable | SimRegisterVariable]:
681
+ self, sort: None, collapse_same_ident: bool = False
682
+ ) -> list[SimRegisterVariable | SimRegisterVariable]: ...
683
+
684
+ def get_variables(self, sort=None, collapse_same_ident=False):
676
685
  """
677
686
  Get a list of variables.
678
687
 
@@ -695,9 +704,14 @@ class VariableManagerInternal(Serializable):
695
704
 
696
705
  return variables
697
706
 
698
- def get_unified_variables(
699
- self, sort: Literal["stack", "reg"] | None = None
700
- ) -> list[SimStackVariable | SimRegisterVariable]:
707
+ @overload
708
+ def get_unified_variables(self, sort: Literal["stack"]) -> list[SimStackVariable]: ...
709
+ @overload
710
+ def get_unified_variables(self, sort: Literal["reg"]) -> list[SimRegisterVariable]: ...
711
+ @overload
712
+ def get_unified_variables(self, sort: None) -> list[SimRegisterVariable | SimRegisterVariable]: ...
713
+
714
+ def get_unified_variables(self, sort=None):
701
715
  """
702
716
  Get a list of unified variables.
703
717
 
angr/lib/angr_native.dll CHANGED
Binary file
angr/sim_manager.py CHANGED
@@ -10,6 +10,7 @@ from types import TracebackType
10
10
  import claripy
11
11
  import mulpyplexer
12
12
 
13
+ from .exploration_techniques import ExplorationTechnique, Veritesting, Threading, Explorer, Suggestions
13
14
  from .misc.hookset import HookSet
14
15
  from .misc.ux import once
15
16
  from .misc.picklable_lock import PicklableLock
@@ -968,6 +969,3 @@ class ErrorRecord:
968
969
 
969
970
  def __eq__(self, other):
970
971
  return self is other or self.state is other
971
-
972
-
973
- from .exploration_techniques import ExplorationTechnique, Veritesting, Threading, Explorer, Suggestions
angr/sim_state.py CHANGED
@@ -5,12 +5,14 @@ import functools
5
5
  import itertools
6
6
  import logging
7
7
  import weakref
8
- from typing import TypeVar, TYPE_CHECKING
8
+ from typing import Any, TypeVar, TYPE_CHECKING, Generic
9
+ from collections.abc import Callable
9
10
 
10
11
  import archinfo
11
- import claripy
12
12
  from archinfo import Arch
13
13
  from archinfo.arch_soot import SootAddressDescriptor
14
+ import claripy
15
+ from cle import Clemory
14
16
 
15
17
  from . import sim_options as o
16
18
  from .errors import SimMergeError, SimValueError, SimStateError, SimSolverModeError
@@ -27,6 +29,8 @@ if TYPE_CHECKING:
27
29
  from .state_plugins.inspect import SimInspector
28
30
  from .state_plugins.jni_references import SimStateJNIReferences
29
31
  from .state_plugins.scratch import SimStateScratch
32
+ from angr.project import Project
33
+ from angr.simos.javavm import SimJavaVM
30
34
 
31
35
 
32
36
  l = logging.getLogger(name=__name__)
@@ -48,9 +52,12 @@ merge_counter = itertools.count()
48
52
 
49
53
  _complained_se = False
50
54
 
55
+ IPTypeConc = TypeVar("IPTypeConc")
56
+ IPTypeSym = TypeVar("IPTypeSym")
57
+
51
58
 
52
59
  # pylint: disable=not-callable
53
- class SimState(PluginHub):
60
+ class SimState(Generic[IPTypeConc, IPTypeSym], PluginHub[SimStatePlugin]):
54
61
  """
55
62
  The SimState represents the state of a program, including its memory, registers, and so forth.
56
63
 
@@ -88,23 +95,23 @@ class SimState(PluginHub):
88
95
 
89
96
  def __init__(
90
97
  self,
91
- project=None,
92
- arch=None,
93
- plugins=None,
94
- mode=None,
95
- options=None,
96
- add_options=None,
97
- remove_options=None,
98
- special_memory_filler=None,
99
- os_name=None,
100
- plugin_preset="default",
101
- cle_memory_backer=None,
102
- dict_memory_backer=None,
103
- permissions_map=None,
104
- default_permissions=3,
105
- stack_perms=None,
106
- stack_end=None,
107
- stack_size=None,
98
+ project: Project | None = None,
99
+ arch: Arch | None = None,
100
+ plugins: dict[str, SimStatePlugin] | None = None,
101
+ mode: str | None = None,
102
+ options: set[str] | list[str] | SimStateOptions | None = None,
103
+ add_options: set[str] | None = None,
104
+ remove_options: set[str] | None = None,
105
+ special_memory_filler: Callable[[str, int, int, SimState], Any] | None = None,
106
+ os_name: str | None = None,
107
+ plugin_preset: str = "default",
108
+ cle_memory_backer: Clemory | None = None,
109
+ dict_memory_backer: dict[int, bytes] | None = None,
110
+ permissions_map: dict[tuple[int, int], int] | None = None,
111
+ default_permissions: int = 3,
112
+ stack_perms: int | None = None,
113
+ stack_end: int | None = None,
114
+ stack_size: int | None = None,
108
115
  regioned_memory_cls=None,
109
116
  **kwargs,
110
117
  ):
@@ -118,7 +125,9 @@ class SimState(PluginHub):
118
125
  self._is_java_jni_project = self.project and self.project.is_java_jni_project
119
126
 
120
127
  # Arch
121
- if self._is_java_jni_project:
128
+ if self._is_java_jni_project and project is not None:
129
+ if TYPE_CHECKING:
130
+ assert isinstance(project.simos, SimJavaVM)
122
131
  self._arch = {"soot": project.arch, "vex": project.simos.native_simos.arch}
123
132
  # This flag indicates whether the current ip is a native address or
124
133
  # a soot address descriptor.
@@ -177,6 +186,7 @@ class SimState(PluginHub):
177
186
  # we have no choice but to use the 'default' plugin preset.
178
187
  if self.plugin_preset is None:
179
188
  self.use_plugin_preset("default")
189
+ assert self.plugin_preset is not None
180
190
 
181
191
  # Determine memory backend
182
192
  if self._is_java_project and not self._is_java_jni_project:
@@ -186,16 +196,14 @@ class SimState(PluginHub):
186
196
  elif o.ABSTRACT_MEMORY in self.options:
187
197
  # We use SimAbstractMemory in static mode.
188
198
  # Convert memory_backer into 'global' region.
189
- if cle_memory_backer is not None:
190
- cle_memory_backer = {"global": cle_memory_backer}
191
- if dict_memory_backer is not None:
192
- dict_memory_backer = {"global": dict_memory_backer}
199
+ cle_memory_backer_map = {"global": cle_memory_backer} if cle_memory_backer is not None else None
200
+ dict_memory_backer_map = {"global": dict_memory_backer} if dict_memory_backer is not None else None
193
201
 
194
202
  # TODO: support permissions backer in SimAbstractMemory
195
203
  sim_memory_cls = self.plugin_preset.request_plugin("abs_memory")
196
204
  sim_memory = sim_memory_cls(
197
- cle_memory_backer=cle_memory_backer,
198
- dict_memory_backer=dict_memory_backer,
205
+ cle_memory_backer=cle_memory_backer_map,
206
+ dict_memory_backer=dict_memory_backer_map,
199
207
  memory_id="mem",
200
208
  regioned_memory_cls=regioned_memory_cls,
201
209
  )
@@ -234,6 +242,7 @@ class SimState(PluginHub):
234
242
  # Same as for 'memory' plugin.
235
243
  if self.plugin_preset is None:
236
244
  self.use_plugin_preset("default")
245
+ assert self.plugin_preset is not None
237
246
 
238
247
  # Get register endness
239
248
  if self._is_java_jni_project:
@@ -322,17 +331,6 @@ class SimState(PluginHub):
322
331
  # TODO: This shouldn't be access directly.
323
332
  return self._active_plugins
324
333
 
325
- @property
326
- def se(self):
327
- """
328
- Deprecated alias for `solver`
329
- """
330
- global _complained_se
331
- if not _complained_se:
332
- _complained_se = True
333
- l.critical("The name state.se is deprecated; please use state.solver.")
334
- return self.get_plugin("solver")
335
-
336
334
  @property
337
335
  def ip(self):
338
336
  """
@@ -348,7 +346,7 @@ class SimState(PluginHub):
348
346
  self.regs.ip = val
349
347
 
350
348
  @property
351
- def _ip(self):
349
+ def _ip(self) -> IPTypeSym:
352
350
  """
353
351
  Get the instruction pointer expression without triggering SimInspect breakpoints or generating SimActions.
354
352
 
@@ -360,7 +358,7 @@ class SimState(PluginHub):
360
358
  raise TypeError(str(e)) from e
361
359
 
362
360
  @_ip.setter
363
- def _ip(self, val):
361
+ def _ip(self, val: IPTypeSym | IPTypeConc):
364
362
  """
365
363
  Set the instruction pointer without triggering SimInspect breakpoints or generating SimActions.
366
364
 
@@ -373,7 +371,7 @@ class SimState(PluginHub):
373
371
  raise TypeError(str(e)) from e
374
372
 
375
373
  @property
376
- def addr(self):
374
+ def addr(self) -> IPTypeConc:
377
375
  """
378
376
  Get the concrete address of the instruction pointer, without triggering SimInspect breakpoints or generating
379
377
  SimActions. An integer is returned, or an exception is raised if the instruction pointer is symbolic.
angr/sim_type.py CHANGED
@@ -535,6 +535,11 @@ class SimTypeInt256(SimTypeFixedSizeInt):
535
535
  _fixed_size = 256
536
536
 
537
537
 
538
+ class SimTypeInt512(SimTypeFixedSizeInt):
539
+ _base_name = "int512_t"
540
+ _fixed_size = 512
541
+
542
+
538
543
  class SimTypeChar(SimTypeReg):
539
544
  """
540
545
  SimTypeChar is a type that specifies a character;
angr/sim_variable.py CHANGED
@@ -22,7 +22,9 @@ class SimVariable(Serializable):
22
22
  "size",
23
23
  ]
24
24
 
25
- def __init__(self, ident=None, name=None, region: int | None = None, category=None, size: int | None = None):
25
+ def __init__(
26
+ self, size: int, ident: str | None = None, name: str | None = None, region: int | None = None, category=None
27
+ ):
26
28
  """
27
29
  :param ident: A unique identifier provided by user or the program. Usually a string.
28
30
  :param str name: Name of this variable.
@@ -87,7 +89,7 @@ class SimVariable(Serializable):
87
89
  class SimConstantVariable(SimVariable):
88
90
  __slots__ = ["value", "_hash"]
89
91
 
90
- def __init__(self, ident=None, value=None, region=None, size=None):
92
+ def __init__(self, size: int, ident=None, value=None, region=None):
91
93
  super().__init__(ident=ident, region=region, size=size)
92
94
  self.value = value
93
95
  self._hash = None
@@ -122,7 +124,7 @@ class SimConstantVariable(SimVariable):
122
124
  class SimTemporaryVariable(SimVariable):
123
125
  __slots__ = ["tmp_id", "_hash"]
124
126
 
125
- def __init__(self, tmp_id, size=None):
127
+ def __init__(self, tmp_id: int, size: int):
126
128
  SimVariable.__init__(self, size=size)
127
129
 
128
130
  self.tmp_id = tmp_id
@@ -162,7 +164,7 @@ class SimTemporaryVariable(SimVariable):
162
164
 
163
165
  @classmethod
164
166
  def parse_from_cmessage(cls, cmsg, **kwargs):
165
- obj = cls(cmsg.tmp_id)
167
+ obj = cls(cmsg.tmp_id, cmsg.base.size)
166
168
  obj._from_base(cmsg)
167
169
  return obj
168
170
 
@@ -170,10 +172,10 @@ class SimTemporaryVariable(SimVariable):
170
172
  class SimRegisterVariable(SimVariable):
171
173
  __slots__ = ["reg", "_hash"]
172
174
 
173
- def __init__(self, reg_offset, size, ident=None, name=None, region=None, category=None):
175
+ def __init__(self, reg_offset: int, size: int, ident=None, name=None, region=None, category=None):
174
176
  SimVariable.__init__(self, ident=ident, name=name, region=region, category=category, size=size)
175
177
 
176
- self.reg: int = reg_offset
178
+ self.reg = reg_offset
177
179
  self._hash: int | None = None
178
180
 
179
181
  @property
@@ -236,7 +238,7 @@ class SimRegisterVariable(SimVariable):
236
238
  class SimMemoryVariable(SimVariable):
237
239
  __slots__ = ["addr", "_hash"]
238
240
 
239
- def __init__(self, addr, size, ident=None, name=None, region=None, category=None):
241
+ def __init__(self, addr, size: int, ident=None, name=None, region=None, category=None):
240
242
  SimVariable.__init__(self, ident=ident, name=name, region=region, category=category, size=size)
241
243
 
242
244
  self.addr = addr
@@ -313,7 +315,9 @@ class SimStackVariable(SimMemoryVariable):
313
315
  "base_addr",
314
316
  )
315
317
 
316
- def __init__(self, offset, size, base="sp", base_addr=None, ident=None, name=None, region=None, category=None):
318
+ def __init__(
319
+ self, offset: int, size: int, base="sp", base_addr=None, ident=None, name=None, region=None, category=None
320
+ ):
317
321
  if isinstance(offset, int) and offset > 0x1000000:
318
322
  # I don't think any positive stack offset will be greater than that...
319
323
  # convert it to a negative number
@@ -422,16 +426,15 @@ class SimVariableSet(collections.abc.MutableSet):
422
426
  # For the sake of performance, we have another set that stores memory addresses of memory_variables
423
427
  self.memory_variable_addresses = set()
424
428
 
425
- def add(self, item): # pylint:disable=arguments-differ
426
- if type(item) is SimRegisterVariable:
427
- if not self.contains_register_variable(item):
428
- self.add_register_variable(item)
429
- elif type(item) is SimMemoryVariable:
430
- if not self.contains_memory_variable(item):
431
- self.add_memory_variable(item)
429
+ def add(self, value):
430
+ if type(value) is SimRegisterVariable:
431
+ if not self.contains_register_variable(value):
432
+ self.add_register_variable(value)
433
+ elif type(value) is SimMemoryVariable:
434
+ if not self.contains_memory_variable(value):
435
+ self.add_memory_variable(value)
432
436
  else:
433
- # TODO:
434
- raise Exception("WTF")
437
+ assert False, "Unknown type"
435
438
 
436
439
  def add_register_variable(self, reg_var):
437
440
  self.register_variables.add(reg_var)
@@ -443,16 +446,15 @@ class SimVariableSet(collections.abc.MutableSet):
443
446
  for i in range(mem_var.size):
444
447
  self.memory_variable_addresses.add(base_address + i)
445
448
 
446
- def discard(self, item): # pylint:disable=arguments-differ
447
- if type(item) is SimRegisterVariable:
448
- if self.contains_register_variable(item):
449
- self.discard_register_variable(item)
450
- elif isinstance(item, SimMemoryVariable):
451
- if self.contains_memory_variable(item):
452
- self.discard_memory_variable(item)
449
+ def discard(self, value):
450
+ if type(value) is SimRegisterVariable:
451
+ if self.contains_register_variable(value):
452
+ self.discard_register_variable(value)
453
+ elif isinstance(value, SimMemoryVariable):
454
+ if self.contains_memory_variable(value):
455
+ self.discard_memory_variable(value)
453
456
  else:
454
- # TODO:
455
- raise Exception("")
457
+ assert False, "Unknown type"
456
458
 
457
459
  def discard_register_variable(self, reg_var):
458
460
  self.register_variables.remove(reg_var)
@@ -528,5 +530,4 @@ class SimVariableSet(collections.abc.MutableSet):
528
530
  # TODO: Make it better!
529
531
  return self.contains_memory_variable(item)
530
532
 
531
- __import__("ipdb").set_trace()
532
- raise Exception("WTF is this variable?")
533
+ assert False, "WTF is this variable?"