angr 9.2.132__py3-none-manylinux2014_x86_64.whl → 9.2.134__py3-none-manylinux2014_x86_64.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 (202) hide show
  1. angr/__init__.py +128 -128
  2. angr/analyses/__init__.py +38 -38
  3. angr/analyses/backward_slice.py +3 -4
  4. angr/analyses/binary_optimizer.py +5 -12
  5. angr/analyses/bindiff.py +3 -6
  6. angr/analyses/calling_convention.py +3 -4
  7. angr/analyses/cfg/__init__.py +3 -3
  8. angr/analyses/cfg/cfg_base.py +1 -1
  9. angr/analyses/cfg/cfg_fast.py +17 -15
  10. angr/analyses/cfg/indirect_jump_resolvers/__init__.py +5 -5
  11. angr/analyses/cfg/indirect_jump_resolvers/amd64_elf_got.py +1 -1
  12. angr/analyses/cfg/indirect_jump_resolvers/jumptable.py +15 -13
  13. angr/analyses/data_dep/__init__.py +4 -4
  14. angr/analyses/datagraph_meta.py +1 -1
  15. angr/analyses/ddg.py +2 -6
  16. angr/analyses/decompiler/__init__.py +12 -12
  17. angr/analyses/decompiler/ail_simplifier.py +21 -10
  18. angr/analyses/decompiler/block_similarity.py +2 -4
  19. angr/analyses/decompiler/callsite_maker.py +1 -1
  20. angr/analyses/decompiler/ccall_rewriters/rewriter_base.py +1 -1
  21. angr/analyses/decompiler/clinic.py +14 -7
  22. angr/analyses/decompiler/condition_processor.py +45 -29
  23. angr/analyses/decompiler/counters/__init__.py +3 -3
  24. angr/analyses/decompiler/decompilation_cache.py +7 -7
  25. angr/analyses/decompiler/dephication/__init__.py +1 -1
  26. angr/analyses/decompiler/dephication/graph_vvar_mapping.py +11 -3
  27. angr/analyses/decompiler/expression_narrower.py +1 -1
  28. angr/analyses/decompiler/graph_region.py +8 -8
  29. angr/analyses/decompiler/optimization_passes/__init__.py +20 -20
  30. angr/analyses/decompiler/optimization_passes/deadblock_remover.py +1 -2
  31. angr/analyses/decompiler/optimization_passes/duplication_reverter/duplication_reverter.py +8 -7
  32. angr/analyses/decompiler/optimization_passes/duplication_reverter/utils.py +1 -3
  33. angr/analyses/decompiler/optimization_passes/engine_base.py +1 -1
  34. angr/analyses/decompiler/optimization_passes/inlined_string_transformation_simplifier.py +2 -4
  35. angr/analyses/decompiler/optimization_passes/ite_region_converter.py +2 -5
  36. angr/analyses/decompiler/optimization_passes/lowered_switch_simplifier.py +5 -5
  37. angr/analyses/decompiler/optimization_passes/mod_simplifier.py +9 -3
  38. angr/analyses/decompiler/optimization_passes/optimization_pass.py +3 -0
  39. angr/analyses/decompiler/optimization_passes/stack_canary_simplifier.py +9 -5
  40. angr/analyses/decompiler/peephole_optimizations/__init__.py +1 -1
  41. angr/analyses/decompiler/peephole_optimizations/base.py +6 -6
  42. angr/analyses/decompiler/peephole_optimizations/rewrite_bit_extractions.py +1 -1
  43. angr/analyses/decompiler/presets/__init__.py +1 -1
  44. angr/analyses/decompiler/region_simplifiers/expr_folding.py +3 -3
  45. angr/analyses/decompiler/region_simplifiers/switch_cluster_simplifier.py +8 -12
  46. angr/analyses/decompiler/ssailification/rewriting_engine.py +1 -1
  47. angr/analyses/decompiler/structured_codegen/__init__.py +5 -5
  48. angr/analyses/decompiler/structured_codegen/base.py +3 -3
  49. angr/analyses/decompiler/structured_codegen/c.py +49 -42
  50. angr/analyses/decompiler/structuring/__init__.py +3 -3
  51. angr/analyses/decompiler/structuring/phoenix.py +19 -20
  52. angr/analyses/decompiler/structuring/structurer_base.py +2 -2
  53. angr/analyses/decompiler/structuring/structurer_nodes.py +14 -14
  54. angr/analyses/deobfuscator/__init__.py +3 -3
  55. angr/analyses/deobfuscator/string_obf_opt_passes.py +1 -1
  56. angr/analyses/disassembly.py +4 -4
  57. angr/analyses/forward_analysis/__init__.py +1 -1
  58. angr/analyses/forward_analysis/visitors/graph.py +6 -6
  59. angr/analyses/loop_analysis.py +1 -1
  60. angr/analyses/loopfinder.py +1 -1
  61. angr/analyses/propagator/outdated_definition_walker.py +12 -6
  62. angr/analyses/propagator/vex_vars.py +3 -3
  63. angr/analyses/reaching_definitions/__init__.py +9 -9
  64. angr/analyses/reaching_definitions/call_trace.py +2 -2
  65. angr/analyses/reaching_definitions/function_handler_library/__init__.py +1 -1
  66. angr/analyses/reaching_definitions/rd_state.py +10 -10
  67. angr/analyses/reassembler.py +26 -31
  68. angr/analyses/s_liveness.py +8 -0
  69. angr/analyses/s_reaching_definitions/s_rda_view.py +2 -5
  70. angr/analyses/stack_pointer_tracker.py +4 -4
  71. angr/analyses/typehoon/simple_solver.py +7 -9
  72. angr/analyses/typehoon/translator.py +2 -2
  73. angr/analyses/typehoon/typeconsts.py +1 -1
  74. angr/analyses/typehoon/typevars.py +17 -19
  75. angr/analyses/unpacker/__init__.py +1 -1
  76. angr/analyses/variable_recovery/engine_base.py +3 -4
  77. angr/analyses/variable_recovery/variable_recovery_base.py +1 -1
  78. angr/analyses/variable_recovery/variable_recovery_fast.py +2 -6
  79. angr/analyses/veritesting.py +2 -2
  80. angr/analyses/vfg.py +5 -5
  81. angr/angrdb/serializers/__init__.py +1 -1
  82. angr/annocfg.py +1 -1
  83. angr/blade.py +2 -2
  84. angr/block.py +16 -16
  85. angr/calling_conventions.py +11 -13
  86. angr/code_location.py +6 -10
  87. angr/codenode.py +3 -3
  88. angr/engines/__init__.py +12 -14
  89. angr/engines/engine.py +1 -54
  90. angr/engines/light/__init__.py +4 -4
  91. angr/engines/light/data.py +1 -1
  92. angr/engines/pcode/__init__.py +1 -1
  93. angr/engines/pcode/behavior.py +1 -1
  94. angr/engines/pcode/lifter.py +13 -15
  95. angr/engines/soot/expressions/__init__.py +12 -12
  96. angr/engines/soot/statements/__init__.py +6 -6
  97. angr/engines/soot/values/__init__.py +6 -6
  98. angr/engines/soot/values/arrayref.py +2 -2
  99. angr/engines/soot/values/constants.py +1 -1
  100. angr/engines/soot/values/instancefieldref.py +1 -1
  101. angr/engines/soot/values/paramref.py +1 -1
  102. angr/engines/soot/values/staticfieldref.py +1 -1
  103. angr/engines/successors.py +2 -5
  104. angr/engines/vex/__init__.py +5 -5
  105. angr/engines/vex/claripy/ccall.py +2 -2
  106. angr/engines/vex/claripy/irop.py +18 -18
  107. angr/engines/vex/heavy/__init__.py +2 -2
  108. angr/engines/vex/heavy/actions.py +1 -3
  109. angr/engines/vex/heavy/heavy.py +4 -6
  110. angr/engines/vex/lifter.py +2 -4
  111. angr/engines/vex/light/light.py +0 -2
  112. angr/engines/vex/light/slicing.py +3 -3
  113. angr/exploration_techniques/__init__.py +18 -18
  114. angr/exploration_techniques/threading.py +0 -6
  115. angr/factory.py +36 -6
  116. angr/keyed_region.py +4 -4
  117. angr/knowledge_base.py +1 -1
  118. angr/knowledge_plugins/__init__.py +11 -11
  119. angr/knowledge_plugins/cfg/__init__.py +5 -5
  120. angr/knowledge_plugins/cfg/cfg_manager.py +2 -2
  121. angr/knowledge_plugins/cfg/cfg_model.py +8 -8
  122. angr/knowledge_plugins/cfg/cfg_node.py +19 -19
  123. angr/knowledge_plugins/cfg/indirect_jump.py +6 -6
  124. angr/knowledge_plugins/cfg/memory_data.py +5 -7
  125. angr/knowledge_plugins/functions/function.py +48 -52
  126. angr/knowledge_plugins/functions/function_parser.py +4 -4
  127. angr/knowledge_plugins/key_definitions/__init__.py +3 -3
  128. angr/knowledge_plugins/key_definitions/atoms.py +6 -6
  129. angr/knowledge_plugins/key_definitions/definition.py +1 -1
  130. angr/knowledge_plugins/key_definitions/live_definitions.py +14 -14
  131. angr/knowledge_plugins/labels.py +1 -1
  132. angr/knowledge_plugins/propagations/__init__.py +1 -1
  133. angr/knowledge_plugins/propagations/prop_value.py +2 -2
  134. angr/knowledge_plugins/propagations/propagation_model.py +7 -8
  135. angr/knowledge_plugins/propagations/states.py +31 -31
  136. angr/knowledge_plugins/variables/variable_access.py +2 -2
  137. angr/knowledge_plugins/variables/variable_manager.py +1 -1
  138. angr/knowledge_plugins/xrefs/xref.py +5 -8
  139. angr/misc/__init__.py +4 -4
  140. angr/misc/hookset.py +4 -5
  141. angr/misc/loggers.py +2 -2
  142. angr/misc/telemetry.py +1 -1
  143. angr/procedures/__init__.py +1 -1
  144. angr/procedures/cgc/fdwait.py +2 -2
  145. angr/procedures/definitions/__init__.py +2 -2
  146. angr/procedures/definitions/linux_kernel.py +0 -1
  147. angr/procedures/definitions/parse_syscalls_from_local_system.py +1 -1
  148. angr/procedures/definitions/parse_win32json.py +0 -1
  149. angr/procedures/ntdll/exceptions.py +1 -1
  150. angr/procedures/stubs/format_parser.py +3 -3
  151. angr/procedures/win32/dynamic_loading.py +1 -1
  152. angr/protos/__init__.py +3 -3
  153. angr/sim_manager.py +2 -2
  154. angr/sim_state.py +1 -1
  155. angr/sim_state_options.py +3 -3
  156. angr/sim_type.py +10 -14
  157. angr/sim_variable.py +13 -17
  158. angr/simos/__init__.py +4 -4
  159. angr/simos/cgc.py +1 -1
  160. angr/simos/simos.py +1 -1
  161. angr/simos/userland.py +1 -1
  162. angr/slicer.py +4 -7
  163. angr/state_plugins/__init__.py +34 -34
  164. angr/state_plugins/callstack.py +5 -12
  165. angr/state_plugins/heap/__init__.py +2 -2
  166. angr/state_plugins/heap/heap_brk.py +2 -4
  167. angr/state_plugins/heap/heap_ptmalloc.py +1 -1
  168. angr/state_plugins/jni_references.py +3 -2
  169. angr/state_plugins/scratch.py +1 -1
  170. angr/state_plugins/sim_action.py +1 -4
  171. angr/state_plugins/sim_event.py +1 -1
  172. angr/state_plugins/solver.py +7 -9
  173. angr/state_plugins/uc_manager.py +1 -1
  174. angr/state_plugins/view.py +2 -2
  175. angr/storage/__init__.py +1 -1
  176. angr/storage/file.py +10 -10
  177. angr/storage/memory_mixins/__init__.py +46 -46
  178. angr/storage/memory_mixins/default_filler_mixin.py +1 -3
  179. angr/storage/memory_mixins/javavm_memory_mixin.py +2 -2
  180. angr/storage/memory_mixins/name_resolution_mixin.py +3 -3
  181. angr/storage/memory_mixins/paged_memory/paged_memory_mixin.py +1 -3
  182. angr/storage/memory_mixins/paged_memory/pages/__init__.py +6 -6
  183. angr/storage/memory_mixins/paged_memory/pages/list_page.py +1 -1
  184. angr/storage/memory_mixins/paged_memory/pages/multi_values.py +1 -1
  185. angr/storage/memory_mixins/paged_memory/pages/mv_list_page.py +1 -1
  186. angr/storage/memory_mixins/paged_memory/pages/ultra_page.py +2 -4
  187. angr/storage/memory_mixins/regioned_memory/__init__.py +3 -3
  188. angr/storage/memory_mixins/regioned_memory/region_data.py +5 -5
  189. angr/storage/memory_mixins/regioned_memory/region_meta_mixin.py +7 -9
  190. angr/storage/memory_mixins/regioned_memory/regioned_memory_mixin.py +4 -4
  191. angr/storage/memory_object.py +4 -4
  192. angr/utils/__init__.py +3 -3
  193. angr/utils/dynamic_dictlist.py +1 -1
  194. angr/utils/graph.py +1 -1
  195. angr/utils/segment_list.py +2 -2
  196. angr/utils/ssa/__init__.py +12 -5
  197. {angr-9.2.132.dist-info → angr-9.2.134.dist-info}/METADATA +6 -6
  198. {angr-9.2.132.dist-info → angr-9.2.134.dist-info}/RECORD +202 -202
  199. {angr-9.2.132.dist-info → angr-9.2.134.dist-info}/LICENSE +0 -0
  200. {angr-9.2.132.dist-info → angr-9.2.134.dist-info}/WHEEL +0 -0
  201. {angr-9.2.132.dist-info → angr-9.2.134.dist-info}/entry_points.txt +0 -0
  202. {angr-9.2.132.dist-info → angr-9.2.134.dist-info}/top_level.txt +0 -0
