angr 9.2.131__py3-none-win_amd64.whl → 9.2.133__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 (265) hide show
  1. angr/__init__.py +128 -128
  2. angr/analyses/__init__.py +38 -38
  3. angr/analyses/analysis.py +6 -2
  4. angr/analyses/backward_slice.py +3 -4
  5. angr/analyses/binary_optimizer.py +5 -12
  6. angr/analyses/bindiff.py +3 -6
  7. angr/analyses/calling_convention.py +3 -4
  8. angr/analyses/cfg/__init__.py +3 -3
  9. angr/analyses/cfg/cfg_base.py +1 -1
  10. angr/analyses/cfg/cfg_emulated.py +5 -5
  11. angr/analyses/cfg/cfg_fast.py +19 -17
  12. angr/analyses/cfg/indirect_jump_resolvers/__init__.py +5 -5
  13. angr/analyses/cfg/indirect_jump_resolvers/amd64_elf_got.py +1 -1
  14. angr/analyses/cfg/indirect_jump_resolvers/jumptable.py +148 -101
  15. angr/analyses/cfg/indirect_jump_resolvers/x86_elf_pic_plt.py +1 -1
  16. angr/analyses/data_dep/__init__.py +4 -4
  17. angr/analyses/datagraph_meta.py +1 -1
  18. angr/analyses/ddg.py +16 -17
  19. angr/analyses/decompiler/__init__.py +12 -12
  20. angr/analyses/decompiler/ail_simplifier.py +24 -12
  21. angr/analyses/decompiler/block_similarity.py +2 -4
  22. angr/analyses/decompiler/block_simplifier.py +10 -21
  23. angr/analyses/decompiler/callsite_maker.py +1 -1
  24. angr/analyses/decompiler/ccall_rewriters/rewriter_base.py +1 -1
  25. angr/analyses/decompiler/clinic.py +122 -41
  26. angr/analyses/decompiler/condition_processor.py +57 -39
  27. angr/analyses/decompiler/counters/__init__.py +3 -3
  28. angr/analyses/decompiler/decompilation_cache.py +7 -7
  29. angr/analyses/decompiler/dephication/__init__.py +1 -1
  30. angr/analyses/decompiler/dephication/graph_rewriting.py +1 -1
  31. angr/analyses/decompiler/dephication/graph_vvar_mapping.py +11 -3
  32. angr/analyses/decompiler/dephication/rewriting_engine.py +169 -45
  33. angr/analyses/decompiler/dephication/seqnode_dephication.py +5 -4
  34. angr/analyses/decompiler/expression_narrower.py +1 -1
  35. angr/analyses/decompiler/graph_region.py +8 -8
  36. angr/analyses/decompiler/optimization_passes/__init__.py +20 -20
  37. angr/analyses/decompiler/optimization_passes/const_derefs.py +1 -0
  38. angr/analyses/decompiler/optimization_passes/deadblock_remover.py +1 -2
  39. angr/analyses/decompiler/optimization_passes/div_simplifier.py +41 -16
  40. angr/analyses/decompiler/optimization_passes/duplication_reverter/duplication_reverter.py +8 -7
  41. angr/analyses/decompiler/optimization_passes/duplication_reverter/utils.py +1 -3
  42. angr/analyses/decompiler/optimization_passes/engine_base.py +262 -84
  43. angr/analyses/decompiler/optimization_passes/inlined_string_transformation_simplifier.py +175 -39
  44. angr/analyses/decompiler/optimization_passes/ite_region_converter.py +2 -5
  45. angr/analyses/decompiler/optimization_passes/lowered_switch_simplifier.py +5 -5
  46. angr/analyses/decompiler/optimization_passes/mod_simplifier.py +12 -3
  47. angr/analyses/decompiler/optimization_passes/optimization_pass.py +42 -19
  48. angr/analyses/decompiler/optimization_passes/stack_canary_simplifier.py +9 -5
  49. angr/analyses/decompiler/peephole_optimizations/__init__.py +1 -1
  50. angr/analyses/decompiler/peephole_optimizations/base.py +6 -6
  51. angr/analyses/decompiler/peephole_optimizations/remove_noop_conversions.py +2 -0
  52. angr/analyses/decompiler/peephole_optimizations/rewrite_bit_extractions.py +1 -1
  53. angr/analyses/decompiler/presets/__init__.py +1 -1
  54. angr/analyses/decompiler/region_simplifiers/expr_folding.py +3 -3
  55. angr/analyses/decompiler/region_simplifiers/switch_cluster_simplifier.py +8 -12
  56. angr/analyses/decompiler/ssailification/rewriting.py +1 -2
  57. angr/analyses/decompiler/ssailification/rewriting_engine.py +139 -56
  58. angr/analyses/decompiler/ssailification/ssailification.py +2 -1
  59. angr/analyses/decompiler/ssailification/traversal.py +4 -6
  60. angr/analyses/decompiler/ssailification/traversal_engine.py +125 -42
  61. angr/analyses/decompiler/structured_codegen/__init__.py +5 -5
  62. angr/analyses/decompiler/structured_codegen/base.py +3 -3
  63. angr/analyses/decompiler/structured_codegen/c.py +39 -40
  64. angr/analyses/decompiler/structuring/__init__.py +3 -3
  65. angr/analyses/decompiler/structuring/phoenix.py +45 -29
  66. angr/analyses/decompiler/structuring/structurer_base.py +2 -2
  67. angr/analyses/decompiler/structuring/structurer_nodes.py +23 -14
  68. angr/analyses/deobfuscator/__init__.py +3 -3
  69. angr/analyses/deobfuscator/irsb_reg_collector.py +29 -60
  70. angr/analyses/deobfuscator/string_obf_finder.py +2 -2
  71. angr/analyses/deobfuscator/string_obf_opt_passes.py +1 -1
  72. angr/analyses/disassembly.py +4 -4
  73. angr/analyses/forward_analysis/__init__.py +1 -1
  74. angr/analyses/forward_analysis/visitors/graph.py +6 -6
  75. angr/analyses/init_finder.py +47 -22
  76. angr/analyses/loop_analysis.py +1 -1
  77. angr/analyses/loopfinder.py +1 -1
  78. angr/analyses/propagator/engine_base.py +21 -14
  79. angr/analyses/propagator/engine_vex.py +149 -179
  80. angr/analyses/propagator/outdated_definition_walker.py +12 -6
  81. angr/analyses/propagator/propagator.py +10 -28
  82. angr/analyses/propagator/top_checker_mixin.py +211 -5
  83. angr/analyses/propagator/vex_vars.py +4 -4
  84. angr/analyses/reaching_definitions/__init__.py +9 -9
  85. angr/analyses/reaching_definitions/call_trace.py +2 -2
  86. angr/analyses/reaching_definitions/dep_graph.py +1 -1
  87. angr/analyses/reaching_definitions/engine_ail.py +304 -329
  88. angr/analyses/reaching_definitions/engine_vex.py +243 -229
  89. angr/analyses/reaching_definitions/function_handler.py +3 -3
  90. angr/analyses/reaching_definitions/function_handler_library/__init__.py +1 -1
  91. angr/analyses/reaching_definitions/rd_state.py +47 -42
  92. angr/analyses/reassembler.py +26 -31
  93. angr/analyses/s_liveness.py +8 -0
  94. angr/analyses/s_propagator.py +18 -3
  95. angr/analyses/s_reaching_definitions/s_rda_view.py +2 -5
  96. angr/analyses/s_reaching_definitions/s_reaching_definitions.py +9 -5
  97. angr/analyses/stack_pointer_tracker.py +4 -4
  98. angr/analyses/typehoon/simple_solver.py +14 -14
  99. angr/analyses/typehoon/translator.py +10 -2
  100. angr/analyses/typehoon/typeconsts.py +11 -3
  101. angr/analyses/typehoon/typevars.py +26 -26
  102. angr/analyses/unpacker/__init__.py +1 -1
  103. angr/analyses/variable_recovery/engine_ail.py +299 -259
  104. angr/analyses/variable_recovery/engine_base.py +138 -121
  105. angr/analyses/variable_recovery/engine_vex.py +175 -185
  106. angr/analyses/variable_recovery/irsb_scanner.py +49 -38
  107. angr/analyses/variable_recovery/variable_recovery.py +28 -5
  108. angr/analyses/variable_recovery/variable_recovery_base.py +33 -34
  109. angr/analyses/variable_recovery/variable_recovery_fast.py +4 -8
  110. angr/analyses/veritesting.py +2 -2
  111. angr/analyses/vfg.py +5 -5
  112. angr/analyses/xrefs.py +46 -19
  113. angr/angrdb/serializers/__init__.py +1 -1
  114. angr/annocfg.py +20 -15
  115. angr/blade.py +2 -2
  116. angr/block.py +20 -25
  117. angr/calling_conventions.py +12 -14
  118. angr/code_location.py +6 -10
  119. angr/codenode.py +3 -3
  120. angr/engines/__init__.py +12 -14
  121. angr/engines/engine.py +24 -61
  122. angr/engines/light/__init__.py +13 -5
  123. angr/engines/light/data.py +1 -1
  124. angr/engines/light/engine.py +1003 -1185
  125. angr/engines/pcode/__init__.py +1 -1
  126. angr/engines/pcode/behavior.py +1 -1
  127. angr/engines/pcode/cc.py +2 -0
  128. angr/engines/pcode/lifter.py +13 -15
  129. angr/engines/soot/expressions/__init__.py +12 -12
  130. angr/engines/soot/statements/__init__.py +6 -6
  131. angr/engines/soot/values/__init__.py +6 -6
  132. angr/engines/soot/values/arrayref.py +2 -2
  133. angr/engines/soot/values/constants.py +1 -1
  134. angr/engines/soot/values/instancefieldref.py +1 -1
  135. angr/engines/soot/values/paramref.py +1 -1
  136. angr/engines/soot/values/staticfieldref.py +1 -1
  137. angr/engines/successors.py +15 -14
  138. angr/engines/vex/__init__.py +5 -5
  139. angr/engines/vex/claripy/ccall.py +2 -2
  140. angr/engines/vex/claripy/datalayer.py +1 -1
  141. angr/engines/vex/claripy/irop.py +19 -19
  142. angr/engines/vex/heavy/__init__.py +2 -2
  143. angr/engines/vex/heavy/actions.py +1 -3
  144. angr/engines/vex/heavy/heavy.py +4 -6
  145. angr/engines/vex/lifter.py +2 -4
  146. angr/engines/vex/light/light.py +0 -2
  147. angr/engines/vex/light/slicing.py +5 -5
  148. angr/exploration_techniques/__init__.py +19 -142
  149. angr/exploration_techniques/base.py +126 -0
  150. angr/exploration_techniques/bucketizer.py +1 -1
  151. angr/exploration_techniques/dfs.py +3 -1
  152. angr/exploration_techniques/director.py +2 -3
  153. angr/exploration_techniques/driller_core.py +1 -1
  154. angr/exploration_techniques/explorer.py +4 -2
  155. angr/exploration_techniques/lengthlimiter.py +2 -1
  156. angr/exploration_techniques/local_loop_seer.py +2 -1
  157. angr/exploration_techniques/loop_seer.py +5 -5
  158. angr/exploration_techniques/manual_mergepoint.py +2 -1
  159. angr/exploration_techniques/memory_watcher.py +3 -1
  160. angr/exploration_techniques/oppologist.py +4 -5
  161. angr/exploration_techniques/slicecutor.py +4 -2
  162. angr/exploration_techniques/spiller.py +1 -1
  163. angr/exploration_techniques/stochastic.py +2 -1
  164. angr/exploration_techniques/stub_stasher.py +2 -1
  165. angr/exploration_techniques/suggestions.py +3 -1
  166. angr/exploration_techniques/symbion.py +3 -1
  167. angr/exploration_techniques/tech_builder.py +2 -1
  168. angr/exploration_techniques/threading.py +2 -11
  169. angr/exploration_techniques/timeout.py +4 -2
  170. angr/exploration_techniques/tracer.py +4 -3
  171. angr/exploration_techniques/unique.py +3 -2
  172. angr/exploration_techniques/veritesting.py +1 -1
  173. angr/factory.py +36 -6
  174. angr/keyed_region.py +4 -4
  175. angr/knowledge_base.py +1 -1
  176. angr/knowledge_plugins/__init__.py +11 -11
  177. angr/knowledge_plugins/cfg/__init__.py +5 -5
  178. angr/knowledge_plugins/cfg/cfg_manager.py +2 -2
  179. angr/knowledge_plugins/cfg/cfg_model.py +8 -8
  180. angr/knowledge_plugins/cfg/cfg_node.py +19 -19
  181. angr/knowledge_plugins/cfg/indirect_jump.py +6 -6
  182. angr/knowledge_plugins/cfg/memory_data.py +5 -7
  183. angr/knowledge_plugins/functions/function.py +48 -52
  184. angr/knowledge_plugins/functions/function_parser.py +4 -4
  185. angr/knowledge_plugins/key_definitions/__init__.py +3 -3
  186. angr/knowledge_plugins/key_definitions/atoms.py +8 -8
  187. angr/knowledge_plugins/key_definitions/definition.py +1 -1
  188. angr/knowledge_plugins/key_definitions/live_definitions.py +30 -27
  189. angr/knowledge_plugins/labels.py +1 -1
  190. angr/knowledge_plugins/propagations/__init__.py +1 -1
  191. angr/knowledge_plugins/propagations/prop_value.py +2 -2
  192. angr/knowledge_plugins/propagations/propagation_model.py +7 -8
  193. angr/knowledge_plugins/propagations/states.py +44 -39
  194. angr/knowledge_plugins/variables/variable_access.py +2 -2
  195. angr/knowledge_plugins/variables/variable_manager.py +24 -10
  196. angr/knowledge_plugins/xrefs/xref.py +5 -8
  197. angr/lib/angr_native.dll +0 -0
  198. angr/misc/__init__.py +4 -4
  199. angr/misc/hookset.py +4 -5
  200. angr/misc/loggers.py +2 -2
  201. angr/misc/telemetry.py +1 -1
  202. angr/procedures/__init__.py +1 -1
  203. angr/procedures/cgc/fdwait.py +2 -2
  204. angr/procedures/definitions/__init__.py +2 -2
  205. angr/procedures/definitions/linux_kernel.py +0 -1
  206. angr/procedures/definitions/parse_syscalls_from_local_system.py +1 -1
  207. angr/procedures/definitions/parse_win32json.py +0 -1
  208. angr/procedures/ntdll/exceptions.py +1 -1
  209. angr/procedures/stubs/format_parser.py +3 -3
  210. angr/procedures/win32/dynamic_loading.py +1 -1
  211. angr/protos/__init__.py +3 -3
  212. angr/sim_manager.py +3 -5
  213. angr/sim_state.py +40 -42
  214. angr/sim_state_options.py +3 -3
  215. angr/sim_type.py +15 -14
  216. angr/sim_variable.py +42 -45
  217. angr/simos/__init__.py +4 -4
  218. angr/simos/cgc.py +1 -1
  219. angr/simos/simos.py +1 -1
  220. angr/simos/userland.py +1 -1
  221. angr/slicer.py +4 -7
  222. angr/state_plugins/__init__.py +34 -34
  223. angr/state_plugins/callstack.py +5 -12
  224. angr/state_plugins/heap/__init__.py +2 -2
  225. angr/state_plugins/heap/heap_brk.py +2 -4
  226. angr/state_plugins/heap/heap_ptmalloc.py +1 -1
  227. angr/state_plugins/jni_references.py +3 -2
  228. angr/state_plugins/scratch.py +1 -1
  229. angr/state_plugins/sim_action.py +1 -4
  230. angr/state_plugins/sim_event.py +1 -1
  231. angr/state_plugins/solver.py +7 -9
  232. angr/state_plugins/uc_manager.py +1 -1
  233. angr/state_plugins/view.py +2 -2
  234. angr/storage/__init__.py +1 -1
  235. angr/storage/file.py +10 -10
  236. angr/storage/memory_mixins/__init__.py +46 -46
  237. angr/storage/memory_mixins/default_filler_mixin.py +1 -3
  238. angr/storage/memory_mixins/javavm_memory_mixin.py +2 -2
  239. angr/storage/memory_mixins/name_resolution_mixin.py +2 -2
  240. angr/storage/memory_mixins/paged_memory/paged_memory_mixin.py +1 -3
  241. angr/storage/memory_mixins/paged_memory/pages/__init__.py +6 -6
  242. angr/storage/memory_mixins/paged_memory/pages/list_page.py +1 -1
  243. angr/storage/memory_mixins/paged_memory/pages/multi_values.py +1 -1
  244. angr/storage/memory_mixins/paged_memory/pages/mv_list_page.py +1 -1
  245. angr/storage/memory_mixins/paged_memory/pages/ultra_page.py +2 -4
  246. angr/storage/memory_mixins/regioned_memory/__init__.py +3 -3
  247. angr/storage/memory_mixins/regioned_memory/region_data.py +5 -5
  248. angr/storage/memory_mixins/regioned_memory/region_meta_mixin.py +7 -9
  249. angr/storage/memory_mixins/regioned_memory/regioned_memory_mixin.py +4 -4
  250. angr/storage/memory_object.py +4 -4
  251. angr/utils/__init__.py +3 -3
  252. angr/utils/bits.py +12 -0
  253. angr/utils/dynamic_dictlist.py +1 -1
  254. angr/utils/graph.py +1 -1
  255. angr/utils/orderedset.py +4 -1
  256. angr/utils/segment_list.py +2 -2
  257. angr/utils/ssa/__init__.py +33 -8
  258. {angr-9.2.131.dist-info → angr-9.2.133.dist-info}/METADATA +6 -6
  259. {angr-9.2.131.dist-info → angr-9.2.133.dist-info}/RECORD +263 -264
  260. angr/analyses/propagator/engine_ail.py +0 -1562
  261. angr/storage/memory_mixins/__init__.pyi +0 -48
  262. {angr-9.2.131.dist-info → angr-9.2.133.dist-info}/LICENSE +0 -0
  263. {angr-9.2.131.dist-info → angr-9.2.133.dist-info}/WHEEL +0 -0
  264. {angr-9.2.131.dist-info → angr-9.2.133.dist-info}/entry_points.txt +0 -0
  265. {angr-9.2.131.dist-info → angr-9.2.133.dist-info}/top_level.txt +0 -0
