angr 9.2.135__py3-none-manylinux2014_aarch64.whl → 9.2.137__py3-none-manylinux2014_aarch64.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 (198) hide show
  1. angr/__init__.py +1 -1
  2. angr/analyses/__init__.py +3 -7
  3. angr/analyses/analysis.py +4 -0
  4. angr/analyses/backward_slice.py +1 -2
  5. angr/analyses/binary_optimizer.py +3 -4
  6. angr/analyses/bindiff.py +4 -6
  7. angr/analyses/boyscout.py +1 -3
  8. angr/analyses/callee_cleanup_finder.py +4 -4
  9. angr/analyses/calling_convention/calling_convention.py +6 -4
  10. angr/analyses/calling_convention/fact_collector.py +10 -3
  11. angr/analyses/cdg.py +1 -2
  12. angr/analyses/cfg/cfb.py +1 -3
  13. angr/analyses/cfg/cfg.py +2 -2
  14. angr/analyses/cfg/cfg_base.py +40 -68
  15. angr/analyses/cfg/cfg_emulated.py +1 -104
  16. angr/analyses/cfg/cfg_fast.py +90 -27
  17. angr/analyses/cfg/cfg_fast_soot.py +1 -1
  18. angr/analyses/cfg/indirect_jump_resolvers/__init__.py +2 -0
  19. angr/analyses/cfg/indirect_jump_resolvers/const_resolver.py +46 -10
  20. angr/analyses/cfg/indirect_jump_resolvers/default_resolvers.py +5 -1
  21. angr/analyses/cfg/indirect_jump_resolvers/jumptable.py +65 -14
  22. angr/analyses/cfg/indirect_jump_resolvers/memload_resolver.py +81 -0
  23. angr/analyses/cfg/indirect_jump_resolvers/propagator_utils.py +24 -5
  24. angr/analyses/cfg/indirect_jump_resolvers/x86_pe_iat.py +2 -5
  25. angr/analyses/class_identifier.py +1 -2
  26. angr/analyses/complete_calling_conventions.py +3 -0
  27. angr/analyses/congruency_check.py +2 -3
  28. angr/analyses/data_dep/data_dependency_analysis.py +2 -2
  29. angr/analyses/ddg.py +1 -4
  30. angr/analyses/decompiler/ail_simplifier.py +15 -5
  31. angr/analyses/decompiler/block_simplifier.py +2 -2
  32. angr/analyses/decompiler/ccall_rewriters/__init__.py +2 -0
  33. angr/analyses/decompiler/ccall_rewriters/amd64_ccalls.py +1 -1
  34. angr/analyses/decompiler/ccall_rewriters/x86_ccalls.py +69 -0
  35. angr/analyses/decompiler/clinic.py +119 -72
  36. angr/analyses/decompiler/condition_processor.py +2 -0
  37. angr/analyses/decompiler/decompiler.py +1 -0
  38. angr/analyses/decompiler/dephication/dephication_base.py +2 -0
  39. angr/analyses/decompiler/dephication/rewriting_engine.py +8 -6
  40. angr/analyses/decompiler/dephication/seqnode_dephication.py +10 -1
  41. angr/analyses/decompiler/optimization_passes/duplication_reverter/ail_merge_graph.py +2 -2
  42. angr/analyses/decompiler/optimization_passes/duplication_reverter/duplication_reverter.py +2 -2
  43. angr/analyses/decompiler/optimization_passes/ite_region_converter.py +1 -1
  44. angr/analyses/decompiler/optimization_passes/lowered_switch_simplifier.py +1 -1
  45. angr/analyses/decompiler/optimization_passes/return_duplicator_base.py +1 -2
  46. angr/analyses/decompiler/optimization_passes/stack_canary_simplifier.py +1 -1
  47. angr/analyses/decompiler/sequence_walker.py +6 -2
  48. angr/analyses/decompiler/ssailification/rewriting.py +11 -1
  49. angr/analyses/decompiler/ssailification/rewriting_engine.py +56 -19
  50. angr/analyses/decompiler/ssailification/ssailification.py +13 -3
  51. angr/analyses/decompiler/ssailification/traversal.py +28 -2
  52. angr/analyses/decompiler/ssailification/traversal_state.py +6 -1
  53. angr/analyses/decompiler/structured_codegen/c.py +44 -21
  54. angr/analyses/decompiler/structuring/phoenix.py +118 -15
  55. angr/analyses/decompiler/utils.py +113 -8
  56. angr/analyses/disassembly.py +5 -5
  57. angr/analyses/fcp/__init__.py +4 -0
  58. angr/analyses/fcp/fcp.py +429 -0
  59. angr/analyses/identifier/identify.py +1 -3
  60. angr/analyses/loopfinder.py +4 -3
  61. angr/analyses/patchfinder.py +1 -1
  62. angr/analyses/propagator/engine_base.py +4 -3
  63. angr/analyses/propagator/propagator.py +14 -53
  64. angr/analyses/reaching_definitions/function_handler.py +1 -1
  65. angr/analyses/reassembler.py +1 -2
  66. angr/analyses/s_liveness.py +5 -1
  67. angr/analyses/s_propagator.py +26 -7
  68. angr/analyses/s_reaching_definitions/s_rda_model.py +2 -1
  69. angr/analyses/s_reaching_definitions/s_rda_view.py +20 -1
  70. angr/analyses/s_reaching_definitions/s_reaching_definitions.py +11 -1
  71. angr/analyses/soot_class_hierarchy.py +1 -2
  72. angr/analyses/stack_pointer_tracker.py +29 -3
  73. angr/analyses/static_hooker.py +1 -2
  74. angr/analyses/typehoon/simple_solver.py +2 -2
  75. angr/analyses/variable_recovery/engine_ail.py +19 -7
  76. angr/analyses/variable_recovery/engine_base.py +16 -14
  77. angr/analyses/variable_recovery/engine_vex.py +2 -2
  78. angr/analyses/variable_recovery/variable_recovery_fast.py +23 -3
  79. angr/analyses/veritesting.py +4 -7
  80. angr/analyses/vfg.py +1 -1
  81. angr/analyses/vsa_ddg.py +1 -2
  82. angr/block.py +62 -22
  83. angr/callable.py +1 -3
  84. angr/calling_conventions.py +3 -3
  85. angr/codenode.py +5 -1
  86. angr/concretization_strategies/__init__.py +1 -83
  87. angr/concretization_strategies/any.py +2 -1
  88. angr/concretization_strategies/any_named.py +1 -1
  89. angr/concretization_strategies/base.py +81 -0
  90. angr/concretization_strategies/controlled_data.py +2 -1
  91. angr/concretization_strategies/eval.py +2 -1
  92. angr/concretization_strategies/logging.py +3 -1
  93. angr/concretization_strategies/max.py +2 -1
  94. angr/concretization_strategies/nonzero.py +2 -1
  95. angr/concretization_strategies/nonzero_range.py +2 -1
  96. angr/concretization_strategies/norepeats.py +2 -1
  97. angr/concretization_strategies/norepeats_range.py +2 -1
  98. angr/concretization_strategies/range.py +2 -1
  99. angr/concretization_strategies/signed_add.py +2 -1
  100. angr/concretization_strategies/single.py +2 -1
  101. angr/concretization_strategies/solutions.py +2 -1
  102. angr/concretization_strategies/unlimited_range.py +2 -1
  103. angr/engines/__init__.py +8 -5
  104. angr/engines/engine.py +3 -5
  105. angr/engines/failure.py +4 -5
  106. angr/engines/pcode/emulate.py +1 -1
  107. angr/engines/pcode/lifter.py +31 -18
  108. angr/engines/procedure.py +5 -7
  109. angr/engines/soot/expressions/__init__.py +20 -23
  110. angr/engines/soot/expressions/base.py +4 -4
  111. angr/engines/soot/expressions/invoke.py +1 -2
  112. angr/engines/soot/statements/__init__.py +10 -12
  113. angr/engines/soot/values/__init__.py +10 -12
  114. angr/engines/soot/values/arrayref.py +3 -3
  115. angr/engines/soot/values/instancefieldref.py +3 -2
  116. angr/engines/successors.py +18 -12
  117. angr/engines/syscall.py +4 -6
  118. angr/engines/unicorn.py +3 -2
  119. angr/engines/vex/claripy/ccall.py +8 -10
  120. angr/engines/vex/claripy/datalayer.py +4 -5
  121. angr/engines/vex/lifter.py +9 -6
  122. angr/exploration_techniques/__init__.py +0 -2
  123. angr/exploration_techniques/spiller.py +1 -3
  124. angr/exploration_techniques/stochastic.py +2 -3
  125. angr/factory.py +3 -9
  126. angr/flirt/build_sig.py +8 -15
  127. angr/knowledge_plugins/cfg/cfg_model.py +20 -17
  128. angr/knowledge_plugins/functions/function.py +70 -79
  129. angr/knowledge_plugins/functions/function_manager.py +8 -7
  130. angr/knowledge_plugins/functions/function_parser.py +1 -1
  131. angr/knowledge_plugins/functions/soot_function.py +21 -24
  132. angr/knowledge_plugins/propagations/propagation_model.py +4 -5
  133. angr/knowledge_plugins/propagations/states.py +0 -511
  134. angr/knowledge_plugins/variables/variable_manager.py +16 -10
  135. angr/procedures/libc/memcpy.py +4 -4
  136. angr/procedures/procedure_dict.py +3 -2
  137. angr/protos/__init__.py +2 -5
  138. angr/protos/cfg_pb2.py +21 -18
  139. angr/protos/function_pb2.py +17 -14
  140. angr/protos/primitives_pb2.py +44 -39
  141. angr/protos/variables_pb2.py +36 -31
  142. angr/protos/xrefs_pb2.py +15 -12
  143. angr/sim_procedure.py +15 -16
  144. angr/sim_variable.py +13 -1
  145. angr/simos/__init__.py +2 -0
  146. angr/simos/javavm.py +4 -6
  147. angr/simos/xbox.py +32 -0
  148. angr/state_plugins/__init__.py +0 -2
  149. angr/state_plugins/callstack.py +4 -4
  150. angr/state_plugins/cgc.py +3 -2
  151. angr/state_plugins/gdb.py +6 -5
  152. angr/state_plugins/globals.py +1 -2
  153. angr/state_plugins/heap/heap_brk.py +1 -2
  154. angr/state_plugins/history.py +10 -12
  155. angr/state_plugins/inspect.py +3 -5
  156. angr/state_plugins/libc.py +2 -2
  157. angr/state_plugins/log.py +8 -10
  158. angr/state_plugins/loop_data.py +1 -2
  159. angr/state_plugins/posix.py +7 -7
  160. angr/state_plugins/preconstrainer.py +2 -3
  161. angr/state_plugins/scratch.py +5 -8
  162. angr/state_plugins/sim_action.py +3 -3
  163. angr/state_plugins/solver.py +8 -3
  164. angr/state_plugins/symbolizer.py +5 -4
  165. angr/state_plugins/uc_manager.py +3 -3
  166. angr/state_plugins/unicorn_engine.py +5 -1
  167. angr/state_plugins/view.py +3 -5
  168. angr/storage/file.py +3 -5
  169. angr/storage/memory_mixins/address_concretization_mixin.py +2 -2
  170. angr/storage/memory_mixins/bvv_conversion_mixin.py +3 -3
  171. angr/storage/memory_mixins/clouseau_mixin.py +1 -3
  172. angr/storage/memory_mixins/name_resolution_mixin.py +1 -3
  173. angr/storage/memory_mixins/paged_memory/paged_memory_mixin.py +13 -15
  174. angr/storage/memory_mixins/paged_memory/pages/__init__.py +1 -22
  175. angr/storage/memory_mixins/paged_memory/pages/base.py +31 -0
  176. angr/storage/memory_mixins/paged_memory/pages/list_page.py +1 -1
  177. angr/storage/memory_mixins/paged_memory/pages/mv_list_page.py +1 -1
  178. angr/storage/memory_mixins/paged_memory/pages/ultra_page.py +2 -4
  179. angr/storage/memory_mixins/paged_memory/privileged_mixin.py +3 -4
  180. angr/storage/memory_mixins/regioned_memory/abstract_merger_mixin.py +4 -2
  181. angr/storage/memory_mixins/smart_find_mixin.py +1 -1
  182. angr/storage/memory_mixins/underconstrained_mixin.py +1 -1
  183. angr/storage/memory_mixins/unwrapper_mixin.py +1 -3
  184. angr/utils/enums_conv.py +28 -12
  185. angr/utils/segment_list.py +25 -22
  186. angr/utils/timing.py +18 -1
  187. angr/vaults.py +5 -6
  188. {angr-9.2.135.dist-info → angr-9.2.137.dist-info}/METADATA +7 -7
  189. {angr-9.2.135.dist-info → angr-9.2.137.dist-info}/RECORD +193 -191
  190. {angr-9.2.135.dist-info → angr-9.2.137.dist-info}/WHEEL +1 -1
  191. angr/analyses/propagator/outdated_definition_walker.py +0 -159
  192. angr/analyses/propagator/tmpvar_finder.py +0 -18
  193. angr/engines/concrete.py +0 -180
  194. angr/exploration_techniques/symbion.py +0 -80
  195. angr/state_plugins/concrete.py +0 -295
  196. {angr-9.2.135.dist-info → angr-9.2.137.dist-info}/LICENSE +0 -0
  197. {angr-9.2.135.dist-info → angr-9.2.137.dist-info}/entry_points.txt +0 -0
  198. {angr-9.2.135.dist-info → angr-9.2.137.dist-info}/top_level.txt +0 -0
