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