angr 9.2.156__cp310-cp310-macosx_10_9_x86_64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of angr might be problematic. Click here for more details.

Files changed (1393) hide show
  1. angr/__init__.py +363 -0
  2. angr/__main__.py +152 -0
  3. angr/analyses/__init__.py +113 -0
  4. angr/analyses/analysis.py +407 -0
  5. angr/analyses/backward_slice.py +686 -0
  6. angr/analyses/binary_optimizer.py +670 -0
  7. angr/analyses/bindiff.py +1512 -0
  8. angr/analyses/boyscout.py +76 -0
  9. angr/analyses/callee_cleanup_finder.py +74 -0
  10. angr/analyses/calling_convention/__init__.py +6 -0
  11. angr/analyses/calling_convention/calling_convention.py +1092 -0
  12. angr/analyses/calling_convention/fact_collector.py +636 -0
  13. angr/analyses/calling_convention/utils.py +60 -0
  14. angr/analyses/cdg.py +189 -0
  15. angr/analyses/cfg/__init__.py +23 -0
  16. angr/analyses/cfg/cfb.py +428 -0
  17. angr/analyses/cfg/cfg.py +74 -0
  18. angr/analyses/cfg/cfg_arch_options.py +95 -0
  19. angr/analyses/cfg/cfg_base.py +2886 -0
  20. angr/analyses/cfg/cfg_emulated.py +3447 -0
  21. angr/analyses/cfg/cfg_fast.py +5273 -0
  22. angr/analyses/cfg/cfg_fast_soot.py +662 -0
  23. angr/analyses/cfg/cfg_job_base.py +203 -0
  24. angr/analyses/cfg/indirect_jump_resolvers/__init__.py +28 -0
  25. angr/analyses/cfg/indirect_jump_resolvers/amd64_elf_got.py +62 -0
  26. angr/analyses/cfg/indirect_jump_resolvers/amd64_pe_iat.py +51 -0
  27. angr/analyses/cfg/indirect_jump_resolvers/arm_elf_fast.py +149 -0
  28. angr/analyses/cfg/indirect_jump_resolvers/const_resolver.py +186 -0
  29. angr/analyses/cfg/indirect_jump_resolvers/constant_value_manager.py +107 -0
  30. angr/analyses/cfg/indirect_jump_resolvers/default_resolvers.py +76 -0
  31. angr/analyses/cfg/indirect_jump_resolvers/jumptable.py +2367 -0
  32. angr/analyses/cfg/indirect_jump_resolvers/memload_resolver.py +81 -0
  33. angr/analyses/cfg/indirect_jump_resolvers/mips_elf_fast.py +286 -0
  34. angr/analyses/cfg/indirect_jump_resolvers/mips_elf_got.py +148 -0
  35. angr/analyses/cfg/indirect_jump_resolvers/propagator_utils.py +46 -0
  36. angr/analyses/cfg/indirect_jump_resolvers/resolver.py +74 -0
  37. angr/analyses/cfg/indirect_jump_resolvers/syscall_resolver.py +92 -0
  38. angr/analyses/cfg/indirect_jump_resolvers/x86_elf_pic_plt.py +88 -0
  39. angr/analyses/cfg/indirect_jump_resolvers/x86_pe_iat.py +47 -0
  40. angr/analyses/cfg_slice_to_sink/__init__.py +11 -0
  41. angr/analyses/cfg_slice_to_sink/cfg_slice_to_sink.py +117 -0
  42. angr/analyses/cfg_slice_to_sink/graph.py +87 -0
  43. angr/analyses/cfg_slice_to_sink/transitions.py +27 -0
  44. angr/analyses/class_identifier.py +63 -0
  45. angr/analyses/code_tagging.py +123 -0
  46. angr/analyses/codecave.py +77 -0
  47. angr/analyses/complete_calling_conventions.py +461 -0
  48. angr/analyses/congruency_check.py +377 -0
  49. angr/analyses/data_dep/__init__.py +16 -0
  50. angr/analyses/data_dep/data_dependency_analysis.py +595 -0
  51. angr/analyses/data_dep/dep_nodes.py +171 -0
  52. angr/analyses/data_dep/sim_act_location.py +49 -0
  53. angr/analyses/datagraph_meta.py +105 -0
  54. angr/analyses/ddg.py +1670 -0
  55. angr/analyses/decompiler/__init__.py +41 -0
  56. angr/analyses/decompiler/ail_simplifier.py +1872 -0
  57. angr/analyses/decompiler/ailgraph_walker.py +49 -0
  58. angr/analyses/decompiler/block_io_finder.py +302 -0
  59. angr/analyses/decompiler/block_similarity.py +196 -0
  60. angr/analyses/decompiler/block_simplifier.py +371 -0
  61. angr/analyses/decompiler/callsite_maker.py +555 -0
  62. angr/analyses/decompiler/ccall_rewriters/__init__.py +9 -0
  63. angr/analyses/decompiler/ccall_rewriters/amd64_ccalls.py +580 -0
  64. angr/analyses/decompiler/ccall_rewriters/rewriter_base.py +20 -0
  65. angr/analyses/decompiler/ccall_rewriters/x86_ccalls.py +313 -0
  66. angr/analyses/decompiler/clinic.py +3222 -0
  67. angr/analyses/decompiler/condition_processor.py +1245 -0
  68. angr/analyses/decompiler/counters/__init__.py +16 -0
  69. angr/analyses/decompiler/counters/boolean_counter.py +27 -0
  70. angr/analyses/decompiler/counters/call_counter.py +47 -0
  71. angr/analyses/decompiler/counters/expression_counters.py +77 -0
  72. angr/analyses/decompiler/counters/seq_cf_structure_counter.py +63 -0
  73. angr/analyses/decompiler/decompilation_cache.py +46 -0
  74. angr/analyses/decompiler/decompilation_options.py +275 -0
  75. angr/analyses/decompiler/decompiler.py +692 -0
  76. angr/analyses/decompiler/dephication/__init__.py +6 -0
  77. angr/analyses/decompiler/dephication/dephication_base.py +89 -0
  78. angr/analyses/decompiler/dephication/graph_dephication.py +63 -0
  79. angr/analyses/decompiler/dephication/graph_rewriting.py +116 -0
  80. angr/analyses/decompiler/dephication/graph_vvar_mapping.py +326 -0
  81. angr/analyses/decompiler/dephication/rewriting_engine.py +504 -0
  82. angr/analyses/decompiler/dephication/seqnode_dephication.py +134 -0
  83. angr/analyses/decompiler/empty_node_remover.py +212 -0
  84. angr/analyses/decompiler/expression_narrower.py +287 -0
  85. angr/analyses/decompiler/goto_manager.py +112 -0
  86. angr/analyses/decompiler/graph_region.py +398 -0
  87. angr/analyses/decompiler/jump_target_collector.py +37 -0
  88. angr/analyses/decompiler/jumptable_entry_condition_rewriter.py +67 -0
  89. angr/analyses/decompiler/label_collector.py +32 -0
  90. angr/analyses/decompiler/optimization_passes/__init__.py +151 -0
  91. angr/analyses/decompiler/optimization_passes/base_ptr_save_simplifier.py +157 -0
  92. angr/analyses/decompiler/optimization_passes/call_stmt_rewriter.py +46 -0
  93. angr/analyses/decompiler/optimization_passes/code_motion.py +362 -0
  94. angr/analyses/decompiler/optimization_passes/condition_constprop.py +219 -0
  95. angr/analyses/decompiler/optimization_passes/const_derefs.py +266 -0
  96. angr/analyses/decompiler/optimization_passes/const_prop_reverter.py +365 -0
  97. angr/analyses/decompiler/optimization_passes/cross_jump_reverter.py +106 -0
  98. angr/analyses/decompiler/optimization_passes/deadblock_remover.py +82 -0
  99. angr/analyses/decompiler/optimization_passes/determine_load_sizes.py +64 -0
  100. angr/analyses/decompiler/optimization_passes/div_simplifier.py +425 -0
  101. angr/analyses/decompiler/optimization_passes/duplication_reverter/__init__.py +5 -0
  102. angr/analyses/decompiler/optimization_passes/duplication_reverter/ail_merge_graph.py +503 -0
  103. angr/analyses/decompiler/optimization_passes/duplication_reverter/duplication_reverter.py +1218 -0
  104. angr/analyses/decompiler/optimization_passes/duplication_reverter/errors.py +16 -0
  105. angr/analyses/decompiler/optimization_passes/duplication_reverter/similarity.py +126 -0
  106. angr/analyses/decompiler/optimization_passes/duplication_reverter/utils.py +167 -0
  107. angr/analyses/decompiler/optimization_passes/eager_std_string_concatenation.py +165 -0
  108. angr/analyses/decompiler/optimization_passes/engine_base.py +500 -0
  109. angr/analyses/decompiler/optimization_passes/expr_op_swapper.py +135 -0
  110. angr/analyses/decompiler/optimization_passes/flip_boolean_cmp.py +113 -0
  111. angr/analyses/decompiler/optimization_passes/inlined_string_transformation_simplifier.py +615 -0
  112. angr/analyses/decompiler/optimization_passes/ite_expr_converter.py +224 -0
  113. angr/analyses/decompiler/optimization_passes/ite_region_converter.py +335 -0
  114. angr/analyses/decompiler/optimization_passes/lowered_switch_simplifier.py +922 -0
  115. angr/analyses/decompiler/optimization_passes/mod_simplifier.py +99 -0
  116. angr/analyses/decompiler/optimization_passes/optimization_pass.py +659 -0
  117. angr/analyses/decompiler/optimization_passes/register_save_area_simplifier.py +221 -0
  118. angr/analyses/decompiler/optimization_passes/ret_addr_save_simplifier.py +171 -0
  119. angr/analyses/decompiler/optimization_passes/ret_deduplicator.py +222 -0
  120. angr/analyses/decompiler/optimization_passes/return_duplicator_base.py +640 -0
  121. angr/analyses/decompiler/optimization_passes/return_duplicator_high.py +61 -0
  122. angr/analyses/decompiler/optimization_passes/return_duplicator_low.py +235 -0
  123. angr/analyses/decompiler/optimization_passes/stack_canary_simplifier.py +333 -0
  124. angr/analyses/decompiler/optimization_passes/switch_default_case_duplicator.py +149 -0
  125. angr/analyses/decompiler/optimization_passes/switch_reused_entry_rewriter.py +102 -0
  126. angr/analyses/decompiler/optimization_passes/tag_slicer.py +41 -0
  127. angr/analyses/decompiler/optimization_passes/win_stack_canary_simplifier.py +421 -0
  128. angr/analyses/decompiler/optimization_passes/x86_gcc_getpc_simplifier.py +88 -0
  129. angr/analyses/decompiler/peephole_optimizations/__init__.py +127 -0
  130. angr/analyses/decompiler/peephole_optimizations/a_div_const_add_a_mul_n_div_const.py +42 -0
  131. angr/analyses/decompiler/peephole_optimizations/a_mul_const_div_shr_const.py +38 -0
  132. angr/analyses/decompiler/peephole_optimizations/a_mul_const_sub_a.py +34 -0
  133. angr/analyses/decompiler/peephole_optimizations/a_shl_const_sub_a.py +34 -0
  134. angr/analyses/decompiler/peephole_optimizations/a_sub_a_div.py +25 -0
  135. angr/analyses/decompiler/peephole_optimizations/a_sub_a_div_const_mul_const.py +57 -0
  136. angr/analyses/decompiler/peephole_optimizations/a_sub_a_shr_const_shr_const.py +37 -0
  137. angr/analyses/decompiler/peephole_optimizations/a_sub_a_sub_n.py +23 -0
  138. angr/analyses/decompiler/peephole_optimizations/arm_cmpf.py +236 -0
  139. angr/analyses/decompiler/peephole_optimizations/base.py +157 -0
  140. angr/analyses/decompiler/peephole_optimizations/basepointeroffset_add_n.py +34 -0
  141. angr/analyses/decompiler/peephole_optimizations/basepointeroffset_and_mask.py +36 -0
  142. angr/analyses/decompiler/peephole_optimizations/bitwise_or_to_logical_or.py +34 -0
  143. angr/analyses/decompiler/peephole_optimizations/bool_expr_xor_1.py +27 -0
  144. angr/analyses/decompiler/peephole_optimizations/bswap.py +142 -0
  145. angr/analyses/decompiler/peephole_optimizations/cas_intrinsics.py +115 -0
  146. angr/analyses/decompiler/peephole_optimizations/cmpord_rewriter.py +71 -0
  147. angr/analyses/decompiler/peephole_optimizations/coalesce_adjacent_shrs.py +39 -0
  148. angr/analyses/decompiler/peephole_optimizations/coalesce_same_cascading_ifs.py +28 -0
  149. angr/analyses/decompiler/peephole_optimizations/const_mull_a_shift.py +189 -0
  150. angr/analyses/decompiler/peephole_optimizations/constant_derefs.py +44 -0
  151. angr/analyses/decompiler/peephole_optimizations/conv_a_sub0_shr_and.py +69 -0
  152. angr/analyses/decompiler/peephole_optimizations/conv_shl_shr.py +52 -0
  153. angr/analyses/decompiler/peephole_optimizations/eager_eval.py +372 -0
  154. angr/analyses/decompiler/peephole_optimizations/extended_byte_and_mask.py +56 -0
  155. angr/analyses/decompiler/peephole_optimizations/inlined_strcpy.py +160 -0
  156. angr/analyses/decompiler/peephole_optimizations/inlined_strcpy_consolidation.py +109 -0
  157. angr/analyses/decompiler/peephole_optimizations/inlined_wstrcpy.py +170 -0
  158. angr/analyses/decompiler/peephole_optimizations/invert_negated_logical_conjuction_disjunction.py +50 -0
  159. angr/analyses/decompiler/peephole_optimizations/one_sub_bool.py +33 -0
  160. angr/analyses/decompiler/peephole_optimizations/remove_cascading_conversions.py +45 -0
  161. angr/analyses/decompiler/peephole_optimizations/remove_cxx_destructor_calls.py +32 -0
  162. angr/analyses/decompiler/peephole_optimizations/remove_empty_if_body.py +46 -0
  163. angr/analyses/decompiler/peephole_optimizations/remove_noop_conversions.py +47 -0
  164. angr/analyses/decompiler/peephole_optimizations/remove_redundant_bitmasks.py +116 -0
  165. angr/analyses/decompiler/peephole_optimizations/remove_redundant_conversions.py +247 -0
  166. angr/analyses/decompiler/peephole_optimizations/remove_redundant_ite_branch.py +30 -0
  167. angr/analyses/decompiler/peephole_optimizations/remove_redundant_ite_comparisons.py +54 -0
  168. angr/analyses/decompiler/peephole_optimizations/remove_redundant_nots.py +36 -0
  169. angr/analyses/decompiler/peephole_optimizations/remove_redundant_reinterprets.py +44 -0
  170. angr/analyses/decompiler/peephole_optimizations/remove_redundant_shifts.py +95 -0
  171. angr/analyses/decompiler/peephole_optimizations/remove_redundant_shifts_around_comparators.py +44 -0
  172. angr/analyses/decompiler/peephole_optimizations/rewrite_bit_extractions.py +85 -0
  173. angr/analyses/decompiler/peephole_optimizations/rewrite_conv_mul.py +40 -0
  174. angr/analyses/decompiler/peephole_optimizations/rewrite_cxx_operator_calls.py +90 -0
  175. angr/analyses/decompiler/peephole_optimizations/rewrite_mips_gp_loads.py +49 -0
  176. angr/analyses/decompiler/peephole_optimizations/rol_ror.py +130 -0
  177. angr/analyses/decompiler/peephole_optimizations/sar_to_signed_div.py +112 -0
  178. angr/analyses/decompiler/peephole_optimizations/shl_to_mul.py +25 -0
  179. angr/analyses/decompiler/peephole_optimizations/simplify_pc_relative_loads.py +51 -0
  180. angr/analyses/decompiler/peephole_optimizations/single_bit_cond_to_boolexpr.py +53 -0
  181. angr/analyses/decompiler/peephole_optimizations/single_bit_xor.py +29 -0
  182. angr/analyses/decompiler/peephole_optimizations/tidy_stack_addr.py +131 -0
  183. angr/analyses/decompiler/peephole_optimizations/utils.py +18 -0
  184. angr/analyses/decompiler/presets/__init__.py +20 -0
  185. angr/analyses/decompiler/presets/basic.py +32 -0
  186. angr/analyses/decompiler/presets/fast.py +58 -0
  187. angr/analyses/decompiler/presets/full.py +68 -0
  188. angr/analyses/decompiler/presets/preset.py +37 -0
  189. angr/analyses/decompiler/redundant_label_remover.py +134 -0
  190. angr/analyses/decompiler/region_identifier.py +1218 -0
  191. angr/analyses/decompiler/region_simplifiers/__init__.py +5 -0
  192. angr/analyses/decompiler/region_simplifiers/cascading_cond_transformer.py +95 -0
  193. angr/analyses/decompiler/region_simplifiers/cascading_ifs.py +82 -0
  194. angr/analyses/decompiler/region_simplifiers/expr_folding.py +789 -0
  195. angr/analyses/decompiler/region_simplifiers/goto.py +178 -0
  196. angr/analyses/decompiler/region_simplifiers/if_.py +135 -0
  197. angr/analyses/decompiler/region_simplifiers/ifelse.py +91 -0
  198. angr/analyses/decompiler/region_simplifiers/loop.py +143 -0
  199. angr/analyses/decompiler/region_simplifiers/node_address_finder.py +24 -0
  200. angr/analyses/decompiler/region_simplifiers/region_simplifier.py +234 -0
  201. angr/analyses/decompiler/region_simplifiers/switch_cluster_simplifier.py +654 -0
  202. angr/analyses/decompiler/region_simplifiers/switch_expr_simplifier.py +87 -0
  203. angr/analyses/decompiler/region_walker.py +24 -0
  204. angr/analyses/decompiler/return_maker.py +72 -0
  205. angr/analyses/decompiler/seq_to_blocks.py +20 -0
  206. angr/analyses/decompiler/sequence_walker.py +257 -0
  207. angr/analyses/decompiler/ssailification/__init__.py +4 -0
  208. angr/analyses/decompiler/ssailification/rewriting.py +379 -0
  209. angr/analyses/decompiler/ssailification/rewriting_engine.py +1053 -0
  210. angr/analyses/decompiler/ssailification/rewriting_state.py +61 -0
  211. angr/analyses/decompiler/ssailification/ssailification.py +276 -0
  212. angr/analyses/decompiler/ssailification/traversal.py +124 -0
  213. angr/analyses/decompiler/ssailification/traversal_engine.py +297 -0
  214. angr/analyses/decompiler/ssailification/traversal_state.py +48 -0
  215. angr/analyses/decompiler/stack_item.py +36 -0
  216. angr/analyses/decompiler/structured_codegen/__init__.py +25 -0
  217. angr/analyses/decompiler/structured_codegen/base.py +132 -0
  218. angr/analyses/decompiler/structured_codegen/c.py +4069 -0
  219. angr/analyses/decompiler/structured_codegen/dummy.py +15 -0
  220. angr/analyses/decompiler/structured_codegen/dwarf_import.py +190 -0
  221. angr/analyses/decompiler/structuring/__init__.py +30 -0
  222. angr/analyses/decompiler/structuring/dream.py +1217 -0
  223. angr/analyses/decompiler/structuring/phoenix.py +2999 -0
  224. angr/analyses/decompiler/structuring/recursive_structurer.py +187 -0
  225. angr/analyses/decompiler/structuring/sailr.py +112 -0
  226. angr/analyses/decompiler/structuring/structurer_base.py +1067 -0
  227. angr/analyses/decompiler/structuring/structurer_nodes.py +438 -0
  228. angr/analyses/decompiler/utils.py +1106 -0
  229. angr/analyses/deobfuscator/__init__.py +18 -0
  230. angr/analyses/deobfuscator/api_obf_finder.py +325 -0
  231. angr/analyses/deobfuscator/api_obf_peephole_optimizer.py +51 -0
  232. angr/analyses/deobfuscator/api_obf_type2_finder.py +166 -0
  233. angr/analyses/deobfuscator/irsb_reg_collector.py +54 -0
  234. angr/analyses/deobfuscator/string_obf_finder.py +861 -0
  235. angr/analyses/deobfuscator/string_obf_opt_passes.py +133 -0
  236. angr/analyses/deobfuscator/string_obf_peephole_optimizer.py +47 -0
  237. angr/analyses/disassembly.py +1301 -0
  238. angr/analyses/disassembly_utils.py +101 -0
  239. angr/analyses/dominance_frontier.py +57 -0
  240. angr/analyses/fcp/__init__.py +4 -0
  241. angr/analyses/fcp/fcp.py +426 -0
  242. angr/analyses/find_objects_static.py +205 -0
  243. angr/analyses/flirt/__init__.py +47 -0
  244. angr/analyses/flirt/consts.py +160 -0
  245. angr/analyses/flirt/flirt.py +244 -0
  246. angr/analyses/flirt/flirt_function.py +20 -0
  247. angr/analyses/flirt/flirt_matcher.py +351 -0
  248. angr/analyses/flirt/flirt_module.py +32 -0
  249. angr/analyses/flirt/flirt_node.py +23 -0
  250. angr/analyses/flirt/flirt_sig.py +356 -0
  251. angr/analyses/flirt/flirt_utils.py +31 -0
  252. angr/analyses/forward_analysis/__init__.py +12 -0
  253. angr/analyses/forward_analysis/forward_analysis.py +530 -0
  254. angr/analyses/forward_analysis/job_info.py +64 -0
  255. angr/analyses/forward_analysis/visitors/__init__.py +14 -0
  256. angr/analyses/forward_analysis/visitors/call_graph.py +29 -0
  257. angr/analyses/forward_analysis/visitors/function_graph.py +86 -0
  258. angr/analyses/forward_analysis/visitors/graph.py +242 -0
  259. angr/analyses/forward_analysis/visitors/loop.py +29 -0
  260. angr/analyses/forward_analysis/visitors/single_node_graph.py +38 -0
  261. angr/analyses/identifier/__init__.py +5 -0
  262. angr/analyses/identifier/custom_callable.py +137 -0
  263. angr/analyses/identifier/errors.py +10 -0
  264. angr/analyses/identifier/func.py +60 -0
  265. angr/analyses/identifier/functions/__init__.py +37 -0
  266. angr/analyses/identifier/functions/atoi.py +73 -0
  267. angr/analyses/identifier/functions/based_atoi.py +125 -0
  268. angr/analyses/identifier/functions/fdprintf.py +123 -0
  269. angr/analyses/identifier/functions/free.py +64 -0
  270. angr/analyses/identifier/functions/int2str.py +287 -0
  271. angr/analyses/identifier/functions/malloc.py +111 -0
  272. angr/analyses/identifier/functions/memcmp.py +67 -0
  273. angr/analyses/identifier/functions/memcpy.py +89 -0
  274. angr/analyses/identifier/functions/memset.py +43 -0
  275. angr/analyses/identifier/functions/printf.py +123 -0
  276. angr/analyses/identifier/functions/recv_until.py +312 -0
  277. angr/analyses/identifier/functions/skip_calloc.py +73 -0
  278. angr/analyses/identifier/functions/skip_realloc.py +97 -0
  279. angr/analyses/identifier/functions/skip_recv_n.py +105 -0
  280. angr/analyses/identifier/functions/snprintf.py +112 -0
  281. angr/analyses/identifier/functions/sprintf.py +116 -0
  282. angr/analyses/identifier/functions/strcasecmp.py +33 -0
  283. angr/analyses/identifier/functions/strcmp.py +113 -0
  284. angr/analyses/identifier/functions/strcpy.py +43 -0
  285. angr/analyses/identifier/functions/strlen.py +27 -0
  286. angr/analyses/identifier/functions/strncmp.py +104 -0
  287. angr/analyses/identifier/functions/strncpy.py +65 -0
  288. angr/analyses/identifier/functions/strtol.py +89 -0
  289. angr/analyses/identifier/identify.py +825 -0
  290. angr/analyses/identifier/runner.py +360 -0
  291. angr/analyses/init_finder.py +289 -0
  292. angr/analyses/loop_analysis.py +349 -0
  293. angr/analyses/loopfinder.py +171 -0
  294. angr/analyses/patchfinder.py +137 -0
  295. angr/analyses/pathfinder.py +282 -0
  296. angr/analyses/propagator/__init__.py +5 -0
  297. angr/analyses/propagator/engine_base.py +62 -0
  298. angr/analyses/propagator/engine_vex.py +297 -0
  299. angr/analyses/propagator/propagator.py +361 -0
  300. angr/analyses/propagator/top_checker_mixin.py +218 -0
  301. angr/analyses/propagator/values.py +117 -0
  302. angr/analyses/propagator/vex_vars.py +68 -0
  303. angr/analyses/proximity_graph.py +444 -0
  304. angr/analyses/reaching_definitions/__init__.py +67 -0
  305. angr/analyses/reaching_definitions/call_trace.py +73 -0
  306. angr/analyses/reaching_definitions/dep_graph.py +433 -0
  307. angr/analyses/reaching_definitions/engine_ail.py +1130 -0
  308. angr/analyses/reaching_definitions/engine_vex.py +1127 -0
  309. angr/analyses/reaching_definitions/external_codeloc.py +0 -0
  310. angr/analyses/reaching_definitions/function_handler.py +637 -0
  311. angr/analyses/reaching_definitions/function_handler_library/__init__.py +12 -0
  312. angr/analyses/reaching_definitions/function_handler_library/stdio.py +268 -0
  313. angr/analyses/reaching_definitions/function_handler_library/stdlib.py +189 -0
  314. angr/analyses/reaching_definitions/function_handler_library/string.py +147 -0
  315. angr/analyses/reaching_definitions/function_handler_library/unistd.py +44 -0
  316. angr/analyses/reaching_definitions/heap_allocator.py +70 -0
  317. angr/analyses/reaching_definitions/rd_initializer.py +237 -0
  318. angr/analyses/reaching_definitions/rd_state.py +579 -0
  319. angr/analyses/reaching_definitions/reaching_definitions.py +581 -0
  320. angr/analyses/reaching_definitions/subject.py +65 -0
  321. angr/analyses/reassembler.py +2900 -0
  322. angr/analyses/s_liveness.py +203 -0
  323. angr/analyses/s_propagator.py +544 -0
  324. angr/analyses/s_reaching_definitions/__init__.py +12 -0
  325. angr/analyses/s_reaching_definitions/s_rda_model.py +135 -0
  326. angr/analyses/s_reaching_definitions/s_rda_view.py +315 -0
  327. angr/analyses/s_reaching_definitions/s_reaching_definitions.py +174 -0
  328. angr/analyses/smc.py +161 -0
  329. angr/analyses/soot_class_hierarchy.py +273 -0
  330. angr/analyses/stack_pointer_tracker.py +957 -0
  331. angr/analyses/static_hooker.py +53 -0
  332. angr/analyses/typehoon/__init__.py +5 -0
  333. angr/analyses/typehoon/dfa.py +118 -0
  334. angr/analyses/typehoon/lifter.py +122 -0
  335. angr/analyses/typehoon/simple_solver.py +1450 -0
  336. angr/analyses/typehoon/translator.py +279 -0
  337. angr/analyses/typehoon/typeconsts.py +336 -0
  338. angr/analyses/typehoon/typehoon.py +305 -0
  339. angr/analyses/typehoon/typevars.py +578 -0
  340. angr/analyses/typehoon/variance.py +11 -0
  341. angr/analyses/unpacker/__init__.py +6 -0
  342. angr/analyses/unpacker/obfuscation_detector.py +103 -0
  343. angr/analyses/unpacker/packing_detector.py +138 -0
  344. angr/analyses/variable_recovery/__init__.py +9 -0
  345. angr/analyses/variable_recovery/annotations.py +58 -0
  346. angr/analyses/variable_recovery/engine_ail.py +891 -0
  347. angr/analyses/variable_recovery/engine_base.py +1185 -0
  348. angr/analyses/variable_recovery/engine_vex.py +593 -0
  349. angr/analyses/variable_recovery/irsb_scanner.py +143 -0
  350. angr/analyses/variable_recovery/variable_recovery.py +573 -0
  351. angr/analyses/variable_recovery/variable_recovery_base.py +461 -0
  352. angr/analyses/variable_recovery/variable_recovery_fast.py +652 -0
  353. angr/analyses/veritesting.py +626 -0
  354. angr/analyses/vfg.py +1898 -0
  355. angr/analyses/vsa_ddg.py +420 -0
  356. angr/analyses/vtable.py +92 -0
  357. angr/analyses/xrefs.py +286 -0
  358. angr/angrdb/__init__.py +14 -0
  359. angr/angrdb/db.py +206 -0
  360. angr/angrdb/models.py +184 -0
  361. angr/angrdb/serializers/__init__.py +10 -0
  362. angr/angrdb/serializers/cfg_model.py +41 -0
  363. angr/angrdb/serializers/comments.py +60 -0
  364. angr/angrdb/serializers/funcs.py +61 -0
  365. angr/angrdb/serializers/kb.py +111 -0
  366. angr/angrdb/serializers/labels.py +59 -0
  367. angr/angrdb/serializers/loader.py +165 -0
  368. angr/angrdb/serializers/structured_code.py +125 -0
  369. angr/angrdb/serializers/variables.py +58 -0
  370. angr/angrdb/serializers/xrefs.py +48 -0
  371. angr/annocfg.py +317 -0
  372. angr/blade.py +426 -0
  373. angr/block.py +509 -0
  374. angr/callable.py +168 -0
  375. angr/calling_conventions.py +2580 -0
  376. angr/code_location.py +163 -0
  377. angr/codenode.py +145 -0
  378. angr/concretization_strategies/__init__.py +32 -0
  379. angr/concretization_strategies/any.py +17 -0
  380. angr/concretization_strategies/any_named.py +35 -0
  381. angr/concretization_strategies/base.py +81 -0
  382. angr/concretization_strategies/controlled_data.py +58 -0
  383. angr/concretization_strategies/eval.py +19 -0
  384. angr/concretization_strategies/logging.py +35 -0
  385. angr/concretization_strategies/max.py +25 -0
  386. angr/concretization_strategies/nonzero.py +16 -0
  387. angr/concretization_strategies/nonzero_range.py +22 -0
  388. angr/concretization_strategies/norepeats.py +37 -0
  389. angr/concretization_strategies/norepeats_range.py +37 -0
  390. angr/concretization_strategies/range.py +19 -0
  391. angr/concretization_strategies/signed_add.py +31 -0
  392. angr/concretization_strategies/single.py +15 -0
  393. angr/concretization_strategies/solutions.py +20 -0
  394. angr/concretization_strategies/unlimited_range.py +17 -0
  395. angr/distributed/__init__.py +9 -0
  396. angr/distributed/server.py +197 -0
  397. angr/distributed/worker.py +185 -0
  398. angr/engines/__init__.py +67 -0
  399. angr/engines/engine.py +29 -0
  400. angr/engines/failure.py +27 -0
  401. angr/engines/hook.py +68 -0
  402. angr/engines/light/__init__.py +23 -0
  403. angr/engines/light/data.py +681 -0
  404. angr/engines/light/engine.py +1285 -0
  405. angr/engines/pcode/__init__.py +9 -0
  406. angr/engines/pcode/behavior.py +997 -0
  407. angr/engines/pcode/cc.py +128 -0
  408. angr/engines/pcode/emulate.py +443 -0
  409. angr/engines/pcode/engine.py +242 -0
  410. angr/engines/pcode/lifter.py +1428 -0
  411. angr/engines/procedure.py +70 -0
  412. angr/engines/soot/__init__.py +5 -0
  413. angr/engines/soot/engine.py +410 -0
  414. angr/engines/soot/exceptions.py +17 -0
  415. angr/engines/soot/expressions/__init__.py +87 -0
  416. angr/engines/soot/expressions/arrayref.py +22 -0
  417. angr/engines/soot/expressions/base.py +21 -0
  418. angr/engines/soot/expressions/binop.py +28 -0
  419. angr/engines/soot/expressions/cast.py +22 -0
  420. angr/engines/soot/expressions/condition.py +35 -0
  421. angr/engines/soot/expressions/constants.py +47 -0
  422. angr/engines/soot/expressions/instanceOf.py +15 -0
  423. angr/engines/soot/expressions/instancefieldref.py +8 -0
  424. angr/engines/soot/expressions/invoke.py +114 -0
  425. angr/engines/soot/expressions/length.py +8 -0
  426. angr/engines/soot/expressions/local.py +8 -0
  427. angr/engines/soot/expressions/new.py +16 -0
  428. angr/engines/soot/expressions/newArray.py +54 -0
  429. angr/engines/soot/expressions/newMultiArray.py +86 -0
  430. angr/engines/soot/expressions/paramref.py +8 -0
  431. angr/engines/soot/expressions/phi.py +30 -0
  432. angr/engines/soot/expressions/staticfieldref.py +8 -0
  433. angr/engines/soot/expressions/thisref.py +7 -0
  434. angr/engines/soot/expressions/unsupported.py +7 -0
  435. angr/engines/soot/field_dispatcher.py +46 -0
  436. angr/engines/soot/method_dispatcher.py +46 -0
  437. angr/engines/soot/statements/__init__.py +44 -0
  438. angr/engines/soot/statements/assign.py +30 -0
  439. angr/engines/soot/statements/base.py +79 -0
  440. angr/engines/soot/statements/goto.py +14 -0
  441. angr/engines/soot/statements/identity.py +15 -0
  442. angr/engines/soot/statements/if_.py +19 -0
  443. angr/engines/soot/statements/invoke.py +12 -0
  444. angr/engines/soot/statements/return_.py +20 -0
  445. angr/engines/soot/statements/switch.py +41 -0
  446. angr/engines/soot/statements/throw.py +15 -0
  447. angr/engines/soot/values/__init__.py +38 -0
  448. angr/engines/soot/values/arrayref.py +122 -0
  449. angr/engines/soot/values/base.py +7 -0
  450. angr/engines/soot/values/constants.py +18 -0
  451. angr/engines/soot/values/instancefieldref.py +44 -0
  452. angr/engines/soot/values/local.py +18 -0
  453. angr/engines/soot/values/paramref.py +18 -0
  454. angr/engines/soot/values/staticfieldref.py +38 -0
  455. angr/engines/soot/values/strref.py +38 -0
  456. angr/engines/soot/values/thisref.py +149 -0
  457. angr/engines/successors.py +654 -0
  458. angr/engines/syscall.py +51 -0
  459. angr/engines/unicorn.py +490 -0
  460. angr/engines/vex/__init__.py +20 -0
  461. angr/engines/vex/claripy/__init__.py +5 -0
  462. angr/engines/vex/claripy/ccall.py +2097 -0
  463. angr/engines/vex/claripy/datalayer.py +141 -0
  464. angr/engines/vex/claripy/irop.py +1276 -0
  465. angr/engines/vex/heavy/__init__.py +16 -0
  466. angr/engines/vex/heavy/actions.py +231 -0
  467. angr/engines/vex/heavy/concretizers.py +403 -0
  468. angr/engines/vex/heavy/dirty.py +466 -0
  469. angr/engines/vex/heavy/heavy.py +370 -0
  470. angr/engines/vex/heavy/inspect.py +52 -0
  471. angr/engines/vex/heavy/resilience.py +85 -0
  472. angr/engines/vex/heavy/super_fastpath.py +34 -0
  473. angr/engines/vex/lifter.py +420 -0
  474. angr/engines/vex/light/__init__.py +11 -0
  475. angr/engines/vex/light/light.py +551 -0
  476. angr/engines/vex/light/resilience.py +74 -0
  477. angr/engines/vex/light/slicing.py +52 -0
  478. angr/errors.py +609 -0
  479. angr/exploration_techniques/__init__.py +53 -0
  480. angr/exploration_techniques/base.py +126 -0
  481. angr/exploration_techniques/bucketizer.py +94 -0
  482. angr/exploration_techniques/common.py +56 -0
  483. angr/exploration_techniques/dfs.py +37 -0
  484. angr/exploration_techniques/director.py +520 -0
  485. angr/exploration_techniques/driller_core.py +100 -0
  486. angr/exploration_techniques/explorer.py +152 -0
  487. angr/exploration_techniques/lengthlimiter.py +22 -0
  488. angr/exploration_techniques/local_loop_seer.py +65 -0
  489. angr/exploration_techniques/loop_seer.py +236 -0
  490. angr/exploration_techniques/manual_mergepoint.py +82 -0
  491. angr/exploration_techniques/memory_watcher.py +43 -0
  492. angr/exploration_techniques/oppologist.py +92 -0
  493. angr/exploration_techniques/slicecutor.py +118 -0
  494. angr/exploration_techniques/spiller.py +280 -0
  495. angr/exploration_techniques/spiller_db.py +27 -0
  496. angr/exploration_techniques/stochastic.py +56 -0
  497. angr/exploration_techniques/stub_stasher.py +19 -0
  498. angr/exploration_techniques/suggestions.py +159 -0
  499. angr/exploration_techniques/tech_builder.py +49 -0
  500. angr/exploration_techniques/threading.py +69 -0
  501. angr/exploration_techniques/timeout.py +34 -0
  502. angr/exploration_techniques/tracer.py +1098 -0
  503. angr/exploration_techniques/unique.py +106 -0
  504. angr/exploration_techniques/veritesting.py +37 -0
  505. angr/factory.py +404 -0
  506. angr/flirt/__init__.py +97 -0
  507. angr/flirt/build_sig.py +305 -0
  508. angr/graph_utils.py +0 -0
  509. angr/keyed_region.py +525 -0
  510. angr/knowledge_base.py +143 -0
  511. angr/knowledge_plugins/__init__.py +43 -0
  512. angr/knowledge_plugins/callsite_prototypes.py +53 -0
  513. angr/knowledge_plugins/cfg/__init__.py +18 -0
  514. angr/knowledge_plugins/cfg/cfg_manager.py +95 -0
  515. angr/knowledge_plugins/cfg/cfg_model.py +1045 -0
  516. angr/knowledge_plugins/cfg/cfg_node.py +536 -0
  517. angr/knowledge_plugins/cfg/indirect_jump.py +65 -0
  518. angr/knowledge_plugins/cfg/memory_data.py +156 -0
  519. angr/knowledge_plugins/comments.py +16 -0
  520. angr/knowledge_plugins/custom_strings.py +38 -0
  521. angr/knowledge_plugins/data.py +22 -0
  522. angr/knowledge_plugins/debug_variables.py +216 -0
  523. angr/knowledge_plugins/functions/__init__.py +9 -0
  524. angr/knowledge_plugins/functions/function.py +1772 -0
  525. angr/knowledge_plugins/functions/function_manager.py +526 -0
  526. angr/knowledge_plugins/functions/function_parser.py +299 -0
  527. angr/knowledge_plugins/functions/soot_function.py +128 -0
  528. angr/knowledge_plugins/indirect_jumps.py +35 -0
  529. angr/knowledge_plugins/key_definitions/__init__.py +17 -0
  530. angr/knowledge_plugins/key_definitions/atoms.py +374 -0
  531. angr/knowledge_plugins/key_definitions/constants.py +29 -0
  532. angr/knowledge_plugins/key_definitions/definition.py +214 -0
  533. angr/knowledge_plugins/key_definitions/environment.py +96 -0
  534. angr/knowledge_plugins/key_definitions/heap_address.py +33 -0
  535. angr/knowledge_plugins/key_definitions/key_definition_manager.py +82 -0
  536. angr/knowledge_plugins/key_definitions/live_definitions.py +1010 -0
  537. angr/knowledge_plugins/key_definitions/liveness.py +165 -0
  538. angr/knowledge_plugins/key_definitions/rd_model.py +171 -0
  539. angr/knowledge_plugins/key_definitions/tag.py +78 -0
  540. angr/knowledge_plugins/key_definitions/undefined.py +70 -0
  541. angr/knowledge_plugins/key_definitions/unknown_size.py +86 -0
  542. angr/knowledge_plugins/key_definitions/uses.py +178 -0
  543. angr/knowledge_plugins/labels.py +110 -0
  544. angr/knowledge_plugins/obfuscations.py +37 -0
  545. angr/knowledge_plugins/patches.py +126 -0
  546. angr/knowledge_plugins/plugin.py +24 -0
  547. angr/knowledge_plugins/propagations/__init__.py +10 -0
  548. angr/knowledge_plugins/propagations/prop_value.py +191 -0
  549. angr/knowledge_plugins/propagations/propagation_manager.py +60 -0
  550. angr/knowledge_plugins/propagations/propagation_model.py +73 -0
  551. angr/knowledge_plugins/propagations/states.py +552 -0
  552. angr/knowledge_plugins/structured_code.py +63 -0
  553. angr/knowledge_plugins/types.py +88 -0
  554. angr/knowledge_plugins/variables/__init__.py +8 -0
  555. angr/knowledge_plugins/variables/variable_access.py +113 -0
  556. angr/knowledge_plugins/variables/variable_manager.py +1368 -0
  557. angr/knowledge_plugins/xrefs/__init__.py +12 -0
  558. angr/knowledge_plugins/xrefs/xref.py +150 -0
  559. angr/knowledge_plugins/xrefs/xref_manager.py +127 -0
  560. angr/knowledge_plugins/xrefs/xref_types.py +16 -0
  561. angr/lib/angr_native.dylib +0 -0
  562. angr/misc/__init__.py +19 -0
  563. angr/misc/ansi.py +47 -0
  564. angr/misc/autoimport.py +90 -0
  565. angr/misc/bug_report.py +117 -0
  566. angr/misc/hookset.py +106 -0
  567. angr/misc/loggers.py +130 -0
  568. angr/misc/picklable_lock.py +46 -0
  569. angr/misc/plugins.py +289 -0
  570. angr/misc/telemetry.py +54 -0
  571. angr/misc/testing.py +24 -0
  572. angr/misc/ux.py +31 -0
  573. angr/procedures/__init__.py +12 -0
  574. angr/procedures/advapi32/__init__.py +0 -0
  575. angr/procedures/cgc/__init__.py +3 -0
  576. angr/procedures/cgc/_terminate.py +11 -0
  577. angr/procedures/cgc/allocate.py +75 -0
  578. angr/procedures/cgc/deallocate.py +67 -0
  579. angr/procedures/cgc/fdwait.py +65 -0
  580. angr/procedures/cgc/random.py +67 -0
  581. angr/procedures/cgc/receive.py +93 -0
  582. angr/procedures/cgc/transmit.py +65 -0
  583. angr/procedures/definitions/__init__.py +779 -0
  584. angr/procedures/definitions/cgc.py +20 -0
  585. angr/procedures/definitions/glibc.py +8372 -0
  586. angr/procedures/definitions/gnulib.py +32 -0
  587. angr/procedures/definitions/libstdcpp.py +21 -0
  588. angr/procedures/definitions/linux_kernel.py +6171 -0
  589. angr/procedures/definitions/linux_loader.py +7 -0
  590. angr/procedures/definitions/msvcr.py +16 -0
  591. angr/procedures/definitions/parse_syscalls_from_local_system.py +50 -0
  592. angr/procedures/definitions/parse_win32json.py +2553 -0
  593. angr/procedures/definitions/types_stl.py +22 -0
  594. angr/procedures/definitions/types_win32.py +34482 -0
  595. angr/procedures/definitions/wdk_api-ms-win-dx-d3dkmt-l1-1-4.py +30 -0
  596. angr/procedures/definitions/wdk_api-ms-win-dx-d3dkmt-l1-1-6.py +26 -0
  597. angr/procedures/definitions/wdk_clfs.py +140 -0
  598. angr/procedures/definitions/wdk_fltmgr.py +556 -0
  599. angr/procedures/definitions/wdk_fwpkclnt.py +30 -0
  600. angr/procedures/definitions/wdk_fwpuclnt.py +316 -0
  601. angr/procedures/definitions/wdk_gdi32.py +366 -0
  602. angr/procedures/definitions/wdk_hal.py +78 -0
  603. angr/procedures/definitions/wdk_ksecdd.py +62 -0
  604. angr/procedures/definitions/wdk_ndis.py +238 -0
  605. angr/procedures/definitions/wdk_ntoskrnl.py +3451 -0
  606. angr/procedures/definitions/wdk_offreg.py +72 -0
  607. angr/procedures/definitions/wdk_pshed.py +36 -0
  608. angr/procedures/definitions/wdk_secur32.py +40 -0
  609. angr/procedures/definitions/wdk_vhfum.py +34 -0
  610. angr/procedures/definitions/win32_aclui.py +30 -0
  611. angr/procedures/definitions/win32_activeds.py +68 -0
  612. angr/procedures/definitions/win32_advapi32.py +1684 -0
  613. angr/procedures/definitions/win32_advpack.py +124 -0
  614. angr/procedures/definitions/win32_amsi.py +38 -0
  615. angr/procedures/definitions/win32_api-ms-win-appmodel-runtime-l1-1-1.py +44 -0
  616. angr/procedures/definitions/win32_api-ms-win-appmodel-runtime-l1-1-3.py +34 -0
  617. angr/procedures/definitions/win32_api-ms-win-appmodel-runtime-l1-1-6.py +26 -0
  618. angr/procedures/definitions/win32_api-ms-win-core-apiquery-l2-1-0.py +26 -0
  619. angr/procedures/definitions/win32_api-ms-win-core-backgroundtask-l1-1-0.py +26 -0
  620. angr/procedures/definitions/win32_api-ms-win-core-comm-l1-1-1.py +26 -0
  621. angr/procedures/definitions/win32_api-ms-win-core-comm-l1-1-2.py +26 -0
  622. angr/procedures/definitions/win32_api-ms-win-core-enclave-l1-1-1.py +30 -0
  623. angr/procedures/definitions/win32_api-ms-win-core-errorhandling-l1-1-3.py +26 -0
  624. angr/procedures/definitions/win32_api-ms-win-core-featurestaging-l1-1-0.py +34 -0
  625. angr/procedures/definitions/win32_api-ms-win-core-featurestaging-l1-1-1.py +26 -0
  626. angr/procedures/definitions/win32_api-ms-win-core-file-fromapp-l1-1-0.py +46 -0
  627. angr/procedures/definitions/win32_api-ms-win-core-handle-l1-1-0.py +26 -0
  628. angr/procedures/definitions/win32_api-ms-win-core-ioring-l1-1-0.py +48 -0
  629. angr/procedures/definitions/win32_api-ms-win-core-marshal-l1-1-0.py +32 -0
  630. angr/procedures/definitions/win32_api-ms-win-core-memory-l1-1-3.py +32 -0
  631. angr/procedures/definitions/win32_api-ms-win-core-memory-l1-1-4.py +26 -0
  632. angr/procedures/definitions/win32_api-ms-win-core-memory-l1-1-5.py +30 -0
  633. angr/procedures/definitions/win32_api-ms-win-core-memory-l1-1-6.py +32 -0
  634. angr/procedures/definitions/win32_api-ms-win-core-memory-l1-1-7.py +28 -0
  635. angr/procedures/definitions/win32_api-ms-win-core-memory-l1-1-8.py +30 -0
  636. angr/procedures/definitions/win32_api-ms-win-core-path-l1-1-0.py +68 -0
  637. angr/procedures/definitions/win32_api-ms-win-core-psm-appnotify-l1-1-0.py +28 -0
  638. angr/procedures/definitions/win32_api-ms-win-core-psm-appnotify-l1-1-1.py +28 -0
  639. angr/procedures/definitions/win32_api-ms-win-core-realtime-l1-1-1.py +30 -0
  640. angr/procedures/definitions/win32_api-ms-win-core-realtime-l1-1-2.py +30 -0
  641. angr/procedures/definitions/win32_api-ms-win-core-slapi-l1-1-0.py +26 -0
  642. angr/procedures/definitions/win32_api-ms-win-core-state-helpers-l1-1-0.py +26 -0
  643. angr/procedures/definitions/win32_api-ms-win-core-synch-l1-2-0.py +30 -0
  644. angr/procedures/definitions/win32_api-ms-win-core-sysinfo-l1-2-0.py +26 -0
  645. angr/procedures/definitions/win32_api-ms-win-core-sysinfo-l1-2-3.py +28 -0
  646. angr/procedures/definitions/win32_api-ms-win-core-sysinfo-l1-2-4.py +28 -0
  647. angr/procedures/definitions/win32_api-ms-win-core-sysinfo-l1-2-6.py +26 -0
  648. angr/procedures/definitions/win32_api-ms-win-core-util-l1-1-1.py +28 -0
  649. angr/procedures/definitions/win32_api-ms-win-core-winrt-error-l1-1-0.py +44 -0
  650. angr/procedures/definitions/win32_api-ms-win-core-winrt-error-l1-1-1.py +38 -0
  651. angr/procedures/definitions/win32_api-ms-win-core-winrt-l1-1-0.py +40 -0
  652. angr/procedures/definitions/win32_api-ms-win-core-winrt-registration-l1-1-0.py +24 -0
  653. angr/procedures/definitions/win32_api-ms-win-core-winrt-robuffer-l1-1-0.py +24 -0
  654. angr/procedures/definitions/win32_api-ms-win-core-winrt-roparameterizediid-l1-1-0.py +28 -0
  655. angr/procedures/definitions/win32_api-ms-win-core-winrt-string-l1-1-0.py +76 -0
  656. angr/procedures/definitions/win32_api-ms-win-core-winrt-string-l1-1-1.py +24 -0
  657. angr/procedures/definitions/win32_api-ms-win-core-wow64-l1-1-1.py +30 -0
  658. angr/procedures/definitions/win32_api-ms-win-devices-query-l1-1-0.py +42 -0
  659. angr/procedures/definitions/win32_api-ms-win-devices-query-l1-1-1.py +34 -0
  660. angr/procedures/definitions/win32_api-ms-win-dx-d3dkmt-l1-1-0.py +26 -0
  661. angr/procedures/definitions/win32_api-ms-win-gaming-deviceinformation-l1-1-0.py +26 -0
  662. angr/procedures/definitions/win32_api-ms-win-gaming-expandedresources-l1-1-0.py +30 -0
  663. angr/procedures/definitions/win32_api-ms-win-gaming-tcui-l1-1-0.py +38 -0
  664. angr/procedures/definitions/win32_api-ms-win-gaming-tcui-l1-1-1.py +28 -0
  665. angr/procedures/definitions/win32_api-ms-win-gaming-tcui-l1-1-2.py +38 -0
  666. angr/procedures/definitions/win32_api-ms-win-gaming-tcui-l1-1-3.py +28 -0
  667. angr/procedures/definitions/win32_api-ms-win-gaming-tcui-l1-1-4.py +40 -0
  668. angr/procedures/definitions/win32_api-ms-win-mm-misc-l1-1-1.py +26 -0
  669. angr/procedures/definitions/win32_api-ms-win-net-isolation-l1-1-0.py +40 -0
  670. angr/procedures/definitions/win32_api-ms-win-security-base-l1-2-2.py +26 -0
  671. angr/procedures/definitions/win32_api-ms-win-security-isolatedcontainer-l1-1-0.py +26 -0
  672. angr/procedures/definitions/win32_api-ms-win-security-isolatedcontainer-l1-1-1.py +26 -0
  673. angr/procedures/definitions/win32_api-ms-win-service-core-l1-1-3.py +26 -0
  674. angr/procedures/definitions/win32_api-ms-win-service-core-l1-1-4.py +26 -0
  675. angr/procedures/definitions/win32_api-ms-win-service-core-l1-1-5.py +28 -0
  676. angr/procedures/definitions/win32_api-ms-win-shcore-scaling-l1-1-0.py +30 -0
  677. angr/procedures/definitions/win32_api-ms-win-shcore-scaling-l1-1-1.py +36 -0
  678. angr/procedures/definitions/win32_api-ms-win-shcore-scaling-l1-1-2.py +26 -0
  679. angr/procedures/definitions/win32_api-ms-win-shcore-stream-winrt-l1-1-0.py +28 -0
  680. angr/procedures/definitions/win32_api-ms-win-wsl-api-l1-1-0.py +38 -0
  681. angr/procedures/definitions/win32_apphelp.py +26 -0
  682. angr/procedures/definitions/win32_authz.py +90 -0
  683. angr/procedures/definitions/win32_avicap32.py +32 -0
  684. angr/procedures/definitions/win32_avifil32.py +144 -0
  685. angr/procedures/definitions/win32_avrt.py +52 -0
  686. angr/procedures/definitions/win32_bcp47mrm.py +28 -0
  687. angr/procedures/definitions/win32_bcrypt.py +130 -0
  688. angr/procedures/definitions/win32_bcryptprimitives.py +28 -0
  689. angr/procedures/definitions/win32_bluetoothapis.py +106 -0
  690. angr/procedures/definitions/win32_bthprops.py +34 -0
  691. angr/procedures/definitions/win32_bthprops_cpl.py +36 -0
  692. angr/procedures/definitions/win32_cabinet.py +68 -0
  693. angr/procedures/definitions/win32_certadm.py +60 -0
  694. angr/procedures/definitions/win32_certpoleng.py +40 -0
  695. angr/procedures/definitions/win32_cfgmgr32.py +502 -0
  696. angr/procedures/definitions/win32_chakra.py +198 -0
  697. angr/procedures/definitions/win32_cldapi.py +96 -0
  698. angr/procedures/definitions/win32_clfsw32.py +142 -0
  699. angr/procedures/definitions/win32_clusapi.py +584 -0
  700. angr/procedures/definitions/win32_comctl32.py +254 -0
  701. angr/procedures/definitions/win32_comdlg32.py +66 -0
  702. angr/procedures/definitions/win32_compstui.py +32 -0
  703. angr/procedures/definitions/win32_computecore.py +132 -0
  704. angr/procedures/definitions/win32_computenetwork.py +110 -0
  705. angr/procedures/definitions/win32_computestorage.py +48 -0
  706. angr/procedures/definitions/win32_comsvcs.py +38 -0
  707. angr/procedures/definitions/win32_coremessaging.py +24 -0
  708. angr/procedures/definitions/win32_credui.py +62 -0
  709. angr/procedures/definitions/win32_crypt32.py +482 -0
  710. angr/procedures/definitions/win32_cryptnet.py +34 -0
  711. angr/procedures/definitions/win32_cryptui.py +44 -0
  712. angr/procedures/definitions/win32_cryptxml.py +62 -0
  713. angr/procedures/definitions/win32_cscapi.py +32 -0
  714. angr/procedures/definitions/win32_d2d1.py +50 -0
  715. angr/procedures/definitions/win32_d3d10.py +78 -0
  716. angr/procedures/definitions/win32_d3d10_1.py +28 -0
  717. angr/procedures/definitions/win32_d3d11.py +30 -0
  718. angr/procedures/definitions/win32_d3d12.py +40 -0
  719. angr/procedures/definitions/win32_d3d9.py +46 -0
  720. angr/procedures/definitions/win32_d3dcompiler_47.py +76 -0
  721. angr/procedures/definitions/win32_d3dcsx.py +42 -0
  722. angr/procedures/definitions/win32_davclnt.py +60 -0
  723. angr/procedures/definitions/win32_dbgeng.py +32 -0
  724. angr/procedures/definitions/win32_dbghelp.py +462 -0
  725. angr/procedures/definitions/win32_dbgmodel.py +26 -0
  726. angr/procedures/definitions/win32_dciman32.py +64 -0
  727. angr/procedures/definitions/win32_dcomp.py +48 -0
  728. angr/procedures/definitions/win32_ddraw.py +38 -0
  729. angr/procedures/definitions/win32_deviceaccess.py +26 -0
  730. angr/procedures/definitions/win32_dflayout.py +26 -0
  731. angr/procedures/definitions/win32_dhcpcsvc.py +54 -0
  732. angr/procedures/definitions/win32_dhcpcsvc6.py +36 -0
  733. angr/procedures/definitions/win32_dhcpsapi.py +416 -0
  734. angr/procedures/definitions/win32_diagnosticdataquery.py +94 -0
  735. angr/procedures/definitions/win32_dinput8.py +26 -0
  736. angr/procedures/definitions/win32_directml.py +28 -0
  737. angr/procedures/definitions/win32_dmprocessxmlfiltered.py +26 -0
  738. angr/procedures/definitions/win32_dnsapi.py +152 -0
  739. angr/procedures/definitions/win32_drt.py +56 -0
  740. angr/procedures/definitions/win32_drtprov.py +42 -0
  741. angr/procedures/definitions/win32_drttransport.py +28 -0
  742. angr/procedures/definitions/win32_dsound.py +44 -0
  743. angr/procedures/definitions/win32_dsparse.py +62 -0
  744. angr/procedures/definitions/win32_dsprop.py +38 -0
  745. angr/procedures/definitions/win32_dssec.py +32 -0
  746. angr/procedures/definitions/win32_dsuiext.py +32 -0
  747. angr/procedures/definitions/win32_dwmapi.py +86 -0
  748. angr/procedures/definitions/win32_dwrite.py +26 -0
  749. angr/procedures/definitions/win32_dxcompiler.py +28 -0
  750. angr/procedures/definitions/win32_dxcore.py +26 -0
  751. angr/procedures/definitions/win32_dxgi.py +36 -0
  752. angr/procedures/definitions/win32_dxva2.py +100 -0
  753. angr/procedures/definitions/win32_eappcfg.py +52 -0
  754. angr/procedures/definitions/win32_eappprxy.py +60 -0
  755. angr/procedures/definitions/win32_efswrt.py +28 -0
  756. angr/procedures/definitions/win32_elscore.py +34 -0
  757. angr/procedures/definitions/win32_esent.py +482 -0
  758. angr/procedures/definitions/win32_evr.py +38 -0
  759. angr/procedures/definitions/win32_faultrep.py +32 -0
  760. angr/procedures/definitions/win32_fhsvcctl.py +38 -0
  761. angr/procedures/definitions/win32_firewallapi.py +30 -0
  762. angr/procedures/definitions/win32_fltlib.py +80 -0
  763. angr/procedures/definitions/win32_fontsub.py +28 -0
  764. angr/procedures/definitions/win32_forceinline.py +30 -0
  765. angr/procedures/definitions/win32_fwpuclnt.py +408 -0
  766. angr/procedures/definitions/win32_fxsutility.py +28 -0
  767. angr/procedures/definitions/win32_gdi32.py +886 -0
  768. angr/procedures/definitions/win32_gdiplus.py +1282 -0
  769. angr/procedures/definitions/win32_glu32.py +128 -0
  770. angr/procedures/definitions/win32_gpedit.py +36 -0
  771. angr/procedures/definitions/win32_hhctrl_ocx.py +28 -0
  772. angr/procedures/definitions/win32_hid.py +114 -0
  773. angr/procedures/definitions/win32_hlink.py +80 -0
  774. angr/procedures/definitions/win32_hrtfapo.py +26 -0
  775. angr/procedures/definitions/win32_httpapi.py +110 -0
  776. angr/procedures/definitions/win32_icm32.py +66 -0
  777. angr/procedures/definitions/win32_icmui.py +28 -0
  778. angr/procedures/definitions/win32_icu.py +2074 -0
  779. angr/procedures/definitions/win32_ieframe.py +82 -0
  780. angr/procedures/definitions/win32_imagehlp.py +76 -0
  781. angr/procedures/definitions/win32_imgutil.py +42 -0
  782. angr/procedures/definitions/win32_imm32.py +188 -0
  783. angr/procedures/definitions/win32_infocardapi.py +58 -0
  784. angr/procedures/definitions/win32_inkobjcore.py +78 -0
  785. angr/procedures/definitions/win32_iphlpapi.py +426 -0
  786. angr/procedures/definitions/win32_iscsidsc.py +182 -0
  787. angr/procedures/definitions/win32_isolatedwindowsenvironmentutils.py +28 -0
  788. angr/procedures/definitions/win32_kernel32.py +3185 -0
  789. angr/procedures/definitions/win32_kernelbase.py +36 -0
  790. angr/procedures/definitions/win32_keycredmgr.py +32 -0
  791. angr/procedures/definitions/win32_ksproxy_ax.py +36 -0
  792. angr/procedures/definitions/win32_ksuser.py +40 -0
  793. angr/procedures/definitions/win32_ktmw32.py +102 -0
  794. angr/procedures/definitions/win32_licenseprotection.py +28 -0
  795. angr/procedures/definitions/win32_loadperf.py +48 -0
  796. angr/procedures/definitions/win32_magnification.py +62 -0
  797. angr/procedures/definitions/win32_mapi32.py +156 -0
  798. angr/procedures/definitions/win32_mdmlocalmanagement.py +30 -0
  799. angr/procedures/definitions/win32_mdmregistration.py +54 -0
  800. angr/procedures/definitions/win32_mf.py +148 -0
  801. angr/procedures/definitions/win32_mfcore.py +28 -0
  802. angr/procedures/definitions/win32_mfplat.py +314 -0
  803. angr/procedures/definitions/win32_mfplay.py +26 -0
  804. angr/procedures/definitions/win32_mfreadwrite.py +34 -0
  805. angr/procedures/definitions/win32_mfsensorgroup.py +44 -0
  806. angr/procedures/definitions/win32_mfsrcsnk.py +28 -0
  807. angr/procedures/definitions/win32_mgmtapi.py +42 -0
  808. angr/procedures/definitions/win32_mi.py +26 -0
  809. angr/procedures/definitions/win32_mmdevapi.py +26 -0
  810. angr/procedures/definitions/win32_mpr.py +118 -0
  811. angr/procedures/definitions/win32_mprapi.py +248 -0
  812. angr/procedures/definitions/win32_mqrt.py +92 -0
  813. angr/procedures/definitions/win32_mrmsupport.py +78 -0
  814. angr/procedures/definitions/win32_msacm32.py +108 -0
  815. angr/procedures/definitions/win32_msajapi.py +1118 -0
  816. angr/procedures/definitions/win32_mscms.py +182 -0
  817. angr/procedures/definitions/win32_mscoree.py +78 -0
  818. angr/procedures/definitions/win32_msctfmonitor.py +30 -0
  819. angr/procedures/definitions/win32_msdelta.py +56 -0
  820. angr/procedures/definitions/win32_msdmo.py +46 -0
  821. angr/procedures/definitions/win32_msdrm.py +192 -0
  822. angr/procedures/definitions/win32_msi.py +552 -0
  823. angr/procedures/definitions/win32_msimg32.py +30 -0
  824. angr/procedures/definitions/win32_mspatcha.py +56 -0
  825. angr/procedures/definitions/win32_mspatchc.py +42 -0
  826. angr/procedures/definitions/win32_msports.py +38 -0
  827. angr/procedures/definitions/win32_msrating.py +62 -0
  828. angr/procedures/definitions/win32_mssign32.py +44 -0
  829. angr/procedures/definitions/win32_mstask.py +28 -0
  830. angr/procedures/definitions/win32_msvfw32.py +110 -0
  831. angr/procedures/definitions/win32_mswsock.py +56 -0
  832. angr/procedures/definitions/win32_mtxdm.py +26 -0
  833. angr/procedures/definitions/win32_ncrypt.py +102 -0
  834. angr/procedures/definitions/win32_ndfapi.py +56 -0
  835. angr/procedures/definitions/win32_netapi32.py +436 -0
  836. angr/procedures/definitions/win32_netsh.py +40 -0
  837. angr/procedures/definitions/win32_netshell.py +28 -0
  838. angr/procedures/definitions/win32_newdev.py +46 -0
  839. angr/procedures/definitions/win32_ninput.py +84 -0
  840. angr/procedures/definitions/win32_normaliz.py +28 -0
  841. angr/procedures/definitions/win32_ntdll.py +171 -0
  842. angr/procedures/definitions/win32_ntdllk.py +26 -0
  843. angr/procedures/definitions/win32_ntdsapi.py +186 -0
  844. angr/procedures/definitions/win32_ntlanman.py +44 -0
  845. angr/procedures/definitions/win32_odbc32.py +392 -0
  846. angr/procedures/definitions/win32_odbcbcp.py +78 -0
  847. angr/procedures/definitions/win32_ole32.py +658 -0
  848. angr/procedures/definitions/win32_oleacc.py +58 -0
  849. angr/procedures/definitions/win32_oleaut32.py +834 -0
  850. angr/procedures/definitions/win32_oledlg.py +70 -0
  851. angr/procedures/definitions/win32_ondemandconnroutehelper.py +34 -0
  852. angr/procedures/definitions/win32_opengl32.py +734 -0
  853. angr/procedures/definitions/win32_opmxbox.py +30 -0
  854. angr/procedures/definitions/win32_p2p.py +240 -0
  855. angr/procedures/definitions/win32_p2pgraph.py +98 -0
  856. angr/procedures/definitions/win32_pdh.py +220 -0
  857. angr/procedures/definitions/win32_peerdist.py +80 -0
  858. angr/procedures/definitions/win32_powrprof.py +192 -0
  859. angr/procedures/definitions/win32_prntvpt.py +46 -0
  860. angr/procedures/definitions/win32_projectedfslib.py +62 -0
  861. angr/procedures/definitions/win32_propsys.py +460 -0
  862. angr/procedures/definitions/win32_psapi.py +78 -0
  863. angr/procedures/definitions/win32_quartz.py +28 -0
  864. angr/procedures/definitions/win32_query.py +32 -0
  865. angr/procedures/definitions/win32_qwave.py +46 -0
  866. angr/procedures/definitions/win32_rasapi32.py +192 -0
  867. angr/procedures/definitions/win32_rasdlg.py +36 -0
  868. angr/procedures/definitions/win32_resutils.py +264 -0
  869. angr/procedures/definitions/win32_rometadata.py +24 -0
  870. angr/procedures/definitions/win32_rpcns4.py +146 -0
  871. angr/procedures/definitions/win32_rpcproxy.py +32 -0
  872. angr/procedures/definitions/win32_rpcrt4.py +918 -0
  873. angr/procedures/definitions/win32_rstrtmgr.py +46 -0
  874. angr/procedures/definitions/win32_rtm.py +176 -0
  875. angr/procedures/definitions/win32_rtutils.py +106 -0
  876. angr/procedures/definitions/win32_rtworkq.py +90 -0
  877. angr/procedures/definitions/win32_sas.py +26 -0
  878. angr/procedures/definitions/win32_scarddlg.py +34 -0
  879. angr/procedures/definitions/win32_schannel.py +42 -0
  880. angr/procedures/definitions/win32_sechost.py +28 -0
  881. angr/procedures/definitions/win32_secur32.py +202 -0
  882. angr/procedures/definitions/win32_sensapi.py +30 -0
  883. angr/procedures/definitions/win32_sensorsutilsv2.py +104 -0
  884. angr/procedures/definitions/win32_setupapi.py +692 -0
  885. angr/procedures/definitions/win32_sfc.py +36 -0
  886. angr/procedures/definitions/win32_shdocvw.py +30 -0
  887. angr/procedures/definitions/win32_shell32.py +512 -0
  888. angr/procedures/definitions/win32_shlwapi.py +744 -0
  889. angr/procedures/definitions/win32_slc.py +88 -0
  890. angr/procedures/definitions/win32_slcext.py +32 -0
  891. angr/procedures/definitions/win32_slwga.py +26 -0
  892. angr/procedures/definitions/win32_snmpapi.py +76 -0
  893. angr/procedures/definitions/win32_spoolss.py +76 -0
  894. angr/procedures/definitions/win32_srclient.py +26 -0
  895. angr/procedures/definitions/win32_srpapi.py +46 -0
  896. angr/procedures/definitions/win32_sspicli.py +38 -0
  897. angr/procedures/definitions/win32_sti.py +26 -0
  898. angr/procedures/definitions/win32_t2embed.py +52 -0
  899. angr/procedures/definitions/win32_tapi32.py +522 -0
  900. angr/procedures/definitions/win32_tbs.py +52 -0
  901. angr/procedures/definitions/win32_tdh.py +78 -0
  902. angr/procedures/definitions/win32_tokenbinding.py +44 -0
  903. angr/procedures/definitions/win32_traffic.py +64 -0
  904. angr/procedures/definitions/win32_txfw32.py +42 -0
  905. angr/procedures/definitions/win32_ualapi.py +32 -0
  906. angr/procedures/definitions/win32_uiautomationcore.py +220 -0
  907. angr/procedures/definitions/win32_urlmon.py +178 -0
  908. angr/procedures/definitions/win32_user32.py +1551 -0
  909. angr/procedures/definitions/win32_userenv.py +112 -0
  910. angr/procedures/definitions/win32_usp10.py +104 -0
  911. angr/procedures/definitions/win32_uxtheme.py +178 -0
  912. angr/procedures/definitions/win32_verifier.py +26 -0
  913. angr/procedures/definitions/win32_version.py +52 -0
  914. angr/procedures/definitions/win32_vertdll.py +38 -0
  915. angr/procedures/definitions/win32_virtdisk.py +82 -0
  916. angr/procedures/definitions/win32_vmdevicehost.py +50 -0
  917. angr/procedures/definitions/win32_vmsavedstatedumpprovider.py +110 -0
  918. angr/procedures/definitions/win32_vssapi.py +26 -0
  919. angr/procedures/definitions/win32_wcmapi.py +34 -0
  920. angr/procedures/definitions/win32_wdsbp.py +38 -0
  921. angr/procedures/definitions/win32_wdsclientapi.py +98 -0
  922. angr/procedures/definitions/win32_wdsmc.py +36 -0
  923. angr/procedures/definitions/win32_wdspxe.py +86 -0
  924. angr/procedures/definitions/win32_wdstptc.py +50 -0
  925. angr/procedures/definitions/win32_webauthn.py +50 -0
  926. angr/procedures/definitions/win32_webservices.py +410 -0
  927. angr/procedures/definitions/win32_websocket.py +50 -0
  928. angr/procedures/definitions/win32_wecapi.py +54 -0
  929. angr/procedures/definitions/win32_wer.py +66 -0
  930. angr/procedures/definitions/win32_wevtapi.py +94 -0
  931. angr/procedures/definitions/win32_winbio.py +132 -0
  932. angr/procedures/definitions/win32_windows_ai_machinelearning.py +26 -0
  933. angr/procedures/definitions/win32_windows_data_pdf.py +24 -0
  934. angr/procedures/definitions/win32_windows_media_mediacontrol.py +40 -0
  935. angr/procedures/definitions/win32_windows_networking.py +26 -0
  936. angr/procedures/definitions/win32_windows_ui_xaml.py +28 -0
  937. angr/procedures/definitions/win32_windowscodecs.py +42 -0
  938. angr/procedures/definitions/win32_winfax.py +136 -0
  939. angr/procedures/definitions/win32_winhttp.py +136 -0
  940. angr/procedures/definitions/win32_winhvemulation.py +32 -0
  941. angr/procedures/definitions/win32_winhvplatform.py +156 -0
  942. angr/procedures/definitions/win32_wininet.py +616 -0
  943. angr/procedures/definitions/win32_winml.py +26 -0
  944. angr/procedures/definitions/win32_winmm.py +376 -0
  945. angr/procedures/definitions/win32_winscard.py +164 -0
  946. angr/procedures/definitions/win32_winspool.py +364 -0
  947. angr/procedures/definitions/win32_winspool_drv.py +368 -0
  948. angr/procedures/definitions/win32_wintrust.py +144 -0
  949. angr/procedures/definitions/win32_winusb.py +92 -0
  950. angr/procedures/definitions/win32_wlanapi.py +144 -0
  951. angr/procedures/definitions/win32_wlanui.py +26 -0
  952. angr/procedures/definitions/win32_wldap32.py +510 -0
  953. angr/procedures/definitions/win32_wldp.py +42 -0
  954. angr/procedures/definitions/win32_wmvcore.py +46 -0
  955. angr/procedures/definitions/win32_wnvapi.py +28 -0
  956. angr/procedures/definitions/win32_wofutil.py +46 -0
  957. angr/procedures/definitions/win32_ws2_32.py +344 -0
  958. angr/procedures/definitions/win32_wscapi.py +36 -0
  959. angr/procedures/definitions/win32_wsclient.py +30 -0
  960. angr/procedures/definitions/win32_wsdapi.py +88 -0
  961. angr/procedures/definitions/win32_wsmsvc.py +90 -0
  962. angr/procedures/definitions/win32_wsnmp32.py +122 -0
  963. angr/procedures/definitions/win32_wtsapi32.py +150 -0
  964. angr/procedures/definitions/win32_xaudio2_8.py +32 -0
  965. angr/procedures/definitions/win32_xinput1_4.py +38 -0
  966. angr/procedures/definitions/win32_xinputuap.py +36 -0
  967. angr/procedures/definitions/win32_xmllite.py +36 -0
  968. angr/procedures/definitions/win32_xolehlp.py +32 -0
  969. angr/procedures/definitions/win32_xpsprint.py +28 -0
  970. angr/procedures/glibc/__ctype_b_loc.py +21 -0
  971. angr/procedures/glibc/__ctype_tolower_loc.py +21 -0
  972. angr/procedures/glibc/__ctype_toupper_loc.py +21 -0
  973. angr/procedures/glibc/__errno_location.py +7 -0
  974. angr/procedures/glibc/__init__.py +3 -0
  975. angr/procedures/glibc/__libc_init.py +37 -0
  976. angr/procedures/glibc/__libc_start_main.py +301 -0
  977. angr/procedures/glibc/dynamic_loading.py +20 -0
  978. angr/procedures/glibc/scanf.py +11 -0
  979. angr/procedures/glibc/sscanf.py +6 -0
  980. angr/procedures/gnulib/__init__.py +3 -0
  981. angr/procedures/gnulib/xalloc_die.py +14 -0
  982. angr/procedures/gnulib/xstrtol_fatal.py +14 -0
  983. angr/procedures/java/__init__.py +42 -0
  984. angr/procedures/java/unconstrained.py +65 -0
  985. angr/procedures/java_io/__init__.py +0 -0
  986. angr/procedures/java_io/read.py +12 -0
  987. angr/procedures/java_io/write.py +17 -0
  988. angr/procedures/java_jni/__init__.py +482 -0
  989. angr/procedures/java_jni/array_operations.py +312 -0
  990. angr/procedures/java_jni/class_and_interface_operations.py +31 -0
  991. angr/procedures/java_jni/field_access.py +173 -0
  992. angr/procedures/java_jni/global_and_local_refs.py +57 -0
  993. angr/procedures/java_jni/method_calls.py +365 -0
  994. angr/procedures/java_jni/not_implemented.py +26 -0
  995. angr/procedures/java_jni/object_operations.py +94 -0
  996. angr/procedures/java_jni/string_operations.py +87 -0
  997. angr/procedures/java_jni/version_information.py +12 -0
  998. angr/procedures/java_lang/__init__.py +0 -0
  999. angr/procedures/java_lang/character.py +30 -0
  1000. angr/procedures/java_lang/double.py +24 -0
  1001. angr/procedures/java_lang/exit.py +13 -0
  1002. angr/procedures/java_lang/getsimplename.py +18 -0
  1003. angr/procedures/java_lang/integer.py +43 -0
  1004. angr/procedures/java_lang/load_library.py +9 -0
  1005. angr/procedures/java_lang/math.py +15 -0
  1006. angr/procedures/java_lang/string.py +78 -0
  1007. angr/procedures/java_lang/stringbuilder.py +44 -0
  1008. angr/procedures/java_lang/system.py +18 -0
  1009. angr/procedures/java_util/__init__.py +0 -0
  1010. angr/procedures/java_util/collection.py +35 -0
  1011. angr/procedures/java_util/iterator.py +46 -0
  1012. angr/procedures/java_util/list.py +99 -0
  1013. angr/procedures/java_util/map.py +131 -0
  1014. angr/procedures/java_util/random.py +14 -0
  1015. angr/procedures/java_util/scanner_nextline.py +23 -0
  1016. angr/procedures/libc/__init__.py +3 -0
  1017. angr/procedures/libc/abort.py +9 -0
  1018. angr/procedures/libc/access.py +13 -0
  1019. angr/procedures/libc/atoi.py +14 -0
  1020. angr/procedures/libc/atol.py +13 -0
  1021. angr/procedures/libc/calloc.py +8 -0
  1022. angr/procedures/libc/closelog.py +10 -0
  1023. angr/procedures/libc/err.py +14 -0
  1024. angr/procedures/libc/error.py +54 -0
  1025. angr/procedures/libc/exit.py +11 -0
  1026. angr/procedures/libc/fclose.py +19 -0
  1027. angr/procedures/libc/feof.py +21 -0
  1028. angr/procedures/libc/fflush.py +16 -0
  1029. angr/procedures/libc/fgetc.py +27 -0
  1030. angr/procedures/libc/fgets.py +68 -0
  1031. angr/procedures/libc/fopen.py +63 -0
  1032. angr/procedures/libc/fprintf.py +25 -0
  1033. angr/procedures/libc/fputc.py +23 -0
  1034. angr/procedures/libc/fputs.py +24 -0
  1035. angr/procedures/libc/fread.py +24 -0
  1036. angr/procedures/libc/free.py +9 -0
  1037. angr/procedures/libc/fscanf.py +20 -0
  1038. angr/procedures/libc/fseek.py +34 -0
  1039. angr/procedures/libc/ftell.py +22 -0
  1040. angr/procedures/libc/fwrite.py +19 -0
  1041. angr/procedures/libc/getchar.py +13 -0
  1042. angr/procedures/libc/getdelim.py +99 -0
  1043. angr/procedures/libc/getegid.py +8 -0
  1044. angr/procedures/libc/geteuid.py +8 -0
  1045. angr/procedures/libc/getgid.py +8 -0
  1046. angr/procedures/libc/gets.py +68 -0
  1047. angr/procedures/libc/getuid.py +8 -0
  1048. angr/procedures/libc/malloc.py +12 -0
  1049. angr/procedures/libc/memcmp.py +69 -0
  1050. angr/procedures/libc/memcpy.py +38 -0
  1051. angr/procedures/libc/memset.py +72 -0
  1052. angr/procedures/libc/openlog.py +10 -0
  1053. angr/procedures/libc/perror.py +13 -0
  1054. angr/procedures/libc/printf.py +34 -0
  1055. angr/procedures/libc/putchar.py +13 -0
  1056. angr/procedures/libc/puts.py +19 -0
  1057. angr/procedures/libc/rand.py +8 -0
  1058. angr/procedures/libc/realloc.py +8 -0
  1059. angr/procedures/libc/rewind.py +12 -0
  1060. angr/procedures/libc/scanf.py +20 -0
  1061. angr/procedures/libc/setbuf.py +9 -0
  1062. angr/procedures/libc/setvbuf.py +7 -0
  1063. angr/procedures/libc/snprintf.py +36 -0
  1064. angr/procedures/libc/sprintf.py +25 -0
  1065. angr/procedures/libc/srand.py +7 -0
  1066. angr/procedures/libc/sscanf.py +13 -0
  1067. angr/procedures/libc/stpcpy.py +18 -0
  1068. angr/procedures/libc/strcat.py +14 -0
  1069. angr/procedures/libc/strchr.py +48 -0
  1070. angr/procedures/libc/strcmp.py +31 -0
  1071. angr/procedures/libc/strcpy.py +13 -0
  1072. angr/procedures/libc/strlen.py +114 -0
  1073. angr/procedures/libc/strncat.py +19 -0
  1074. angr/procedures/libc/strncmp.py +183 -0
  1075. angr/procedures/libc/strncpy.py +22 -0
  1076. angr/procedures/libc/strnlen.py +13 -0
  1077. angr/procedures/libc/strstr.py +101 -0
  1078. angr/procedures/libc/strtol.py +261 -0
  1079. angr/procedures/libc/strtoul.py +9 -0
  1080. angr/procedures/libc/system.py +13 -0
  1081. angr/procedures/libc/time.py +9 -0
  1082. angr/procedures/libc/tmpnam.py +20 -0
  1083. angr/procedures/libc/tolower.py +10 -0
  1084. angr/procedures/libc/toupper.py +10 -0
  1085. angr/procedures/libc/ungetc.py +20 -0
  1086. angr/procedures/libc/vsnprintf.py +17 -0
  1087. angr/procedures/libc/wchar.py +16 -0
  1088. angr/procedures/libstdcpp/__init__.py +0 -0
  1089. angr/procedures/libstdcpp/_unwind_resume.py +11 -0
  1090. angr/procedures/libstdcpp/std____throw_bad_alloc.py +13 -0
  1091. angr/procedures/libstdcpp/std____throw_bad_cast.py +13 -0
  1092. angr/procedures/libstdcpp/std____throw_length_error.py +13 -0
  1093. angr/procedures/libstdcpp/std____throw_logic_error.py +13 -0
  1094. angr/procedures/libstdcpp/std__terminate.py +13 -0
  1095. angr/procedures/linux_kernel/__init__.py +3 -0
  1096. angr/procedures/linux_kernel/access.py +18 -0
  1097. angr/procedures/linux_kernel/arch_prctl.py +34 -0
  1098. angr/procedures/linux_kernel/arm_user_helpers.py +59 -0
  1099. angr/procedures/linux_kernel/brk.py +18 -0
  1100. angr/procedures/linux_kernel/cwd.py +28 -0
  1101. angr/procedures/linux_kernel/fstat.py +138 -0
  1102. angr/procedures/linux_kernel/fstat64.py +170 -0
  1103. angr/procedures/linux_kernel/futex.py +17 -0
  1104. angr/procedures/linux_kernel/getegid.py +17 -0
  1105. angr/procedures/linux_kernel/geteuid.py +17 -0
  1106. angr/procedures/linux_kernel/getgid.py +17 -0
  1107. angr/procedures/linux_kernel/getpid.py +14 -0
  1108. angr/procedures/linux_kernel/getrlimit.py +24 -0
  1109. angr/procedures/linux_kernel/gettid.py +9 -0
  1110. angr/procedures/linux_kernel/getuid.py +17 -0
  1111. angr/procedures/linux_kernel/iovec.py +47 -0
  1112. angr/procedures/linux_kernel/lseek.py +42 -0
  1113. angr/procedures/linux_kernel/mmap.py +16 -0
  1114. angr/procedures/linux_kernel/mprotect.py +42 -0
  1115. angr/procedures/linux_kernel/munmap.py +8 -0
  1116. angr/procedures/linux_kernel/openat.py +26 -0
  1117. angr/procedures/linux_kernel/set_tid_address.py +8 -0
  1118. angr/procedures/linux_kernel/sigaction.py +19 -0
  1119. angr/procedures/linux_kernel/sigprocmask.py +23 -0
  1120. angr/procedures/linux_kernel/stat.py +23 -0
  1121. angr/procedures/linux_kernel/sysinfo.py +59 -0
  1122. angr/procedures/linux_kernel/tgkill.py +10 -0
  1123. angr/procedures/linux_kernel/time.py +34 -0
  1124. angr/procedures/linux_kernel/uid.py +30 -0
  1125. angr/procedures/linux_kernel/uname.py +29 -0
  1126. angr/procedures/linux_kernel/unlink.py +22 -0
  1127. angr/procedures/linux_kernel/vsyscall.py +16 -0
  1128. angr/procedures/linux_loader/__init__.py +3 -0
  1129. angr/procedures/linux_loader/_dl_initial_error_catch_tsd.py +7 -0
  1130. angr/procedures/linux_loader/_dl_rtld_lock.py +15 -0
  1131. angr/procedures/linux_loader/sim_loader.py +54 -0
  1132. angr/procedures/linux_loader/tls.py +40 -0
  1133. angr/procedures/msvcr/__getmainargs.py +16 -0
  1134. angr/procedures/msvcr/__init__.py +4 -0
  1135. angr/procedures/msvcr/_initterm.py +38 -0
  1136. angr/procedures/msvcr/fmode.py +31 -0
  1137. angr/procedures/ntdll/__init__.py +0 -0
  1138. angr/procedures/ntdll/exceptions.py +60 -0
  1139. angr/procedures/posix/__init__.py +3 -0
  1140. angr/procedures/posix/accept.py +29 -0
  1141. angr/procedures/posix/bind.py +13 -0
  1142. angr/procedures/posix/bzero.py +9 -0
  1143. angr/procedures/posix/chroot.py +27 -0
  1144. angr/procedures/posix/close.py +9 -0
  1145. angr/procedures/posix/closedir.py +7 -0
  1146. angr/procedures/posix/dup.py +56 -0
  1147. angr/procedures/posix/fcntl.py +10 -0
  1148. angr/procedures/posix/fdopen.py +76 -0
  1149. angr/procedures/posix/fileno.py +18 -0
  1150. angr/procedures/posix/fork.py +13 -0
  1151. angr/procedures/posix/getenv.py +35 -0
  1152. angr/procedures/posix/gethostbyname.py +43 -0
  1153. angr/procedures/posix/getpass.py +19 -0
  1154. angr/procedures/posix/getsockopt.py +11 -0
  1155. angr/procedures/posix/htonl.py +11 -0
  1156. angr/procedures/posix/htons.py +11 -0
  1157. angr/procedures/posix/inet_ntoa.py +59 -0
  1158. angr/procedures/posix/listen.py +13 -0
  1159. angr/procedures/posix/mmap.py +144 -0
  1160. angr/procedures/posix/open.py +18 -0
  1161. angr/procedures/posix/opendir.py +10 -0
  1162. angr/procedures/posix/poll.py +55 -0
  1163. angr/procedures/posix/pread64.py +46 -0
  1164. angr/procedures/posix/pthread.py +87 -0
  1165. angr/procedures/posix/pwrite64.py +46 -0
  1166. angr/procedures/posix/read.py +13 -0
  1167. angr/procedures/posix/readdir.py +62 -0
  1168. angr/procedures/posix/recv.py +13 -0
  1169. angr/procedures/posix/recvfrom.py +13 -0
  1170. angr/procedures/posix/select.py +48 -0
  1171. angr/procedures/posix/send.py +23 -0
  1172. angr/procedures/posix/setsockopt.py +9 -0
  1173. angr/procedures/posix/sigaction.py +23 -0
  1174. angr/procedures/posix/sim_time.py +48 -0
  1175. angr/procedures/posix/sleep.py +8 -0
  1176. angr/procedures/posix/socket.py +18 -0
  1177. angr/procedures/posix/strcasecmp.py +26 -0
  1178. angr/procedures/posix/strdup.py +18 -0
  1179. angr/procedures/posix/strtok_r.py +64 -0
  1180. angr/procedures/posix/syslog.py +15 -0
  1181. angr/procedures/posix/tz.py +9 -0
  1182. angr/procedures/posix/unlink.py +11 -0
  1183. angr/procedures/posix/usleep.py +8 -0
  1184. angr/procedures/posix/write.py +13 -0
  1185. angr/procedures/procedure_dict.py +50 -0
  1186. angr/procedures/stubs/CallReturn.py +13 -0
  1187. angr/procedures/stubs/NoReturnUnconstrained.py +13 -0
  1188. angr/procedures/stubs/Nop.py +7 -0
  1189. angr/procedures/stubs/PathTerminator.py +9 -0
  1190. angr/procedures/stubs/Redirect.py +18 -0
  1191. angr/procedures/stubs/ReturnChar.py +11 -0
  1192. angr/procedures/stubs/ReturnUnconstrained.py +24 -0
  1193. angr/procedures/stubs/UnresolvableCallTarget.py +9 -0
  1194. angr/procedures/stubs/UnresolvableJumpTarget.py +9 -0
  1195. angr/procedures/stubs/UserHook.py +18 -0
  1196. angr/procedures/stubs/__init__.py +3 -0
  1197. angr/procedures/stubs/b64_decode.py +15 -0
  1198. angr/procedures/stubs/caller.py +14 -0
  1199. angr/procedures/stubs/crazy_scanf.py +20 -0
  1200. angr/procedures/stubs/format_parser.py +669 -0
  1201. angr/procedures/stubs/syscall_stub.py +24 -0
  1202. angr/procedures/testing/__init__.py +3 -0
  1203. angr/procedures/testing/manyargs.py +9 -0
  1204. angr/procedures/testing/retreg.py +8 -0
  1205. angr/procedures/tracer/__init__.py +4 -0
  1206. angr/procedures/tracer/random.py +9 -0
  1207. angr/procedures/tracer/receive.py +23 -0
  1208. angr/procedures/tracer/transmit.py +26 -0
  1209. angr/procedures/uclibc/__init__.py +3 -0
  1210. angr/procedures/uclibc/__uClibc_main.py +10 -0
  1211. angr/procedures/win32/EncodePointer.py +7 -0
  1212. angr/procedures/win32/ExitProcess.py +9 -0
  1213. angr/procedures/win32/GetCommandLine.py +12 -0
  1214. angr/procedures/win32/GetCurrentProcessId.py +7 -0
  1215. angr/procedures/win32/GetCurrentThreadId.py +7 -0
  1216. angr/procedures/win32/GetLastInputInfo.py +40 -0
  1217. angr/procedures/win32/GetModuleHandle.py +29 -0
  1218. angr/procedures/win32/GetProcessAffinityMask.py +37 -0
  1219. angr/procedures/win32/InterlockedExchange.py +15 -0
  1220. angr/procedures/win32/IsProcessorFeaturePresent.py +7 -0
  1221. angr/procedures/win32/VirtualAlloc.py +114 -0
  1222. angr/procedures/win32/VirtualProtect.py +60 -0
  1223. angr/procedures/win32/__init__.py +3 -0
  1224. angr/procedures/win32/critical_section.py +12 -0
  1225. angr/procedures/win32/dynamic_loading.py +104 -0
  1226. angr/procedures/win32/file_handles.py +47 -0
  1227. angr/procedures/win32/gethostbyname.py +12 -0
  1228. angr/procedures/win32/heap.py +45 -0
  1229. angr/procedures/win32/is_bad_ptr.py +26 -0
  1230. angr/procedures/win32/local_storage.py +88 -0
  1231. angr/procedures/win32/mutex.py +11 -0
  1232. angr/procedures/win32/sim_time.py +135 -0
  1233. angr/procedures/win32/system_paths.py +35 -0
  1234. angr/procedures/win32_kernel/ExAllocatePool.py +13 -0
  1235. angr/procedures/win32_kernel/ExFreePoolWithTag.py +8 -0
  1236. angr/procedures/win32_kernel/__fastfail.py +15 -0
  1237. angr/procedures/win32_kernel/__init__.py +3 -0
  1238. angr/procedures/win_user32/__init__.py +0 -0
  1239. angr/procedures/win_user32/chars.py +15 -0
  1240. angr/procedures/win_user32/keyboard.py +14 -0
  1241. angr/procedures/win_user32/messagebox.py +49 -0
  1242. angr/project.py +837 -0
  1243. angr/protos/__init__.py +19 -0
  1244. angr/protos/cfg_pb2.py +31 -0
  1245. angr/protos/function_pb2.py +27 -0
  1246. angr/protos/primitives_pb2.py +52 -0
  1247. angr/protos/variables_pb2.py +44 -0
  1248. angr/protos/xrefs_pb2.py +25 -0
  1249. angr/py.typed +1 -0
  1250. angr/rustylib.cpython-310-darwin.so +0 -0
  1251. angr/rustylib.pyi +165 -0
  1252. angr/serializable.py +66 -0
  1253. angr/sim_manager.py +971 -0
  1254. angr/sim_options.py +438 -0
  1255. angr/sim_procedure.py +606 -0
  1256. angr/sim_state.py +901 -0
  1257. angr/sim_state_options.py +403 -0
  1258. angr/sim_type.py +3679 -0
  1259. angr/sim_variable.py +434 -0
  1260. angr/simos/__init__.py +47 -0
  1261. angr/simos/cgc.py +153 -0
  1262. angr/simos/javavm.py +458 -0
  1263. angr/simos/linux.py +509 -0
  1264. angr/simos/simos.py +444 -0
  1265. angr/simos/snimmuc_nxp.py +149 -0
  1266. angr/simos/userland.py +163 -0
  1267. angr/simos/windows.py +601 -0
  1268. angr/simos/xbox.py +32 -0
  1269. angr/slicer.py +352 -0
  1270. angr/state_hierarchy.py +262 -0
  1271. angr/state_plugins/__init__.py +84 -0
  1272. angr/state_plugins/callstack.py +398 -0
  1273. angr/state_plugins/cgc.py +155 -0
  1274. angr/state_plugins/debug_variables.py +192 -0
  1275. angr/state_plugins/filesystem.py +463 -0
  1276. angr/state_plugins/gdb.py +148 -0
  1277. angr/state_plugins/globals.py +65 -0
  1278. angr/state_plugins/heap/__init__.py +15 -0
  1279. angr/state_plugins/heap/heap_base.py +128 -0
  1280. angr/state_plugins/heap/heap_brk.py +136 -0
  1281. angr/state_plugins/heap/heap_freelist.py +213 -0
  1282. angr/state_plugins/heap/heap_libc.py +46 -0
  1283. angr/state_plugins/heap/heap_ptmalloc.py +620 -0
  1284. angr/state_plugins/heap/utils.py +22 -0
  1285. angr/state_plugins/history.py +548 -0
  1286. angr/state_plugins/inspect.py +375 -0
  1287. angr/state_plugins/javavm_classloader.py +134 -0
  1288. angr/state_plugins/jni_references.py +95 -0
  1289. angr/state_plugins/libc.py +1263 -0
  1290. angr/state_plugins/light_registers.py +168 -0
  1291. angr/state_plugins/log.py +84 -0
  1292. angr/state_plugins/loop_data.py +92 -0
  1293. angr/state_plugins/plugin.py +170 -0
  1294. angr/state_plugins/posix.py +703 -0
  1295. angr/state_plugins/preconstrainer.py +196 -0
  1296. angr/state_plugins/scratch.py +173 -0
  1297. angr/state_plugins/sim_action.py +326 -0
  1298. angr/state_plugins/sim_action_object.py +271 -0
  1299. angr/state_plugins/sim_event.py +59 -0
  1300. angr/state_plugins/solver.py +1127 -0
  1301. angr/state_plugins/symbolizer.py +291 -0
  1302. angr/state_plugins/trace_additions.py +738 -0
  1303. angr/state_plugins/uc_manager.py +94 -0
  1304. angr/state_plugins/unicorn_engine.py +1886 -0
  1305. angr/state_plugins/view.py +340 -0
  1306. angr/storage/__init__.py +15 -0
  1307. angr/storage/file.py +1210 -0
  1308. angr/storage/memory_mixins/__init__.py +317 -0
  1309. angr/storage/memory_mixins/actions_mixin.py +72 -0
  1310. angr/storage/memory_mixins/address_concretization_mixin.py +384 -0
  1311. angr/storage/memory_mixins/bvv_conversion_mixin.py +73 -0
  1312. angr/storage/memory_mixins/clouseau_mixin.py +137 -0
  1313. angr/storage/memory_mixins/conditional_store_mixin.py +25 -0
  1314. angr/storage/memory_mixins/convenient_mappings_mixin.py +256 -0
  1315. angr/storage/memory_mixins/default_filler_mixin.py +144 -0
  1316. angr/storage/memory_mixins/dirty_addrs_mixin.py +11 -0
  1317. angr/storage/memory_mixins/hex_dumper_mixin.py +82 -0
  1318. angr/storage/memory_mixins/javavm_memory_mixin.py +392 -0
  1319. angr/storage/memory_mixins/keyvalue_memory_mixin.py +42 -0
  1320. angr/storage/memory_mixins/label_merger_mixin.py +31 -0
  1321. angr/storage/memory_mixins/memory_mixin.py +174 -0
  1322. angr/storage/memory_mixins/multi_value_merger_mixin.py +79 -0
  1323. angr/storage/memory_mixins/name_resolution_mixin.py +67 -0
  1324. angr/storage/memory_mixins/paged_memory/__init__.py +0 -0
  1325. angr/storage/memory_mixins/paged_memory/page_backer_mixins.py +266 -0
  1326. angr/storage/memory_mixins/paged_memory/paged_memory_mixin.py +743 -0
  1327. angr/storage/memory_mixins/paged_memory/paged_memory_multivalue_mixin.py +65 -0
  1328. angr/storage/memory_mixins/paged_memory/pages/__init__.py +26 -0
  1329. angr/storage/memory_mixins/paged_memory/pages/base.py +31 -0
  1330. angr/storage/memory_mixins/paged_memory/pages/cooperation.py +341 -0
  1331. angr/storage/memory_mixins/paged_memory/pages/history_tracking_mixin.py +92 -0
  1332. angr/storage/memory_mixins/paged_memory/pages/ispo_mixin.py +55 -0
  1333. angr/storage/memory_mixins/paged_memory/pages/list_page.py +338 -0
  1334. angr/storage/memory_mixins/paged_memory/pages/multi_values.py +324 -0
  1335. angr/storage/memory_mixins/paged_memory/pages/mv_list_page.py +419 -0
  1336. angr/storage/memory_mixins/paged_memory/pages/permissions_mixin.py +36 -0
  1337. angr/storage/memory_mixins/paged_memory/pages/refcount_mixin.py +52 -0
  1338. angr/storage/memory_mixins/paged_memory/pages/ultra_page.py +503 -0
  1339. angr/storage/memory_mixins/paged_memory/privileged_mixin.py +36 -0
  1340. angr/storage/memory_mixins/paged_memory/stack_allocation_mixin.py +74 -0
  1341. angr/storage/memory_mixins/regioned_memory/__init__.py +17 -0
  1342. angr/storage/memory_mixins/regioned_memory/abstract_address_descriptor.py +36 -0
  1343. angr/storage/memory_mixins/regioned_memory/abstract_merger_mixin.py +31 -0
  1344. angr/storage/memory_mixins/regioned_memory/region_category_mixin.py +9 -0
  1345. angr/storage/memory_mixins/regioned_memory/region_data.py +246 -0
  1346. angr/storage/memory_mixins/regioned_memory/region_meta_mixin.py +241 -0
  1347. angr/storage/memory_mixins/regioned_memory/regioned_address_concretization_mixin.py +119 -0
  1348. angr/storage/memory_mixins/regioned_memory/regioned_memory_mixin.py +441 -0
  1349. angr/storage/memory_mixins/regioned_memory/static_find_mixin.py +69 -0
  1350. angr/storage/memory_mixins/simple_interface_mixin.py +71 -0
  1351. angr/storage/memory_mixins/simplification_mixin.py +15 -0
  1352. angr/storage/memory_mixins/size_resolution_mixin.py +143 -0
  1353. angr/storage/memory_mixins/slotted_memory.py +140 -0
  1354. angr/storage/memory_mixins/smart_find_mixin.py +161 -0
  1355. angr/storage/memory_mixins/symbolic_merger_mixin.py +16 -0
  1356. angr/storage/memory_mixins/top_merger_mixin.py +25 -0
  1357. angr/storage/memory_mixins/underconstrained_mixin.py +67 -0
  1358. angr/storage/memory_mixins/unwrapper_mixin.py +26 -0
  1359. angr/storage/memory_object.py +195 -0
  1360. angr/tablespecs.py +91 -0
  1361. angr/utils/__init__.py +46 -0
  1362. angr/utils/ail.py +70 -0
  1363. angr/utils/algo.py +34 -0
  1364. angr/utils/bits.py +46 -0
  1365. angr/utils/constants.py +9 -0
  1366. angr/utils/cowdict.py +63 -0
  1367. angr/utils/cpp.py +17 -0
  1368. angr/utils/doms.py +149 -0
  1369. angr/utils/dynamic_dictlist.py +89 -0
  1370. angr/utils/endness.py +18 -0
  1371. angr/utils/enums_conv.py +97 -0
  1372. angr/utils/env.py +12 -0
  1373. angr/utils/formatting.py +128 -0
  1374. angr/utils/funcid.py +159 -0
  1375. angr/utils/graph.py +898 -0
  1376. angr/utils/lazy_import.py +13 -0
  1377. angr/utils/library.py +211 -0
  1378. angr/utils/loader.py +55 -0
  1379. angr/utils/mp.py +66 -0
  1380. angr/utils/orderedset.py +74 -0
  1381. angr/utils/ssa/__init__.py +395 -0
  1382. angr/utils/ssa/tmp_uses_collector.py +23 -0
  1383. angr/utils/ssa/vvar_uses_collector.py +37 -0
  1384. angr/utils/tagged_interval_map.py +112 -0
  1385. angr/utils/timing.py +74 -0
  1386. angr/utils/types.py +151 -0
  1387. angr/vaults.py +367 -0
  1388. angr-9.2.156.dist-info/METADATA +112 -0
  1389. angr-9.2.156.dist-info/RECORD +1393 -0
  1390. angr-9.2.156.dist-info/WHEEL +5 -0
  1391. angr-9.2.156.dist-info/entry_points.txt +2 -0
  1392. angr-9.2.156.dist-info/licenses/LICENSE +27 -0
  1393. angr-9.2.156.dist-info/top_level.txt +1 -0