@@ -1,3 +1,4 @@
1
+ # pylint:disable=too-many-boolean-expressions
1
2
  from __future__ import annotations
2
3
  from typing import Any, NamedTuple, TYPE_CHECKING
3
4
  import copy
@@ -12,6 +13,7 @@ import capstone
12
13
 
13
14
  import ailment
14
15
 
16
+ from angr.analyses.decompiler.ssailification.ssailification import Ssailification
15
17
  from angr.errors import AngrDecompilationError
16
18
  from angr.knowledge_base import KnowledgeBase
17
19
  from angr.knowledge_plugins.functions import Function
@@ -268,6 +270,7 @@ class Clinic(Analysis):
268
270
  def _decompilation_fixups(self, ail_graph):
269
271
  is_pcode_arch = ":" in self.project.arch.name
270
272
 
273
+ self._remove_redundant_jump_blocks(ail_graph)
271
274
  # _fix_abnormal_switch_case_heads may re-lift from VEX blocks, so it should be placed as high up as possible
272
275
  self._fix_abnormal_switch_case_heads(ail_graph)
273
276
  if self._rewrite_ites_to_diamonds:
@@ -597,7 +600,7 @@ class Clinic(Analysis):
597
600
  arg_list.append(arg_vvars[idx][1])
598
601
 
