angr 9.2.134__py3-none-win_amd64.whl → 9.2.136__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 (174) hide show
  1. angr/__init__.py +1 -1
  2. angr/analyses/__init__.py +5 -8
  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/__init__.py +6 -0
  10. angr/analyses/{calling_convention.py → calling_convention/calling_convention.py} +32 -64
  11. angr/analyses/calling_convention/fact_collector.py +502 -0
  12. angr/analyses/calling_convention/utils.py +57 -0
  13. angr/analyses/cdg.py +1 -2
  14. angr/analyses/cfg/cfb.py +1 -3
  15. angr/analyses/cfg/cfg.py +2 -2
  16. angr/analyses/cfg/cfg_base.py +37 -35
  17. angr/analyses/cfg/cfg_emulated.py +1 -1
  18. angr/analyses/cfg/cfg_fast.py +62 -15
  19. angr/analyses/cfg/cfg_fast_soot.py +1 -1
  20. angr/analyses/cfg/indirect_jump_resolvers/__init__.py +2 -0
  21. angr/analyses/cfg/indirect_jump_resolvers/const_resolver.py +46 -10
  22. angr/analyses/cfg/indirect_jump_resolvers/default_resolvers.py +5 -1
  23. angr/analyses/cfg/indirect_jump_resolvers/jumptable.py +50 -14
  24. angr/analyses/cfg/indirect_jump_resolvers/memload_resolver.py +81 -0
  25. angr/analyses/cfg/indirect_jump_resolvers/propagator_utils.py +24 -5
  26. angr/analyses/cfg/indirect_jump_resolvers/x86_pe_iat.py +2 -5
  27. angr/analyses/complete_calling_conventions.py +32 -3
  28. angr/analyses/congruency_check.py +2 -3
  29. angr/analyses/data_dep/data_dependency_analysis.py +2 -2
  30. angr/analyses/ddg.py +1 -4
  31. angr/analyses/decompiler/ail_simplifier.py +3 -4
  32. angr/analyses/decompiler/clinic.py +42 -7
  33. angr/analyses/decompiler/optimization_passes/duplication_reverter/ail_merge_graph.py +2 -2
  34. angr/analyses/decompiler/optimization_passes/duplication_reverter/duplication_reverter.py +2 -2
  35. angr/analyses/decompiler/optimization_passes/ite_region_converter.py +1 -1
  36. angr/analyses/decompiler/optimization_passes/lowered_switch_simplifier.py +1 -1
  37. angr/analyses/decompiler/optimization_passes/register_save_area_simplifier.py +0 -6
  38. angr/analyses/decompiler/optimization_passes/stack_canary_simplifier.py +2 -7
  39. angr/analyses/decompiler/optimization_passes/switch_default_case_duplicator.py +0 -6
  40. angr/analyses/decompiler/optimization_passes/win_stack_canary_simplifier.py +0 -6
  41. angr/analyses/decompiler/structuring/phoenix.py +1 -1
  42. angr/analyses/disassembly.py +5 -5
  43. angr/analyses/fcp/__init__.py +4 -0
  44. angr/analyses/fcp/fcp.py +429 -0
  45. angr/analyses/identifier/identify.py +1 -3
  46. angr/analyses/loopfinder.py +4 -3
  47. angr/analyses/patchfinder.py +1 -1
  48. angr/analyses/propagator/engine_base.py +4 -3
  49. angr/analyses/propagator/propagator.py +14 -53
  50. angr/analyses/reassembler.py +1 -2
  51. angr/analyses/s_propagator.py +1 -3
  52. angr/analyses/soot_class_hierarchy.py +1 -2
  53. angr/analyses/stack_pointer_tracker.py +18 -2
  54. angr/analyses/static_hooker.py +1 -2
  55. angr/analyses/typehoon/simple_solver.py +2 -2
  56. angr/analyses/variable_recovery/engine_vex.py +5 -0
  57. angr/analyses/variable_recovery/variable_recovery_fast.py +1 -2
  58. angr/analyses/veritesting.py +4 -7
  59. angr/analyses/vfg.py +1 -1
  60. angr/analyses/vsa_ddg.py +1 -2
  61. angr/block.py +3 -2
  62. angr/callable.py +1 -3
  63. angr/calling_conventions.py +15 -7
  64. angr/codenode.py +5 -1
  65. angr/concretization_strategies/__init__.py +1 -83
  66. angr/concretization_strategies/any.py +2 -1
  67. angr/concretization_strategies/any_named.py +1 -1
  68. angr/concretization_strategies/base.py +81 -0
  69. angr/concretization_strategies/controlled_data.py +2 -1
  70. angr/concretization_strategies/eval.py +2 -1
  71. angr/concretization_strategies/logging.py +3 -1
  72. angr/concretization_strategies/max.py +2 -1
  73. angr/concretization_strategies/nonzero.py +2 -1
  74. angr/concretization_strategies/nonzero_range.py +2 -1
  75. angr/concretization_strategies/norepeats.py +2 -1
  76. angr/concretization_strategies/norepeats_range.py +2 -1
  77. angr/concretization_strategies/range.py +2 -1
  78. angr/concretization_strategies/signed_add.py +2 -1
  79. angr/concretization_strategies/single.py +2 -1
  80. angr/concretization_strategies/solutions.py +2 -1
  81. angr/concretization_strategies/unlimited_range.py +2 -1
  82. angr/engines/__init__.py +8 -5
  83. angr/engines/engine.py +3 -5
  84. angr/engines/failure.py +4 -5
  85. angr/engines/procedure.py +5 -7
  86. angr/engines/soot/expressions/__init__.py +22 -23
  87. angr/engines/soot/expressions/base.py +4 -4
  88. angr/engines/soot/expressions/invoke.py +1 -2
  89. angr/engines/soot/statements/__init__.py +9 -10
  90. angr/engines/soot/values/__init__.py +9 -10
  91. angr/engines/soot/values/arrayref.py +3 -3
  92. angr/engines/soot/values/instancefieldref.py +3 -2
  93. angr/engines/successors.py +7 -6
  94. angr/engines/syscall.py +4 -6
  95. angr/engines/unicorn.py +3 -2
  96. angr/engines/vex/claripy/ccall.py +8 -10
  97. angr/engines/vex/claripy/datalayer.py +4 -5
  98. angr/exploration_techniques/__init__.py +0 -2
  99. angr/exploration_techniques/spiller.py +1 -3
  100. angr/exploration_techniques/stochastic.py +2 -3
  101. angr/factory.py +3 -9
  102. angr/knowledge_plugins/cfg/cfg_model.py +20 -17
  103. angr/knowledge_plugins/functions/function.py +74 -77
  104. angr/knowledge_plugins/functions/function_manager.py +14 -7
  105. angr/knowledge_plugins/functions/function_parser.py +1 -1
  106. angr/knowledge_plugins/functions/soot_function.py +16 -16
  107. angr/knowledge_plugins/propagations/propagation_model.py +4 -5
  108. angr/knowledge_plugins/propagations/states.py +0 -511
  109. angr/lib/angr_native.dll +0 -0
  110. angr/procedures/libc/memcpy.py +4 -4
  111. angr/procedures/procedure_dict.py +3 -2
  112. angr/protos/__init__.py +2 -5
  113. angr/protos/cfg_pb2.py +21 -18
  114. angr/protos/function_pb2.py +17 -14
  115. angr/protos/primitives_pb2.py +44 -39
  116. angr/protos/variables_pb2.py +36 -31
  117. angr/protos/xrefs_pb2.py +15 -12
  118. angr/sim_procedure.py +15 -16
  119. angr/sim_variable.py +13 -1
  120. angr/simos/__init__.py +2 -0
  121. angr/simos/javavm.py +4 -6
  122. angr/simos/xbox.py +32 -0
  123. angr/state_plugins/__init__.py +0 -2
  124. angr/state_plugins/callstack.py +4 -4
  125. angr/state_plugins/cgc.py +3 -2
  126. angr/state_plugins/gdb.py +6 -5
  127. angr/state_plugins/globals.py +1 -2
  128. angr/state_plugins/heap/heap_brk.py +1 -2
  129. angr/state_plugins/history.py +10 -12
  130. angr/state_plugins/inspect.py +3 -5
  131. angr/state_plugins/libc.py +2 -2
  132. angr/state_plugins/log.py +8 -10
  133. angr/state_plugins/loop_data.py +1 -2
  134. angr/state_plugins/posix.py +7 -7
  135. angr/state_plugins/preconstrainer.py +2 -3
  136. angr/state_plugins/scratch.py +5 -8
  137. angr/state_plugins/sim_action.py +3 -3
  138. angr/state_plugins/solver.py +8 -3
  139. angr/state_plugins/symbolizer.py +5 -4
  140. angr/state_plugins/uc_manager.py +3 -3
  141. angr/state_plugins/unicorn_engine.py +5 -1
  142. angr/state_plugins/view.py +3 -5
  143. angr/storage/file.py +3 -5
  144. angr/storage/memory_mixins/address_concretization_mixin.py +2 -2
  145. angr/storage/memory_mixins/bvv_conversion_mixin.py +3 -3
  146. angr/storage/memory_mixins/clouseau_mixin.py +1 -3
  147. angr/storage/memory_mixins/name_resolution_mixin.py +1 -3
  148. angr/storage/memory_mixins/paged_memory/paged_memory_mixin.py +13 -15
  149. angr/storage/memory_mixins/paged_memory/pages/__init__.py +1 -22
  150. angr/storage/memory_mixins/paged_memory/pages/base.py +31 -0
  151. angr/storage/memory_mixins/paged_memory/pages/list_page.py +1 -1
  152. angr/storage/memory_mixins/paged_memory/pages/mv_list_page.py +1 -1
  153. angr/storage/memory_mixins/paged_memory/pages/ultra_page.py +2 -4
  154. angr/storage/memory_mixins/paged_memory/privileged_mixin.py +3 -4
  155. angr/storage/memory_mixins/regioned_memory/abstract_merger_mixin.py +4 -2
  156. angr/storage/memory_mixins/smart_find_mixin.py +1 -1
  157. angr/storage/memory_mixins/underconstrained_mixin.py +1 -1
  158. angr/storage/memory_mixins/unwrapper_mixin.py +1 -3
  159. angr/utils/bits.py +13 -0
  160. angr/utils/enums_conv.py +28 -12
  161. angr/utils/segment_list.py +25 -22
  162. angr/utils/timing.py +18 -1
  163. angr/vaults.py +5 -6
  164. {angr-9.2.134.dist-info → angr-9.2.136.dist-info}/METADATA +6 -6
  165. {angr-9.2.134.dist-info → angr-9.2.136.dist-info}/RECORD +169 -165
  166. {angr-9.2.134.dist-info → angr-9.2.136.dist-info}/WHEEL +1 -1
  167. angr/analyses/propagator/outdated_definition_walker.py +0 -159
  168. angr/analyses/propagator/tmpvar_finder.py +0 -18
  169. angr/engines/concrete.py +0 -180
  170. angr/exploration_techniques/symbion.py +0 -80
  171. angr/state_plugins/concrete.py +0 -295
  172. {angr-9.2.134.dist-info → angr-9.2.136.dist-info}/LICENSE +0 -0
  173. {angr-9.2.134.dist-info → angr-9.2.136.dist-info}/entry_points.txt +0 -0
  174. {angr-9.2.134.dist-info → angr-9.2.136.dist-info}/top_level.txt +0 -0