@@ -12,6 +12,7 @@ import cle
12
12
  import networkx
13
13
  import pyvex
14
14
 
15
+ from angr.analyses import AnalysesHub
15
16
  from . import Analysis
16
17
  from .cfg.cfg_emulated import CFGEmulated
17
18
  from .ddg import DDG
@@ -2896,6 +2897,4 @@ class Reassembler(Analysis):
2896
2897
  return None
2897
2898
 
2898
2899
 
2899
- from angr.analyses import AnalysesHub
2900
-
2901
2900
  AnalysesHub.register_default("Reassembler", Reassembler)
@@ -2,7 +2,7 @@ from __future__ import annotations
2
2
 
3
3
  import networkx
4
4
  from ailment.expression import VirtualVariable
5
- from ailment.statement import Assignment
5
+ from ailment.statement import Assignment, Call
6
6
 
7
7
  from angr.analyses import Analysis, register_analysis
8
8
  from angr.utils.ssa import VVarUsesCollector, phi_assignment_get_src
@@ -86,6 +86,8 @@ class SLivenessAnalysis(Analysis):
86
86
  # handle assignments: a defined vvar is not live before the assignment
87
87
  if isinstance(stmt, Assignment) and isinstance(stmt.dst, VirtualVariable):
88
88
  live.discard(stmt.dst.varid)
