angr 9.2.84__py3-none-win_amd64.whl → 9.2.85__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 (58) hide show
  1. angr/__init__.py +1 -1
  2. angr/analyses/cfg/cfg_base.py +6 -1
  3. angr/analyses/cfg/cfg_fast.py +32 -10
  4. angr/analyses/decompiler/clinic.py +204 -4
  5. angr/analyses/decompiler/condition_processor.py +8 -2
  6. angr/analyses/decompiler/decompiler.py +19 -17
  7. angr/analyses/decompiler/goto_manager.py +34 -51
  8. angr/analyses/decompiler/optimization_passes/__init__.py +5 -5
  9. angr/analyses/decompiler/optimization_passes/div_simplifier.py +2 -0
  10. angr/analyses/decompiler/optimization_passes/lowered_switch_simplifier.py +1 -1
  11. angr/analyses/decompiler/optimization_passes/mod_simplifier.py +2 -0
  12. angr/analyses/decompiler/optimization_passes/multi_simplifier.py +2 -0
  13. angr/analyses/decompiler/optimization_passes/optimization_pass.py +131 -3
  14. angr/analyses/decompiler/optimization_passes/ret_deduplicator.py +3 -3
  15. angr/analyses/decompiler/optimization_passes/return_duplicator.py +519 -0
  16. angr/analyses/decompiler/peephole_optimizations/constant_derefs.py +14 -2
  17. angr/analyses/decompiler/region_identifier.py +8 -2
  18. angr/analyses/decompiler/region_simplifiers/goto.py +5 -4
  19. angr/analyses/decompiler/structured_codegen/c.py +33 -1
  20. angr/analyses/decompiler/structuring/phoenix.py +3 -1
  21. angr/analyses/decompiler/structuring/structurer_nodes.py +11 -5
  22. angr/analyses/decompiler/utils.py +50 -0
  23. angr/analyses/disassembly.py +10 -3
  24. angr/analyses/propagator/engine_ail.py +125 -0
  25. angr/analyses/reaching_definitions/engine_ail.py +36 -2
  26. angr/analyses/reaching_definitions/rd_initializer.py +15 -1
  27. angr/analyses/reaching_definitions/rd_state.py +9 -4
  28. angr/analyses/stack_pointer_tracker.py +10 -17
  29. angr/analyses/variable_recovery/engine_ail.py +27 -1
  30. angr/angrdb/serializers/loader.py +10 -3
  31. angr/calling_conventions.py +2 -0
  32. angr/engines/pcode/behavior.py +7 -2
  33. angr/engines/pcode/cc.py +1 -0
  34. angr/engines/pcode/emulate.py +144 -104
  35. angr/engines/pcode/lifter.py +135 -79
  36. angr/knowledge_plugins/functions/function_manager.py +5 -3
  37. angr/knowledge_plugins/propagations/states.py +14 -0
  38. angr/lib/angr_native.dll +0 -0
  39. angr/procedures/cgc/deallocate.py +5 -2
  40. angr/procedures/posix/gethostbyname.py +23 -8
  41. angr/project.py +4 -0
  42. angr/simos/__init__.py +2 -0
  43. angr/simos/simos.py +1 -0
  44. angr/simos/snimmuc_nxp.py +152 -0
  45. angr/state_plugins/history.py +3 -1
  46. angr/utils/graph.py +20 -18
  47. {angr-9.2.84.dist-info → angr-9.2.85.dist-info}/METADATA +9 -8
  48. {angr-9.2.84.dist-info → angr-9.2.85.dist-info}/RECORD +57 -55
  49. tests/analyses/cfg/test_cfg_rust_got_resolution.py +2 -1
  50. tests/analyses/cfg/test_jumptables.py +2 -1
  51. tests/analyses/decompiler/test_decompiler.py +130 -103
  52. tests/engines/pcode/test_emulate.py +607 -0
  53. tests/serialization/test_db.py +30 -0
  54. angr/analyses/decompiler/optimization_passes/eager_returns.py +0 -285
  55. {angr-9.2.84.dist-info → angr-9.2.85.dist-info}/LICENSE +0 -0
  56. {angr-9.2.84.dist-info → angr-9.2.85.dist-info}/WHEEL +0 -0
  57. {angr-9.2.84.dist-info → angr-9.2.85.dist-info}/entry_points.txt +0 -0
  58. {angr-9.2.84.dist-info → angr-9.2.85.dist-info}/top_level.txt +0 -0
@@ -1,11 +1,13 @@
1
1
  import logging
2
2
 
3
3
  from ailment import Expr