@@ -17,11 +17,7 @@ from angr.storage.memory_object import SimMemoryObject, SimLabeledMemoryObject
17
17
  from angr.storage.memory_mixins import LabeledMemory
18
18
  from angr.engines.light.engine import SimEngineLight
19
19
  from angr.code_location import CodeLocation
20
- from angr.knowledge_plugins.key_definitions import atoms
21
- from angr.knowledge_plugins.key_definitions.constants import OP_BEFORE
22
- from angr.engines.light.data import SpOffset
23
20
 
24
- from .prop_value import PropValue, Detail
25
21
 
26
22
  if TYPE_CHECKING:
27
23
  from archinfo import Arch
@@ -55,7 +51,6 @@ class PropagatorState:
55
51
  :ivar arch: Architecture of the binary.
56
52
  :ivar gp: value of the global pointer for MIPS binaries.
57
53
  :ivar _replacements: Stores expressions to replace, keyed by CodeLocation instances
58
- :ivar _equivalence: Stores equivalence constraints that Propagator discovers during the analysis.
59
54
  :ivar _only_consts: Only track constants.
60
55
  :ivar _expr_used_locs: A dict keyed by expressions and valued by CodeLocations where the expression is used.
61
56
  :ivar _max_prop_expr_occurrence: The upperbound for the number of occurrences of an expression for Propagator