@@ -388,16 +388,16 @@ class CFunction(CConstruct): # pylint:disable=abstract-method
388
388
 
389
389
  __slots__ = (
390
390
  "addr",
391
- "name",
392
- "functy",
393
391
  "arg_list",
394
- "statements",
395
- "variables_in_use",
396
- "variable_manager",
397
392
  "demangled_name",
398
- "unified_local_vars",
399
- "show_demangled_name",
393
+ "functy",
394
+ "name",
400
395
  "omit_header",
396
+ "show_demangled_name",
397
+ "statements",
398
+ "unified_local_vars",
399
+ "variable_manager",
400
+ "variables_in_use",
401
401
  )
402
402
 
403
403
  def __init__(
@@ -492,7 +492,7 @@ class CFunction(CConstruct): # pylint:disable=abstract-method
492
492
  if variable.name:
493
493
  name = variable.name
494
494
  elif isinstance(variable, SimTemporaryVariable):
495
- name = "tmp_%d" % variable.tmp_id
495
+ name = f"tmp_{variable.tmp_id}"
496
496
  else:
497
497
  name = str(variable)
498
498
 
@@ -728,8 +728,8 @@ class CWhileLoop(CLoop):
728
728
  """
729
729
 
730
730
  __slots__ = (
731
- "condition",
732
731
  "body",
732
+ "condition",
733
733
  "tags",
734
734
  )
735
735
 
@@ -776,8 +776,8 @@ class CDoWhileLoop(CLoop):
776
776
  """
777
777
 
778
778
  __slots__ = (
779
- "condition",
780
779
  "body",
780
+ "condition",
781
781
  "tags",
782
782
  )
783
783
 
@@ -826,7 +826,7 @@ class CForLoop(CStatement):
826
826
  Represents a for-loop in C.
827
827
  """
828
828
 
829
- __slots__ = ("initializer", "condition", "iterator", "body", "tags")
829
+ __slots__ = ("body", "condition", "initializer", "iterator", "tags")
830
830
 
831
831
  def __init__(self, initializer, condition, iterator, body, tags=None, **kwargs):
832
832
  super().__init__(**kwargs)
@@ -878,7 +878,7 @@ class CIfElse(CStatement):
878
878
  Represents an if-else construct in C.
879
879
  """
880
880
 
881
- __slots__ = ("condition_and_nodes", "else_node", "simplify_else_scope", "cstyle_ifs", "tags")
881
+ __slots__ = ("condition_and_nodes", "cstyle_ifs", "else_node", "simplify_else_scope", "tags")
882
882
 
883
883
  def __init__(
884
884
  self,
@@ -1085,7 +1085,7 @@ class CSwitchCase(CStatement):
1085
1085
  Represents a switch-case statement in C.
1086
1086
  """
1087
1087
 
1088
- __slots__ = ("switch", "cases", "default", "tags")
1088
+ __slots__ = ("cases", "default", "switch", "tags")
1089
1089
 
1090
1090
  def __init__(self, switch, cases, default, tags=None, **kwargs):
1091
1091
  super().__init__(**kwargs)
@@ -1144,7 +1144,7 @@ class CIncompleteSwitchCase(CStatement):
1144
1144
  structuring fails (for whatever reason).
1145
1145
  """
1146
1146
 
1147
- __slots__ = ("head", "cases", "tags")
1147
+ __slots__ = ("cases", "head", "tags")
1148
1148
 
1149
1149
  def __init__(self, head, cases, tags=None, **kwargs):
1150
1150
  super().__init__(**kwargs)
@@ -1221,20 +1221,30 @@ class CAssignment(CStatement):
1221
1221
  "Shl": "<<",
1222
1222
  "Sar": ">>",
1223
1223
  }
1224
+ commutative_ops = {"Add", "Mul", "And", "Xor", "Or"}
1224
1225
 
1226
+ compound_expr_rhs = None
1225
1227
  if (
1226
1228
  self.codegen.use_compound_assignments
1227
1229
  and isinstance(self.lhs, CVariable)
1228
1230
  and isinstance(self.rhs, CBinaryOp)
1229
- and isinstance(self.rhs.lhs, CVariable)
1230
- and self.lhs.unified_variable is not None
1231
- and self.rhs.lhs.unified_variable is not None
1232
- and self.lhs.unified_variable is self.rhs.lhs.unified_variable
1233
1231
  and self.rhs.op in compound_assignment_ops
1232
+ and self.lhs.unified_variable is not None
1234
1233
  ):
1234
+ if isinstance(self.rhs.lhs, CVariable) and self.lhs.unified_variable is self.rhs.lhs.unified_variable:
1235
+ compound_expr_rhs = self.rhs.rhs
1236
+ elif (
1237
+ self.rhs.op in commutative_ops
1238
+ and isinstance(self.rhs.rhs, CVariable)
1239
+ and self.lhs.unified_variable is self.rhs.rhs.unified_variable
1240
+ ):
1241
+ compound_expr_rhs = self.rhs.lhs
1242
+
1243
+ if compound_expr_rhs is not None:
1235
1244
  # a = a + x => a += x
1245
+ # a = x + a => a += x
1236
1246
  yield f" {compound_assignment_ops[self.rhs.op]}= ", self
1237
- yield from CExpression._try_c_repr_chunks(self.rhs.rhs)
1247
+ yield from CExpression._try_c_repr_chunks(compound_expr_rhs)
1238
1248
  else:
1239
1249
  yield " = ", self
1240
1250
  yield from CExpression._try_c_repr_chunks(self.rhs)
@@ -1251,15 +1261,15 @@ class CFunctionCall(CStatement, CExpression):
1251
1261
  """
1252
1262
 
1253
1263
  __slots__ = (
1254
- "callee_target",
1255
- "callee_func",
1256
1264
  "args",
1257
- "returning",
1258
- "ret_expr",
1259
- "tags",
1265
+ "callee_func",
1266
+ "callee_target",
1260
1267
  "is_expr",
1268
+ "ret_expr",
1269
+ "returning",
1261
1270
  "show_demangled_name",
1262
1271
  "show_disambiguated_name",
1272
+ "tags",
1263
1273
  )
1264
1274
 
1265
1275
  def __init__(
@@ -1397,9 +1407,9 @@ class CReturn(CStatement):
1397
1407
 
1398
1408
  class CGoto(CStatement):
1399
1409
  __slots__ = (
1410
+ "tags",
1400
1411
  "target",
1401
1412
  "target_idx",
1402
- "tags",
1403
1413
  )
1404
1414
 
1405
1415
  def __init__(self, target, target_idx, tags=None, **kwargs):
@@ -1481,9 +1491,9 @@ class CLabel(CStatement):
1481
1491
  """
1482
1492
 
1483
1493
  __slots__ = (
1484
- "name",
1485
- "ins_addr",
1486
1494
  "block_idx",
1495
+ "ins_addr",
1496
+ "name",
1487
1497
  "tags",
1488
1498
  )
1489
1499
 
@@ -1504,9 +1514,9 @@ class CLabel(CStatement):
1504
1514
 
1505
1515
  class CStructField(CExpression):
1506
1516
  __slots__ = (
1507
- "struct_type",
1508
- "offset",
1509
1517
  "field",
1518
+ "offset",
1519
+ "struct_type",
1510
1520
  "tags",
1511
1521
  )
1512
1522
 
@@ -1558,10 +1568,10 @@ class CVariable(CExpression):
1558
1568
  """
1559
1569
 
1560
1570
  __slots__ = (
1571
+ "tags",
1572
+ "unified_variable",
1561
1573
  "variable",
1562
1574
  "variable_type",
1563
- "unified_variable",
1564
- "tags",
1565
1575
  )
1566
1576
 
1567
1577
  def __init__(self, variable: SimVariable, unified_variable=None, variable_type=None, tags=None, **kwargs):
@@ -1583,7 +1593,7 @@ class CVariable(CExpression):
1583
1593
  if v.name:
1584
1594
  return v.name
1585
1595
  if isinstance(v, SimTemporaryVariable):
1586
- return "tmp_%d" % v.tmp_id
1596
+ return f"tmp_{v.tmp_id}"
1587
1597
  return str(v)
1588
1598
 
1589
1599
  def c_repr_chunks(self, indent=0, asexpr=False):
@@ -1766,7 +1776,7 @@ class CBinaryOp(CExpression):
1766
1776
  Binary operations.
1767
1777
  """
1768
1778
 
1769
- __slots__ = ("op", "lhs", "rhs", "tags", "common_type", "_cstyle_null_cmp")
1779
+ __slots__ = ("_cstyle_null_cmp", "common_type", "lhs", "op", "rhs", "tags")
1770
1780
 
1771
1781
  def __init__(self, op, lhs, rhs, tags: dict | None = None, **kwargs):
1772
1782
  super().__init__(**kwargs)
@@ -2038,9 +2048,9 @@ class CBinaryOp(CExpression):
2038
2048
 
2039
2049
  class CTypeCast(CExpression):
2040
2050
  __slots__ = (
2041
- "src_type",
2042
2051
  "dst_type",
2043
2052
  "expr",
2053
+ "src_type",
2044
2054
  "tags",
2045
2055
  )
2046
2056
 
@@ -2080,9 +2090,9 @@ class CTypeCast(CExpression):
2080
2090
 
2081
2091
  class CConstant(CExpression):
2082
2092
  __slots__ = (
2083
- "value",
2084
2093
  "reference_values",
2085
2094
  "tags",
2095
+ "value",
2086
2096
  )
2087
2097
 
2088
2098
  def __init__(self, value, type_: SimType, reference_values=None, tags: dict | None = None, **kwargs):
@@ -2133,11 +2143,8 @@ class CConstant(CExpression):
2133
2143
  result = False
2134
2144
  if isinstance(self.value, int):
2135
2145
  value_size = self._type.size if self._type is not None else None
2136
- if (
2137
- value_size == 32
2138
- and 0xF000_0000 <= self.value <= 0xFFFF_FFFF
2139
- or value_size == 64
2140
- and 0xF000_0000_0000_0000 <= self.value <= 0xFFFF_FFFF_FFFF_FFFF
2146
+ if (value_size == 32 and 0xF000_0000 <= self.value <= 0xFFFF_FFFF) or (
2147
+ value_size == 64 and 0xF000_0000_0000_0000 <= self.value <= 0xFFFF_FFFF_FFFF_FFFF
2141
2148
  ):
2142
2149
  result = True
2143
2150
 
@@ -2304,8 +2311,8 @@ class CRegister(CExpression):
2304
2311
  class CITE(CExpression):
2305
2312
  __slots__ = (
2306
2313
  "cond",
2307
- "iftrue",
2308
2314
  "iffalse",
2315
+ "iftrue",
2309
2316
  "tags",
2310
2317
  )
2311
2318
 
@@ -2339,7 +2346,7 @@ class CMultiStatementExpression(CExpression):
2339
2346
  (stmt0, stmt1, stmt2, expr)
2340
2347
  """
2341
2348
 
2342
- __slots__ = ("stmts", "expr", "tags")
2349
+ __slots__ = ("expr", "stmts", "tags")
2343
2350
 
2344
2351
  def __init__(self, stmts: CStatements, expr: CExpression, tags=None, **kwargs):
2345
2352
  super().__init__(**kwargs)
@@ -20,11 +20,11 @@ def structurer_class_from_name(name: str) -> type | None:
20
20
 
21
21
 
22
22
  __all__ = (
23
+ "DEFAULT_STRUCTURER",
24
+ "STRUCTURER_CLASSES",
23
25
  "DreamStructurer",
24
26
  "PhoenixStructurer",
25
- "SAILRStructurer",
26
27
  "RecursiveStructurer",
27
- "STRUCTURER_CLASSES",
28
- "DEFAULT_STRUCTURER",
28
+ "SAILRStructurer",
29
29
  "structurer_class_from_name",
30
30
  )
@@ -306,7 +306,8 @@ class PhoenixStructurer(StructurerBase):
306
306
  and isinstance(head_block.nodes[0], Block)
307
307
  and head_block.nodes[0].statements
308
308
  and isinstance(first_nonlabel_nonphi_statement(head_block.nodes[0]), ConditionalJump)
309
- or isinstance(head_block, Block)
309
+ ) or (
310
+ isinstance(head_block, Block)
310
311
  and head_block.statements
311
312
  and isinstance(first_nonlabel_nonphi_statement(head_block), ConditionalJump)
312
313
  ):
@@ -1747,10 +1748,8 @@ class PhoenixStructurer(StructurerBase):
1747
1748
  and right not in graph
1748
1749
  and full_graph.in_degree[left] == 1
1749
1750
  and (
1750
- full_graph.in_degree[right] == 2
1751
- and left_succs == [right]
1752
- or full_graph.in_degree[right] == 1
1753
- and not left_succs
1751
+ (full_graph.in_degree[right] == 2 and left_succs == [right])
1752
+ or (full_graph.in_degree[right] == 1 and not left_succs)
1754
1753
  )
1755
1754
  ):
1756
1755
  edge_cond_left = self.cond_proc.recover_edge_condition(full_graph, start_node, left)
@@ -2384,17 +2383,19 @@ class PhoenixStructurer(StructurerBase):
2384
2383
  and last_stmt.target.value == dst_addr
2385
2384
  and (dst_idx is ... or last_stmt.target_idx == dst_idx)
2386
2385
  )
2387
- or isinstance(last_stmt, ConditionalJump)
2388
- and (
2389
- (
2390
- isinstance(last_stmt.true_target, Const)
2391
- and last_stmt.true_target.value == dst_addr
2392
- and (dst_idx is ... or last_stmt.true_target_idx == dst_idx)
2393
- )
2394
- or (
2395
- isinstance(last_stmt.false_target, Const)
2396
- and last_stmt.false_target.value == dst_addr
2397
- and (dst_idx is ... or last_stmt.false_target_idx == dst_idx)
2386
+ or (
2387
+ isinstance(last_stmt, ConditionalJump)
2388
+ and (
2389
+ (
2390
+ isinstance(last_stmt.true_target, Const)
2391
+ and last_stmt.true_target.value == dst_addr
2392
+ and (dst_idx is ... or last_stmt.true_target_idx == dst_idx)
2393
+ )
2394
+ or (
2395
+ isinstance(last_stmt.false_target, Const)
2396
+ and last_stmt.false_target.value == dst_addr
2397
+ and (dst_idx is ... or last_stmt.false_target_idx == dst_idx)
2398
+ )
2398
2399
  )
2399
2400
  )
2400
2401
  or (
@@ -2431,10 +2432,8 @@ class PhoenixStructurer(StructurerBase):
2431
2432
 
2432
2433
  def _handle_BreakNode(break_node: BreakNode, parent=None, **kwargs): # pylint:disable=unused-argument
2433
2434
  walker.block_id += 1
2434
- if (
2435
- break_node.target == dst_addr
2436
- or isinstance(break_node.target, Const)
2437
- and break_node.target.value == dst_addr
2435
+ if break_node.target == dst_addr or (
2436
+ isinstance(break_node.target, Const) and break_node.target.value == dst_addr
2438
2437
  ):
2439
2438
  # FIXME: idx is ignored
2440
2439
  walker.parent_and_block.append((walker.block_id, parent, break_node))
@@ -150,7 +150,7 @@ class StructurerBase(Analysis):
150
150
  if isinstance(stmt, ailment.Stmt.Jump):
151
151
  targets = extract_jump_targets(stmt)
152
152
  for t in targets:
153
- if t in cases or default is not None and t == default.addr:
153
+ if t in cases or (default is not None and t == default.addr):
154
154
  # the node after switch cannot be one of the nodes in the switch-case construct
155
155
  continue
156
156
  goto_addrs[t] += 1
@@ -863,7 +863,7 @@ class StructurerBase(Analysis):
863
863
  addr = node_0.addr if node_0.addr is not None else node_1.addr
864
864
 
865
865
  # fix the last block of node_0 and remove useless goto statements
866
- if isinstance(node_0, SequenceNode) and node_0.nodes or isinstance(node_0, MultiNode) and node_0.nodes:
866
+ if (isinstance(node_0, SequenceNode) and node_0.nodes) or (isinstance(node_0, MultiNode) and node_0.nodes):
867
867
  last_node = node_0.nodes[-1]
868
868
  elif isinstance(node_0, ailment.Block):
869
869
  last_node = node_0
@@ -17,9 +17,9 @@ class EmptyBlockNotice(Exception):
17
17
 
18
18
  class MultiNode:
19
19
  __slots__ = (
20
- "nodes",
21
20
  "addr",
22
21
  "idx",
22
+ "nodes",
23
23
  )
24
24
 
25
25
  def __init__(self, nodes, addr=None, idx=None):
@@ -48,7 +48,7 @@ class MultiNode:
48
48
  addrs.append(node.addr)
49
49
  s = f": {min(addrs):#x}-{max(addrs):#x}"
50
50
 
51
- return "<MultiNode %#x of %d nodes%s>" % (self.addr, len(self.nodes), s)
51
+ return f"<MultiNode {self.addr:#x} of {len(self.nodes)} nodes{s}>"
52
52
 
53
53
  def __hash__(self):
54
54
  # changing self.nodes does not change the hash, which enables in-place editing
@@ -110,8 +110,8 @@ class SequenceNode(BaseNode):
110
110
 
111
111
  def __repr__(self):
112
112
  if self.addr is None:
113
- return "<SequenceNode, %d nodes>" % len(self.nodes)
114
- return "<SequenceNode %#x, %d nodes>" % (self.addr, len(self.nodes))
113
+ return f"<SequenceNode, {len(self.nodes)} nodes>"
114
+ return f"<SequenceNode {self.addr:#x}, {len(self.nodes)} nodes>"
115
115
 
116
116
  def add_node(self, node):
117
117
  self.nodes.append(node)
@@ -192,11 +192,11 @@ class CodeNode(BaseNode):
192
192
  class ConditionNode(BaseNode):
193
193
  __slots__ = (
194
194
  "addr",
195
+ "condition",
196
+ "false_node",
195
197
  "node",
196
198
  "reaching_condition",
197
- "condition",
198
199
  "true_node",
199
- "false_node",
200
200
  )
201
201
 
202
202
  def __init__(self, addr, reaching_condition, condition, true_node, false_node=None):
@@ -238,13 +238,13 @@ class CascadingConditionNode(BaseNode):
238
238
 
239
239
  class LoopNode(BaseNode):
240
240
  __slots__ = (
241
- "sort",
241
+ "_addr",
242
+ "_continue_addr",
242
243
  "condition",
243
- "sequence_node",
244
244
  "initializer",
245
245
  "iterator",
246
- "_addr",
247
- "_continue_addr",
246
+ "sequence_node",
247
+ "sort",
248
248
  )
249
249
 
250
250
  def __init__(
@@ -351,10 +351,10 @@ class ConditionalBreakNode(BreakNode):
351
351
 
352
352
  class SwitchCaseNode(BaseNode):
353
353
  __slots__ = (
354
- "switch_expr",
354
+ "addr",
355
355
  "cases",
356
356
  "default_node",
357
- "addr",
357
+ "switch_expr",
358
358
  )
359
359
 
360
360
  def __init__(self, switch_expr, cases: OrderedDict[int | tuple[int, ...], SequenceNode], default_node, addr=None):
@@ -370,7 +370,7 @@ class IncompleteSwitchCaseNode(BaseNode):
370
370
  into a SwitchCaseNode by the end of structuring. Only used in Phoenix structurer.
371
371
  """
372
372
 
373
- __slots__ = ("addr", "head", "cases")
373
+ __slots__ = ("addr", "cases", "head")
374
374
 
375
375
  def __init__(self, addr, head, cases: list):
376
376
  self.addr = addr
@@ -388,7 +388,7 @@ class IncompleteSwitchCaseHeadStatement(ailment.statement.Statement):
388
388
  Describes a switch-case head. This is only created by LoweredSwitchSimplifier.
389
389
  """
390
390
 
391
- __slots__ = ("addr", "switch_variable", "case_addrs", "_case_addrs_str")
391
+ __slots__ = ("_case_addrs_str", "addr", "case_addrs", "switch_variable")
392
392
 
393
393
  def __init__(self, idx, switch_variable, case_addrs, **kwargs):
394
394
  super().__init__(idx, **kwargs)
@@ -10,9 +10,9 @@ from .api_obf_peephole_optimizer import APIObfType1PeepholeOptimizer
10
10
 
11
11
 
12
12
  __all__ = (
13
- "StringObfuscationFinder",
13
+ "APIObfType1PeepholeOptimizer",
14
+ "APIObfuscationFinder",
14
15
  "StringObfType1PeepholeOptimizer",
15
16
  "StringObfType3Rewriter",
16
- "APIObfuscationFinder",
17
- "APIObfType1PeepholeOptimizer",
17
+ "StringObfuscationFinder",
18
18
  )
@@ -44,7 +44,7 @@ class StringObfType3Rewriter(OptimizationPass):
44
44
 
45
45
  @staticmethod
46
46
  def is_call_or_call_assignment(stmt) -> bool:
47
- return isinstance(stmt, Call) or isinstance(stmt, Assignment) and isinstance(stmt.src, Call)
47
+ return isinstance(stmt, Call) or (isinstance(stmt, Assignment) and isinstance(stmt.src, Call))
48
48
 
49
49
  def _analyze(self, cache=None):
50
50
 
@@ -119,9 +119,9 @@ class Label(DisassemblyPiece):
119
119
  class IROp(DisassemblyPiece):
120
120
  __slots__ = (
121
121
  "addr",
122
- "seq",
123
- "obj",
124
122
  "irsb",
123
+ "obj",
124
+ "seq",
125
125
  )
126
126
 
127
127
  addr: int
@@ -444,7 +444,7 @@ class SootExpressionTarget(SootExpression):
444
444
  self.target_stmt_idx = target_stmt_idx
445
445
 
446
446
  def _render(self, formatting=None):
447
- return ["Goto %d" % self.target_stmt_idx]
447
+ return [f"Goto {self.target_stmt_idx}"]
448
448
 
449
449
 
450
450
  class SootExpressionStaticFieldRef(SootExpression):
@@ -898,7 +898,7 @@ class Value(OperandPiece):
898
898
  return [f"{self.val:#x}"]
899
899
  if style[0] == "dec":
900
900
  if self.render_with_sign:
901
- return ["%+d" % self.val]
901
+ return [f"{self.val:+d}"]
902
902
  return [str(self.val)]
903
903
  if style[0] == "label":
904
904
  labeloffset = style[1]
@@ -4,8 +4,8 @@ from .forward_analysis import ForwardAnalysis
4
4
  from .visitors import CallGraphVisitor, FunctionGraphVisitor, LoopVisitor, SingleNodeGraphVisitor
5
5
 
6
6
  __all__ = (
7
- "ForwardAnalysis",
8
7
  "CallGraphVisitor",
8
+ "ForwardAnalysis",
9
9
  "FunctionGraphVisitor",
10
10
  "LoopVisitor",
11
11
  "SingleNodeGraphVisitor",
@@ -16,14 +16,14 @@ class GraphVisitor(Generic[NodeType]):
16
16
  """
17
17
 
18
18
  __slots__ = (
19
- "_sorted_nodes",
20
- "_worklist",
21
- "_nodes_set",
22
- "_node_to_index",
23
- "_reached_fixedpoint",
24
- "_back_edges_by_src",
25
19
  "_back_edges_by_dst",
20
+ "_back_edges_by_src",
21
+ "_node_to_index",
22
+ "_nodes_set",
26
23
  "_pending_nodes",
24
+ "_reached_fixedpoint",
25
+ "_sorted_nodes",
26
+ "_worklist",
27
27
  )
28
28
 
29
29
  def __init__(self):
@@ -19,7 +19,7 @@ class VariableTypes:
19
19
 
20
20
 
21
21
  class AnnotatedVariable:
22
- __slots__ = ["variable", "type"]
22
+ __slots__ = ["type", "variable"]
23
23
 
24
24
  def __init__(self, variable, type_):
25
25
  self.variable = variable
@@ -28,7 +28,7 @@ class Loop:
28
28
  break
29
29
 
30
30
  def __repr__(self):
31
- return "<Loop @ %s, %d blocks>" % (self.entry.addr, len(self.body_nodes))
31
+ return f"<Loop @ {self.entry.addr}, {len(self.body_nodes)} blocks>"
32
32
 
33
33
 
34
34
  class LoopFinder(Analysis):
@@ -119,13 +119,19 @@ class OutdatedDefinitionWalker(AILBlockWalker):
119
119
  super()._handle_Load(expr_idx, expr, stmt_idx, stmt, block)
120
120
  # then if the address expression is up-to-date, we check the global store
121
121
  if not self.out_dated and (
122
- self.state.global_stores
123
- and not all(
124
- self._check_store_precedes_load(CodeLocation(store_block_addr, store_stmt_idx), self.expr_defat)
125
- for store_block_addr, store_stmt_idx, addr, store in self.state.global_stores
122
+ (
123
+ self.state.global_stores
124
+ and not all(
125
+ self._check_store_precedes_load(CodeLocation(store_block_addr, store_stmt_idx), self.expr_defat)
126
+ for store_block_addr, store_stmt_idx, addr, store in self.state.global_stores
127
+ )
128
+ )
129
+ or (
130
+ self.state.last_stack_store is not None
131
+ and not self._check_store_precedes_load(
132
+ CodeLocation(*self.state.last_stack_store[:2]), self.expr_defat
133
+ )
126
134
  )
127
- or self.state.last_stack_store is not None
128
- and not self._check_store_precedes_load(CodeLocation(*self.state.last_stack_store[:2]), self.expr_defat)
129
135
  ):
130
136
  self.out_dated = True
131
137
 
@@ -29,7 +29,7 @@ class VEXMemVar:
29
29
  return type(other) is VEXMemVar and other.addr == self.addr and other.size == self.size
30
30
 
31
31
  def __repr__(self):
32
- return "<mem %#x[%d bytes]>" % (self.addr, self.size)
32
+ return f"<mem {self.addr:#x}[{self.size} bytes]>"
33
33
 
34
34
 
35
35
  class VEXReg(VEXVariable):
@@ -49,7 +49,7 @@ class VEXReg(VEXVariable):
49
49
  return type(other) is VEXReg and other.offset == self.offset and other.size == self.size
50
50
 
51
51
  def __repr__(self):
52
- return "<reg %d[%d]>" % (self.offset, self.size)
52
+ return f"<reg {self.offset}[{self.size}]>"
53
53
 
54
54
 
55
55
  class VEXTmp(VEXVariable):
@@ -65,4 +65,4 @@ class VEXTmp(VEXVariable):
65
65
  return type(other) is VEXTmp and other.tmp == self.tmp
66
66
 
67
67
  def __repr__(self):
68
- return "<tmp %d>" % self.tmp
68
+ return f"<tmp {self.tmp}>"
@@ -24,21 +24,21 @@ if TYPE_CHECKING:
24
24
  from angr.storage.memory_mixins.paged_memory.pages import MVListPage
25
25
 
26
26
  __all__ = (
27
- "LiveDefinitions",
28
- "ObservationPointType",
29
- "AtomKind",
30
27
  "Atom",
31
- "Register",
32
- "MemoryLocation",
33
- "Tmp",
34
- "GuardUse",
28
+ "AtomKind",
35
29
  "ConstantSrc",
36
30
  "Definition",
31
+ "FunctionCallData",
32
+ "FunctionHandler",
33
+ "GuardUse",
34
+ "LiveDefinitions",
35
+ "MemoryLocation",
36
+ "ObservationPointType",
37
37
  "ReachingDefinitionsAnalysis",
38
38
  "ReachingDefinitionsModel",
39
39
  "ReachingDefinitionsState",
40
- "FunctionHandler",
41
- "FunctionCallData",
40
+ "Register",
41
+ "Tmp",
42
42
  "get_all_definitions",
43
43
  )
44
44
 
@@ -7,9 +7,9 @@ class CallSite:
7
7
  """
8
8
 
9
9
  __slots__ = (
10
- "caller_func_addr",
11
10
  "block_addr",
12
11
  "callee_func_addr",
12
+ "caller_func_addr",
13
13
  )
14
14
 
15
15
  def __init__(self, caller_func_addr: int, block_addr: int | None, callee_func_addr: int):
@@ -48,7 +48,7 @@ class CallTrace:
48
48
  self.callsites: list[CallSite] = []
49
49
 
50
50
  def __repr__(self):
51
- return "<Trace with %d callsites>" % len(self.callsites)
51
+ return f"<Trace with {len(self.callsites)} callsites>"
52
52
 
53
53
  def current_function_address(self) -> int:
54
54
  if not self.callsites:
@@ -9,4 +9,4 @@ class LibcHandlers(LibcStdlibHandlers, LibcStdioHandlers, LibcUnistdHandlers, Li
9
9
  pass
10
10
 
11
11
 
12
- __all__ = ["EnvironAtom", "SystemAtom", "ExecveAtom", "StdoutAtom", "StdinAtom", "LibcHandlers"]
12
+ __all__ = ["EnvironAtom", "ExecveAtom", "LibcHandlers", "StdinAtom", "StdoutAtom", "SystemAtom"]