4
+ from unique_log_filter import UniqueLogFilter
4
5
 
5
6
  from .engine_base import SimplifierAILEngine, SimplifierAILState
6
7
  from .optimization_pass import OptimizationPass, OptimizationPassStage
7
8
 
8
9
  _l = logging.getLogger(name=__name__)
10
+ _l.addFilter(UniqueLogFilter())
9
11
 
10
12
 
11
13
  class ModSimplifierAILEngine(SimplifierAILEngine):
@@ -1,11 +1,13 @@
1
1
  import logging
2
2
 
3
3
  from ailment import Expr
4
+ from unique_log_filter import UniqueLogFilter
4
5
 
5
6
  from .engine_base import SimplifierAILEngine, SimplifierAILState
6
7
  from .optimization_pass import OptimizationPass, OptimizationPassStage
7
8
 
8
9
  _l = logging.getLogger(name=__name__)
10
+ _l.addFilter(UniqueLogFilter())
9
11
 
10
12
 
11
13
  class MultiSimplifierAILEngine(SimplifierAILEngine):
@@ -3,9 +3,12 @@ from typing import Optional, Dict, Set, Tuple, Generator, TYPE_CHECKING
3
3
  from enum import Enum
4
4
 
5
5
  import networkx # pylint:disable=unused-import
6
-
7
6
  import ailment
8
7
 
8
+ from angr.analyses.decompiler import RegionIdentifier
9
+ from angr.analyses.decompiler.goto_manager import GotoManager
10
+ from angr.analyses.decompiler.structuring import RecursiveStructurer, PhoenixStructurer
11
+ from angr.analyses.decompiler.utils import add_labels
9
12
 
10
13
  if TYPE_CHECKING:
11
14
  from angr.knowledge_plugins.functions import Function
@@ -17,8 +20,6 @@ class MultipleBlocksException(Exception):
17
20
  requested.
18
21
  """
19
22
 
20
- pass
21
-
22
23
 
23
24
  class OptimizationPassStage(Enum):
24
25
  """
@@ -234,3 +235,130 @@ class SequenceOptimizationPass(BaseOptimizationPass):
234
235
  super().__init__(func)
235
236
  self.seq = seq
236
237
  self.out_seq = None