599
602
  # Get virtual variable mapping that can de-phi the SSA representation
600
- vvar2vvar = self._collect_dephi_vvar_mapping_and_rewrite_blocks(ail_graph)
603
+ vvar2vvar, copied_vvar_ids = self._collect_dephi_vvar_mapping_and_rewrite_blocks(ail_graph, arg_vvars)
601
604
 
602
605
  # Recover variables on AIL blocks
603
606
  self._update_progress(80.0, text="Recovering variables")
@@ -605,7 +608,11 @@ class Clinic(Analysis):
605
608
 
606
609
  # Run simplification passes
607
610
  self._update_progress(85.0, text="Running simplifications 4")
608
- ail_graph = self._run_simplification_passes(ail_graph, stage=OptimizationPassStage.AFTER_VARIABLE_RECOVERY)
611
+ ail_graph = self._run_simplification_passes(
612
+ ail_graph,
613
+ stage=OptimizationPassStage.AFTER_VARIABLE_RECOVERY,
614
+ avoid_vvar_ids=copied_vvar_ids,
615
+ )
609
616
 
610
617
  # Make function prototype
611
618
  self._update_progress(90.0, text="Making function prototype")
@@ -1359,10 +1366,9 @@ class Clinic(Analysis):
1359
1366
 
1360
1367
  @timethis
1361
1368
  def _transform_to_ssa_level0(self, ail_graph: networkx.DiGraph) -> networkx.DiGraph:
