angr 9.2.192__cp311-cp311-macosx_10_12_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.
Files changed (1442) hide show
  1. angr/__init__.py +366 -0
  2. angr/__main__.py +182 -0
  3. angr/ail_callable.py +79 -0
  4. angr/ailment/__init__.py +83 -0
  5. angr/ailment/block.py +88 -0
  6. angr/ailment/block_walker.py +856 -0
  7. angr/ailment/constant.py +3 -0
  8. angr/ailment/converter_common.py +11 -0
  9. angr/ailment/converter_pcode.py +648 -0
  10. angr/ailment/converter_vex.py +829 -0
  11. angr/ailment/expression.py +1655 -0
  12. angr/ailment/manager.py +34 -0
  13. angr/ailment/statement.py +973 -0
  14. angr/ailment/tagged_object.py +58 -0
  15. angr/ailment/utils.py +114 -0
  16. angr/analyses/__init__.py +117 -0
  17. angr/analyses/analysis.py +429 -0
  18. angr/analyses/backward_slice.py +686 -0
  19. angr/analyses/binary_optimizer.py +670 -0
  20. angr/analyses/bindiff.py +1512 -0
  21. angr/analyses/boyscout.py +76 -0
  22. angr/analyses/callee_cleanup_finder.py +74 -0
  23. angr/analyses/calling_convention/__init__.py +6 -0
  24. angr/analyses/calling_convention/calling_convention.py +1113 -0
  25. angr/analyses/calling_convention/fact_collector.py +647 -0
  26. angr/analyses/calling_convention/utils.py +60 -0
  27. angr/analyses/cdg.py +189 -0
  28. angr/analyses/cfg/__init__.py +23 -0
  29. angr/analyses/cfg/cfb.py +451 -0
  30. angr/analyses/cfg/cfg.py +74 -0
  31. angr/analyses/cfg/cfg_arch_options.py +95 -0
  32. angr/analyses/cfg/cfg_base.py +2954 -0
  33. angr/analyses/cfg/cfg_emulated.py +3451 -0
  34. angr/analyses/cfg/cfg_fast.py +5431 -0
  35. angr/analyses/cfg/cfg_fast_soot.py +662 -0
  36. angr/analyses/cfg/cfg_job_base.py +203 -0
  37. angr/analyses/cfg/indirect_jump_resolvers/__init__.py +30 -0
  38. angr/analyses/cfg/indirect_jump_resolvers/aarch64_macho_got.py +77 -0
  39. angr/analyses/cfg/indirect_jump_resolvers/amd64_elf_got.py +62 -0
  40. angr/analyses/cfg/indirect_jump_resolvers/amd64_pe_iat.py +51 -0
  41. angr/analyses/cfg/indirect_jump_resolvers/arm_elf_fast.py +159 -0
  42. angr/analyses/cfg/indirect_jump_resolvers/const_resolver.py +339 -0
  43. angr/analyses/cfg/indirect_jump_resolvers/constant_value_manager.py +107 -0
  44. angr/analyses/cfg/indirect_jump_resolvers/default_resolvers.py +82 -0
  45. angr/analyses/cfg/indirect_jump_resolvers/jumptable.py +2490 -0
  46. angr/analyses/cfg/indirect_jump_resolvers/memload_resolver.py +81 -0
  47. angr/analyses/cfg/indirect_jump_resolvers/mips_elf_fast.py +286 -0
  48. angr/analyses/cfg/indirect_jump_resolvers/mips_elf_got.py +148 -0
  49. angr/analyses/cfg/indirect_jump_resolvers/propagator_utils.py +46 -0
  50. angr/analyses/cfg/indirect_jump_resolvers/resolver.py +74 -0
  51. angr/analyses/cfg/indirect_jump_resolvers/syscall_resolver.py +92 -0
  52. angr/analyses/cfg/indirect_jump_resolvers/x86_elf_pic_plt.py +88 -0
  53. angr/analyses/cfg/indirect_jump_resolvers/x86_pe_iat.py +47 -0
  54. angr/analyses/cfg_slice_to_sink/__init__.py +11 -0
  55. angr/analyses/cfg_slice_to_sink/cfg_slice_to_sink.py +117 -0
  56. angr/analyses/cfg_slice_to_sink/graph.py +87 -0
  57. angr/analyses/cfg_slice_to_sink/transitions.py +27 -0
  58. angr/analyses/class_identifier.py +63 -0
  59. angr/analyses/code_tagging.py +123 -0
  60. angr/analyses/codecave.py +77 -0
  61. angr/analyses/complete_calling_conventions.py +475 -0
  62. angr/analyses/congruency_check.py +377 -0
  63. angr/analyses/data_dep/__init__.py +16 -0
  64. angr/analyses/data_dep/data_dependency_analysis.py +595 -0
  65. angr/analyses/data_dep/dep_nodes.py +171 -0
  66. angr/analyses/data_dep/sim_act_location.py +49 -0
  67. angr/analyses/datagraph_meta.py +105 -0
  68. angr/analyses/ddg.py +1670 -0
  69. angr/analyses/decompiler/__init__.py +41 -0
  70. angr/analyses/decompiler/ail_simplifier.py +2246 -0
  71. angr/analyses/decompiler/ailgraph_walker.py +49 -0
  72. angr/analyses/decompiler/block_io_finder.py +302 -0
  73. angr/analyses/decompiler/block_similarity.py +199 -0
  74. angr/analyses/decompiler/block_simplifier.py +397 -0
  75. angr/analyses/decompiler/callsite_maker.py +579 -0
  76. angr/analyses/decompiler/ccall_rewriters/__init__.py +9 -0
  77. angr/analyses/decompiler/ccall_rewriters/amd64_ccalls.py +618 -0
  78. angr/analyses/decompiler/ccall_rewriters/rewriter_base.py +24 -0
  79. angr/analyses/decompiler/ccall_rewriters/x86_ccalls.py +354 -0
  80. angr/analyses/decompiler/clinic.py +3662 -0
  81. angr/analyses/decompiler/condition_processor.py +1323 -0
  82. angr/analyses/decompiler/counters/__init__.py +16 -0
  83. angr/analyses/decompiler/counters/boolean_counter.py +27 -0
  84. angr/analyses/decompiler/counters/call_counter.py +77 -0
  85. angr/analyses/decompiler/counters/expression_counters.py +77 -0
  86. angr/analyses/decompiler/counters/seq_cf_structure_counter.py +63 -0
  87. angr/analyses/decompiler/decompilation_cache.py +54 -0
  88. angr/analyses/decompiler/decompilation_options.py +317 -0
  89. angr/analyses/decompiler/decompiler.py +796 -0
  90. angr/analyses/decompiler/dephication/__init__.py +6 -0
  91. angr/analyses/decompiler/dephication/dephication_base.py +100 -0
  92. angr/analyses/decompiler/dephication/graph_dephication.py +70 -0
  93. angr/analyses/decompiler/dephication/graph_rewriting.py +112 -0
  94. angr/analyses/decompiler/dephication/graph_vvar_mapping.py +357 -0
  95. angr/analyses/decompiler/dephication/rewriting_engine.py +528 -0
  96. angr/analyses/decompiler/dephication/seqnode_dephication.py +156 -0
  97. angr/analyses/decompiler/dirty_rewriters/__init__.py +7 -0
  98. angr/analyses/decompiler/dirty_rewriters/amd64_dirty.py +74 -0
  99. angr/analyses/decompiler/dirty_rewriters/rewriter_base.py +27 -0
  100. angr/analyses/decompiler/empty_node_remover.py +212 -0
  101. angr/analyses/decompiler/expression_narrower.py +290 -0
  102. angr/analyses/decompiler/goto_manager.py +112 -0
  103. angr/analyses/decompiler/graph_region.py +441 -0
  104. angr/analyses/decompiler/jump_target_collector.py +37 -0
  105. angr/analyses/decompiler/jumptable_entry_condition_rewriter.py +67 -0
  106. angr/analyses/decompiler/label_collector.py +32 -0
  107. angr/analyses/decompiler/node_replacer.py +42 -0
  108. angr/analyses/decompiler/notes/__init__.py +9 -0
  109. angr/analyses/decompiler/notes/decompilation_note.py +48 -0
  110. angr/analyses/decompiler/notes/deobfuscated_strings.py +56 -0
  111. angr/analyses/decompiler/optimization_passes/__init__.py +164 -0
  112. angr/analyses/decompiler/optimization_passes/base_ptr_save_simplifier.py +157 -0
  113. angr/analyses/decompiler/optimization_passes/call_stmt_rewriter.py +46 -0
  114. angr/analyses/decompiler/optimization_passes/code_motion.py +362 -0
  115. angr/analyses/decompiler/optimization_passes/condition_constprop.py +211 -0
  116. angr/analyses/decompiler/optimization_passes/const_derefs.py +127 -0
  117. angr/analyses/decompiler/optimization_passes/const_prop_reverter.py +365 -0
  118. angr/analyses/decompiler/optimization_passes/cross_jump_reverter.py +106 -0
  119. angr/analyses/decompiler/optimization_passes/deadblock_remover.py +82 -0
  120. angr/analyses/decompiler/optimization_passes/determine_load_sizes.py +64 -0
  121. angr/analyses/decompiler/optimization_passes/div_simplifier.py +425 -0
  122. angr/analyses/decompiler/optimization_passes/duplication_reverter/__init__.py +5 -0
  123. angr/analyses/decompiler/optimization_passes/duplication_reverter/ail_merge_graph.py +503 -0
  124. angr/analyses/decompiler/optimization_passes/duplication_reverter/duplication_reverter.py +1221 -0
  125. angr/analyses/decompiler/optimization_passes/duplication_reverter/errors.py +16 -0
  126. angr/analyses/decompiler/optimization_passes/duplication_reverter/similarity.py +126 -0
  127. angr/analyses/decompiler/optimization_passes/duplication_reverter/utils.py +167 -0
  128. angr/analyses/decompiler/optimization_passes/eager_std_string_concatenation.py +236 -0
  129. angr/analyses/decompiler/optimization_passes/eager_std_string_eval.py +186 -0
  130. angr/analyses/decompiler/optimization_passes/engine_base.py +502 -0
  131. angr/analyses/decompiler/optimization_passes/expr_op_swapper.py +138 -0
  132. angr/analyses/decompiler/optimization_passes/flip_boolean_cmp.py +113 -0
  133. angr/analyses/decompiler/optimization_passes/inlined_string_transformation_simplifier.py +618 -0
  134. angr/analyses/decompiler/optimization_passes/inlined_strlen_simplifier.py +274 -0
  135. angr/analyses/decompiler/optimization_passes/ite_expr_converter.py +224 -0
  136. angr/analyses/decompiler/optimization_passes/ite_region_converter.py +337 -0
  137. angr/analyses/decompiler/optimization_passes/lowered_switch_simplifier.py +939 -0
  138. angr/analyses/decompiler/optimization_passes/mod_simplifier.py +99 -0
  139. angr/analyses/decompiler/optimization_passes/optimization_pass.py +710 -0
  140. angr/analyses/decompiler/optimization_passes/peephole_simplifier.py +75 -0
  141. angr/analyses/decompiler/optimization_passes/register_save_area_simplifier.py +263 -0
  142. angr/analyses/decompiler/optimization_passes/register_save_area_simplifier_adv.py +198 -0
  143. angr/analyses/decompiler/optimization_passes/ret_addr_save_simplifier.py +171 -0
  144. angr/analyses/decompiler/optimization_passes/ret_deduplicator.py +222 -0
  145. angr/analyses/decompiler/optimization_passes/return_duplicator_base.py +632 -0
  146. angr/analyses/decompiler/optimization_passes/return_duplicator_high.py +61 -0
  147. angr/analyses/decompiler/optimization_passes/return_duplicator_low.py +166 -0
  148. angr/analyses/decompiler/optimization_passes/stack_canary_simplifier.py +333 -0
  149. angr/analyses/decompiler/optimization_passes/static_vvar_rewriter.py +336 -0
  150. angr/analyses/decompiler/optimization_passes/switch_default_case_duplicator.py +166 -0
  151. angr/analyses/decompiler/optimization_passes/switch_reused_entry_rewriter.py +102 -0
  152. angr/analyses/decompiler/optimization_passes/tag_slicer.py +41 -0
  153. angr/analyses/decompiler/optimization_passes/win_stack_canary_simplifier.py +477 -0
  154. angr/analyses/decompiler/optimization_passes/x86_gcc_getpc_simplifier.py +88 -0
  155. angr/analyses/decompiler/peephole_optimizations/__init__.py +136 -0
  156. angr/analyses/decompiler/peephole_optimizations/a_div_const_add_a_mul_n_div_const.py +42 -0
  157. angr/analyses/decompiler/peephole_optimizations/a_mul_const_div_shr_const.py +38 -0
  158. angr/analyses/decompiler/peephole_optimizations/a_mul_const_sub_a.py +34 -0
  159. angr/analyses/decompiler/peephole_optimizations/a_shl_const_sub_a.py +34 -0
  160. angr/analyses/decompiler/peephole_optimizations/a_sub_a_div.py +25 -0
  161. angr/analyses/decompiler/peephole_optimizations/a_sub_a_shr_const_shr_const.py +37 -0
  162. angr/analyses/decompiler/peephole_optimizations/a_sub_a_sub_n.py +23 -0
  163. angr/analyses/decompiler/peephole_optimizations/arm_cmpf.py +236 -0
  164. angr/analyses/decompiler/peephole_optimizations/base.py +157 -0
  165. angr/analyses/decompiler/peephole_optimizations/basepointeroffset_add_n.py +34 -0
  166. angr/analyses/decompiler/peephole_optimizations/basepointeroffset_and_mask.py +36 -0
  167. angr/analyses/decompiler/peephole_optimizations/bitwise_or_to_logical_or.py +34 -0
  168. angr/analyses/decompiler/peephole_optimizations/bool_expr_xor_1.py +27 -0
  169. angr/analyses/decompiler/peephole_optimizations/bswap.py +142 -0
  170. angr/analyses/decompiler/peephole_optimizations/cas_intrinsics.py +182 -0
  171. angr/analyses/decompiler/peephole_optimizations/cmpord_rewriter.py +71 -0
  172. angr/analyses/decompiler/peephole_optimizations/coalesce_adjacent_shrs.py +39 -0
  173. angr/analyses/decompiler/peephole_optimizations/coalesce_same_cascading_ifs.py +28 -0
  174. angr/analyses/decompiler/peephole_optimizations/constant_derefs.py +44 -0
  175. angr/analyses/decompiler/peephole_optimizations/conv_a_sub0_shr_and.py +69 -0
  176. angr/analyses/decompiler/peephole_optimizations/conv_shl_shr.py +52 -0
  177. angr/analyses/decompiler/peephole_optimizations/eager_eval.py +436 -0
  178. angr/analyses/decompiler/peephole_optimizations/extended_byte_and_mask.py +56 -0
  179. angr/analyses/decompiler/peephole_optimizations/inlined_memcpy.py +78 -0
  180. angr/analyses/decompiler/peephole_optimizations/inlined_memset.py +262 -0
  181. angr/analyses/decompiler/peephole_optimizations/inlined_strcpy.py +217 -0
  182. angr/analyses/decompiler/peephole_optimizations/inlined_strcpy_consolidation.py +106 -0
  183. angr/analyses/decompiler/peephole_optimizations/inlined_wcscpy.py +256 -0
  184. angr/analyses/decompiler/peephole_optimizations/inlined_wcscpy_consolidation.py +296 -0
  185. angr/analyses/decompiler/peephole_optimizations/invert_negated_logical_conjuction_disjunction.py +50 -0
  186. angr/analyses/decompiler/peephole_optimizations/modulo_simplifier.py +89 -0
  187. angr/analyses/decompiler/peephole_optimizations/one_sub_bool.py +33 -0
  188. angr/analyses/decompiler/peephole_optimizations/optimized_div_simplifier.py +356 -0
  189. angr/analyses/decompiler/peephole_optimizations/remove_cascading_conversions.py +45 -0
  190. angr/analyses/decompiler/peephole_optimizations/remove_cxx_destructor_calls.py +32 -0
  191. angr/analyses/decompiler/peephole_optimizations/remove_empty_if_body.py +46 -0
  192. angr/analyses/decompiler/peephole_optimizations/remove_noop_conversions.py +47 -0
  193. angr/analyses/decompiler/peephole_optimizations/remove_redundant_bitmasks.py +125 -0
  194. angr/analyses/decompiler/peephole_optimizations/remove_redundant_conversions.py +273 -0
  195. angr/analyses/decompiler/peephole_optimizations/remove_redundant_derefs.py +21 -0
  196. angr/analyses/decompiler/peephole_optimizations/remove_redundant_ite_branch.py +30 -0
  197. angr/analyses/decompiler/peephole_optimizations/remove_redundant_ite_comparisons.py +54 -0
  198. angr/analyses/decompiler/peephole_optimizations/remove_redundant_nots.py +36 -0
  199. angr/analyses/decompiler/peephole_optimizations/remove_redundant_reinterprets.py +44 -0
  200. angr/analyses/decompiler/peephole_optimizations/remove_redundant_shifts.py +95 -0
  201. angr/analyses/decompiler/peephole_optimizations/remove_redundant_shifts_around_comparators.py +115 -0
  202. angr/analyses/decompiler/peephole_optimizations/rewrite_bit_extractions.py +85 -0
  203. angr/analyses/decompiler/peephole_optimizations/rewrite_conv_mul.py +40 -0
  204. angr/analyses/decompiler/peephole_optimizations/rewrite_cxx_operator_calls.py +90 -0
  205. angr/analyses/decompiler/peephole_optimizations/rewrite_mips_gp_loads.py +49 -0
  206. angr/analyses/decompiler/peephole_optimizations/rol_ror.py +130 -0
  207. angr/analyses/decompiler/peephole_optimizations/sar_to_signed_div.py +143 -0
  208. angr/analyses/decompiler/peephole_optimizations/shl_to_mul.py +25 -0
  209. angr/analyses/decompiler/peephole_optimizations/simplify_pc_relative_loads.py +51 -0
  210. angr/analyses/decompiler/peephole_optimizations/single_bit_cond_to_boolexpr.py +28 -0
  211. angr/analyses/decompiler/peephole_optimizations/single_bit_xor.py +29 -0
  212. angr/analyses/decompiler/peephole_optimizations/tidy_stack_addr.py +131 -0
  213. angr/analyses/decompiler/peephole_optimizations/utils.py +18 -0
  214. angr/analyses/decompiler/presets/__init__.py +22 -0
  215. angr/analyses/decompiler/presets/basic.py +36 -0
  216. angr/analyses/decompiler/presets/fast.py +66 -0
  217. angr/analyses/decompiler/presets/full.py +76 -0
  218. angr/analyses/decompiler/presets/malware.py +70 -0
  219. angr/analyses/decompiler/presets/preset.py +37 -0
  220. angr/analyses/decompiler/redundant_label_remover.py +141 -0
  221. angr/analyses/decompiler/region_identifier.py +1319 -0
  222. angr/analyses/decompiler/region_simplifiers/__init__.py +5 -0
  223. angr/analyses/decompiler/region_simplifiers/cascading_cond_transformer.py +95 -0
  224. angr/analyses/decompiler/region_simplifiers/cascading_ifs.py +82 -0
  225. angr/analyses/decompiler/region_simplifiers/expr_folding.py +838 -0
  226. angr/analyses/decompiler/region_simplifiers/goto.py +178 -0
  227. angr/analyses/decompiler/region_simplifiers/if_.py +135 -0
  228. angr/analyses/decompiler/region_simplifiers/ifelse.py +91 -0
  229. angr/analyses/decompiler/region_simplifiers/loop.py +143 -0
  230. angr/analyses/decompiler/region_simplifiers/node_address_finder.py +24 -0
  231. angr/analyses/decompiler/region_simplifiers/region_simplifier.py +270 -0
  232. angr/analyses/decompiler/region_simplifiers/switch_cluster_simplifier.py +654 -0
  233. angr/analyses/decompiler/region_simplifiers/switch_expr_simplifier.py +87 -0
  234. angr/analyses/decompiler/region_walker.py +24 -0
  235. angr/analyses/decompiler/return_maker.py +72 -0
  236. angr/analyses/decompiler/semantic_naming/__init__.py +37 -0
  237. angr/analyses/decompiler/semantic_naming/array_index_naming.py +196 -0
  238. angr/analyses/decompiler/semantic_naming/boolean_naming.py +264 -0
  239. angr/analyses/decompiler/semantic_naming/call_result_naming.py +220 -0
  240. angr/analyses/decompiler/semantic_naming/naming_base.py +166 -0
  241. angr/analyses/decompiler/semantic_naming/orchestrator.py +107 -0
  242. angr/analyses/decompiler/semantic_naming/pointer_naming.py +334 -0
  243. angr/analyses/decompiler/semantic_naming/region_loop_counter_naming.py +246 -0
  244. angr/analyses/decompiler/semantic_naming/size_naming.py +137 -0
  245. angr/analyses/decompiler/seq_to_blocks.py +20 -0
  246. angr/analyses/decompiler/sequence_walker.py +261 -0
  247. angr/analyses/decompiler/ssailification/__init__.py +4 -0
  248. angr/analyses/decompiler/ssailification/rewriting.py +451 -0
  249. angr/analyses/decompiler/ssailification/rewriting_engine.py +1091 -0
  250. angr/analyses/decompiler/ssailification/rewriting_state.py +61 -0
  251. angr/analyses/decompiler/ssailification/ssailification.py +283 -0
  252. angr/analyses/decompiler/ssailification/traversal.py +127 -0
  253. angr/analyses/decompiler/ssailification/traversal_engine.py +323 -0
  254. angr/analyses/decompiler/ssailification/traversal_state.py +48 -0
  255. angr/analyses/decompiler/stack_item.py +36 -0
  256. angr/analyses/decompiler/structured_codegen/__init__.py +25 -0
  257. angr/analyses/decompiler/structured_codegen/base.py +193 -0
  258. angr/analyses/decompiler/structured_codegen/c.py +4257 -0
  259. angr/analyses/decompiler/structured_codegen/dummy.py +15 -0
  260. angr/analyses/decompiler/structured_codegen/dwarf_import.py +190 -0
  261. angr/analyses/decompiler/structuring/__init__.py +30 -0
  262. angr/analyses/decompiler/structuring/dream.py +1217 -0
  263. angr/analyses/decompiler/structuring/phoenix.py +3636 -0
  264. angr/analyses/decompiler/structuring/recursive_structurer.py +187 -0
  265. angr/analyses/decompiler/structuring/sailr.py +120 -0
  266. angr/analyses/decompiler/structuring/structurer_base.py +1140 -0
  267. angr/analyses/decompiler/structuring/structurer_nodes.py +442 -0
  268. angr/analyses/decompiler/utils.py +1224 -0
  269. angr/analyses/deobfuscator/__init__.py +23 -0
  270. angr/analyses/deobfuscator/api_obf_finder.py +333 -0
  271. angr/analyses/deobfuscator/api_obf_peephole_optimizer.py +80 -0
  272. angr/analyses/deobfuscator/api_obf_type2_finder.py +166 -0
  273. angr/analyses/deobfuscator/data_transformation_embedder.py +633 -0
  274. angr/analyses/deobfuscator/hash_lookup_api_deobfuscator.py +156 -0
  275. angr/analyses/deobfuscator/irsb_reg_collector.py +54 -0
  276. angr/analyses/deobfuscator/scope_ops_analyzer.py +68 -0
  277. angr/analyses/deobfuscator/string_obf_finder.py +983 -0
  278. angr/analyses/deobfuscator/string_obf_opt_passes.py +136 -0
  279. angr/analyses/deobfuscator/string_obf_peephole_optimizer.py +47 -0
  280. angr/analyses/disassembly.py +1351 -0
  281. angr/analyses/disassembly_utils.py +101 -0
  282. angr/analyses/dominance_frontier.py +57 -0
  283. angr/analyses/fcp/__init__.py +4 -0
  284. angr/analyses/fcp/fcp.py +427 -0
  285. angr/analyses/find_objects_static.py +205 -0
  286. angr/analyses/flirt/__init__.py +47 -0
  287. angr/analyses/flirt/consts.py +160 -0
  288. angr/analyses/flirt/flirt.py +249 -0
  289. angr/analyses/flirt/flirt_function.py +20 -0
  290. angr/analyses/flirt/flirt_matcher.py +352 -0
  291. angr/analyses/flirt/flirt_module.py +32 -0
  292. angr/analyses/flirt/flirt_node.py +23 -0
  293. angr/analyses/flirt/flirt_sig.py +359 -0
  294. angr/analyses/flirt/flirt_utils.py +31 -0
  295. angr/analyses/forward_analysis/__init__.py +12 -0
  296. angr/analyses/forward_analysis/forward_analysis.py +619 -0
  297. angr/analyses/forward_analysis/job_info.py +64 -0
  298. angr/analyses/forward_analysis/visitors/__init__.py +14 -0
  299. angr/analyses/forward_analysis/visitors/call_graph.py +29 -0
  300. angr/analyses/forward_analysis/visitors/function_graph.py +86 -0
  301. angr/analyses/forward_analysis/visitors/graph.py +242 -0
  302. angr/analyses/forward_analysis/visitors/loop.py +29 -0
  303. angr/analyses/forward_analysis/visitors/single_node_graph.py +38 -0
  304. angr/analyses/identifier/__init__.py +5 -0
  305. angr/analyses/identifier/custom_callable.py +137 -0
  306. angr/analyses/identifier/errors.py +10 -0
  307. angr/analyses/identifier/func.py +60 -0
  308. angr/analyses/identifier/functions/__init__.py +37 -0
  309. angr/analyses/identifier/functions/atoi.py +73 -0
  310. angr/analyses/identifier/functions/based_atoi.py +125 -0
  311. angr/analyses/identifier/functions/fdprintf.py +123 -0
  312. angr/analyses/identifier/functions/free.py +64 -0
  313. angr/analyses/identifier/functions/int2str.py +287 -0
  314. angr/analyses/identifier/functions/malloc.py +111 -0
  315. angr/analyses/identifier/functions/memcmp.py +67 -0
  316. angr/analyses/identifier/functions/memcpy.py +89 -0
  317. angr/analyses/identifier/functions/memset.py +43 -0
  318. angr/analyses/identifier/functions/printf.py +123 -0
  319. angr/analyses/identifier/functions/recv_until.py +312 -0
  320. angr/analyses/identifier/functions/skip_calloc.py +73 -0
  321. angr/analyses/identifier/functions/skip_realloc.py +97 -0
  322. angr/analyses/identifier/functions/skip_recv_n.py +105 -0
  323. angr/analyses/identifier/functions/snprintf.py +112 -0
  324. angr/analyses/identifier/functions/sprintf.py +116 -0
  325. angr/analyses/identifier/functions/strcasecmp.py +33 -0
  326. angr/analyses/identifier/functions/strcmp.py +113 -0
  327. angr/analyses/identifier/functions/strcpy.py +43 -0
  328. angr/analyses/identifier/functions/strlen.py +27 -0
  329. angr/analyses/identifier/functions/strncmp.py +104 -0
  330. angr/analyses/identifier/functions/strncpy.py +65 -0
  331. angr/analyses/identifier/functions/strtol.py +89 -0
  332. angr/analyses/identifier/identify.py +825 -0
  333. angr/analyses/identifier/runner.py +360 -0
  334. angr/analyses/init_finder.py +289 -0
  335. angr/analyses/loop_analysis/__init__.py +4 -0
  336. angr/analyses/loop_analysis/loop_analysis.py +464 -0
  337. angr/analyses/loop_analysis.py +349 -0
  338. angr/analyses/loop_unroller/__init__.py +4 -0
  339. angr/analyses/loop_unroller/loop_unroller.py +222 -0
  340. angr/analyses/loopfinder.py +171 -0
  341. angr/analyses/outliner/__init__.py +7 -0
  342. angr/analyses/outliner/outliner.py +402 -0
  343. angr/analyses/patchfinder.py +137 -0
  344. angr/analyses/pathfinder.py +282 -0
  345. angr/analyses/propagator/__init__.py +5 -0
  346. angr/analyses/propagator/engine_base.py +62 -0
  347. angr/analyses/propagator/engine_vex.py +297 -0
  348. angr/analyses/propagator/propagator.py +361 -0
  349. angr/analyses/propagator/top_checker_mixin.py +218 -0
  350. angr/analyses/propagator/values.py +117 -0
  351. angr/analyses/propagator/vex_vars.py +68 -0
  352. angr/analyses/proximity_graph.py +444 -0
  353. angr/analyses/purity/__init__.py +15 -0
  354. angr/analyses/purity/analysis.py +78 -0
  355. angr/analyses/purity/engine.py +593 -0
  356. angr/analyses/reaching_definitions/__init__.py +67 -0
  357. angr/analyses/reaching_definitions/call_trace.py +73 -0
  358. angr/analyses/reaching_definitions/dep_graph.py +433 -0
  359. angr/analyses/reaching_definitions/engine_ail.py +1128 -0
  360. angr/analyses/reaching_definitions/engine_vex.py +1128 -0
  361. angr/analyses/reaching_definitions/external_codeloc.py +0 -0
  362. angr/analyses/reaching_definitions/function_handler.py +639 -0
  363. angr/analyses/reaching_definitions/function_handler_library/__init__.py +12 -0
  364. angr/analyses/reaching_definitions/function_handler_library/stdio.py +269 -0
  365. angr/analyses/reaching_definitions/function_handler_library/stdlib.py +195 -0
  366. angr/analyses/reaching_definitions/function_handler_library/string.py +158 -0
  367. angr/analyses/reaching_definitions/function_handler_library/unistd.py +51 -0
  368. angr/analyses/reaching_definitions/heap_allocator.py +70 -0
  369. angr/analyses/reaching_definitions/rd_initializer.py +237 -0
  370. angr/analyses/reaching_definitions/rd_state.py +579 -0
  371. angr/analyses/reaching_definitions/reaching_definitions.py +581 -0
  372. angr/analyses/reaching_definitions/subject.py +65 -0
  373. angr/analyses/reassembler.py +2900 -0
  374. angr/analyses/s_liveness.py +254 -0
  375. angr/analyses/s_propagator.py +575 -0
  376. angr/analyses/s_reaching_definitions/__init__.py +12 -0
  377. angr/analyses/s_reaching_definitions/s_rda_model.py +145 -0
  378. angr/analyses/s_reaching_definitions/s_rda_view.py +344 -0
  379. angr/analyses/s_reaching_definitions/s_reaching_definitions.py +230 -0
  380. angr/analyses/smc.py +160 -0
  381. angr/analyses/soot_class_hierarchy.py +273 -0
  382. angr/analyses/stack_pointer_tracker.py +954 -0
  383. angr/analyses/static_hooker.py +53 -0
  384. angr/analyses/typehoon/__init__.py +5 -0
  385. angr/analyses/typehoon/dfa.py +118 -0
  386. angr/analyses/typehoon/lifter.py +133 -0
  387. angr/analyses/typehoon/simple_solver.py +2009 -0
  388. angr/analyses/typehoon/translator.py +283 -0
  389. angr/analyses/typehoon/typeconsts.py +439 -0
  390. angr/analyses/typehoon/typehoon.py +338 -0
  391. angr/analyses/typehoon/typevars.py +633 -0
  392. angr/analyses/typehoon/variance.py +11 -0
  393. angr/analyses/unpacker/__init__.py +6 -0
  394. angr/analyses/unpacker/obfuscation_detector.py +103 -0
  395. angr/analyses/unpacker/packing_detector.py +138 -0
  396. angr/analyses/variable_recovery/__init__.py +9 -0
  397. angr/analyses/variable_recovery/annotations.py +58 -0
  398. angr/analyses/variable_recovery/engine_ail.py +978 -0
  399. angr/analyses/variable_recovery/engine_base.py +1256 -0
  400. angr/analyses/variable_recovery/engine_vex.py +594 -0
  401. angr/analyses/variable_recovery/irsb_scanner.py +143 -0
  402. angr/analyses/variable_recovery/variable_recovery.py +574 -0
  403. angr/analyses/variable_recovery/variable_recovery_base.py +489 -0
  404. angr/analyses/variable_recovery/variable_recovery_fast.py +669 -0
  405. angr/analyses/veritesting.py +626 -0
  406. angr/analyses/vfg.py +1898 -0
  407. angr/analyses/vsa_ddg.py +420 -0
  408. angr/analyses/vtable.py +92 -0
  409. angr/analyses/xrefs.py +286 -0
  410. angr/angrdb/__init__.py +14 -0
  411. angr/angrdb/db.py +215 -0
  412. angr/angrdb/models.py +184 -0
  413. angr/angrdb/serializers/__init__.py +10 -0
  414. angr/angrdb/serializers/cfg_model.py +41 -0
  415. angr/angrdb/serializers/comments.py +60 -0
  416. angr/angrdb/serializers/funcs.py +61 -0
  417. angr/angrdb/serializers/kb.py +111 -0
  418. angr/angrdb/serializers/labels.py +59 -0
  419. angr/angrdb/serializers/loader.py +165 -0
  420. angr/angrdb/serializers/structured_code.py +167 -0
  421. angr/angrdb/serializers/variables.py +58 -0
  422. angr/angrdb/serializers/xrefs.py +48 -0
  423. angr/annocfg.py +317 -0
  424. angr/blade.py +431 -0
  425. angr/block.py +509 -0
  426. angr/callable.py +176 -0
  427. angr/calling_conventions.py +2613 -0
  428. angr/code_location.py +249 -0
  429. angr/codenode.py +145 -0
  430. angr/concretization_strategies/__init__.py +32 -0
  431. angr/concretization_strategies/any.py +17 -0
  432. angr/concretization_strategies/any_named.py +35 -0
  433. angr/concretization_strategies/base.py +81 -0
  434. angr/concretization_strategies/controlled_data.py +58 -0
  435. angr/concretization_strategies/eval.py +19 -0
  436. angr/concretization_strategies/logging.py +35 -0
  437. angr/concretization_strategies/max.py +25 -0
  438. angr/concretization_strategies/nonzero.py +16 -0
  439. angr/concretization_strategies/nonzero_range.py +22 -0
  440. angr/concretization_strategies/norepeats.py +37 -0
  441. angr/concretization_strategies/norepeats_range.py +37 -0
  442. angr/concretization_strategies/range.py +19 -0
  443. angr/concretization_strategies/signed_add.py +31 -0
  444. angr/concretization_strategies/single.py +15 -0
  445. angr/concretization_strategies/solutions.py +20 -0
  446. angr/concretization_strategies/unlimited_range.py +17 -0
  447. angr/distributed/__init__.py +9 -0
  448. angr/distributed/server.py +197 -0
  449. angr/distributed/worker.py +185 -0
  450. angr/emulator.py +144 -0
  451. angr/engines/__init__.py +69 -0
  452. angr/engines/ail/__init__.py +16 -0
  453. angr/engines/ail/callstack.py +58 -0
  454. angr/engines/ail/engine_light.py +903 -0
  455. angr/engines/ail/engine_successors.py +24 -0
  456. angr/engines/ail/setup.py +57 -0
  457. angr/engines/concrete.py +66 -0
  458. angr/engines/engine.py +29 -0
  459. angr/engines/failure.py +27 -0
  460. angr/engines/hook.py +93 -0
  461. angr/engines/icicle.py +294 -0
  462. angr/engines/light/__init__.py +23 -0
  463. angr/engines/light/data.py +681 -0
  464. angr/engines/light/engine.py +1297 -0
  465. angr/engines/pcode/__init__.py +9 -0
  466. angr/engines/pcode/behavior.py +998 -0
  467. angr/engines/pcode/cc.py +148 -0
  468. angr/engines/pcode/emulate.py +440 -0
  469. angr/engines/pcode/engine.py +242 -0
  470. angr/engines/pcode/lifter.py +1428 -0
  471. angr/engines/procedure.py +70 -0
  472. angr/engines/soot/__init__.py +5 -0
  473. angr/engines/soot/engine.py +410 -0
  474. angr/engines/soot/exceptions.py +17 -0
  475. angr/engines/soot/expressions/__init__.py +87 -0
  476. angr/engines/soot/expressions/arrayref.py +22 -0
  477. angr/engines/soot/expressions/base.py +21 -0
  478. angr/engines/soot/expressions/binop.py +28 -0
  479. angr/engines/soot/expressions/cast.py +22 -0
  480. angr/engines/soot/expressions/condition.py +35 -0
  481. angr/engines/soot/expressions/constants.py +47 -0
  482. angr/engines/soot/expressions/instanceOf.py +15 -0
  483. angr/engines/soot/expressions/instancefieldref.py +8 -0
  484. angr/engines/soot/expressions/invoke.py +114 -0
  485. angr/engines/soot/expressions/length.py +8 -0
  486. angr/engines/soot/expressions/local.py +8 -0
  487. angr/engines/soot/expressions/new.py +16 -0
  488. angr/engines/soot/expressions/newArray.py +54 -0
  489. angr/engines/soot/expressions/newMultiArray.py +86 -0
  490. angr/engines/soot/expressions/paramref.py +8 -0
  491. angr/engines/soot/expressions/phi.py +30 -0
  492. angr/engines/soot/expressions/staticfieldref.py +8 -0
  493. angr/engines/soot/expressions/thisref.py +7 -0
  494. angr/engines/soot/expressions/unsupported.py +7 -0
  495. angr/engines/soot/field_dispatcher.py +46 -0
  496. angr/engines/soot/method_dispatcher.py +46 -0
  497. angr/engines/soot/statements/__init__.py +44 -0
  498. angr/engines/soot/statements/assign.py +30 -0
  499. angr/engines/soot/statements/base.py +79 -0
  500. angr/engines/soot/statements/goto.py +14 -0
  501. angr/engines/soot/statements/identity.py +15 -0
  502. angr/engines/soot/statements/if_.py +19 -0
  503. angr/engines/soot/statements/invoke.py +12 -0
  504. angr/engines/soot/statements/return_.py +20 -0
  505. angr/engines/soot/statements/switch.py +41 -0
  506. angr/engines/soot/statements/throw.py +15 -0
  507. angr/engines/soot/values/__init__.py +38 -0
  508. angr/engines/soot/values/arrayref.py +122 -0
  509. angr/engines/soot/values/base.py +7 -0
  510. angr/engines/soot/values/constants.py +18 -0
  511. angr/engines/soot/values/instancefieldref.py +44 -0
  512. angr/engines/soot/values/local.py +18 -0
  513. angr/engines/soot/values/paramref.py +18 -0
  514. angr/engines/soot/values/staticfieldref.py +38 -0
  515. angr/engines/soot/values/strref.py +38 -0
  516. angr/engines/soot/values/thisref.py +149 -0
  517. angr/engines/successors.py +608 -0
  518. angr/engines/syscall.py +51 -0
  519. angr/engines/unicorn.py +490 -0
  520. angr/engines/vex/__init__.py +20 -0
  521. angr/engines/vex/claripy/__init__.py +5 -0
  522. angr/engines/vex/claripy/ccall.py +2097 -0
  523. angr/engines/vex/claripy/datalayer.py +141 -0
  524. angr/engines/vex/claripy/irop.py +1276 -0
  525. angr/engines/vex/heavy/__init__.py +16 -0
  526. angr/engines/vex/heavy/actions.py +231 -0
  527. angr/engines/vex/heavy/concretizers.py +403 -0
  528. angr/engines/vex/heavy/dirty.py +466 -0
  529. angr/engines/vex/heavy/heavy.py +370 -0
  530. angr/engines/vex/heavy/inspect.py +52 -0
  531. angr/engines/vex/heavy/resilience.py +85 -0
  532. angr/engines/vex/heavy/super_fastpath.py +34 -0
  533. angr/engines/vex/lifter.py +420 -0
  534. angr/engines/vex/light/__init__.py +11 -0
  535. angr/engines/vex/light/light.py +551 -0
  536. angr/engines/vex/light/resilience.py +74 -0
  537. angr/engines/vex/light/slicing.py +52 -0
  538. angr/errors.py +611 -0
  539. angr/exploration_techniques/__init__.py +53 -0
  540. angr/exploration_techniques/base.py +126 -0
  541. angr/exploration_techniques/bucketizer.py +94 -0
  542. angr/exploration_techniques/common.py +56 -0
  543. angr/exploration_techniques/dfs.py +37 -0
  544. angr/exploration_techniques/director.py +520 -0
  545. angr/exploration_techniques/driller_core.py +100 -0
  546. angr/exploration_techniques/explorer.py +152 -0
  547. angr/exploration_techniques/lengthlimiter.py +22 -0
  548. angr/exploration_techniques/local_loop_seer.py +65 -0
  549. angr/exploration_techniques/loop_seer.py +236 -0
  550. angr/exploration_techniques/manual_mergepoint.py +82 -0
  551. angr/exploration_techniques/memory_watcher.py +43 -0
  552. angr/exploration_techniques/oppologist.py +92 -0
  553. angr/exploration_techniques/slicecutor.py +118 -0
  554. angr/exploration_techniques/spiller.py +280 -0
  555. angr/exploration_techniques/spiller_db.py +27 -0
  556. angr/exploration_techniques/stochastic.py +56 -0
  557. angr/exploration_techniques/stub_stasher.py +19 -0
  558. angr/exploration_techniques/suggestions.py +159 -0
  559. angr/exploration_techniques/tech_builder.py +49 -0
  560. angr/exploration_techniques/threading.py +69 -0
  561. angr/exploration_techniques/timeout.py +34 -0
  562. angr/exploration_techniques/tracer.py +1098 -0
  563. angr/exploration_techniques/unique.py +106 -0
  564. angr/exploration_techniques/veritesting.py +37 -0
  565. angr/factory.py +413 -0
  566. angr/flirt/__init__.py +124 -0
  567. angr/flirt/build_sig.py +305 -0
  568. angr/graph_utils.py +0 -0
  569. angr/keyed_region.py +525 -0
  570. angr/knowledge_base.py +146 -0
  571. angr/knowledge_plugins/__init__.py +43 -0
  572. angr/knowledge_plugins/callsite_prototypes.py +95 -0
  573. angr/knowledge_plugins/cfg/__init__.py +18 -0
  574. angr/knowledge_plugins/cfg/cfg_manager.py +95 -0
  575. angr/knowledge_plugins/cfg/cfg_model.py +1043 -0
  576. angr/knowledge_plugins/cfg/cfg_node.py +536 -0
  577. angr/knowledge_plugins/cfg/indirect_jump.py +131 -0
  578. angr/knowledge_plugins/cfg/memory_data.py +156 -0
  579. angr/knowledge_plugins/comments.py +16 -0
  580. angr/knowledge_plugins/custom_strings.py +38 -0
  581. angr/knowledge_plugins/data.py +22 -0
  582. angr/knowledge_plugins/debug_variables.py +216 -0
  583. angr/knowledge_plugins/functions/__init__.py +9 -0
  584. angr/knowledge_plugins/functions/function.py +1830 -0
  585. angr/knowledge_plugins/functions/function_manager.py +621 -0
  586. angr/knowledge_plugins/functions/function_parser.py +360 -0
  587. angr/knowledge_plugins/functions/soot_function.py +128 -0
  588. angr/knowledge_plugins/indirect_jumps.py +35 -0
  589. angr/knowledge_plugins/key_definitions/__init__.py +17 -0
  590. angr/knowledge_plugins/key_definitions/atoms.py +374 -0
  591. angr/knowledge_plugins/key_definitions/constants.py +29 -0
  592. angr/knowledge_plugins/key_definitions/definition.py +216 -0
  593. angr/knowledge_plugins/key_definitions/environment.py +96 -0
  594. angr/knowledge_plugins/key_definitions/heap_address.py +33 -0
  595. angr/knowledge_plugins/key_definitions/key_definition_manager.py +82 -0
  596. angr/knowledge_plugins/key_definitions/live_definitions.py +1020 -0
  597. angr/knowledge_plugins/key_definitions/liveness.py +165 -0
  598. angr/knowledge_plugins/key_definitions/rd_model.py +171 -0
  599. angr/knowledge_plugins/key_definitions/tag.py +78 -0
  600. angr/knowledge_plugins/key_definitions/undefined.py +70 -0
  601. angr/knowledge_plugins/key_definitions/unknown_size.py +86 -0
  602. angr/knowledge_plugins/key_definitions/uses.py +178 -0
  603. angr/knowledge_plugins/labels.py +110 -0
  604. angr/knowledge_plugins/obfuscations.py +40 -0
  605. angr/knowledge_plugins/patches.py +126 -0
  606. angr/knowledge_plugins/plugin.py +24 -0
  607. angr/knowledge_plugins/propagations/__init__.py +10 -0
  608. angr/knowledge_plugins/propagations/prop_value.py +191 -0
  609. angr/knowledge_plugins/propagations/propagation_manager.py +60 -0
  610. angr/knowledge_plugins/propagations/propagation_model.py +80 -0
  611. angr/knowledge_plugins/propagations/states.py +552 -0
  612. angr/knowledge_plugins/structured_code.py +63 -0
  613. angr/knowledge_plugins/types.py +95 -0
  614. angr/knowledge_plugins/variables/__init__.py +8 -0
  615. angr/knowledge_plugins/variables/variable_access.py +113 -0
  616. angr/knowledge_plugins/variables/variable_manager.py +1375 -0
  617. angr/knowledge_plugins/xrefs/__init__.py +12 -0
  618. angr/knowledge_plugins/xrefs/xref.py +150 -0
  619. angr/knowledge_plugins/xrefs/xref_manager.py +127 -0
  620. angr/knowledge_plugins/xrefs/xref_types.py +16 -0
  621. angr/misc/__init__.py +19 -0
  622. angr/misc/ansi.py +47 -0
  623. angr/misc/autoimport.py +90 -0
  624. angr/misc/bug_report.py +126 -0
  625. angr/misc/hookset.py +106 -0
  626. angr/misc/loggers.py +130 -0
  627. angr/misc/picklable_lock.py +46 -0
  628. angr/misc/plugins.py +289 -0
  629. angr/misc/telemetry.py +54 -0
  630. angr/misc/testing.py +24 -0
  631. angr/misc/ux.py +31 -0
  632. angr/procedures/__init__.py +12 -0
  633. angr/procedures/advapi32/__init__.py +0 -0
  634. angr/procedures/cgc/__init__.py +3 -0
  635. angr/procedures/cgc/_terminate.py +11 -0
  636. angr/procedures/cgc/allocate.py +75 -0
  637. angr/procedures/cgc/deallocate.py +67 -0
  638. angr/procedures/cgc/fdwait.py +65 -0
  639. angr/procedures/cgc/random.py +67 -0
  640. angr/procedures/cgc/receive.py +93 -0
  641. angr/procedures/cgc/transmit.py +65 -0
  642. angr/procedures/definitions/__init__.py +1043 -0
  643. angr/procedures/definitions/cgc.py +23 -0
  644. angr/procedures/definitions/common/glibc.json +3516 -0
  645. angr/procedures/definitions/gnulib.py +41 -0
  646. angr/procedures/definitions/libstdcpp.py +25 -0
  647. angr/procedures/definitions/linux_kernel.py +8382 -0
  648. angr/procedures/definitions/linux_loader.py +7 -0
  649. angr/procedures/definitions/macho_libsystem.py +18 -0
  650. angr/procedures/definitions/msvcr.py +25 -0
  651. angr/procedures/definitions/parse_glibc.py +77 -0
  652. angr/procedures/definitions/parse_syscalls_from_local_system.py +54 -0
  653. angr/procedures/definitions/parse_win32json.py +2540 -0
  654. angr/procedures/definitions/types_stl.py +22 -0
  655. angr/procedures/definitions/wdk/api-ms-win-dx-d3dkmt-l1-1-4.json +24 -0
  656. angr/procedures/definitions/wdk/api-ms-win-dx-d3dkmt-l1-1-6.json +18 -0
  657. angr/procedures/definitions/wdk/clfs.json +189 -0
  658. angr/procedures/definitions/wdk/fltmgr.json +813 -0
  659. angr/procedures/definitions/wdk/fwpkclnt.json +24 -0
  660. angr/procedures/definitions/wdk/fwpuclnt.json +453 -0
  661. angr/procedures/definitions/wdk/gdi32.json +528 -0
  662. angr/procedures/definitions/wdk/hal.json +96 -0
  663. angr/procedures/definitions/wdk/ksecdd.json +72 -0
  664. angr/procedures/definitions/wdk/ndis.json +336 -0
  665. angr/procedures/definitions/wdk/ntoskrnl.json +5158 -0
  666. angr/procedures/definitions/wdk/offreg.json +87 -0
  667. angr/procedures/definitions/wdk/pshed.json +33 -0
  668. angr/procedures/definitions/wdk/secur32.json +39 -0
  669. angr/procedures/definitions/wdk/vhfum.json +30 -0
  670. angr/procedures/definitions/win32/_types_win32.json +34480 -0
  671. angr/procedures/definitions/win32/aclui.json +24 -0
  672. angr/procedures/definitions/win32/activeds.json +81 -0
  673. angr/procedures/definitions/win32/advapi32.json +2505 -0
  674. angr/procedures/definitions/win32/advpack.json +165 -0
  675. angr/procedures/definitions/win32/amsi.json +36 -0
  676. angr/procedures/definitions/win32/api-ms-win-appmodel-runtime-l1-1-1.json +45 -0
  677. angr/procedures/definitions/win32/api-ms-win-appmodel-runtime-l1-1-3.json +30 -0
  678. angr/procedures/definitions/win32/api-ms-win-appmodel-runtime-l1-1-6.json +18 -0
  679. angr/procedures/definitions/win32/api-ms-win-core-apiquery-l2-1-0.json +18 -0
  680. angr/procedures/definitions/win32/api-ms-win-core-backgroundtask-l1-1-0.json +18 -0
  681. angr/procedures/definitions/win32/api-ms-win-core-comm-l1-1-1.json +18 -0
  682. angr/procedures/definitions/win32/api-ms-win-core-comm-l1-1-2.json +18 -0
  683. angr/procedures/definitions/win32/api-ms-win-core-enclave-l1-1-1.json +24 -0
  684. angr/procedures/definitions/win32/api-ms-win-core-errorhandling-l1-1-3.json +18 -0
  685. angr/procedures/definitions/win32/api-ms-win-core-featurestaging-l1-1-0.json +30 -0
  686. angr/procedures/definitions/win32/api-ms-win-core-featurestaging-l1-1-1.json +18 -0
  687. angr/procedures/definitions/win32/api-ms-win-core-file-fromapp-l1-1-0.json +48 -0
  688. angr/procedures/definitions/win32/api-ms-win-core-handle-l1-1-0.json +18 -0
  689. angr/procedures/definitions/win32/api-ms-win-core-ioring-l1-1-0.json +51 -0
  690. angr/procedures/definitions/win32/api-ms-win-core-marshal-l1-1-0.json +27 -0
  691. angr/procedures/definitions/win32/api-ms-win-core-memory-l1-1-3.json +27 -0
  692. angr/procedures/definitions/win32/api-ms-win-core-memory-l1-1-4.json +18 -0
  693. angr/procedures/definitions/win32/api-ms-win-core-memory-l1-1-5.json +24 -0
  694. angr/procedures/definitions/win32/api-ms-win-core-memory-l1-1-6.json +27 -0
  695. angr/procedures/definitions/win32/api-ms-win-core-memory-l1-1-7.json +21 -0
  696. angr/procedures/definitions/win32/api-ms-win-core-memory-l1-1-8.json +24 -0
  697. angr/procedures/definitions/win32/api-ms-win-core-path-l1-1-0.json +81 -0
  698. angr/procedures/definitions/win32/api-ms-win-core-psm-appnotify-l1-1-0.json +21 -0
  699. angr/procedures/definitions/win32/api-ms-win-core-psm-appnotify-l1-1-1.json +21 -0
  700. angr/procedures/definitions/win32/api-ms-win-core-realtime-l1-1-1.json +24 -0
  701. angr/procedures/definitions/win32/api-ms-win-core-realtime-l1-1-2.json +24 -0
  702. angr/procedures/definitions/win32/api-ms-win-core-slapi-l1-1-0.json +18 -0
  703. angr/procedures/definitions/win32/api-ms-win-core-state-helpers-l1-1-0.json +18 -0
  704. angr/procedures/definitions/win32/api-ms-win-core-synch-l1-2-0.json +24 -0
  705. angr/procedures/definitions/win32/api-ms-win-core-sysinfo-l1-2-0.json +18 -0
  706. angr/procedures/definitions/win32/api-ms-win-core-sysinfo-l1-2-3.json +21 -0
  707. angr/procedures/definitions/win32/api-ms-win-core-sysinfo-l1-2-4.json +21 -0
  708. angr/procedures/definitions/win32/api-ms-win-core-sysinfo-l1-2-6.json +18 -0
  709. angr/procedures/definitions/win32/api-ms-win-core-util-l1-1-1.json +21 -0
  710. angr/procedures/definitions/win32/api-ms-win-core-wow64-l1-1-1.json +24 -0
  711. angr/procedures/definitions/win32/api-ms-win-devices-query-l1-1-0.json +42 -0
  712. angr/procedures/definitions/win32/api-ms-win-devices-query-l1-1-1.json +30 -0
  713. angr/procedures/definitions/win32/api-ms-win-dx-d3dkmt-l1-1-0.json +18 -0
  714. angr/procedures/definitions/win32/api-ms-win-gaming-deviceinformation-l1-1-0.json +18 -0
  715. angr/procedures/definitions/win32/api-ms-win-gaming-expandedresources-l1-1-0.json +24 -0
  716. angr/procedures/definitions/win32/api-ms-win-gaming-tcui-l1-1-0.json +36 -0
  717. angr/procedures/definitions/win32/api-ms-win-gaming-tcui-l1-1-1.json +21 -0
  718. angr/procedures/definitions/win32/api-ms-win-gaming-tcui-l1-1-2.json +36 -0
  719. angr/procedures/definitions/win32/api-ms-win-gaming-tcui-l1-1-3.json +21 -0
  720. angr/procedures/definitions/win32/api-ms-win-gaming-tcui-l1-1-4.json +39 -0
  721. angr/procedures/definitions/win32/api-ms-win-mm-misc-l1-1-1.json +18 -0
  722. angr/procedures/definitions/win32/api-ms-win-net-isolation-l1-1-0.json +39 -0
  723. angr/procedures/definitions/win32/api-ms-win-security-base-l1-2-2.json +18 -0
  724. angr/procedures/definitions/win32/api-ms-win-security-isolatedcontainer-l1-1-0.json +18 -0
  725. angr/procedures/definitions/win32/api-ms-win-security-isolatedcontainer-l1-1-1.json +18 -0
  726. angr/procedures/definitions/win32/api-ms-win-service-core-l1-1-3.json +18 -0
  727. angr/procedures/definitions/win32/api-ms-win-service-core-l1-1-4.json +18 -0
  728. angr/procedures/definitions/win32/api-ms-win-service-core-l1-1-5.json +21 -0
  729. angr/procedures/definitions/win32/api-ms-win-shcore-scaling-l1-1-0.json +24 -0
  730. angr/procedures/definitions/win32/api-ms-win-shcore-scaling-l1-1-1.json +33 -0
  731. angr/procedures/definitions/win32/api-ms-win-shcore-scaling-l1-1-2.json +18 -0
  732. angr/procedures/definitions/win32/api-ms-win-wsl-api-l1-1-0.json +36 -0
  733. angr/procedures/definitions/win32/apphelp.json +18 -0
  734. angr/procedures/definitions/win32/authz.json +114 -0
  735. angr/procedures/definitions/win32/avicap32.json +27 -0
  736. angr/procedures/definitions/win32/avifil32.json +195 -0
  737. angr/procedures/definitions/win32/avrt.json +57 -0
  738. angr/procedures/definitions/win32/bcp47mrm.json +21 -0
  739. angr/procedures/definitions/win32/bcrypt.json +174 -0
  740. angr/procedures/definitions/win32/bcryptprimitives.json +21 -0
  741. angr/procedures/definitions/win32/bluetoothapis.json +138 -0
  742. angr/procedures/definitions/win32/bthprops_cpl.json +33 -0
  743. angr/procedures/definitions/win32/cabinet.json +81 -0
  744. angr/procedures/definitions/win32/certadm.json +69 -0
  745. angr/procedures/definitions/win32/certpoleng.json +39 -0
  746. angr/procedures/definitions/win32/cfgmgr32.json +732 -0
  747. angr/procedures/definitions/win32/chakra.json +270 -0
  748. angr/procedures/definitions/win32/cldapi.json +123 -0
  749. angr/procedures/definitions/win32/clfsw32.json +192 -0
  750. angr/procedures/definitions/win32/clusapi.json +855 -0
  751. angr/procedures/definitions/win32/comctl32.json +360 -0
  752. angr/procedures/definitions/win32/comdlg32.json +78 -0
  753. angr/procedures/definitions/win32/compstui.json +27 -0
  754. angr/procedures/definitions/win32/computecore.json +177 -0
  755. angr/procedures/definitions/win32/computenetwork.json +144 -0
  756. angr/procedures/definitions/win32/computestorage.json +51 -0
  757. angr/procedures/definitions/win32/comsvcs.json +36 -0
  758. angr/procedures/definitions/win32/credui.json +72 -0
  759. angr/procedures/definitions/win32/crypt32.json +702 -0
  760. angr/procedures/definitions/win32/cryptnet.json +30 -0
  761. angr/procedures/definitions/win32/cryptui.json +45 -0
  762. angr/procedures/definitions/win32/cryptxml.json +72 -0
  763. angr/procedures/definitions/win32/cscapi.json +27 -0
  764. angr/procedures/definitions/win32/d2d1.json +54 -0
  765. angr/procedures/definitions/win32/d3d10.json +96 -0
  766. angr/procedures/definitions/win32/d3d10_1.json +21 -0
  767. angr/procedures/definitions/win32/d3d11.json +24 -0
  768. angr/procedures/definitions/win32/d3d12.json +39 -0
  769. angr/procedures/definitions/win32/d3d9.json +48 -0
  770. angr/procedures/definitions/win32/d3dcompiler_47.json +93 -0
  771. angr/procedures/definitions/win32/d3dcsx.json +42 -0
  772. angr/procedures/definitions/win32/davclnt.json +69 -0
  773. angr/procedures/definitions/win32/dbgeng.json +27 -0
  774. angr/procedures/definitions/win32/dbghelp.json +663 -0
  775. angr/procedures/definitions/win32/dbgmodel.json +18 -0
  776. angr/procedures/definitions/win32/dciman32.json +75 -0
  777. angr/procedures/definitions/win32/dcomp.json +51 -0
  778. angr/procedures/definitions/win32/ddraw.json +36 -0
  779. angr/procedures/definitions/win32/deviceaccess.json +18 -0
  780. angr/procedures/definitions/win32/dflayout.json +18 -0
  781. angr/procedures/definitions/win32/dhcpcsvc.json +60 -0
  782. angr/procedures/definitions/win32/dhcpcsvc6.json +33 -0
  783. angr/procedures/definitions/win32/dhcpsapi.json +603 -0
  784. angr/procedures/definitions/win32/diagnosticdataquery.json +120 -0
  785. angr/procedures/definitions/win32/dinput8.json +18 -0
  786. angr/procedures/definitions/win32/directml.json +21 -0
  787. angr/procedures/definitions/win32/dmprocessxmlfiltered.json +18 -0
  788. angr/procedures/definitions/win32/dnsapi.json +207 -0
  789. angr/procedures/definitions/win32/drt.json +63 -0
  790. angr/procedures/definitions/win32/drtprov.json +42 -0
  791. angr/procedures/definitions/win32/drttransport.json +21 -0
  792. angr/procedures/definitions/win32/dsound.json +45 -0
  793. angr/procedures/definitions/win32/dsparse.json +72 -0
  794. angr/procedures/definitions/win32/dsprop.json +36 -0
  795. angr/procedures/definitions/win32/dssec.json +27 -0
  796. angr/procedures/definitions/win32/dsuiext.json +27 -0
  797. angr/procedures/definitions/win32/dwmapi.json +108 -0
  798. angr/procedures/definitions/win32/dwrite.json +18 -0
  799. angr/procedures/definitions/win32/dxcompiler.json +21 -0
  800. angr/procedures/definitions/win32/dxcore.json +18 -0
  801. angr/procedures/definitions/win32/dxgi.json +33 -0
  802. angr/procedures/definitions/win32/dxva2.json +129 -0
  803. angr/procedures/definitions/win32/eappcfg.json +57 -0
  804. angr/procedures/definitions/win32/eappprxy.json +69 -0
  805. angr/procedures/definitions/win32/efswrt.json +21 -0
  806. angr/procedures/definitions/win32/elscore.json +30 -0
  807. angr/procedures/definitions/win32/esent.json +702 -0
  808. angr/procedures/definitions/win32/evr.json +36 -0
  809. angr/procedures/definitions/win32/faultrep.json +27 -0
  810. angr/procedures/definitions/win32/fhsvcctl.json +36 -0
  811. angr/procedures/definitions/win32/firewallapi.json +24 -0
  812. angr/procedures/definitions/win32/fltlib.json +99 -0
  813. angr/procedures/definitions/win32/fontsub.json +21 -0
  814. angr/procedures/definitions/win32/forceinline.json +24 -0
  815. angr/procedures/definitions/win32/fwpuclnt.json +591 -0
  816. angr/procedures/definitions/win32/fxsutility.json +21 -0
  817. angr/procedures/definitions/win32/gdi32.json +1308 -0
  818. angr/procedures/definitions/win32/gdiplus.json +1902 -0
  819. angr/procedures/definitions/win32/glu32.json +171 -0
  820. angr/procedures/definitions/win32/gpedit.json +33 -0
  821. angr/procedures/definitions/win32/hhctrl_ocx.json +21 -0
  822. angr/procedures/definitions/win32/hid.json +150 -0
  823. angr/procedures/definitions/win32/hlink.json +99 -0
  824. angr/procedures/definitions/win32/hrtfapo.json +18 -0
  825. angr/procedures/definitions/win32/httpapi.json +144 -0
  826. angr/procedures/definitions/win32/icm32.json +78 -0
  827. angr/procedures/definitions/win32/icmui.json +21 -0
  828. angr/procedures/definitions/win32/icu.json +3090 -0
  829. angr/procedures/definitions/win32/ieframe.json +102 -0
  830. angr/procedures/definitions/win32/imagehlp.json +84 -0
  831. angr/procedures/definitions/win32/imgutil.json +42 -0
  832. angr/procedures/definitions/win32/imm32.json +261 -0
  833. angr/procedures/definitions/win32/infocardapi.json +66 -0
  834. angr/procedures/definitions/win32/inkobjcore.json +96 -0
  835. angr/procedures/definitions/win32/iphlpapi.json +618 -0
  836. angr/procedures/definitions/win32/iscsidsc.json +252 -0
  837. angr/procedures/definitions/win32/isolatedwindowsenvironmentutils.json +21 -0
  838. angr/procedures/definitions/win32/kernel32.json +4566 -0
  839. angr/procedures/definitions/win32/kernelbase.json +33 -0
  840. angr/procedures/definitions/win32/keycredmgr.json +27 -0
  841. angr/procedures/definitions/win32/ksproxy_ax.json +33 -0
  842. angr/procedures/definitions/win32/ksuser.json +39 -0
  843. angr/procedures/definitions/win32/ktmw32.json +132 -0
  844. angr/procedures/definitions/win32/licenseprotection.json +21 -0
  845. angr/procedures/definitions/win32/loadperf.json +51 -0
  846. angr/procedures/definitions/win32/magnification.json +72 -0
  847. angr/procedures/definitions/win32/mapi32.json +213 -0
  848. angr/procedures/definitions/win32/mdmlocalmanagement.json +24 -0
  849. angr/procedures/definitions/win32/mdmregistration.json +60 -0
  850. angr/procedures/definitions/win32/mf.json +201 -0
  851. angr/procedures/definitions/win32/mfcore.json +21 -0
  852. angr/procedures/definitions/win32/mfplat.json +450 -0
  853. angr/procedures/definitions/win32/mfplay.json +18 -0
  854. angr/procedures/definitions/win32/mfreadwrite.json +30 -0
  855. angr/procedures/definitions/win32/mfsensorgroup.json +45 -0
  856. angr/procedures/definitions/win32/mfsrcsnk.json +21 -0
  857. angr/procedures/definitions/win32/mgmtapi.json +42 -0
  858. angr/procedures/definitions/win32/mi.json +18 -0
  859. angr/procedures/definitions/win32/mmdevapi.json +18 -0
  860. angr/procedures/definitions/win32/mpr.json +156 -0
  861. angr/procedures/definitions/win32/mprapi.json +351 -0
  862. angr/procedures/definitions/win32/mqrt.json +117 -0
  863. angr/procedures/definitions/win32/mrmsupport.json +96 -0
  864. angr/procedures/definitions/win32/msacm32.json +141 -0
  865. angr/procedures/definitions/win32/msajapi.json +1656 -0
  866. angr/procedures/definitions/win32/mscms.json +252 -0
  867. angr/procedures/definitions/win32/mscoree.json +96 -0
  868. angr/procedures/definitions/win32/msctfmonitor.json +24 -0
  869. angr/procedures/definitions/win32/msdelta.json +63 -0
  870. angr/procedures/definitions/win32/msdmo.json +48 -0
  871. angr/procedures/definitions/win32/msdrm.json +267 -0
  872. angr/procedures/definitions/win32/msi.json +807 -0
  873. angr/procedures/definitions/win32/msimg32.json +24 -0
  874. angr/procedures/definitions/win32/mspatcha.json +63 -0
  875. angr/procedures/definitions/win32/mspatchc.json +42 -0
  876. angr/procedures/definitions/win32/msports.json +36 -0
  877. angr/procedures/definitions/win32/msrating.json +72 -0
  878. angr/procedures/definitions/win32/mssign32.json +45 -0
  879. angr/procedures/definitions/win32/mstask.json +21 -0
  880. angr/procedures/definitions/win32/msvfw32.json +144 -0
  881. angr/procedures/definitions/win32/mswsock.json +63 -0
  882. angr/procedures/definitions/win32/mtxdm.json +18 -0
  883. angr/procedures/definitions/win32/ncrypt.json +132 -0
  884. angr/procedures/definitions/win32/ndfapi.json +63 -0
  885. angr/procedures/definitions/win32/netapi32.json +633 -0
  886. angr/procedures/definitions/win32/netsh.json +39 -0
  887. angr/procedures/definitions/win32/netshell.json +21 -0
  888. angr/procedures/definitions/win32/newdev.json +48 -0
  889. angr/procedures/definitions/win32/ninput.json +105 -0
  890. angr/procedures/definitions/win32/normaliz.json +21 -0
  891. angr/procedures/definitions/win32/ntdll.json +234 -0
  892. angr/procedures/definitions/win32/ntdllk.json +18 -0
  893. angr/procedures/definitions/win32/ntdsapi.json +258 -0
  894. angr/procedures/definitions/win32/ntlanman.json +45 -0
  895. angr/procedures/definitions/win32/odbc32.json +477 -0
  896. angr/procedures/definitions/win32/odbcbcp.json +96 -0
  897. angr/procedures/definitions/win32/ole32.json +966 -0
  898. angr/procedures/definitions/win32/oleacc.json +66 -0
  899. angr/procedures/definitions/win32/oleaut32.json +1230 -0
  900. angr/procedures/definitions/win32/oledlg.json +84 -0
  901. angr/procedures/definitions/win32/ondemandconnroutehelper.json +30 -0
  902. angr/procedures/definitions/win32/opengl32.json +1080 -0
  903. angr/procedures/definitions/win32/opmxbox.json +24 -0
  904. angr/procedures/definitions/win32/p2p.json +339 -0
  905. angr/procedures/definitions/win32/p2pgraph.json +126 -0
  906. angr/procedures/definitions/win32/pdh.json +309 -0
  907. angr/procedures/definitions/win32/peerdist.json +99 -0
  908. angr/procedures/definitions/win32/powrprof.json +267 -0
  909. angr/procedures/definitions/win32/prntvpt.json +48 -0
  910. angr/procedures/definitions/win32/projectedfslib.json +72 -0
  911. angr/procedures/definitions/win32/propsys.json +669 -0
  912. angr/procedures/definitions/win32/psapi.json +96 -0
  913. angr/procedures/definitions/win32/quartz.json +21 -0
  914. angr/procedures/definitions/win32/query.json +27 -0
  915. angr/procedures/definitions/win32/qwave.json +48 -0
  916. angr/procedures/definitions/win32/rasapi32.json +267 -0
  917. angr/procedures/definitions/win32/rasdlg.json +33 -0
  918. angr/procedures/definitions/win32/resutils.json +375 -0
  919. angr/procedures/definitions/win32/rpcns4.json +198 -0
  920. angr/procedures/definitions/win32/rpcproxy.json +27 -0
  921. angr/procedures/definitions/win32/rpcrt4.json +1356 -0
  922. angr/procedures/definitions/win32/rstrtmgr.json +48 -0
  923. angr/procedures/definitions/win32/rtm.json +243 -0
  924. angr/procedures/definitions/win32/rtutils.json +138 -0
  925. angr/procedures/definitions/win32/rtworkq.json +114 -0
  926. angr/procedures/definitions/win32/sas.json +18 -0
  927. angr/procedures/definitions/win32/scarddlg.json +30 -0
  928. angr/procedures/definitions/win32/schannel.json +42 -0
  929. angr/procedures/definitions/win32/sechost.json +21 -0
  930. angr/procedures/definitions/win32/secur32.json +282 -0
  931. angr/procedures/definitions/win32/sensapi.json +24 -0
  932. angr/procedures/definitions/win32/sensorsutilsv2.json +135 -0
  933. angr/procedures/definitions/win32/setupapi.json +1017 -0
  934. angr/procedures/definitions/win32/sfc.json +33 -0
  935. angr/procedures/definitions/win32/shdocvw.json +24 -0
  936. angr/procedures/definitions/win32/shell32.json +747 -0
  937. angr/procedures/definitions/win32/shlwapi.json +1095 -0
  938. angr/procedures/definitions/win32/slc.json +111 -0
  939. angr/procedures/definitions/win32/slcext.json +27 -0
  940. angr/procedures/definitions/win32/slwga.json +18 -0
  941. angr/procedures/definitions/win32/snmpapi.json +93 -0
  942. angr/procedures/definitions/win32/spoolss.json +93 -0
  943. angr/procedures/definitions/win32/srclient.json +18 -0
  944. angr/procedures/definitions/win32/srpapi.json +48 -0
  945. angr/procedures/definitions/win32/sspicli.json +36 -0
  946. angr/procedures/definitions/win32/sti.json +18 -0
  947. angr/procedures/definitions/win32/t2embed.json +57 -0
  948. angr/procedures/definitions/win32/tapi32.json +762 -0
  949. angr/procedures/definitions/win32/tbs.json +57 -0
  950. angr/procedures/definitions/win32/tdh.json +96 -0
  951. angr/procedures/definitions/win32/tokenbinding.json +45 -0
  952. angr/procedures/definitions/win32/traffic.json +75 -0
  953. angr/procedures/definitions/win32/txfw32.json +42 -0
  954. angr/procedures/definitions/win32/ualapi.json +27 -0
  955. angr/procedures/definitions/win32/uiautomationcore.json +309 -0
  956. angr/procedures/definitions/win32/urlmon.json +246 -0
  957. angr/procedures/definitions/win32/user32.json +2298 -0
  958. angr/procedures/definitions/win32/userenv.json +147 -0
  959. angr/procedures/definitions/win32/usp10.json +135 -0
  960. angr/procedures/definitions/win32/uxtheme.json +246 -0
  961. angr/procedures/definitions/win32/verifier.json +18 -0
  962. angr/procedures/definitions/win32/version.json +57 -0
  963. angr/procedures/definitions/win32/vertdll.json +36 -0
  964. angr/procedures/definitions/win32/virtdisk.json +102 -0
  965. angr/procedures/definitions/win32/vmdevicehost.json +54 -0
  966. angr/procedures/definitions/win32/vmsavedstatedumpprovider.json +144 -0
  967. angr/procedures/definitions/win32/vssapi.json +18 -0
  968. angr/procedures/definitions/win32/wcmapi.json +30 -0
  969. angr/procedures/definitions/win32/wdsbp.json +36 -0
  970. angr/procedures/definitions/win32/wdsclientapi.json +126 -0
  971. angr/procedures/definitions/win32/wdsmc.json +33 -0
  972. angr/procedures/definitions/win32/wdspxe.json +108 -0
  973. angr/procedures/definitions/win32/wdstptc.json +54 -0
  974. angr/procedures/definitions/win32/webauthn.json +54 -0
  975. angr/procedures/definitions/win32/webservices.json +594 -0
  976. angr/procedures/definitions/win32/websocket.json +54 -0
  977. angr/procedures/definitions/win32/wecapi.json +60 -0
  978. angr/procedures/definitions/win32/wer.json +78 -0
  979. angr/procedures/definitions/win32/wevtapi.json +120 -0
  980. angr/procedures/definitions/win32/winbio.json +177 -0
  981. angr/procedures/definitions/win32/windows_ai_machinelearning.json +18 -0
  982. angr/procedures/definitions/win32/windows_media_mediacontrol.json +39 -0
  983. angr/procedures/definitions/win32/windows_networking.json +18 -0
  984. angr/procedures/definitions/win32/windows_ui_xaml.json +21 -0
  985. angr/procedures/definitions/win32/windowscodecs.json +42 -0
  986. angr/procedures/definitions/win32/winfax.json +183 -0
  987. angr/procedures/definitions/win32/winhttp.json +183 -0
  988. angr/procedures/definitions/win32/winhvemulation.json +27 -0
  989. angr/procedures/definitions/win32/winhvplatform.json +213 -0
  990. angr/procedures/definitions/win32/wininet.json +903 -0
  991. angr/procedures/definitions/win32/winml.json +18 -0
  992. angr/procedures/definitions/win32/winmm.json +543 -0
  993. angr/procedures/definitions/win32/winscard.json +225 -0
  994. angr/procedures/definitions/win32/winspool_drv.json +531 -0
  995. angr/procedures/definitions/win32/wintrust.json +195 -0
  996. angr/procedures/definitions/win32/winusb.json +117 -0
  997. angr/procedures/definitions/win32/wlanapi.json +195 -0
  998. angr/procedures/definitions/win32/wlanui.json +18 -0
  999. angr/procedures/definitions/win32/wldap32.json +744 -0
  1000. angr/procedures/definitions/win32/wldp.json +42 -0
  1001. angr/procedures/definitions/win32/wmvcore.json +48 -0
  1002. angr/procedures/definitions/win32/wnvapi.json +21 -0
  1003. angr/procedures/definitions/win32/wofutil.json +48 -0
  1004. angr/procedures/definitions/win32/ws2_32.json +495 -0
  1005. angr/procedures/definitions/win32/wscapi.json +33 -0
  1006. angr/procedures/definitions/win32/wsclient.json +24 -0
  1007. angr/procedures/definitions/win32/wsdapi.json +111 -0
  1008. angr/procedures/definitions/win32/wsmsvc.json +114 -0
  1009. angr/procedures/definitions/win32/wsnmp32.json +162 -0
  1010. angr/procedures/definitions/win32/wtsapi32.json +204 -0
  1011. angr/procedures/definitions/win32/xaudio2_8.json +27 -0
  1012. angr/procedures/definitions/win32/xinput1_4.json +36 -0
  1013. angr/procedures/definitions/win32/xmllite.json +33 -0
  1014. angr/procedures/definitions/win32/xolehlp.json +27 -0
  1015. angr/procedures/definitions/win32/xpsprint.json +21 -0
  1016. angr/procedures/glibc/__ctype_b_loc.py +21 -0
  1017. angr/procedures/glibc/__ctype_tolower_loc.py +21 -0
  1018. angr/procedures/glibc/__ctype_toupper_loc.py +21 -0
  1019. angr/procedures/glibc/__errno_location.py +7 -0
  1020. angr/procedures/glibc/__init__.py +3 -0
  1021. angr/procedures/glibc/__libc_init.py +37 -0
  1022. angr/procedures/glibc/__libc_start_main.py +301 -0
  1023. angr/procedures/glibc/dynamic_loading.py +20 -0
  1024. angr/procedures/glibc/scanf.py +19 -0
  1025. angr/procedures/glibc/sscanf.py +10 -0
  1026. angr/procedures/gnulib/__init__.py +3 -0
  1027. angr/procedures/gnulib/xalloc_die.py +14 -0
  1028. angr/procedures/gnulib/xstrtol_fatal.py +14 -0
  1029. angr/procedures/java/__init__.py +42 -0
  1030. angr/procedures/java/unconstrained.py +65 -0
  1031. angr/procedures/java_io/__init__.py +0 -0
  1032. angr/procedures/java_io/read.py +12 -0
  1033. angr/procedures/java_io/write.py +17 -0
  1034. angr/procedures/java_jni/__init__.py +482 -0
  1035. angr/procedures/java_jni/array_operations.py +312 -0
  1036. angr/procedures/java_jni/class_and_interface_operations.py +31 -0
  1037. angr/procedures/java_jni/field_access.py +173 -0
  1038. angr/procedures/java_jni/global_and_local_refs.py +57 -0
  1039. angr/procedures/java_jni/method_calls.py +365 -0
  1040. angr/procedures/java_jni/not_implemented.py +26 -0
  1041. angr/procedures/java_jni/object_operations.py +94 -0
  1042. angr/procedures/java_jni/string_operations.py +87 -0
  1043. angr/procedures/java_jni/version_information.py +12 -0
  1044. angr/procedures/java_lang/__init__.py +0 -0
  1045. angr/procedures/java_lang/character.py +30 -0
  1046. angr/procedures/java_lang/double.py +24 -0
  1047. angr/procedures/java_lang/exit.py +13 -0
  1048. angr/procedures/java_lang/getsimplename.py +18 -0
  1049. angr/procedures/java_lang/integer.py +43 -0
  1050. angr/procedures/java_lang/load_library.py +9 -0
  1051. angr/procedures/java_lang/math.py +15 -0
  1052. angr/procedures/java_lang/string.py +78 -0
  1053. angr/procedures/java_lang/stringbuilder.py +44 -0
  1054. angr/procedures/java_lang/system.py +18 -0
  1055. angr/procedures/java_util/__init__.py +0 -0
  1056. angr/procedures/java_util/collection.py +35 -0
  1057. angr/procedures/java_util/iterator.py +46 -0
  1058. angr/procedures/java_util/list.py +99 -0
  1059. angr/procedures/java_util/map.py +131 -0
  1060. angr/procedures/java_util/random.py +14 -0
  1061. angr/procedures/java_util/scanner_nextline.py +23 -0
  1062. angr/procedures/libc/__init__.py +3 -0
  1063. angr/procedures/libc/abort.py +9 -0
  1064. angr/procedures/libc/access.py +13 -0
  1065. angr/procedures/libc/atoi.py +14 -0
  1066. angr/procedures/libc/atol.py +13 -0
  1067. angr/procedures/libc/calloc.py +8 -0
  1068. angr/procedures/libc/closelog.py +10 -0
  1069. angr/procedures/libc/err.py +14 -0
  1070. angr/procedures/libc/error.py +54 -0
  1071. angr/procedures/libc/exit.py +11 -0
  1072. angr/procedures/libc/fclose.py +19 -0
  1073. angr/procedures/libc/feof.py +21 -0
  1074. angr/procedures/libc/fflush.py +16 -0
  1075. angr/procedures/libc/fgetc.py +27 -0
  1076. angr/procedures/libc/fgets.py +69 -0
  1077. angr/procedures/libc/fopen.py +63 -0
  1078. angr/procedures/libc/fprintf.py +25 -0
  1079. angr/procedures/libc/fputc.py +23 -0
  1080. angr/procedures/libc/fputs.py +24 -0
  1081. angr/procedures/libc/fread.py +24 -0
  1082. angr/procedures/libc/free.py +9 -0
  1083. angr/procedures/libc/fscanf.py +20 -0
  1084. angr/procedures/libc/fseek.py +34 -0
  1085. angr/procedures/libc/ftell.py +22 -0
  1086. angr/procedures/libc/fwrite.py +19 -0
  1087. angr/procedures/libc/getchar.py +13 -0
  1088. angr/procedures/libc/getdelim.py +99 -0
  1089. angr/procedures/libc/getegid.py +8 -0
  1090. angr/procedures/libc/geteuid.py +8 -0
  1091. angr/procedures/libc/getgid.py +8 -0
  1092. angr/procedures/libc/gets.py +68 -0
  1093. angr/procedures/libc/getuid.py +8 -0
  1094. angr/procedures/libc/malloc.py +12 -0
  1095. angr/procedures/libc/memcmp.py +69 -0
  1096. angr/procedures/libc/memcpy.py +45 -0
  1097. angr/procedures/libc/memset.py +72 -0
  1098. angr/procedures/libc/openlog.py +10 -0
  1099. angr/procedures/libc/perror.py +13 -0
  1100. angr/procedures/libc/printf.py +34 -0
  1101. angr/procedures/libc/putchar.py +13 -0
  1102. angr/procedures/libc/puts.py +19 -0
  1103. angr/procedures/libc/rand.py +8 -0
  1104. angr/procedures/libc/realloc.py +8 -0
  1105. angr/procedures/libc/rewind.py +12 -0
  1106. angr/procedures/libc/scanf.py +20 -0
  1107. angr/procedures/libc/setbuf.py +9 -0
  1108. angr/procedures/libc/setvbuf.py +7 -0
  1109. angr/procedures/libc/snprintf.py +36 -0
  1110. angr/procedures/libc/sprintf.py +25 -0
  1111. angr/procedures/libc/srand.py +7 -0
  1112. angr/procedures/libc/sscanf.py +13 -0
  1113. angr/procedures/libc/stpcpy.py +18 -0
  1114. angr/procedures/libc/strcat.py +14 -0
  1115. angr/procedures/libc/strchr.py +48 -0
  1116. angr/procedures/libc/strcmp.py +31 -0
  1117. angr/procedures/libc/strcpy.py +13 -0
  1118. angr/procedures/libc/strlen.py +114 -0
  1119. angr/procedures/libc/strncat.py +19 -0
  1120. angr/procedures/libc/strncmp.py +183 -0
  1121. angr/procedures/libc/strncpy.py +22 -0
  1122. angr/procedures/libc/strnlen.py +13 -0
  1123. angr/procedures/libc/strstr.py +101 -0
  1124. angr/procedures/libc/strtol.py +261 -0
  1125. angr/procedures/libc/strtoul.py +9 -0
  1126. angr/procedures/libc/system.py +13 -0
  1127. angr/procedures/libc/time.py +9 -0
  1128. angr/procedures/libc/tmpnam.py +20 -0
  1129. angr/procedures/libc/tolower.py +10 -0
  1130. angr/procedures/libc/toupper.py +10 -0
  1131. angr/procedures/libc/ungetc.py +20 -0
  1132. angr/procedures/libc/vsnprintf.py +17 -0
  1133. angr/procedures/libc/wchar.py +16 -0
  1134. angr/procedures/libstdcpp/__init__.py +0 -0
  1135. angr/procedures/libstdcpp/_unwind_resume.py +11 -0
  1136. angr/procedures/libstdcpp/std____throw_bad_alloc.py +13 -0
  1137. angr/procedures/libstdcpp/std____throw_bad_cast.py +13 -0
  1138. angr/procedures/libstdcpp/std____throw_length_error.py +13 -0
  1139. angr/procedures/libstdcpp/std____throw_logic_error.py +13 -0
  1140. angr/procedures/libstdcpp/std__terminate.py +13 -0
  1141. angr/procedures/linux_kernel/__init__.py +3 -0
  1142. angr/procedures/linux_kernel/access.py +18 -0
  1143. angr/procedures/linux_kernel/arch_prctl.py +34 -0
  1144. angr/procedures/linux_kernel/arm_user_helpers.py +59 -0
  1145. angr/procedures/linux_kernel/brk.py +18 -0
  1146. angr/procedures/linux_kernel/cwd.py +28 -0
  1147. angr/procedures/linux_kernel/fstat.py +138 -0
  1148. angr/procedures/linux_kernel/fstat64.py +170 -0
  1149. angr/procedures/linux_kernel/futex.py +17 -0
  1150. angr/procedures/linux_kernel/getegid.py +17 -0
  1151. angr/procedures/linux_kernel/geteuid.py +17 -0
  1152. angr/procedures/linux_kernel/getgid.py +17 -0
  1153. angr/procedures/linux_kernel/getpid.py +14 -0
  1154. angr/procedures/linux_kernel/getrlimit.py +24 -0
  1155. angr/procedures/linux_kernel/gettid.py +9 -0
  1156. angr/procedures/linux_kernel/getuid.py +17 -0
  1157. angr/procedures/linux_kernel/iovec.py +47 -0
  1158. angr/procedures/linux_kernel/lseek.py +42 -0
  1159. angr/procedures/linux_kernel/mmap.py +16 -0
  1160. angr/procedures/linux_kernel/mprotect.py +42 -0
  1161. angr/procedures/linux_kernel/munmap.py +8 -0
  1162. angr/procedures/linux_kernel/openat.py +26 -0
  1163. angr/procedures/linux_kernel/set_tid_address.py +8 -0
  1164. angr/procedures/linux_kernel/sigaction.py +19 -0
  1165. angr/procedures/linux_kernel/sigprocmask.py +23 -0
  1166. angr/procedures/linux_kernel/stat.py +23 -0
  1167. angr/procedures/linux_kernel/sysinfo.py +59 -0
  1168. angr/procedures/linux_kernel/tgkill.py +10 -0
  1169. angr/procedures/linux_kernel/time.py +34 -0
  1170. angr/procedures/linux_kernel/uid.py +30 -0
  1171. angr/procedures/linux_kernel/uname.py +29 -0
  1172. angr/procedures/linux_kernel/unlink.py +22 -0
  1173. angr/procedures/linux_kernel/vsyscall.py +16 -0
  1174. angr/procedures/linux_loader/__init__.py +3 -0
  1175. angr/procedures/linux_loader/_dl_initial_error_catch_tsd.py +7 -0
  1176. angr/procedures/linux_loader/_dl_rtld_lock.py +15 -0
  1177. angr/procedures/linux_loader/sim_loader.py +54 -0
  1178. angr/procedures/linux_loader/tls.py +40 -0
  1179. angr/procedures/msvcr/__getmainargs.py +16 -0
  1180. angr/procedures/msvcr/__init__.py +4 -0
  1181. angr/procedures/msvcr/_initterm.py +38 -0
  1182. angr/procedures/msvcr/fmode.py +31 -0
  1183. angr/procedures/ntdll/__init__.py +0 -0
  1184. angr/procedures/ntdll/exceptions.py +60 -0
  1185. angr/procedures/posix/__init__.py +3 -0
  1186. angr/procedures/posix/accept.py +29 -0
  1187. angr/procedures/posix/bind.py +13 -0
  1188. angr/procedures/posix/bzero.py +9 -0
  1189. angr/procedures/posix/chroot.py +27 -0
  1190. angr/procedures/posix/close.py +9 -0
  1191. angr/procedures/posix/closedir.py +7 -0
  1192. angr/procedures/posix/dup.py +56 -0
  1193. angr/procedures/posix/fcntl.py +10 -0
  1194. angr/procedures/posix/fdopen.py +76 -0
  1195. angr/procedures/posix/fileno.py +18 -0
  1196. angr/procedures/posix/fork.py +13 -0
  1197. angr/procedures/posix/getenv.py +35 -0
  1198. angr/procedures/posix/gethostbyname.py +43 -0
  1199. angr/procedures/posix/getpass.py +19 -0
  1200. angr/procedures/posix/getsockopt.py +11 -0
  1201. angr/procedures/posix/htonl.py +11 -0
  1202. angr/procedures/posix/htons.py +11 -0
  1203. angr/procedures/posix/inet_ntoa.py +59 -0
  1204. angr/procedures/posix/listen.py +13 -0
  1205. angr/procedures/posix/mmap.py +144 -0
  1206. angr/procedures/posix/open.py +18 -0
  1207. angr/procedures/posix/opendir.py +10 -0
  1208. angr/procedures/posix/poll.py +55 -0
  1209. angr/procedures/posix/pread64.py +46 -0
  1210. angr/procedures/posix/pthread.py +87 -0
  1211. angr/procedures/posix/pwrite64.py +46 -0
  1212. angr/procedures/posix/read.py +13 -0
  1213. angr/procedures/posix/readdir.py +62 -0
  1214. angr/procedures/posix/recv.py +13 -0
  1215. angr/procedures/posix/recvfrom.py +13 -0
  1216. angr/procedures/posix/select.py +48 -0
  1217. angr/procedures/posix/send.py +23 -0
  1218. angr/procedures/posix/setsockopt.py +9 -0
  1219. angr/procedures/posix/sigaction.py +23 -0
  1220. angr/procedures/posix/sim_time.py +48 -0
  1221. angr/procedures/posix/sleep.py +8 -0
  1222. angr/procedures/posix/socket.py +18 -0
  1223. angr/procedures/posix/strcasecmp.py +26 -0
  1224. angr/procedures/posix/strdup.py +18 -0
  1225. angr/procedures/posix/strtok_r.py +64 -0
  1226. angr/procedures/posix/syslog.py +15 -0
  1227. angr/procedures/posix/tz.py +9 -0
  1228. angr/procedures/posix/unlink.py +11 -0
  1229. angr/procedures/posix/usleep.py +8 -0
  1230. angr/procedures/posix/write.py +13 -0
  1231. angr/procedures/procedure_dict.py +50 -0
  1232. angr/procedures/stubs/CallReturn.py +13 -0
  1233. angr/procedures/stubs/NoReturnUnconstrained.py +13 -0
  1234. angr/procedures/stubs/Nop.py +7 -0
  1235. angr/procedures/stubs/PathTerminator.py +9 -0
  1236. angr/procedures/stubs/Redirect.py +18 -0
  1237. angr/procedures/stubs/ReturnChar.py +11 -0
  1238. angr/procedures/stubs/ReturnUnconstrained.py +24 -0
  1239. angr/procedures/stubs/UnresolvableCallTarget.py +9 -0
  1240. angr/procedures/stubs/UnresolvableJumpTarget.py +9 -0
  1241. angr/procedures/stubs/UserHook.py +18 -0
  1242. angr/procedures/stubs/__init__.py +3 -0
  1243. angr/procedures/stubs/b64_decode.py +15 -0
  1244. angr/procedures/stubs/caller.py +14 -0
  1245. angr/procedures/stubs/crazy_scanf.py +20 -0
  1246. angr/procedures/stubs/format_parser.py +669 -0
  1247. angr/procedures/stubs/syscall_stub.py +24 -0
  1248. angr/procedures/testing/__init__.py +3 -0
  1249. angr/procedures/testing/manyargs.py +9 -0
  1250. angr/procedures/testing/retreg.py +8 -0
  1251. angr/procedures/tracer/__init__.py +4 -0
  1252. angr/procedures/tracer/random.py +9 -0
  1253. angr/procedures/tracer/receive.py +23 -0
  1254. angr/procedures/tracer/transmit.py +26 -0
  1255. angr/procedures/uclibc/__init__.py +3 -0
  1256. angr/procedures/uclibc/__uClibc_main.py +10 -0
  1257. angr/procedures/win32/EncodePointer.py +7 -0
  1258. angr/procedures/win32/ExitProcess.py +9 -0
  1259. angr/procedures/win32/GetCommandLine.py +12 -0
  1260. angr/procedures/win32/GetCurrentProcessId.py +7 -0
  1261. angr/procedures/win32/GetCurrentThreadId.py +7 -0
  1262. angr/procedures/win32/GetLastInputInfo.py +40 -0
  1263. angr/procedures/win32/GetModuleHandle.py +29 -0
  1264. angr/procedures/win32/GetProcessAffinityMask.py +37 -0
  1265. angr/procedures/win32/InterlockedExchange.py +15 -0
  1266. angr/procedures/win32/IsProcessorFeaturePresent.py +7 -0
  1267. angr/procedures/win32/VirtualAlloc.py +114 -0
  1268. angr/procedures/win32/VirtualProtect.py +60 -0
  1269. angr/procedures/win32/__init__.py +3 -0
  1270. angr/procedures/win32/critical_section.py +12 -0
  1271. angr/procedures/win32/dynamic_loading.py +104 -0
  1272. angr/procedures/win32/file_handles.py +47 -0
  1273. angr/procedures/win32/gethostbyname.py +12 -0
  1274. angr/procedures/win32/heap.py +45 -0
  1275. angr/procedures/win32/is_bad_ptr.py +26 -0
  1276. angr/procedures/win32/local_storage.py +88 -0
  1277. angr/procedures/win32/mutex.py +11 -0
  1278. angr/procedures/win32/sim_time.py +135 -0
  1279. angr/procedures/win32/system_paths.py +35 -0
  1280. angr/procedures/win32_kernel/ExAllocatePool.py +13 -0
  1281. angr/procedures/win32_kernel/ExFreePoolWithTag.py +8 -0
  1282. angr/procedures/win32_kernel/__fastfail.py +15 -0
  1283. angr/procedures/win32_kernel/__init__.py +3 -0
  1284. angr/procedures/win_user32/__init__.py +0 -0
  1285. angr/procedures/win_user32/chars.py +15 -0
  1286. angr/procedures/win_user32/keyboard.py +14 -0
  1287. angr/procedures/win_user32/messagebox.py +49 -0
  1288. angr/project.py +860 -0
  1289. angr/protos/__init__.py +19 -0
  1290. angr/protos/cfg_pb2.py +42 -0
  1291. angr/protos/function_pb2.py +38 -0
  1292. angr/protos/primitives_pb2.py +59 -0
  1293. angr/protos/variables_pb2.py +55 -0
  1294. angr/protos/xrefs_pb2.py +36 -0
  1295. angr/py.typed +1 -0
  1296. angr/rustylib.cpython-311-darwin.so +0 -0
  1297. angr/serializable.py +66 -0
  1298. angr/sim_manager.py +971 -0
  1299. angr/sim_options.py +436 -0
  1300. angr/sim_procedure.py +626 -0
  1301. angr/sim_state.py +926 -0
  1302. angr/sim_state_options.py +403 -0
  1303. angr/sim_type.py +4026 -0
  1304. angr/sim_variable.py +470 -0
  1305. angr/simos/__init__.py +47 -0
  1306. angr/simos/cgc.py +153 -0
  1307. angr/simos/javavm.py +458 -0
  1308. angr/simos/linux.py +509 -0
  1309. angr/simos/simos.py +444 -0
  1310. angr/simos/snimmuc_nxp.py +149 -0
  1311. angr/simos/userland.py +163 -0
  1312. angr/simos/windows.py +615 -0
  1313. angr/simos/xbox.py +32 -0
  1314. angr/slicer.py +352 -0
  1315. angr/state_hierarchy.py +262 -0
  1316. angr/state_plugins/__init__.py +84 -0
  1317. angr/state_plugins/callstack.py +478 -0
  1318. angr/state_plugins/cgc.py +155 -0
  1319. angr/state_plugins/debug_variables.py +192 -0
  1320. angr/state_plugins/filesystem.py +463 -0
  1321. angr/state_plugins/gdb.py +148 -0
  1322. angr/state_plugins/globals.py +65 -0
  1323. angr/state_plugins/heap/__init__.py +15 -0
  1324. angr/state_plugins/heap/heap_base.py +128 -0
  1325. angr/state_plugins/heap/heap_brk.py +136 -0
  1326. angr/state_plugins/heap/heap_freelist.py +213 -0
  1327. angr/state_plugins/heap/heap_libc.py +46 -0
  1328. angr/state_plugins/heap/heap_ptmalloc.py +620 -0
  1329. angr/state_plugins/heap/utils.py +22 -0
  1330. angr/state_plugins/history.py +564 -0
  1331. angr/state_plugins/inspect.py +375 -0
  1332. angr/state_plugins/javavm_classloader.py +134 -0
  1333. angr/state_plugins/jni_references.py +95 -0
  1334. angr/state_plugins/libc.py +1263 -0
  1335. angr/state_plugins/light_registers.py +168 -0
  1336. angr/state_plugins/log.py +84 -0
  1337. angr/state_plugins/loop_data.py +92 -0
  1338. angr/state_plugins/plugin.py +176 -0
  1339. angr/state_plugins/posix.py +703 -0
  1340. angr/state_plugins/preconstrainer.py +196 -0
  1341. angr/state_plugins/scratch.py +173 -0
  1342. angr/state_plugins/sim_action.py +326 -0
  1343. angr/state_plugins/sim_action_object.py +271 -0
  1344. angr/state_plugins/sim_event.py +59 -0
  1345. angr/state_plugins/solver.py +1128 -0
  1346. angr/state_plugins/symbolizer.py +291 -0
  1347. angr/state_plugins/trace_additions.py +738 -0
  1348. angr/state_plugins/uc_manager.py +94 -0
  1349. angr/state_plugins/unicorn_engine.py +1920 -0
  1350. angr/state_plugins/view.py +340 -0
  1351. angr/storage/__init__.py +15 -0
  1352. angr/storage/file.py +1210 -0
  1353. angr/storage/memory_mixins/__init__.py +317 -0
  1354. angr/storage/memory_mixins/actions_mixin.py +72 -0
  1355. angr/storage/memory_mixins/address_concretization_mixin.py +384 -0
  1356. angr/storage/memory_mixins/bvv_conversion_mixin.py +73 -0
  1357. angr/storage/memory_mixins/clouseau_mixin.py +137 -0
  1358. angr/storage/memory_mixins/conditional_store_mixin.py +25 -0
  1359. angr/storage/memory_mixins/convenient_mappings_mixin.py +256 -0
  1360. angr/storage/memory_mixins/default_filler_mixin.py +144 -0
  1361. angr/storage/memory_mixins/dirty_addrs_mixin.py +11 -0
  1362. angr/storage/memory_mixins/hex_dumper_mixin.py +82 -0
  1363. angr/storage/memory_mixins/javavm_memory_mixin.py +392 -0
  1364. angr/storage/memory_mixins/keyvalue_memory_mixin.py +43 -0
  1365. angr/storage/memory_mixins/label_merger_mixin.py +31 -0
  1366. angr/storage/memory_mixins/memory_mixin.py +175 -0
  1367. angr/storage/memory_mixins/multi_value_merger_mixin.py +79 -0
  1368. angr/storage/memory_mixins/name_resolution_mixin.py +67 -0
  1369. angr/storage/memory_mixins/paged_memory/__init__.py +0 -0
  1370. angr/storage/memory_mixins/paged_memory/page_backer_mixins.py +266 -0
  1371. angr/storage/memory_mixins/paged_memory/paged_memory_mixin.py +743 -0
  1372. angr/storage/memory_mixins/paged_memory/paged_memory_multivalue_mixin.py +65 -0
  1373. angr/storage/memory_mixins/paged_memory/pages/__init__.py +26 -0
  1374. angr/storage/memory_mixins/paged_memory/pages/base.py +31 -0
  1375. angr/storage/memory_mixins/paged_memory/pages/cooperation.py +341 -0
  1376. angr/storage/memory_mixins/paged_memory/pages/history_tracking_mixin.py +92 -0
  1377. angr/storage/memory_mixins/paged_memory/pages/ispo_mixin.py +55 -0
  1378. angr/storage/memory_mixins/paged_memory/pages/list_page.py +338 -0
  1379. angr/storage/memory_mixins/paged_memory/pages/multi_values.py +324 -0
  1380. angr/storage/memory_mixins/paged_memory/pages/mv_list_page.py +419 -0
  1381. angr/storage/memory_mixins/paged_memory/pages/permissions_mixin.py +36 -0
  1382. angr/storage/memory_mixins/paged_memory/pages/refcount_mixin.py +52 -0
  1383. angr/storage/memory_mixins/paged_memory/pages/ultra_page.py +529 -0
  1384. angr/storage/memory_mixins/paged_memory/privileged_mixin.py +36 -0
  1385. angr/storage/memory_mixins/paged_memory/stack_allocation_mixin.py +74 -0
  1386. angr/storage/memory_mixins/regioned_memory/__init__.py +17 -0
  1387. angr/storage/memory_mixins/regioned_memory/abstract_address_descriptor.py +36 -0
  1388. angr/storage/memory_mixins/regioned_memory/abstract_merger_mixin.py +31 -0
  1389. angr/storage/memory_mixins/regioned_memory/region_category_mixin.py +9 -0
  1390. angr/storage/memory_mixins/regioned_memory/region_data.py +246 -0
  1391. angr/storage/memory_mixins/regioned_memory/region_meta_mixin.py +241 -0
  1392. angr/storage/memory_mixins/regioned_memory/regioned_address_concretization_mixin.py +119 -0
  1393. angr/storage/memory_mixins/regioned_memory/regioned_memory_mixin.py +442 -0
  1394. angr/storage/memory_mixins/regioned_memory/static_find_mixin.py +69 -0
  1395. angr/storage/memory_mixins/simple_interface_mixin.py +71 -0
  1396. angr/storage/memory_mixins/simplification_mixin.py +15 -0
  1397. angr/storage/memory_mixins/size_resolution_mixin.py +143 -0
  1398. angr/storage/memory_mixins/slotted_memory.py +140 -0
  1399. angr/storage/memory_mixins/smart_find_mixin.py +161 -0
  1400. angr/storage/memory_mixins/symbolic_merger_mixin.py +16 -0
  1401. angr/storage/memory_mixins/top_merger_mixin.py +25 -0
  1402. angr/storage/memory_mixins/underconstrained_mixin.py +67 -0
  1403. angr/storage/memory_mixins/unwrapper_mixin.py +26 -0
  1404. angr/storage/memory_object.py +195 -0
  1405. angr/tablespecs.py +91 -0
  1406. angr/unicornlib.dylib +0 -0
  1407. angr/utils/__init__.py +46 -0
  1408. angr/utils/ail.py +176 -0
  1409. angr/utils/algo.py +34 -0
  1410. angr/utils/balancer.py +776 -0
  1411. angr/utils/bits.py +46 -0
  1412. angr/utils/constants.py +9 -0
  1413. angr/utils/cowdict.py +63 -0
  1414. angr/utils/cpp.py +17 -0
  1415. angr/utils/doms.py +150 -0
  1416. angr/utils/dynamic_dictlist.py +89 -0
  1417. angr/utils/endness.py +18 -0
  1418. angr/utils/enums_conv.py +97 -0
  1419. angr/utils/env.py +12 -0
  1420. angr/utils/formatting.py +128 -0
  1421. angr/utils/funcid.py +244 -0
  1422. angr/utils/graph.py +981 -0
  1423. angr/utils/lazy_import.py +13 -0
  1424. angr/utils/library.py +236 -0
  1425. angr/utils/loader.py +55 -0
  1426. angr/utils/mp.py +66 -0
  1427. angr/utils/orderedset.py +74 -0
  1428. angr/utils/ssa/__init__.py +455 -0
  1429. angr/utils/ssa/tmp_uses_collector.py +23 -0
  1430. angr/utils/ssa/vvar_uses_collector.py +36 -0
  1431. angr/utils/strings.py +20 -0
  1432. angr/utils/tagged_interval_map.py +112 -0
  1433. angr/utils/timing.py +74 -0
  1434. angr/utils/types.py +193 -0
  1435. angr/utils/vex.py +11 -0
  1436. angr/vaults.py +367 -0
  1437. angr-9.2.192.dist-info/METADATA +112 -0
  1438. angr-9.2.192.dist-info/RECORD +1442 -0
  1439. angr-9.2.192.dist-info/WHEEL +6 -0
  1440. angr-9.2.192.dist-info/entry_points.txt +2 -0
  1441. angr-9.2.192.dist-info/licenses/LICENSE +27 -0
  1442. angr-9.2.192.dist-info/top_level.txt +1 -0