89
+ elif isinstance(stmt, Call) and isinstance(stmt.ret_expr, VirtualVariable):
90
+ live.discard(stmt.ret_expr.varid)
89
91
 
90
92
  phi_expr = phi_assignment_get_src(stmt)
91
93
  if phi_expr is not None:
@@ -136,6 +138,8 @@ class SLivenessAnalysis(Analysis):
136
138
  for stmt in reversed(block.statements):
137
139
  if isinstance(stmt, Assignment) and isinstance(stmt.dst, VirtualVariable):
138
140
  def_vvar = stmt.dst.varid
141
+ elif isinstance(stmt, Call) and isinstance(stmt.ret_expr, VirtualVariable):
142
+ def_vvar = stmt.ret_expr.varid
139
143
  else:
140
144
  def_vvar = None
141
145
 
@@ -17,7 +17,7 @@ from ailment.expression import (
17
17
  from ailment.statement import Assignment, Store, Return, Jump
18
18
 
19
19
  from angr.knowledge_plugins.functions import Function
20
- from angr.code_location import CodeLocation
20
+ from angr.code_location import CodeLocation, ExternalCodeLocation
21
21
  from angr.analyses import Analysis, register_analysis
22
22
  from angr.utils.ssa import (
23
23
  get_vvar_uselocs,
@@ -53,8 +53,8 @@ class SPropagatorAnalysis(Analysis):
53
53
  subject: Block | Function,
54
54
  func_graph=None,
55
55
  only_consts: bool = True,
56
- immediate_stmt_removal: bool = False,
57
56
  stack_pointer_tracker=None,
57
+ func_args: set[VirtualVariable] | None = None,
58
58
  func_addr: int | None = None,
59
59
  ):
60
60
  if isinstance(subject, Block):
@@ -70,8 +70,8 @@ class SPropagatorAnalysis(Analysis):
70
70
 
71
71
  self.func_graph = func_graph
72
72
  self.func_addr = func_addr
73
+ self.func_args = func_args
73
74
  self.only_consts = only_consts
74
- self.immediate_stmt_removal = immediate_stmt_removal
75
75
  self._sp_tracker = stack_pointer_tracker
76
76
 
77
77
  bp_as_gpr = False
@@ -111,6 +111,11 @@ class SPropagatorAnalysis(Analysis):
111
111
  # find all vvar uses
112
112
  vvar_uselocs = get_vvar_uselocs(blocks.values())
113
113
 
114
+ # update vvar_deflocs using function arguments
115
+ if self.func_args:
116
+ for func_arg in self.func_args:
117
+ vvar_deflocs[func_arg] = ExternalCodeLocation()
118
+
114
119
  # find all ret sites and indirect jump sites
115
120
  retsites: set[tuple[int, int | None, int]] = set()
116
121
  jumpsites: set[tuple[int, int | None, int]] = set()
@@ -132,8 +137,9 @@ class SPropagatorAnalysis(Analysis):
132
137
 
133
138
  vvarid_to_vvar[vvar.varid] = vvar
134
139
  defloc = vvar_deflocs[vvar]
135
- assert defloc.block_addr is not None
136
- assert defloc.stmt_idx is not None
140
+ if isinstance(defloc, ExternalCodeLocation):
141
+ continue
142
+
137
143
  block = blocks[(defloc.block_addr, defloc.block_idx)]
138
144
  stmt = block.statements[defloc.stmt_idx]
139
145
  r, v = is_const_assignment(stmt)
@@ -181,7 +187,20 @@ class SPropagatorAnalysis(Analysis):
181
187
  continue
182
188
 
183
189
  if is_const_and_vvar_assignment(stmt):
184
- replacements[vvar_useloc][vvar_used] = stmt.src
190
+ # if the useloc is a phi assignment statement, ensure that stmt.src is the same as the phi
191
+ # variable
192
+ useloc_stmt = blocks[(vvar_useloc.block_addr, vvar_useloc.block_idx)].statements[
193
+ vvar_useloc.stmt_idx
194
+ ]
195
+ if is_phi_assignment(useloc_stmt):
196
+ if (
197
+ isinstance(stmt.src, VirtualVariable)
198
+ and stmt.src.oident == useloc_stmt.dst.oident
199
+ and stmt.src.category == useloc_stmt.dst.category
200
+ ):
201
+ replacements[vvar_useloc][vvar_used] = stmt.src
202
+ else:
203
+ replacements[vvar_useloc][vvar_used] = stmt.src
185
204
  continue
186
205
 
187
206
  elif (
@@ -209,7 +228,7 @@ class SPropagatorAnalysis(Analysis):
209
228
  stmt_src = stmt_src.operand
210
229
  if isinstance(stmt_src, Load) and isinstance(stmt_src.addr, Const):
211
230
  gv_updated = False
212
- for vvar_used, vvar_useloc in vvar_uselocs[vvar.varid]:
231
+ for _vvar_used, vvar_useloc in vvar_uselocs[vvar.varid]:
213
232
  gv_updated |= self.is_global_variable_updated(
214
233
  self.func_graph,
215
234
  blocks,
@@ -15,8 +15,9 @@ class SRDAModel:
15
15
  The model for SRDA.
16
16
  """
17
17
 
18
- def __init__(self, func_graph, arch):
18
+ def __init__(self, func_graph, func_args, arch):
19
19
  self.func_graph = func_graph
20
+ self.func_args = func_args
20
21
  self.arch = arch
21
22
  self.varid_to_vvar: dict[int, VirtualVariable] = {}
22
23
  self.all_vvar_definitions: dict[VirtualVariable, CodeLocation] = {}
@@ -4,7 +4,7 @@ import logging
4
4
  from collections import defaultdict
5
5
 
6
6
  from ailment.statement import Statement, Assignment, Call, Label
7
- from ailment.expression import VirtualVariable, Expression
7
+ from ailment.expression import VirtualVariable, VirtualVariableCategory, Expression
8
8
 
9
9
  from angr.utils.ail import is_phi_assignment
10
10
  from angr.utils.graph import GraphUtils
@@ -133,6 +133,16 @@ class SRDAView:
133
133
  predicater = RegVVarPredicate(reg_offset, vvars, self.model.arch)
134
134
  self._get_vvar_by_stmt(block_addr, block_idx, stmt_idx, op_type, predicater.predicate)
135
135
 
136
+ if not vvars:
137
+ # not found - check function arguments
138
+ for func_arg in self.model.func_args:
139
+ if isinstance(func_arg, VirtualVariable):
140
+ func_arg_category = func_arg.oident[0]
141
+ if func_arg_category == VirtualVariableCategory.REGISTER:
142
+ func_arg_regoff = func_arg.oident[1]
143
+ if func_arg_regoff == reg_offset:
144
+ vvars.add(func_arg)
145
+
136
146
  assert len(vvars) <= 1
137
147
  return next(iter(vvars), None)
138
148
 
@@ -149,6 +159,15 @@ class SRDAView:
149
159
  predicater = StackVVarPredicate(stack_offset, size, vvars)
150
160
  self._get_vvar_by_stmt(block_addr, block_idx, stmt_idx, op_type, predicater.predicate)
151
161
 
162
+ if not vvars:
163
+ # not found - check function arguments
164
+ for func_arg in self.model.func_args:
165
+ if isinstance(func_arg, VirtualVariable):
166
+ func_arg_category = func_arg.oident[0]
167
+ if func_arg_category == VirtualVariableCategory.STACK:
168
+ func_arg_stackoff = func_arg.oident[1]
169
+ if func_arg_stackoff == stack_offset and func_arg.size == size:
170
+ vvars.add(func_arg)
152
171
  assert len(vvars) <= 1
153
172
  return next(iter(vvars), None)
154
173
 
@@ -2,6 +2,7 @@ from __future__ import annotations
2
2
 
3
3
  from ailment.block import Block
4
4
  from ailment.statement import Assignment, Call, Return
5
+ from ailment.expression import VirtualVariable
5
6
  import networkx
6
7
 
7
8
  from angr.knowledge_plugins.functions import Function
@@ -24,6 +25,7 @@ class SReachingDefinitionsAnalysis(Analysis):
24
25
  subject,
25
26
  func_addr: int | None = None,
26
27
  func_graph: networkx.DiGraph[Block] | None = None,
28
+ func_args: set[VirtualVariable] | None = None,
27
29
  track_tmps: bool = False,
28
30
  ):
29
31
  if isinstance(subject, Block):
@@ -39,13 +41,14 @@ class SReachingDefinitionsAnalysis(Analysis):
39
41
 
40
42
  self.func_graph = func_graph
41
43
  self.func_addr = func_addr if func_addr is not None else self.func.addr if self.func is not None else None
44
+ self.func_args = func_args
42
45
  self._track_tmps = track_tmps
43
46
 
44
47
  self._bp_as_gpr = False
45
48
  if self.func is not None:
46
49
  self._bp_as_gpr = self.func.info.get("bp_as_gpr", False)
47
50
 
48
- self.model = SRDAModel(func_graph, self.project.arch)
51
+ self.model = SRDAModel(func_graph, func_args, self.project.arch)
49
52
 
50
53
  self._analyze()
51
54
 
@@ -66,6 +69,13 @@ class SReachingDefinitionsAnalysis(Analysis):
66
69
  # find all explicit vvar uses
67
70
  vvar_uselocs = get_vvar_uselocs(blocks.values())
68
71
 
72
+ # update vvar definitions using function arguments
73
+ if self.func_args:
74
+ for vvar in self.func_args:
75
+ if vvar not in vvar_deflocs:
76
+ vvar_deflocs[vvar] = ExternalCodeLocation()
77
+ self.model.func_args = self.func_args
78
+
69
79
  # update model
70
80
  for vvar, defloc in vvar_deflocs.items():
71
81
  self.model.varid_to_vvar[vvar.varid] = vvar
@@ -1,6 +1,7 @@
1
1
  from __future__ import annotations
2
2
  import logging
3
3
 
4
+ from angr.analyses import AnalysesHub
4
5
  from . import Analysis
5
6
 
6
7
  l = logging.getLogger(name=__name__)
@@ -269,6 +270,4 @@ class SootClassHierarchy(Analysis):
269
270
  return targets
270
271
 
271
272
 
272
- from angr.analyses import AnalysesHub
273
-
274
273
  AnalysesHub.register_default("SootClassHierarchy", SootClassHierarchy)
@@ -2,6 +2,7 @@
2
2
  from __future__ import annotations
3
3
 
4
4
  from typing import Any, TYPE_CHECKING
5
+ import contextlib
5
6
  import re
6
7
  import logging
7
8
  from collections import defaultdict
@@ -15,7 +16,6 @@ from angr.knowledge_plugins import Function
15
16
  from angr.block import BlockNode
16
17
  from angr.errors import SimTranslationError
17
18
  from .analysis import Analysis
18
- import contextlib
19
19
 
20
20
  try:
21
21
  import pypcode
@@ -258,11 +258,11 @@ class StackPointerTrackerState:
258
258
  pass
259
259
  raise CouldNotResolveException
260
260
 
261
- def put(self, reg, val):
261
+ def put(self, reg, val, force: bool = False):
262
262
  # strong update, but we only update values for registers that are already in self.regs and ignore all other
263
263
  # registers. obviously, self.regs should be initialized with registers that should be considered during
264
264
  # tracking,
265
- if reg in self.regs:
265
+ if reg in self.regs or force:
266
266
  self.regs[reg] = val
267
267
 
268
268
  def copy(self):
@@ -702,6 +702,32 @@ class StackPointerTracker(Analysis, ForwardAnalysis):
702
702
  # who are we calling?
703
703
  callees = [] if self._func is None else self._find_callees(node)
704
704
  if callees:
705
+ if len(callees) == 1:
706
+ callee = callees[0]
707
+
708
+ if callee.info.get("is_rust_probestack", False) is True and self.project.arch.name == "AMD64":
709
+ # special-case for rust_probestack: sp = sp - rax right after returning from the call, so we
710
+ # need to keep track of rax
711
+ for stmt in reversed(vex_block.statements):
712
+ if (
713
+ isinstance(stmt, pyvex.IRStmt.Put)
714
+ and stmt.offset == self.project.arch.registers["rax"][0]
715
+ and isinstance(stmt.data, pyvex.IRExpr.Const)
716
+ ):
717
+ state.put(stmt.offset, Constant(stmt.data.con.value), force=True)
718
+ break
719
+ elif callee.name == "__chkstk":
720
+ # special-case for __chkstk: sp = sp - rax right after returning from the call, so we need to
721
+ # keep track of rax
722
+ for stmt in reversed(vex_block.statements):
723
+ if (
724
+ isinstance(stmt, pyvex.IRStmt.Put)
725
+ and stmt.offset == self.project.arch.registers["rax"][0]
726
+ and isinstance(stmt.data, pyvex.IRExpr.Const)
727
+ ):
728
+ state.put(stmt.offset, Constant(stmt.data.con.value), force=True)
729
+ break
730
+
705
731
  callee_cleanups = [
706
732
  callee
707
733
  for callee in callees
@@ -4,6 +4,7 @@ import logging
4
4
  from . import Analysis
5
5
 
6
6
  from angr import SIM_LIBRARIES
7
+ from angr.analyses import AnalysesHub
7
8
  from angr.errors import AngrValueError
8
9
 
9
10
  l = logging.getLogger(name=__name__)
@@ -47,6 +48,4 @@ class StaticHooker(Analysis):
47
48
  l.debug("Failed to hook %s at %#x", func.name, func.rebased_addr)
48
49
 
49
50
 
50
- from angr.analyses import AnalysesHub
51
-
52
51
  AnalysesHub.register_default("StaticHooker", StaticHooker)
@@ -870,7 +870,7 @@ class SimpleSolver:
870
870
  for x, y, data in graph.edges(data=True):
871
871
  lbl = data.get("label")
872
872
  if lbl and lbl[1] == "recall":
873
- for label, z in R[x]:
873
+ for _label, z in R[x]:
874
874
  if not graph.has_edge(z, y):
875
875
  changed = True
876
876
  graph.add_edge(z, y)
@@ -1167,7 +1167,7 @@ class SimpleSolver:
1167
1167
 
1168
1168
  candidate_bases = defaultdict(set)
1169
1169
 
1170
- for labels, succ in path_and_successors:
1170
+ for labels, _succ in path_and_successors:
1171
1171
  last_label = labels[-1] if labels else None
1172
1172
  if isinstance(last_label, HasField):
1173
1173
  # TODO: Really determine the maximum possible size of the field when MAX_POINTSTO_BITS is in use
@@ -74,17 +74,28 @@ class SimEngineVRAIL(
74
74
 
75
75
  elif dst_type is ailment.Expr.VirtualVariable:
76
76
  data = self._expr(stmt.src)
77
- self._assign_to_vvar(
77
+ variable = self._assign_to_vvar(
78
78
  stmt.dst, data, src=stmt.src, dst=stmt.dst, vvar_id=self._mapped_vvarid(stmt.dst.varid)
79
79
  )
80
80
 
81
+ if variable is not None and isinstance(stmt.src, ailment.Expr.Phi):
82
+ # this is a phi node - we update variable manager's phi variable tracking
83
+ for _, vvar in stmt.src.src_and_vvars:
84
+ if vvar is not None:
85
+ r = self._read_from_vvar(vvar, expr=stmt.src, vvar_id=self._mapped_vvarid(vvar.varid))
86
+ if r.variable is not None:
87
+ pv = self.variable_manager[self.func_addr]._phi_variables
88
+ if variable not in pv:
89
+ pv[variable] = set()
90
+ pv[variable].add(r.variable)
91
+
81
92
  if stmt.dst.was_stack and isinstance(stmt.dst.stack_offset, int):
82
93
  # store it to the stack region in case it's directly referenced later
83
94
  self._store(
84
95
  RichR(self.state.stack_address(stmt.dst.stack_offset)),
85
96
  data,
86
97
  stmt.dst.bits // self.arch.byte_width,
87
- stmt=stmt,
98
+ atom=stmt.dst,
88
99
  )
89
100
 
90
101
  else:
@@ -94,10 +105,11 @@ class SimEngineVRAIL(
94
105
  addr_r = self._expr_bv(stmt.addr)
95
106
  data = self._expr(stmt.data)
96
107
  size = stmt.size
97
- self._store(addr_r, data, size, stmt=stmt)
108
+ self._store(addr_r, data, size, atom=stmt)
98
109
 
99
- def _handle_stmt_Jump(self, stmt):
100
- pass
110
+ def _handle_stmt_Jump(self, stmt: ailment.Stmt.Jump):
111
+ if not isinstance(stmt.target, ailment.Expr.Const):
112
+ self._expr(stmt.target)
101
113
 
102
114
  def _handle_stmt_ConditionalJump(self, stmt):
103
115
  self._expr(stmt.condition)
@@ -149,7 +161,7 @@ class SimEngineVRAIL(
149
161
  prototype_libname = func.prototype_libname
150
162
 
151
163
  # dump the type of the return value
152
- ret_ty = typevars.TypeVariable() if prototype is not None else typevars.TypeVariable()
164
+ ret_ty = typevars.TypeVariable()
153
165
  if isinstance(ret_ty, typeconsts.BottomType):
154
166
  ret_ty = typevars.TypeVariable()
155
167
 
@@ -218,7 +230,7 @@ class SimEngineVRAIL(
218
230
  prototype_libname = func.prototype_libname
219
231
 
220
232
  # dump the type of the return value
221
- ret_ty = typevars.TypeVariable() if prototype is not None else typevars.TypeVariable()
233
+ ret_ty = typevars.TypeVariable()
222
234
  if isinstance(ret_ty, typeconsts.BottomType):
223
235
  ret_ty = typevars.TypeVariable()
224
236
 
@@ -387,7 +387,7 @@ class SimEngineVRBase(
387
387
  ) or not create_variable:
388
388
  # only store the value. don't worry about variables.
389
389
  self.vvar_region[vvar_id] = richr.data
390
- return
390
+ return None
391
391
 
392
392
  codeloc: CodeLocation = self._codeloc()
393
393
  data = richr.data
@@ -463,10 +463,14 @@ class SimEngineVRBase(
463
463
  else:
464
464
  typevar = self.state.typevars.get_type_variable(variable, codeloc)
465
465
  self.state.add_type_constraint(typevars.Subtype(richr.typevar, typevar))
466
+ # the constraint below is a default constraint that may conflict with more specific ones with different
467
+ # sizes; we post-process at the very end of VRA to remove conflicting default constraints.
466
468
  self.state.add_type_constraint(typevars.Subtype(typevar, typeconsts.int_type(variable.size * 8)))
467
469
 
470
+ return variable
471
+
468
472
  def _store(
469
- self, richr_addr: RichR[claripy.ast.BV], data: RichR[claripy.ast.BV | claripy.ast.FP], size, stmt=None
473
+ self, richr_addr: RichR[claripy.ast.BV], data: RichR[claripy.ast.BV | claripy.ast.FP], size, atom=None
470
474
  ): # pylint:disable=unused-argument
471
475
  """
472
476
 
@@ -481,19 +485,19 @@ class SimEngineVRBase(
481
485
 
482
486
  if addr.concrete:
483
487
  # fully concrete. this is a global address
484
- self._store_to_global(addr.concrete_value, data, size, stmt=stmt)
488
+ self._store_to_global(addr.concrete_value, data, size, stmt=atom)
485
489
  stored = True
486
490
  elif self._addr_has_concrete_base(addr) and (parsed := self._parse_offsetted_addr(addr)) is not None:
487
491
  # we are storing to a concrete global address with an offset
488
492
  base_addr, offset, elem_size = parsed
489
- self._store_to_global(base_addr.concrete_value, data, size, stmt=stmt, offset=offset, elem_size=elem_size)
493
+ self._store_to_global(base_addr.concrete_value, data, size, stmt=atom, offset=offset, elem_size=elem_size)
490
494
  stored = True
491
495
  else:
492
496
  if self.state.is_stack_address(addr):
493
497
  stack_offset = self.state.get_stack_offset(addr)
494
498
  if stack_offset is not None:
495
499
  # fast path: Storing data to stack
496
- self._store_to_stack(stack_offset, data, size, stmt=stmt)
500
+ self._store_to_stack(stack_offset, data, size, atom=atom)
497
501
  stored = True
498
502
 
499
503
  if not stored:
@@ -504,21 +508,21 @@ class SimEngineVRBase(
504
508
  codeloc = self._codeloc()
505
509
  if existing_vars:
506
510
  for existing_var, _ in list(existing_vars):
507
- self.variable_manager[self.func_addr].remove_variable_by_atom(codeloc, existing_var, stmt)
511
+ self.variable_manager[self.func_addr].remove_variable_by_atom(codeloc, existing_var, atom)
508
512
 
509
513
  # storing to a location specified by a pointer whose value cannot be determined at this point
510
- self._store_to_variable(richr_addr, size, stmt=stmt)
514
+ self._store_to_variable(richr_addr, size)
511
515
 
512
516
  def _store_to_stack(
513
- self, stack_offset, data: RichR[claripy.ast.BV | claripy.ast.FP], size, offset=0, stmt=None, endness=None
517
+ self, stack_offset, data: RichR[claripy.ast.BV | claripy.ast.FP], size, offset=0, atom=None, endness=None
514
518
  ):
515
- if stmt is None:
519
+ if atom is None:
516
520
  existing_vars = self.variable_manager[self.func_addr].find_variables_by_stmt(
517
521
  self.block.addr, self.stmt_idx, "memory"
518
522
  )
519
523
  else:
520
524
  existing_vars = self.variable_manager[self.func_addr].find_variables_by_atom(
521
- self.block.addr, self.stmt_idx, stmt
525
+ self.block.addr, self.stmt_idx, atom
522
526
  )
523
527
  if not existing_vars:
524
528
  variable = SimStackVariable(
@@ -562,7 +566,7 @@ class SimEngineVRBase(
562
566
  var,
563
567
  offset_into_var,
564
568
  codeloc,
565
- atom=stmt,
569
+ atom=atom,
566
570
  )
567
571
 
568
572
  # create type constraints
@@ -673,9 +677,7 @@ class SimEngineVRBase(
673
677
  self.state.add_type_constraint(typevars.Subtype(store_typevar, typeconsts.TopType()))
674
678
  self.state.add_type_constraint(typevars.Subtype(data.typevar, store_typevar))
675
679
 
676
- def _store_to_variable(
677
- self, richr_addr: RichR[claripy.ast.BV], size: int, stmt=None
678
- ): # pylint:disable=unused-argument
680
+ def _store_to_variable(self, richr_addr: RichR[claripy.ast.BV], size: int):
679
681
  addr_variable = richr_addr.variable
680
682
  codeloc = self._codeloc()
681
683
 
@@ -74,7 +74,7 @@ class SimEngineVRVEX(
74
74
  size = stmt.data.result_size(self.tyenv) // 8
75
75
  r = self._expr(stmt.data)
76
76
 
77
- self._store(addr_r, r, size, stmt=stmt)
77
+ self._store(addr_r, r, size, atom=stmt)
78
78
 
79
79
  def _handle_stmt_StoreG(self, stmt):
80
80
  guard = self._expr(stmt.guard)
@@ -82,7 +82,7 @@ class SimEngineVRVEX(
82
82
  addr = self._expr_bv(stmt.addr)
83
83
  size = stmt.data.result_size(self.tyenv) // 8
84
84
  data = self._expr(stmt.data)
85
- self._store(addr, data, size, stmt=stmt)
85
+ self._store(addr, data, size, atom=stmt)
86
86
 
87
87
  def _handle_stmt_LoadG(self, stmt):
88
88
  guard = self._expr(stmt.guard)
@@ -12,6 +12,7 @@ import ailment
12
12
  from ailment.expression import VirtualVariable
13
13
 
14
14
  import angr.errors
15
+ from angr.analyses import AnalysesHub
15
16
  from angr.storage.memory_mixins.paged_memory.pages.multi_values import MultiValues
16
17
  from angr.block import Block
17
18
  from angr.errors import AngrVariableRecoveryError, SimEngineError
@@ -19,7 +20,8 @@ from angr.knowledge_plugins import Function
19
20
  from angr.sim_variable import SimStackVariable, SimRegisterVariable, SimVariable, SimMemoryVariable
20
21
  from angr.engines.vex.claripy.irop import vexop_to_simop
21
22
  from angr.analyses import ForwardAnalysis, visitors
22
- from angr.analyses.typehoon.typevars import Equivalence, TypeVariable, TypeVariables
23
+ from angr.analyses.typehoon.typevars import Equivalence, TypeVariable, TypeVariables, Subtype, DerivedTypeVariable
24
+ from angr.analyses.typehoon.typeconsts import Int
23
25
  from .variable_recovery_base import VariableRecoveryBase, VariableRecoveryStateBase
24
26
  from .engine_vex import SimEngineVRVEX
25
27
  from .engine_ail import SimEngineVRAIL
@@ -499,6 +501,26 @@ class VariableRecoveryFast(ForwardAnalysis, VariableRecoveryBase): # pylint:dis
499
501
  for tv in sorted_typevars[1:]:
500
502
  self.type_constraints[self.func_typevar].add(Equivalence(sorted_typevars[0], tv))
501
503
 
504
+ # remove default constraints with size conflicts
505
+ for func_var in self.type_constraints:
506
+ var_to_subtyping: dict[TypeVariable, list[Subtype]] = defaultdict(list)
507
+ for constraint in self.type_constraints[func_var]:
508
+ if isinstance(constraint, Subtype) and isinstance(constraint.sub_type, TypeVariable):
509
+ var_to_subtyping[constraint.sub_type].append(constraint)
510
+
511
+ for constraints in var_to_subtyping.values():
512
+ if len(constraints) <= 1:
513
+ continue
514
+ default_subtyping_constraints = set()
515
+ has_nondefault_subtyping_constraints = False
516
+ for constraint in constraints:
517
+ if isinstance(constraint.super_type, Int):
518
+ default_subtyping_constraints.add(constraint)
519
+ elif isinstance(constraint.super_type, DerivedTypeVariable) and constraint.super_type.labels:
520
+ has_nondefault_subtyping_constraints = True
521
+ if has_nondefault_subtyping_constraints:
522
+ self.type_constraints[func_var].difference_update(default_subtyping_constraints)
523
+
502
524
  self.variable_manager[self.function.addr].ret_val_size = self.ret_val_size
503
525
 
504
526
  self.delayed_type_constraints = None
@@ -600,6 +622,4 @@ class VariableRecoveryFast(ForwardAnalysis, VariableRecoveryBase): # pylint:dis
600
622
  state.register_region.store(self.project.arch.sp_offset, sp_v)
601
623
 
602
624
 
603
- from angr.analyses import AnalysesHub
604
-
605
625
  AnalysesHub.register_default("VariableRecoveryFast", VariableRecoveryFast)
@@ -4,11 +4,14 @@ from collections import defaultdict
4
4
  from functools import cmp_to_key
5
5
 
6
6
  import networkx
7
+ from claripy import ClaripyError
7
8
 
8
9
  from angr import SIM_PROCEDURES
9
10
  from angr import options as o
11
+ from angr.analyses import AnalysesHub
10
12
  from angr.knowledge_base import KnowledgeBase
11
- from angr.errors import AngrError, AngrCFGError
13
+ from angr.errors import AngrError, AngrCFGError, SimValueError, SimSolverModeError, SimError
14
+ from angr.sim_options import BYPASS_VERITESTING_EXCEPTIONS
12
15
  from angr.sim_manager import SimulationManager
13
16
  from angr.utils.graph import shallow_reverse
14
17
  from . import Analysis, CFGEmulated
@@ -620,10 +623,4 @@ class Veritesting(Analysis):
620
623
  return [(n.addr, n.looping_times) for n in nodes]
621
624
 
622
625
 
623
- from angr.analyses import AnalysesHub
624
-
625
626
  AnalysesHub.register_default("Veritesting", Veritesting)
626
-
627
- from angr.errors import SimValueError, SimSolverModeError, SimError
628
- from angr.sim_options import BYPASS_VERITESTING_EXCEPTIONS
629
- from claripy import ClaripyError
angr/analyses/vfg.py CHANGED
@@ -651,7 +651,7 @@ class VFG(ForwardAnalysis[SimState, VFGNode, VFGJob, BlockID], Analysis): # pyl
651
651
  l.debug("%s is not recorded. Skip the job.", job)
652
652
  raise AngrSkipJobNotice
653
653
  # unwind the stack till the target, unless we see any pending jobs for each new top task
654
- for i in range(unwind_count):
654
+ for _ in range(unwind_count):
655
655
  if isinstance(self._top_task, FunctionAnalysis):
656
656
  # are there any pending job belonging to the current function that we should handle first?
657
657
  pending_job_key = self._get_pending_job(self._top_task.function_address)
angr/analyses/vsa_ddg.py CHANGED
@@ -5,6 +5,7 @@ from collections import defaultdict
5
5
  import networkx
6
6
  from . import Analysis, VFG
7
7
 
8
+ from angr.analyses import AnalysesHub
8
9
  from angr.code_location import CodeLocation
9
10
  from angr.errors import AngrDDGError
10
11
  from angr.sim_variable import SimRegisterVariable, SimMemoryVariable
@@ -416,6 +417,4 @@ class VSA_DDG(Analysis):
416
417
  return nodes
417
418
 
418
419
 
419
- from angr.analyses import AnalysesHub
420
-
421
420
  AnalysesHub.register_default("VSA_DDG", VSA_DDG)