1362
- ssailification = self.project.analyses.Ssailification(
1369
+ ssailification = self.project.analyses[Ssailification].prep(fail_fast=self._fail_fast)(
1363
1370
  self.function,
1364
1371
  ail_graph,
1365
- fail_fast=self._fail_fast,
1366
1372
  entry=next(iter(bb for bb in ail_graph if (bb.addr, bb.idx) == self.entry_node_addr)),
1367
1373
  ail_manager=self._ail_manager,
1368
1374
  ssa_stackvars=False,
@@ -1387,16 +1393,19 @@ class Clinic(Analysis):
1387
1393
  return ssailification.out_graph
1388
1394
 
1389
1395
  @timethis
1390
- def _collect_dephi_vvar_mapping_and_rewrite_blocks(self, ail_graph: networkx.DiGraph) -> dict[int, int]:
1396
+ def _collect_dephi_vvar_mapping_and_rewrite_blocks(
1397
+ self, ail_graph: networkx.DiGraph, arg_vvars: dict[int, tuple[ailment.Expr.VirtualVariable, SimVariable]]
1398
+ ) -> tuple[dict[int, int], set[int]]:
1391
1399
  dephication = self.project.analyses.GraphDephicationVVarMapping(
1392
1400
  self.function,
1393
1401
  ail_graph,
1394
1402
  fail_fast=self._fail_fast,
1395
1403
  entry=next(iter(bb for bb in ail_graph if (bb.addr, bb.idx) == self.entry_node_addr)),
1396
1404
  vvar_id_start=self.vvar_id_start,
1405
+ arg_vvars=[arg_vvar for arg_vvar, _ in arg_vvars.values()],
1397
1406
  )
1398
1407
  self.vvar_id_start = dephication.vvar_id_start + 1
1399
- return dephication.vvar_to_vvar_mapping
1408
+ return dephication.vvar_to_vvar_mapping, dephication.copied_vvar_ids
1400
1409
 
1401
1410
  @timethis
1402
1411
  def _make_argument_list(self) -> list[SimVariable]:
@@ -1410,7 +1419,7 @@ class Clinic(Analysis):
1410
1419
  argvar = SimRegisterVariable(
1411
1420
  self.project.arch.registers[arg.reg_name][0],
1412
1421
  arg.size,
1413
- ident="arg_%d" % idx,
1422
+ ident=f"arg_{idx}",
1414
1423
  name=arg_names[idx],
1415
1424
  region=self.function.addr,
1416
1425
  )
@@ -1419,13 +1428,13 @@ class Clinic(Analysis):
1419
1428
  arg.stack_offset,
1420
1429
  arg.size,
1421
1430
  base="bp",
1422
- ident="arg_%d" % idx,
1431
+ ident=f"arg_{idx}",
1423
1432
  name=arg_names[idx],
1424
1433
  region=self.function.addr,
1425
1434
  )
1426
1435
  else:
1427
1436
  argvar = SimVariable(
1428
- ident="arg_%d" % idx,
1437
+ ident=f"arg_{idx}",
1429
1438
  name=arg_names[idx],
1430
1439
  region=self.function.addr,
1431
1440
  size=arg.size,
@@ -1932,10 +1941,12 @@ class Clinic(Analysis):
1932
1941
  break
1933
1942
 
1934
1943
  def _create_triangle_for_ite_expression(self, ail_graph, block_addr: int, ite_ins_addr: int):
1935
- # lift the ite instruction to get its size
1936
- ite_insn_size = self.project.factory.block(ite_ins_addr, num_inst=1).size
1944
+ ite_insn_only_block = self.project.factory.block(ite_ins_addr, num_inst=1)
1945
+ ite_insn_size = ite_insn_only_block.size
1937
1946
  if ite_insn_size <= 2: # we need an address for true_block and another address for false_block
1938
1947
  return None
1948
+ if ite_insn_only_block.vex.exit_statements:
1949
+ return None
1939
1950
 
1940
1951
  # relift the head and the ITE instruction
1941
1952
  new_head = self.project.factory.block(
@@ -2037,6 +2048,10 @@ class Clinic(Analysis):
2037
2048
  ):
2038
2049
  return None
2039
2050
 
2051
+ # corner-case: the last statement of original_block might have been patched by _remove_redundant_jump_blocks.
2052
+ # we detect such case and fix it in new_head_ail
2053
+ self._remove_redundant_jump_blocks_repatch_relifted_block(original_block, end_block_ail)
2054
+
2040
2055
  ail_graph.remove_node(original_block)
2041
2056
 
2042
2057
  if end_block_ail not in ail_graph:
@@ -2142,15 +2157,15 @@ class Clinic(Analysis):
2142
2157
  ),
2143
2158
  None,
2144
2159
  )
2160
+ intended_head_block = self.project.factory.block(
2161
+ intended_head.addr, size=intended_head.original_size
2162
+ )
2145
2163
  if comparison_stmt is not None:
2146
- intended_head_block = self.project.factory.block(
2147
- intended_head.addr, size=intended_head.original_size
2148
- )
2149
2164
  cmp_rpos = len(
2150
2165
  intended_head_block.instruction_addrs
2151
2166
  ) - intended_head_block.instruction_addrs.index(comparison_stmt.ins_addr)
2152
2167
  else:
2153
- cmp_rpos = 2
2168
+ cmp_rpos = min(len(intended_head_block.instruction_addrs), 2)
2154
2169
  self._fix_abnormal_switch_case_heads_case2(
2155
2170
  ail_graph,
2156
2171
  candidate,
@@ -2216,7 +2231,6 @@ class Clinic(Analysis):
2216
2231
  if isinstance(stmt, ailment.Stmt.Assignment)
2217
2232
  and isinstance(stmt.src, ailment.Expr.BinaryOp)
2218
2233
  and stmt.src.op in ailment.Expr.BinaryOp.COMPARISON_NEGATION
2219
- and isinstance(stmt.src.operands[1], ailment.Expr.Const)
2220
2234
  and stmt.ins_addr == last_stmt_0.ins_addr
2221
2235
  ),
2222
2236
  None,
@@ -2228,7 +2242,6 @@ class Clinic(Analysis):
2228
2242
  if isinstance(stmt, ailment.Stmt.Assignment)
2229
2243
  and isinstance(stmt.src, ailment.Expr.BinaryOp)
2230
2244
  and stmt.src.op in ailment.Expr.BinaryOp.COMPARISON_NEGATION
2231
- and isinstance(stmt.src.operands[1], ailment.Expr.Const)
2232
2245
  and stmt.ins_addr == last_stmt_1.ins_addr
2233
2246
  ),
2234
2247
  None,
@@ -2270,51 +2283,86 @@ class Clinic(Analysis):
2270
2283
  # split the intended head into two
2271
2284
  intended_head_block = self.project.factory.block(intended_head.addr, size=intended_head.original_size)
2272
2285
  split_ins_addr = intended_head_block.instruction_addrs[-intended_head_split_insns]