@@ -0,0 +1,1872 @@
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 Iterable
5
+ from collections import defaultdict
6
+ from enum import Enum
7
+ import logging
8
+
9
+ import networkx
10
+
11
+ from ailment import AILBlockWalker
12
+ from ailment.block import Block
13
+ from ailment.statement import Statement, Assignment, Store, Call, ConditionalJump, DirtyStatement, WeakAssignment
14
+ from ailment.expression import (
15
+ Register,
16
+ Convert,
17
+ Load,
18
+ StackBaseOffset,
19
+ Expression,
20
+ DirtyExpression,
21
+ VEXCCallExpression,
22
+ Tmp,
23
+ Const,
24
+ BinaryOp,
25
+ VirtualVariable,
26
+ UnaryOp,
27
+ )
28
+
29
+ from angr.analyses.s_propagator import SPropagatorAnalysis
30
+ from angr.analyses.s_reaching_definitions import SRDAModel
31
+ from angr.utils.ail import is_phi_assignment, HasExprWalker
32
+ from angr.utils.ssa import (
33
+ has_call_in_between_stmts,
34
+ has_store_stmt_in_between_stmts,
35
+ has_load_expr_in_between_stmts,
36
+ is_vvar_eliminatable,
37
+ )
38
+ from angr.code_location import CodeLocation, ExternalCodeLocation
39
+ from angr.sim_variable import SimStackVariable, SimMemoryVariable, SimVariable
40
+ from angr.knowledge_plugins.propagations.states import Equivalence
41
+ from angr.knowledge_plugins.key_definitions import atoms
42
+ from angr.knowledge_plugins.key_definitions.definition import Definition
43
+ from angr.knowledge_plugins.key_definitions.constants import OP_BEFORE
44
+ from angr.errors import AngrRuntimeError
45
+ from angr.analyses import Analysis, AnalysesHub
46
+ from angr.utils.timing import timethis
47
+ from .ailgraph_walker import AILGraphWalker
48
+ from .expression_narrower import ExprNarrowingInfo, NarrowingInfoExtractor, ExpressionNarrower
49
+ from .block_simplifier import BlockSimplifier
50
+ from .ccall_rewriters import CCALL_REWRITERS
51
+ from .counters.expression_counters import SingleExpressionCounter
52
+
53
+ if TYPE_CHECKING:
54
+ from ailment.manager import Manager
55
+
56
+
57
+ _l = logging.getLogger(__name__)
58
+
59
+
60
+ class HasCallNotification(Exception):
61
+ """
62
+ Notifies the existence of a call statement.
63
+ """
64
+
65
+
66
+ class HasVVarNotification(Exception):
67
+ """
68
+ Notifies the existence of a VirtualVariable.
69
+ """
70
+
71
+
72
+ class HasRefVVarNotification(Exception):
73
+ """
74
+ Notifies the existence of a reference to a VirtualVariable.
75
+ """
76
+
77
+
78
+ class AILBlockTempCollector(AILBlockWalker):
79
+ """
80
+ Collects any temporaries used in a block.
81
+ """
82
+
83
+ def __init__(self, **kwargs):
84
+ super().__init__(**kwargs)
85
+ self.temps = set()
86
+ self.expr_handlers[Tmp] = self._handle_Tmp
87
+
88
+ # pylint:disable=unused-argument
89
+ def _handle_Tmp(self, expr_idx: int, expr: Expression, stmt_idx: int, stmt: Statement, block) -> None:
90
+ if isinstance(expr, Tmp):
91
+ self.temps.add(expr)
92
+
93
+
94
+ class DefEqRelation(Enum):
95
+ """
96
+ Describes the location relationship between a virtual variable definition and the equivalence statement.
97
+ """
98
+
99
+ UNKNOWN = 0
100
+ DEF_IS_FUNCARG = 1
101
+ DEF_EQ_SAME_BLOCK = 2
102
+ DEF_IN_EQ_PRED_BLOCK = 3
103
+
104
+
105
+ class AILSimplifier(Analysis):
106
+ """
107
+ Perform function-level simplifications.
108
+ """
109
+
110
+ def __init__(
111
+ self,
112
+ func,
113
+ func_graph=None,
114
+ remove_dead_memdefs=False,
115
+ stack_arg_offsets: set[tuple[int, int]] | None = None,
116
+ unify_variables=False,
117
+ ail_manager: Manager | None = None,
118
+ gp: int | None = None,
119
+ narrow_expressions=False,
120
+ only_consts=False,
121
+ fold_callexprs_into_conditions=False,
122
+ use_callee_saved_regs_at_return=True,
123
+ rewrite_ccalls=True,
124
+ removed_vvar_ids: set[int] | None = None,
125
+ arg_vvars: dict[int, tuple[VirtualVariable, SimVariable]] | None = None,
126
+ avoid_vvar_ids: set[int] | None = None,
127
+ secondary_stackvars: set[int] | None = None,
128
+ ):
129
+ self.func = func
130
+ self.func_graph = func_graph if func_graph is not None else func.graph
131
+ self._reaching_definitions: SRDAModel | None = None
132
+ self._propagator: SPropagatorAnalysis | None = None
133
+
134
+ self._remove_dead_memdefs = remove_dead_memdefs
135
+ self._stack_arg_offsets = stack_arg_offsets
136
+ self._unify_vars = unify_variables
137
+ self._ail_manager: Manager | None = ail_manager
138
+ self._gp = gp
139
+ self._narrow_expressions = narrow_expressions
140
+ self._only_consts = only_consts
141
+ self._fold_callexprs_into_conditions = fold_callexprs_into_conditions
142
+ self._use_callee_saved_regs_at_return = use_callee_saved_regs_at_return
143
+ self._should_rewrite_ccalls = rewrite_ccalls
144
+ self._removed_vvar_ids = removed_vvar_ids if removed_vvar_ids is not None else set()
145
+ self._arg_vvars = arg_vvars
146
+ self._avoid_vvar_ids = avoid_vvar_ids if avoid_vvar_ids is not None else set()
147
+ self._propagator_dead_vvar_ids: set[int] = set()
148
+ self._secondary_stackvars: set[int] = secondary_stackvars if secondary_stackvars is not None else set()
149
+
150
+ self._calls_to_remove: set[CodeLocation] = set()
151
+ self._assignments_to_remove: set[CodeLocation] = set()
152
+ self.blocks = {} # Mapping nodes to simplified blocks
153
+
154
+ self.simplified: bool = False
155
+ self._simplify()
156
+
157
+ def _simplify(self):
158
+ if self._narrow_expressions:
159
+ _l.debug("Removing dead assignments before narrowing expressions")
160
+ r = self._iteratively_remove_dead_assignments()
161
+ if r:
162
+ _l.debug("... dead assignments removed")
163
+ self.simplified = True
164
+
165
+ _l.debug("Narrowing expressions")
166
+ narrowed_exprs = self._narrow_exprs()
167
+ self.simplified |= narrowed_exprs
168
+ if narrowed_exprs:
169
+ _l.debug("... expressions narrowed")
170
+ self._rebuild_func_graph()
171
+ self._clear_cache()
172
+
173
+ _l.debug("Folding expressions")
174
+ folded_exprs = self._fold_exprs()
175
+ self.simplified |= folded_exprs
176
+ if folded_exprs:
177
+ _l.debug("... expressions folded")
178
+ self._rebuild_func_graph()
179
+ # reaching definition analysis results are no longer reliable
180
+ self._clear_cache()
181
+
182
+ if self._only_consts:
183
+ return
184
+
185
+ if self._should_rewrite_ccalls:
186
+ _l.debug("Rewriting ccalls")
187
+ ccalls_rewritten = self._rewrite_ccalls()
188
+ self.simplified |= ccalls_rewritten
189
+ if ccalls_rewritten:
190
+ _l.debug("... ccalls rewritten")
191
+ self._rebuild_func_graph()
192
+ self._clear_cache()
193
+
194
+ if self._unify_vars:
195
+ _l.debug("Removing dead assignments")
196
+ r = self._iteratively_remove_dead_assignments()
197
+ if r:
198
+ _l.debug("... dead assignments removed")
199
+ self.simplified = True
200
+
201
+ _l.debug("Unifying local variables")
202
+ r = self._unify_local_variables()
203
+ if r:
204
+ _l.debug("... local variables unified")
205
+ self.simplified = True
206
+ self._rebuild_func_graph()
207
+
208
+ # _fold_call_exprs() may set self._calls_to_remove, which will be honored in _remove_dead_assignments()
209
+ _l.debug("Folding call expressions")
210
+ r = self._fold_call_exprs()
211
+ if r:
212
+ _l.debug("... call expressions folded")
213
+ self.simplified = True
214
+ self._rebuild_func_graph()
215
+ self._clear_cache()
216
+
217
+ _l.debug("Removing dead assignments")
218
+ r = self._iteratively_remove_dead_assignments()
219
+ if r:
220
+ _l.debug("... dead assignments removed")
221
+ self.simplified = True
222
+
223
+ def _rebuild_func_graph(self):
224
+ def _handler(node):
225
+ return self.blocks.get(node, None)
226
+
227
+ AILGraphWalker(self.func_graph, _handler, replace_nodes=True).walk()
228
+ self.blocks = {}
229
+
230
+ def _compute_reaching_definitions(self) -> SRDAModel:
231
+ # Computing reaching definitions or return the cached one
232
+ if self._reaching_definitions is not None:
233
+ return self._reaching_definitions
234
+ func_args = {vvar for vvar, _ in self._arg_vvars.values()} if self._arg_vvars else set()
235
+ rd = self.project.analyses.SReachingDefinitions(
236
+ subject=self.func,
237
+ func_graph=self.func_graph,
238
+ func_args=func_args,
239
+ # use_callee_saved_regs_at_return=self._use_callee_saved_regs_at_return,
240
+ # track_tmps=True,
241
+ ).model
242
+ self._reaching_definitions = rd
243
+ return rd
244
+
245
+ @timethis
246
+ def _compute_propagation(self) -> SPropagatorAnalysis:
247
+ # Propagate expressions or return the existing result
248
+ if self._propagator is not None:
249
+ return self._propagator
250
+ func_args = {vvar for vvar, _ in self._arg_vvars.values()} if self._arg_vvars else set()
251
+ prop = self.project.analyses[SPropagatorAnalysis].prep(fail_fast=self._fail_fast)(
252
+ subject=self.func,
253
+ func_graph=self.func_graph,
254
+ func_args=func_args,
255
+ # gp=self._gp,
256
+ only_consts=self._only_consts,
257
+ )
258
+ self._propagator = prop
259
+ self._propagator_dead_vvar_ids = prop.dead_vvar_ids
260
+ return prop
261
+
262
+ @timethis
263
+ def _compute_equivalence(self) -> set[Equivalence]:
264
+ equivalence = set()
265
+ for block in self.func_graph:
266
+ for stmt_idx, stmt in enumerate(block.statements):
267
+ if isinstance(stmt, Assignment):
268
+ if isinstance(stmt.dst, VirtualVariable) and isinstance(
269
+ stmt.src, (VirtualVariable, Tmp, Call, Convert)
270
+ ):
271
+ codeloc = CodeLocation(block.addr, stmt_idx, block_idx=block.idx, ins_addr=stmt.ins_addr)
272
+ equivalence.add(Equivalence(codeloc, stmt.dst, stmt.src))
273
+ elif isinstance(stmt, WeakAssignment):
274
+ codeloc = CodeLocation(block.addr, stmt_idx, block_idx=block.idx, ins_addr=stmt.ins_addr)
275
+ equivalence.add(Equivalence(codeloc, stmt.dst, stmt.src, is_weakassignment=True))
276
+ elif isinstance(stmt, Call):
277
+ if isinstance(stmt.ret_expr, (VirtualVariable, Load)):
278
+ codeloc = CodeLocation(block.addr, stmt_idx, block_idx=block.idx, ins_addr=stmt.ins_addr)
279
+ equivalence.add(Equivalence(codeloc, stmt.ret_expr, stmt))
280
+ elif isinstance(stmt.fp_ret_expr, (VirtualVariable, Load)):
281
+ codeloc = CodeLocation(block.addr, stmt_idx, block_idx=block.idx, ins_addr=stmt.ins_addr)
282
+ equivalence.add(Equivalence(codeloc, stmt.fp_ret_expr, stmt))
283
+ elif (
284
+ isinstance(stmt, Store)
285
+ and isinstance(stmt.size, int)
286
+ and isinstance(stmt.data, (VirtualVariable, Tmp, Call, Convert))
287
+ ):
288
+ if isinstance(stmt.addr, StackBaseOffset) and isinstance(stmt.addr.offset, int):
289
+ # stack variable
290
+ atom = SimStackVariable(stmt.addr.offset, stmt.size)
291
+ codeloc = CodeLocation(block.addr, stmt_idx, block_idx=block.idx, ins_addr=stmt.ins_addr)
292
+ equivalence.add(Equivalence(codeloc, atom, stmt.data))
293
+ elif isinstance(stmt.addr, Const):
294
+ # global variable
295
+ atom = SimMemoryVariable(stmt.addr.value, stmt.size)
296
+ codeloc = CodeLocation(block.addr, stmt_idx, block_idx=block.idx, ins_addr=stmt.ins_addr)
297
+ equivalence.add(Equivalence(codeloc, atom, stmt.data))
298
+ return equivalence
299
+
300
+ def _clear_cache(self) -> None:
301
+ self._propagator = None
302
+ self._reaching_definitions = None
303
+
304
+ def _clear_propagator_cache(self) -> None:
305
+ self._propagator = None
306
+
307
+ def _clear_reaching_definitions_cache(self) -> None:
308
+ self._reaching_definitions = None
309
+
310
+ #
311
+ # Expression narrowing
312
+ #
313
+
314
+ @timethis
315
+ def _narrow_exprs(self) -> bool:
316
+ """
317
+ A register may be used with full width even when only the lower bytes are really needed. This results in the
318
+ incorrect determination of wider variables while the actual variable is narrower (e.g., int64 vs char). This
319
+ optimization narrows a register definition if all its uses are narrower than the definition itself.
320
+ """
321
+
322
+ narrowed = False
323
+
324
+ addr_and_idx_to_block: dict[tuple[int, int | None], Block] = {}
325
+ for block in self.func_graph.nodes():
326
+ addr_and_idx_to_block[(block.addr, block.idx)] = block
327
+
328
+ rd = self._compute_reaching_definitions()
329
+ sorted_defs = sorted(rd.all_definitions, key=lambda d: d.codeloc, reverse=True)
330
+ narrowing_candidates: dict[int, tuple[Definition, ExprNarrowingInfo]] = {}
331
+ for def_ in (d_ for d_ in sorted_defs if d_.codeloc.context is None):
332
+ if isinstance(def_.atom, atoms.VirtualVariable) and (def_.atom.was_reg or def_.atom.was_parameter):
333
+ # only do this for general purpose register
334
+ skip_def = False
335
+ for reg in self.project.arch.register_list:
336
+ if not reg.artificial and reg.vex_offset == def_.atom.reg_offset and not reg.general_purpose:
337
+ skip_def = True
338
+ break
339
+
340
+ if skip_def:
341
+ continue
342
+
343
+ narrow = self._narrowing_needed(def_, rd, addr_and_idx_to_block)
344
+ if narrow.narrowable:
345
+ # we cannot narrow it immediately because any definition that is used by phi variables must be
346
+ # narrowed together with all other definitions that can reach the phi variables.
347
+ # so we record the information and decide if we are going to narrow these expressions or not at the
348
+ # end of the loop.
349
+ narrowing_candidates[def_.atom.varid] = def_, narrow
350
+
351
+ # first, determine which phi vars need to be narrowed and can be narrowed.
352
+ # a phi var can only be narrowed if all its source vvars are narrowable
353
+ vvar_to_narrowing_size = {}
354
+ for def_varid, (_, narrow_info) in narrowing_candidates.items():
355
+ vvar_to_narrowing_size[def_varid] = narrow_info.to_size
356
+
357
+ blacklist_varids = set()
358
+ while True:
359
+ repeat, narrowables = self._compute_narrowables_once(
360
+ rd, narrowing_candidates, vvar_to_narrowing_size, blacklist_varids
361
+ )
362
+ if not repeat:
363
+ break
364
+
365
+ # let's narrow them (finally)
366
+ narrower = ExpressionNarrower(self.project, rd, narrowables, addr_and_idx_to_block, self.blocks)
367
+ for old_block in addr_and_idx_to_block.values():
368
+ new_block = self.blocks.get(old_block, old_block)
369
+ new_block = narrower.walk(new_block)
370
+ if narrower.narrowed_any:
371
+ narrowed = True
372
+ self.blocks[old_block] = new_block
373
+
374
+ # update self._arg_vvars if necessary
375
+ for new_vvars in narrower.replacement_core_vvars.values():
376
+ for new_vvar in new_vvars:
377
+ if new_vvar.was_parameter and self._arg_vvars:
378
+ for func_arg_idx in list(self._arg_vvars):
379
+ vvar, simvar = self._arg_vvars[func_arg_idx]
380
+ if vvar.varid == new_vvar.varid:
381
+ simvar_new = simvar.copy()
382
+ simvar_new._hash = None
383
+ simvar_new.size = new_vvar.size
384
+ self._arg_vvars[func_arg_idx] = new_vvar, simvar_new
385
+
386
+ return narrowed
387
+
388
+ @staticmethod
389
+ def _compute_narrowables_once(
390
+ rd, narrowing_candidates: dict, vvar_to_narrowing_size: dict[int, int], blacklist_varids: set
391
+ ):
392
+ repeat = False
393
+ narrowable_phivarids = set()
394
+ for def_vvarid in narrowing_candidates:
395
+ if def_vvarid in blacklist_varids:
396
+ continue
397
+ if def_vvarid in rd.phi_vvar_ids:
398
+ narrowing_sizes = set()
399
+ src_vvarids = rd.phivarid_to_varids[def_vvarid]
400
+ for vvarid in src_vvarids:
401
+ if vvarid in blacklist_varids:
402
+ narrowing_sizes.add(None)
403
+ else:
404
+ narrowing_sizes.add(vvar_to_narrowing_size.get(vvarid))
405
+ if len(narrowing_sizes) == 1 and None not in narrowing_sizes:
406
+ # we can narrow this phi vvar!
407
+ narrowable_phivarids.add(def_vvarid)
408
+ else:
409
+ # blacklist it for now
410
+ blacklist_varids.add(def_vvarid)
411
+
412
+ # now determine what to narrow!
413
+ narrowables = []
414
+
415
+ for def_, narrow_info in narrowing_candidates.values():
416
+ if def_.atom.varid in blacklist_varids:
417
+ continue
418
+ if not narrow_info.phi_vars:
419
+ # not used by any other phi variables. good!
420
+ narrowables.append((def_, narrow_info))
421
+ else:
422
+ if {phivar.varid for phivar in narrow_info.phi_vars}.issubset(narrowable_phivarids):
423
+ # all phi vvars that use this definition can be narrowed
424
+ narrowables.append((def_, narrow_info))
425
+ else:
426
+ # this vvar cannot be narrowed
427
+ # note that all phi variables that relies on this vvar also cannot be narrowed! we must analyze
428
+ # again
429
+ repeat = True
430
+ blacklist_varids.add(def_.atom.varid)
431
+ blacklist_varids |= {phivar.varid for phivar in narrow_info.phi_vars}
432
+
433
+ return repeat, narrowables
434
+
435
+ def _narrowing_needed(self, def_, rd: SRDAModel, addr_and_idx_to_block) -> ExprNarrowingInfo:
436
+
437
+ def_size = def_.size
438
+ # find its uses
439
+ # some use locations are phi assignments. we keep tracking the uses of phi variables and update the dictionary
440
+ result = self._get_vvar_use_and_exprs_recursive(def_.atom, rd, addr_and_idx_to_block)
441
+ if result is None:
442
+ return ExprNarrowingInfo(False)
443
+ use_and_exprs, phi_vars = result
444
+
445
+ all_used_sizes = set()
446
+ used_by: list[tuple[atoms.VirtualVariable, CodeLocation, tuple[str, tuple[Expression, ...]]]] = []
447
+ used_by_loc = defaultdict(list)
448
+
449
+ for atom, loc, expr in use_and_exprs:
450
+ old_block = addr_and_idx_to_block.get((loc.block_addr, loc.block_idx), None)
451
+ if old_block is None:
452
+ # missing a block for whatever reason
453
+ return ExprNarrowingInfo(False)
454
+
455
+ block = self.blocks.get(old_block, old_block)
456
+ assert loc.stmt_idx is not None
457
+ if loc.stmt_idx >= len(block.statements):
458
+ # missing a statement for whatever reason
459
+ return ExprNarrowingInfo(False)
460
+ stmt = block.statements[loc.stmt_idx]
461
+
462
+ # special case: if the statement is a Call statement and expr is None, it means we have not been able to
463
+ # determine if the expression is really used by the call or not. skip it in this case
464
+ if isinstance(stmt, Call) and expr is None:
465
+ continue
466
+ # special case: if the statement is a phi statement, we ignore it
467
+ if is_phi_assignment(stmt):
468
+ continue
469
+
470
+ expr_size, used_by_exprs = self._extract_expression_effective_size(stmt, expr)
471
+ if expr_size is None:
472
+ # it's probably used in full width
473
+ return ExprNarrowingInfo(False)
474
+
475
+ all_used_sizes.add(expr_size)
476
+ used_by_loc[loc].append((atom, used_by_exprs))
477
+
478
+ if len(all_used_sizes) == 1 and next(iter(all_used_sizes)) < def_size:
479
+ for loc, atom_expr_pairs in used_by_loc.items():
480
+ if len(atom_expr_pairs) == 1:
481
+ atom, used_by_exprs = atom_expr_pairs[0]
482
+ used_by.append((atom, loc, used_by_exprs))
483
+ else:
484
+ # the order matters - we must replace the outer expressions first, then replace the inner
485
+ # expressions. replacing in the wrong order will lead to expressions that are not replaced in the
486
+ # end.
487
+ ordered = []
488
+ for atom, used_by_exprs in atom_expr_pairs:
489
+ last_inclusion = len(ordered) - 1 # by default we append at the end of the list
490
+ for idx in range(len(ordered)):
491
+ if self._is_expr0_included_in_expr1(ordered[idx][1], used_by_exprs):
492
+ # this element must be inserted before idx
493
+ ordered.insert(idx, (atom, used_by_exprs))
494
+ break
495
+ if self._is_expr0_included_in_expr1(used_by_exprs, ordered[idx][1]):
496
+ # this element can be inserted after this element. record the index
497
+ last_inclusion = idx
498
+ else:
499
+ ordered.insert(last_inclusion + 1, (atom, used_by_exprs))
500
+
501
+ for atom, used_by_exprs in ordered:
502
+ used_by.append((atom, loc, used_by_exprs))
503
+
504
+ return ExprNarrowingInfo(True, to_size=next(iter(all_used_sizes)), use_exprs=used_by, phi_vars=phi_vars)
505
+
506
+ return ExprNarrowingInfo(False)
507
+
508
+ @staticmethod
509
+ def _exprs_from_used_by_exprs(used_by_exprs) -> set[Expression]:
510
+ use_type, expr_tuple = used_by_exprs
511
+ match use_type:
512
+ case "expr" | "mask" | "convert":
513
+ return {expr_tuple[1]} if len(expr_tuple) == 2 else {expr_tuple[0]}
514
+ case "phi-src-expr":
515
+ return {expr_tuple[0]}
516
+ case "binop-convert":
517
+ return {expr_tuple[0], expr_tuple[1]}
518
+ case _:
519
+ return set()
520
+
521
+ def _is_expr0_included_in_expr1(self, used_by_exprs0, used_by_exprs1) -> bool:
522
+ # extract expressions
523
+ exprs0 = self._exprs_from_used_by_exprs(used_by_exprs0)
524
+ exprs1 = self._exprs_from_used_by_exprs(used_by_exprs1)
525
+
526
+ # test for inclusion
527
+ for expr1 in exprs1:
528
+ walker = HasExprWalker(exprs0)
529
+ walker.walk_expression(expr1)
530
+ if walker.contains_exprs:
531
+ return True
532
+ return False
533
+
534
+ def _get_vvar_use_and_exprs_recursive(
535
+ self, initial_atom: atoms.VirtualVariable, rd, block_dict: dict[tuple[int, int | None], Block]
536
+ ) -> tuple[list[tuple[atoms.VirtualVariable, CodeLocation, Expression]], set[VirtualVariable]] | None:
537
+ result = []
538
+ atom_queue = [initial_atom]
539
+ phi_vars = set()
540
+ seen = set()
541
+ while atom_queue:
542
+ atom = atom_queue.pop(0)
543
+ seen.add(atom)
544
+
545
+ expr_and_uses = rd.all_vvar_uses[atom.varid]
546
+
547
+ for expr, loc in set(expr_and_uses):
548
+ old_block = block_dict.get((loc.block_addr, loc.block_idx), None)
549
+ if old_block is None:
550
+ # missing a block for whatever reason
551
+ return None
552
+
553
+ block: Block = self.blocks.get(old_block, old_block)
554
+ if loc.stmt_idx >= len(block.statements):
555
+ # missing a statement for whatever reason
556
+ return None
557
+ stmt = block.statements[loc.stmt_idx]
558
+
559
+ if is_phi_assignment(stmt):
560
+ phi_vars.add(stmt.dst)
561
+ new_atom = atoms.VirtualVariable(
562
+ stmt.dst.varid, stmt.dst.size, stmt.dst.category, oident=stmt.dst.oident
563
+ )
564
+ if new_atom not in seen:
565
+ atom_queue.append(new_atom)
566
+ seen.add(new_atom)
567
+ else:
568
+ result.append((atom, loc, expr))
569
+ return result, phi_vars
570
+
571
+ def _extract_expression_effective_size(
572
+ self, statement, expr
573
+ ) -> tuple[int | None, tuple[str, tuple[Expression, ...]] | None]:
574
+ """
575
+ Determine the effective size of an expression when it's used.
576
+ """
577
+
578
+ walker = NarrowingInfoExtractor(expr)
579
+ walker.walk_statement(statement)
580
+ if not walker.operations:
581
+ if expr is None:
582
+ return None, None
583
+ return expr.size, ("expr", (expr,))
584
+
585
+ ops = walker.operations
586
+ first_op = ops[0]
587
+ if isinstance(first_op, BinaryOp) and first_op.op in {"Add", "Sub"}:
588
+ # expr + x
589
+ ops = ops[1:]
590
+ if not ops:
591
+ if expr is None:
592
+ return None, None
593
+ return expr.size, ("expr", (expr,))
594
+ first_op = ops[0]
595
+ if isinstance(first_op, Convert) and first_op.to_bits >= self.project.arch.byte_width:
596
+ # we need at least one byte!
597
+ return first_op.to_bits // self.project.arch.byte_width, ("convert", (first_op,))
598
+ if isinstance(first_op, BinaryOp):
599
+ second_op = None
600
+ if len(ops) >= 2:
601
+ second_op = ops[1]
602
+ if (
603
+ first_op.op == "And"
604
+ and isinstance(first_op.operands[1], Const)
605
+ and (
606
+ second_op is None or (isinstance(second_op, BinaryOp) and isinstance(second_op.operands[1], Const))
607
+ )
608
+ ):
609
+ mask = first_op.operands[1].value
610
+ if mask == 0xFF:
611
+ return 1, ("mask", (first_op, second_op)) if second_op is not None else ("mask", (first_op,))
612
+ if mask == 0xFFFF:
613
+ return 2, ("mask", (first_op, second_op)) if second_op is not None else ("mask", (first_op,))
614
+ if mask == 0xFFFF_FFFF:
615
+ return 4, ("mask", (first_op, second_op)) if second_op is not None else ("mask", (first_op,))
616
+ if (
617
+ (first_op.operands[0] is expr or first_op.operands[1] is expr)
618
+ and first_op.op not in {"Shr", "Sar"}
619
+ and isinstance(second_op, Convert)
620
+ and second_op.from_bits == expr.bits
621
+ and second_op.to_bits >= self.project.arch.byte_width # we need at least one byte!
622
+ ):
623
+ return min(expr.bits, second_op.to_bits) // self.project.arch.byte_width, (
624
+ "binop-convert",
625
+ (expr, first_op, second_op),
626
+ )
627
+
628
+ if expr is None:
629
+ return None, None
630
+ return expr.size, ("expr", (expr,))
631
+
632
+ #
633
+ # Expression folding
634
+ #
635
+
636
+ def _fold_exprs(self):
637
+ """
638
+ Fold expressions: Fold assigned expressions that are constant or only used once.
639
+ """
640
+
641
+ # propagator
642
+ propagator = self._compute_propagation()
643
+ replacements = propagator.replacements
644
+
645
+ # take replacements and rebuild the corresponding blocks
646
+ replacements_by_block_addrs_and_idx = defaultdict(dict)
647
+ for codeloc, reps in replacements.items():
648
+ if reps:
649
+ replacements_by_block_addrs_and_idx[(codeloc.block_addr, codeloc.block_idx)][codeloc] = reps
650
+
651
+ if not replacements_by_block_addrs_and_idx:
652
+ return False
653
+
654
+ blocks_by_addr_and_idx = {(node.addr, node.idx): node for node in self.func_graph.nodes()}
655
+
656
+ if self._stack_arg_offsets:
657
+ insn_addrs_using_stack_args = {ins_addr for ins_addr, _ in self._stack_arg_offsets}
658
+ else:
659
+ insn_addrs_using_stack_args = None
660
+
661
+ replaced = False
662
+ for (block_addr, block_idx), reps in replacements_by_block_addrs_and_idx.items():
663
+ block = blocks_by_addr_and_idx[(block_addr, block_idx)]
664
+
665
+ # only replace loads if there are stack arguments in this block
666
+ replace_loads: bool = insn_addrs_using_stack_args is not None and bool(
667
+ {stmt.ins_addr for stmt in block.statements}.intersection(insn_addrs_using_stack_args)
668
+ )
669
+
670
+ # remove virtual variables in the avoid list
671
+ if self._avoid_vvar_ids:
672
+ filtered_reps = {}
673
+ for loc, rep_dict in reps.items():
674
+ filtered_reps[loc] = {
675
+ k: v
676
+ for k, v in rep_dict.items()
677
+ if not (isinstance(k, VirtualVariable) and k.varid in self._avoid_vvar_ids)
678
+ }
679
+ reps = filtered_reps
680
+
681
+ r, new_block = BlockSimplifier._replace_and_build(block, reps, gp=self._gp, replace_loads=replace_loads)
682
+ replaced |= r
683
+ self.blocks[block] = new_block
684
+
685
+ if replaced:
686
+ # blocks have been rebuilt - expression propagation results are no longer reliable
687
+ self._clear_cache()
688
+ return replaced
689
+
690
+ #
691
+ # Unifying local variables
692
+ #
693
+
694
+ @timethis
695
+ def _unify_local_variables(self) -> bool:
696
+ """
697
+ Find variables that are definitely equivalent and then eliminate unnecessary copies.
698
+ """
699
+
700
+ simplified = False
701
+
702
+ equivalence = self._compute_equivalence()
703
+ if not equivalence:
704
+ return simplified
705
+
706
+ addr_and_idx_to_block: dict[tuple[int, int | None], Block] = {}
707
+ for block in self.func_graph.nodes():
708
+ addr_and_idx_to_block[(block.addr, block.idx)] = block
709
+
710
+ equivalences: dict[Any, set[Equivalence]] = defaultdict(set)
711
+ atom_by_loc = set()
712
+ for eq in equivalence:
713
+ equivalences[eq.atom1].add(eq)
714
+ atom_by_loc.add((eq.codeloc, eq.atom1))
715
+
716
+ # sort keys to ensure a reproducible result
717
+ sorted_loc_and_atoms = sorted(atom_by_loc, key=lambda x: x[0])
718
+
719
+ for _, atom in sorted_loc_and_atoms:
720
+ eqs = equivalences[atom]
721
+ if len(eqs) > 1:
722
+ continue
723
+
724
+ eq = next(iter(eqs))
725
+
726
+ # Acceptable equivalence classes:
727
+ #
728
+ # stack variable == register
729
+ # register variable == register
730
+ # stack variable == Conv(register, M->N)
731
+ # global variable == register
732
+ #
733
+ # Equivalence is generally created at assignment sites. Therefore, eq.atom0 is the definition and
734
+ # eq.atom1 is the use.
735
+ the_def = None
736
+ if (isinstance(eq.atom0, VirtualVariable) and eq.atom0.was_stack) or (
737
+ isinstance(eq.atom0, SimMemoryVariable)
738
+ and not isinstance(eq.atom0, SimStackVariable)
739
+ and isinstance(eq.atom0.addr, int)
740
+ ):
741
+ if isinstance(eq.atom1, VirtualVariable) and eq.atom1.was_reg:
742
+ # stack_var == register or global_var == register
743
+ to_replace = eq.atom1
744
+ to_replace_is_def = False
745
+ elif (
746
+ isinstance(eq.atom0, VirtualVariable)
747
+ and eq.atom0.was_stack
748
+ and isinstance(eq.atom1, VirtualVariable)
749
+ and eq.atom1.was_parameter
750
+ ):
751
+ # stack_var == parameter
752
+ to_replace = eq.atom0
753
+ to_replace_is_def = True
754
+ elif (
755
+ isinstance(eq.atom1, Convert)
756
+ and isinstance(eq.atom1.operand, VirtualVariable)
757
+ and eq.atom1.operand.was_reg
758
+ ):
759
+ # stack_var == Conv(register, M->N)
760
+ to_replace = eq.atom1.operand
761
+ to_replace_is_def = False
762
+ else:
763
+ continue
764
+
765
+ elif isinstance(eq.atom0, VirtualVariable) and eq.atom0.was_reg:
766
+ if isinstance(eq.atom1, VirtualVariable):
767
+ if eq.atom1.was_reg or eq.atom1.was_parameter:
768
+ # register == register
769
+ if self.project.arch.is_artificial_register(eq.atom0.reg_offset, eq.atom0.size):
770
+ to_replace = eq.atom0
771
+ to_replace_is_def = True
772
+ else:
773
+ to_replace = eq.atom1
774
+ to_replace_is_def = False
775
+ elif eq.atom1.was_stack:
776
+ # register == stack (but we try to replace the register vvar with the stack vvar)
777
+ to_replace = eq.atom0
778
+ to_replace_is_def = True
779
+ else:
780
+ continue
781
+ else:
782
+ continue
783
+
784
+ else:
785
+ continue
786
+
787
+ assert isinstance(to_replace, VirtualVariable)
788
+
789
+ # find the definition of this virtual register
790
+ rd = self._compute_reaching_definitions()
791
+ if to_replace_is_def:
792
+ # find defs
793
+ defs = []
794
+ for def_ in rd.all_definitions:
795
+ if def_.atom.varid == to_replace.varid:
796
+ defs.append(def_)
797
+ if len(defs) != 1:
798
+ continue
799
+ the_def = defs[0]
800
+ else:
801
+ # find uses
802
+ defs = rd.get_uses_by_location(eq.codeloc)
803
+ if len(defs) != 1:
804
+ # there are multiple defs for this register - we do not support replacing all of them
805
+ continue
806
+ for def_ in defs:
807
+ def_: Definition
808
+ if (
809
+ isinstance(def_.atom, atoms.VirtualVariable)
810
+ and def_.atom.category == to_replace.category
811
+ and def_.atom.oident == to_replace.oident
812
+ ):
813
+ # found it!
814
+ the_def = def_
815
+ break
816
+ if the_def is None:
817
+ continue
818
+ if the_def.codeloc.context: # FIXME: now the_def.codeloc.context is never filled in
819
+ # the definition is in a callee function
820
+ continue
821
+
822
+ def_eq_rel: DefEqRelation = DefEqRelation.UNKNOWN
823
+ if isinstance(the_def.codeloc, ExternalCodeLocation) or (
824
+ isinstance(eq.atom1, VirtualVariable) and eq.atom1.was_parameter
825
+ ):
826
+ # this is a function argument. we enter a slightly different logic and try to eliminate copies of this
827
+ # argument if
828
+ # (a) the on-stack or in-register copy of it has never been modified in this function
829
+ # (b) the function argument register has never been updated.
830
+ # TODO: we may loosen requirement (b) once we have real register versioning in AIL.
831
+ defs = [def_ for def_ in rd.all_definitions if def_.codeloc == eq.codeloc]
832
+ all_uses_with_def = None
833
+ replace_with = None
834
+ remove_initial_assignment = None
835
+ def_eq_rel = DefEqRelation.DEF_IS_FUNCARG
836
+
837
+ if defs and len(defs) == 1:
838
+ arg_copy_def = defs[0]
839
+ if (isinstance(arg_copy_def.atom, atoms.VirtualVariable) and arg_copy_def.atom.was_stack) or (
840
+ isinstance(arg_copy_def.atom, atoms.VirtualVariable) and arg_copy_def.atom.was_reg
841
+ ):
842
+ # found the copied definition (either a stack variable or a register variable)
843
+
844
+ # Make sure there is no other write to this stack location if the copy is a stack variable
845
+ if (
846
+ isinstance(arg_copy_def.atom, atoms.VirtualVariable)
847
+ and arg_copy_def.atom.was_stack
848
+ and any(
849
+ (def_ != arg_copy_def and def_.atom.stack_offset == arg_copy_def.atom.stack_offset)
850
+ for def_ in rd.all_definitions
851
+ if isinstance(def_.atom, atoms.VirtualVariable) and def_.atom.was_stack
852
+ )
853
+ ):
854
+ continue
855
+
856
+ # Make sure the register is never updated across this function
857
+ if any(
858
+ (def_ != the_def and def_.atom == the_def.atom)
859
+ for def_ in rd.all_definitions
860
+ if isinstance(def_.atom, atoms.VirtualVariable)
861
+ and def_.atom.was_reg
862
+ and rd.get_vvar_uses(def_.atom)
863
+ ):
864
+ continue
865
+
866
+ # find all its uses
867
+ all_arg_copy_var_uses: set[tuple[Any, CodeLocation]] = rd.get_vvar_uses_with_expr(
868
+ arg_copy_def.atom
869
+ )
870
+ all_uses_with_def = set()
871
+
872
+ should_abort = False
873
+ for use in all_arg_copy_var_uses:
874
+ used_expr = use[0]
875
+ if used_expr is not None and used_expr.size != arg_copy_def.size:
876
+ should_abort = True
877
+ break
878
+ all_uses_with_def.add((arg_copy_def, use))
879
+ if should_abort:
880
+ continue
881
+
882
+ replace_with = eq.atom1
883
+ remove_initial_assignment = True
884
+
885
+ if all_uses_with_def is None:
886
+ continue
887
+
888
+ else:
889
+ if (
890
+ eq.codeloc.block_addr == the_def.codeloc.block_addr
891
+ and eq.codeloc.block_idx == the_def.codeloc.block_idx
892
+ ):
893
+ # the definition and the eq location are within the same block, and the definition is before
894
+ # the eq location.
895
+ if eq.codeloc.stmt_idx < the_def.codeloc.stmt_idx:
896
+ continue
897
+ def_eq_rel = DefEqRelation.DEF_EQ_SAME_BLOCK
898
+ else:
899
+ # the definition is in the predecessor block of the eq
900
+ eq_block = next(
901
+ iter(
902
+ bb
903
+ for bb in self.func_graph
904
+ if bb.addr == eq.codeloc.block_addr and bb.idx == eq.codeloc.block_idx
905
+ )
906
+ )
907
+ eq_block_preds = set(self.func_graph.predecessors(eq_block))
908
+ if not any(
909
+ pred.addr == the_def.codeloc.block_addr and pred.idx == the_def.codeloc.block_idx
910
+ for pred in eq_block_preds
911
+ ):
912
+ continue
913
+ def_eq_rel = DefEqRelation.DEF_IN_EQ_PRED_BLOCK
914
+
915
+ if isinstance(eq.atom0, VirtualVariable) and eq.atom0.was_stack:
916
+ # create the replacement expression
917
+ if isinstance(eq.atom1, VirtualVariable) and eq.atom1.was_parameter:
918
+ # replacing atom0
919
+ new_idx = None if self._ail_manager is None else next(self._ail_manager.atom_ctr)
920
+ replace_with = VirtualVariable(
921
+ new_idx,
922
+ eq.atom1.varid,
923
+ eq.atom1.bits,
924
+ category=eq.atom1.category,
925
+ oident=eq.atom1.oident,
926
+ **eq.atom1.tags,
927
+ )
928
+ else:
929
+ # replacing atom1
930
+ new_idx = None if self._ail_manager is None else next(self._ail_manager.atom_ctr)
931
+ replace_with = VirtualVariable(
932
+ new_idx,
933
+ eq.atom0.varid,
934
+ eq.atom0.bits,
935
+ category=eq.atom0.category,
936
+ oident=eq.atom0.oident,
937
+ **eq.atom0.tags,
938
+ )
939
+ elif isinstance(eq.atom0, SimMemoryVariable) and isinstance(eq.atom0.addr, int):
940
+ # create the memory loading expression
941
+ new_idx = None if self._ail_manager is None else next(self._ail_manager.atom_ctr)
942
+ replace_with = Load(
943
+ new_idx,
944
+ Const(None, None, eq.atom0.addr, self.project.arch.bits),
945
+ eq.atom0.size,
946
+ endness=self.project.arch.memory_endness,
947
+ **eq.atom1.tags,
948
+ )
949
+ elif isinstance(eq.atom0, VirtualVariable) and eq.atom0.was_reg:
950
+ if isinstance(eq.atom1, VirtualVariable):
951
+ if eq.atom1.was_reg:
952
+ if self.project.arch.is_artificial_register(eq.atom0.reg_offset, eq.atom0.size):
953
+ replace_with = eq.atom1
954
+ else:
955
+ replace_with = eq.atom0
956
+ elif eq.atom1.was_stack:
957
+ replace_with = eq.atom1
958
+ else:
959
+ raise AngrRuntimeError(f"Unsupported atom1 vvar type {eq.atom1.category}.")
960
+ else:
961
+ raise AngrRuntimeError(f"Unsupported atom1 type {type(eq.atom1)}.")
962
+ else:
963
+ raise AngrRuntimeError(f"Unsupported atom0 type {type(eq.atom0)}.")
964
+
965
+ to_replace_def = the_def
966
+
967
+ # check: the definition of expression being replaced should not be a phi variable
968
+ if (
969
+ isinstance(to_replace_def.atom, atoms.VirtualVariable)
970
+ and to_replace_def.atom.varid in rd.phi_vvar_ids
971
+ ):
972
+ continue
973
+
974
+ # find all uses of this definition
975
+ # we make a copy of the set since we may touch the set (uses) when replacing expressions
976
+ all_uses: set[tuple[Any, CodeLocation]] = set(rd.all_vvar_uses[to_replace_def.atom.varid])
977
+ # make sure none of these uses are phi nodes (depends on more than one def)
978
+ all_uses_with_unique_def = set()
979
+ for expr_and_use in all_uses:
980
+ used_expr, use_loc = expr_and_use
981
+ defs_and_exprs = rd.get_uses_by_location(use_loc, exprs=True)
982
+ filtered_defs = {
983
+ def_
984
+ for def_, expr_ in defs_and_exprs
985
+ if expr_ is not None and used_expr is not None and expr_.varid == used_expr.varid
986
+ }
987
+ if len(filtered_defs) == 1:
988
+ all_uses_with_unique_def.add(expr_and_use)
989
+ else:
990
+ # optimization: break early
991
+ break
992
+
993
+ if len(all_uses) != len(all_uses_with_unique_def):
994
+ # only when all uses are determined by the same definition will we continue with the simplification
995
+ continue
996
+
997
+ # one more check: there can be at most one assignment in all these use locations if the expression is
998
+ # not going to be replaced with a parameter. the assignment can be an Assignment statement, but may also
999
+ # be a Store if it's a global variable (via Load) that we are replacing with
1000
+
1001
+ if not (isinstance(replace_with, VirtualVariable) and replace_with.was_parameter):
1002
+ assignment_ctr = 0
1003
+ all_use_locs = {use_loc for _, use_loc in all_uses}
1004
+ for use_loc in all_use_locs:
1005
+ if use_loc == eq.codeloc:
1006
+ continue
1007
+ assert use_loc.block_addr is not None
1008
+ assert use_loc.stmt_idx is not None
1009
+ block = addr_and_idx_to_block[(use_loc.block_addr, use_loc.block_idx)]
1010
+ stmt = block.statements[use_loc.stmt_idx]
1011
+ if isinstance(stmt, Assignment) or (isinstance(replace_with, Load) and isinstance(stmt, Store)):
1012
+ assignment_ctr += 1
1013
+ if assignment_ctr > 1:
1014
+ continue
1015
+
1016
+ all_uses_with_def = {(to_replace_def, expr_and_use) for expr_and_use in all_uses}
1017
+
1018
+ remove_initial_assignment = False # expression folding will take care of it
1019
+
1020
+ assert replace_with is not None
1021
+
1022
+ to_replace_used_in_refs = False
1023
+ if isinstance(to_replace, VirtualVariable) and to_replace.was_stack:
1024
+ # if the variable being replaced has ever been accessed as a reference, we cannot replace it safely
1025
+ for _, (_, use_loc) in all_uses_with_def:
1026
+ assert use_loc.block_addr is not None and use_loc.stmt_idx is not None
1027
+ block = addr_and_idx_to_block[(use_loc.block_addr, use_loc.block_idx)]
1028
+ stmt = block.statements[use_loc.stmt_idx]
1029
+ if self._statement_uses_ref_vvar(stmt, to_replace.varid):
1030
+ to_replace_used_in_refs = True
1031
+ break
1032
+ if to_replace_used_in_refs:
1033
+ continue
1034
+
1035
+ if any(not isinstance(expr_and_use[0], VirtualVariable) for _, expr_and_use in all_uses_with_def):
1036
+ # if any of the uses are phi assignments, we skip
1037
+ used_in_phi_assignment = False
1038
+ for _, expr_and_use in all_uses_with_def:
1039
+ u = expr_and_use[1]
1040
+ assert u.block_addr is not None
1041
+ assert u.stmt_idx is not None
1042
+ block = addr_and_idx_to_block[(u.block_addr, u.block_idx)]
1043
+ stmt = block.statements[u.stmt_idx]
1044
+ if is_phi_assignment(stmt):
1045
+ used_in_phi_assignment = True
1046
+ break
1047
+ if used_in_phi_assignment:
1048
+ continue
1049
+
1050
+ # ensure the uses we consider are all after the eq location
1051
+ filtered_all_uses_with_def = []
1052
+ for def_, expr_and_use in all_uses_with_def:
1053
+ u = expr_and_use[1]
1054
+ if (
1055
+ u.block_addr == eq.codeloc.block_addr
1056
+ and u.block_idx == eq.codeloc.block_idx
1057
+ and u.stmt_idx < eq.codeloc.stmt_idx
1058
+ ):
1059
+ # this use happens before the assignment - ignore it
1060
+ continue
1061
+ if def_eq_rel == DefEqRelation.DEF_IN_EQ_PRED_BLOCK and u.block_addr == def_.codeloc.block_addr:
1062
+ # the definition is in a predecessor block of the eq location, so all uses must be in the same
1063
+ # block as the eq location. (technically it can also be in a successor block to the eq location, but
1064
+ # we don't support it yet).
1065
+ continue
1066
+ filtered_all_uses_with_def.append((def_, expr_and_use))
1067
+ all_uses_with_def = filtered_all_uses_with_def
1068
+
1069
+ if not all_uses_with_def:
1070
+ # definitions without uses may simply be our data-flow analysis being incorrect. do not remove them.
1071
+ continue
1072
+
1073
+ # TODO: We can only replace all these uses with the stack variable if the stack variable isn't
1074
+ # TODO: re-assigned of a new value. Perform this check.
1075
+
1076
+ # replace all uses
1077
+ all_uses_replaced = True
1078
+ for def_, expr_and_use in all_uses_with_def:
1079
+ used_expr, u = expr_and_use
1080
+
1081
+ use_expr_defns = []
1082
+ for d in rd.get_uses_by_location(u):
1083
+ if (
1084
+ isinstance(d.atom, atoms.VirtualVariable)
1085
+ and d.atom.was_reg
1086
+ and isinstance(def_.atom, atoms.VirtualVariable)
1087
+ and def_.atom.was_reg
1088
+ and d.atom.reg_offset == def_.atom.reg_offset
1089
+ ) or d.atom == def_.atom:
1090
+ use_expr_defns.append(d)
1091
+ # you can never replace a use with dependencies from outside the checked defn
1092
+ if len(use_expr_defns) != 1 or next(iter(use_expr_defns)) != def_:
1093
+ if not use_expr_defns:
1094
+ _l.warning("There was no use_expr_defns for %s, this is likely a bug", u)
1095
+ # TODO: can you have multiple definitions which can all be eliminated?
1096
+ all_uses_replaced = False
1097
+ continue
1098
+
1099
+ if u == eq.codeloc:
1100
+ # skip the very initial assignment location
1101
+ continue
1102
+ old_block = addr_and_idx_to_block.get((u.block_addr, u.block_idx), None)
1103
+ if old_block is None:
1104
+ continue
1105
+ if used_expr is None:
1106
+ all_uses_replaced = False
1107
+ continue
1108
+
1109
+ # ensure the expression that we want to replace with is still up-to-date
1110
+ replace_with_original_def = self._find_atom_def_at(replace_with, rd, def_.codeloc)
1111
+ if replace_with_original_def is not None and not self._check_atom_last_def(
1112
+ replace_with, u, rd, replace_with_original_def
1113
+ ):
1114
+ all_uses_replaced = False
1115
+ continue
1116
+
1117
+ # if there is an updated block, use it
1118
+ the_block = self.blocks.get(old_block, old_block)
1119
+ stmt: Statement = the_block.statements[u.stmt_idx]
1120
+
1121
+ replace_with_copy = replace_with.copy()
1122
+ if used_expr.size != replace_with_copy.size:
1123
+ new_idx = None if self._ail_manager is None else next(self._ail_manager.atom_ctr)
1124
+ replace_with_copy = Convert(
1125
+ new_idx,
1126
+ replace_with_copy.bits,
1127
+ used_expr.bits,
1128
+ False,
1129
+ replace_with_copy,
1130
+ )
1131
+
1132
+ r, new_block = self._replace_expr_and_update_block(
1133
+ the_block, u.stmt_idx, stmt, used_expr, replace_with_copy
1134
+ )
1135
+ if r:
1136
+ self.blocks[old_block] = new_block
1137
+ else:
1138
+ # failed to replace a use - we need to keep the initial assignment!
1139
+ all_uses_replaced = False
1140
+ simplified |= r
1141
+
1142
+ if all_uses_replaced and remove_initial_assignment:
1143
+ # the initial statement can be removed
1144
+ self._assignments_to_remove.add(eq.codeloc)
1145
+
1146
+ if simplified:
1147
+ self._clear_cache()
1148
+ return simplified
1149
+
1150
+ @staticmethod
1151
+ def _find_atom_def_at(atom, rd, codeloc: CodeLocation) -> Definition | None:
1152
+ if isinstance(atom, Register):
1153
+ defs = rd.get_defs(atom, codeloc, OP_BEFORE)
1154
+ return next(iter(defs)) if len(defs) == 1 else None
1155
+
1156
+ return None
1157
+
1158
+ @staticmethod
1159
+ def _check_atom_last_def(atom, codeloc, rd, the_def) -> bool:
1160
+ if isinstance(atom, Register):
1161
+ defs = rd.get_defs(atom, codeloc, OP_BEFORE)
1162
+ for d in defs:
1163
+ if d.codeloc != the_def.codeloc:
1164
+ return False
1165
+
1166
+ return True
1167
+
1168
+ #
1169
+ # Folding call expressions
1170
+ #
1171
+
1172
+ @staticmethod
1173
+ def _is_expr_using_temporaries(expr: Expression) -> bool:
1174
+ walker = AILBlockTempCollector()
1175
+ walker.walk_expression(expr)
1176
+ return len(walker.temps) > 0
1177
+
1178
+ @staticmethod
1179
+ def _is_stmt_using_temporaries(stmt: Statement) -> bool:
1180
+ walker = AILBlockTempCollector()
1181
+ walker.walk_statement(stmt)
1182
+ return len(walker.temps) > 0
1183
+
1184
+ @timethis
1185
+ def _fold_call_exprs(self) -> bool:
1186
+ """
1187
+ Fold a call expression (statement) into other statements if the return value of the call expression (statement)
1188
+ is only used once, and the use site and the call site belongs to the same supernode.
1189
+
1190
+ Example::
1191
+
1192
+ s1 = func();
1193
+ s0 = s1;
1194
+ if (s0) ...
1195
+
1196
+ after folding, it will be transformed to::
1197
+
1198
+ s0 = func();
1199
+ if (s0) ...
1200
+
1201
+ s0 can be folded into the condition, which means this example can further be transformed to::
1202
+
1203
+ if (func()) ...
1204
+
1205
+ this behavior is controlled by fold_callexprs_into_conditions. This to avoid cases where func() is called more
1206
+ than once after simplification and graph structuring where conditions might be duplicated (e.g., in Dream).
1207
+ In such cases, the one-use expression folder in RegionSimplifier will perform this transformation.
1208
+ """
1209
+
1210
+ # pylint:disable=unreachable
1211
+ simplified = False
1212
+
1213
+ equivalence = self._compute_equivalence()
1214
+ if not equivalence:
1215
+ return simplified
1216
+
1217
+ addr_and_idx_to_block: dict[tuple[int, int | None], Block] = {}
1218
+ for block in self.func_graph.nodes():
1219
+ addr_and_idx_to_block[(block.addr, block.idx)] = block
1220
+
1221
+ def_locations_to_remove: set[CodeLocation] = set()
1222
+ updated_use_locations: set[CodeLocation] = set()
1223
+
1224
+ for eq in equivalence:
1225
+ # register variable == Call
1226
+ if isinstance(eq.atom0, VirtualVariable) and eq.atom0.was_reg:
1227
+ if isinstance(eq.atom1, Call):
1228
+ # register variable = Call
1229
+ call: Expression = eq.atom1
1230
+ # call_addr = call.target.value if isinstance(call.target, Const) else None
1231
+ elif isinstance(eq.atom1, Convert) and isinstance(eq.atom1.operand, Call):
1232
+ # register variable = Convert(Call)
1233
+ call = eq.atom1
1234
+ # call_addr = call.operand.target.value if isinstance(call.operand.target, Const) else None
1235
+ elif eq.is_weakassignment:
1236
+ # variable =w something else
1237
+ call = eq.atom1
1238
+ else:
1239
+ continue
1240
+
1241
+ if self._is_expr_using_temporaries(call):
1242
+ continue
1243
+
1244
+ if eq.codeloc in updated_use_locations:
1245
+ # this def is now created by an updated use. the corresponding statement will be updated in the end.
1246
+ # we must rerun Propagator to get an updated definition (and Equivalence)
1247
+ continue
1248
+
1249
+ # find all uses of this virtual register
1250
+ rd = self._compute_reaching_definitions()
1251
+
1252
+ the_def: Definition = Definition(
1253
+ atoms.VirtualVariable(
1254
+ eq.atom0.varid, eq.atom0.size, category=eq.atom0.category, oident=eq.atom0.oident
1255
+ ),
1256
+ eq.codeloc,
1257
+ )
1258
+ assert the_def.codeloc.block_addr is not None
1259
+ assert the_def.codeloc.stmt_idx is not None
1260
+
1261
+ all_uses: set[tuple[Any, CodeLocation]] = rd.get_vvar_uses_with_expr(the_def.atom)
1262
+ if eq.is_weakassignment:
1263
+ # eliminate the "use" at the weak assignment site
1264
+ all_uses = {use for use in all_uses if use[1] != eq.codeloc}
1265
+
1266
+ if len(all_uses) != 1:
1267
+ continue
1268
+ used_expr, u = next(iter(all_uses))
1269
+ if used_expr is None:
1270
+ continue
1271
+ assert u.block_addr is not None
1272
+ assert u.stmt_idx is not None
1273
+
1274
+ if u in def_locations_to_remove:
1275
+ # this use site has been altered by previous folding attempts. the corresponding statement will be
1276
+ # removed in the end. in this case, this Equivalence is probably useless, and we must rerun
1277
+ # Propagator to get an updated Equivalence.
1278
+ continue
1279
+
1280
+ if not self._fold_callexprs_into_conditions:
1281
+ # check the statement and make sure it's not a conditional jump
1282
+ the_block = addr_and_idx_to_block[(u.block_addr, u.block_idx)]
1283
+ if isinstance(the_block.statements[u.stmt_idx], ConditionalJump):
1284
+ continue
1285
+
1286
+ # check if the use and the definition is within the same supernode
1287
+ # also we do not allow any calls between the def site and the use site
1288
+ if not self._loc_within_superblock(
1289
+ addr_and_idx_to_block[(the_def.codeloc.block_addr, the_def.codeloc.block_idx)],
1290
+ u.block_addr,
1291
+ u.block_idx,
1292
+ terminate_with_calls=True,
1293
+ ):
1294
+ continue
1295
+
1296
+ # ensure there are no other calls between the def site and the use site.
1297
+ # this is because we do not want to alter the order of calls.
1298
+ u_inclusive = CodeLocation(u.block_addr, u.stmt_idx + 1, block_idx=u.block_idx)
1299
+ # note that the target statement being a store is fine
1300
+ if (
1301
+ has_call_in_between_stmts(
1302
+ self.func_graph,
1303
+ addr_and_idx_to_block,
1304
+ the_def.codeloc,
1305
+ u_inclusive,
1306
+ skip_if_contains_vvar=the_def.atom.varid,
1307
+ )
1308
+ or has_store_stmt_in_between_stmts(self.func_graph, addr_and_idx_to_block, the_def.codeloc, u)
1309
+ or has_load_expr_in_between_stmts(
1310
+ self.func_graph,
1311
+ addr_and_idx_to_block,
1312
+ the_def.codeloc,
1313
+ u_inclusive,
1314
+ skip_if_contains_vvar=the_def.atom.varid,
1315
+ )
1316
+ ):
1317
+ continue
1318
+
1319
+ # replace all uses
1320
+ old_block = addr_and_idx_to_block.get((u.block_addr, u.block_idx), None)
1321
+ if old_block is None:
1322
+ continue
1323
+
1324
+ # if there is an updated block, use that
1325
+ the_block = self.blocks.get(old_block, old_block)
1326
+ stmt: Statement = the_block.statements[u.stmt_idx]
1327
+
1328
+ if isinstance(eq.atom0, VirtualVariable):
1329
+ src = used_expr
1330
+ dst: Expression = call.copy()
1331
+
1332
+ if isinstance(dst, Call) and dst.ret_expr is not None:
1333
+ dst_bits = dst.ret_expr.bits
1334
+ # clear the ret_expr and fp_ret_expr of dst, then set bits so that it can be used as an
1335
+ # expression
1336
+ dst.ret_expr = None
1337
+ dst.fp_ret_expr = None
1338
+ dst.bits = dst_bits
1339
+
1340
+ if src.bits != dst.bits and not eq.is_weakassignment:
1341
+ dst = Convert(None, dst.bits, src.bits, False, dst)
1342
+ else:
1343
+ continue
1344
+
1345
+ # ensure what we are going to replace only appears once
1346
+ expr_ctr = SingleExpressionCounter(stmt, src)
1347
+ if expr_ctr.count > 1:
1348
+ continue
1349
+
1350
+ replaced, new_block = self._replace_expr_and_update_block(the_block, u.stmt_idx, stmt, src, dst)
1351
+
1352
+ if replaced:
1353
+ self.blocks[old_block] = new_block
1354
+ # this call has been folded to the use site. we can remove this call.
1355
+ self._calls_to_remove.add(eq.codeloc)
1356
+ simplified = True
1357
+ def_locations_to_remove.add(eq.codeloc)
1358
+ updated_use_locations.add(u)
1359
+
1360
+ # no need to clear the cache at the end of this method
1361
+ return simplified
1362
+
1363
+ def _get_super_node_blocks(self, start_node: Block) -> list[Block]:
1364
+ lst: list[Block] = [start_node]
1365
+ while True:
1366
+ b = lst[-1]
1367
+ successors = list(self.func_graph.successors(b))
1368
+ if len(successors) == 0:
1369
+ break
1370
+ if len(successors) == 1:
1371
+ succ = successors[0]
1372
+ # check its predecessors
1373
+ succ_predecessors = list(self.func_graph.predecessors(succ))
1374
+ if len(succ_predecessors) == 1:
1375
+ if succ in lst:
1376
+ # we are about to form a loop - bad!
1377
+ # example: binary ce1897b492c80bf94083dd783aefb413ab1f6d8d4981adce8420f6669d0cb3e1, block
1378
+ # 0x2976EF7.
1379
+ break
1380
+ lst.append(succ)
1381
+ else:
1382
+ break
1383
+ else:
1384
+ # too many successors
1385
+ break
1386
+ return lst
1387
+
1388
+ def _loc_within_superblock(
1389
+ self, start_node: Block, block_addr: int, block_idx: int | None, terminate_with_calls=False
1390
+ ) -> bool:
1391
+ b = start_node
1392
+ if block_addr == b.addr and block_idx == b.idx:
1393
+ return True
1394
+
1395
+ encountered_block_addrs: set[tuple[int, int | None]] = {(b.addr, b.idx)}
1396
+ while True:
1397
+ if terminate_with_calls and b.statements and isinstance(b.statements[-1], Call):
1398
+ return False
1399
+
1400
+ encountered_block_addrs.add((b.addr, b.idx))
1401
+ successors = list(self.func_graph.successors(b))
1402
+ if len(successors) == 0:
1403
+ # did not encounter the block before running out of successors
1404
+ return False
1405
+ if len(successors) == 1:
1406
+ succ = successors[0]
1407
+ # check its predecessors
1408
+ succ_predecessors = list(self.func_graph.predecessors(succ))
1409
+ if len(succ_predecessors) == 1:
1410
+ if (succ.addr, succ.idx) in encountered_block_addrs:
1411
+ # we are about to form a loop - bad!
1412
+ # example: binary ce1897b492c80bf94083dd783aefb413ab1f6d8d4981adce8420f6669d0cb3e1, block
1413
+ # 0x2976EF7.
1414
+ return False
1415
+ if block_addr == succ.addr and block_idx == succ.idx:
1416
+ return True
1417
+ b = succ
1418
+ else:
1419
+ return False
1420
+ else:
1421
+ # too many successors
1422
+ return False
1423
+
1424
+ @staticmethod
1425
+ def _replace_expr_and_update_block(block, stmt_idx, stmt, src_expr, dst_expr) -> tuple[bool, Block | None]:
1426
+ replaced, new_stmt = stmt.replace(src_expr, dst_expr)
1427
+ if replaced:
1428
+ new_block = block.copy()
1429
+ new_block.statements = block.statements[::]
1430
+ new_block.statements[stmt_idx] = new_stmt
1431
+ return True, new_block
1432
+
1433
+ return False, None
1434
+
1435
+ @timethis
1436
+ def _iteratively_remove_dead_assignments(self) -> bool:
1437
+ anything_removed = False
1438
+ while True:
1439
+ r = self._remove_dead_assignments()
1440
+ if not r:
1441
+ return anything_removed
1442
+ self._rebuild_func_graph()
1443
+ self._clear_cache()
1444
+
1445
+ @timethis
1446
+ def _remove_dead_assignments(self) -> bool:
1447
+
1448
+ # keeping tracking of statements to remove and statements (as well as dead vvars) to keep allows us to handle
1449
+ # cases where a statement defines more than one atom, e.g., a call statement that defines both the return
1450
+ # value and the floating-point return value.
1451
+ stmts_to_remove_per_block: dict[tuple[int, int | None], set[int]] = defaultdict(set)
1452
+ stmts_to_keep_per_block: dict[tuple[int, int | None], set[int]] = defaultdict(set)
1453
+ dead_vvar_ids: set[int] = self._removed_vvar_ids.copy()
1454
+ dead_vvar_codelocs: set[CodeLocation] = set()
1455
+ blocks: dict[tuple[int, int | None], Block] = {
1456
+ (node.addr, node.idx): self.blocks.get(node, node) for node in self.func_graph.nodes()
1457
+ }
1458
+
1459
+ # Find all statements that should be removed
1460
+ mask = (1 << self.project.arch.bits) - 1
1461
+
1462
+ rd = self._compute_reaching_definitions()
1463
+ stackarg_offsets = (
1464
+ {(tpl[1] & mask) for tpl in self._stack_arg_offsets} if self._stack_arg_offsets is not None else None
1465
+ )
1466
+
1467
+ while True:
1468
+ new_dead_vars_found = False
1469
+
1470
+ # traverse all virtual variable definitions
1471
+ for vvar_id, codeloc in rd.all_vvar_definitions.items():
1472
+ if vvar_id in dead_vvar_ids:
1473
+ continue
1474
+ uses = None
1475
+ if vvar_id in self._propagator_dead_vvar_ids:
1476
+ # we are definitely removing this variable if it has no uses
1477
+ uses = rd.all_vvar_uses[vvar_id]
1478
+
1479
+ if uses is None:
1480
+ vvar = rd.varid_to_vvar[vvar_id]
1481
+ def_codeloc = rd.all_vvar_definitions[vvar_id]
1482
+ if isinstance(def_codeloc, ExternalCodeLocation):
1483
+ def_stmt = None
1484
+ else:
1485
+ assert def_codeloc.block_addr is not None and def_codeloc.stmt_idx is not None
1486
+ def_stmt = blocks[(def_codeloc.block_addr, def_codeloc.block_idx)].statements[
1487
+ def_codeloc.stmt_idx
1488
+ ]
1489
+ if is_vvar_eliminatable(vvar, def_stmt):
1490
+ uses = rd.all_vvar_uses[vvar_id]
1491
+ elif vvar.was_stack:
1492
+ if not self._remove_dead_memdefs:
1493
+ if rd.is_phi_vvar_id(vvar_id):
1494
+ # we always remove unused phi variables
1495
+ pass
1496
+ elif vvar_id in self._secondary_stackvars:
1497
+ # secondary stack variables are potentially removable
1498
+ pass
1499
+ elif stackarg_offsets is not None:
1500
+ # we always remove definitions for stack arguments
1501
+ assert vvar.stack_offset is not None
1502
+ if (vvar.stack_offset & mask) not in stackarg_offsets:
1503
+ continue
1504
+ else:
1505
+ continue
1506
+ uses = rd.all_vvar_uses[vvar_id]
1507
+
1508
+ else:
1509
+ uses = set()
1510
+
1511
+ # remove uses where vvars are going to be removed
1512
+ filtered_uses_count = 0
1513
+ for _, loc in uses:
1514
+ if loc in dead_vvar_codelocs and loc.block_addr is not None and loc.stmt_idx is not None:
1515
+ stmt = blocks[(loc.block_addr, loc.block_idx)].statements[loc.stmt_idx]
1516
+ if not self._statement_has_call_exprs(stmt) and not isinstance(stmt, (DirtyStatement, Call)):
1517
+ continue
1518
+ filtered_uses_count += 1
1519
+
1520
+ if filtered_uses_count == 0:
1521
+ new_dead_vars_found = True
1522
+ dead_vvar_ids.add(vvar_id)
1523
+ dead_vvar_codelocs.add(codeloc)
1524
+ if not isinstance(codeloc, ExternalCodeLocation):
1525
+ assert codeloc.block_addr is not None
1526
+ assert codeloc.stmt_idx is not None
1527
+ stmts_to_remove_per_block[(codeloc.block_addr, codeloc.block_idx)].add(codeloc.stmt_idx)
1528
+ stmts_to_keep_per_block[(codeloc.block_addr, codeloc.block_idx)].discard(codeloc.stmt_idx)
1529
+ else:
1530
+ if not isinstance(codeloc, ExternalCodeLocation):
1531
+ assert codeloc.block_addr is not None
1532
+ assert codeloc.stmt_idx is not None
1533
+ stmts_to_keep_per_block[(codeloc.block_addr, codeloc.block_idx)].add(codeloc.stmt_idx)
1534
+
1535
+ if not new_dead_vars_found:
1536
+ # nothing more is found. let's end the loop
1537
+ break
1538
+
1539
+ # find all phi variables that rely on variables that no longer exist
1540
+ removed_vvar_ids = self._removed_vvar_ids
1541
+ while True:
1542
+ new_removed_vvar_ids = set()
1543
+ for phi_varid, phi_use_varids in rd.phivarid_to_varids.items():
1544
+ if phi_varid not in dead_vvar_ids and any(vvarid in removed_vvar_ids for vvarid in phi_use_varids):
1545
+ loc = rd.all_vvar_definitions[phi_varid]
1546
+ assert loc.block_addr is not None and loc.stmt_idx is not None
1547
+ if loc.stmt_idx not in stmts_to_remove_per_block[(loc.block_addr, loc.block_idx)]:
1548
+ stmts_to_remove_per_block[(loc.block_addr, loc.block_idx)].add(loc.stmt_idx)
1549
+ new_removed_vvar_ids.add(phi_varid)
1550
+ dead_vvar_ids.add(phi_varid)
1551
+ if not new_removed_vvar_ids:
1552
+ break
1553
+ removed_vvar_ids = new_removed_vvar_ids
1554
+
1555
+ # find all phi variables that are only ever used by other phi variables
1556
+ redundant_phi_and_dirty_varids = self._find_cyclic_dependent_phis_and_dirty_vvars(rd, dead_vvar_ids)
1557
+ for varid in redundant_phi_and_dirty_varids:
1558
+ loc = rd.all_vvar_definitions[varid]
1559
+ assert loc.block_addr is not None and loc.stmt_idx is not None
1560
+ if loc.stmt_idx not in stmts_to_remove_per_block[(loc.block_addr, loc.block_idx)]:
1561
+ stmts_to_remove_per_block[(loc.block_addr, loc.block_idx)].add(loc.stmt_idx)
1562
+ stmts_to_keep_per_block[(loc.block_addr, loc.block_idx)].discard(loc.stmt_idx)
1563
+
1564
+ for codeloc in self._calls_to_remove | self._assignments_to_remove:
1565
+ # this call can be removed. make sure it exists in stmts_to_remove_per_block
1566
+ assert codeloc.block_addr is not None and codeloc.stmt_idx is not None
1567
+ stmts_to_remove_per_block[codeloc.block_addr, codeloc.block_idx].add(codeloc.stmt_idx)
1568
+
1569
+ simplified = False
1570
+
1571
+ # Remove the statements
1572
+ for old_block in self.func_graph.nodes():
1573
+ # if there is an updated block, use it
1574
+ block = self.blocks.get(old_block, old_block)
1575
+
1576
+ if not isinstance(block, Block):
1577
+ continue
1578
+
1579
+ if (block.addr, block.idx) not in stmts_to_remove_per_block:
1580
+ continue
1581
+
1582
+ new_statements = []
1583
+ stmts_to_remove = stmts_to_remove_per_block[(block.addr, block.idx)]
1584
+ stmts_to_keep = stmts_to_keep_per_block[(block.addr, block.idx)]
1585
+
1586
+ if not stmts_to_remove:
1587
+ continue
1588
+
1589
+ for idx, stmt in enumerate(block.statements):
1590
+ if idx in stmts_to_remove and idx in stmts_to_keep and isinstance(stmt, Call):
1591
+ # this statement declares more than one variable. we should handle it surgically
1592
+ # case 1: stmt.ret_expr and stmt.fp_ret_expr are both set, but one of them is not used
1593
+ if isinstance(stmt.ret_expr, VirtualVariable) and stmt.ret_expr.varid in dead_vvar_ids:
1594
+ stmt = stmt.copy()
1595
+ stmt.ret_expr = None
1596
+ simplified = True
1597
+ if isinstance(stmt.fp_ret_expr, VirtualVariable) and stmt.fp_ret_expr.varid in dead_vvar_ids:
1598
+ stmt = stmt.copy()
1599
+ stmt.fp_ret_expr = None
1600
+ simplified = True
1601
+
1602
+ if idx in stmts_to_remove and idx not in stmts_to_keep and not isinstance(stmt, DirtyStatement):
1603
+ if isinstance(stmt, (Assignment, WeakAssignment, Store)):
1604
+ # Special logic for Assignment and Store statements
1605
+
1606
+ # if this statement writes to a virtual variable that must be preserved, we ignore it
1607
+ if (
1608
+ isinstance(stmt, Assignment)
1609
+ and isinstance(stmt.dst, VirtualVariable)
1610
+ and stmt.dst.varid in self._avoid_vvar_ids
1611
+ ):
1612
+ new_statements.append(stmt)
1613
+ continue
1614
+
1615
+ # if this statement triggers a call, it should only be removed if it's in self._calls_to_remove
1616
+ codeloc = CodeLocation(block.addr, idx, ins_addr=stmt.ins_addr, block_idx=block.idx)
1617
+ if codeloc in self._assignments_to_remove:
1618
+ # it should be removed
1619
+ simplified = True
1620
+ self._assignments_to_remove.discard(codeloc)
1621
+ continue
1622
+
1623
+ if self._statement_has_call_exprs(stmt):
1624
+ if codeloc in self._calls_to_remove:
1625
+ # it has a call and must be removed
1626
+ self._calls_to_remove.discard(codeloc)
1627
+ simplified = True
1628
+ continue
1629
+ if isinstance(stmt, Assignment) and isinstance(stmt.dst, VirtualVariable):
1630
+ # no one is using the returned virtual variable.
1631
+ # now the things are a bit tricky here
1632
+ if isinstance(stmt.src, Call):
1633
+ # replace this assignment statement with a call statement
1634
+ stmt = stmt.src
1635
+ elif isinstance(stmt.src, Convert) and isinstance(stmt.src.operand, Call):
1636
+ # the convert is useless now
1637
+ stmt = stmt.src.operand
1638
+ else:
1639
+ # we can't change this stmt at all because it has an expression with Calls inside
1640
+ pass
1641
+ else:
1642
+ # no calls. remove it
1643
+ simplified = True
1644
+ continue
1645
+ elif isinstance(stmt, Call):
1646
+ codeloc = CodeLocation(block.addr, idx, ins_addr=stmt.ins_addr, block_idx=block.idx)
1647
+ if codeloc in self._calls_to_remove:
1648
+ # this call can be removed
1649
+ self._calls_to_remove.discard(codeloc)
1650
+ simplified = True
1651
+ continue
1652
+
1653
+ if stmt.ret_expr is not None or stmt.fp_ret_expr is not None:
1654
+ # both the return expr and the fp_ret_expr are not used
1655
+ stmt = stmt.copy()
1656
+ stmt.ret_expr = None
1657
+ stmt.fp_ret_expr = None
1658
+ simplified = True
1659
+ else:
1660
+ # Should not happen!
1661
+ raise NotImplementedError
1662
+
1663
+ new_statements.append(stmt)
1664
+
1665
+ new_block = block.copy()
1666
+ new_block.statements = new_statements
1667
+ self.blocks[old_block] = new_block
1668
+
1669
+ return simplified
1670
+
1671
+ @staticmethod
1672
+ def _get_vvar_used_by(
1673
+ vvar_id: int, rd: SRDAModel, blocks_dict: dict[tuple[int, int | None], Block]
1674
+ ) -> set[int | None]:
1675
+ """
1676
+ Get all atoms that use a specified virtual variable. The atoms are in the form of virtual variable ID or None
1677
+ (indicating the virtual variable is used by another statement like Store).
1678
+
1679
+ :param vvar_id: ID of the virtual variable.
1680
+ :param rd: The SRDA model.
1681
+ :return: The set of vvar use atoms.
1682
+ """
1683
+
1684
+ used_by: set[int | None] = set()
1685
+ for used_vvar, loc in rd.all_vvar_uses[vvar_id]:
1686
+ if used_vvar is None:
1687
+ # no explicit reference
1688
+ used_by.add(None)
1689
+ elif loc.block_addr is not None:
1690
+ assert loc.stmt_idx is not None
1691
+ stmt = blocks_dict[(loc.block_addr, loc.block_idx)].statements[loc.stmt_idx]
1692
+ if isinstance(stmt, Assignment) and isinstance(stmt.dst, VirtualVariable):
1693
+ used_by.add(stmt.dst.varid)
1694
+ else:
1695
+ used_by.add(None)
1696
+ return used_by
1697
+
1698
+ def _find_cyclic_dependent_phis_and_dirty_vvars(self, rd: SRDAModel, dead_vvar_ids: set[int]) -> set[int]:
1699
+ blocks_dict: dict[tuple[int, int | None], Block] = {(bb.addr, bb.idx): bb for bb in self.func_graph}
1700
+
1701
+ # find dirty vvars and vexccall vvars
1702
+ dirty_vvar_ids = set()
1703
+ for bb in self.func_graph:
1704
+ for stmt in bb.statements:
1705
+ if (
1706
+ isinstance(stmt, Assignment)
1707
+ and isinstance(stmt.dst, VirtualVariable)
1708
+ and stmt.dst.was_reg
1709
+ and isinstance(stmt.src, (DirtyExpression, VEXCCallExpression))
1710
+ ):
1711
+ dirty_vvar_ids.add(stmt.dst.varid)
1712
+
1713
+ phi_and_dirty_vvar_ids = (rd.phi_vvar_ids | dirty_vvar_ids).difference(dead_vvar_ids)
1714
+
1715
+ vvar_used_by: dict[int, set[int | None]] = defaultdict(set)
1716
+ for var_id in phi_and_dirty_vvar_ids:
1717
+ if var_id in rd.phivarid_to_varids:
1718
+ for used_by_varid in rd.phivarid_to_varids[var_id]:
1719
+ if used_by_varid in dead_vvar_ids:
1720
+ # this variable no longer exists
1721
+ continue
1722
+ if used_by_varid not in vvar_used_by:
1723
+ vvar_used_by[used_by_varid] |= self._get_vvar_used_by(
1724
+ used_by_varid, rd, blocks_dict
1725
+ ).difference(dead_vvar_ids)
1726
+ vvar_used_by[used_by_varid].add(var_id) # probably unnecessary
1727
+ vvar_used_by[var_id] |= self._get_vvar_used_by(var_id, rd, blocks_dict).difference(dead_vvar_ids)
1728
+
1729
+ g = networkx.DiGraph()
1730
+ dummy_vvar_id = -1
1731
+ for var_id, used_by_initial in vvar_used_by.items():
1732
+ for u in used_by_initial:
1733
+ if u is None:
1734
+ # we can't have None in networkx.DiGraph
1735
+ g.add_edge(var_id, dummy_vvar_id)
1736
+ else:
1737
+ g.add_edge(var_id, u)
1738
+
1739
+ cyclic_dependent_phi_varids = set()
1740
+ for scc in networkx.strongly_connected_components(g):
1741
+ if len(scc) == 1:
1742
+ continue
1743
+
1744
+ bail = False
1745
+ for varid in scc:
1746
+ # ensure this vvar is not used by anything else outside the scc (regardless of whether this vvar is a
1747
+ # phi variable or not)
1748
+ if varid in vvar_used_by and None in vvar_used_by[varid]:
1749
+ bail = True
1750
+ break
1751
+ if bail is False:
1752
+ succs = list(g.successors(varid))
1753
+ if any(succ_varid not in scc for succ_varid in succs):
1754
+ bail = True
1755
+ break
1756
+ if bail:
1757
+ continue
1758
+
1759
+ if all(varid in phi_and_dirty_vvar_ids or rd.varid_to_vvar[varid].was_reg for varid in scc):
1760
+ cyclic_dependent_phi_varids |= set(scc)
1761
+
1762
+ return cyclic_dependent_phi_varids
1763
+
1764
+ #
1765
+ # Rewriting ccalls
1766
+ #
1767
+
1768
+ def _rewrite_ccalls(self):
1769
+ rewriter_cls = CCALL_REWRITERS.get(self.project.arch.name, None)
1770
+ if rewriter_cls is None:
1771
+ return False
1772
+
1773
+ walker = AILBlockWalker()
1774
+
1775
+ class _any_update:
1776
+ """
1777
+ Dummy class for storing if any result has been updated.
1778
+ """
1779
+
1780
+ v = False
1781
+
1782
+ def _handle_expr(
1783
+ expr_idx: int, expr: Expression, stmt_idx: int, stmt: Statement | None, block: Block | None
1784
+ ) -> Expression | None:
1785
+ if isinstance(expr, VEXCCallExpression):
1786
+ rewriter = rewriter_cls(expr, self.project.arch)
1787
+ if rewriter.result is not None:
1788
+ _any_update.v = True
1789
+ return rewriter.result
1790
+ return None
1791
+
1792
+ return AILBlockWalker._handle_expr(walker, expr_idx, expr, stmt_idx, stmt, block)
1793
+
1794
+ blocks_by_addr_and_idx = {(node.addr, node.idx): node for node in self.func_graph.nodes()}
1795
+ walker._handle_expr = _handle_expr
1796
+
1797
+ updated = False
1798
+ for block in blocks_by_addr_and_idx.values():
1799
+ _any_update.v = False
1800
+ old_block = block.copy()
1801
+ walker.walk(block)
1802
+ if _any_update.v:
1803
+ self.blocks[old_block] = block
1804
+ updated = True
1805
+
1806
+ return updated
1807
+
1808
+ #
1809
+ # Util functions
1810
+ #
1811
+
1812
+ @staticmethod
1813
+ def _statement_has_call_exprs(stmt: Statement) -> bool:
1814
+ def _handle_callexpr(expr_idx, expr, stmt_idx, stmt, block): # pylint:disable=unused-argument
1815
+ raise HasCallNotification
1816
+
1817
+ walker = AILBlockWalker()
1818
+ walker.expr_handlers[Call] = _handle_callexpr
1819
+ try:
1820
+ walker.walk_statement(stmt)
1821
+ except HasCallNotification:
1822
+ return True
1823
+
1824
+ return False
1825
+
1826
+ @staticmethod
1827
+ def _expression_has_call_exprs(expr: Expression) -> bool:
1828
+ def _handle_callexpr(expr_idx, expr, stmt_idx, stmt, block): # pylint:disable=unused-argument
1829
+ raise HasCallNotification
1830
+
1831
+ walker = AILBlockWalker()
1832
+ walker.expr_handlers[Call] = _handle_callexpr
1833
+ try:
1834
+ walker.walk_expression(expr)
1835
+ except HasCallNotification:
1836
+ return True
1837
+
1838
+ return False
1839
+
1840
+ @staticmethod
1841
+ def _exprs_contain_vvar(exprs: Iterable[Expression], vvar_ids: set[int]) -> bool:
1842
+ def _handle_VirtualVariable(expr_idx, expr, stmt_idx, stmt, block): # pylint:disable=unused-argument
1843
+ if expr.varid in vvar_ids:
1844
+ raise HasVVarNotification
1845
+
1846
+ walker = AILBlockWalker()
1847
+ walker.expr_handlers[VirtualVariable] = _handle_VirtualVariable
1848
+
1849
+ for expr in exprs:
1850
+ try:
1851
+ walker.walk_expression(expr)
1852
+ except HasVVarNotification:
1853
+ return True
1854
+ return False
1855
+
1856
+ @staticmethod
1857
+ def _statement_uses_ref_vvar(stmt: Statement, vvar_id: int) -> bool:
1858
+ def _handle_UnaryOp(expr_idx, expr, stmt_idx, stmt, block): # pylint:disable=unused-argument
1859
+ if expr.op == "Reference" and isinstance(expr.operand, VirtualVariable) and expr.operand.varid == vvar_id:
1860
+ raise HasRefVVarNotification
1861
+
1862
+ walker = AILBlockWalker()
1863
+ walker.expr_handlers[UnaryOp] = _handle_UnaryOp
1864
+ try:
1865
+ walker.walk_statement(stmt)
1866
+ except HasRefVVarNotification:
1867
+ return True
1868
+
1869
+ return False
1870
+
1871
+
1872
+ AnalysesHub.register_default("AILSimplifier", AILSimplifier)