@@ -0,0 +1,2246 @@
1
+ # pylint:disable=too-many-boolean-expressions,consider-using-enumerate
2
+ from __future__ import annotations
3
+ from typing import Any, TYPE_CHECKING
4
+ from collections.abc import Container
5
+ from collections.abc import Iterable
6
+ from collections import defaultdict
7
+ from enum import Enum
8
+ import logging
9
+
10
+ import networkx
11
+
12
+ from angr.ailment import AILBlockRewriter, AILBlockViewer
13
+ from angr.ailment.block import Block
14
+ from angr.ailment.statement import (
15
+ Statement,
16
+ Assignment,
17
+ Store,
18
+ Call,
19
+ ConditionalJump,
20
+ DirtyStatement,
21
+ WeakAssignment,
22
+ Return,
23
+ )
24
+ from angr.ailment.expression import (
25
+ Register,
26
+ Convert,
27
+ Load,
28
+ StackBaseOffset,
29
+ Expression,
30
+ DirtyExpression,
31
+ VEXCCallExpression,
32
+ Tmp,
33
+ Const,
34
+ BinaryOp,
35
+ VirtualVariable,
36
+ UnaryOp,
37
+ )
38
+
39
+ from angr.analyses.s_propagator import SPropagatorAnalysis
40
+ from angr.analyses.s_reaching_definitions import SRDAModel, SReachingDefinitionsAnalysis
41
+ from angr.utils.ail import is_phi_assignment, HasExprWalker, is_expr_used_as_reg_base_value
42
+ from angr.utils.ssa import (
43
+ has_call_in_between_stmts,
44
+ has_store_stmt_in_between_stmts,
45
+ has_load_expr_in_between_stmts,
46
+ is_vvar_eliminatable,
47
+ )
48
+ from angr.code_location import AILCodeLocation
49
+ from angr.sim_variable import SimStackVariable, SimMemoryVariable, SimVariable
50
+ from angr.knowledge_plugins.propagations.states import Equivalence
51
+ from angr.knowledge_plugins.key_definitions import atoms
52
+ from angr.knowledge_plugins.key_definitions.definition import Definition
53
+ from angr.knowledge_plugins.key_definitions.constants import OP_BEFORE
54
+ from angr.errors import AngrRuntimeError
55
+ from angr.analyses import Analysis, AnalysesHub
56
+ from angr.utils.timing import timethis
57
+ from .ailgraph_walker import AILGraphWalker
58
+ from .expression_narrower import ExprNarrowingInfo, NarrowingInfoExtractor, ExpressionNarrower
59
+ from .block_simplifier import BlockSimplifier
60
+ from .ccall_rewriters import CCALL_REWRITERS
61
+ from .dirty_rewriters import DIRTY_REWRITERS
62
+ from .counters.expression_counters import SingleExpressionCounter
63
+
64
+ if TYPE_CHECKING:
65
+ from angr.ailment.manager import Manager
66
+
67
+
68
+ _l = logging.getLogger(__name__)
69
+
70
+
71
+ class HasCallNotification(Exception):
72
+ """
73
+ Notifies the existence of a call statement.
74
+ """
75
+
76
+
77
+ class HasVVarNotification(Exception):
78
+ """
79
+ Notifies the existence of a VirtualVariable.
80
+ """
81
+
82
+
83
+ class HasRefVVarNotification(Exception):
84
+ """
85
+ Notifies the existence of a reference to a VirtualVariable.
86
+ """
87
+
88
+
89
+ class AILBlockTempCollector(AILBlockViewer):
90
+ """
91
+ Collects any temporaries used in a block.
92
+ """
93
+
94
+ def __init__(self, **kwargs):
95
+ super().__init__(**kwargs)
96
+ self.temps = set()
97
+ self.expr_handlers[Tmp] = self._handle_Tmp
98
+
99
+ # pylint:disable=unused-argument
100
+ def _handle_Tmp(self, expr_idx: int, expr: Expression, stmt_idx: int, stmt: Statement | None, block):
101
+ if isinstance(expr, Tmp):
102
+ self.temps.add(expr)
103
+
104
+
105
+ class DefEqRelation(Enum):
106
+ """
107
+ Describes the location relationship between a virtual variable definition and the equivalence statement.
108
+ """
109
+
110
+ UNKNOWN = 0
111
+ DEF_IS_FUNCARG = 1
112
+ DEF_EQ_SAME_BLOCK = 2
113
+ DEF_IN_EQ_PRED_BLOCK = 3
114
+
115
+
116
+ class PartialConstantExprRewriter(AILBlockRewriter):
117
+ """
118
+ Rewrites expressions whose high bits are definitely zero to constants (if possible) or mask them with masks
119
+ properly.
120
+ """
121
+
122
+ def __init__(self, varid: int, zero_high_bits: int):
123
+ super().__init__(update_block=False)
124
+ self.varid = varid
125
+ self.zero_high_bits = zero_high_bits
126
+
127
+ def _handle_BinaryOp( # type:ignore
128
+ self, expr_idx: int, expr: BinaryOp, stmt_idx: int, stmt: Statement, block: Block | None
129
+ ):
130
+ if (
131
+ expr.op == "And"
132
+ and isinstance(expr.operands[0], VirtualVariable)
133
+ and expr.operands[0].varid == self.varid
134
+ and isinstance(expr.operands[1], Const)
135
+ and expr.operands[1].is_int
136
+ ):
137
+ vvar = expr.operands[0]
138
+ mask_expr = expr.operands[1]
139
+ mask = mask_expr.value
140
+ assert isinstance(mask, int)
141
+ # high_bits_mask[vvar.bits - 1:vvar.bits - self.zero_high_bits] == 0
142
+ high_bits_mask = ((1 << vvar.bits) - 1) ^ ((1 << (vvar.bits - self.zero_high_bits)) - 1)
143
+ high_bits_mask &= mask # in case high bits of mask are zero
144
+ new_mask = mask ^ high_bits_mask
145
+ if new_mask == mask:
146
+ return expr
147
+ if new_mask == 0:
148
+ return Const(expr_idx, None, 0, expr.bits, **expr.tags)
149
+ new_mask_expr = Const(mask_expr.idx, mask_expr.variable, new_mask, mask_expr.bits, **mask_expr.tags)
150
+ return BinaryOp(expr_idx, expr.op, [vvar, new_mask_expr], bits=expr.bits, **expr.tags)
151
+ return super()._handle_BinaryOp(expr_idx, expr, stmt_idx, stmt, block)
152
+
153
+
154
+ class AILSimplifier(Analysis):
155
+ """
156
+ Perform function-level simplifications.
157
+ """
158
+
159
+ def __init__(
160
+ self,
161
+ func,
162
+ func_graph=None,
163
+ remove_dead_memdefs=False,
164
+ stack_arg_offsets: set[tuple[int, int]] | None = None,
165
+ unify_variables=False,
166
+ ail_manager: Manager | None = None,
167
+ gp: int | None = None,
168
+ narrow_expressions=False,
169
+ only_consts=False,
170
+ fold_callexprs_into_conditions=False,
171
+ use_callee_saved_regs_at_return=True,
172
+ rewrite_ccalls=True,
173
+ rename_ccalls=True,
174
+ rewrite_dirty=True,
175
+ removed_vvar_ids: set[int] | None = None,
176
+ arg_vvars: dict[int, tuple[VirtualVariable, SimVariable]] | None = None,
177
+ avoid_vvar_ids: set[int] | None = None,
178
+ secondary_stackvars: set[int] | None = None,
179
+ ):
180
+ self.func = func
181
+ self.func_graph = func_graph if func_graph is not None else func.graph
182
+ self._reaching_definitions: SRDAModel | None = None
183
+ self._propagator: SPropagatorAnalysis | None = None
184
+
185
+ self._remove_dead_memdefs = remove_dead_memdefs
186
+ self._stack_arg_offsets = stack_arg_offsets
187
+ self._unify_vars = unify_variables
188
+ self._ail_manager: Manager | None = ail_manager
189
+ self._gp = gp
190
+ self._narrow_expressions = narrow_expressions
191
+ self._only_consts = only_consts
192
+ self._fold_callexprs_into_conditions = fold_callexprs_into_conditions
193
+ self._use_callee_saved_regs_at_return = use_callee_saved_regs_at_return
194
+ self._should_rewrite_ccalls = rewrite_ccalls
195
+ self._should_rename_ccalls = rename_ccalls
196
+ self._should_rewrite_dirty = rewrite_dirty
197
+ self._removed_vvar_ids = removed_vvar_ids if removed_vvar_ids is not None else set()
198
+ self._arg_vvars = arg_vvars
199
+ self._avoid_vvar_ids = avoid_vvar_ids if avoid_vvar_ids is not None else set()
200
+ self._propagator_dead_vvar_ids: set[int] = set()
201
+ self._secondary_stackvars: set[int] = secondary_stackvars if secondary_stackvars is not None else set()
202
+
203
+ self._calls_to_remove: set[AILCodeLocation] = set()
204
+ self._assignments_to_remove: set[AILCodeLocation] = set()
205
+ self.blocks = {} # Mapping nodes to simplified blocks
206
+
207
+ self.simplified: bool = False
208
+ self._simplify()
209
+
210
+ def _simplify(self):
211
+ if self._narrow_expressions:
212
+ _l.debug("Removing dead assignments before narrowing expressions")
213
+ r = self._iteratively_remove_dead_assignments()
214
+ if r:
215
+ _l.debug("... dead assignments removed")
216
+ self.simplified = True
217
+
218
+ _l.debug("Narrowing expressions")
219
+ narrowed_exprs = self._narrow_exprs()
220
+ self.simplified |= narrowed_exprs
221
+ if narrowed_exprs:
222
+ _l.debug("... expressions narrowed")
223
+ self._rebuild_func_graph()
224
+ self._clear_cache()
225
+
226
+ _l.debug("Folding expressions")
227
+ folded_exprs = self._fold_exprs()
228
+ self.simplified |= folded_exprs
229
+ if folded_exprs:
230
+ _l.debug("... expressions folded")
231
+ self._rebuild_func_graph()
232
+ # reaching definition analysis results are no longer reliable
233
+ self._clear_cache()
234
+
235
+ _l.debug("Propagating partial-constant expressions")
236
+ pconst_propagated = self._propagate_partial_constant_exprs()
237
+ self.simplified |= pconst_propagated
238
+ if pconst_propagated:
239
+ _l.debug("... partial-constant expressions propagated")
240
+ self._rebuild_func_graph()
241
+ # reaching definition analysis results are no longer reliable
242
+ self._clear_cache()
243
+
244
+ _l.debug("Rewriting constant expressions with phi variables")
245
+ phi_const_rewritten = self._rewrite_phi_const_exprs()
246
+ self.simplified |= phi_const_rewritten
247
+ if phi_const_rewritten:
248
+ _l.debug("... constant expressions with phi variables rewritten")
249
+ self._rebuild_func_graph()
250
+ # reaching definition analysis results are no longer reliable
251
+ self._clear_cache()
252
+
253
+ if self._only_consts:
254
+ return
255
+
256
+ _l.debug("Removing dead assignments")
257
+ r = self._iteratively_remove_dead_assignments()
258
+ if r:
259
+ _l.debug("... dead assignments removed")
260
+ self.simplified = True
261
+
262
+ if self._should_rewrite_ccalls:
263
+ _l.debug("Rewriting ccalls")
264
+ ccalls_rewritten = self._rewrite_ccalls()
265
+ self.simplified |= ccalls_rewritten
266
+ if ccalls_rewritten:
267
+ _l.debug("... ccalls rewritten")
268
+ self._rebuild_func_graph()
269
+ self._clear_cache()
270
+
271
+ if self._should_rewrite_dirty:
272
+ _l.debug("Rewriting dirty expressions/statements")
273
+ dirty_rewritten = self._rewrite_dirty_calls()
274
+ self.simplified |= dirty_rewritten
275
+ if dirty_rewritten:
276
+ _l.debug("... dirty expressions/statements rewritten")
277
+ self._rebuild_func_graph()
278
+ self._clear_cache()
279
+
280
+ if self._unify_vars:
281
+ _l.debug("Removing dead assignments")
282
+ r = self._iteratively_remove_dead_assignments()
283
+ if r:
284
+ _l.debug("... dead assignments removed")
285
+ self.simplified = True
286
+
287
+ _l.debug("Unifying local variables")
288
+ r = self._unify_local_variables()
289
+ if r:
290
+ _l.debug("... local variables unified")
291
+ self.simplified = True
292
+ self._rebuild_func_graph()
293
+
294
+ # _fold_call_exprs() may set self._calls_to_remove, which will be honored in _remove_dead_assignments()
295
+ _l.debug("Folding call expressions")
296
+ r = self._fold_call_exprs()
297
+ if r:
298
+ _l.debug("... call expressions folded")
299
+ self.simplified = True
300
+ self._rebuild_func_graph()
301
+ self._clear_cache()
302
+
303
+ _l.debug("Removing dead assignments")
304
+ r = self._iteratively_remove_dead_assignments()
305
+ if r:
306
+ _l.debug("... dead assignments removed")
307
+ self.simplified = True
308
+
309
+ def _rebuild_func_graph(self):
310
+ def _handler(node):
311
+ return self.blocks.get(node, None)
312
+
313
+ AILGraphWalker(self.func_graph, _handler, replace_nodes=True).walk()
314
+ self.blocks = {}
315
+
316
+ def _compute_reaching_definitions(self) -> SRDAModel:
317
+ # Computing reaching definitions or return the cached one
318
+ if self._reaching_definitions is not None:
319
+ return self._reaching_definitions
320
+ func_args = {vvar for vvar, _ in self._arg_vvars.values()} if self._arg_vvars else set()
321
+ rd = (
322
+ self.project.analyses[SReachingDefinitionsAnalysis]
323
+ .prep()(
324
+ subject=self.func,
325
+ func_graph=self.func_graph,
326
+ func_args=func_args,
327
+ use_callee_saved_regs_at_return=self._use_callee_saved_regs_at_return,
328
+ # track_tmps=True,
329
+ )
330
+ .model
331
+ )
332
+ self._reaching_definitions = rd
333
+ return rd
334
+
335
+ @timethis
336
+ def _compute_propagation(self) -> SPropagatorAnalysis:
337
+ # Propagate expressions or return the existing result
338
+ if self._propagator is not None:
339
+ return self._propagator
340
+ func_args = {vvar for vvar, _ in self._arg_vvars.values()} if self._arg_vvars else set()
341
+ prop = self.project.analyses[SPropagatorAnalysis].prep(fail_fast=self._fail_fast)(
342
+ subject=self.func,
343
+ func_graph=self.func_graph,
344
+ func_args=func_args,
345
+ # gp=self._gp,
346
+ only_consts=self._only_consts,
347
+ )
348
+ self._propagator = prop
349
+ self._propagator_dead_vvar_ids = prop.dead_vvar_ids
350
+ return prop
351
+
352
+ @timethis
353
+ def _compute_equivalence(self) -> set[Equivalence]:
354
+ equivalence = set()
355
+ for block in self.func_graph:
356
+ for stmt_idx, stmt in enumerate(block.statements):
357
+ if isinstance(stmt, Assignment):
358
+ if isinstance(stmt.dst, VirtualVariable) and isinstance(
359
+ stmt.src, (VirtualVariable, Tmp, Call, Convert)
360
+ ):
361
+ codeloc = AILCodeLocation(block.addr, block.idx, stmt_idx, stmt.tags.get("ins_addr"))
362
+ equivalence.add(Equivalence(codeloc, stmt.dst, stmt.src))
363
+ elif isinstance(stmt, WeakAssignment):
364
+ codeloc = AILCodeLocation(block.addr, block.idx, stmt_idx, stmt.tags.get("ins_addr"))
365
+ equivalence.add(Equivalence(codeloc, stmt.dst, stmt.src, is_weakassignment=True))
366
+ elif isinstance(stmt, Call):
367
+ if isinstance(stmt.ret_expr, (VirtualVariable, Load)):
368
+ codeloc = AILCodeLocation(block.addr, block.idx, stmt_idx, stmt.tags.get("ins_addr"))
369
+ equivalence.add(Equivalence(codeloc, stmt.ret_expr, stmt))
370
+ elif isinstance(stmt.fp_ret_expr, (VirtualVariable, Load)):
371
+ codeloc = AILCodeLocation(block.addr, block.idx, stmt_idx, stmt.tags.get("ins_addr"))
372
+ equivalence.add(Equivalence(codeloc, stmt.fp_ret_expr, stmt))
373
+ elif (
374
+ isinstance(stmt, Store)
375
+ and isinstance(stmt.size, int)
376
+ and isinstance(stmt.data, (VirtualVariable, Tmp, Call, Convert))
377
+ ):
378
+ if isinstance(stmt.addr, StackBaseOffset) and isinstance(stmt.addr.offset, int):
379
+ # stack variable
380
+ atom = SimStackVariable(stmt.addr.offset, stmt.size)
381
+ codeloc = AILCodeLocation(block.addr, block.idx, stmt_idx, stmt.tags.get("ins_addr"))
382
+ equivalence.add(Equivalence(codeloc, atom, stmt.data))
383
+ elif isinstance(stmt.addr, Const):
384
+ # global variable
385
+ atom = SimMemoryVariable(stmt.addr.value, stmt.size)
386
+ codeloc = AILCodeLocation(block.addr, block.idx, stmt_idx, stmt.tags.get("ins_addr"))
387
+ equivalence.add(Equivalence(codeloc, atom, stmt.data))
388
+ return equivalence
389
+
390
+ def _clear_cache(self) -> None:
391
+ self._propagator = None
392
+ self._reaching_definitions = None
393
+
394
+ def _clear_propagator_cache(self) -> None:
395
+ self._propagator = None
396
+
397
+ def _clear_reaching_definitions_cache(self) -> None:
398
+ self._reaching_definitions = None
399
+
400
+ #
401
+ # Expression narrowing
402
+ #
403
+
404
+ @timethis
405
+ def _narrow_exprs(self) -> bool:
406
+ """
407
+ A register may be used with full width even when only the lower bytes are really needed. This results in the
408
+ incorrect determination of wider variables while the actual variable is narrower (e.g., int64 vs char). This
409
+ optimization narrows a register definition if all its uses are narrower than the definition itself.
410
+
411
+ Note that at this point, we must account for all uses of any narrowed expressions. This means expression
412
+ narrowing must be done _after_ making call sites instead of before making call sites.
413
+ """
414
+
415
+ narrowed = False
416
+
417
+ addr_and_idx_to_block: dict[tuple[int, int | None], Block] = {}
418
+ for block in self.func_graph.nodes():
419
+ addr_and_idx_to_block[(block.addr, block.idx)] = block
420
+
421
+ rd = self._compute_reaching_definitions()
422
+ sorted_defs = sorted(rd.all_definitions, key=lambda d: d.codeloc, reverse=True)
423
+
424
+ # compute effective sizes for each vvar
425
+ effective_sizes = self._compute_effective_sizes(rd, sorted_defs, addr_and_idx_to_block)
426
+
427
+ narrowing_candidates: dict[int, tuple[Definition, ExprNarrowingInfo]] = {}
428
+ for def_ in sorted_defs:
429
+ if isinstance(def_.atom, atoms.VirtualVariable) and (def_.atom.was_reg or def_.atom.was_parameter):
430
+ # only do this for general purpose register
431
+ skip_def = False
432
+ reg = None
433
+ for reg in self.project.arch.register_list:
434
+ if reg.vex_offset == def_.atom.reg_offset:
435
+ if not reg.artificial and not reg.general_purpose and not reg.vector:
436
+ skip_def = True
437
+ break
438
+
439
+ if skip_def:
440
+ continue
441
+
442
+ narrow = self._narrowing_needed(def_, rd, addr_and_idx_to_block, effective_sizes)
443
+ if narrow.narrowable:
444
+ # we cannot narrow it immediately because any definition that is used by phi variables must be
445
+ # narrowed together with all other definitions that can reach the phi variables.
446
+ # so we record the information and decide if we are going to narrow these expressions or not at the
447
+ # end of the loop.
448
+ narrowing_candidates[def_.atom.varid] = def_, narrow
449
+
450
+ # first, determine which phi vars need to be narrowed and can be narrowed.
451
+ # a phi var can only be narrowed if all its source vvars are narrowable
452
+ vvar_to_narrowing_size = {}
453
+ for def_varid, (_, narrow_info) in narrowing_candidates.items():
454
+ vvar_to_narrowing_size[def_varid] = narrow_info.to_size
455
+
456
+ blacklist_varids = set()
457
+ while True:
458
+ repeat, narrowables = self._compute_narrowables_once(
459
+ rd, narrowing_candidates, vvar_to_narrowing_size, blacklist_varids
460
+ )
461
+ if not repeat:
462
+ break
463
+
464
+ if not narrowables:
465
+ # nothing to narrow
466
+ return False
467
+
468
+ # let's narrow them (finally)
469
+ narrower = ExpressionNarrower(self.project, rd, narrowables, addr_and_idx_to_block, self.blocks)
470
+ for old_block in addr_and_idx_to_block.values():
471
+ new_block = self.blocks.get(old_block, old_block)
472
+ new_block = narrower.walk(new_block)
473
+ if narrower.narrowed_any:
474
+ narrowed = True
475
+ self.blocks[old_block] = new_block
476
+
477
+ # update self._arg_vvars if necessary
478
+ for new_vvars in narrower.replacement_core_vvars.values():
479
+ for new_vvar in new_vvars:
480
+ if new_vvar.was_parameter and self._arg_vvars:
481
+ for func_arg_idx in list(self._arg_vvars):
482
+ vvar, simvar = self._arg_vvars[func_arg_idx]
483
+ if vvar.varid == new_vvar.varid:
484
+ simvar_new = simvar.copy()
485
+ simvar_new._hash = None
486
+ simvar_new.size = new_vvar.size
487
+ self._arg_vvars[func_arg_idx] = new_vvar, simvar_new
488
+
489
+ return narrowed
490
+
491
+ def _compute_effective_sizes(self, rd, defs, addr_and_idx_to_block) -> dict[int, int]:
492
+
493
+ vvar_effective_sizes: dict[int, int] = {}
494
+
495
+ # determine effective sizes for non-phi vvars
496
+ for def_ in defs:
497
+ # find its def statement
498
+ old_block = addr_and_idx_to_block.get((def_.codeloc.block_addr, def_.codeloc.block_idx), None)
499
+ if old_block is None:
500
+ continue
501
+ block = self.blocks.get(old_block, old_block)
502
+ if def_.codeloc.stmt_idx is None or def_.codeloc.stmt_idx >= len(block.statements):
503
+ continue
504
+ def_stmt = block.statements[def_.codeloc.stmt_idx]
505
+ if (
506
+ isinstance(def_stmt, Assignment)
507
+ and isinstance(def_stmt.src, Convert)
508
+ and not def_stmt.src.is_signed
509
+ and def_stmt.src.from_type == Convert.TYPE_INT
510
+ and def_stmt.src.to_type == Convert.TYPE_INT
511
+ and def_stmt.src.from_bits < def_stmt.src.to_bits
512
+ ):
513
+ effective_size = def_stmt.src.from_bits // self.project.arch.byte_width
514
+ vvar_effective_sizes[def_.atom.varid] = effective_size
515
+
516
+ # update effective sizes for phi vvars
517
+ changed = True
518
+ while changed:
519
+ changed = False
520
+ for phi_vvar in rd.phivarid_to_varids:
521
+ if phi_vvar in vvar_effective_sizes:
522
+ continue
523
+ if rd.phivarid_to_varids[phi_vvar] and all(
524
+ src_vvar in vvar_effective_sizes for src_vvar in rd.phivarid_to_varids[phi_vvar]
525
+ ):
526
+ effective_size = max(vvar_effective_sizes[src_vvar] for src_vvar in rd.phivarid_to_varids[phi_vvar])
527
+ vvar_effective_sizes[phi_vvar] = effective_size
528
+ changed = True
529
+
530
+ return vvar_effective_sizes
531
+
532
+ @staticmethod
533
+ def _compute_narrowables_once(
534
+ rd, narrowing_candidates: dict, vvar_to_narrowing_size: dict[int, int], blacklist_varids: set
535
+ ):
536
+ repeat = False
537
+ narrowable_phivarids = set()
538
+ for def_vvarid in narrowing_candidates:
539
+ if def_vvarid in blacklist_varids:
540
+ continue
541
+ if def_vvarid in rd.phi_vvar_ids:
542
+ narrowing_sizes = set()
543
+ src_vvarids = rd.phivarid_to_varids[def_vvarid]
544
+ for vvarid in src_vvarids:
545
+ if vvarid in blacklist_varids:
546
+ narrowing_sizes.add(None)
547
+ else:
548
+ narrowing_sizes.add(vvar_to_narrowing_size.get(vvarid))
549
+ if len(narrowing_sizes) == 1 and None not in narrowing_sizes:
550
+ # we can narrow this phi vvar!
551
+ narrowable_phivarids.add(def_vvarid)
552
+ else:
553
+ # blacklist it for now
554
+ blacklist_varids.add(def_vvarid)
555
+
556
+ # now determine what to narrow!
557
+ narrowables = []
558
+
559
+ for def_, narrow_info in narrowing_candidates.values():
560
+ if def_.atom.varid in blacklist_varids:
561
+ continue
562
+ if not narrow_info.phi_vars:
563
+ # not used by any other phi variables. good!
564
+ narrowables.append((def_, narrow_info))
565
+ else:
566
+ if {phivar.varid for phivar in narrow_info.phi_vars}.issubset(narrowable_phivarids):
567
+ # all phi vvars that use this definition can be narrowed
568
+ narrowables.append((def_, narrow_info))
569
+ else:
570
+ # this vvar cannot be narrowed
571
+ # note that all phi variables that relies on this vvar also cannot be narrowed! we must analyze
572
+ # again
573
+ repeat = True
574
+ blacklist_varids.add(def_.atom.varid)
575
+ blacklist_varids |= {phivar.varid for phivar in narrow_info.phi_vars}
576
+
577
+ return repeat, narrowables
578
+
579
+ def _narrowing_needed(
580
+ self, def_: Definition, rd: SRDAModel, addr_and_idx_to_block, effective_sizes: dict[int, int]
581
+ ) -> ExprNarrowingInfo:
582
+
583
+ def_size = def_.size
584
+ # find its uses
585
+ # some use locations are phi assignments. we keep tracking the uses of phi variables and update the dictionary
586
+ result = self._get_vvar_use_and_exprs_recursive(def_.atom, rd, addr_and_idx_to_block)
587
+ if result is None:
588
+ return ExprNarrowingInfo(False)
589
+ use_and_exprs, phi_vars = result
590
+
591
+ all_used_sizes = set()
592
+ noncall_used_sizes = set()
593
+ used_by: list[tuple[atoms.VirtualVariable, AILCodeLocation, tuple[str, tuple[Expression, ...]]]] = []
594
+ used_by_loc = defaultdict(list)
595
+
596
+ for atom, loc, expr in use_and_exprs:
597
+ old_block = addr_and_idx_to_block.get((loc.block_addr, loc.block_idx), None)
598
+ if old_block is None:
599
+ # missing a block for whatever reason
600
+ return ExprNarrowingInfo(False)
601
+
602
+ block = self.blocks.get(old_block, old_block)
603
+ assert loc.stmt_idx is not None
604
+ if loc.stmt_idx >= len(block.statements):
605
+ # missing a statement for whatever reason
606
+ return ExprNarrowingInfo(False)
607
+ stmt = block.statements[loc.stmt_idx]
608
+
609
+ # special case: if the statement is a Call statement and expr is None, it means we have not been able to
610
+ # determine if the expression is really used by the call or not. skip it in this case
611
+ if isinstance(stmt, Call) and expr is None:
612
+ all_used_sizes.add(atom.size)
613
+ continue
614
+ # special case: if the statement is a phi statement, we ignore it
615
+ if is_phi_assignment(stmt):
616
+ continue
617
+ # special case: if the statement is an assignment to a destination vvar A, and the source is the bitwise-or
618
+ # of two expressions where one of them is the high bits of expr, and expr is a phi var that relies on
619
+ # vvar A, then we skip it.
620
+ if is_expr_used_as_reg_base_value(stmt, expr, rd):
621
+ continue
622
+
623
+ expr_size, used_by_exprs = self._extract_expression_effective_size(stmt, expr)
624
+ if expr_size is None:
625
+ # it's probably used in full width
626
+ return ExprNarrowingInfo(False)
627
+
628
+ all_used_sizes.add(expr_size)
629
+ if not isinstance(stmt, Call):
630
+ noncall_used_sizes.add(expr_size)
631
+ used_by_loc[loc].append((atom, used_by_exprs))
632
+
633
+ target_size = None
634
+ if len(all_used_sizes) >= 1 and max(all_used_sizes) < def_size:
635
+ target_size = max(all_used_sizes)
636
+ else:
637
+ effective_size = effective_sizes.get(def_.atom.varid, None)
638
+ if (
639
+ effective_size is not None
640
+ and any(used_size <= effective_size for used_size in all_used_sizes)
641
+ and all(used_size <= effective_size for used_size in noncall_used_sizes)
642
+ ):
643
+ # special case: sometimes we have an explicit Convert that narrows the value, all other uses are either
644
+ # in the effective size or narrower, but we pass the full register to a function call as an argument
645
+ # because we do not know the real type of the argument, or there are cases like putchar(int ch) while
646
+ # ch is actually a char. We use effective size in such cases to narrow the variable.
647
+ target_size = effective_size
648
+
649
+ if target_size is not None:
650
+ for loc, atom_expr_pairs in used_by_loc.items():
651
+ if len(atom_expr_pairs) == 1:
652
+ atom, used_by_exprs = atom_expr_pairs[0]
653
+ used_by.append((atom, loc, used_by_exprs))
654
+ else:
655
+ # the order matters - we must replace the outer expressions first, then replace the inner
656
+ # expressions. replacing in the wrong order will lead to expressions that are not replaced in the
657
+ # end.
658
+ ordered = []
659
+ for atom, used_by_exprs in atom_expr_pairs:
660
+ last_inclusion = len(ordered) - 1 # by default we append at the end of the list
661
+ for idx in range(len(ordered)):
662
+ if self._is_expr0_included_in_expr1(ordered[idx][1], used_by_exprs):
663
+ # this element must be inserted before idx
664
+ ordered.insert(idx, (atom, used_by_exprs))
665
+ break
666
+ if self._is_expr0_included_in_expr1(used_by_exprs, ordered[idx][1]):
667
+ # this element can be inserted after this element. record the index
668
+ last_inclusion = idx
669
+ else:
670
+ ordered.insert(last_inclusion + 1, (atom, used_by_exprs))
671
+
672
+ for atom, used_by_exprs in ordered:
673
+ used_by.append((atom, loc, used_by_exprs))
674
+
675
+ return ExprNarrowingInfo(True, to_size=target_size, use_exprs=used_by, phi_vars=phi_vars)
676
+
677
+ return ExprNarrowingInfo(False)
678
+
679
+ @staticmethod
680
+ def _exprs_from_used_by_exprs(used_by_exprs) -> set[Expression]:
681
+ use_type, expr_tuple = used_by_exprs
682
+ match use_type:
683
+ case "expr" | "mask" | "convert":
684
+ return {expr_tuple[1]} if len(expr_tuple) == 2 else {expr_tuple[0]}
685
+ case "phi-src-expr":
686
+ return {expr_tuple[0]}
687
+ case "binop-convert":
688
+ return {expr_tuple[0], expr_tuple[1]}
689
+ case _:
690
+ return set()
691
+
692
+ def _is_expr0_included_in_expr1(self, used_by_exprs0, used_by_exprs1) -> bool:
693
+ # extract expressions
694
+ exprs0 = self._exprs_from_used_by_exprs(used_by_exprs0)
695
+ exprs1 = self._exprs_from_used_by_exprs(used_by_exprs1)
696
+
697
+ # test for inclusion
698
+ for expr1 in exprs1:
699
+ walker = HasExprWalker(exprs0)
700
+ walker.walk_expression(expr1)
701
+ if walker.contains_exprs:
702
+ return True
703
+ return False
704
+
705
+ def _get_vvar_use_and_exprs_recursive(
706
+ self, initial_atom: atoms.VirtualVariable, rd, block_dict: dict[tuple[int, int | None], Block]
707
+ ) -> tuple[list[tuple[atoms.VirtualVariable, AILCodeLocation, Expression]], set[VirtualVariable]] | None:
708
+ result = []
709
+ atom_queue = [initial_atom]
710
+ phi_vars = set()
711
+ seen = set()
712
+ while atom_queue:
713
+ atom = atom_queue.pop(0)
714
+ seen.add(atom)
715
+
716
+ expr_and_uses = rd.all_vvar_uses[atom.varid]
717
+
718
+ for expr, loc in set(expr_and_uses):
719
+ old_block = block_dict.get((loc.block_addr, loc.block_idx), None)
720
+ if old_block is None:
721
+ # missing a block for whatever reason
722
+ return None
723
+
724
+ block: Block = self.blocks.get(old_block, old_block)
725
+ if loc.stmt_idx >= len(block.statements):
726
+ # missing a statement for whatever reason
727
+ return None
728
+ stmt = block.statements[loc.stmt_idx]
729
+
730
+ if is_phi_assignment(stmt):
731
+ phi_vars.add(stmt.dst)
732
+ new_atom = atoms.VirtualVariable(
733
+ stmt.dst.varid, stmt.dst.size, stmt.dst.category, oident=stmt.dst.oident
734
+ )
735
+ if new_atom not in seen:
736
+ atom_queue.append(new_atom)
737
+ seen.add(new_atom)
738
+ else:
739
+ result.append((atom, loc, expr))
740
+ return result, phi_vars
741
+
742
+ def _extract_expression_effective_size(
743
+ self, statement, expr
744
+ ) -> tuple[int | None, tuple[str, tuple[Expression, ...]] | None]:
745
+ """
746
+ Determine the effective size of an expression when it's used.
747
+ """
748
+
749
+ walker = NarrowingInfoExtractor(expr)
750
+ walker.walk_statement(statement)
751
+ if not walker.operations:
752
+ if expr is None:
753
+ return None, None
754
+ return expr.size, ("expr", (expr,))
755
+
756
+ ops = walker.operations
757
+ first_op = ops[0]
758
+ if isinstance(first_op, BinaryOp) and first_op.op in {"Add", "Sub"}:
759
+ # expr + x
760
+ ops = ops[1:]
761
+ if not ops:
762
+ if expr is None:
763
+ return None, None
764
+ return expr.size, ("expr", (expr,))
765
+ first_op = ops[0]
766
+ if isinstance(first_op, Convert) and first_op.to_bits >= self.project.arch.byte_width:
767
+ # we need at least one byte!
768
+ if (
769
+ len({(op.from_bits, op.to_bits) for op in ops if isinstance(op, Convert) and op.operand.likes(expr)})
770
+ > 1
771
+ ):
772
+ # there are more Convert operations; it's probably because there are multiple expressions involving the
773
+ # same core expr. just give up (for now)
774
+ return None, None
775
+ if any(op for op in ops if isinstance(op, BinaryOp) and op.op == "Shr" and op.operands[0].likes(expr)):
776
+ # the expression is right-shifted, which means higher bits might be used.
777
+ return None, None
778
+ return first_op.to_bits // self.project.arch.byte_width, ("convert", (first_op,))
779
+ if isinstance(first_op, BinaryOp):
780
+ second_op = None
781
+ if len(ops) >= 2:
782
+ second_op = ops[1]
783
+ if (
784
+ first_op.op == "And"
785
+ and isinstance(first_op.operands[1], Const)
786
+ and (
787
+ second_op is None or (isinstance(second_op, BinaryOp) and isinstance(second_op.operands[1], Const))
788
+ )
789
+ ):
790
+ mask = first_op.operands[1].value
791
+ if mask == 0xFF:
792
+ return 1, ("mask", (first_op, second_op)) if second_op is not None else ("mask", (first_op,))
793
+ if mask == 0xFFFF:
794
+ return 2, ("mask", (first_op, second_op)) if second_op is not None else ("mask", (first_op,))
795
+ if mask == 0xFFFF_FFFF:
796
+ return 4, ("mask", (first_op, second_op)) if second_op is not None else ("mask", (first_op,))
797
+ if (
798
+ (first_op.operands[0] is expr or first_op.operands[1] is expr)
799
+ and first_op.op not in {"Shr", "Sar"}
800
+ and isinstance(second_op, Convert)
801
+ and second_op.from_bits == expr.bits
802
+ and second_op.to_bits >= self.project.arch.byte_width # we need at least one byte!
803
+ ):
804
+ return min(expr.bits, second_op.to_bits) // self.project.arch.byte_width, (
805
+ "binop-convert",
806
+ (expr, first_op, second_op),
807
+ )
808
+
809
+ if expr is None:
810
+ return None, None
811
+ return expr.size, ("expr", (expr,))
812
+
813
+ #
814
+ # Expression folding
815
+ #
816
+
817
+ def _fold_exprs(self):
818
+ """
819
+ Fold expressions: Fold assigned expressions that are constant or only used once.
820
+ """
821
+
822
+ # propagator
823
+ propagator = self._compute_propagation()
824
+ replacements = propagator.replacements
825
+
826
+ # take replacements and rebuild the corresponding blocks
827
+ replacements_by_block_addrs_and_idx = defaultdict(dict)
828
+ for codeloc, reps in replacements.items():
829
+ if reps:
830
+ replacements_by_block_addrs_and_idx[(codeloc.block_addr, codeloc.block_idx)][codeloc] = reps
831
+
832
+ if not replacements_by_block_addrs_and_idx:
833
+ return False
834
+
835
+ return self._replace_exprs_in_blocks(replacements_by_block_addrs_and_idx)
836
+
837
+ def _replace_exprs_in_blocks(
838
+ self, replacements: dict[tuple[int, int | None], dict[AILCodeLocation, dict[Expression, Expression]]]
839
+ ) -> bool:
840
+ blocks_by_addr_and_idx = {(node.addr, node.idx): node for node in self.func_graph.nodes()}
841
+
842
+ if self._stack_arg_offsets:
843
+ insn_addrs_using_stack_args = {ins_addr for ins_addr, _ in self._stack_arg_offsets}
844
+ else:
845
+ insn_addrs_using_stack_args = None
846
+
847
+ replaced = False
848
+ for (block_addr, block_idx), reps in replacements.items():
849
+ block = blocks_by_addr_and_idx[(block_addr, block_idx)]
850
+
851
+ # only replace loads if there are stack arguments in this block
852
+ replace_loads: bool = insn_addrs_using_stack_args is not None and bool(
853
+ {stmt.tags["ins_addr"] for stmt in block.statements}.intersection(insn_addrs_using_stack_args)
854
+ )
855
+
856
+ # remove virtual variables in the avoid list
857
+ if self._avoid_vvar_ids:
858
+ filtered_reps = {}
859
+ for loc, rep_dict in reps.items():
860
+ filtered_reps[loc] = {
861
+ k: v
862
+ for k, v in rep_dict.items()
863
+ if not (isinstance(k, VirtualVariable) and k.varid in self._avoid_vvar_ids)
864
+ }
865
+ reps = filtered_reps
866
+
867
+ r, new_block = BlockSimplifier._replace_and_build(block, reps, gp=self._gp, replace_loads=replace_loads)
868
+ replaced |= r
869
+ self.blocks[block] = new_block
870
+
871
+ if replaced:
872
+ # blocks have been rebuilt - expression propagation results are no longer reliable
873
+ self._clear_cache()
874
+ return replaced
875
+
876
+ #
877
+ # Partial constant expression propagation
878
+ #
879
+
880
+ def _propagate_partial_constant_exprs(self) -> bool:
881
+ """
882
+ Discover virtual variables whose certain consecutive bits are constant and propagate these bits.
883
+ """
884
+
885
+ # vvar_zero_bits[varid] = N ==> the high N bits of vvar varid are 0s
886
+ vvar_zero_bits: dict[int, int] = {}
887
+
888
+ # go over all vvar definitions and find the ones with partial constants
889
+ for block in self.func_graph:
890
+ for stmt in block.statements:
891
+ if (
892
+ isinstance(stmt, Assignment)
893
+ and isinstance(stmt.dst, VirtualVariable)
894
+ and isinstance(stmt.src, Convert)
895
+ and stmt.src.to_bits > stmt.src.from_bits
896
+ ):
897
+ # this is a conversion from a wider to a narrower type; the top N bits are 0s
898
+ vvar_zero_bits[stmt.dst.varid] = stmt.src.to_bits - stmt.src.from_bits
899
+
900
+ if not vvar_zero_bits:
901
+ return False
902
+
903
+ # now replace the uses of these vvars
904
+ addr_and_idx_to_block: dict[tuple[int, int | None], Block] = {}
905
+ for block in self.func_graph:
906
+ addr_and_idx_to_block[(block.addr, block.idx)] = block
907
+
908
+ rda = self._compute_reaching_definitions()
909
+ changed = False
910
+ for vvarid, zero_high_bits in vvar_zero_bits.items():
911
+ rewriter = PartialConstantExprRewriter(vvarid, zero_high_bits)
912
+ for _, use_loc in rda.all_vvar_uses[vvarid]:
913
+ assert use_loc.block_addr is not None
914
+ original_block = addr_and_idx_to_block[(use_loc.block_addr, use_loc.block_idx)]
915
+ block = self.blocks.get(original_block, original_block)
916
+ stmt = block.statements[use_loc.stmt_idx]
917
+ new_stmt = rewriter.walk_statement(stmt, block)
918
+
919
+ if new_stmt is not None and new_stmt is not stmt:
920
+ statements = block.statements[::]
921
+ statements[use_loc.stmt_idx] = new_stmt
922
+ new_block = block.copy(statements=statements)
923
+
924
+ self.blocks[original_block] = new_block
925
+ changed = True
926
+
927
+ return changed
928
+
929
+ #
930
+ # Rewriting constant expressions with phi variables
931
+ #
932
+
933
+ def _rewrite_phi_const_exprs(self) -> bool:
934
+ """
935
+ Rewrite phi variables that are definitely constant expressions to constants.
936
+ """
937
+
938
+ # gather constant assignments
939
+
940
+ vvar_values: dict[int, tuple[int, int]] = {}
941
+ for block in self.func_graph:
942
+ for stmt in block.statements:
943
+ if (
944
+ isinstance(stmt, Assignment)
945
+ and isinstance(stmt.dst, VirtualVariable)
946
+ and stmt.dst.was_reg # values of stack variables might be updated in callees or via pointers
947
+ and isinstance(stmt.src, Const)
948
+ and isinstance(stmt.src.value, int)
949
+ ):
950
+ vvar_values[stmt.dst.varid] = stmt.src.value, stmt.src.bits
951
+
952
+ srda = self._compute_reaching_definitions()
953
+ # compute vvar reachability for phi variables
954
+ # ensure that each phi variable is fully defined, i.e., all its source variables are defined
955
+ g = networkx.Graph()
956
+ for phi_vvar_id, vvar_ids in srda.phivarid_to_varids_with_unknown.items():
957
+ for vvar_id in vvar_ids:
958
+ # we cannot store None to networkx graph, so we use -1 to represent unknown source vvars
959
+ g.add_edge(phi_vvar_id, vvar_id if vvar_id is not None else -1)
960
+
961
+ phi_vvar_ids = srda.phi_vvar_ids
962
+ to_replace = {}
963
+ for cc in networkx.algorithms.connected_components(g):
964
+ if -1 in cc:
965
+ continue
966
+ normal_vvar_ids = cc.difference(phi_vvar_ids)
967
+ # ensure there is at least one phi variable and all remaining vvars are constant non-phi variables
968
+ if len(normal_vvar_ids) < len(cc) and len(normal_vvar_ids.intersection(vvar_values)) == len(
969
+ normal_vvar_ids
970
+ ):
971
+ all_values = {vvar_values[vvar_id] for vvar_id in normal_vvar_ids}
972
+ if len(all_values) == 1:
973
+ # found it!
974
+ value, bits = next(iter(all_values))
975
+ for var_id in cc:
976
+ to_replace[var_id] = value, bits
977
+
978
+ # build the replacement dictionary
979
+ blocks_dict = {(node.addr, node.idx): node for node in self.func_graph.nodes()}
980
+ replacements: dict[tuple[int, int | None], dict[AILCodeLocation, dict[Expression, Expression]]] = defaultdict(
981
+ dict
982
+ )
983
+ for vvar_id, (value, bits) in to_replace.items():
984
+ for expr, use_loc in srda.all_vvar_uses[vvar_id]:
985
+ if expr is None:
986
+ continue
987
+ assert use_loc.block_addr is not None
988
+ key = use_loc.block_addr, use_loc.block_idx
989
+ stmt = blocks_dict[key].statements[use_loc.stmt_idx]
990
+ if is_phi_assignment(stmt):
991
+ continue
992
+ if use_loc not in replacements[key]:
993
+ replacements[key][use_loc] = {}
994
+ replacements[key][use_loc][expr] = Const(None, None, value, bits, **expr.tags)
995
+
996
+ return self._replace_exprs_in_blocks(replacements) if replacements else False
997
+
998
+ #
999
+ # Unifying local variables
1000
+ #
1001
+
1002
+ @timethis
1003
+ def _unify_local_variables(self) -> bool:
1004
+ """
1005
+ Find variables that are definitely equivalent and then eliminate unnecessary copies.
1006
+ """
1007
+
1008
+ simplified = False
1009
+
1010
+ equivalence = self._compute_equivalence()
1011
+ if not equivalence:
1012
+ return simplified
1013
+
1014
+ addr_and_idx_to_block: dict[tuple[int, int | None], Block] = {}
1015
+ for block in self.func_graph.nodes():
1016
+ addr_and_idx_to_block[(block.addr, block.idx)] = block
1017
+
1018
+ equivalences: dict[Any, set[Equivalence]] = defaultdict(set)
1019
+ atom_by_loc = set()
1020
+ for eq in equivalence:
1021
+ equivalences[eq.atom1].add(eq)
1022
+ atom_by_loc.add((eq.codeloc, eq.atom1))
1023
+
1024
+ # sort keys to ensure a reproducible result
1025
+ sorted_loc_and_atoms = sorted(atom_by_loc, key=lambda x: x[0])
1026
+
1027
+ # keep track of code locations where the statements have been updated; we can then skip Equivalences that are
1028
+ # out-of-date
1029
+ updated_locs: set[AILCodeLocation] = set()
1030
+
1031
+ for _, atom in sorted_loc_and_atoms:
1032
+ eqs = equivalences[atom]
1033
+ if len(eqs) > 1:
1034
+ continue
1035
+
1036
+ eq = next(iter(eqs))
1037
+ if eq.codeloc in updated_locs:
1038
+ continue
1039
+
1040
+ # Acceptable equivalence classes:
1041
+ #
1042
+ # stack variable == register
1043
+ # register variable == register
1044
+ # stack variable == Conv(register, M->N)
1045
+ # global variable == register
1046
+ #
1047
+ # Equivalence is generally created at assignment sites. Therefore, eq.atom0 is the definition and
1048
+ # eq.atom1 is the use.
1049
+ the_def = None
1050
+ if (isinstance(eq.atom0, VirtualVariable) and eq.atom0.was_stack) or (
1051
+ isinstance(eq.atom0, SimMemoryVariable)
1052
+ and not isinstance(eq.atom0, SimStackVariable)
1053
+ and isinstance(eq.atom0.addr, int)
1054
+ ):
1055
+ if isinstance(eq.atom1, VirtualVariable) and eq.atom1.was_reg:
1056
+ # stack_var == register or global_var == register
1057
+ to_replace = eq.atom1
1058
+ to_replace_is_def = False
1059
+ elif (
1060
+ isinstance(eq.atom0, VirtualVariable)
1061
+ and eq.atom0.was_stack
1062
+ and isinstance(eq.atom1, VirtualVariable)
1063
+ and eq.atom1.was_parameter
1064
+ ):
1065
+ # stack_var == parameter
1066
+ to_replace = eq.atom0
1067
+ to_replace_is_def = True
1068
+ elif (
1069
+ isinstance(eq.atom1, Convert)
1070
+ and isinstance(eq.atom1.operand, VirtualVariable)
1071
+ and eq.atom1.operand.was_reg
1072
+ ):
1073
+ # stack_var == Conv(register, M->N)
1074
+ to_replace = eq.atom1.operand
1075
+ to_replace_is_def = False
1076
+ else:
1077
+ continue
1078
+
1079
+ elif isinstance(eq.atom0, VirtualVariable) and eq.atom0.was_reg:
1080
+ if isinstance(eq.atom1, VirtualVariable):
1081
+ if eq.atom1.was_reg or eq.atom1.was_parameter:
1082
+ # register == register
1083
+ if self.project.arch.is_artificial_register(eq.atom0.reg_offset, eq.atom0.size):
1084
+ to_replace = eq.atom0
1085
+ to_replace_is_def = True
1086
+ else:
1087
+ to_replace = eq.atom1
1088
+ to_replace_is_def = False
1089
+ elif eq.atom1.was_stack:
1090
+ # register == stack (but we try to replace the register vvar with the stack vvar)
1091
+ to_replace = eq.atom0
1092
+ to_replace_is_def = True
1093
+ else:
1094
+ continue
1095
+ else:
1096
+ continue
1097
+
1098
+ else:
1099
+ continue
1100
+
1101
+ assert isinstance(to_replace, VirtualVariable)
1102
+
1103
+ # find the definition of this virtual register
1104
+ rd = self._compute_reaching_definitions()
1105
+ if to_replace_is_def:
1106
+ # find defs
1107
+ defs: Container[Definition[atoms.VirtualVariable, AILCodeLocation]] = []
1108
+ for def_ in rd.all_definitions:
1109
+ if def_.atom.varid == to_replace.varid:
1110
+ defs.append(def_)
1111
+ if len(defs) != 1:
1112
+ continue
1113
+ the_def = defs[0]
1114
+ else:
1115
+ # find uses
1116
+ defs = rd.get_uses_by_location(eq.codeloc)
1117
+ if len(defs) != 1:
1118
+ # there are multiple defs for this register - we do not support replacing all of them
1119
+ continue
1120
+ for def_ in defs:
1121
+ if (
1122
+ isinstance(def_.atom, atoms.VirtualVariable)
1123
+ and def_.atom.category == to_replace.category
1124
+ and def_.atom.oident == to_replace.oident
1125
+ ):
1126
+ # found it!
1127
+ the_def = def_
1128
+ break
1129
+ if the_def is None:
1130
+ continue
1131
+
1132
+ def_eq_rel: DefEqRelation = DefEqRelation.UNKNOWN
1133
+ if the_def.codeloc.is_extern or (isinstance(eq.atom1, VirtualVariable) and eq.atom1.was_parameter):
1134
+ # this is a function argument. we enter a slightly different logic and try to eliminate copies of this
1135
+ # argument if
1136
+ # (a) the on-stack or in-register copy of it has never been modified in this function
1137
+ # (b) the function argument register has never been updated.
1138
+ # TODO: we may loosen requirement (b) once we have real register versioning in AIL.
1139
+ defs = [def_ for def_ in rd.all_definitions if def_.codeloc == eq.codeloc]
1140
+ all_uses_with_def = None
1141
+ replace_with = None
1142
+ remove_initial_assignment = None
1143
+ def_eq_rel = DefEqRelation.DEF_IS_FUNCARG
1144
+
1145
+ if defs and len(defs) == 1:
1146
+ arg_copy_def = defs[0]
1147
+ if (isinstance(arg_copy_def.atom, atoms.VirtualVariable) and arg_copy_def.atom.was_stack) or (
1148
+ isinstance(arg_copy_def.atom, atoms.VirtualVariable) and arg_copy_def.atom.was_reg
1149
+ ):
1150
+ # found the copied definition (either a stack variable or a register variable)
1151
+
1152
+ # Make sure there is no other write to this stack location if the copy is a stack variable
1153
+ if (
1154
+ isinstance(arg_copy_def.atom, atoms.VirtualVariable)
1155
+ and arg_copy_def.atom.was_stack
1156
+ and any(
1157
+ (def_ != arg_copy_def and def_.atom.stack_offset == arg_copy_def.atom.stack_offset)
1158
+ for def_ in rd.all_definitions
1159
+ if isinstance(def_.atom, atoms.VirtualVariable) and def_.atom.was_stack
1160
+ )
1161
+ ):
1162
+ continue
1163
+
1164
+ # Make sure the register is never updated across this function
1165
+ if any(
1166
+ (def_ != the_def and def_.atom == the_def.atom)
1167
+ for def_ in rd.all_definitions
1168
+ if isinstance(def_.atom, atoms.VirtualVariable)
1169
+ and def_.atom.was_reg
1170
+ and rd.get_vvar_uses(def_.atom)
1171
+ ):
1172
+ continue
1173
+
1174
+ # find all its uses
1175
+ all_arg_copy_var_uses = rd.get_vvar_uses_with_expr(arg_copy_def.atom)
1176
+ all_uses_with_def = set()
1177
+
1178
+ should_abort = False
1179
+ for use in all_arg_copy_var_uses:
1180
+ used_expr = use[0]
1181
+ if used_expr is not None and used_expr.size != arg_copy_def.size:
1182
+ should_abort = True
1183
+ break
1184
+ all_uses_with_def.add((arg_copy_def, use))
1185
+ if should_abort:
1186
+ continue
1187
+
1188
+ replace_with = eq.atom1
1189
+ remove_initial_assignment = True
1190
+
1191
+ if all_uses_with_def is None:
1192
+ continue
1193
+
1194
+ else:
1195
+ if (
1196
+ eq.codeloc.block_addr == the_def.codeloc.block_addr
1197
+ and eq.codeloc.block_idx == the_def.codeloc.block_idx
1198
+ ):
1199
+ # the definition and the eq location are within the same block, and the definition is before
1200
+ # the eq location.
1201
+ if eq.codeloc.stmt_idx < the_def.codeloc.stmt_idx:
1202
+ continue
1203
+ def_eq_rel = DefEqRelation.DEF_EQ_SAME_BLOCK
1204
+ else:
1205
+ # the definition is in the predecessor block of the eq
1206
+ eq_block = next(
1207
+ iter(
1208
+ bb
1209
+ for bb in self.func_graph
1210
+ if bb.addr == eq.codeloc.block_addr and bb.idx == eq.codeloc.block_idx
1211
+ )
1212
+ )
1213
+ eq_block_preds = set(self.func_graph.predecessors(eq_block))
1214
+ if not any(
1215
+ pred.addr == the_def.codeloc.block_addr and pred.idx == the_def.codeloc.block_idx
1216
+ for pred in eq_block_preds
1217
+ ):
1218
+ continue
1219
+ def_eq_rel = DefEqRelation.DEF_IN_EQ_PRED_BLOCK
1220
+
1221
+ if isinstance(eq.atom0, VirtualVariable) and eq.atom0.was_stack:
1222
+ # create the replacement expression
1223
+ if isinstance(eq.atom1, VirtualVariable) and eq.atom1.was_parameter:
1224
+ # replacing atom0
1225
+ new_idx = None if self._ail_manager is None else next(self._ail_manager.atom_ctr)
1226
+ replace_with = VirtualVariable(
1227
+ new_idx,
1228
+ eq.atom1.varid,
1229
+ eq.atom1.bits,
1230
+ category=eq.atom1.category,
1231
+ oident=eq.atom1.oident,
1232
+ **eq.atom1.tags,
1233
+ )
1234
+ else:
1235
+ # replacing atom1
1236
+ new_idx = None if self._ail_manager is None else next(self._ail_manager.atom_ctr)
1237
+ replace_with = VirtualVariable(
1238
+ new_idx,
1239
+ eq.atom0.varid,
1240
+ eq.atom0.bits,
1241
+ category=eq.atom0.category,
1242
+ oident=eq.atom0.oident,
1243
+ **eq.atom0.tags,
1244
+ )
1245
+ elif isinstance(eq.atom0, SimMemoryVariable) and isinstance(eq.atom0.addr, int):
1246
+ # create the memory loading expression
1247
+ new_idx = None if self._ail_manager is None else next(self._ail_manager.atom_ctr)
1248
+ replace_with = Load(
1249
+ new_idx,
1250
+ Const(None, None, eq.atom0.addr, self.project.arch.bits),
1251
+ eq.atom0.size,
1252
+ endness=self.project.arch.memory_endness,
1253
+ **eq.atom1.tags,
1254
+ )
1255
+ elif isinstance(eq.atom0, VirtualVariable) and eq.atom0.was_reg:
1256
+ if isinstance(eq.atom1, VirtualVariable):
1257
+ if eq.atom1.was_reg:
1258
+ if self.project.arch.is_artificial_register(eq.atom0.reg_offset, eq.atom0.size):
1259
+ replace_with = eq.atom1
1260
+ else:
1261
+ replace_with = eq.atom0
1262
+ elif eq.atom1.was_stack:
1263
+ replace_with = eq.atom1
1264
+ else:
1265
+ raise AngrRuntimeError(f"Unsupported atom1 vvar type {eq.atom1.category}.")
1266
+ else:
1267
+ raise AngrRuntimeError(f"Unsupported atom1 type {type(eq.atom1)}.")
1268
+ else:
1269
+ raise AngrRuntimeError(f"Unsupported atom0 type {type(eq.atom0)}.")
1270
+
1271
+ to_replace_def = the_def
1272
+
1273
+ # check: the definition of expression being replaced should not be a phi variable
1274
+ if (
1275
+ isinstance(to_replace_def.atom, atoms.VirtualVariable)
1276
+ and to_replace_def.atom.varid in rd.phi_vvar_ids
1277
+ ):
1278
+ continue
1279
+
1280
+ # find all uses of this definition
1281
+ # we make a copy of the set since we may touch the set (uses) when replacing expressions
1282
+ all_uses = set(rd.all_vvar_uses[to_replace_def.atom.varid])
1283
+ # make sure none of these uses are phi nodes (depends on more than one def)
1284
+ all_uses_with_unique_def = set()
1285
+ for expr_and_use in all_uses:
1286
+ used_expr, use_loc = expr_and_use
1287
+ defs_and_exprs = rd.get_uses_by_location(use_loc, exprs=True)
1288
+ filtered_defs = {
1289
+ def_
1290
+ for def_, expr_ in defs_and_exprs
1291
+ if expr_ is not None and used_expr is not None and expr_.varid == used_expr.varid
1292
+ }
1293
+ if len(filtered_defs) == 1:
1294
+ all_uses_with_unique_def.add(expr_and_use)
1295
+ else:
1296
+ # optimization: break early
1297
+ break
1298
+
1299
+ if len(all_uses) != len(all_uses_with_unique_def):
1300
+ # only when all uses are determined by the same definition will we continue with the simplification
1301
+ continue
1302
+
1303
+ # one more check: there can be at most one assignment in all these use locations if the expression is
1304
+ # not going to be replaced with a parameter. the assignment can be an Assignment statement, but may also
1305
+ # be a Store if it's a global variable (via Load) that we are replacing with
1306
+
1307
+ if not (isinstance(replace_with, VirtualVariable) and replace_with.was_parameter):
1308
+ assignment_ctr = 0
1309
+ all_use_locs = {use_loc for _, use_loc in all_uses}
1310
+ for use_loc in all_use_locs:
1311
+ if use_loc == eq.codeloc:
1312
+ continue
1313
+ assert use_loc.block_addr is not None
1314
+ assert use_loc.stmt_idx is not None
1315
+ block = addr_and_idx_to_block[(use_loc.block_addr, use_loc.block_idx)]
1316
+ stmt = block.statements[use_loc.stmt_idx]
1317
+ if isinstance(stmt, Assignment) or (isinstance(replace_with, Load) and isinstance(stmt, Store)):
1318
+ assignment_ctr += 1
1319
+ if assignment_ctr > 1:
1320
+ continue
1321
+
1322
+ all_uses_with_def = {(to_replace_def, expr_and_use) for expr_and_use in all_uses}
1323
+
1324
+ remove_initial_assignment = False # expression folding will take care of it
1325
+
1326
+ assert replace_with is not None
1327
+
1328
+ to_replace_used_in_refs = False
1329
+ if isinstance(to_replace, VirtualVariable) and to_replace.was_stack:
1330
+ # if the variable being replaced has ever been accessed as a reference, we cannot replace it safely
1331
+ for _, (_, use_loc) in all_uses_with_def:
1332
+ assert use_loc.block_addr is not None and use_loc.stmt_idx is not None
1333
+ block = addr_and_idx_to_block[(use_loc.block_addr, use_loc.block_idx)]
1334
+ stmt = block.statements[use_loc.stmt_idx]
1335
+ if self._statement_uses_ref_vvar(stmt, to_replace.varid):
1336
+ to_replace_used_in_refs = True
1337
+ break
1338
+ if to_replace_used_in_refs:
1339
+ continue
1340
+
1341
+ if any(isinstance(expr_and_use[0], VirtualVariable) for _, expr_and_use in all_uses_with_def):
1342
+ # if any of the uses are phi assignments, we skip
1343
+ used_in_phi_assignment = False
1344
+ for _, expr_and_use in all_uses_with_def:
1345
+ u = expr_and_use[1]
1346
+ assert u.block_addr is not None
1347
+ assert u.stmt_idx is not None
1348
+ block = addr_and_idx_to_block[(u.block_addr, u.block_idx)]
1349
+ stmt = block.statements[u.stmt_idx]
1350
+ if is_phi_assignment(stmt):
1351
+ used_in_phi_assignment = True
1352
+ break
1353
+ if used_in_phi_assignment:
1354
+ continue
1355
+
1356
+ # ensure the uses we consider are all after the eq location
1357
+ filtered_all_uses_with_def = []
1358
+ for def_, expr_and_use in all_uses_with_def:
1359
+ u = expr_and_use[1]
1360
+ if (
1361
+ u.block_addr == eq.codeloc.block_addr
1362
+ and u.block_idx == eq.codeloc.block_idx
1363
+ and u.stmt_idx < eq.codeloc.stmt_idx
1364
+ ):
1365
+ # this use happens before the assignment - ignore it
1366
+ continue
1367
+ if def_eq_rel == DefEqRelation.DEF_IN_EQ_PRED_BLOCK and u.block_addr == def_.codeloc.block_addr:
1368
+ # the definition is in a predecessor block of the eq location, so all uses must be in the same
1369
+ # block as the eq location. (technically it can also be in a successor block to the eq location, but
1370
+ # we don't support it yet).
1371
+ continue
1372
+ filtered_all_uses_with_def.append((def_, expr_and_use))
1373
+ all_uses_with_def = filtered_all_uses_with_def
1374
+
1375
+ if not all_uses_with_def:
1376
+ # definitions without uses may simply be our data-flow analysis being incorrect. do not remove them.
1377
+ continue
1378
+
1379
+ # TODO: We can only replace all these uses with the stack variable if the stack variable isn't
1380
+ # TODO: re-assigned of a new value. Perform this check.
1381
+
1382
+ # replace all uses
1383
+ all_uses_replaced = True
1384
+ for def_, expr_and_use in all_uses_with_def:
1385
+ used_expr, u = expr_and_use
1386
+
1387
+ use_expr_defns = []
1388
+ for d in rd.get_uses_by_location(u):
1389
+ if (
1390
+ isinstance(d.atom, atoms.VirtualVariable)
1391
+ and d.atom.was_reg
1392
+ and isinstance(def_.atom, atoms.VirtualVariable)
1393
+ and def_.atom.was_reg
1394
+ and d.atom.reg_offset == def_.atom.reg_offset
1395
+ ) or d.atom == def_.atom:
1396
+ use_expr_defns.append(d)
1397
+ # you can never replace a use with dependencies from outside the checked defn
1398
+ if len(use_expr_defns) != 1 or next(iter(use_expr_defns)) != def_:
1399
+ if not use_expr_defns:
1400
+ _l.warning("There was no use_expr_defns for %s, this is likely a bug", u)
1401
+ # TODO: can you have multiple definitions which can all be eliminated?
1402
+ all_uses_replaced = False
1403
+ continue
1404
+
1405
+ if u == eq.codeloc:
1406
+ # skip the very initial assignment location
1407
+ continue
1408
+ old_block = addr_and_idx_to_block.get((u.block_addr, u.block_idx), None)
1409
+ if old_block is None:
1410
+ continue
1411
+ if used_expr is None:
1412
+ all_uses_replaced = False
1413
+ continue
1414
+
1415
+ # ensure the expression that we want to replace with is still up-to-date
1416
+ replace_with_original_def = self._find_atom_def_at(replace_with, rd, def_.codeloc)
1417
+ if replace_with_original_def is not None and not self._check_atom_last_def(
1418
+ replace_with, u, rd, replace_with_original_def
1419
+ ):
1420
+ all_uses_replaced = False
1421
+ continue
1422
+
1423
+ # if there is an updated block, use it
1424
+ the_block = self.blocks.get(old_block, old_block)
1425
+ stmt: Statement = the_block.statements[u.stmt_idx]
1426
+
1427
+ replace_with_copy = replace_with.copy()
1428
+ if used_expr.size != replace_with_copy.size:
1429
+ new_idx = None if self._ail_manager is None else next(self._ail_manager.atom_ctr)
1430
+ replace_with_copy = Convert(
1431
+ new_idx,
1432
+ replace_with_copy.bits,
1433
+ used_expr.bits,
1434
+ False,
1435
+ replace_with_copy,
1436
+ )
1437
+
1438
+ r, new_block = self._replace_expr_and_update_block(
1439
+ the_block, u.stmt_idx, stmt, used_expr, replace_with_copy
1440
+ )
1441
+ if r:
1442
+ self.blocks[old_block] = new_block
1443
+ updated_locs.add(u)
1444
+ else:
1445
+ # failed to replace a use - we need to keep the initial assignment!
1446
+ all_uses_replaced = False
1447
+ simplified |= r
1448
+
1449
+ if all_uses_replaced and remove_initial_assignment:
1450
+ # the initial statement can be removed
1451
+ self._assignments_to_remove.add(eq.codeloc)
1452
+
1453
+ if simplified:
1454
+ self._clear_cache()
1455
+ return simplified
1456
+
1457
+ @staticmethod
1458
+ def _find_atom_def_at(atom, rd, codeloc: AILCodeLocation) -> Definition | None:
1459
+ if isinstance(atom, Register):
1460
+ defs = rd.get_defs(atom, codeloc, OP_BEFORE)
1461
+ return next(iter(defs)) if len(defs) == 1 else None
1462
+
1463
+ return None
1464
+
1465
+ @staticmethod
1466
+ def _check_atom_last_def(atom, codeloc, rd, the_def) -> bool:
1467
+ if isinstance(atom, Register):
1468
+ defs = rd.get_defs(atom, codeloc, OP_BEFORE)
1469
+ for d in defs:
1470
+ if d.codeloc != the_def.codeloc:
1471
+ return False
1472
+
1473
+ return True
1474
+
1475
+ #
1476
+ # Folding call expressions
1477
+ #
1478
+
1479
+ @staticmethod
1480
+ def _is_expr_using_temporaries(expr: Expression) -> bool:
1481
+ walker = AILBlockTempCollector()
1482
+ walker.walk_expression(expr)
1483
+ return len(walker.temps) > 0
1484
+
1485
+ @staticmethod
1486
+ def _is_stmt_using_temporaries(stmt: Statement) -> bool:
1487
+ walker = AILBlockTempCollector()
1488
+ walker.walk_statement(stmt)
1489
+ return len(walker.temps) > 0
1490
+
1491
+ @timethis
1492
+ def _fold_call_exprs(self) -> bool:
1493
+ """
1494
+ Fold a call expression (statement) into other statements if the return value of the call expression (statement)
1495
+ is only used once, and the use site and the call site belongs to the same supernode.
1496
+
1497
+ Example::
1498
+
1499
+ s1 = func();
1500
+ s0 = s1;
1501
+ if (s0) ...
1502
+
1503
+ after folding, it will be transformed to::
1504
+
1505
+ s0 = func();
1506
+ if (s0) ...
1507
+
1508
+ s0 can be folded into the condition, which means this example can further be transformed to::
1509
+
1510
+ if (func()) ...
1511
+
1512
+ this behavior is controlled by fold_callexprs_into_conditions. This to avoid cases where func() is called more
1513
+ than once after simplification and graph structuring where conditions might be duplicated (e.g., in Dream).
1514
+ In such cases, the one-use expression folder in RegionSimplifier will perform this transformation.
1515
+ """
1516
+
1517
+ # pylint:disable=unreachable
1518
+ simplified = False
1519
+
1520
+ equivalence = self._compute_equivalence()
1521
+ if not equivalence:
1522
+ return simplified
1523
+
1524
+ addr_and_idx_to_block: dict[tuple[int, int | None], Block] = {}
1525
+ for block in self.func_graph.nodes():
1526
+ addr_and_idx_to_block[(block.addr, block.idx)] = block
1527
+
1528
+ def_locations_to_remove: set[AILCodeLocation] = set()
1529
+ updated_use_locations: set[AILCodeLocation] = set()
1530
+
1531
+ for eq in equivalence:
1532
+ # register variable == Call
1533
+ if isinstance(eq.atom0, VirtualVariable) and (eq.atom0.was_reg or eq.atom0.was_tmp):
1534
+ if isinstance(eq.atom1, Call):
1535
+ # register variable = Call
1536
+ call: Expression = eq.atom1
1537
+ # call_addr = call.target.value if isinstance(call.target, Const) else None
1538
+ elif isinstance(eq.atom1, Convert) and isinstance(eq.atom1.operand, Call):
1539
+ # register variable = Convert(Call)
1540
+ call = eq.atom1
1541
+ # call_addr = call.operand.target.value if isinstance(call.operand.target, Const) else None
1542
+ elif eq.is_weakassignment:
1543
+ # variable =w something else
1544
+ call = eq.atom1
1545
+ else:
1546
+ continue
1547
+
1548
+ if self._is_expr_using_temporaries(call):
1549
+ continue
1550
+
1551
+ if eq.codeloc in updated_use_locations:
1552
+ # this def is now created by an updated use. the corresponding statement will be updated in the end.
1553
+ # we must rerun Propagator to get an updated definition (and Equivalence)
1554
+ continue
1555
+
1556
+ # find all uses of this virtual register
1557
+ rd = self._compute_reaching_definitions()
1558
+
1559
+ the_def: Definition = Definition(
1560
+ atoms.VirtualVariable(
1561
+ eq.atom0.varid, eq.atom0.size, category=eq.atom0.category, oident=eq.atom0.oident
1562
+ ),
1563
+ eq.codeloc,
1564
+ )
1565
+ assert the_def.codeloc.block_addr is not None
1566
+ assert the_def.codeloc.stmt_idx is not None
1567
+
1568
+ all_uses = rd.get_vvar_uses_with_expr(the_def.atom)
1569
+ if eq.is_weakassignment:
1570
+ # eliminate the "use" at the weak assignment site
1571
+ all_uses = {use for use in all_uses if use[1] != eq.codeloc}
1572
+
1573
+ if len(all_uses) != 1:
1574
+ continue
1575
+ used_expr, u = next(iter(all_uses))
1576
+ if used_expr is None:
1577
+ continue
1578
+ assert u.block_addr is not None
1579
+ assert u.stmt_idx is not None
1580
+
1581
+ if u in def_locations_to_remove:
1582
+ # this use site has been altered by previous folding attempts. the corresponding statement will be
1583
+ # removed in the end. in this case, this Equivalence is probably useless, and we must rerun
1584
+ # Propagator to get an updated Equivalence.
1585
+ continue
1586
+
1587
+ if not self._fold_callexprs_into_conditions:
1588
+ # check the statement and make sure it's not a conditional jump
1589
+ the_block = addr_and_idx_to_block[(u.block_addr, u.block_idx)]
1590
+ if isinstance(the_block.statements[u.stmt_idx], ConditionalJump):
1591
+ continue
1592
+
1593
+ # check if the use and the definition is within the same supernode
1594
+ # also we do not allow any calls between the def site and the use site
1595
+ if not self._loc_within_superblock(
1596
+ addr_and_idx_to_block[(the_def.codeloc.block_addr, the_def.codeloc.block_idx)],
1597
+ u.block_addr,
1598
+ u.block_idx,
1599
+ terminate_with_calls=True,
1600
+ ):
1601
+ continue
1602
+
1603
+ # ensure there are no other calls between the def site and the use site.
1604
+ # this is because we do not want to alter the order of calls.
1605
+ u_inclusive = AILCodeLocation(u.block_addr, u.block_idx, u.stmt_idx + 1)
1606
+ # note that the target statement being a store is fine
1607
+ if (
1608
+ has_call_in_between_stmts(
1609
+ self.func_graph,
1610
+ addr_and_idx_to_block,
1611
+ the_def.codeloc,
1612
+ u_inclusive,
1613
+ skip_if_contains_vvar=the_def.atom.varid,
1614
+ )
1615
+ or has_store_stmt_in_between_stmts(self.func_graph, addr_and_idx_to_block, the_def.codeloc, u)
1616
+ or has_load_expr_in_between_stmts(
1617
+ self.func_graph,
1618
+ addr_and_idx_to_block,
1619
+ the_def.codeloc,
1620
+ u_inclusive,
1621
+ skip_if_contains_vvar=the_def.atom.varid,
1622
+ )
1623
+ ):
1624
+ continue
1625
+
1626
+ # replace all uses
1627
+ old_block = addr_and_idx_to_block.get((u.block_addr, u.block_idx), None)
1628
+ if old_block is None:
1629
+ continue
1630
+
1631
+ # if there is an updated block, use that
1632
+ the_block = self.blocks.get(old_block, old_block)
1633
+ stmt: Statement = the_block.statements[u.stmt_idx]
1634
+
1635
+ if isinstance(eq.atom0, VirtualVariable):
1636
+ src = used_expr
1637
+ dst: Expression = call.copy()
1638
+
1639
+ if isinstance(dst, Call) and dst.ret_expr is not None:
1640
+ dst_bits = dst.ret_expr.bits
1641
+ # clear the ret_expr and fp_ret_expr of dst, then set bits so that it can be used as an
1642
+ # expression
1643
+ dst.ret_expr = None
1644
+ dst.fp_ret_expr = None
1645
+ dst.bits = dst_bits
1646
+
1647
+ if src.bits != dst.bits and not eq.is_weakassignment:
1648
+ dst = Convert(None, dst.bits, src.bits, False, dst)
1649
+ else:
1650
+ continue
1651
+
1652
+ # ensure what we are going to replace only appears once
1653
+ expr_ctr = SingleExpressionCounter(stmt, src)
1654
+ if expr_ctr.count > 1:
1655
+ continue
1656
+
1657
+ replaced, new_block = self._replace_expr_and_update_block(the_block, u.stmt_idx, stmt, src, dst)
1658
+
1659
+ if replaced:
1660
+ self.blocks[old_block] = new_block
1661
+ # this call has been folded to the use site. we can remove this call.
1662
+ self._calls_to_remove.add(eq.codeloc)
1663
+ simplified = True
1664
+ def_locations_to_remove.add(eq.codeloc)
1665
+ updated_use_locations.add(u)
1666
+
1667
+ # no need to clear the cache at the end of this method
1668
+ return simplified
1669
+
1670
+ def _get_super_node_blocks(self, start_node: Block) -> list[Block]:
1671
+ lst: list[Block] = [start_node]
1672
+ while True:
1673
+ b = lst[-1]
1674
+ successors = list(self.func_graph.successors(b))
1675
+ if len(successors) == 0:
1676
+ break
1677
+ if len(successors) == 1:
1678
+ succ = successors[0]
1679
+ # check its predecessors
1680
+ succ_predecessors = list(self.func_graph.predecessors(succ))
1681
+ if len(succ_predecessors) == 1:
1682
+ if succ in lst:
1683
+ # we are about to form a loop - bad!
1684
+ # example: binary ce1897b492c80bf94083dd783aefb413ab1f6d8d4981adce8420f6669d0cb3e1, block
1685
+ # 0x2976EF7.
1686
+ break
1687
+ lst.append(succ)
1688
+ else:
1689
+ break
1690
+ else:
1691
+ # too many successors
1692
+ break
1693
+ return lst
1694
+
1695
+ def _loc_within_superblock(
1696
+ self, start_node: Block, block_addr: int, block_idx: int | None, terminate_with_calls=False
1697
+ ) -> bool:
1698
+ b = start_node
1699
+ if block_addr == b.addr and block_idx == b.idx:
1700
+ return True
1701
+
1702
+ encountered_block_addrs: set[tuple[int, int | None]] = {(b.addr, b.idx)}
1703
+ while True:
1704
+ if terminate_with_calls and b.statements and isinstance(b.statements[-1], Call):
1705
+ return False
1706
+
1707
+ encountered_block_addrs.add((b.addr, b.idx))
1708
+ successors = list(self.func_graph.successors(b))
1709
+ if len(successors) == 0:
1710
+ # did not encounter the block before running out of successors
1711
+ return False
1712
+ if len(successors) == 1:
1713
+ succ = successors[0]
1714
+ # check its predecessors
1715
+ succ_predecessors = list(self.func_graph.predecessors(succ))
1716
+ if len(succ_predecessors) == 1:
1717
+ if (succ.addr, succ.idx) in encountered_block_addrs:
1718
+ # we are about to form a loop - bad!
1719
+ # example: binary ce1897b492c80bf94083dd783aefb413ab1f6d8d4981adce8420f6669d0cb3e1, block
1720
+ # 0x2976EF7.
1721
+ return False
1722
+ if block_addr == succ.addr and block_idx == succ.idx:
1723
+ return True
1724
+ b = succ
1725
+ else:
1726
+ return False
1727
+ else:
1728
+ # too many successors
1729
+ return False
1730
+
1731
+ @staticmethod
1732
+ def _replace_expr_and_update_block(block, stmt_idx, stmt, src_expr, dst_expr) -> tuple[bool, Block | None]:
1733
+ replaced, new_stmt = stmt.replace(src_expr, dst_expr)
1734
+ if replaced:
1735
+ new_block = block.copy()
1736
+ new_block.statements = block.statements[::]
1737
+ new_block.statements[stmt_idx] = new_stmt
1738
+ return True, new_block
1739
+
1740
+ return False, None
1741
+
1742
+ @timethis
1743
+ def _iteratively_remove_dead_assignments(self) -> bool:
1744
+ anything_removed = False
1745
+ while True:
1746
+ r = self._remove_dead_assignments()
1747
+ if not r:
1748
+ return anything_removed
1749
+ self._rebuild_func_graph()
1750
+ self._clear_cache()
1751
+
1752
+ @timethis
1753
+ def _remove_dead_assignments(self) -> bool:
1754
+
1755
+ # keeping tracking of statements to remove and statements (as well as dead vvars) to keep allows us to handle
1756
+ # cases where a statement defines more than one atom, e.g., a call statement that defines both the return
1757
+ # value and the floating-point return value.
1758
+ stmts_to_remove_per_block: dict[tuple[int, int | None], set[int]] = defaultdict(set)
1759
+ stmts_to_keep_per_block: dict[tuple[int, int | None], set[int]] = defaultdict(set)
1760
+ dead_vvar_ids: set[int] = self._removed_vvar_ids.copy()
1761
+ dead_vvar_codelocs: set[AILCodeLocation] = set()
1762
+ blocks: dict[tuple[int, int | None], Block] = {
1763
+ (node.addr, node.idx): self.blocks.get(node, node) for node in self.func_graph.nodes()
1764
+ }
1765
+
1766
+ # Find all statements that should be removed
1767
+ mask = (1 << self.project.arch.bits) - 1
1768
+
1769
+ rd = self._compute_reaching_definitions()
1770
+ stackarg_offsets = (
1771
+ {(tpl[1] & mask) for tpl in self._stack_arg_offsets} if self._stack_arg_offsets is not None else None
1772
+ )
1773
+ retpoints: set[tuple[int, int]] = {
1774
+ (node.addr, node.idx)
1775
+ for node in self.func_graph
1776
+ if node.statements and isinstance(node.statements[-1], Return) and self.func_graph.out_degree[node] == 0
1777
+ }
1778
+
1779
+ while True:
1780
+ new_dead_vars_found = False
1781
+
1782
+ # traverse all virtual variable definitions
1783
+ for vvar_id, codeloc in rd.all_vvar_definitions.items():
1784
+ if vvar_id in dead_vvar_ids:
1785
+ continue
1786
+ uses = None
1787
+ if vvar_id in self._propagator_dead_vvar_ids:
1788
+ # we are definitely removing this variable if it has no uses
1789
+ uses = rd.all_vvar_uses[vvar_id]
1790
+
1791
+ if uses is None:
1792
+ vvar = rd.varid_to_vvar[vvar_id]
1793
+ def_codeloc = rd.all_vvar_definitions[vvar_id]
1794
+ if def_codeloc.is_extern:
1795
+ def_stmt = None
1796
+ else:
1797
+ assert def_codeloc.block_addr is not None and def_codeloc.stmt_idx is not None
1798
+ def_stmt = blocks[(def_codeloc.block_addr, def_codeloc.block_idx)].statements[
1799
+ def_codeloc.stmt_idx
1800
+ ]
1801
+ if is_vvar_eliminatable(vvar, def_stmt):
1802
+ uses = rd.all_vvar_uses[vvar_id]
1803
+ elif vvar.was_stack:
1804
+ if not self._remove_dead_memdefs:
1805
+ if rd.is_phi_vvar_id(vvar_id):
1806
+ # we always remove unused phi variables
1807
+ pass
1808
+ elif vvar_id in self._secondary_stackvars:
1809
+ # secondary stack variables are potentially removable
1810
+ pass
1811
+ elif (def_codeloc.block_addr, def_codeloc.block_idx) in retpoints:
1812
+ # slack variable assignments in endpoint blocks are potentially removable.
1813
+ # note that this is a hack! we should rely on more reliable stack variable
1814
+ # eliminatability detection.
1815
+ pass
1816
+ elif stackarg_offsets is not None:
1817
+ # we always remove definitions for stack arguments
1818
+ assert vvar.stack_offset is not None
1819
+ if (vvar.stack_offset & mask) not in stackarg_offsets:
1820
+ continue
1821
+ else:
1822
+ continue
1823
+ uses = rd.all_vvar_uses[vvar_id]
1824
+
1825
+ else:
1826
+ uses = set()
1827
+
1828
+ # remove uses where vvars are going to be removed
1829
+ filtered_uses_count = 0
1830
+ for _, loc in uses:
1831
+ if loc in dead_vvar_codelocs and loc.block_addr is not None and loc.stmt_idx is not None:
1832
+ stmt = blocks[(loc.block_addr, loc.block_idx)].statements[loc.stmt_idx]
1833
+ if not self._statement_has_call_exprs(stmt) and not isinstance(stmt, (DirtyStatement, Call)):
1834
+ continue
1835
+ filtered_uses_count += 1
1836
+
1837
+ if filtered_uses_count == 0:
1838
+ new_dead_vars_found = True
1839
+ dead_vvar_ids.add(vvar_id)
1840
+ dead_vvar_codelocs.add(codeloc)
1841
+ if not codeloc.is_extern:
1842
+ stmts_to_remove_per_block[(codeloc.block_addr, codeloc.block_idx)].add(codeloc.stmt_idx)
1843
+ stmts_to_keep_per_block[(codeloc.block_addr, codeloc.block_idx)].discard(codeloc.stmt_idx)
1844
+ else:
1845
+ if not codeloc.is_extern:
1846
+ stmts_to_keep_per_block[(codeloc.block_addr, codeloc.block_idx)].add(codeloc.stmt_idx)
1847
+
1848
+ if not new_dead_vars_found:
1849
+ # nothing more is found. let's end the loop
1850
+ break
1851
+
1852
+ # find all phi variables that rely on variables that no longer exist
1853
+ removed_vvar_ids = self._removed_vvar_ids
1854
+ while True:
1855
+ new_removed_vvar_ids = set()
1856
+ for phi_varid, phi_use_varids in rd.phivarid_to_varids.items():
1857
+ if phi_varid not in dead_vvar_ids and any(vvarid in removed_vvar_ids for vvarid in phi_use_varids):
1858
+ loc = rd.all_vvar_definitions[phi_varid]
1859
+ assert loc.block_addr is not None and loc.stmt_idx is not None
1860
+ if loc.stmt_idx not in stmts_to_remove_per_block[(loc.block_addr, loc.block_idx)]:
1861
+ stmts_to_remove_per_block[(loc.block_addr, loc.block_idx)].add(loc.stmt_idx)
1862
+ new_removed_vvar_ids.add(phi_varid)
1863
+ dead_vvar_ids.add(phi_varid)
1864
+ if not new_removed_vvar_ids:
1865
+ break
1866
+ removed_vvar_ids = new_removed_vvar_ids
1867
+
1868
+ # find all phi variables that are only ever used by other phi variables
1869
+ redundant_phi_and_dirty_varids = self._find_cyclic_dependent_phis_and_dirty_vvars(rd, dead_vvar_ids)
1870
+ for varid in redundant_phi_and_dirty_varids:
1871
+ loc = rd.all_vvar_definitions[varid]
1872
+ assert loc.block_addr is not None and loc.stmt_idx is not None
1873
+ if loc.stmt_idx not in stmts_to_remove_per_block[(loc.block_addr, loc.block_idx)]:
1874
+ stmts_to_remove_per_block[(loc.block_addr, loc.block_idx)].add(loc.stmt_idx)
1875
+ stmts_to_keep_per_block[(loc.block_addr, loc.block_idx)].discard(loc.stmt_idx)
1876
+
1877
+ for codeloc in self._calls_to_remove | self._assignments_to_remove:
1878
+ # this call can be removed. make sure it exists in stmts_to_remove_per_block
1879
+ assert codeloc.block_addr is not None and codeloc.stmt_idx is not None
1880
+ stmts_to_remove_per_block[codeloc.block_addr, codeloc.block_idx].add(codeloc.stmt_idx)
1881
+
1882
+ simplified = False
1883
+
1884
+ # Remove the statements
1885
+ for old_block in self.func_graph.nodes():
1886
+ # if there is an updated block, use it
1887
+ block = self.blocks.get(old_block, old_block)
1888
+
1889
+ if not isinstance(block, Block):
1890
+ continue
1891
+
1892
+ if (block.addr, block.idx) not in stmts_to_remove_per_block:
1893
+ continue
1894
+
1895
+ new_statements = []
1896
+ stmts_to_remove = stmts_to_remove_per_block[(block.addr, block.idx)]
1897
+ stmts_to_keep = stmts_to_keep_per_block[(block.addr, block.idx)]
1898
+
1899
+ if not stmts_to_remove:
1900
+ continue
1901
+
1902
+ for idx, stmt in enumerate(block.statements):
1903
+ if idx in stmts_to_remove and idx in stmts_to_keep and isinstance(stmt, Call):
1904
+ # this statement declares more than one variable. we should handle it surgically
1905
+ # case 1: stmt.ret_expr and stmt.fp_ret_expr are both set, but one of them is not used
1906
+ if isinstance(stmt.ret_expr, VirtualVariable) and stmt.ret_expr.varid in dead_vvar_ids:
1907
+ stmt = stmt.copy()
1908
+ stmt.ret_expr = None
1909
+ simplified = True
1910
+ if isinstance(stmt.fp_ret_expr, VirtualVariable) and stmt.fp_ret_expr.varid in dead_vvar_ids:
1911
+ stmt = stmt.copy()
1912
+ stmt.fp_ret_expr = None
1913
+ simplified = True
1914
+
1915
+ if idx in stmts_to_remove and idx not in stmts_to_keep and not isinstance(stmt, DirtyStatement):
1916
+ if isinstance(stmt, (Assignment, WeakAssignment, Store)):
1917
+ # Special logic for Assignment and Store statements
1918
+
1919
+ # if this statement writes to a virtual variable that must be preserved, we ignore it
1920
+ if (
1921
+ isinstance(stmt, Assignment)
1922
+ and isinstance(stmt.dst, VirtualVariable)
1923
+ and stmt.dst.varid in self._avoid_vvar_ids
1924
+ ):
1925
+ new_statements.append(stmt)
1926
+ continue
1927
+
1928
+ # if this statement triggers a call, it should only be removed if it's in self._calls_to_remove
1929
+ codeloc = AILCodeLocation(block.addr, block.idx, idx, stmt.tags.get("ins_addr"))
1930
+ if codeloc in self._assignments_to_remove:
1931
+ # it should be removed
1932
+ simplified = True
1933
+ continue
1934
+
1935
+ if self._statement_has_call_exprs(stmt):
1936
+ if codeloc in self._calls_to_remove:
1937
+ # it has a call and must be removed
1938
+ simplified = True
1939
+ continue
1940
+ if isinstance(stmt, Assignment) and isinstance(stmt.dst, VirtualVariable):
1941
+ # no one is using the returned virtual variable.
1942
+ # now the things are a bit tricky here
1943
+ if isinstance(stmt.src, Call):
1944
+ # replace this assignment statement with a call statement
1945
+ stmt = stmt.src
1946
+ elif isinstance(stmt.src, Convert) and isinstance(stmt.src.operand, Call):
1947
+ # the convert is useless now
1948
+ stmt = stmt.src.operand
1949
+ else:
1950
+ # we can't change this stmt at all because it has an expression with Calls inside
1951
+ pass
1952
+ else:
1953
+ # no calls. remove it
1954
+ simplified = True
1955
+ continue
1956
+ elif isinstance(stmt, Call):
1957
+ codeloc = AILCodeLocation(block.addr, block.idx, idx, stmt.tags.get("ins_addr"))
1958
+ if codeloc in self._calls_to_remove:
1959
+ # this call can be removed
1960
+ simplified = True
1961
+ continue
1962
+
1963
+ if stmt.ret_expr is not None or stmt.fp_ret_expr is not None:
1964
+ # both the return expr and the fp_ret_expr are not used
1965
+ stmt = stmt.copy()
1966
+ stmt.ret_expr = None
1967
+ stmt.fp_ret_expr = None
1968
+ simplified = True
1969
+ else:
1970
+ # Should not happen!
1971
+ raise NotImplementedError
1972
+
1973
+ new_statements.append(stmt)
1974
+
1975
+ new_block = block.copy()
1976
+ new_block.statements = new_statements
1977
+ self.blocks[old_block] = new_block
1978
+
1979
+ # we can only use calls_to_remove and assignments_to_remove once; if any statements in blocks are removed, then
1980
+ # the statement IDs in calls_to_remove and assignments_to_remove no longer match!
1981
+ self._calls_to_remove.clear()
1982
+ self._assignments_to_remove.clear()
1983
+
1984
+ return simplified
1985
+
1986
+ @staticmethod
1987
+ def _get_vvar_used_by(
1988
+ vvar_id: int, rd: SRDAModel, blocks_dict: dict[tuple[int, int | None], Block]
1989
+ ) -> set[int | None]:
1990
+ """
1991
+ Get all atoms that use a specified virtual variable. The atoms are in the form of virtual variable ID or None
1992
+ (indicating the virtual variable is used by another statement like Store).
1993
+
1994
+ :param vvar_id: ID of the virtual variable.
1995
+ :param rd: The SRDA model.
1996
+ :return: The set of vvar use atoms.
1997
+ """
1998
+
1999
+ used_by: set[int | None] = set()
2000
+ for used_vvar, loc in rd.all_vvar_uses[vvar_id]:
2001
+ if used_vvar is None:
2002
+ # no explicit reference
2003
+ used_by.add(None)
2004
+ elif loc.block_addr is not None:
2005
+ assert loc.stmt_idx is not None
2006
+ stmt = blocks_dict[(loc.block_addr, loc.block_idx)].statements[loc.stmt_idx]
2007
+ if isinstance(stmt, Assignment) and isinstance(stmt.dst, VirtualVariable):
2008
+ used_by.add(stmt.dst.varid)
2009
+ else:
2010
+ used_by.add(None)
2011
+ return used_by
2012
+
2013
+ def _find_cyclic_dependent_phis_and_dirty_vvars(self, rd: SRDAModel, dead_vvar_ids: set[int]) -> set[int]:
2014
+ blocks_dict: dict[tuple[int, int | None], Block] = {(bb.addr, bb.idx): bb for bb in self.func_graph}
2015
+
2016
+ # find dirty vvars and vexccall vvars
2017
+ dirty_vvar_ids = set()
2018
+ for bb in self.func_graph:
2019
+ for stmt in bb.statements:
2020
+ if (
2021
+ isinstance(stmt, Assignment)
2022
+ and isinstance(stmt.dst, VirtualVariable)
2023
+ and stmt.dst.was_reg
2024
+ and isinstance(stmt.src, (DirtyExpression, VEXCCallExpression))
2025
+ ):
2026
+ dirty_vvar_ids.add(stmt.dst.varid)
2027
+
2028
+ phi_and_dirty_vvar_ids = (rd.phi_vvar_ids | dirty_vvar_ids).difference(dead_vvar_ids)
2029
+
2030
+ vvar_used_by: dict[int, set[int | None]] = defaultdict(set)
2031
+ for var_id in phi_and_dirty_vvar_ids:
2032
+ if var_id in rd.phivarid_to_varids:
2033
+ for used_by_varid in rd.phivarid_to_varids[var_id]:
2034
+ if used_by_varid in dead_vvar_ids:
2035
+ # this variable no longer exists
2036
+ continue
2037
+ if used_by_varid not in vvar_used_by:
2038
+ vvar_used_by[used_by_varid] |= self._get_vvar_used_by(
2039
+ used_by_varid, rd, blocks_dict
2040
+ ).difference(dead_vvar_ids)
2041
+ vvar_used_by[used_by_varid].add(var_id) # probably unnecessary
2042
+ vvar_used_by[var_id] |= self._get_vvar_used_by(var_id, rd, blocks_dict).difference(dead_vvar_ids)
2043
+
2044
+ g = networkx.DiGraph()
2045
+ dummy_vvar_id = -1
2046
+ for var_id, used_by_initial in vvar_used_by.items():
2047
+ for u in used_by_initial:
2048
+ if u is None:
2049
+ # we can't have None in networkx.DiGraph
2050
+ g.add_edge(var_id, dummy_vvar_id)
2051
+ else:
2052
+ g.add_edge(var_id, u)
2053
+
2054
+ cyclic_dependent_phi_varids = set()
2055
+ for scc in networkx.strongly_connected_components(g):
2056
+ if len(scc) == 1:
2057
+ continue
2058
+
2059
+ bail = False
2060
+ for varid in scc:
2061
+ # ensure this vvar is not used by anything else outside the scc (regardless of whether this vvar is a
2062
+ # phi variable or not)
2063
+ if varid in vvar_used_by and None in vvar_used_by[varid]:
2064
+ bail = True
2065
+ break
2066
+ if bail is False:
2067
+ succs = list(g.successors(varid))
2068
+ if any(succ_varid not in scc for succ_varid in succs):
2069
+ bail = True
2070
+ break
2071
+ if bail:
2072
+ continue
2073
+
2074
+ if all(
2075
+ varid in phi_and_dirty_vvar_ids or rd.varid_to_vvar[varid].was_reg or varid in self._secondary_stackvars
2076
+ for varid in scc
2077
+ ):
2078
+ cyclic_dependent_phi_varids |= set(scc)
2079
+
2080
+ return cyclic_dependent_phi_varids
2081
+
2082
+ #
2083
+ # Rewriting ccalls
2084
+ #
2085
+
2086
+ def _rewrite_ccalls(self):
2087
+ rewriter_cls = CCALL_REWRITERS.get(self.project.arch.name, None)
2088
+ if rewriter_cls is None:
2089
+ return False
2090
+
2091
+ walker = AILBlockRewriter()
2092
+
2093
+ class _any_update:
2094
+ """
2095
+ Dummy class for storing if any result has been updated.
2096
+ """
2097
+
2098
+ v = False
2099
+
2100
+ def _handle_VEXCCallExpression(
2101
+ expr_idx: int, expr: VEXCCallExpression, stmt_idx: int, stmt: Statement | None, block: Block | None
2102
+ ) -> Expression:
2103
+ r_expr = AILBlockRewriter._handle_VEXCCallExpression(walker, expr_idx, expr, stmt_idx, stmt, block)
2104
+ rewriter = rewriter_cls(r_expr, self.project, rename_ccalls=self._should_rename_ccalls)
2105
+ if rewriter.result is not None:
2106
+ _any_update.v = True
2107
+ return rewriter.result
2108
+ return r_expr
2109
+
2110
+ blocks_by_addr_and_idx = {(node.addr, node.idx): node for node in self.func_graph.nodes()}
2111
+ walker.expr_handlers[VEXCCallExpression] = _handle_VEXCCallExpression
2112
+
2113
+ updated = False
2114
+ for block in blocks_by_addr_and_idx.values():
2115
+ _any_update.v = False
2116
+ old_block = block.copy()
2117
+ walker.walk(block)
2118
+ if _any_update.v:
2119
+ self.blocks[old_block] = block
2120
+ updated = True
2121
+
2122
+ return updated
2123
+
2124
+ #
2125
+ # Rewriting dirty calls
2126
+ #
2127
+
2128
+ def _rewrite_dirty_calls(self):
2129
+ rewriter_cls = DIRTY_REWRITERS.get(self.project.arch.name, None)
2130
+ if rewriter_cls is None:
2131
+ return False
2132
+
2133
+ walker = AILBlockRewriter()
2134
+
2135
+ class _any_update:
2136
+ """
2137
+ Dummy class for storing if any result has been updated.
2138
+ """
2139
+
2140
+ v = False
2141
+
2142
+ def _handle_DirtyStatement( # pylint:disable=unused-argument
2143
+ stmt_idx: int, stmt: DirtyStatement, block: Block | None
2144
+ ) -> Statement:
2145
+ # we do not want to trigger _handle_DirtyExpression, which is why we do not call the superclass method
2146
+ rewriter = rewriter_cls(stmt, self.project.arch)
2147
+ if rewriter.result is not None:
2148
+ _any_update.v = True
2149
+ if walker._update_block and block is not None:
2150
+ block.statements[stmt_idx] = rewriter.result # type:ignore
2151
+ assert isinstance(rewriter.result, Statement)
2152
+ return rewriter.result
2153
+ return stmt
2154
+
2155
+ def _handle_DirtyExpression(
2156
+ expr_idx: int, expr: DirtyExpression, stmt_idx: int, stmt: Statement | None, block: Block | None
2157
+ ):
2158
+ r_expr = AILBlockRewriter._handle_DirtyExpression(walker, expr_idx, expr, stmt_idx, stmt, block)
2159
+ assert isinstance(r_expr, DirtyExpression)
2160
+ rewriter = rewriter_cls(r_expr, self.project.arch)
2161
+ if rewriter.result is not None:
2162
+ _any_update.v = True
2163
+ assert isinstance(rewriter.result, Expression)
2164
+ return rewriter.result
2165
+ return r_expr
2166
+
2167
+ blocks_by_addr_and_idx = {(node.addr, node.idx): node for node in self.func_graph.nodes()}
2168
+ walker.expr_handlers[DirtyExpression] = _handle_DirtyExpression
2169
+ walker.stmt_handlers[DirtyStatement] = _handle_DirtyStatement
2170
+
2171
+ updated = False
2172
+ for block in blocks_by_addr_and_idx.values():
2173
+ _any_update.v = False
2174
+ old_block = block.copy()
2175
+ walker.walk(block)
2176
+ if _any_update.v:
2177
+ self.blocks[old_block] = block
2178
+ updated = True
2179
+
2180
+ return updated
2181
+
2182
+ #
2183
+ # Util functions
2184
+ #
2185
+
2186
+ @staticmethod
2187
+ def _statement_has_call_exprs(stmt: Statement) -> bool:
2188
+ def _handle_callexpr(expr_idx, expr, stmt_idx, stmt, block): # pylint:disable=unused-argument
2189
+ raise HasCallNotification
2190
+
2191
+ walker = AILBlockViewer()
2192
+ walker.expr_handlers[Call] = _handle_callexpr
2193
+ try:
2194
+ walker.walk_statement(stmt)
2195
+ except HasCallNotification:
2196
+ return True
2197
+
2198
+ return False
2199
+
2200
+ @staticmethod
2201
+ def _expression_has_call_exprs(expr: Expression) -> bool:
2202
+ def _handle_callexpr(expr_idx, expr, stmt_idx, stmt, block): # pylint:disable=unused-argument
2203
+ raise HasCallNotification
2204
+
2205
+ walker = AILBlockViewer()
2206
+ walker.expr_handlers[Call] = _handle_callexpr
2207
+ try:
2208
+ walker.walk_expression(expr)
2209
+ except HasCallNotification:
2210
+ return True
2211
+
2212
+ return False
2213
+
2214
+ @staticmethod
2215
+ def _exprs_contain_vvar(exprs: Iterable[Expression], vvar_ids: set[int]) -> bool:
2216
+ def _handle_VirtualVariable(expr_idx, expr, stmt_idx, stmt, block): # pylint:disable=unused-argument
2217
+ if expr.varid in vvar_ids:
2218
+ raise HasVVarNotification
2219
+
2220
+ walker = AILBlockViewer()
2221
+ walker.expr_handlers[VirtualVariable] = _handle_VirtualVariable
2222
+
2223
+ for expr in exprs:
2224
+ try:
2225
+ walker.walk_expression(expr)
2226
+ except HasVVarNotification:
2227
+ return True
2228
+ return False
2229
+
2230
+ @staticmethod
2231
+ def _statement_uses_ref_vvar(stmt: Statement, vvar_id: int) -> bool:
2232
+ def _handle_UnaryOp(expr_idx, expr, stmt_idx, stmt, block): # pylint:disable=unused-argument
2233
+ if expr.op == "Reference" and isinstance(expr.operand, VirtualVariable) and expr.operand.varid == vvar_id:
2234
+ raise HasRefVVarNotification
2235
+
2236
+ walker = AILBlockViewer()
2237
+ walker.expr_handlers[UnaryOp] = _handle_UnaryOp
2238
+ try:
2239
+ walker.walk_statement(stmt)
2240
+ except HasRefVVarNotification:
2241
+ return True
2242
+
2243
+ return False
2244
+
2245
+
2246
+ AnalysesHub.register_default("AILSimplifier", AILSimplifier)