2273
- intended_head_block_0 = self.project.factory.block(intended_head.addr, size=split_ins_addr - intended_head.addr)
2286
+ # note that the two blocks can be fully overlapping, so block_0 will be empty...
2287
+ intended_head_block_0 = (
2288
+ self.project.factory.block(intended_head.addr, size=split_ins_addr - intended_head.addr)
2289
+ if split_ins_addr != intended_head.addr
2290
+ else None
2291
+ )
2274
2292
  intended_head_block_1 = self.project.factory.block(
2275
2293
  split_ins_addr, size=intended_head.addr + intended_head.original_size - split_ins_addr
2276
2294
  )
2277
- intended_head_0 = self._convert_vex(intended_head_block_0)
2295
+ intended_head_0 = self._convert_vex(intended_head_block_0) if intended_head_block_0 is not None else None
2278
2296
  intended_head_1 = self._convert_vex(intended_head_block_1)
2279
2297
 
2298
+ # corner-case: the last statement of intended_head might have been patched by _remove_redundant_jump_blocks. we
2299
+ # detect such case and fix it in intended_head_1
2300
+ self._remove_redundant_jump_blocks_repatch_relifted_block(intended_head, intended_head_1)
2301
+
2280
2302
  # adjust the graph accordingly
2281
2303
  preds = list(ail_graph.predecessors(intended_head))
2282
2304
  succs = list(ail_graph.successors(intended_head))
2283
2305
  ail_graph.remove_node(intended_head)
2284
- ail_graph.add_edge(intended_head_0, intended_head_1)
2285
- for pred in preds:
2286
- if pred is intended_head:
2287
- ail_graph.add_edge(intended_head_1, intended_head_0)
2288
- else:
2289
- ail_graph.add_edge(pred, intended_head_0)
2290
- for succ in succs:
2291
- if succ is intended_head:
2292
- ail_graph.add_edge(intended_head_1, intended_head_0)
2293
- else:
2294
- ail_graph.add_edge(intended_head_1, succ)
2306
+
2307
+ if intended_head_0 is None:
2308
+ # perfect overlap; the first block is empty
2309
+ for pred in preds:
2310
+ if pred is intended_head:
2311
+ ail_graph.add_edge(intended_head_1, intended_head_1)
2312
+ else:
2313
+ ail_graph.add_edge(pred, intended_head_1)
2314
+ for succ in succs:
2315
+ if succ is intended_head:
2316
+ ail_graph.add_edge(intended_head_1, intended_head_1)
2317
+ else:
2318
+ ail_graph.add_edge(intended_head_1, succ)
2319
+ else:
2320
+ ail_graph.add_edge(intended_head_0, intended_head_1)
2321
+ for pred in preds:
2322
+ if pred is intended_head:
2323
+ ail_graph.add_edge(intended_head_1, intended_head_0)
2324
+ else:
2325
+ ail_graph.add_edge(pred, intended_head_0)
2326
+ for succ in succs:
2327
+ if succ is intended_head:
2328
+ ail_graph.add_edge(intended_head_1, intended_head_0)
2329
+ else:
2330
+ ail_graph.add_edge(intended_head_1, succ)
2295
2331
 
2296
2332
  # split other heads
2297
2333
  for o in other_heads:
2298
2334
  if other_head_split_insns > 0:
2299
2335
  o_block = self.project.factory.block(o.addr, size=o.original_size)
2300
2336
  o_split_addr = o_block.instruction_addrs[-other_head_split_insns]
2301
- new_o_block = self.project.factory.block(o.addr, size=o_split_addr - o.addr)
2302
- new_head = self._convert_vex(new_o_block)
2337
+ new_o_block = (
2338
+ self.project.factory.block(o.addr, size=o_split_addr - o.addr) if o_split_addr != o.addr else None
2339
+ )
2340
+ new_head = self._convert_vex(new_o_block) if new_o_block is not None else None
2303
2341
  else:
2304
2342
  new_head = o
2305
2343
 