@@ -67,7 +62,6 @@ class PropagatorState:
67
62
  __slots__ = (
68
63
  "__weakref__",
69
64
  "_artificial_reg_offsets",
70
- "_equivalence",
71
65
  "_expr_used_locs",
72
66
  "_gp",
73
67
  "_max_prop_expr_occurrence",
@@ -78,7 +72,6 @@ class PropagatorState:
78
72
  "gpr_size",
79
73
  "model",
80
74
  "project",
81
- "rda",
82
75
  )
83
76
 
84
77
  _tops = {}
@@ -87,11 +80,9 @@ class PropagatorState:
87
80
  self,
88
81
  arch: Arch,
89
82
  project: Project | None = None,
90
- rda=None,
91
83
  replacements: defaultdict[CodeLocation, dict] | None = None,
92
84
  only_consts: bool = False,
93
85
  expr_used_locs: defaultdict[Any, set[CodeLocation]] | None = None,
94
- equivalence: set[Equivalence] | None = None,
95
86
  store_tops: bool = True,
96
87
  gp: int | None = None,
97
88
  max_prop_expr_occurrence: int = 1,
@@ -105,7 +96,6 @@ class PropagatorState:
105
96
  self._expr_used_locs = defaultdict(list) if expr_used_locs is None else expr_used_locs
106
97
  self._only_consts = only_consts
107
98
  self._replacements = defaultdict(dict) if replacements is None else replacements
108
- self._equivalence: set[Equivalence] = equivalence if equivalence is not None else set()
109
99
  self._store_tops = store_tops
110
100
  self._max_prop_expr_occurrence = max_prop_expr_occurrence
111
101
  self._artificial_reg_offsets = artificial_reg_offsets if artificial_reg_offsets is not None else set()
@@ -115,7 +105,6 @@ class PropagatorState:
115
105
 
116
106
  self.project = project
117
107
  self.model = model
118
- self.rda = rda
119
108
 
120
109
  def __repr__(self) -> str:
121
110
  return "<PropagatorState>"