238
+
239
+
240
+ class StructuringOptimizationPass(OptimizationPass):
241
+ """
242
+ The base class for any optimization pass that requires structuring. Optimization passes that inherit from this class
243
+ should directly depend on structuring artifacts, such as regions and gotos. Otherwise, they should use
244
+ OptimizationPass. This is the heaviest (computation time) optimization pass class.
245
+ """
246
+
247
+ ARCHES = None
248
+ PLATFORMS = None
249
+ STAGE = OptimizationPassStage.DURING_REGION_IDENTIFICATION
250
+
251
+ def __init__(
252
+ self, func, prevent_new_gotos=True, recover_structure_fails=True, max_opt_iters=1, simplify_ail=True, **kwargs
253
+ ):
254
+ super().__init__(func, **kwargs)
255
+ self._prevent_new_gotos = prevent_new_gotos
256
+ self._recover_structure_fails = recover_structure_fails
257
+ self._max_opt_iters = max_opt_iters
258
+ self._simplify_ail = simplify_ail
259
+
260
+ self._goto_manager: Optional[GotoManager] = None
261
+ self._prev_graph: Optional[networkx.DiGraph] = None
262
+
263
+ def _analyze(self, cache=None) -> bool:
264
+ raise NotImplementedError()
265
+
266
+ def analyze(self):
267
+ """
268
+ Wrapper for _analyze() that verifies the graph is structurable before and after the optimization.
269
+ """
270
+ if not self._graph_is_structurable(self._graph):
271
+ return
272
+
273
+ initial_gotos = self._goto_manager.gotos.copy()
274
+ # replace the normal check in OptimizationPass.analyze()
275
+ ret, cache = self._check()
276
+ if not ret:
277
+ return
278
+
279
+ # setup for the very first analysis
280
+ self.out_graph = networkx.DiGraph(self._graph)
281
+ if self._max_opt_iters > 1:
282
+ self._fixed_point_analyze(cache=cache)
283
+ else:
284
+ updates = self._analyze(cache=cache)
285
+ if not updates:
286
+ self.out_graph = None
287
+
288
+ # analysis is complete, no out_graph means it failed somewhere along the way
289
+ if self.out_graph is None:
290
+ return
291
+
292
+ if not self._graph_is_structurable(self.out_graph):
293
+ self.out_graph = None
294
+ return
295
+
296
+ # simplify the AIL graph
297
+ if self._simplify_ail:
298
+ # this should not (TM) change the structure of the graph but is needed for later optimizations
299
+ self.out_graph = self._simplify_ail_graph(self.out_graph)
300
+
301
+ if self._prevent_new_gotos and (len(self._goto_manager.gotos) > len(initial_gotos)):
302
+ self.out_graph = None
303
+ return
304
+
305
+ def _fixed_point_analyze(self, cache=None):
306
+ for _ in range(self._max_opt_iters):
307
+ # backup the graph before the optimization
308
+ if self._recover_structure_fails and self.out_graph is not None:
309
+ self._prev_graph = networkx.DiGraph(self.out_graph)
310
+
311
+ # run the optimization, output applied to self.out_graph
312
+ changes = self._analyze(cache=cache)
313
+ if not changes:
314
+ break
315
+
316
+ # check if the graph is structurable
317
+ if not self._graph_is_structurable(self.out_graph):
318
+ self.out_graph = self._prev_graph if self._recover_structure_fails else None
319
+ break
320
+
321
+ def _simplify_ail_graph(self, graph):
322
+ simp = self.project.analyses.AILSimplifier(
323
+ self._func,
324
+ func_graph=graph,
325
+ gp=self._func.info.get("gp", None) if self.project.arch.name in {"MIPS32", "MIPS64"} else None,
326
+ )
327
+ return simp.func_graph if simp.simplified else graph
328
+
329
+ def _graph_is_structurable(self, graph, readd_labels=False) -> bool:
330
+ """
331
+ Checks weather the input graph is structurable under the Phoenix schema-matching structuring algorithm.
332
+ As a side effect, this will also update the region identifier and goto manager of this optimization pass.
333
+ Consequently, a true return guarantees up-to-date goto information in the goto manager.
334
+ """
335
+ if readd_labels:
336
+ graph = add_labels(graph)
337
+
338
+ self._ri = self.project.analyses[RegionIdentifier].prep(kb=self.kb)(
339
+ self._func,
340
+ graph=graph,
341
+ # never update the graph in-place, we need to keep the original graph for later use
342
+ update_graph=False,
343
+ cond_proc=self._ri.cond_proc,
344
+ force_loop_single_exit=False,
345
+ complete_successors=True,
346
+ )
347
+ if self._ri is None:
348
+ return False
349
+
350
+ rs = self.project.analyses[RecursiveStructurer].prep(kb=self.kb)(
351
+ self._ri.region,
352
+ cond_proc=self._ri.cond_proc,
353
+ func=self._func,
354
+ structurer_cls=PhoenixStructurer,
355
+ )
356
+ if not rs or not rs.result or not rs.result.nodes:
357
+ return False
358
+
359
+ rs = self.project.analyses.RegionSimplifier(self._func, rs.result, kb=self.kb, variable_kb=self._variable_kb)
360
+ if not rs or rs.goto_manager is None:
361
+ return False
362
+
363
+ self._goto_manager = rs.goto_manager
364
+ return True
@@ -6,7 +6,7 @@ from ailment import Block
6
6
  from ailment.statement import ConditionalJump, Return
7
7
 
8
8
  from ....utils.graph import subgraph_between_nodes
9
- from ..utils import remove_labels, to_ail_supergraph
9
+ from ..utils import remove_labels, to_ail_supergraph, update_labels
10
10
  from .optimization_pass import OptimizationPass, OptimizationPassStage
11
11
 
12
12
 
@@ -26,7 +26,7 @@ class ReturnDeduplicator(OptimizationPass):
26
26
 
27
27
  ARCHES = ["X86", "AMD64", "ARMEL", "ARMHF", "ARMCortexM", "MIPS32", "MIPS64"]
28
28
  PLATFORMS = ["windows", "linux", "cgc"]
29
- STAGE = OptimizationPassStage.AFTER_GLOBAL_SIMPLIFICATION
29
+ STAGE = OptimizationPassStage.DURING_REGION_IDENTIFICATION
30
30
  NAME = "Deduplicates return statements that may have been duplicated"
31
31
  DESCRIPTION = __doc__.strip()
32
32
 
@@ -44,7 +44,7 @@ class ReturnDeduplicator(OptimizationPass):
44
44
  graph_updated |= self._fix_if_ret_region(region_head, true_child, false_child, super_true, super_false)
45
45
 
46
46
  if graph_updated:
47
- self.out_graph = self._graph
47
+ self.out_graph = update_labels(self._graph)
48
48
 
49
49
  def _fix_if_ret_region(self, region_head, true_child, false_child, super_true, super_false):
50
50
  """