2306
- if (
2307
- new_head.statements
2308
- and isinstance(new_head.statements[-1], ailment.Stmt.Jump)
2309
- and isinstance(new_head.statements[-1].target, ailment.Expr.Const)
2310
- ):
2311
- # update the jump target
2312
- new_head.statements[-1] = ailment.Stmt.Jump(
2313
- new_head.statements[-1].idx,
2344
+ if new_head is None:
2345
+ # the head is removed - let's replace it with a jump to the target
2346
+ jump_stmt = ailment.Stmt.Jump(
2347
+ None,
2314
2348
  ailment.Expr.Const(None, None, intended_head_1.addr, self.project.arch.bits),
2315
2349
  target_idx=intended_head_1.idx,
2316
- **new_head.statements[-1].tags,
2350
+ ins_addr=o.addr,
2317
2351
  )
2352
+ new_head = ailment.Block(o.addr, 1, statements=[jump_stmt], idx=o.idx)
2353
+ else:
2354
+ if (
2355
+ new_head.statements
2356
+ and isinstance(new_head.statements[-1], ailment.Stmt.Jump)
2357
+ and isinstance(new_head.statements[-1].target, ailment.Expr.Const)
2358
+ ):
2359
+ # update the jump target
2360
+ new_head.statements[-1] = ailment.Stmt.Jump(
2361
+ new_head.statements[-1].idx,
2362
+ ailment.Expr.Const(None, None, intended_head_1.addr, self.project.arch.bits),
2363
+ target_idx=intended_head_1.idx,
2364
+ **new_head.statements[-1].tags,
2365
+ )
2318
2366
 
2319
2367
  # adjust the graph accordingly
2320
2368
  preds = list(ail_graph.predecessors(o))
@@ -2384,6 +2432,39 @@ class Clinic(Analysis):
2384
2432
  ail_graph.add_edge(pred, succs[0])
2385
2433
  ail_graph.remove_node(node)
2386
2434
 
2435
+ @staticmethod
2436
+ def _remove_redundant_jump_blocks_repatch_relifted_block(
2437
+ patched_block: ailment.Block, new_block: ailment.Block
2438
+ ) -> None:
2439
+ """
2440
+ The last statement of patched_block might have been patched by _remove_redundant_jump_blocks. In this case, we
2441
+ fix the last instruction for new_block, which is a newly lifted (from VEX) block that ends at the same address
2442
+ as patched_block.
2443
+
2444
+ :param patched_block: Previously patched block.
2445
+ :param new_block: Newly lifted block.
2446
+ """
2447
+
2448
+ if (
2449
+ isinstance(patched_block.statements[-1], ailment.Stmt.Jump)
2450
+ and isinstance(patched_block.statements[-1].target, ailment.Expr.Const)
2451
+ and isinstance(new_block.statements[-1], ailment.Stmt.Jump)
2452
+ and isinstance(new_block.statements[-1].target, ailment.Expr.Const)
2453
+ and not patched_block.statements[-1].likes(new_block.statements[-1])
2454
+ ):
2455
+ new_block.statements[-1].target = patched_block.statements[-1].target
2456
+ if (
2457
+ isinstance(patched_block.statements[-1], ailment.Stmt.ConditionalJump)
2458
+ and isinstance(patched_block.statements[-1].true_target, ailment.Expr.Const)
2459
+ and isinstance(patched_block.statements[-1].false_target, ailment.Expr.Const)
2460
+ and isinstance(new_block.statements[-1], ailment.Stmt.ConditionalJump)
2461
+ and isinstance(new_block.statements[-1].true_target, ailment.Expr.Const)
2462
+ and isinstance(new_block.statements[-1].false_target, ailment.Expr.Const)
2463
+ and not patched_block.statements[-1].likes(new_block.statements[-1])
2464
+ ):
2465
+ new_block.statements[-1].true_target = patched_block.statements[-1].true_target
2466
+ new_block.statements[-1].false_target = patched_block.statements[-1].false_target
2467
+
2387
2468
  @staticmethod
2388
2469
  def _insert_block_labels(ail_graph):
2389
2470
  for node in ail_graph.nodes:
@@ -113,41 +113,53 @@ _ail2claripy_op_mapping = {
113
113
  "LogicalOr": lambda expr, conv, _, ia: claripy.Or(
114
114
  conv(expr.operands[0], ins_addr=ia), conv(expr.operands[1], ins_addr=ia)
115
115
  ),
116
- "CmpEQ": lambda expr, conv, _, ia: conv(expr.operands[0], ins_addr=ia) == conv(expr.operands[1], ins_addr=ia),
117
- "CmpNE": lambda expr, conv, _, ia: conv(expr.operands[0], ins_addr=ia) != conv(expr.operands[1], ins_addr=ia),
118
- "CmpLE": lambda expr, conv, _, ia: conv(expr.operands[0], ins_addr=ia) <= conv(expr.operands[1], ins_addr=ia),
119
- "CmpLEs": lambda expr, conv, _, ia: claripy.SLE(
120
- conv(expr.operands[0], ins_addr=ia), conv(expr.operands[1], ins_addr=ia)
116
+ "CmpEQ": lambda expr, conv, _, ia: conv(expr.operands[0], nobool=True, ins_addr=ia)
117
+ == conv(expr.operands[1], nobool=True, ins_addr=ia),
118
+ "CmpNE": lambda expr, conv, _, ia: conv(expr.operands[0], nobool=True, ins_addr=ia)
119
+ != conv(expr.operands[1], nobool=True, ins_addr=ia),
120
+ "CmpLE": lambda expr, conv, _, ia: conv(expr.operands[0], nobool=True, ins_addr=ia)
121
+ <= conv(expr.operands[1], nobool=True, ins_addr=ia),
122
+ "CmpLE (signed)": lambda expr, conv, _, ia: claripy.SLE(
123
+ conv(expr.operands[0], nobool=True, ins_addr=ia), conv(expr.operands[1], nobool=True, ins_addr=ia)
121
124
  ),
122
- "CmpLT": lambda expr, conv, _, ia: conv(expr.operands[0], ins_addr=ia) < conv(expr.operands[1], ins_addr=ia),
123
- "CmpLTs": lambda expr, conv, _, ia: claripy.SLT(
124
- conv(expr.operands[0], ins_addr=ia), conv(expr.operands[1], ins_addr=ia)
125
+ "CmpLT": lambda expr, conv, _, ia: conv(expr.operands[0], nobool=True, ins_addr=ia)
126
+ < conv(expr.operands[1], nobool=True, ins_addr=ia),
127
+ "CmpLT (signed)": lambda expr, conv, _, ia: claripy.SLT(
128
+ conv(expr.operands[0], nobool=True, ins_addr=ia), conv(expr.operands[1], nobool=True, ins_addr=ia)
125
129
  ),
126
- "CmpGE": lambda expr, conv, _, ia: conv(expr.operands[0], ins_addr=ia) >= conv(expr.operands[1], ins_addr=ia),
127
- "CmpGEs": lambda expr, conv, _, ia: claripy.SGE(
128
- conv(expr.operands[0], ins_addr=ia), conv(expr.operands[1], ins_addr=ia)
130
+ "CmpGE": lambda expr, conv, _, ia: conv(expr.operands[0], nobool=True, ins_addr=ia)
131
+ >= conv(expr.operands[1], nobool=True, ins_addr=ia),
132
+ "CmpGE (signed)": lambda expr, conv, _, ia: claripy.SGE(
133
+ conv(expr.operands[0], nobool=True, ins_addr=ia), conv(expr.operands[1], nobool=True, ins_addr=ia)
129
134
  ),
130
- "CmpGT": lambda expr, conv, _, ia: conv(expr.operands[0], ins_addr=ia) > conv(expr.operands[1], ins_addr=ia),
131
- "CmpGTs": lambda expr, conv, _, ia: claripy.SGT(
132
- conv(expr.operands[0], ins_addr=ia), conv(expr.operands[1], ins_addr=ia)
135
+ "CmpGT": lambda expr, conv, _, ia: conv(expr.operands[0], nobool=True, ins_addr=ia)
136
+ > conv(expr.operands[1], nobool=True, ins_addr=ia),
137
+ "CmpGT (signed)": lambda expr, conv, _, ia: claripy.SGT(
138
+ conv(expr.operands[0], nobool=True, ins_addr=ia), conv(expr.operands[1], nobool=True, ins_addr=ia)
133
139
  ),
134
- "CasCmpEQ": lambda expr, conv, _, ia: conv(expr.operands[0], ins_addr=ia) == conv(expr.operands[1], ins_addr=ia),
135
- "CasCmpNE": lambda expr, conv, _, ia: conv(expr.operands[0], ins_addr=ia) != conv(expr.operands[1], ins_addr=ia),
136
- "CasCmpLE": lambda expr, conv, _, ia: conv(expr.operands[0], ins_addr=ia) <= conv(expr.operands[1], ins_addr=ia),
137
- "CasCmpLEs": lambda expr, conv, _, ia: claripy.SLE(
138
- conv(expr.operands[0], ins_addr=ia), conv(expr.operands[1], ins_addr=ia)
140
+ "CasCmpEQ": lambda expr, conv, _, ia: conv(expr.operands[0], nobool=True, ins_addr=ia)
141
+ == conv(expr.operands[1], nobool=True, ins_addr=ia),
142
+ "CasCmpNE": lambda expr, conv, _, ia: conv(expr.operands[0], nobool=True, ins_addr=ia)
143
+ != conv(expr.operands[1], nobool=True, ins_addr=ia),
144
+ "CasCmpLE": lambda expr, conv, _, ia: conv(expr.operands[0], nobool=True, ins_addr=ia)
145
+ <= conv(expr.operands[1], nobool=True, ins_addr=ia),
146
+ "CasCmpLE (signed)": lambda expr, conv, _, ia: claripy.SLE(
147
+ conv(expr.operands[0], nobool=True, ins_addr=ia), conv(expr.operands[1], nobool=True, ins_addr=ia)
139
148
  ),
140
- "CasCmpLT": lambda expr, conv, _, ia: conv(expr.operands[0], ins_addr=ia) < conv(expr.operands[1], ins_addr=ia),
141
- "CasCmpLTs": lambda expr, conv, _, ia: claripy.SLT(
142
- conv(expr.operands[0], ins_addr=ia), conv(expr.operands[1], ins_addr=ia)
149
+ "CasCmpLT": lambda expr, conv, _, ia: conv(expr.operands[0], nobool=True, ins_addr=ia)
150
+ < conv(expr.operands[1], nobool=True, ins_addr=ia),
151
+ "CasCmpLT (signed)": lambda expr, conv, _, ia: claripy.SLT(
152
+ conv(expr.operands[0], nobool=True, ins_addr=ia), conv(expr.operands[1], nobool=True, ins_addr=ia)
143
153
  ),
144
- "CasCmpGE": lambda expr, conv, _, ia: conv(expr.operands[0], ins_addr=ia) >= conv(expr.operands[1], ins_addr=ia),
145
- "CasCmpGEs": lambda expr, conv, _, ia: claripy.SGE(
146
- conv(expr.operands[0], ins_addr=ia), conv(expr.operands[1], ins_addr=ia)
154
+ "CasCmpGE": lambda expr, conv, _, ia: conv(expr.operands[0], nobool=True, ins_addr=ia)
155
+ >= conv(expr.operands[1], nobool=True, ins_addr=ia),
156
+ "CasCmpGE (signed)": lambda expr, conv, _, ia: claripy.SGE(
157
+ conv(expr.operands[0], nobool=True, ins_addr=ia), conv(expr.operands[1], nobool=True, ins_addr=ia)
147
158
  ),
148
- "CasCmpGT": lambda expr, conv, _, ia: conv(expr.operands[0], ins_addr=ia) > conv(expr.operands[1], ins_addr=ia),
149
- "CasCmpGTs": lambda expr, conv, _, ia: claripy.SGT(
150
- conv(expr.operands[0], ins_addr=ia), conv(expr.operands[1], ins_addr=ia)
159
+ "CasCmpGT": lambda expr, conv, _, ia: conv(expr.operands[0], nobool=True, ins_addr=ia)
160
+ > conv(expr.operands[1], nobool=True, ins_addr=ia),
161
+ "CasCmpGT (signed)": lambda expr, conv, _, ia: claripy.SGT(
162
+ conv(expr.operands[0], nobool=True, ins_addr=ia), conv(expr.operands[1], nobool=True, ins_addr=ia)
151
163
  ),
152
164
  "Add": lambda expr, conv, _, ia: conv(expr.operands[0], nobool=True, ins_addr=ia)
153
165
  + conv(expr.operands[1], nobool=True, ins_addr=ia),
@@ -177,10 +189,9 @@ _ail2claripy_op_mapping = {
177
189
  ),
178
190
  "Concat": lambda expr, conv, _, ia: claripy.Concat(*[conv(operand, ins_addr=ia) for operand in expr.operands]),
179
191
  # There are no corresponding claripy operations for the following operations
180
- "DivMod": lambda expr, _, m, *args: _dummy_bvs(expr, m),
181
192
  "CmpF": lambda expr, _, m, *args: _dummy_bvs(expr, m),
182
193
  "Mull": lambda expr, _, m, *args: _dummy_bvs(expr, m),
183
- "Mulls": lambda expr, _, m, *args: _dummy_bvs(expr, m),
194
+ "Mull (signed)": lambda expr, _, m, *args: _dummy_bvs(expr, m),
184
195
  "Reinterpret": lambda expr, _, m, *args: _dummy_bvs(expr, m),
185
196
  "Rol": lambda expr, _, m, *args: _dummy_bvs(expr, m),
186
197
  "Ror": lambda expr, _, m, *args: _dummy_bvs(expr, m),
@@ -190,7 +201,10 @@ _ail2claripy_op_mapping = {
190
201
  "SBorrow": lambda expr, _, m, *args: _dummy_bvs(expr, m),
191
202
  "ExpCmpNE": lambda expr, _, m, *args: _dummy_bools(expr, m),
192
203
  "CmpORD": lambda expr, _, m, *args: _dummy_bvs(expr, m), # in case CmpORDRewriter fails
204
+ "CmpEQV": lambda expr, _, m, *args: _dummy_bvs(expr, m),
193
205
  "GetMSBs": lambda expr, _, m, *args: _dummy_bvs(expr, m),
206
+ "ShlNV": lambda expr, _, m, *args: _dummy_bvs(expr, m),
207
+ "ShrNV": lambda expr, _, m, *args: _dummy_bvs(expr, m),
194
208
  "InterleaveLOV": lambda expr, _, m, *args: _dummy_bvs(expr, m),
195
209
  "InterleaveHIV": lambda expr, _, m, *args: _dummy_bvs(expr, m),
196
210
  # catch-all
@@ -800,9 +814,13 @@ class ConditionProcessor:
800
814
  f"Condition variable {cond} has an unsupported operator {cond.op}. Consider implementing."
801
815
  )
802
816
 
803
- def claripy_ast_from_ail_condition(self, condition, nobool: bool = False, *, ins_addr: int = 0) -> claripy.ast.Bool:
817
+ def claripy_ast_from_ail_condition(
818
+ self, condition, nobool: bool = False, *, ins_addr: int = 0
819
+ ) -> claripy.ast.Bool | claripy.ast.Bits:
804
820
  # Unpack a condition all the way to the leaves
805
- if isinstance(condition, claripy.ast.Base): # pylint:disable=isinstance-second-argument-not-valid-type
821
+ if isinstance(
822
+ condition, (claripy.ast.Bits, claripy.ast.Bool)
823
+ ): # pylint:disable=isinstance-second-argument-not-valid-type
806
824
  return condition
807
825
 
808
826
  if isinstance(
@@ -830,11 +848,11 @@ class ConditionProcessor:
830
848
  # convert is special. if it generates a 1-bit variable, it should be treated as a BoolS
831
849
  if condition.to_bits == 1:
832
850
  var_ = self.claripy_ast_from_ail_condition(condition.operands[0], ins_addr=ins_addr)
833
- name = "ailcond_Conv(%d->%d, %d)" % (condition.from_bits, condition.to_bits, hash(var_))
851
+ name = f"ailcond_Conv({condition.from_bits}->{condition.to_bits}, {hash(var_)})"
834
852
  var = claripy.BoolS(name, explicit_name=True)
835
853
  else:
836
854
  var_ = self.claripy_ast_from_ail_condition(condition.operands[0], ins_addr=ins_addr)
837
- name = "ailexpr_Conv(%d->%d, %d)" % (condition.from_bits, condition.to_bits, hash(var_))
855
+ name = f"ailexpr_Conv({condition.from_bits}->{condition.to_bits}, {hash(var_)})"
838
856
  var = claripy.BVS(name, condition.to_bits, explicit_name=True)
839
857
  self._condition_mapping[var.args[0]] = condition
840
858
  return var
@@ -849,17 +867,17 @@ class ConditionProcessor:
849
867
  if isinstance(condition, ailment.Expr.Tmp):
850
868
  l.warning("Left-over ailment.Tmp variable %s.", condition)
851
869
  if condition.bits == 1:
852
- var = claripy.BoolS("ailtmp_%d" % condition.tmp_idx, explicit_name=True)
870
+ var = claripy.BoolS(f"ailtmp_{condition.tmp_idx}", explicit_name=True)
853
871
  else:
854
- var = claripy.BVS("ailtmp_%d" % condition.tmp_idx, condition.bits, explicit_name=True)
872
+ var = claripy.BVS(f"ailtmp_{condition.tmp_idx}", condition.bits, explicit_name=True)
855
873
  self._condition_mapping[var.args[0]] = condition
856
874
  return var
857
875
  if isinstance(condition, ailment.Expr.MultiStatementExpression):
858
876
  # just cache it
859
877
  if condition.bits == 1:
860
- var = claripy.BoolS("mstmtexpr_%d" % hash(condition), explicit_name=True)
878
+ var = claripy.BoolS(f"mstmtexpr_{hash(condition)}", explicit_name=True)
861
879
  else:
862
- var = claripy.BVS("mstmtexpr_%d" % hash(condition), condition.bits, explicit_name=True)
880
+ var = claripy.BVS(f"mstmtexpr_{hash(condition)}", condition.bits, explicit_name=True)
863
881
  self._condition_mapping[var.args[0]] = condition
864
882
  return var
865
883
 
@@ -883,7 +901,7 @@ class ConditionProcessor:
883
901
  self._condition_mapping[r.args[0]] = condition
884
902
 
885
903
  if r is NotImplemented:
886
- if condition.bits == 1:
904
+ if condition.bits == 1 and not nobool:
887
905
  r = claripy.BoolS(f"ailexpr_{condition!r}", explicit_name=True)
888
906
  else:
889
907
  r = claripy.BVS(f"ailexpr_{condition!r}", condition.bits, explicit_name=True)
@@ -7,10 +7,10 @@ from .expression_counters import SingleExpressionCounter, RegisterExpressionCoun
7
7
 
8
8
 
9
9
  __all__ = (
10
- "BooleanCounter",
11
10
  "AILBlockCallCounter",
11
+ "BooleanCounter",
12
12
  "ControlFlowStructureCounter",
13
- "SingleExpressionCounter",
14
- "RegisterExpressionCounter",
15
13
  "OperatorCounter",
14
+ "RegisterExpressionCounter",
15
+ "SingleExpressionCounter",
16
16
  )
@@ -14,16 +14,16 @@ class DecompilationCache:
14
14
  """
15
15
 
16
16
  __slots__ = (
17
- "parameters",
18
17
  "addr",
19
- "type_constraints",
20
- "func_typevar",
21
- "var_to_typevar",
22
- "codegen",
23
- "clinic",
24
- "ite_exprs",
25
18
  "binop_operators",
19
+ "clinic",
20
+ "codegen",
26
21
  "errors",
22
+ "func_typevar",
23
+ "ite_exprs",
24
+ "parameters",
25
+ "type_constraints",
26
+ "var_to_typevar",
27
27
  )
28
28
 
29
29
  def __init__(self, addr):
@@ -3,4 +3,4 @@ from .graph_vvar_mapping import GraphDephicationVVarMapping
3
3
  from .graph_dephication import GraphDephication
4
4
  from .seqnode_dephication import SeqNodeDephication
5
5
 
6
- __all__ = ["GraphDephicationVVarMapping", "GraphDephication", "SeqNodeDephication"]
6
+ __all__ = ["GraphDephication", "GraphDephicationVVarMapping", "SeqNodeDephication"]
@@ -37,7 +37,7 @@ class GraphRewritingAnalysis(ForwardAnalysis[None, NodeType, object, object]):
37
37
  )
38
38
  self._graph = ail_graph
39
39
  self._vvar_to_vvar = vvar_to_vvar
40
- self._engine_ail = SimEngineDephiRewriting(self.project.arch, self._vvar_to_vvar)
40
+ self._engine_ail = SimEngineDephiRewriting(self.project, self._vvar_to_vvar)
41
41
 
42
42
  self._visited_blocks: set[Any] = set()
43
43
  self.out_blocks = {}
@@ -10,7 +10,7 @@ from angr.analyses import Analysis
10
10
  from angr.analyses.s_reaching_definitions import SRDAModel
11
11
  from angr.knowledge_plugins.functions import Function
12
12
  from angr.analyses import register_analysis
13
- from angr.utils.ssa import is_phi_assignment
13
+ from angr.utils.ssa import is_phi_assignment, DEPHI_VVAR_REG_OFFSET
14
14
 
15
15
  l = logging.getLogger(name=__name__)
16
16
 
@@ -30,6 +30,7 @@ class GraphDephicationVVarMapping(Analysis): # pylint:disable=abstract-method
30
30
  ail_graph,
31
31
  entry=None,
32
32
  vvar_id_start: int = 0,
33
+ arg_vvars: list[VirtualVariable] | None = None,
33
34
  ):
34
35
  """
35
36
  :param func: The subject of the analysis: a function, or a single basic block
@@ -49,8 +50,10 @@ class GraphDephicationVVarMapping(Analysis): # pylint:disable=abstract-method
49
50
  self._vvar_defloc = {}
50
51
  self.vvar_id_start = vvar_id_start
51
52
  self._stmts_to_prepend = defaultdict(list)
53
+ self._arg_vvars = arg_vvars or []
52
54
 
53
55
  self.vvar_to_vvar_mapping = None
56
+ self.copied_vvar_ids: set[int] = set()
54
57
  self._rd: SRDAModel = self.project.analyses.SReachingDefinitions(
55
58
  subject=self._function, func_graph=self._graph
56
59
  ).model
@@ -74,7 +77,9 @@ class GraphDephicationVVarMapping(Analysis): # pylint:disable=abstract-method
74
77
  phi_congruence_class[varid] = {varid}
75
78
 
76
79
  # compute liveness
77
- liveness = self.project.analyses.SLiveness(self._function, func_graph=self._graph, entry=self._entry)
80
+ liveness = self.project.analyses.SLiveness(
81
+ self._function, func_graph=self._graph, entry=self._entry, arg_vvars=self._arg_vvars
82
+ )
78
83
 
79
84
  live_ins = liveness.model.live_ins
80
85
  live_outs = liveness.model.live_outs
@@ -136,6 +141,8 @@ class GraphDephicationVVarMapping(Analysis): # pylint:disable=abstract-method
136
141
 
137
142
  if insertion_type == 0:
138
143
  for src, old_vvar_id, new_vvar_id in new_vvar_ids:
144
+ self.copied_vvar_ids.add(new_vvar_id)
145
+
139
146
  phi_congruence_class[new_vvar_id] = {new_vvar_id}
140
147
  live_outs[src].add(new_vvar_id)
141
148
 
@@ -153,6 +160,7 @@ class GraphDephicationVVarMapping(Analysis): # pylint:disable=abstract-method
153
160
 
154
161
  else: # insertion_type == 1
155
162
  phi_block_loc, old_phi_varid, new_phi_varid = next(iter(new_vvar_ids))
163
+ self.copied_vvar_ids.add(new_phi_varid)
156
164
 
157
165
  phi_congruence_class[new_phi_varid] = {new_phi_varid}
158
166
 
@@ -217,7 +225,7 @@ class GraphDephicationVVarMapping(Analysis): # pylint:disable=abstract-method
217
225
  # it's a parameter, so we copy the variable into a dummy register vvar
218
226
  # a parameter vvar should never be assigned to
219
227
  new_category = VirtualVariableCategory.REGISTER
220
- new_oident = 4096
228
+ new_oident = DEPHI_VVAR_REG_OFFSET
221
229
  else:
222
230
  new_category = vvar.category
223
231
  new_oident = vvar.oident