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