@@ -124,7 +113,6 @@ class PropagatorState:
124
113
  def initial_state(
125
114
  cls,
126
115
  project: Project,
127
- rda=None,
128
116
  only_consts=False,
129
117
  gp=None,
130
118
  do_binops=True,
@@ -257,10 +245,6 @@ class PropagatorState:
257
245
  for o in others:
258
246
  merge_occurred |= PropagatorState.merge_replacements(state._replacements, o._replacements)
259
247
 
260
- if state._equivalence != o._equivalence:
261
- merge_occurred = True
262
- state._equivalence |= o._equivalence
263
-
264
248
  return state, merge_occurred
265
249
 
266
250
  def init_replacements(self):
@@ -378,7 +362,6 @@ class PropagatorVEXState(PropagatorState):
378
362
  self,
379
363
  arch,
380
364
  project=None,
381
- rda=None,
382
365
  registers=None,
383
366
  local_variables=None,
384
367
  replacements=None,
@@ -395,7 +378,6 @@ class PropagatorVEXState(PropagatorState):
395
378
  super().__init__(
396
379
  arch,
397
380
  project=project,
398
- rda=rda,
399
381
  replacements=replacements,
400
382
  only_consts=only_consts,
401
383
  expr_used_locs=expr_used_locs,
@@ -430,7 +412,6 @@ class PropagatorVEXState(PropagatorState):
430
412
  def initial_state(
431
413
  cls,
432
414
  project,
433
- rda=None,
434
415
  only_consts=False,
435
416
  gp=None,
436
417
  do_binops=True,
@@ -443,7 +424,6 @@ class PropagatorVEXState(PropagatorState):
443
424
  state = cls(
444
425
  project.arch,
445
426
  project=project,
446
- rda=rda,
447
427
  only_consts=only_consts,
448
428
  do_binops=do_binops,
449
429
  store_tops=store_tops,
@@ -483,7 +463,6 @@ class PropagatorVEXState(PropagatorState):
483
463
  return PropagatorVEXState(
484
464
  self.arch,
485
465
  project=self.project,
486
- rda=self.rda,
487
466
  registers=self._registers.copy(),
488
467
  local_variables=self._stack_variables.copy(),
489
468
  replacements=self._replacements.copy(),
@@ -519,11 +498,6 @@ class PropagatorVEXState(PropagatorState):
519
498
  self._registers.store(offset, value, size=size)
520
499
 
521
500
  def load_register(self, offset, size):
522
- # TODO: Fix me
523
- # load register even if size != self.gpr_size
524
- # if size != self.gpr_size:
525
- # return self.top(size * self.arch.byte_width).annotate(RegisterAnnotation(offset, size))
526
-
527
501
  try:
528
502
  v = self._registers.load(offset, size=size)
529
503
  if self.is_top(v):
@@ -573,488 +547,3 @@ class Equivalence:
573
547
 
574
548
  def __hash__(self):
575
549
  return hash((Equivalence, self.codeloc, self.atom0, self.atom1))
576
-
577
-
578
- class PropagatorAILState(PropagatorState):
579
- """
580
- Describes the state used in the AIL engine of Propagator.
581
- """
582
-
583
- __slots__ = (
584
- "_registers",
585
- "_sp_adjusted",
586
- "_stack_variables",
587
- "_tmps",
588
- "block_initial_reg_values",
589
- "global_stores",
590
- "last_stack_store",
591
- "register_expressions",
592
- "temp_expressions",
593
- )
594
-
595
- def __init__(
596
- self,
597
- arch,
598
- project=None,
599
- rda=None,
600
- replacements=None,
601
- only_consts=False,
602
- expr_used_locs=None,
603
- equivalence=None,
604
- stack_variables=None,
605
- registers=None,
606
- gp=None,
607
- block_initial_reg_values=None,
608
- max_prop_expr_occurrence: int = 1,
609
- sp_adjusted: bool = False,
610
- model=None,
611
- artificial_reg_offsets=None,
612
- ):
613
- super().__init__(
614
- arch,
615
- project=project,
616
- rda=rda,
617
- replacements=replacements,
618
- only_consts=only_consts,
619
- expr_used_locs=expr_used_locs,
620
- equivalence=equivalence,
621
- gp=gp,
622
- max_prop_expr_occurrence=max_prop_expr_occurrence,
623
- model=model,
624
- artificial_reg_offsets=artificial_reg_offsets,
625
- )
626
-
627
- self._stack_variables = (
628
- LabeledMemory(memory_id="mem", top_func=self.top, page_kwargs={"mo_cmp": self._mo_cmp})
629
- if stack_variables is None
630
- else stack_variables
631
- )
632
- self._registers = (
633
- LabeledMemory(memory_id="reg", top_func=self.top, page_kwargs={"mo_cmp": self._mo_cmp})
634
- if registers is None
635
- else registers
636
- )
637
- self._tmps = {}
638
- self.temp_expressions = {}
639
- self.register_expressions = {}
640
- self.block_initial_reg_values: defaultdict[
641
- tuple[int, int], list[tuple[ailment.Expr.Register, ailment.Expr.Const]]
642
- ] = (defaultdict(list) if block_initial_reg_values is None else block_initial_reg_values)
643
- self._sp_adjusted: bool = sp_adjusted
644
-
645
- self._registers.set_state(self)
646
- self._stack_variables.set_state(self)
647
- # last_stack_store stores the most recent stack store statement with a non-concrete or unresolvable address. we
648
- # use this information to determine if stack reads after this store can be safely resolved to definitions prior
649
- # to the stack read.
650
- self.last_stack_store: tuple[int, int, ailment.Stmt.Store] | None = None
651
- self.global_stores: list[tuple[int, int, Any, ailment.Stmt.Store]] = []
652
-
653
- def __repr__(self):
654
- return "<PropagatorAILState>"
655
-
656
- @classmethod
657
- def initial_state(
658
- cls,
659
- project: Project,
660
- rda=None,
661
- only_consts=False,
662
- gp=None,
663
- do_binops=True,
664
- store_tops=False,
665
- func_addr=None,
666
- max_prop_expr_occurrence=None,
667
- initial_codeloc=None,
668
- model=None,
669
- ):
670
- state = cls(
671
- project.arch,
672
- project=project,
673
- rda=rda,
674
- only_consts=only_consts,
675
- gp=gp,
676
- max_prop_expr_occurrence=max_prop_expr_occurrence,
677
- model=model,
678
- )
679
- spoffset_var = ailment.Expr.StackBaseOffset(None, project.arch.bits, 0)
680
- sp_value = PropValue(
681
- claripy.BVV(0x7FFF_FF00, project.arch.bits),
682
- offset_and_details={0: Detail(project.arch.bytes, spoffset_var, initial_codeloc)},
683
- )
684
- state.store_register(
685
- ailment.Expr.Register(None, None, project.arch.sp_offset, project.arch.bits),
686
- sp_value,
687
- )
688
-
689
- if project.arch.name == "MIPS64":
690
- if func_addr is not None:
691
- reg_expr = ailment.Expr.Register(
692
- None, None, project.arch.registers["t9"][0], project.arch.registers["t9"][1]
693
- )
694
- reg_value = ailment.Expr.Const(None, None, func_addr, 64)
695
- state.store_register(
696
- reg_expr,
697
- PropValue(
698
- claripy.BVV(func_addr, 64),
699
- offset_and_details={0: Detail(8, reg_value, initial_codeloc)},
700
- ),
701
- )
702
- elif project.arch.name == "MIPS32":
703
- if func_addr is not None:
704
- reg_expr = ailment.Expr.Register(
705
- None, None, project.arch.registers["t9"][0], project.arch.registers["t9"][1]
706
- )
707
- reg_value = ailment.Expr.Const(None, None, func_addr, 32)
708
- state.store_register(
709
- reg_expr,
710
- PropValue(
711
- claripy.BVV(func_addr, 32),
712
- offset_and_details={0: Detail(4, reg_value, initial_codeloc)},
713
- ),
714
- )
715
- elif archinfo.arch_arm.is_arm_arch(project.arch):
716
- # clear fpscr
717
- reg_expr = ailment.Expr.Register(None, None, *project.arch.registers["fpscr"])
718
- reg_value = ailment.Expr.Const(None, None, 0, 32)
719
- state.store_register(
720
- reg_expr,
721
- PropValue(claripy.BVV(0, 32), offset_and_details={0: Detail(4, reg_value, initial_codeloc)}),
722
- )
723
-
724
- elif project.arch.name.startswith("PowerPC:"):
725
- # pcode PowerPC
726
- state._artificial_reg_offsets = {project.arch.registers["tea"][0]}
727
-
728
- # clear xer_so
729
- reg_expr = ailment.Expr.Register(None, None, *project.arch.registers["xer_so"])
730
- reg_value = ailment.Expr.Const(None, None, 0, 8)
731
- state.store_register(
732
- reg_expr,
733
- PropValue(claripy.BVV(0, 8), offset_and_details={0: Detail(1, reg_value, initial_codeloc)}),
734
- )
735
-
736
- if (
737
- project is not None
738
- and project.simos is not None
739
- and project.simos.function_initial_registers
740
- and func_addr is not None
741
- ):
742
- for reg_name, reg_value in project.simos.function_initial_registers.items():
743
- reg_size = project.arch.registers[reg_name][1]
744
- reg_expr = ailment.Expr.Register(None, None, project.arch.registers[reg_name][0], reg_size)
745
- reg_value_expr = ailment.Expr.Const(None, None, reg_value, reg_size * 8)
746
- state.store_register(
747
- reg_expr,
748
- PropValue(
749
- claripy.BVV(reg_value, project.arch.bits),
750
- offset_and_details={0: Detail(reg_size, reg_value_expr, initial_codeloc)},
751
- ),
752
- )
753
-
754
- return state
755
-
756
- def copy(self) -> PropagatorAILState:
757
- return PropagatorAILState(
758
- self.arch,
759
- project=self.project,
760
- rda=self.rda,
761
- replacements=self._replacements.copy(),
762
- expr_used_locs=self._expr_used_locs.copy(),
763
- only_consts=self._only_consts,
764
- equivalence=self._equivalence.copy(),
765
- stack_variables=self._stack_variables.copy(),
766
- registers=self._registers.copy(),
767
- block_initial_reg_values=self.block_initial_reg_values.copy(),
768
- # drop tmps
769
- gp=self._gp,
770
- max_prop_expr_occurrence=self._max_prop_expr_occurrence,
771
- sp_adjusted=self._sp_adjusted,
772
- model=self.model,
773
- artificial_reg_offsets=self._artificial_reg_offsets,
774
- )
775
-
776
- @staticmethod
777
- def is_const_or_register(value: ailment.Expr.Expression | claripy.ast.Bits | None) -> bool:
778
- if value is None:
779
- return False
780
- if isinstance(value, claripy.ast.BV):
781
- return not value.symbolic
782
- if isinstance(value, ailment.Expr.Register):
783
- return True
784
- if isinstance(value, ailment.Expr.Const) or (isinstance(value, int) and value == 0):
785
- return True
786
- if isinstance(value, ailment.Expr.StackBaseOffset):
787
- return True
788
- # more hacks: also store the eq comparisons
789
- if (
790
- isinstance(value, ailment.Expr.BinaryOp)
791
- and value.op == "CmpEQ"
792
- and all(isinstance(arg, (ailment.Expr.Const, ailment.Expr.Tmp)) for arg in value.operands)
793
- ):
794
- return True
795
- # more hacks: also store the conversions
796
- return bool(isinstance(value, ailment.Expr.Convert) and PropagatorAILState.is_const_or_register(value.operand))
797
-
798
- def merge(self, *others) -> tuple[PropagatorAILState, bool]:
799
- state, merge_occurred = super().merge(*others)
800
- state: PropagatorAILState
801
-
802
- merge_occurred |= state._registers.merge([o._registers for o in others], None)
803
- merge_occurred |= state._stack_variables.merge([o._stack_variables for o in others], None)
804
-
805
- return state, merge_occurred
806
-
807
- def store_temp(self, tmp_idx: int, value: PropValue):
808
- self._tmps[tmp_idx] = value
809
-
810
- def load_tmp(self, tmp_idx: int) -> PropValue | None:
811
- return self._tmps.get(tmp_idx, None)
812
-
813
- def store_register(self, reg: ailment.Expr.Register, value: PropValue) -> None:
814
- if isinstance(value, ailment.Expr.Expression) and value.has_atom(reg, identity=False):
815
- return
816
-
817
- for offset, chopped_value, size, label in value.value_and_labels():
818
- self._registers.store(
819
- reg.reg_offset + offset,
820
- chopped_value,
821
- size=size,
822
- label=label,
823
- endness=self.project.arch.register_endness,
824
- )
825
-
826
- def store_stack_variable(
827
- self, sp_offset: int, new: PropValue, endness=None
828
- ) -> None: # pylint:disable=unused-argument
829
- # normalize sp_offset to handle negative offsets
830
- sp_offset += 0x65536
831
- sp_offset &= (1 << self.arch.bits) - 1
832
-
833
- for offset, value, size, label in new.value_and_labels():
834
- self._stack_variables.store(sp_offset + offset, value, size=size, endness=endness, label=label)
835
-
836
- def load_register(self, reg: ailment.Expr.Register) -> PropValue | None:
837
- try:
838
- value, labels = self._registers.load_with_labels(
839
- reg.reg_offset, size=reg.size, endness=self.project.arch.register_endness
840
- )
841
- except SimMemoryMissingError:
842
- # value does not exist
843
- return None
844
-
845
- return PropValue.from_value_and_labels(value, labels)
846
-
847
- def load_stack_variable(self, sp_offset: int, size, endness=None) -> PropValue | None:
848
- # normalize sp_offset to handle negative offsets
849
- sp_offset += 0x65536
850
- sp_offset &= (1 << self.arch.bits) - 1
851
- try:
852
- value, labels = self._stack_variables.load_with_labels(sp_offset, size=size, endness=endness)
853
- except SimMemoryMissingError as ex:
854
- # the stack variable does not exist - however, maybe some portion of it exists!
855
- if ex.missing_addr > sp_offset:
856
- # some data exist. load again
857
- try:
858
- value, labels = self._stack_variables.load_with_labels(
859
- sp_offset, size=ex.missing_addr - sp_offset, endness=endness
860
- )
861
- # then we zero-extend both the value and labels
862
- if value is not None and len(labels) == 1 and labels[0][0] == 0:
863
- value = claripy.ZeroExt(ex.missing_size * self.arch.byte_width, value)
864
- offset, offset_in_expr, size, label = labels[0]
865
- labels = ((offset, offset_in_expr, size + ex.missing_size, label),)
866
- except SimMemoryMissingError:
867
- # failed again... welp
868
- return None
869
- else:
870
- return None
871
-
872
- return PropValue.from_value_and_labels(value, labels)
873
-
874
- def should_replace_reg(self, old_reg_offset: int, bp_as_gpr: bool, new_value) -> bool:
875
- if old_reg_offset == self.arch.sp_offset or (not bp_as_gpr and old_reg_offset == self.arch.bp_offset):
876
- return True
877
- if old_reg_offset in self._artificial_reg_offsets:
878
- return True
879
- return bool(isinstance(new_value, ailment.Expr.StackBaseOffset))
880
-
881
- def add_replacement(
882
- self,
883
- codeloc: CodeLocation,
884
- old,
885
- new,
886
- force_replace: bool = False,
887
- stmt_to_remove: CodeLocation | None = None,
888
- bp_as_gpr: bool = False,
889
- ) -> bool:
890
- if self._only_consts:
891
- if self.is_const_or_register(new) or self.is_top(new):
892
- pass
893
- else:
894
- new = self.top(1)
895
-
896
- # do not replace anything with a call expression
897
- if isinstance(new, ailment.statement.Call):
898
- return False
899
- callexpr_finder = CallExprFinder()
900
- callexpr_finder.walk_expression(new)
901
- if callexpr_finder.has_call:
902
- return False
903
-
904
- if self.is_top(new):
905
- self._replacements[codeloc][old] = self.top(1) # placeholder
906
- return False
907
-
908
- if isinstance(new, ailment.Expr.Expression) and (
909
- self.is_expression_too_deep(new) or (self.has_ternary_expr(new) and not isinstance(old, ailment.Expr.Tmp))
910
- ):
911
- # eliminate the past propagation of this expression
912
- self._replacements[codeloc][old] = self.top(1) # placeholder
913
- self.revert_past_replacements(new, to_replace=old)
914
- return False
915
-
916
- replaced = False
917
- # count-based propagation rule only matters when we are performing a full-function copy propagation
918
- if self._max_prop_expr_occurrence == 0:
919
- if isinstance(old, ailment.Expr.Tmp) or (
920
- isinstance(old, ailment.Expr.Register) and self.should_replace_reg(old.reg_offset, bp_as_gpr, new)
921
- ):
922
- self._replacements[codeloc][old] = (
923
- new if stmt_to_remove is None else {"expr": new, "stmt_to_remove": stmt_to_remove}
924
- )
925
- replaced = True
926
- else:
927
- prop_count = 0
928
- def_ = None
929
- if isinstance(old, ailment.Expr.Tmp) or isinstance(new, ailment.Expr.Const):
930
- # we always propagate tmp and constants
931
- pass
932
- elif self.is_simple_expression(new):
933
- # always propagate variables without other operations
934
- pass
935
- else:
936
- if self.rda is not None:
937
- if isinstance(old, ailment.Expr.Register):
938
- defs = self.rda.get_defs(atoms.Register(old.reg_offset, old.size), codeloc, OP_BEFORE)
939
- if len(defs) == 1:
940
- def_ = next(iter(defs))
941
- elif isinstance(old, ailment.Expr.Load) and isinstance(old.addr, ailment.Expr.StackBaseOffset):
942
- defs = self.rda.get_defs(
943
- atoms.MemoryLocation(SpOffset(old.addr.bits, old.addr.offset), old.size), codeloc, OP_BEFORE
944
- )
945
- if len(defs) == 1:
946
- def_ = next(iter(defs))
947
- if def_ is not None:
948
- self._expr_used_locs[def_].append(codeloc)
949
- # we must consider known future uses of this definition as well
950
- prop_count = max(len(self._expr_used_locs[def_]), len(self.rda.all_uses.get_uses(def_)))
951
- else:
952
- # multiple definitions or no definitions - do not propagate
953
- return False
954
- else:
955
- # when RDA result is not available, we use the expression directly for worse results
956
- self._expr_used_locs[new].append(codeloc)
957
- prop_count = len(self._expr_used_locs[new])
958
-
959
- if ( # pylint:disable=too-many-boolean-expressions
960
- force_replace
961
- or prop_count <= self._max_prop_expr_occurrence
962
- or isinstance(new, ailment.Expr.StackBaseOffset)
963
- or (isinstance(new, ailment.Expr.Convert) and isinstance(new.operand, ailment.Expr.StackBaseOffset))
964
- or (
965
- isinstance(old, ailment.Expr.Register)
966
- and self.arch.is_artificial_register(old.reg_offset, old.size)
967
- )
968
- ):
969
- # we can propagate this expression
970
- self._replacements[codeloc][old] = (
971
- new if stmt_to_remove is None else {"expr": new, "stmt_to_remove": stmt_to_remove}
972
- )
973
- replaced = True
974
- else:
975
- self._replacements[codeloc][old] = self.top(1) # placeholder
976
-
977
- # eliminate the past propagation of this expression
978
- for codeloc_ in self._replacements:
979
- if old in self._replacements[codeloc_]:
980
- self._replacements[codeloc_][old] = self.top(1)
981
- self.revert_past_replacements(new, to_replace=old, to_replace_def=def_)
982
-
983
- return replaced
984
-
985
- def revert_past_replacements(self, replaced_by, to_replace=None, to_replace_def=None) -> set[CodeLocation]:
986
- updated_codelocs = set()
987
- if self.model.replacements is not None:
988
- for codeloc_ in self._expr_used_locs[to_replace_def if to_replace_def is not None else to_replace]:
989
- for key, replace_with in list(self.model.replacements[codeloc_].items()):
990
- if isinstance(replace_with, dict):
991
- replace_with = replace_with["expr"]
992
- if not self.is_top(replace_with) and replace_with == replaced_by:
993
- self.model.replacements[codeloc_][key] = self.top(1)
994
- updated_codelocs.add(codeloc_)
995
-
996
- for codeloc_ in self._expr_used_locs[to_replace_def if to_replace_def is not None else to_replace]:
997
- if codeloc_ in self._replacements:
998
- for key, replace_with in list(self._replacements[codeloc_].items()):
999
- if isinstance(replace_with, dict):
1000
- replace_with = replace_with["expr"]
1001
- if not self.is_top(replace_with) and replace_with == replaced_by and to_replace.likes(key):
1002
- self._replacements[codeloc_][key] = self.top(1)
1003
- updated_codelocs.add(codeloc_)
1004
-
1005
- return updated_codelocs
1006
-
1007
- def add_equivalence(self, codeloc, old, new):
1008
- eq = Equivalence(codeloc, old, new)
1009
- self._equivalence.add(eq)
1010
-
1011
- @staticmethod
1012
- def is_simple_expression(expr: ailment.Expr.Expression) -> bool:
1013
- if PropagatorAILState.is_shallow_expression(expr):
1014
- return True
1015
- return bool(
1016
- isinstance(expr, ailment.Expr.BinaryOp)
1017
- and expr.op in {"Add", "Sub"}
1018
- and (
1019
- (
1020
- isinstance(expr.operands[0], ailment.Expr.Register)
1021
- and PropagatorAILState.is_global_variable_load(expr.operands[1])
1022
- )
1023
- or (
1024
- isinstance(expr.operands[1], ailment.Expr.Register)
1025
- and PropagatorAILState.is_global_variable_load(expr.operands[0])
1026
- )
1027
- )
1028
- )
1029
-
1030
- @staticmethod
1031
- def is_shallow_expression(expr: ailment.Expr.Expression) -> bool:
1032
- return expr.depth <= 0 or PropagatorAILState.is_global_variable_load(expr)
1033
-
1034
- @staticmethod
1035
- def is_global_variable_load(expr: ailment.Expr.Expression) -> bool:
1036
- if isinstance(expr, ailment.Expr.Load) and isinstance(expr.addr, ailment.Expr.Const):
1037
- return True
1038
- return bool(isinstance(expr, ailment.Expr.Convert) and PropagatorAILState.is_global_variable_load(expr.operand))
1039
-
1040
- @staticmethod
1041
- def is_expression_too_deep(expr: ailment.Expr.Expression) -> bool:
1042
- # determine if the expression is too deep to propagate
1043
- return expr.depth >= 30
1044
-
1045
- @staticmethod
1046
- def has_ternary_expr(expr: ailment.Expr.Expression) -> bool:
1047
- class _has_ternary_expr:
1048
- """
1049
- Temporary class holding values.
1050
- """
1051
-
1052
- v = False
1053
-
1054
- def _handle_ITE(*args, **kwargs): # pylint:disable=unused-argument
1055
- _has_ternary_expr.v = True
1056
-
1057
- walker = ailment.AILBlockWalkerBase()
1058
- walker.expr_handlers[ailment.Expr.ITE] = _handle_ITE
1059
- walker.walk_expression(expr, 0, None, None)
1060
- return _has_ternary_expr.v
angr/lib/angr_native.dll CHANGED
Binary file
@@ -1,7 +1,10 @@
1
1
  from __future__ import annotations
2
- import angr
2
+
3
3
  import logging
4
4
 
5
+ import angr
6
+ from angr.sim_options import ABSTRACT_MEMORY
7
+
5
8
  l = logging.getLogger(name=__name__)
6
9
 
7
10
 
@@ -33,6 +36,3 @@ class memcpy(angr.SimProcedure):
33
36
  self.state.memory.store(dst_addr, src_mem, size=limit, endness="Iend_BE")
34
37
 
35
38
  return dst_addr
36
-
37
-
38
- from angr.sim_options import ABSTRACT_MEMORY
@@ -1,12 +1,13 @@
1
1
  from __future__ import annotations
2
+
2
3
  import logging
3
4
  import os
4
5
 
5
- l = logging.getLogger(name=__name__)
6
-
7
6
  from angr.misc import autoimport
8
7
  from angr.sim_procedure import SimProcedure
9
8
 
9
+ l = logging.getLogger(name=__name__)
10
+
10
11
  # Import all classes under the current directory, and group them based on
11
12
  # lib names.
12
13
  SIM_PROCEDURES = {}
angr/protos/__init__.py CHANGED
@@ -1,10 +1,7 @@
1
1
  # Generating proto files
2
2
  #
3
- # $ cd angr
4
- # $ protoc -I=. --python_out=. protos/xxx.proto
5
- #
6
- # Then you need to manually fix all _pb2 imports to be relative because of this unresolved issue:
7
- # https://github.com/protocolbuffers/protobuf/issues/1491
3
+ # $ cd angr # you would expect angr/protos to exist after this
4
+ # $ protoc -I=. --python_out=. angr/protos/*.proto
8
5
  from __future__ import annotations
9
6
 
10
7
  from . import primitives_pb2