angr 9.2.103__py3-none-macosx_11_0_arm64.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 (1300) hide show
  1. angr/__init__.py +153 -0
  2. angr/__main__.py +59 -0
  3. angr/analyses/__init__.py +46 -0
  4. angr/analyses/analysis.py +359 -0
  5. angr/analyses/backward_slice.py +691 -0
  6. angr/analyses/binary_optimizer.py +683 -0
  7. angr/analyses/bindiff.py +1251 -0
  8. angr/analyses/boyscout.py +77 -0
  9. angr/analyses/callee_cleanup_finder.py +75 -0
  10. angr/analyses/calling_convention.py +956 -0
  11. angr/analyses/cdg.py +197 -0
  12. angr/analyses/cfg/__init__.py +11 -0
  13. angr/analyses/cfg/cfb.py +436 -0
  14. angr/analyses/cfg/cfg.py +73 -0
  15. angr/analyses/cfg/cfg_arch_options.py +82 -0
  16. angr/analyses/cfg/cfg_base.py +2917 -0
  17. angr/analyses/cfg/cfg_emulated.py +3570 -0
  18. angr/analyses/cfg/cfg_fast.py +5053 -0
  19. angr/analyses/cfg/cfg_fast_soot.py +669 -0
  20. angr/analyses/cfg/cfg_job_base.py +204 -0
  21. angr/analyses/cfg/indirect_jump_resolvers/__init__.py +8 -0
  22. angr/analyses/cfg/indirect_jump_resolvers/amd64_elf_got.py +63 -0
  23. angr/analyses/cfg/indirect_jump_resolvers/amd64_pe_iat.py +52 -0
  24. angr/analyses/cfg/indirect_jump_resolvers/arm_elf_fast.py +151 -0
  25. angr/analyses/cfg/indirect_jump_resolvers/const_resolver.py +141 -0
  26. angr/analyses/cfg/indirect_jump_resolvers/default_resolvers.py +68 -0
  27. angr/analyses/cfg/indirect_jump_resolvers/jumptable.py +2368 -0
  28. angr/analyses/cfg/indirect_jump_resolvers/mips_elf_fast.py +517 -0
  29. angr/analyses/cfg/indirect_jump_resolvers/propagator_utils.py +26 -0
  30. angr/analyses/cfg/indirect_jump_resolvers/resolver.py +74 -0
  31. angr/analyses/cfg/indirect_jump_resolvers/x86_elf_pic_plt.py +93 -0
  32. angr/analyses/cfg/indirect_jump_resolvers/x86_pe_iat.py +51 -0
  33. angr/analyses/cfg_slice_to_sink/__init__.py +2 -0
  34. angr/analyses/cfg_slice_to_sink/cfg_slice_to_sink.py +117 -0
  35. angr/analyses/cfg_slice_to_sink/graph.py +84 -0
  36. angr/analyses/cfg_slice_to_sink/transitions.py +25 -0
  37. angr/analyses/class_identifier.py +62 -0
  38. angr/analyses/code_tagging.py +123 -0
  39. angr/analyses/complete_calling_conventions.py +424 -0
  40. angr/analyses/congruency_check.py +384 -0
  41. angr/analyses/data_dep/__init__.py +2 -0
  42. angr/analyses/data_dep/data_dependency_analysis.py +605 -0
  43. angr/analyses/data_dep/dep_nodes.py +170 -0
  44. angr/analyses/data_dep/sim_act_location.py +46 -0
  45. angr/analyses/datagraph_meta.py +105 -0
  46. angr/analyses/ddg.py +1695 -0
  47. angr/analyses/decompiler/__init__.py +13 -0
  48. angr/analyses/decompiler/ail_simplifier.py +1408 -0
  49. angr/analyses/decompiler/ailgraph_walker.py +48 -0
  50. angr/analyses/decompiler/block_io_finder.py +293 -0
  51. angr/analyses/decompiler/block_similarity.py +188 -0
  52. angr/analyses/decompiler/block_simplifier.py +434 -0
  53. angr/analyses/decompiler/call_counter.py +43 -0
  54. angr/analyses/decompiler/callsite_maker.py +403 -0
  55. angr/analyses/decompiler/ccall_rewriters/__init__.py +6 -0
  56. angr/analyses/decompiler/ccall_rewriters/amd64_ccalls.py +489 -0
  57. angr/analyses/decompiler/ccall_rewriters/rewriter_base.py +19 -0
  58. angr/analyses/decompiler/clinic.py +2166 -0
  59. angr/analyses/decompiler/condition_processor.py +1184 -0
  60. angr/analyses/decompiler/decompilation_cache.py +38 -0
  61. angr/analyses/decompiler/decompilation_options.py +274 -0
  62. angr/analyses/decompiler/decompiler.py +544 -0
  63. angr/analyses/decompiler/empty_node_remover.py +211 -0
  64. angr/analyses/decompiler/expression_counters.py +76 -0
  65. angr/analyses/decompiler/expression_narrower.py +92 -0
  66. angr/analyses/decompiler/goto_manager.py +73 -0
  67. angr/analyses/decompiler/graph_region.py +413 -0
  68. angr/analyses/decompiler/jump_target_collector.py +36 -0
  69. angr/analyses/decompiler/jumptable_entry_condition_rewriter.py +66 -0
  70. angr/analyses/decompiler/optimization_passes/__init__.py +108 -0
  71. angr/analyses/decompiler/optimization_passes/base_ptr_save_simplifier.py +144 -0
  72. angr/analyses/decompiler/optimization_passes/code_motion.py +360 -0
  73. angr/analyses/decompiler/optimization_passes/const_derefs.py +265 -0
  74. angr/analyses/decompiler/optimization_passes/cross_jump_reverter.py +108 -0
  75. angr/analyses/decompiler/optimization_passes/deadblock_remover.py +73 -0
  76. angr/analyses/decompiler/optimization_passes/div_simplifier.py +391 -0
  77. angr/analyses/decompiler/optimization_passes/engine_base.py +303 -0
  78. angr/analyses/decompiler/optimization_passes/expr_op_swapper.py +136 -0
  79. angr/analyses/decompiler/optimization_passes/flip_boolean_cmp.py +91 -0
  80. angr/analyses/decompiler/optimization_passes/inlined_string_transformation_simplifier.py +386 -0
  81. angr/analyses/decompiler/optimization_passes/ite_expr_converter.py +226 -0
  82. angr/analyses/decompiler/optimization_passes/ite_region_converter.py +189 -0
  83. angr/analyses/decompiler/optimization_passes/lowered_switch_simplifier.py +757 -0
  84. angr/analyses/decompiler/optimization_passes/mod_simplifier.py +86 -0
  85. angr/analyses/decompiler/optimization_passes/multi_simplifier.py +227 -0
  86. angr/analyses/decompiler/optimization_passes/optimization_pass.py +397 -0
  87. angr/analyses/decompiler/optimization_passes/register_save_area_simplifier.py +198 -0
  88. angr/analyses/decompiler/optimization_passes/ret_addr_save_simplifier.py +172 -0
  89. angr/analyses/decompiler/optimization_passes/ret_deduplicator.py +219 -0
  90. angr/analyses/decompiler/optimization_passes/return_duplicator_base.py +448 -0
  91. angr/analyses/decompiler/optimization_passes/return_duplicator_high.py +57 -0
  92. angr/analyses/decompiler/optimization_passes/return_duplicator_low.py +121 -0
  93. angr/analyses/decompiler/optimization_passes/spilled_register_finder.py +18 -0
  94. angr/analyses/decompiler/optimization_passes/stack_canary_simplifier.py +293 -0
  95. angr/analyses/decompiler/optimization_passes/switch_default_case_duplicator.py +110 -0
  96. angr/analyses/decompiler/optimization_passes/win_stack_canary_simplifier.py +281 -0
  97. angr/analyses/decompiler/optimization_passes/x86_gcc_getpc_simplifier.py +87 -0
  98. angr/analyses/decompiler/peephole_optimizations/__init__.py +69 -0
  99. angr/analyses/decompiler/peephole_optimizations/a_div_const_add_a_mul_n_div_const.py +38 -0
  100. angr/analyses/decompiler/peephole_optimizations/a_mul_const_div_shr_const.py +38 -0
  101. angr/analyses/decompiler/peephole_optimizations/a_shl_const_sub_a.py +31 -0
  102. angr/analyses/decompiler/peephole_optimizations/a_sub_a_div.py +25 -0
  103. angr/analyses/decompiler/peephole_optimizations/a_sub_a_div_const_mul_const.py +56 -0
  104. angr/analyses/decompiler/peephole_optimizations/a_sub_a_sub_n.py +19 -0
  105. angr/analyses/decompiler/peephole_optimizations/arm_cmpf.py +235 -0
  106. angr/analyses/decompiler/peephole_optimizations/base.py +120 -0
  107. angr/analyses/decompiler/peephole_optimizations/basepointeroffset_add_n.py +33 -0
  108. angr/analyses/decompiler/peephole_optimizations/basepointeroffset_and_mask.py +35 -0
  109. angr/analyses/decompiler/peephole_optimizations/bitwise_or_to_logical_or.py +34 -0
  110. angr/analyses/decompiler/peephole_optimizations/bool_expr_xor_1.py +27 -0
  111. angr/analyses/decompiler/peephole_optimizations/bswap.py +131 -0
  112. angr/analyses/decompiler/peephole_optimizations/cmpord_rewriter.py +72 -0
  113. angr/analyses/decompiler/peephole_optimizations/coalesce_same_cascading_ifs.py +27 -0
  114. angr/analyses/decompiler/peephole_optimizations/const_mull_a_shift.py +91 -0
  115. angr/analyses/decompiler/peephole_optimizations/constant_derefs.py +43 -0
  116. angr/analyses/decompiler/peephole_optimizations/conv_a_sub0_shr_and.py +70 -0
  117. angr/analyses/decompiler/peephole_optimizations/conv_shl_shr.py +51 -0
  118. angr/analyses/decompiler/peephole_optimizations/eager_eval.py +225 -0
  119. angr/analyses/decompiler/peephole_optimizations/extended_byte_and_mask.py +55 -0
  120. angr/analyses/decompiler/peephole_optimizations/inlined_strcpy.py +146 -0
  121. angr/analyses/decompiler/peephole_optimizations/inlined_strcpy_consolidation.py +102 -0
  122. angr/analyses/decompiler/peephole_optimizations/inlined_wstrcpy.py +159 -0
  123. angr/analyses/decompiler/peephole_optimizations/invert_negated_logical_conjuction_disjunction.py +50 -0
  124. angr/analyses/decompiler/peephole_optimizations/one_sub_bool.py +33 -0
  125. angr/analyses/decompiler/peephole_optimizations/remove_cascading_conversions.py +19 -0
  126. angr/analyses/decompiler/peephole_optimizations/remove_empty_if_body.py +45 -0
  127. angr/analyses/decompiler/peephole_optimizations/remove_noop_conversions.py +26 -0
  128. angr/analyses/decompiler/peephole_optimizations/remove_redundant_bitmasks.py +48 -0
  129. angr/analyses/decompiler/peephole_optimizations/remove_redundant_conversions.py +160 -0
  130. angr/analyses/decompiler/peephole_optimizations/remove_redundant_ite_branch.py +29 -0
  131. angr/analyses/decompiler/peephole_optimizations/remove_redundant_ite_comparisons.py +54 -0
  132. angr/analyses/decompiler/peephole_optimizations/remove_redundant_nots.py +17 -0
  133. angr/analyses/decompiler/peephole_optimizations/remove_redundant_reinterprets.py +43 -0
  134. angr/analyses/decompiler/peephole_optimizations/remove_redundant_shifts.py +44 -0
  135. angr/analyses/decompiler/peephole_optimizations/remove_redundant_shifts_around_comparators.py +40 -0
  136. angr/analyses/decompiler/peephole_optimizations/rewrite_bit_extractions.py +85 -0
  137. angr/analyses/decompiler/peephole_optimizations/rewrite_mips_gp_loads.py +47 -0
  138. angr/analyses/decompiler/peephole_optimizations/rol_ror.py +77 -0
  139. angr/analyses/decompiler/peephole_optimizations/sar_to_signed_div.py +105 -0
  140. angr/analyses/decompiler/peephole_optimizations/simplify_pc_relative_loads.py +37 -0
  141. angr/analyses/decompiler/peephole_optimizations/single_bit_cond_to_boolexpr.py +52 -0
  142. angr/analyses/decompiler/peephole_optimizations/single_bit_xor.py +26 -0
  143. angr/analyses/decompiler/peephole_optimizations/tidy_stack_addr.py +133 -0
  144. angr/analyses/decompiler/redundant_label_remover.py +116 -0
  145. angr/analyses/decompiler/region_identifier.py +1098 -0
  146. angr/analyses/decompiler/region_simplifiers/__init__.py +1 -0
  147. angr/analyses/decompiler/region_simplifiers/cascading_cond_transformer.py +93 -0
  148. angr/analyses/decompiler/region_simplifiers/cascading_ifs.py +81 -0
  149. angr/analyses/decompiler/region_simplifiers/expr_folding.py +606 -0
  150. angr/analyses/decompiler/region_simplifiers/goto.py +177 -0
  151. angr/analyses/decompiler/region_simplifiers/if_.py +142 -0
  152. angr/analyses/decompiler/region_simplifiers/ifelse.py +90 -0
  153. angr/analyses/decompiler/region_simplifiers/loop.py +135 -0
  154. angr/analyses/decompiler/region_simplifiers/node_address_finder.py +23 -0
  155. angr/analyses/decompiler/region_simplifiers/region_simplifier.py +211 -0
  156. angr/analyses/decompiler/region_simplifiers/switch_cluster_simplifier.py +644 -0
  157. angr/analyses/decompiler/region_simplifiers/switch_expr_simplifier.py +83 -0
  158. angr/analyses/decompiler/region_walker.py +23 -0
  159. angr/analyses/decompiler/return_maker.py +70 -0
  160. angr/analyses/decompiler/seq_to_blocks.py +19 -0
  161. angr/analyses/decompiler/sequence_walker.py +235 -0
  162. angr/analyses/decompiler/structured_codegen/__init__.py +10 -0
  163. angr/analyses/decompiler/structured_codegen/base.py +132 -0
  164. angr/analyses/decompiler/structured_codegen/c.py +3811 -0
  165. angr/analyses/decompiler/structured_codegen/dummy.py +14 -0
  166. angr/analyses/decompiler/structured_codegen/dwarf_import.py +186 -0
  167. angr/analyses/decompiler/structuring/__init__.py +15 -0
  168. angr/analyses/decompiler/structuring/dream.py +1225 -0
  169. angr/analyses/decompiler/structuring/phoenix.py +2546 -0
  170. angr/analyses/decompiler/structuring/recursive_structurer.py +186 -0
  171. angr/analyses/decompiler/structuring/structurer_base.py +954 -0
  172. angr/analyses/decompiler/structuring/structurer_nodes.py +414 -0
  173. angr/analyses/decompiler/utils.py +787 -0
  174. angr/analyses/disassembly.py +1302 -0
  175. angr/analyses/disassembly_utils.py +104 -0
  176. angr/analyses/dominance_frontier.py +39 -0
  177. angr/analyses/find_objects_static.py +203 -0
  178. angr/analyses/flirt.py +185 -0
  179. angr/analyses/forward_analysis/__init__.py +2 -0
  180. angr/analyses/forward_analysis/forward_analysis.py +527 -0
  181. angr/analyses/forward_analysis/job_info.py +64 -0
  182. angr/analyses/forward_analysis/visitors/__init__.py +4 -0
  183. angr/analyses/forward_analysis/visitors/call_graph.py +28 -0
  184. angr/analyses/forward_analysis/visitors/function_graph.py +85 -0
  185. angr/analyses/forward_analysis/visitors/graph.py +250 -0
  186. angr/analyses/forward_analysis/visitors/loop.py +28 -0
  187. angr/analyses/forward_analysis/visitors/single_node_graph.py +38 -0
  188. angr/analyses/identifier/__init__.py +1 -0
  189. angr/analyses/identifier/custom_callable.py +138 -0
  190. angr/analyses/identifier/errors.py +9 -0
  191. angr/analyses/identifier/func.py +57 -0
  192. angr/analyses/identifier/functions/__init__.py +36 -0
  193. angr/analyses/identifier/functions/atoi.py +75 -0
  194. angr/analyses/identifier/functions/based_atoi.py +128 -0
  195. angr/analyses/identifier/functions/fdprintf.py +122 -0
  196. angr/analyses/identifier/functions/free.py +64 -0
  197. angr/analyses/identifier/functions/int2str.py +302 -0
  198. angr/analyses/identifier/functions/malloc.py +113 -0
  199. angr/analyses/identifier/functions/memcmp.py +69 -0
  200. angr/analyses/identifier/functions/memcpy.py +89 -0
  201. angr/analyses/identifier/functions/memset.py +43 -0
  202. angr/analyses/identifier/functions/printf.py +122 -0
  203. angr/analyses/identifier/functions/recv_until.py +315 -0
  204. angr/analyses/identifier/functions/skip_calloc.py +72 -0
  205. angr/analyses/identifier/functions/skip_realloc.py +99 -0
  206. angr/analyses/identifier/functions/skip_recv_n.py +107 -0
  207. angr/analyses/identifier/functions/snprintf.py +114 -0
  208. angr/analyses/identifier/functions/sprintf.py +115 -0
  209. angr/analyses/identifier/functions/strcasecmp.py +32 -0
  210. angr/analyses/identifier/functions/strcmp.py +112 -0
  211. angr/analyses/identifier/functions/strcpy.py +43 -0
  212. angr/analyses/identifier/functions/strlen.py +26 -0
  213. angr/analyses/identifier/functions/strncmp.py +103 -0
  214. angr/analyses/identifier/functions/strncpy.py +65 -0
  215. angr/analyses/identifier/functions/strtol.py +91 -0
  216. angr/analyses/identifier/identify.py +848 -0
  217. angr/analyses/identifier/runner.py +359 -0
  218. angr/analyses/init_finder.py +264 -0
  219. angr/analyses/loop_analysis.py +353 -0
  220. angr/analyses/loopfinder.py +174 -0
  221. angr/analyses/propagator/__init__.py +1 -0
  222. angr/analyses/propagator/engine_ail.py +1560 -0
  223. angr/analyses/propagator/engine_base.py +53 -0
  224. angr/analyses/propagator/engine_vex.py +328 -0
  225. angr/analyses/propagator/outdated_definition_walker.py +158 -0
  226. angr/analyses/propagator/propagator.py +422 -0
  227. angr/analyses/propagator/tmpvar_finder.py +17 -0
  228. angr/analyses/propagator/top_checker_mixin.py +14 -0
  229. angr/analyses/propagator/values.py +116 -0
  230. angr/analyses/propagator/vex_vars.py +67 -0
  231. angr/analyses/proximity_graph.py +452 -0
  232. angr/analyses/reaching_definitions/__init__.py +65 -0
  233. angr/analyses/reaching_definitions/call_trace.py +72 -0
  234. angr/analyses/reaching_definitions/dep_graph.py +392 -0
  235. angr/analyses/reaching_definitions/engine_ail.py +1172 -0
  236. angr/analyses/reaching_definitions/engine_vex.py +1102 -0
  237. angr/analyses/reaching_definitions/external_codeloc.py +0 -0
  238. angr/analyses/reaching_definitions/function_handler.py +603 -0
  239. angr/analyses/reaching_definitions/heap_allocator.py +69 -0
  240. angr/analyses/reaching_definitions/rd_initializer.py +235 -0
  241. angr/analyses/reaching_definitions/rd_state.py +613 -0
  242. angr/analyses/reaching_definitions/reaching_definitions.py +594 -0
  243. angr/analyses/reaching_definitions/subject.py +64 -0
  244. angr/analyses/reassembler.py +2970 -0
  245. angr/analyses/soot_class_hierarchy.py +283 -0
  246. angr/analyses/stack_pointer_tracker.py +832 -0
  247. angr/analyses/static_hooker.py +51 -0
  248. angr/analyses/typehoon/__init__.py +1 -0
  249. angr/analyses/typehoon/dfa.py +108 -0
  250. angr/analyses/typehoon/lifter.py +91 -0
  251. angr/analyses/typehoon/simple_solver.py +1258 -0
  252. angr/analyses/typehoon/translator.py +242 -0
  253. angr/analyses/typehoon/typeconsts.py +294 -0
  254. angr/analyses/typehoon/typehoon.py +239 -0
  255. angr/analyses/typehoon/typevars.py +565 -0
  256. angr/analyses/typehoon/variance.py +10 -0
  257. angr/analyses/variable_recovery/__init__.py +2 -0
  258. angr/analyses/variable_recovery/annotations.py +57 -0
  259. angr/analyses/variable_recovery/engine_ail.py +746 -0
  260. angr/analyses/variable_recovery/engine_base.py +962 -0
  261. angr/analyses/variable_recovery/engine_vex.py +580 -0
  262. angr/analyses/variable_recovery/irsb_scanner.py +131 -0
  263. angr/analyses/variable_recovery/variable_recovery.py +552 -0
  264. angr/analyses/variable_recovery/variable_recovery_base.py +452 -0
  265. angr/analyses/variable_recovery/variable_recovery_fast.py +589 -0
  266. angr/analyses/veritesting.py +635 -0
  267. angr/analyses/vfg.py +1945 -0
  268. angr/analyses/vsa_ddg.py +423 -0
  269. angr/analyses/vtable.py +92 -0
  270. angr/analyses/xrefs.py +263 -0
  271. angr/angrdb/__init__.py +9 -0
  272. angr/angrdb/db.py +208 -0
  273. angr/angrdb/models.py +183 -0
  274. angr/angrdb/serializers/__init__.py +2 -0
  275. angr/angrdb/serializers/cfg_model.py +41 -0
  276. angr/angrdb/serializers/comments.py +59 -0
  277. angr/angrdb/serializers/funcs.py +60 -0
  278. angr/angrdb/serializers/kb.py +110 -0
  279. angr/angrdb/serializers/labels.py +58 -0
  280. angr/angrdb/serializers/loader.py +81 -0
  281. angr/angrdb/serializers/structured_code.py +128 -0
  282. angr/angrdb/serializers/variables.py +58 -0
  283. angr/angrdb/serializers/xrefs.py +48 -0
  284. angr/annocfg.py +320 -0
  285. angr/blade.py +430 -0
  286. angr/block.py +506 -0
  287. angr/callable.py +162 -0
  288. angr/calling_conventions.py +2383 -0
  289. angr/code_location.py +168 -0
  290. angr/codenode.py +140 -0
  291. angr/concretization_strategies/__init__.py +97 -0
  292. angr/concretization_strategies/any.py +15 -0
  293. angr/concretization_strategies/any_named.py +32 -0
  294. angr/concretization_strategies/controlled_data.py +54 -0
  295. angr/concretization_strategies/eval.py +18 -0
  296. angr/concretization_strategies/logging.py +32 -0
  297. angr/concretization_strategies/max.py +24 -0
  298. angr/concretization_strategies/nonzero.py +14 -0
  299. angr/concretization_strategies/nonzero_range.py +20 -0
  300. angr/concretization_strategies/norepeats.py +35 -0
  301. angr/concretization_strategies/norepeats_range.py +35 -0
  302. angr/concretization_strategies/range.py +17 -0
  303. angr/concretization_strategies/signed_add.py +24 -0
  304. angr/concretization_strategies/single.py +12 -0
  305. angr/concretization_strategies/solutions.py +18 -0
  306. angr/concretization_strategies/unlimited_range.py +15 -0
  307. angr/distributed/__init__.py +3 -0
  308. angr/distributed/server.py +198 -0
  309. angr/distributed/worker.py +183 -0
  310. angr/engines/__init__.py +41 -0
  311. angr/engines/concrete.py +178 -0
  312. angr/engines/engine.py +212 -0
  313. angr/engines/failure.py +27 -0
  314. angr/engines/hook.py +67 -0
  315. angr/engines/light/__init__.py +2 -0
  316. angr/engines/light/data.py +715 -0
  317. angr/engines/light/engine.py +1441 -0
  318. angr/engines/pcode/__init__.py +2 -0
  319. angr/engines/pcode/behavior.py +995 -0
  320. angr/engines/pcode/cc.py +123 -0
  321. angr/engines/pcode/emulate.py +446 -0
  322. angr/engines/pcode/engine.py +256 -0
  323. angr/engines/pcode/lifter.py +1423 -0
  324. angr/engines/procedure.py +71 -0
  325. angr/engines/soot/__init__.py +1 -0
  326. angr/engines/soot/engine.py +415 -0
  327. angr/engines/soot/exceptions.py +14 -0
  328. angr/engines/soot/expressions/__init__.py +56 -0
  329. angr/engines/soot/expressions/arrayref.py +21 -0
  330. angr/engines/soot/expressions/base.py +22 -0
  331. angr/engines/soot/expressions/binop.py +27 -0
  332. angr/engines/soot/expressions/cast.py +21 -0
  333. angr/engines/soot/expressions/condition.py +34 -0
  334. angr/engines/soot/expressions/constants.py +45 -0
  335. angr/engines/soot/expressions/instanceOf.py +11 -0
  336. angr/engines/soot/expressions/instancefieldref.py +7 -0
  337. angr/engines/soot/expressions/invoke.py +117 -0
  338. angr/engines/soot/expressions/length.py +7 -0
  339. angr/engines/soot/expressions/local.py +7 -0
  340. angr/engines/soot/expressions/new.py +15 -0
  341. angr/engines/soot/expressions/newArray.py +51 -0
  342. angr/engines/soot/expressions/newMultiArray.py +84 -0
  343. angr/engines/soot/expressions/paramref.py +7 -0
  344. angr/engines/soot/expressions/phi.py +29 -0
  345. angr/engines/soot/expressions/staticfieldref.py +7 -0
  346. angr/engines/soot/expressions/thisref.py +6 -0
  347. angr/engines/soot/expressions/unsupported.py +6 -0
  348. angr/engines/soot/field_dispatcher.py +49 -0
  349. angr/engines/soot/method_dispatcher.py +49 -0
  350. angr/engines/soot/statements/__init__.py +30 -0
  351. angr/engines/soot/statements/assign.py +29 -0
  352. angr/engines/soot/statements/base.py +80 -0
  353. angr/engines/soot/statements/goto.py +11 -0
  354. angr/engines/soot/statements/identity.py +14 -0
  355. angr/engines/soot/statements/if_.py +16 -0
  356. angr/engines/soot/statements/invoke.py +11 -0
  357. angr/engines/soot/statements/return_.py +19 -0
  358. angr/engines/soot/statements/switch.py +38 -0
  359. angr/engines/soot/statements/throw.py +12 -0
  360. angr/engines/soot/values/__init__.py +24 -0
  361. angr/engines/soot/values/arrayref.py +124 -0
  362. angr/engines/soot/values/base.py +4 -0
  363. angr/engines/soot/values/constants.py +17 -0
  364. angr/engines/soot/values/instancefieldref.py +42 -0
  365. angr/engines/soot/values/local.py +17 -0
  366. angr/engines/soot/values/paramref.py +17 -0
  367. angr/engines/soot/values/staticfieldref.py +37 -0
  368. angr/engines/soot/values/strref.py +37 -0
  369. angr/engines/soot/values/thisref.py +148 -0
  370. angr/engines/successors.py +540 -0
  371. angr/engines/syscall.py +53 -0
  372. angr/engines/unicorn.py +483 -0
  373. angr/engines/vex/__init__.py +4 -0
  374. angr/engines/vex/claripy/__init__.py +1 -0
  375. angr/engines/vex/claripy/ccall.py +2097 -0
  376. angr/engines/vex/claripy/datalayer.py +149 -0
  377. angr/engines/vex/claripy/irop.py +1279 -0
  378. angr/engines/vex/heavy/__init__.py +5 -0
  379. angr/engines/vex/heavy/actions.py +237 -0
  380. angr/engines/vex/heavy/concretizers.py +394 -0
  381. angr/engines/vex/heavy/dirty.py +467 -0
  382. angr/engines/vex/heavy/heavy.py +379 -0
  383. angr/engines/vex/heavy/inspect.py +51 -0
  384. angr/engines/vex/heavy/resilience.py +85 -0
  385. angr/engines/vex/heavy/super_fastpath.py +34 -0
  386. angr/engines/vex/lifter.py +424 -0
  387. angr/engines/vex/light/__init__.py +3 -0
  388. angr/engines/vex/light/light.py +555 -0
  389. angr/engines/vex/light/resilience.py +73 -0
  390. angr/engines/vex/light/slicing.py +51 -0
  391. angr/errors.py +604 -0
  392. angr/exploration_techniques/__init__.py +176 -0
  393. angr/exploration_techniques/bucketizer.py +96 -0
  394. angr/exploration_techniques/common.py +56 -0
  395. angr/exploration_techniques/dfs.py +34 -0
  396. angr/exploration_techniques/director.py +523 -0
  397. angr/exploration_techniques/driller_core.py +102 -0
  398. angr/exploration_techniques/explorer.py +146 -0
  399. angr/exploration_techniques/lengthlimiter.py +20 -0
  400. angr/exploration_techniques/local_loop_seer.py +64 -0
  401. angr/exploration_techniques/loop_seer.py +239 -0
  402. angr/exploration_techniques/manual_mergepoint.py +80 -0
  403. angr/exploration_techniques/memory_watcher.py +40 -0
  404. angr/exploration_techniques/oppologist.py +93 -0
  405. angr/exploration_techniques/slicecutor.py +115 -0
  406. angr/exploration_techniques/spiller.py +282 -0
  407. angr/exploration_techniques/spiller_db.py +27 -0
  408. angr/exploration_techniques/stochastic.py +57 -0
  409. angr/exploration_techniques/suggestions.py +156 -0
  410. angr/exploration_techniques/symbion.py +78 -0
  411. angr/exploration_techniques/tech_builder.py +47 -0
  412. angr/exploration_techniques/threading.py +77 -0
  413. angr/exploration_techniques/timeout.py +31 -0
  414. angr/exploration_techniques/tracer.py +1101 -0
  415. angr/exploration_techniques/unique.py +104 -0
  416. angr/exploration_techniques/veritesting.py +36 -0
  417. angr/factory.py +385 -0
  418. angr/flirt/__init__.py +126 -0
  419. angr/flirt/build_sig.py +316 -0
  420. angr/graph_utils.py +0 -0
  421. angr/keyed_region.py +532 -0
  422. angr/knowledge_base/__init__.py +1 -0
  423. angr/knowledge_base/knowledge_base.py +145 -0
  424. angr/knowledge_plugins/__init__.py +18 -0
  425. angr/knowledge_plugins/callsite_prototypes.py +52 -0
  426. angr/knowledge_plugins/cfg/__init__.py +16 -0
  427. angr/knowledge_plugins/cfg/cfg_manager.py +94 -0
  428. angr/knowledge_plugins/cfg/cfg_model.py +1057 -0
  429. angr/knowledge_plugins/cfg/cfg_node.py +541 -0
  430. angr/knowledge_plugins/cfg/indirect_jump.py +67 -0
  431. angr/knowledge_plugins/cfg/memory_data.py +156 -0
  432. angr/knowledge_plugins/comments.py +15 -0
  433. angr/knowledge_plugins/custom_strings.py +37 -0
  434. angr/knowledge_plugins/data.py +21 -0
  435. angr/knowledge_plugins/debug_variables.py +221 -0
  436. angr/knowledge_plugins/functions/__init__.py +2 -0
  437. angr/knowledge_plugins/functions/function.py +1694 -0
  438. angr/knowledge_plugins/functions/function_manager.py +501 -0
  439. angr/knowledge_plugins/functions/function_parser.py +295 -0
  440. angr/knowledge_plugins/functions/soot_function.py +131 -0
  441. angr/knowledge_plugins/indirect_jumps.py +34 -0
  442. angr/knowledge_plugins/key_definitions/__init__.py +16 -0
  443. angr/knowledge_plugins/key_definitions/atoms.py +314 -0
  444. angr/knowledge_plugins/key_definitions/constants.py +23 -0
  445. angr/knowledge_plugins/key_definitions/definition.py +217 -0
  446. angr/knowledge_plugins/key_definitions/environment.py +92 -0
  447. angr/knowledge_plugins/key_definitions/heap_address.py +32 -0
  448. angr/knowledge_plugins/key_definitions/key_definition_manager.py +81 -0
  449. angr/knowledge_plugins/key_definitions/live_definitions.py +1074 -0
  450. angr/knowledge_plugins/key_definitions/liveness.py +170 -0
  451. angr/knowledge_plugins/key_definitions/rd_model.py +176 -0
  452. angr/knowledge_plugins/key_definitions/tag.py +77 -0
  453. angr/knowledge_plugins/key_definitions/undefined.py +67 -0
  454. angr/knowledge_plugins/key_definitions/unknown_size.py +83 -0
  455. angr/knowledge_plugins/key_definitions/uses.py +180 -0
  456. angr/knowledge_plugins/labels.py +109 -0
  457. angr/knowledge_plugins/patches.py +125 -0
  458. angr/knowledge_plugins/plugin.py +23 -0
  459. angr/knowledge_plugins/propagations/__init__.py +2 -0
  460. angr/knowledge_plugins/propagations/prop_value.py +193 -0
  461. angr/knowledge_plugins/propagations/propagation_manager.py +60 -0
  462. angr/knowledge_plugins/propagations/propagation_model.py +74 -0
  463. angr/knowledge_plugins/propagations/states.py +1064 -0
  464. angr/knowledge_plugins/structured_code/__init__.py +1 -0
  465. angr/knowledge_plugins/structured_code/manager.py +59 -0
  466. angr/knowledge_plugins/sync/__init__.py +1 -0
  467. angr/knowledge_plugins/sync/sync_controller.py +329 -0
  468. angr/knowledge_plugins/types.py +87 -0
  469. angr/knowledge_plugins/variables/__init__.py +1 -0
  470. angr/knowledge_plugins/variables/variable_access.py +114 -0
  471. angr/knowledge_plugins/variables/variable_manager.py +1191 -0
  472. angr/knowledge_plugins/xrefs/__init__.py +3 -0
  473. angr/knowledge_plugins/xrefs/xref.py +157 -0
  474. angr/knowledge_plugins/xrefs/xref_manager.py +122 -0
  475. angr/knowledge_plugins/xrefs/xref_types.py +13 -0
  476. angr/lib/angr_native.dylib +0 -0
  477. angr/misc/__init__.py +8 -0
  478. angr/misc/ansi.py +46 -0
  479. angr/misc/autoimport.py +89 -0
  480. angr/misc/bug_report.py +125 -0
  481. angr/misc/hookset.py +106 -0
  482. angr/misc/import_hooks.py +63 -0
  483. angr/misc/loggers.py +130 -0
  484. angr/misc/picklable_lock.py +45 -0
  485. angr/misc/plugins.py +291 -0
  486. angr/misc/range.py +21 -0
  487. angr/misc/testing.py +23 -0
  488. angr/misc/ux.py +31 -0
  489. angr/misc/weakpatch.py +58 -0
  490. angr/procedures/__init__.py +2 -0
  491. angr/procedures/advapi32/__init__.py +0 -0
  492. angr/procedures/cgc/__init__.py +3 -0
  493. angr/procedures/cgc/_terminate.py +10 -0
  494. angr/procedures/cgc/allocate.py +76 -0
  495. angr/procedures/cgc/deallocate.py +59 -0
  496. angr/procedures/cgc/fdwait.py +62 -0
  497. angr/procedures/cgc/random.py +60 -0
  498. angr/procedures/cgc/receive.py +91 -0
  499. angr/procedures/cgc/transmit.py +63 -0
  500. angr/procedures/definitions/__init__.py +784 -0
  501. angr/procedures/definitions/cgc.py +19 -0
  502. angr/procedures/definitions/glibc.py +8384 -0
  503. angr/procedures/definitions/gnulib.py +35 -0
  504. angr/procedures/definitions/libstdcpp.py +20 -0
  505. angr/procedures/definitions/linux_kernel.py +6167 -0
  506. angr/procedures/definitions/linux_loader.py +6 -0
  507. angr/procedures/definitions/msvcr.py +15 -0
  508. angr/procedures/definitions/parse_syscalls_from_local_system.py +49 -0
  509. angr/procedures/definitions/parse_win32json.py +2556 -0
  510. angr/procedures/definitions/types_win32.py +34481 -0
  511. angr/procedures/definitions/wdk_api-ms-win-dx-d3dkmt-l1-1-4.py +44 -0
  512. angr/procedures/definitions/wdk_api-ms-win-dx-d3dkmt-l1-1-6.py +40 -0
  513. angr/procedures/definitions/wdk_clfs.py +154 -0
  514. angr/procedures/definitions/wdk_fltmgr.py +570 -0
  515. angr/procedures/definitions/wdk_fwpkclnt.py +44 -0
  516. angr/procedures/definitions/wdk_fwpuclnt.py +330 -0
  517. angr/procedures/definitions/wdk_gdi32.py +380 -0
  518. angr/procedures/definitions/wdk_hal.py +92 -0
  519. angr/procedures/definitions/wdk_ksecdd.py +76 -0
  520. angr/procedures/definitions/wdk_ndis.py +252 -0
  521. angr/procedures/definitions/wdk_ntoskrnl.py +3463 -0
  522. angr/procedures/definitions/wdk_offreg.py +86 -0
  523. angr/procedures/definitions/wdk_pshed.py +50 -0
  524. angr/procedures/definitions/wdk_secur32.py +54 -0
  525. angr/procedures/definitions/wdk_vhfum.py +48 -0
  526. angr/procedures/definitions/win32_aclui.py +44 -0
  527. angr/procedures/definitions/win32_activeds.py +82 -0
  528. angr/procedures/definitions/win32_advapi32.py +1698 -0
  529. angr/procedures/definitions/win32_advpack.py +138 -0
  530. angr/procedures/definitions/win32_amsi.py +52 -0
  531. angr/procedures/definitions/win32_api-ms-win-appmodel-runtime-l1-1-1.py +58 -0
  532. angr/procedures/definitions/win32_api-ms-win-appmodel-runtime-l1-1-3.py +48 -0
  533. angr/procedures/definitions/win32_api-ms-win-appmodel-runtime-l1-1-6.py +40 -0
  534. angr/procedures/definitions/win32_api-ms-win-core-apiquery-l2-1-0.py +40 -0
  535. angr/procedures/definitions/win32_api-ms-win-core-backgroundtask-l1-1-0.py +40 -0
  536. angr/procedures/definitions/win32_api-ms-win-core-comm-l1-1-1.py +40 -0
  537. angr/procedures/definitions/win32_api-ms-win-core-comm-l1-1-2.py +40 -0
  538. angr/procedures/definitions/win32_api-ms-win-core-enclave-l1-1-1.py +44 -0
  539. angr/procedures/definitions/win32_api-ms-win-core-errorhandling-l1-1-3.py +40 -0
  540. angr/procedures/definitions/win32_api-ms-win-core-featurestaging-l1-1-0.py +48 -0
  541. angr/procedures/definitions/win32_api-ms-win-core-featurestaging-l1-1-1.py +40 -0
  542. angr/procedures/definitions/win32_api-ms-win-core-file-fromapp-l1-1-0.py +60 -0
  543. angr/procedures/definitions/win32_api-ms-win-core-handle-l1-1-0.py +40 -0
  544. angr/procedures/definitions/win32_api-ms-win-core-ioring-l1-1-0.py +62 -0
  545. angr/procedures/definitions/win32_api-ms-win-core-marshal-l1-1-0.py +46 -0
  546. angr/procedures/definitions/win32_api-ms-win-core-memory-l1-1-3.py +46 -0
  547. angr/procedures/definitions/win32_api-ms-win-core-memory-l1-1-4.py +40 -0
  548. angr/procedures/definitions/win32_api-ms-win-core-memory-l1-1-5.py +44 -0
  549. angr/procedures/definitions/win32_api-ms-win-core-memory-l1-1-6.py +46 -0
  550. angr/procedures/definitions/win32_api-ms-win-core-memory-l1-1-7.py +42 -0
  551. angr/procedures/definitions/win32_api-ms-win-core-memory-l1-1-8.py +44 -0
  552. angr/procedures/definitions/win32_api-ms-win-core-path-l1-1-0.py +82 -0
  553. angr/procedures/definitions/win32_api-ms-win-core-psm-appnotify-l1-1-0.py +42 -0
  554. angr/procedures/definitions/win32_api-ms-win-core-psm-appnotify-l1-1-1.py +42 -0
  555. angr/procedures/definitions/win32_api-ms-win-core-realtime-l1-1-1.py +44 -0
  556. angr/procedures/definitions/win32_api-ms-win-core-realtime-l1-1-2.py +44 -0
  557. angr/procedures/definitions/win32_api-ms-win-core-slapi-l1-1-0.py +40 -0
  558. angr/procedures/definitions/win32_api-ms-win-core-state-helpers-l1-1-0.py +40 -0
  559. angr/procedures/definitions/win32_api-ms-win-core-synch-l1-2-0.py +44 -0
  560. angr/procedures/definitions/win32_api-ms-win-core-sysinfo-l1-2-0.py +40 -0
  561. angr/procedures/definitions/win32_api-ms-win-core-sysinfo-l1-2-3.py +42 -0
  562. angr/procedures/definitions/win32_api-ms-win-core-sysinfo-l1-2-4.py +42 -0
  563. angr/procedures/definitions/win32_api-ms-win-core-sysinfo-l1-2-6.py +40 -0
  564. angr/procedures/definitions/win32_api-ms-win-core-util-l1-1-1.py +42 -0
  565. angr/procedures/definitions/win32_api-ms-win-core-winrt-error-l1-1-0.py +43 -0
  566. angr/procedures/definitions/win32_api-ms-win-core-winrt-error-l1-1-1.py +37 -0
  567. angr/procedures/definitions/win32_api-ms-win-core-winrt-l1-1-0.py +39 -0
  568. angr/procedures/definitions/win32_api-ms-win-core-winrt-registration-l1-1-0.py +23 -0
  569. angr/procedures/definitions/win32_api-ms-win-core-winrt-robuffer-l1-1-0.py +23 -0
  570. angr/procedures/definitions/win32_api-ms-win-core-winrt-roparameterizediid-l1-1-0.py +27 -0
  571. angr/procedures/definitions/win32_api-ms-win-core-winrt-string-l1-1-0.py +75 -0
  572. angr/procedures/definitions/win32_api-ms-win-core-winrt-string-l1-1-1.py +23 -0
  573. angr/procedures/definitions/win32_api-ms-win-core-wow64-l1-1-1.py +44 -0
  574. angr/procedures/definitions/win32_api-ms-win-devices-query-l1-1-0.py +56 -0
  575. angr/procedures/definitions/win32_api-ms-win-devices-query-l1-1-1.py +48 -0
  576. angr/procedures/definitions/win32_api-ms-win-dx-d3dkmt-l1-1-0.py +40 -0
  577. angr/procedures/definitions/win32_api-ms-win-gaming-deviceinformation-l1-1-0.py +40 -0
  578. angr/procedures/definitions/win32_api-ms-win-gaming-expandedresources-l1-1-0.py +44 -0
  579. angr/procedures/definitions/win32_api-ms-win-gaming-tcui-l1-1-0.py +52 -0
  580. angr/procedures/definitions/win32_api-ms-win-gaming-tcui-l1-1-1.py +42 -0
  581. angr/procedures/definitions/win32_api-ms-win-gaming-tcui-l1-1-2.py +52 -0
  582. angr/procedures/definitions/win32_api-ms-win-gaming-tcui-l1-1-3.py +42 -0
  583. angr/procedures/definitions/win32_api-ms-win-gaming-tcui-l1-1-4.py +54 -0
  584. angr/procedures/definitions/win32_api-ms-win-mm-misc-l1-1-1.py +40 -0
  585. angr/procedures/definitions/win32_api-ms-win-net-isolation-l1-1-0.py +54 -0
  586. angr/procedures/definitions/win32_api-ms-win-security-base-l1-2-2.py +40 -0
  587. angr/procedures/definitions/win32_api-ms-win-security-isolatedcontainer-l1-1-0.py +40 -0
  588. angr/procedures/definitions/win32_api-ms-win-security-isolatedcontainer-l1-1-1.py +40 -0
  589. angr/procedures/definitions/win32_api-ms-win-service-core-l1-1-3.py +40 -0
  590. angr/procedures/definitions/win32_api-ms-win-service-core-l1-1-4.py +40 -0
  591. angr/procedures/definitions/win32_api-ms-win-service-core-l1-1-5.py +42 -0
  592. angr/procedures/definitions/win32_api-ms-win-shcore-scaling-l1-1-0.py +44 -0
  593. angr/procedures/definitions/win32_api-ms-win-shcore-scaling-l1-1-1.py +50 -0
  594. angr/procedures/definitions/win32_api-ms-win-shcore-scaling-l1-1-2.py +40 -0
  595. angr/procedures/definitions/win32_api-ms-win-shcore-stream-winrt-l1-1-0.py +27 -0
  596. angr/procedures/definitions/win32_api-ms-win-wsl-api-l1-1-0.py +52 -0
  597. angr/procedures/definitions/win32_apphelp.py +40 -0
  598. angr/procedures/definitions/win32_authz.py +104 -0
  599. angr/procedures/definitions/win32_avicap32.py +46 -0
  600. angr/procedures/definitions/win32_avifil32.py +158 -0
  601. angr/procedures/definitions/win32_avrt.py +66 -0
  602. angr/procedures/definitions/win32_bcp47mrm.py +42 -0
  603. angr/procedures/definitions/win32_bcrypt.py +144 -0
  604. angr/procedures/definitions/win32_bcryptprimitives.py +42 -0
  605. angr/procedures/definitions/win32_bluetoothapis.py +120 -0
  606. angr/procedures/definitions/win32_bthprops.py +33 -0
  607. angr/procedures/definitions/win32_bthprops_cpl.py +50 -0
  608. angr/procedures/definitions/win32_cabinet.py +82 -0
  609. angr/procedures/definitions/win32_certadm.py +74 -0
  610. angr/procedures/definitions/win32_certpoleng.py +54 -0
  611. angr/procedures/definitions/win32_cfgmgr32.py +516 -0
  612. angr/procedures/definitions/win32_chakra.py +212 -0
  613. angr/procedures/definitions/win32_cldapi.py +110 -0
  614. angr/procedures/definitions/win32_clfsw32.py +156 -0
  615. angr/procedures/definitions/win32_clusapi.py +598 -0
  616. angr/procedures/definitions/win32_comctl32.py +268 -0
  617. angr/procedures/definitions/win32_comdlg32.py +80 -0
  618. angr/procedures/definitions/win32_compstui.py +46 -0
  619. angr/procedures/definitions/win32_computecore.py +146 -0
  620. angr/procedures/definitions/win32_computenetwork.py +124 -0
  621. angr/procedures/definitions/win32_computestorage.py +62 -0
  622. angr/procedures/definitions/win32_comsvcs.py +52 -0
  623. angr/procedures/definitions/win32_coremessaging.py +23 -0
  624. angr/procedures/definitions/win32_credui.py +76 -0
  625. angr/procedures/definitions/win32_crypt32.py +496 -0
  626. angr/procedures/definitions/win32_cryptnet.py +48 -0
  627. angr/procedures/definitions/win32_cryptui.py +58 -0
  628. angr/procedures/definitions/win32_cryptxml.py +76 -0
  629. angr/procedures/definitions/win32_cscapi.py +46 -0
  630. angr/procedures/definitions/win32_d2d1.py +64 -0
  631. angr/procedures/definitions/win32_d3d10.py +92 -0
  632. angr/procedures/definitions/win32_d3d10_1.py +42 -0
  633. angr/procedures/definitions/win32_d3d11.py +44 -0
  634. angr/procedures/definitions/win32_d3d12.py +54 -0
  635. angr/procedures/definitions/win32_d3d9.py +60 -0
  636. angr/procedures/definitions/win32_d3dcompiler_47.py +90 -0
  637. angr/procedures/definitions/win32_d3dcsx.py +56 -0
  638. angr/procedures/definitions/win32_davclnt.py +74 -0
  639. angr/procedures/definitions/win32_dbgeng.py +46 -0
  640. angr/procedures/definitions/win32_dbghelp.py +476 -0
  641. angr/procedures/definitions/win32_dbgmodel.py +40 -0
  642. angr/procedures/definitions/win32_dciman32.py +78 -0
  643. angr/procedures/definitions/win32_dcomp.py +62 -0
  644. angr/procedures/definitions/win32_ddraw.py +52 -0
  645. angr/procedures/definitions/win32_deviceaccess.py +40 -0
  646. angr/procedures/definitions/win32_dflayout.py +40 -0
  647. angr/procedures/definitions/win32_dhcpcsvc.py +68 -0
  648. angr/procedures/definitions/win32_dhcpcsvc6.py +50 -0
  649. angr/procedures/definitions/win32_dhcpsapi.py +430 -0
  650. angr/procedures/definitions/win32_diagnosticdataquery.py +108 -0
  651. angr/procedures/definitions/win32_dinput8.py +40 -0
  652. angr/procedures/definitions/win32_directml.py +42 -0
  653. angr/procedures/definitions/win32_dmprocessxmlfiltered.py +40 -0
  654. angr/procedures/definitions/win32_dnsapi.py +166 -0
  655. angr/procedures/definitions/win32_drt.py +70 -0
  656. angr/procedures/definitions/win32_drtprov.py +56 -0
  657. angr/procedures/definitions/win32_drttransport.py +42 -0
  658. angr/procedures/definitions/win32_dsound.py +58 -0
  659. angr/procedures/definitions/win32_dsparse.py +76 -0
  660. angr/procedures/definitions/win32_dsprop.py +52 -0
  661. angr/procedures/definitions/win32_dssec.py +46 -0
  662. angr/procedures/definitions/win32_dsuiext.py +46 -0
  663. angr/procedures/definitions/win32_dwmapi.py +100 -0
  664. angr/procedures/definitions/win32_dwrite.py +40 -0
  665. angr/procedures/definitions/win32_dxcompiler.py +42 -0
  666. angr/procedures/definitions/win32_dxcore.py +40 -0
  667. angr/procedures/definitions/win32_dxgi.py +50 -0
  668. angr/procedures/definitions/win32_dxva2.py +114 -0
  669. angr/procedures/definitions/win32_eappcfg.py +66 -0
  670. angr/procedures/definitions/win32_eappprxy.py +74 -0
  671. angr/procedures/definitions/win32_efswrt.py +42 -0
  672. angr/procedures/definitions/win32_elscore.py +48 -0
  673. angr/procedures/definitions/win32_esent.py +496 -0
  674. angr/procedures/definitions/win32_evr.py +52 -0
  675. angr/procedures/definitions/win32_faultrep.py +46 -0
  676. angr/procedures/definitions/win32_fhsvcctl.py +52 -0
  677. angr/procedures/definitions/win32_firewallapi.py +44 -0
  678. angr/procedures/definitions/win32_fltlib.py +94 -0
  679. angr/procedures/definitions/win32_fontsub.py +42 -0
  680. angr/procedures/definitions/win32_forceinline.py +44 -0
  681. angr/procedures/definitions/win32_fwpuclnt.py +422 -0
  682. angr/procedures/definitions/win32_fxsutility.py +42 -0
  683. angr/procedures/definitions/win32_gdi32.py +900 -0
  684. angr/procedures/definitions/win32_gdiplus.py +1296 -0
  685. angr/procedures/definitions/win32_glu32.py +142 -0
  686. angr/procedures/definitions/win32_gpedit.py +50 -0
  687. angr/procedures/definitions/win32_hhctrl_ocx.py +42 -0
  688. angr/procedures/definitions/win32_hid.py +128 -0
  689. angr/procedures/definitions/win32_hlink.py +94 -0
  690. angr/procedures/definitions/win32_hrtfapo.py +40 -0
  691. angr/procedures/definitions/win32_httpapi.py +124 -0
  692. angr/procedures/definitions/win32_icm32.py +80 -0
  693. angr/procedures/definitions/win32_icmui.py +42 -0
  694. angr/procedures/definitions/win32_icu.py +2088 -0
  695. angr/procedures/definitions/win32_ieframe.py +96 -0
  696. angr/procedures/definitions/win32_imagehlp.py +90 -0
  697. angr/procedures/definitions/win32_imgutil.py +56 -0
  698. angr/procedures/definitions/win32_imm32.py +202 -0
  699. angr/procedures/definitions/win32_infocardapi.py +72 -0
  700. angr/procedures/definitions/win32_inkobjcore.py +92 -0
  701. angr/procedures/definitions/win32_iphlpapi.py +440 -0
  702. angr/procedures/definitions/win32_iscsidsc.py +196 -0
  703. angr/procedures/definitions/win32_isolatedwindowsenvironmentutils.py +42 -0
  704. angr/procedures/definitions/win32_kernel32.py +3199 -0
  705. angr/procedures/definitions/win32_kernelbase.py +50 -0
  706. angr/procedures/definitions/win32_keycredmgr.py +46 -0
  707. angr/procedures/definitions/win32_ksproxy_ax.py +50 -0
  708. angr/procedures/definitions/win32_ksuser.py +54 -0
  709. angr/procedures/definitions/win32_ktmw32.py +116 -0
  710. angr/procedures/definitions/win32_licenseprotection.py +42 -0
  711. angr/procedures/definitions/win32_loadperf.py +62 -0
  712. angr/procedures/definitions/win32_magnification.py +76 -0
  713. angr/procedures/definitions/win32_mapi32.py +170 -0
  714. angr/procedures/definitions/win32_mdmlocalmanagement.py +44 -0
  715. angr/procedures/definitions/win32_mdmregistration.py +68 -0
  716. angr/procedures/definitions/win32_mf.py +162 -0
  717. angr/procedures/definitions/win32_mfcore.py +42 -0
  718. angr/procedures/definitions/win32_mfplat.py +328 -0
  719. angr/procedures/definitions/win32_mfplay.py +40 -0
  720. angr/procedures/definitions/win32_mfreadwrite.py +48 -0
  721. angr/procedures/definitions/win32_mfsensorgroup.py +58 -0
  722. angr/procedures/definitions/win32_mfsrcsnk.py +42 -0
  723. angr/procedures/definitions/win32_mgmtapi.py +56 -0
  724. angr/procedures/definitions/win32_mi.py +40 -0
  725. angr/procedures/definitions/win32_mmdevapi.py +40 -0
  726. angr/procedures/definitions/win32_mpr.py +132 -0
  727. angr/procedures/definitions/win32_mprapi.py +262 -0
  728. angr/procedures/definitions/win32_mqrt.py +106 -0
  729. angr/procedures/definitions/win32_mrmsupport.py +92 -0
  730. angr/procedures/definitions/win32_msacm32.py +122 -0
  731. angr/procedures/definitions/win32_msajapi.py +1132 -0
  732. angr/procedures/definitions/win32_mscms.py +196 -0
  733. angr/procedures/definitions/win32_mscoree.py +92 -0
  734. angr/procedures/definitions/win32_msctfmonitor.py +44 -0
  735. angr/procedures/definitions/win32_msdelta.py +70 -0
  736. angr/procedures/definitions/win32_msdmo.py +60 -0
  737. angr/procedures/definitions/win32_msdrm.py +206 -0
  738. angr/procedures/definitions/win32_msi.py +566 -0
  739. angr/procedures/definitions/win32_msimg32.py +44 -0
  740. angr/procedures/definitions/win32_mspatcha.py +70 -0
  741. angr/procedures/definitions/win32_mspatchc.py +56 -0
  742. angr/procedures/definitions/win32_msports.py +52 -0
  743. angr/procedures/definitions/win32_msrating.py +76 -0
  744. angr/procedures/definitions/win32_mssign32.py +58 -0
  745. angr/procedures/definitions/win32_mstask.py +42 -0
  746. angr/procedures/definitions/win32_msvfw32.py +124 -0
  747. angr/procedures/definitions/win32_mswsock.py +70 -0
  748. angr/procedures/definitions/win32_mtxdm.py +40 -0
  749. angr/procedures/definitions/win32_ncrypt.py +116 -0
  750. angr/procedures/definitions/win32_ndfapi.py +70 -0
  751. angr/procedures/definitions/win32_netapi32.py +450 -0
  752. angr/procedures/definitions/win32_netsh.py +54 -0
  753. angr/procedures/definitions/win32_netshell.py +42 -0
  754. angr/procedures/definitions/win32_newdev.py +60 -0
  755. angr/procedures/definitions/win32_ninput.py +98 -0
  756. angr/procedures/definitions/win32_normaliz.py +42 -0
  757. angr/procedures/definitions/win32_ntdll.py +185 -0
  758. angr/procedures/definitions/win32_ntdllk.py +40 -0
  759. angr/procedures/definitions/win32_ntdsapi.py +200 -0
  760. angr/procedures/definitions/win32_ntlanman.py +58 -0
  761. angr/procedures/definitions/win32_odbc32.py +406 -0
  762. angr/procedures/definitions/win32_odbcbcp.py +92 -0
  763. angr/procedures/definitions/win32_ole32.py +672 -0
  764. angr/procedures/definitions/win32_oleacc.py +72 -0
  765. angr/procedures/definitions/win32_oleaut32.py +848 -0
  766. angr/procedures/definitions/win32_oledlg.py +84 -0
  767. angr/procedures/definitions/win32_ondemandconnroutehelper.py +48 -0
  768. angr/procedures/definitions/win32_opengl32.py +748 -0
  769. angr/procedures/definitions/win32_opmxbox.py +44 -0
  770. angr/procedures/definitions/win32_p2p.py +254 -0
  771. angr/procedures/definitions/win32_p2pgraph.py +112 -0
  772. angr/procedures/definitions/win32_pdh.py +234 -0
  773. angr/procedures/definitions/win32_peerdist.py +94 -0
  774. angr/procedures/definitions/win32_powrprof.py +206 -0
  775. angr/procedures/definitions/win32_prntvpt.py +60 -0
  776. angr/procedures/definitions/win32_projectedfslib.py +76 -0
  777. angr/procedures/definitions/win32_propsys.py +474 -0
  778. angr/procedures/definitions/win32_psapi.py +92 -0
  779. angr/procedures/definitions/win32_quartz.py +42 -0
  780. angr/procedures/definitions/win32_query.py +46 -0
  781. angr/procedures/definitions/win32_qwave.py +60 -0
  782. angr/procedures/definitions/win32_rasapi32.py +206 -0
  783. angr/procedures/definitions/win32_rasdlg.py +50 -0
  784. angr/procedures/definitions/win32_resutils.py +278 -0
  785. angr/procedures/definitions/win32_rometadata.py +23 -0
  786. angr/procedures/definitions/win32_rpcns4.py +160 -0
  787. angr/procedures/definitions/win32_rpcproxy.py +46 -0
  788. angr/procedures/definitions/win32_rpcrt4.py +932 -0
  789. angr/procedures/definitions/win32_rstrtmgr.py +60 -0
  790. angr/procedures/definitions/win32_rtm.py +190 -0
  791. angr/procedures/definitions/win32_rtutils.py +120 -0
  792. angr/procedures/definitions/win32_rtworkq.py +104 -0
  793. angr/procedures/definitions/win32_sas.py +40 -0
  794. angr/procedures/definitions/win32_scarddlg.py +48 -0
  795. angr/procedures/definitions/win32_schannel.py +56 -0
  796. angr/procedures/definitions/win32_sechost.py +42 -0
  797. angr/procedures/definitions/win32_secur32.py +216 -0
  798. angr/procedures/definitions/win32_sensapi.py +44 -0
  799. angr/procedures/definitions/win32_sensorsutilsv2.py +118 -0
  800. angr/procedures/definitions/win32_setupapi.py +706 -0
  801. angr/procedures/definitions/win32_sfc.py +50 -0
  802. angr/procedures/definitions/win32_shdocvw.py +44 -0
  803. angr/procedures/definitions/win32_shell32.py +526 -0
  804. angr/procedures/definitions/win32_shlwapi.py +758 -0
  805. angr/procedures/definitions/win32_slc.py +102 -0
  806. angr/procedures/definitions/win32_slcext.py +46 -0
  807. angr/procedures/definitions/win32_slwga.py +40 -0
  808. angr/procedures/definitions/win32_snmpapi.py +90 -0
  809. angr/procedures/definitions/win32_spoolss.py +90 -0
  810. angr/procedures/definitions/win32_srclient.py +40 -0
  811. angr/procedures/definitions/win32_srpapi.py +60 -0
  812. angr/procedures/definitions/win32_sspicli.py +52 -0
  813. angr/procedures/definitions/win32_sti.py +40 -0
  814. angr/procedures/definitions/win32_t2embed.py +66 -0
  815. angr/procedures/definitions/win32_tapi32.py +536 -0
  816. angr/procedures/definitions/win32_tbs.py +66 -0
  817. angr/procedures/definitions/win32_tdh.py +92 -0
  818. angr/procedures/definitions/win32_tokenbinding.py +58 -0
  819. angr/procedures/definitions/win32_traffic.py +78 -0
  820. angr/procedures/definitions/win32_txfw32.py +56 -0
  821. angr/procedures/definitions/win32_ualapi.py +46 -0
  822. angr/procedures/definitions/win32_uiautomationcore.py +234 -0
  823. angr/procedures/definitions/win32_urlmon.py +192 -0
  824. angr/procedures/definitions/win32_user32.py +1565 -0
  825. angr/procedures/definitions/win32_userenv.py +126 -0
  826. angr/procedures/definitions/win32_usp10.py +118 -0
  827. angr/procedures/definitions/win32_uxtheme.py +192 -0
  828. angr/procedures/definitions/win32_verifier.py +40 -0
  829. angr/procedures/definitions/win32_version.py +66 -0
  830. angr/procedures/definitions/win32_vertdll.py +52 -0
  831. angr/procedures/definitions/win32_virtdisk.py +96 -0
  832. angr/procedures/definitions/win32_vmdevicehost.py +64 -0
  833. angr/procedures/definitions/win32_vmsavedstatedumpprovider.py +124 -0
  834. angr/procedures/definitions/win32_vssapi.py +40 -0
  835. angr/procedures/definitions/win32_wcmapi.py +48 -0
  836. angr/procedures/definitions/win32_wdsbp.py +52 -0
  837. angr/procedures/definitions/win32_wdsclientapi.py +112 -0
  838. angr/procedures/definitions/win32_wdsmc.py +50 -0
  839. angr/procedures/definitions/win32_wdspxe.py +100 -0
  840. angr/procedures/definitions/win32_wdstptc.py +64 -0
  841. angr/procedures/definitions/win32_webauthn.py +64 -0
  842. angr/procedures/definitions/win32_webservices.py +424 -0
  843. angr/procedures/definitions/win32_websocket.py +64 -0
  844. angr/procedures/definitions/win32_wecapi.py +68 -0
  845. angr/procedures/definitions/win32_wer.py +80 -0
  846. angr/procedures/definitions/win32_wevtapi.py +108 -0
  847. angr/procedures/definitions/win32_winbio.py +146 -0
  848. angr/procedures/definitions/win32_windows_ai_machinelearning.py +40 -0
  849. angr/procedures/definitions/win32_windows_data_pdf.py +23 -0
  850. angr/procedures/definitions/win32_windows_media_mediacontrol.py +54 -0
  851. angr/procedures/definitions/win32_windows_networking.py +40 -0
  852. angr/procedures/definitions/win32_windows_ui_xaml.py +42 -0
  853. angr/procedures/definitions/win32_windowscodecs.py +56 -0
  854. angr/procedures/definitions/win32_winfax.py +150 -0
  855. angr/procedures/definitions/win32_winhttp.py +150 -0
  856. angr/procedures/definitions/win32_winhvemulation.py +46 -0
  857. angr/procedures/definitions/win32_winhvplatform.py +170 -0
  858. angr/procedures/definitions/win32_wininet.py +630 -0
  859. angr/procedures/definitions/win32_winml.py +40 -0
  860. angr/procedures/definitions/win32_winmm.py +390 -0
  861. angr/procedures/definitions/win32_winscard.py +178 -0
  862. angr/procedures/definitions/win32_winspool.py +363 -0
  863. angr/procedures/definitions/win32_winspool_drv.py +382 -0
  864. angr/procedures/definitions/win32_wintrust.py +158 -0
  865. angr/procedures/definitions/win32_winusb.py +106 -0
  866. angr/procedures/definitions/win32_wlanapi.py +158 -0
  867. angr/procedures/definitions/win32_wlanui.py +40 -0
  868. angr/procedures/definitions/win32_wldap32.py +524 -0
  869. angr/procedures/definitions/win32_wldp.py +56 -0
  870. angr/procedures/definitions/win32_wmvcore.py +60 -0
  871. angr/procedures/definitions/win32_wnvapi.py +42 -0
  872. angr/procedures/definitions/win32_wofutil.py +60 -0
  873. angr/procedures/definitions/win32_ws2_32.py +358 -0
  874. angr/procedures/definitions/win32_wscapi.py +50 -0
  875. angr/procedures/definitions/win32_wsclient.py +44 -0
  876. angr/procedures/definitions/win32_wsdapi.py +102 -0
  877. angr/procedures/definitions/win32_wsmsvc.py +104 -0
  878. angr/procedures/definitions/win32_wsnmp32.py +136 -0
  879. angr/procedures/definitions/win32_wtsapi32.py +164 -0
  880. angr/procedures/definitions/win32_xaudio2_8.py +46 -0
  881. angr/procedures/definitions/win32_xinput1_4.py +52 -0
  882. angr/procedures/definitions/win32_xinputuap.py +35 -0
  883. angr/procedures/definitions/win32_xmllite.py +50 -0
  884. angr/procedures/definitions/win32_xolehlp.py +46 -0
  885. angr/procedures/definitions/win32_xpsprint.py +42 -0
  886. angr/procedures/glibc/__ctype_b_loc.py +22 -0
  887. angr/procedures/glibc/__ctype_tolower_loc.py +22 -0
  888. angr/procedures/glibc/__ctype_toupper_loc.py +22 -0
  889. angr/procedures/glibc/__errno_location.py +6 -0
  890. angr/procedures/glibc/__init__.py +3 -0
  891. angr/procedures/glibc/__libc_init.py +36 -0
  892. angr/procedures/glibc/__libc_start_main.py +294 -0
  893. angr/procedures/glibc/dynamic_loading.py +19 -0
  894. angr/procedures/glibc/scanf.py +10 -0
  895. angr/procedures/glibc/sscanf.py +5 -0
  896. angr/procedures/gnulib/__init__.py +3 -0
  897. angr/procedures/gnulib/xalloc_die.py +13 -0
  898. angr/procedures/gnulib/xstrtol_fatal.py +13 -0
  899. angr/procedures/java/__init__.py +38 -0
  900. angr/procedures/java/unconstrained.py +64 -0
  901. angr/procedures/java_io/__init__.py +0 -0
  902. angr/procedures/java_io/read.py +11 -0
  903. angr/procedures/java_io/write.py +16 -0
  904. angr/procedures/java_jni/__init__.py +475 -0
  905. angr/procedures/java_jni/array_operations.py +309 -0
  906. angr/procedures/java_jni/class_and_interface_operations.py +31 -0
  907. angr/procedures/java_jni/field_access.py +176 -0
  908. angr/procedures/java_jni/global_and_local_refs.py +56 -0
  909. angr/procedures/java_jni/method_calls.py +364 -0
  910. angr/procedures/java_jni/not_implemented.py +25 -0
  911. angr/procedures/java_jni/object_operations.py +95 -0
  912. angr/procedures/java_jni/string_operations.py +86 -0
  913. angr/procedures/java_jni/version_information.py +11 -0
  914. angr/procedures/java_lang/__init__.py +0 -0
  915. angr/procedures/java_lang/character.py +31 -0
  916. angr/procedures/java_lang/double.py +24 -0
  917. angr/procedures/java_lang/exit.py +12 -0
  918. angr/procedures/java_lang/getsimplename.py +15 -0
  919. angr/procedures/java_lang/integer.py +42 -0
  920. angr/procedures/java_lang/load_library.py +8 -0
  921. angr/procedures/java_lang/math.py +14 -0
  922. angr/procedures/java_lang/string.py +78 -0
  923. angr/procedures/java_lang/stringbuilder.py +43 -0
  924. angr/procedures/java_lang/system.py +17 -0
  925. angr/procedures/java_util/__init__.py +0 -0
  926. angr/procedures/java_util/collection.py +34 -0
  927. angr/procedures/java_util/iterator.py +45 -0
  928. angr/procedures/java_util/list.py +98 -0
  929. angr/procedures/java_util/map.py +132 -0
  930. angr/procedures/java_util/random.py +11 -0
  931. angr/procedures/java_util/scanner_nextline.py +22 -0
  932. angr/procedures/libc/__init__.py +3 -0
  933. angr/procedures/libc/abort.py +8 -0
  934. angr/procedures/libc/access.py +10 -0
  935. angr/procedures/libc/atoi.py +14 -0
  936. angr/procedures/libc/atol.py +12 -0
  937. angr/procedures/libc/calloc.py +7 -0
  938. angr/procedures/libc/closelog.py +9 -0
  939. angr/procedures/libc/err.py +13 -0
  940. angr/procedures/libc/error.py +55 -0
  941. angr/procedures/libc/exit.py +10 -0
  942. angr/procedures/libc/fclose.py +20 -0
  943. angr/procedures/libc/feof.py +19 -0
  944. angr/procedures/libc/fflush.py +15 -0
  945. angr/procedures/libc/fgetc.py +24 -0
  946. angr/procedures/libc/fgets.py +68 -0
  947. angr/procedures/libc/fopen.py +64 -0
  948. angr/procedures/libc/fprintf.py +24 -0
  949. angr/procedures/libc/fputc.py +22 -0
  950. angr/procedures/libc/fputs.py +23 -0
  951. angr/procedures/libc/fread.py +22 -0
  952. angr/procedures/libc/free.py +8 -0
  953. angr/procedures/libc/fscanf.py +20 -0
  954. angr/procedures/libc/fseek.py +32 -0
  955. angr/procedures/libc/ftell.py +21 -0
  956. angr/procedures/libc/fwrite.py +18 -0
  957. angr/procedures/libc/getchar.py +13 -0
  958. angr/procedures/libc/getdelim.py +96 -0
  959. angr/procedures/libc/getegid.py +7 -0
  960. angr/procedures/libc/geteuid.py +7 -0
  961. angr/procedures/libc/getgid.py +7 -0
  962. angr/procedures/libc/gets.py +66 -0
  963. angr/procedures/libc/getuid.py +7 -0
  964. angr/procedures/libc/malloc.py +11 -0
  965. angr/procedures/libc/memcmp.py +69 -0
  966. angr/procedures/libc/memcpy.py +37 -0
  967. angr/procedures/libc/memset.py +69 -0
  968. angr/procedures/libc/openlog.py +9 -0
  969. angr/procedures/libc/perror.py +12 -0
  970. angr/procedures/libc/printf.py +33 -0
  971. angr/procedures/libc/putchar.py +12 -0
  972. angr/procedures/libc/puts.py +16 -0
  973. angr/procedures/libc/rand.py +7 -0
  974. angr/procedures/libc/realloc.py +7 -0
  975. angr/procedures/libc/rewind.py +11 -0
  976. angr/procedures/libc/scanf.py +20 -0
  977. angr/procedures/libc/setbuf.py +8 -0
  978. angr/procedures/libc/setvbuf.py +6 -0
  979. angr/procedures/libc/snprintf.py +33 -0
  980. angr/procedures/libc/sprintf.py +22 -0
  981. angr/procedures/libc/srand.py +6 -0
  982. angr/procedures/libc/sscanf.py +13 -0
  983. angr/procedures/libc/stpcpy.py +18 -0
  984. angr/procedures/libc/strcat.py +13 -0
  985. angr/procedures/libc/strchr.py +44 -0
  986. angr/procedures/libc/strcmp.py +28 -0
  987. angr/procedures/libc/strcpy.py +13 -0
  988. angr/procedures/libc/strlen.py +99 -0
  989. angr/procedures/libc/strncat.py +18 -0
  990. angr/procedures/libc/strncmp.py +180 -0
  991. angr/procedures/libc/strncpy.py +18 -0
  992. angr/procedures/libc/strnlen.py +13 -0
  993. angr/procedures/libc/strstr.py +94 -0
  994. angr/procedures/libc/strtol.py +263 -0
  995. angr/procedures/libc/strtoul.py +9 -0
  996. angr/procedures/libc/system.py +12 -0
  997. angr/procedures/libc/time.py +9 -0
  998. angr/procedures/libc/tmpnam.py +19 -0
  999. angr/procedures/libc/tolower.py +7 -0
  1000. angr/procedures/libc/toupper.py +7 -0
  1001. angr/procedures/libc/ungetc.py +19 -0
  1002. angr/procedures/libc/vsnprintf.py +16 -0
  1003. angr/procedures/libc/wchar.py +15 -0
  1004. angr/procedures/libstdcpp/__init__.py +0 -0
  1005. angr/procedures/libstdcpp/_unwind_resume.py +10 -0
  1006. angr/procedures/libstdcpp/std____throw_bad_alloc.py +12 -0
  1007. angr/procedures/libstdcpp/std____throw_bad_cast.py +12 -0
  1008. angr/procedures/libstdcpp/std____throw_length_error.py +12 -0
  1009. angr/procedures/libstdcpp/std____throw_logic_error.py +12 -0
  1010. angr/procedures/libstdcpp/std__terminate.py +12 -0
  1011. angr/procedures/linux_kernel/__init__.py +3 -0
  1012. angr/procedures/linux_kernel/access.py +17 -0
  1013. angr/procedures/linux_kernel/arch_prctl.py +33 -0
  1014. angr/procedures/linux_kernel/arm_user_helpers.py +58 -0
  1015. angr/procedures/linux_kernel/brk.py +17 -0
  1016. angr/procedures/linux_kernel/cwd.py +27 -0
  1017. angr/procedures/linux_kernel/fstat.py +137 -0
  1018. angr/procedures/linux_kernel/fstat64.py +169 -0
  1019. angr/procedures/linux_kernel/futex.py +17 -0
  1020. angr/procedures/linux_kernel/getegid.py +16 -0
  1021. angr/procedures/linux_kernel/geteuid.py +16 -0
  1022. angr/procedures/linux_kernel/getgid.py +16 -0
  1023. angr/procedures/linux_kernel/getpid.py +13 -0
  1024. angr/procedures/linux_kernel/getrlimit.py +24 -0
  1025. angr/procedures/linux_kernel/gettid.py +8 -0
  1026. angr/procedures/linux_kernel/getuid.py +16 -0
  1027. angr/procedures/linux_kernel/iovec.py +43 -0
  1028. angr/procedures/linux_kernel/lseek.py +39 -0
  1029. angr/procedures/linux_kernel/mmap.py +15 -0
  1030. angr/procedures/linux_kernel/mprotect.py +41 -0
  1031. angr/procedures/linux_kernel/munmap.py +7 -0
  1032. angr/procedures/linux_kernel/openat.py +28 -0
  1033. angr/procedures/linux_kernel/set_tid_address.py +7 -0
  1034. angr/procedures/linux_kernel/sigaction.py +16 -0
  1035. angr/procedures/linux_kernel/sigprocmask.py +20 -0
  1036. angr/procedures/linux_kernel/stat.py +22 -0
  1037. angr/procedures/linux_kernel/sysinfo.py +58 -0
  1038. angr/procedures/linux_kernel/tgkill.py +7 -0
  1039. angr/procedures/linux_kernel/time.py +30 -0
  1040. angr/procedures/linux_kernel/uid.py +29 -0
  1041. angr/procedures/linux_kernel/uname.py +28 -0
  1042. angr/procedures/linux_kernel/unlink.py +22 -0
  1043. angr/procedures/linux_kernel/vsyscall.py +15 -0
  1044. angr/procedures/linux_loader/__init__.py +3 -0
  1045. angr/procedures/linux_loader/_dl_initial_error_catch_tsd.py +6 -0
  1046. angr/procedures/linux_loader/_dl_rtld_lock.py +14 -0
  1047. angr/procedures/linux_loader/sim_loader.py +53 -0
  1048. angr/procedures/linux_loader/tls.py +40 -0
  1049. angr/procedures/msvcr/__getmainargs.py +15 -0
  1050. angr/procedures/msvcr/__init__.py +4 -0
  1051. angr/procedures/msvcr/_initterm.py +37 -0
  1052. angr/procedures/msvcr/fmode.py +28 -0
  1053. angr/procedures/ntdll/__init__.py +0 -0
  1054. angr/procedures/ntdll/exceptions.py +57 -0
  1055. angr/procedures/posix/__init__.py +3 -0
  1056. angr/procedures/posix/accept.py +29 -0
  1057. angr/procedures/posix/bind.py +12 -0
  1058. angr/procedures/posix/bzero.py +6 -0
  1059. angr/procedures/posix/chroot.py +26 -0
  1060. angr/procedures/posix/close.py +9 -0
  1061. angr/procedures/posix/closedir.py +6 -0
  1062. angr/procedures/posix/dup.py +55 -0
  1063. angr/procedures/posix/fcntl.py +9 -0
  1064. angr/procedures/posix/fdopen.py +77 -0
  1065. angr/procedures/posix/fileno.py +17 -0
  1066. angr/procedures/posix/fork.py +10 -0
  1067. angr/procedures/posix/getenv.py +34 -0
  1068. angr/procedures/posix/gethostbyname.py +42 -0
  1069. angr/procedures/posix/getpass.py +18 -0
  1070. angr/procedures/posix/getsockopt.py +10 -0
  1071. angr/procedures/posix/htonl.py +11 -0
  1072. angr/procedures/posix/htons.py +11 -0
  1073. angr/procedures/posix/inet_ntoa.py +61 -0
  1074. angr/procedures/posix/listen.py +12 -0
  1075. angr/procedures/posix/mmap.py +140 -0
  1076. angr/procedures/posix/open.py +17 -0
  1077. angr/procedures/posix/opendir.py +9 -0
  1078. angr/procedures/posix/poll.py +54 -0
  1079. angr/procedures/posix/pread64.py +45 -0
  1080. angr/procedures/posix/pthread.py +87 -0
  1081. angr/procedures/posix/pwrite64.py +45 -0
  1082. angr/procedures/posix/read.py +12 -0
  1083. angr/procedures/posix/readdir.py +59 -0
  1084. angr/procedures/posix/recv.py +12 -0
  1085. angr/procedures/posix/recvfrom.py +12 -0
  1086. angr/procedures/posix/select.py +46 -0
  1087. angr/procedures/posix/send.py +22 -0
  1088. angr/procedures/posix/setsockopt.py +8 -0
  1089. angr/procedures/posix/sigaction.py +20 -0
  1090. angr/procedures/posix/sim_time.py +45 -0
  1091. angr/procedures/posix/sleep.py +7 -0
  1092. angr/procedures/posix/socket.py +18 -0
  1093. angr/procedures/posix/strcasecmp.py +23 -0
  1094. angr/procedures/posix/strdup.py +17 -0
  1095. angr/procedures/posix/strtok_r.py +65 -0
  1096. angr/procedures/posix/syslog.py +15 -0
  1097. angr/procedures/posix/tz.py +8 -0
  1098. angr/procedures/posix/unlink.py +10 -0
  1099. angr/procedures/posix/usleep.py +7 -0
  1100. angr/procedures/posix/write.py +12 -0
  1101. angr/procedures/procedure_dict.py +48 -0
  1102. angr/procedures/stubs/CallReturn.py +12 -0
  1103. angr/procedures/stubs/NoReturnUnconstrained.py +12 -0
  1104. angr/procedures/stubs/Nop.py +6 -0
  1105. angr/procedures/stubs/PathTerminator.py +8 -0
  1106. angr/procedures/stubs/Redirect.py +15 -0
  1107. angr/procedures/stubs/ReturnChar.py +10 -0
  1108. angr/procedures/stubs/ReturnUnconstrained.py +24 -0
  1109. angr/procedures/stubs/UnresolvableCallTarget.py +8 -0
  1110. angr/procedures/stubs/UnresolvableJumpTarget.py +8 -0
  1111. angr/procedures/stubs/UserHook.py +15 -0
  1112. angr/procedures/stubs/__init__.py +3 -0
  1113. angr/procedures/stubs/b64_decode.py +12 -0
  1114. angr/procedures/stubs/caller.py +13 -0
  1115. angr/procedures/stubs/crazy_scanf.py +17 -0
  1116. angr/procedures/stubs/format_parser.py +677 -0
  1117. angr/procedures/stubs/syscall_stub.py +26 -0
  1118. angr/procedures/testing/__init__.py +3 -0
  1119. angr/procedures/testing/manyargs.py +8 -0
  1120. angr/procedures/testing/retreg.py +8 -0
  1121. angr/procedures/tracer/__init__.py +4 -0
  1122. angr/procedures/tracer/random.py +8 -0
  1123. angr/procedures/tracer/receive.py +21 -0
  1124. angr/procedures/tracer/transmit.py +24 -0
  1125. angr/procedures/uclibc/__init__.py +3 -0
  1126. angr/procedures/uclibc/__uClibc_main.py +9 -0
  1127. angr/procedures/win32/EncodePointer.py +6 -0
  1128. angr/procedures/win32/ExitProcess.py +8 -0
  1129. angr/procedures/win32/GetCommandLine.py +11 -0
  1130. angr/procedures/win32/GetCurrentProcessId.py +6 -0
  1131. angr/procedures/win32/GetCurrentThreadId.py +6 -0
  1132. angr/procedures/win32/GetLastInputInfo.py +37 -0
  1133. angr/procedures/win32/GetModuleHandle.py +30 -0
  1134. angr/procedures/win32/GetProcessAffinityMask.py +34 -0
  1135. angr/procedures/win32/InterlockedExchange.py +14 -0
  1136. angr/procedures/win32/IsProcessorFeaturePresent.py +6 -0
  1137. angr/procedures/win32/VirtualAlloc.py +113 -0
  1138. angr/procedures/win32/VirtualProtect.py +59 -0
  1139. angr/procedures/win32/__init__.py +3 -0
  1140. angr/procedures/win32/critical_section.py +11 -0
  1141. angr/procedures/win32/dynamic_loading.py +103 -0
  1142. angr/procedures/win32/file_handles.py +47 -0
  1143. angr/procedures/win32/gethostbyname.py +10 -0
  1144. angr/procedures/win32/heap.py +42 -0
  1145. angr/procedures/win32/is_bad_ptr.py +25 -0
  1146. angr/procedures/win32/local_storage.py +85 -0
  1147. angr/procedures/win32/mutex.py +10 -0
  1148. angr/procedures/win32/sim_time.py +135 -0
  1149. angr/procedures/win32/system_paths.py +34 -0
  1150. angr/procedures/win32_kernel/ExAllocatePool.py +12 -0
  1151. angr/procedures/win32_kernel/ExFreePoolWithTag.py +7 -0
  1152. angr/procedures/win32_kernel/__init__.py +3 -0
  1153. angr/procedures/win_user32/__init__.py +0 -0
  1154. angr/procedures/win_user32/chars.py +12 -0
  1155. angr/procedures/win_user32/keyboard.py +13 -0
  1156. angr/procedures/win_user32/messagebox.py +49 -0
  1157. angr/project.py +834 -0
  1158. angr/protos/__init__.py +13 -0
  1159. angr/protos/cfg_pb2.py +31 -0
  1160. angr/protos/function_pb2.py +37 -0
  1161. angr/protos/primitives_pb2.py +124 -0
  1162. angr/protos/variables_pb2.py +126 -0
  1163. angr/protos/xrefs_pb2.py +34 -0
  1164. angr/py.typed +1 -0
  1165. angr/serializable.py +63 -0
  1166. angr/service.py +35 -0
  1167. angr/sim_manager.py +971 -0
  1168. angr/sim_options.py +444 -0
  1169. angr/sim_procedure.py +606 -0
  1170. angr/sim_state.py +1003 -0
  1171. angr/sim_state_options.py +409 -0
  1172. angr/sim_type.py +3372 -0
  1173. angr/sim_variable.py +562 -0
  1174. angr/simos/__init__.py +31 -0
  1175. angr/simos/cgc.py +152 -0
  1176. angr/simos/javavm.py +471 -0
  1177. angr/simos/linux.py +519 -0
  1178. angr/simos/simos.py +450 -0
  1179. angr/simos/snimmuc_nxp.py +152 -0
  1180. angr/simos/userland.py +163 -0
  1181. angr/simos/windows.py +562 -0
  1182. angr/slicer.py +353 -0
  1183. angr/state_hierarchy.py +262 -0
  1184. angr/state_plugins/__init__.py +29 -0
  1185. angr/state_plugins/callstack.py +404 -0
  1186. angr/state_plugins/cgc.py +153 -0
  1187. angr/state_plugins/concrete.py +297 -0
  1188. angr/state_plugins/debug_variables.py +194 -0
  1189. angr/state_plugins/filesystem.py +469 -0
  1190. angr/state_plugins/gdb.py +146 -0
  1191. angr/state_plugins/globals.py +62 -0
  1192. angr/state_plugins/heap/__init__.py +5 -0
  1193. angr/state_plugins/heap/heap_base.py +126 -0
  1194. angr/state_plugins/heap/heap_brk.py +134 -0
  1195. angr/state_plugins/heap/heap_freelist.py +210 -0
  1196. angr/state_plugins/heap/heap_libc.py +45 -0
  1197. angr/state_plugins/heap/heap_ptmalloc.py +646 -0
  1198. angr/state_plugins/heap/utils.py +21 -0
  1199. angr/state_plugins/history.py +548 -0
  1200. angr/state_plugins/inspect.py +376 -0
  1201. angr/state_plugins/javavm_classloader.py +133 -0
  1202. angr/state_plugins/jni_references.py +93 -0
  1203. angr/state_plugins/libc.py +1263 -0
  1204. angr/state_plugins/light_registers.py +170 -0
  1205. angr/state_plugins/log.py +85 -0
  1206. angr/state_plugins/loop_data.py +92 -0
  1207. angr/state_plugins/plugin.py +155 -0
  1208. angr/state_plugins/posix.py +709 -0
  1209. angr/state_plugins/preconstrainer.py +195 -0
  1210. angr/state_plugins/scratch.py +175 -0
  1211. angr/state_plugins/sim_action.py +334 -0
  1212. angr/state_plugins/sim_action_object.py +148 -0
  1213. angr/state_plugins/sim_event.py +58 -0
  1214. angr/state_plugins/solver.py +1129 -0
  1215. angr/state_plugins/symbolizer.py +292 -0
  1216. angr/state_plugins/trace_additions.py +752 -0
  1217. angr/state_plugins/uc_manager.py +85 -0
  1218. angr/state_plugins/unicorn_engine.py +1899 -0
  1219. angr/state_plugins/view.py +341 -0
  1220. angr/storage/__init__.py +9 -0
  1221. angr/storage/file.py +1219 -0
  1222. angr/storage/memory_mixins/__init__.py +393 -0
  1223. angr/storage/memory_mixins/__init__.pyi +49 -0
  1224. angr/storage/memory_mixins/actions_mixin.py +69 -0
  1225. angr/storage/memory_mixins/address_concretization_mixin.py +388 -0
  1226. angr/storage/memory_mixins/bvv_conversion_mixin.py +74 -0
  1227. angr/storage/memory_mixins/clouseau_mixin.py +131 -0
  1228. angr/storage/memory_mixins/conditional_store_mixin.py +24 -0
  1229. angr/storage/memory_mixins/convenient_mappings_mixin.py +257 -0
  1230. angr/storage/memory_mixins/default_filler_mixin.py +146 -0
  1231. angr/storage/memory_mixins/dirty_addrs_mixin.py +9 -0
  1232. angr/storage/memory_mixins/hex_dumper_mixin.py +85 -0
  1233. angr/storage/memory_mixins/javavm_memory/__init__.py +1 -0
  1234. angr/storage/memory_mixins/javavm_memory/javavm_memory_mixin.py +394 -0
  1235. angr/storage/memory_mixins/keyvalue_memory/__init__.py +1 -0
  1236. angr/storage/memory_mixins/keyvalue_memory/keyvalue_memory_mixin.py +36 -0
  1237. angr/storage/memory_mixins/label_merger_mixin.py +31 -0
  1238. angr/storage/memory_mixins/multi_value_merger_mixin.py +68 -0
  1239. angr/storage/memory_mixins/name_resolution_mixin.py +70 -0
  1240. angr/storage/memory_mixins/paged_memory/__init__.py +0 -0
  1241. angr/storage/memory_mixins/paged_memory/page_backer_mixins.py +266 -0
  1242. angr/storage/memory_mixins/paged_memory/paged_memory_mixin.py +750 -0
  1243. angr/storage/memory_mixins/paged_memory/paged_memory_multivalue_mixin.py +63 -0
  1244. angr/storage/memory_mixins/paged_memory/pages/__init__.py +33 -0
  1245. angr/storage/memory_mixins/paged_memory/pages/cooperation.py +330 -0
  1246. angr/storage/memory_mixins/paged_memory/pages/history_tracking_mixin.py +87 -0
  1247. angr/storage/memory_mixins/paged_memory/pages/ispo_mixin.py +53 -0
  1248. angr/storage/memory_mixins/paged_memory/pages/list_page.py +346 -0
  1249. angr/storage/memory_mixins/paged_memory/pages/multi_values.py +290 -0
  1250. angr/storage/memory_mixins/paged_memory/pages/mv_list_page.py +434 -0
  1251. angr/storage/memory_mixins/paged_memory/pages/permissions_mixin.py +33 -0
  1252. angr/storage/memory_mixins/paged_memory/pages/refcount_mixin.py +51 -0
  1253. angr/storage/memory_mixins/paged_memory/pages/ultra_page.py +468 -0
  1254. angr/storage/memory_mixins/paged_memory/privileged_mixin.py +36 -0
  1255. angr/storage/memory_mixins/paged_memory/stack_allocation_mixin.py +73 -0
  1256. angr/storage/memory_mixins/regioned_memory/__init__.py +6 -0
  1257. angr/storage/memory_mixins/regioned_memory/abstract_address_descriptor.py +35 -0
  1258. angr/storage/memory_mixins/regioned_memory/abstract_merger_mixin.py +43 -0
  1259. angr/storage/memory_mixins/regioned_memory/region_category_mixin.py +7 -0
  1260. angr/storage/memory_mixins/regioned_memory/region_data.py +245 -0
  1261. angr/storage/memory_mixins/regioned_memory/region_meta_mixin.py +125 -0
  1262. angr/storage/memory_mixins/regioned_memory/regioned_address_concretization_mixin.py +118 -0
  1263. angr/storage/memory_mixins/regioned_memory/regioned_memory_mixin.py +462 -0
  1264. angr/storage/memory_mixins/regioned_memory/static_find_mixin.py +70 -0
  1265. angr/storage/memory_mixins/simple_interface_mixin.py +73 -0
  1266. angr/storage/memory_mixins/simplification_mixin.py +13 -0
  1267. angr/storage/memory_mixins/size_resolution_mixin.py +140 -0
  1268. angr/storage/memory_mixins/slotted_memory.py +140 -0
  1269. angr/storage/memory_mixins/smart_find_mixin.py +159 -0
  1270. angr/storage/memory_mixins/symbolic_merger_mixin.py +12 -0
  1271. angr/storage/memory_mixins/top_merger_mixin.py +24 -0
  1272. angr/storage/memory_mixins/underconstrained_mixin.py +67 -0
  1273. angr/storage/memory_mixins/unwrapper_mixin.py +26 -0
  1274. angr/storage/memory_object.py +194 -0
  1275. angr/storage/pcap.py +65 -0
  1276. angr/tablespecs.py +90 -0
  1277. angr/utils/__init__.py +33 -0
  1278. angr/utils/algo.py +33 -0
  1279. angr/utils/constants.py +7 -0
  1280. angr/utils/cowdict.py +64 -0
  1281. angr/utils/dynamic_dictlist.py +92 -0
  1282. angr/utils/enums_conv.py +80 -0
  1283. angr/utils/env.py +11 -0
  1284. angr/utils/formatting.py +124 -0
  1285. angr/utils/funcid.py +133 -0
  1286. angr/utils/graph.py +822 -0
  1287. angr/utils/lazy_import.py +12 -0
  1288. angr/utils/library.py +214 -0
  1289. angr/utils/loader.py +55 -0
  1290. angr/utils/mp.py +64 -0
  1291. angr/utils/segment_list.py +558 -0
  1292. angr/utils/timing.py +45 -0
  1293. angr/utils/typing.py +17 -0
  1294. angr/vaults.py +370 -0
  1295. angr-9.2.103.dist-info/LICENSE +24 -0
  1296. angr-9.2.103.dist-info/METADATA +119 -0
  1297. angr-9.2.103.dist-info/RECORD +1300 -0
  1298. angr-9.2.103.dist-info/WHEEL +5 -0
  1299. angr-9.2.103.dist-info/entry_points.txt +2 -0
  1300. angr-9.2.103.dist-info/top_level.txt +1 -0
@@ -0,0 +1,2166 @@
1
+ from __future__ import annotations
2
+ import copy
3
+ from collections import defaultdict, namedtuple
4
+ import logging
5
+ import enum
6
+ from dataclasses import dataclass
7
+ from typing import Any, NamedTuple, TYPE_CHECKING
8
+
9
+ from collections.abc import Iterable
10
+
11
+ import networkx
12
+ import capstone
13
+
14
+ import ailment
15
+
16
+ from ...knowledge_base import KnowledgeBase
17
+ from ...knowledge_plugins.functions import Function
18
+ from ...knowledge_plugins.cfg.memory_data import MemoryDataSort
19
+ from ...codenode import BlockNode
20
+ from ...utils import timethis
21
+ from ...calling_conventions import SimRegArg, SimStackArg, SimStructArg, SimFunctionArgument
22
+ from ...sim_type import (
23
+ SimTypeChar,
24
+ SimTypeInt,
25
+ SimTypeLongLong,
26
+ SimTypeShort,
27
+ SimTypeFunction,
28
+ SimTypeBottom,
29
+ SimTypeFloat,
30
+ SimTypePointer,
31
+ )
32
+ from ..stack_pointer_tracker import Register, OffsetVal
33
+ from ...sim_variable import SimVariable, SimStackVariable, SimRegisterVariable, SimMemoryVariable
34
+ from ...knowledge_plugins.key_definitions.constants import OP_BEFORE
35
+ from ...procedures.stubs.UnresolvableCallTarget import UnresolvableCallTarget
36
+ from ...procedures.stubs.UnresolvableJumpTarget import UnresolvableJumpTarget
37
+ from .. import Analysis, register_analysis
38
+ from ..cfg.cfg_base import CFGBase
39
+ from ..reaching_definitions import ReachingDefinitionsAnalysis
40
+ from .return_maker import ReturnMaker
41
+ from .ailgraph_walker import AILGraphWalker, RemoveNodeNotice
42
+ from .optimization_passes import (
43
+ get_default_optimization_passes,
44
+ OptimizationPassStage,
45
+ RegisterSaveAreaSimplifier,
46
+ StackCanarySimplifier,
47
+ SpilledRegisterFinder,
48
+ DUPLICATING_OPTS,
49
+ CONDENSING_OPTS,
50
+ )
51
+
52
+ if TYPE_CHECKING:
53
+ from angr.knowledge_plugins.cfg import CFGModel
54
+ from .decompilation_cache import DecompilationCache
55
+ from .peephole_optimizations import PeepholeOptimizationStmtBase, PeepholeOptimizationExprBase
56
+
57
+ l = logging.getLogger(name=__name__)
58
+
59
+
60
+ BlockCache = namedtuple("BlockCache", ("rd", "prop"))
61
+
62
+
63
+ class ClinicMode(enum.Enum):
64
+ """
65
+ Analysis mode for Clinic.
66
+ """
67
+
68
+ DECOMPILE = 1
69
+ COLLECT_DATA_REFS = 2
70
+
71
+
72
+ @dataclass
73
+ class DataRefDesc:
74
+ """
75
+ The fields of this class is compatible with items inside IRSB.data_refs.
76
+ """
77
+
78
+ data_addr: int
79
+ data_size: int
80
+ block_addr: int
81
+ stmt_idx: int
82
+ ins_addr: int
83
+ data_type_str: str
84
+
85
+
86
+ class Clinic(Analysis):
87
+ """
88
+ A Clinic deals with AILments.
89
+ """
90
+
91
+ def __init__(
92
+ self,
93
+ func,
94
+ remove_dead_memdefs=False,
95
+ exception_edges=False,
96
+ sp_tracker_track_memory=True,
97
+ fold_callexprs_into_conditions=False,
98
+ insert_labels=True,
99
+ optimization_passes=None,
100
+ cfg=None,
101
+ peephole_optimizations: None | (
102
+ Iterable[type[PeepholeOptimizationStmtBase] | type[PeepholeOptimizationExprBase]]
103
+ ) = None, # pylint:disable=line-too-long
104
+ must_struct: set[str] | None = None,
105
+ variable_kb=None,
106
+ reset_variable_names=False,
107
+ rewrite_ites_to_diamonds=True,
108
+ cache: DecompilationCache | None = None,
109
+ mode: ClinicMode = ClinicMode.DECOMPILE,
110
+ sp_shift: int = 0,
111
+ inline_functions: set[Function] | None = frozenset(),
112
+ inlined_counts: dict[int, int] | None = None,
113
+ inlining_parents: set[int] | None = None,
114
+ ):
115
+ if not func.normalized and mode == ClinicMode.DECOMPILE:
116
+ raise ValueError("Decompilation must work on normalized function graphs.")
117
+
118
+ self.function = func
119
+
120
+ self.graph = None
121
+ self.cc_graph: networkx.DiGraph | None = None
122
+ self.unoptimized_graph: networkx.DiGraph | None = None
123
+ self.arg_list = None
124
+ self.variable_kb = variable_kb
125
+ self.externs: set[SimMemoryVariable] = set()
126
+ self.data_refs: dict[int, int] = {} # data address to instruction address
127
+
128
+ self._func_graph: networkx.DiGraph | None = None
129
+ self._ail_manager = None
130
+ self._blocks_by_addr_and_size = {}
131
+
132
+ self._fold_callexprs_into_conditions = fold_callexprs_into_conditions
133
+ self._insert_labels = insert_labels
134
+ self._remove_dead_memdefs = remove_dead_memdefs
135
+ self._exception_edges = exception_edges
136
+ self._sp_tracker_track_memory = sp_tracker_track_memory
137
+ self._cfg: CFGModel | None = cfg
138
+ self.peephole_optimizations = peephole_optimizations
139
+ self._must_struct = must_struct
140
+ self._reset_variable_names = reset_variable_names
141
+ self._rewrite_ites_to_diamonds = rewrite_ites_to_diamonds
142
+ self.reaching_definitions: ReachingDefinitionsAnalysis | None = None
143
+ self._cache = cache
144
+ self._mode = mode
145
+
146
+ # inlining help
147
+ self._sp_shift = sp_shift
148
+ self._max_stack_depth = 0
149
+ self._inline_functions = inline_functions
150
+ self._inlined_counts = {} if inlined_counts is None else inlined_counts
151
+ self._inlining_parents = inlining_parents or ()
152
+
153
+ self._register_save_areas_removed: bool = False
154
+
155
+ self._new_block_addrs = set()
156
+
157
+ # sanity checks
158
+ if not self.kb.functions:
159
+ l.warning("No function is available in kb.functions. It will lead to a suboptimal conversion result.")
160
+
161
+ if optimization_passes is not None:
162
+ self._optimization_passes = optimization_passes
163
+ else:
164
+ self._optimization_passes = get_default_optimization_passes(self.project.arch, self.project.simos.name)
165
+ l.debug("Get %d optimization passes for the current binary.", len(self._optimization_passes))
166
+
167
+ if self._mode == ClinicMode.DECOMPILE:
168
+ self._analyze_for_decompiling()
169
+ elif self._mode == ClinicMode.COLLECT_DATA_REFS:
170
+ self._analyze_for_data_refs()
171
+ else:
172
+ raise TypeError(f"Unsupported analysis mode {self._mode}")
173
+
174
+ #
175
+ # Public methods
176
+ #
177
+
178
+ def block(self, addr, size):
179
+ """
180
+ Get the converted block at the given specific address with the given size.
181
+
182
+ :param int addr:
183
+ :param int size:
184
+ :return:
185
+ """
186
+
187
+ try:
188
+ return self._blocks_by_addr_and_size[(addr, size)]
189
+ except KeyError:
190
+ return None
191
+
192
+ def dbg_repr(self):
193
+ """
194
+
195
+ :return:
196
+ """
197
+
198
+ s = ""
199
+
200
+ for block in sorted(self.graph.nodes(), key=lambda x: x.addr):
201
+ s += str(block) + "\n\n"
202
+
203
+ return s
204
+
205
+ #
206
+ # Private methods
207
+ #
208
+
209
+ def _analyze_for_decompiling(self):
210
+ if not (ail_graph := self._decompilation_graph_recovery()):
211
+ return
212
+ ail_graph = self._decompilation_fixups(ail_graph)
213
+
214
+ if self._inline_functions:
215
+ self._max_stack_depth += self.calculate_stack_depth()
216
+ ail_graph = self._inline_child_functions(ail_graph)
217
+
218
+ ail_graph = self._decompilation_simplifications(ail_graph)
219
+ self.graph = ail_graph
220
+
221
+ def _decompilation_graph_recovery(self):
222
+ is_pcode_arch = ":" in self.project.arch.name
223
+
224
+ # Set up the function graph according to configurations
225
+ self._update_progress(0.0, text="Setting up function graph")
226
+ self._set_function_graph()
227
+
228
+ # Remove alignment blocks
229
+ self._update_progress(5.0, text="Removing alignment blocks")
230
+ self._remove_alignment_blocks()
231
+
232
+ # if the graph is empty, don't continue
233
+ if not self._func_graph:
234
+ return None
235
+
236
+ # Make sure calling conventions of all functions that the current function calls have been recovered
237
+ if not is_pcode_arch:
238
+ self._update_progress(10.0, text="Recovering calling conventions")
239
+ self._recover_calling_conventions()
240
+
241
+ # initialize the AIL conversion manager
242
+ self._ail_manager = ailment.Manager(arch=self.project.arch)
243
+
244
+ # Convert VEX blocks to AIL blocks and then simplify them
245
+
246
+ self._update_progress(20.0, text="Converting VEX to AIL")
247
+ self._convert_all()
248
+
249
+ return self._make_ailgraph()
250
+
251
+ def _decompilation_fixups(self, ail_graph):
252
+ is_pcode_arch = ":" in self.project.arch.name
253
+
254
+ if self._rewrite_ites_to_diamonds:
255
+ self._rewrite_ite_expressions(ail_graph)
256
+ self._remove_redundant_jump_blocks(ail_graph)
257
+ if self._insert_labels:
258
+ self._insert_block_labels(ail_graph)
259
+
260
+ # Run simplification passes
261
+ self._update_progress(22.0, text="Optimizing fresh ailment graph")
262
+ ail_graph = self._run_simplification_passes(ail_graph, OptimizationPassStage.AFTER_AIL_GRAPH_CREATION)
263
+
264
+ # Fix "fake" indirect jumps and calls
265
+ self._update_progress(25.0, text="Analyzing simple indirect jumps")
266
+ ail_graph = self._replace_single_target_indirect_transitions(ail_graph)
267
+
268
+ # Fix tail calls
269
+ self._update_progress(28.0, text="Analyzing tail calls")
270
+ ail_graph = self._replace_tail_jumps_with_calls(ail_graph)
271
+
272
+ if is_pcode_arch:
273
+ self._update_progress(29.0, text="Recovering calling conventions (AIL mode)")
274
+ self._recover_calling_conventions(func_graph=ail_graph)
275
+
276
+ return ail_graph
277
+
278
+ def _inline_child_functions(self, ail_graph):
279
+ for blk in ail_graph.nodes():
280
+ for idx, stmt in enumerate(blk.statements):
281
+ if isinstance(stmt, ailment.Stmt.Call) and isinstance(stmt.target, ailment.Expr.Const):
282
+ callee = self.function._function_manager.function(stmt.target.value)
283
+ if (
284
+ callee.addr == self.function.addr
285
+ or callee.addr in self._inlining_parents
286
+ or callee not in self._inline_functions
287
+ or callee.is_plt
288
+ or callee.is_simprocedure
289
+ ):
290
+ continue
291
+
292
+ ail_graph = self._inline_call(ail_graph, blk, idx, callee)
293
+ return ail_graph
294
+
295
+ def _inline_call(self, ail_graph, caller_block, call_idx, callee):
296
+ callee_clinic = self.project.analyses.Clinic(
297
+ callee,
298
+ mode=ClinicMode.DECOMPILE,
299
+ inline_functions=self._inline_functions,
300
+ inlining_parents=self._inlining_parents + (self.function.addr,),
301
+ inlined_counts=self._inlined_counts,
302
+ optimization_passes=[StackCanarySimplifier, SpilledRegisterFinder],
303
+ sp_shift=self._max_stack_depth,
304
+ )
305
+ self._max_stack_depth = callee_clinic._max_stack_depth
306
+ callee_graph = callee_clinic.copy_graph()
307
+
308
+ # uniquely mark all the blocks in case of duplicates (e.g., foo(); foo();)
309
+ self._inlined_counts.setdefault(callee.addr, 0)
310
+ for blk in callee_graph.nodes():
311
+ blk.idx = self._inlined_counts[callee.addr]
312
+ self._inlined_counts[callee.addr] += 1
313
+
314
+ # figure out where the callee should start at and return to
315
+ callee_start = next(n for n in callee_graph if n.addr == callee.addr)
316
+ caller_successors = list(ail_graph.out_edges(caller_block, data=True))
317
+ assert len(caller_successors) == 1
318
+ caller_successor = caller_successors[0][1]
319
+ ail_graph.remove_edge(caller_block, caller_successor)
320
+
321
+ # update all callee return nodes with caller successor
322
+ # and rewrite pseudoreg-tagged spills to actually use pseudoregs
323
+ ail_graph = networkx.union(ail_graph, callee_graph)
324
+ for blk in callee_graph.nodes():
325
+ for idx, stmt in enumerate(list(blk.statements)):
326
+ if isinstance(stmt, ailment.Stmt.Return):
327
+ blk.statements[idx] = ailment.Stmt.Jump(
328
+ None,
329
+ ailment.Expr.Const(None, None, caller_successor.addr, self.project.arch.bits),
330
+ caller_successor.idx,
331
+ **blk.statements[idx].tags,
332
+ )
333
+ blk.statements.pop(idx)
334
+ ail_graph.add_edge(blk, caller_successor)
335
+ break
336
+ if "pseudoreg" in stmt.tags and isinstance(stmt, ailment.Stmt.Store):
337
+ new_stmt = ailment.Stmt.Assignment(
338
+ stmt.idx, ailment.Expr.Register(None, None, stmt.pseudoreg, stmt.size * 8), stmt.data
339
+ )
340
+ new_stmt.tags.update(stmt.tags)
341
+ new_stmt.tags.pop("pseudoreg")
342
+ blk.statements[idx] = new_stmt
343
+ if "pseudoreg" in stmt.tags and isinstance(stmt, ailment.Stmt.Assignment):
344
+ new_stmt = ailment.Stmt.Assignment(
345
+ stmt.idx, stmt.dst, ailment.Expr.Register(None, None, stmt.pseudoreg, stmt.src.size * 8)
346
+ )
347
+ new_stmt.tags.update(stmt.tags)
348
+ new_stmt.tags.pop("pseudoreg")
349
+ blk.statements[idx] = new_stmt
350
+
351
+ # update the call edge
352
+ caller_block.statements[call_idx] = ailment.Stmt.Jump(
353
+ None,
354
+ ailment.Expr.Const(None, None, callee.addr, self.project.arch.bits),
355
+ callee_start.idx,
356
+ **caller_block.statements[call_idx].tags,
357
+ )
358
+ if (
359
+ isinstance(caller_block.statements[call_idx - 2], ailment.Stmt.Store)
360
+ and caller_block.statements[call_idx - 2].data.value == caller_successor.addr
361
+ ):
362
+ # don't push the return address
363
+ caller_block.statements.pop(call_idx - 5) # t6 = rsp<8>
364
+ caller_block.statements.pop(call_idx - 5) # t5 = (t6 - 0x8<64>)
365
+ caller_block.statements.pop(call_idx - 5) # rsp<8> = t5
366
+ caller_block.statements.pop(
367
+ call_idx - 5
368
+ ) # STORE(addr=t5, data=0x40121b<64>, size=8, endness=Iend_LE, guard=None)
369
+ caller_block.statements.pop(call_idx - 5) # t7 = (t5 - 0x80<64>) <- wtf is this??
370
+ elif (
371
+ isinstance(caller_block.statements[call_idx - 1], ailment.Stmt.Store)
372
+ and caller_block.statements[call_idx - 1].addr.base == "stack_base"
373
+ and caller_block.statements[call_idx - 1].data.value == caller_successor.addr
374
+ ):
375
+ caller_block.statements.pop(call_idx - 1) # s_10 =L 0x401225<64><8>
376
+ ail_graph.add_edge(caller_block, callee_start)
377
+
378
+ return ail_graph
379
+
380
+ def calculate_stack_depth(self):
381
+ # we need to reserve space for our own stack
382
+ spt = self._track_stack_pointers()
383
+ stack_offsets = spt.offsets_for(self.project.arch.sp_offset)
384
+ if max(stack_offsets) > 2 ** (self.project.arch.bits - 1):
385
+ # why is this unsigned...
386
+ depth = min(s for s in stack_offsets if s > 2 ** (self.project.arch.bits - 1)) - 2**self.project.arch.bits
387
+ else:
388
+ depth = min(stack_offsets)
389
+
390
+ if spt.inconsistent_for(self.project.arch.sp_offset):
391
+ l.warning("Inconsistency found during stack pointer tracking. Stack depth may be incorrect.")
392
+ depth -= 0x1000
393
+
394
+ return depth
395
+
396
+ def _decompilation_simplifications(self, ail_graph):
397
+ # Make returns
398
+ self._update_progress(30.0, text="Making return sites")
399
+ if self.function.prototype is None or not isinstance(self.function.prototype.returnty, SimTypeBottom):
400
+ ail_graph = self._make_returns(ail_graph)
401
+
402
+ # full-function constant-only propagation
403
+ self._update_progress(33.0, text="Constant propagation")
404
+ self._simplify_function(
405
+ ail_graph,
406
+ remove_dead_memdefs=False,
407
+ unify_variables=False,
408
+ narrow_expressions=False,
409
+ only_consts=True,
410
+ fold_callexprs_into_conditions=self._fold_callexprs_into_conditions,
411
+ max_iterations=1,
412
+ )
413
+
414
+ # cached block-level reaching definition analysis results and propagator results
415
+ block_simplification_cache: dict[ailment.Block, NamedTuple] | None = {}
416
+
417
+ # Track stack pointers
418
+ self._update_progress(15.0, text="Tracking stack pointers")
419
+ spt = self._track_stack_pointers()
420
+
421
+ # Simplify blocks
422
+ # we never remove dead memory definitions before making callsites. otherwise stack arguments may go missing
423
+ # before they are recognized as stack arguments.
424
+ self._update_progress(35.0, text="Simplifying blocks 1")
425
+ ail_graph = self._simplify_blocks(
426
+ ail_graph, stack_pointer_tracker=spt, remove_dead_memdefs=False, cache=block_simplification_cache
427
+ )
428
+ self._rewrite_alloca(ail_graph)
429
+
430
+ # Run simplification passes
431
+ self._update_progress(40.0, text="Running simplifications 1")
432
+ ail_graph = self._run_simplification_passes(
433
+ ail_graph, stage=OptimizationPassStage.AFTER_SINGLE_BLOCK_SIMPLIFICATION
434
+ )
435
+
436
+ # Simplify the entire function for the first time
437
+ self._update_progress(45.0, text="Simplifying function 1")
438
+ self._simplify_function(
439
+ ail_graph,
440
+ remove_dead_memdefs=False,
441
+ unify_variables=False,
442
+ narrow_expressions=True,
443
+ fold_callexprs_into_conditions=self._fold_callexprs_into_conditions,
444
+ )
445
+
446
+ # Run simplification passes again. there might be more chances for peephole optimizations after function-level
447
+ # simplification
448
+ self._update_progress(48.0, text="Simplifying blocks 2")
449
+ ail_graph = self._simplify_blocks(
450
+ ail_graph, stack_pointer_tracker=spt, remove_dead_memdefs=False, cache=block_simplification_cache
451
+ )
452
+
453
+ # clear _blocks_by_addr_and_size so no one can use it again
454
+ # TODO: Totally remove this dict
455
+ self._blocks_by_addr_and_size = None
456
+
457
+ # Make call-sites
458
+ self._update_progress(50.0, text="Making callsites")
459
+ _, stackarg_offsets = self._make_callsites(ail_graph, stack_pointer_tracker=spt)
460
+
461
+ # Run simplification passes
462
+ self._update_progress(53.0, text="Running simplifications 2")
463
+ ail_graph = self._run_simplification_passes(ail_graph, stage=OptimizationPassStage.AFTER_MAKING_CALLSITES)
464
+
465
+ # Simplify the entire function for the second time
466
+ self._update_progress(55.0, text="Simplifying function 2")
467
+ self._simplify_function(
468
+ ail_graph,
469
+ remove_dead_memdefs=self._remove_dead_memdefs,
470
+ stack_arg_offsets=stackarg_offsets,
471
+ unify_variables=True,
472
+ narrow_expressions=True,
473
+ fold_callexprs_into_conditions=self._fold_callexprs_into_conditions,
474
+ )
475
+
476
+ # After global optimization, there might be more chances for peephole optimizations.
477
+ # Simplify blocks for the second time
478
+ self._update_progress(60.0, text="Simplifying blocks 3")
479
+ ail_graph = self._simplify_blocks(
480
+ ail_graph,
481
+ remove_dead_memdefs=self._remove_dead_memdefs,
482
+ stack_pointer_tracker=spt,
483
+ cache=block_simplification_cache,
484
+ )
485
+
486
+ # Run simplification passes
487
+ self._update_progress(65.0, text="Running simplifications 3 ")
488
+ ail_graph = self._run_simplification_passes(ail_graph, stage=OptimizationPassStage.AFTER_GLOBAL_SIMPLIFICATION)
489
+
490
+ # Simplify the entire function for the third time
491
+ self._update_progress(70.0, text="Simplifying function 3")
492
+ self._simplify_function(
493
+ ail_graph,
494
+ remove_dead_memdefs=self._remove_dead_memdefs,
495
+ stack_arg_offsets=stackarg_offsets,
496
+ unify_variables=True,
497
+ narrow_expressions=True,
498
+ fold_callexprs_into_conditions=self._fold_callexprs_into_conditions,
499
+ )
500
+
501
+ self._update_progress(72.0, text="Simplifying blocks 4")
502
+ ail_graph = self._simplify_blocks(
503
+ ail_graph,
504
+ remove_dead_memdefs=self._remove_dead_memdefs,
505
+ stack_pointer_tracker=spt,
506
+ cache=block_simplification_cache,
507
+ )
508
+
509
+ # Make function arguments
510
+ self._update_progress(75.0, text="Making argument list")
511
+ arg_list = self._make_argument_list()
512
+
513
+ # Recover variables on AIL blocks
514
+ self._update_progress(80.0, text="Recovering variables")
515
+ variable_kb = self._recover_and_link_variables(ail_graph, arg_list)
516
+
517
+ # Make function prototype
518
+ self._update_progress(90.0, text="Making function prototype")
519
+ self._make_function_prototype(arg_list, variable_kb)
520
+
521
+ # Run simplification passes
522
+ self._update_progress(95.0, text="Running simplifications 4")
523
+ ail_graph = self._run_simplification_passes(
524
+ ail_graph, stage=OptimizationPassStage.AFTER_VARIABLE_RECOVERY, variable_kb=variable_kb
525
+ )
526
+
527
+ # remove empty nodes from the graph
528
+ ail_graph = self.remove_empty_nodes(ail_graph)
529
+
530
+ self.arg_list = arg_list
531
+ self.variable_kb = variable_kb
532
+ self.cc_graph = self.copy_graph(ail_graph)
533
+ self.externs = self._collect_externs(ail_graph, variable_kb)
534
+ return ail_graph
535
+
536
+ def _analyze_for_data_refs(self):
537
+ # Set up the function graph according to configurations
538
+ self._update_progress(0.0, text="Setting up function graph")
539
+ self._set_function_graph()
540
+
541
+ # Remove alignment blocks
542
+ self._update_progress(5.0, text="Removing alignment blocks")
543
+ self._remove_alignment_blocks()
544
+
545
+ # if the graph is empty, don't continue
546
+ if not self._func_graph:
547
+ return
548
+
549
+ # initialize the AIL conversion manager
550
+ self._ail_manager = ailment.Manager(arch=self.project.arch)
551
+
552
+ # Track stack pointers
553
+ self._update_progress(15.0, text="Tracking stack pointers")
554
+ spt = self._track_stack_pointers()
555
+
556
+ # Convert VEX blocks to AIL blocks and then simplify them
557
+
558
+ self._update_progress(20.0, text="Converting VEX to AIL")
559
+ self._convert_all()
560
+
561
+ # there must be at least one Load or one Store
562
+ found_load_or_store = False
563
+ for ail_block in self._blocks_by_addr_and_size.values():
564
+ for stmt in ail_block.statements:
565
+ if isinstance(stmt, ailment.Stmt.Store):
566
+ found_load_or_store = True
567
+ break
568
+ if isinstance(stmt, ailment.Stmt.Assignment) and isinstance(stmt.src, ailment.Expr.Load):
569
+ found_load_or_store = True
570
+ break
571
+ if not found_load_or_store:
572
+ self.data_refs = {}
573
+ return
574
+
575
+ ail_graph = self._make_ailgraph()
576
+ self._remove_redundant_jump_blocks(ail_graph)
577
+
578
+ # full-function constant-only propagation
579
+ self._update_progress(33.0, text="Constant propagation")
580
+ self._simplify_function(
581
+ ail_graph,
582
+ remove_dead_memdefs=False,
583
+ unify_variables=False,
584
+ narrow_expressions=False,
585
+ only_consts=True,
586
+ fold_callexprs_into_conditions=self._fold_callexprs_into_conditions,
587
+ max_iterations=1,
588
+ )
589
+
590
+ # cached block-level reaching definition analysis results and propagator results
591
+ block_simplification_cache: dict[ailment.Block, NamedTuple] | None = {}
592
+
593
+ # Simplify blocks
594
+ # we never remove dead memory definitions before making callsites. otherwise stack arguments may go missing
595
+ # before they are recognized as stack arguments.
596
+ self._update_progress(35.0, text="Simplifying blocks 1")
597
+ ail_graph = self._simplify_blocks(
598
+ ail_graph, stack_pointer_tracker=spt, remove_dead_memdefs=False, cache=block_simplification_cache
599
+ )
600
+
601
+ # Simplify the entire function for the first time
602
+ self._update_progress(45.0, text="Simplifying function 1")
603
+ self._simplify_function(
604
+ ail_graph,
605
+ remove_dead_memdefs=False,
606
+ unify_variables=False,
607
+ narrow_expressions=False,
608
+ fold_callexprs_into_conditions=False,
609
+ rewrite_ccalls=False,
610
+ max_iterations=1,
611
+ )
612
+
613
+ # clear _blocks_by_addr_and_size so no one can use it again
614
+ # TODO: Totally remove this dict
615
+ self._blocks_by_addr_and_size = None
616
+
617
+ self.graph = ail_graph
618
+ self.arg_list = None
619
+ self.variable_kb = None
620
+ self.cc_graph = None
621
+ self.externs = None
622
+ self.data_refs: dict[int, list[DataRefDesc]] = self._collect_data_refs(ail_graph)
623
+
624
+ @staticmethod
625
+ def _copy_graph(graph: networkx.DiGraph) -> networkx.DiGraph:
626
+ """
627
+ Copy AIL Graph.
628
+
629
+ :return: A copy of the AIl graph.
630
+ """
631
+ graph_copy = networkx.DiGraph()
632
+ block_mapping = {}
633
+ # copy all blocks
634
+ for block in graph.nodes():
635
+ new_block = copy.copy(block)
636
+ new_stmts = copy.copy(block.statements)
637
+ new_block.statements = new_stmts
638
+ block_mapping[block] = new_block
639
+ graph_copy.add_node(new_block)
640
+
641
+ # copy all edges
642
+ for src, dst, data in graph.edges(data=True):
643
+ new_src = block_mapping[src]
644
+ new_dst = block_mapping[dst]
645
+ graph_copy.add_edge(new_src, new_dst, **data)
646
+ return graph_copy
647
+
648
+ def copy_graph(self, graph=None) -> networkx.DiGraph:
649
+ return self._copy_graph(graph or self.graph)
650
+
651
+ @timethis
652
+ def _set_function_graph(self):
653
+ self._func_graph = self.function.graph_ex(exception_edges=self._exception_edges)
654
+
655
+ @timethis
656
+ def _remove_alignment_blocks(self):
657
+ """
658
+ Alignment blocks are basic blocks that only consist of nops. They should not be included in the graph.
659
+ """
660
+ for node in list(self._func_graph.nodes()):
661
+ if self._func_graph.in_degree(node) == 0 and CFGBase._is_noop_block(
662
+ self.project.arch, self.project.factory.block(node.addr, node.size)
663
+ ):
664
+ self._func_graph.remove_node(node)
665
+
666
+ @timethis
667
+ def _recover_calling_conventions(self, func_graph=None) -> None:
668
+ """
669
+ Examine the calling convention and function prototype for each function called. For functions with missing
670
+ calling conventions or function prototypes, analyze each *call site* and recover the calling convention and
671
+ function prototype of the callee function.
672
+
673
+ :return: None
674
+ """
675
+
676
+ for node in self.function.transition_graph:
677
+ if (
678
+ isinstance(node, BlockNode)
679
+ and node.addr != self.function.addr
680
+ and self.kb.functions.contains_addr(node.addr)
681
+ ):
682
+ # tail jumps
683
+ target_func = self.kb.functions.get_by_addr(node.addr)
684
+ elif isinstance(node, Function):
685
+ target_func = node
686
+ else:
687
+ continue
688
+
689
+ # case 0: the calling convention and prototype are available
690
+ if target_func.calling_convention is not None and target_func.prototype is not None:
691
+ continue
692
+
693
+ call_sites = []
694
+ for pred in self.function.transition_graph.predecessors(node):
695
+ call_sites.append(pred)
696
+ # case 1: calling conventions and prototypes are available at every single call site
697
+ if call_sites and all(self.kb.callsite_prototypes.has_prototype(callsite.addr) for callsite in call_sites):
698
+ continue
699
+
700
+ # case 2: the callee is a SimProcedure
701
+ if target_func.is_simprocedure:
702
+ cc = self.project.analyses.CallingConvention(target_func)
703
+ if cc.cc is not None and cc.prototype is not None:
704
+ target_func.calling_convention = cc.cc
705
+ target_func.prototype = cc.prototype
706
+ continue
707
+
708
+ # case 3: the callee is a PLT function
709
+ if target_func.is_plt:
710
+ cc = self.project.analyses.CallingConvention(target_func)
711
+ if cc.cc is not None and cc.prototype is not None:
712
+ target_func.calling_convention = cc.cc
713
+ target_func.prototype = cc.prototype
714
+ continue
715
+
716
+ # case 4: fall back to call site analysis
717
+ for callsite in call_sites:
718
+ if self.kb.callsite_prototypes.has_prototype(callsite.addr):
719
+ continue
720
+
721
+ # parse the call instruction address from the edge
722
+ callsite_ins_addr = None
723
+ edge_data = [
724
+ data
725
+ for src, dst, data in self.function.transition_graph.in_edges(node, data=True)
726
+ if src is callsite
727
+ ]
728
+ if len(edge_data) == 1:
729
+ callsite_ins_addr = edge_data[0].get("ins_addr", None)
730
+ if callsite_ins_addr is None:
731
+ # parse the block...
732
+ callsite_block = self.project.factory.block(callsite.addr, size=callsite.size)
733
+ if self.project.arch.branch_delay_slot:
734
+ if callsite_block.instructions < 2:
735
+ continue
736
+ callsite_ins_addr = callsite_block.instruction_addrs[-2]
737
+ else:
738
+ if callsite_block.instructions == 0:
739
+ continue
740
+ callsite_ins_addr = callsite_block.instruction_addrs[-1]
741
+
742
+ cc = self.project.analyses.CallingConvention(
743
+ None,
744
+ analyze_callsites=True,
745
+ caller_func_addr=self.function.addr,
746
+ callsite_block_addr=callsite.addr,
747
+ callsite_insn_addr=callsite_ins_addr,
748
+ func_graph=func_graph,
749
+ )
750
+
751
+ if cc.cc is not None and cc.prototype is not None:
752
+ self.kb.callsite_prototypes.set_prototype(callsite.addr, cc.cc, cc.prototype, manual=False)
753
+ if func_graph is not None and cc.prototype.returnty is not None:
754
+ # patch the AIL call statement if we can find one
755
+ callsite_ail_block: ailment.Block = next(
756
+ iter(bb for bb in func_graph if bb.addr == callsite.addr), None
757
+ )
758
+ if callsite_ail_block is not None and callsite_ail_block.statements:
759
+ last_stmt = callsite_ail_block.statements[-1]
760
+ if isinstance(last_stmt, ailment.Stmt.Call) and last_stmt.ret_expr is None:
761
+ if isinstance(cc.cc.RETURN_VAL, SimRegArg):
762
+ reg_offset, reg_size = self.project.arch.registers[cc.cc.RETURN_VAL.reg_name]
763
+ last_stmt.ret_expr = ailment.Expr.Register(
764
+ None,
765
+ None,
766
+ reg_offset,
767
+ reg_size * 8,
768
+ ins_addr=callsite_ins_addr,
769
+ reg_name=cc.cc.RETURN_VAL.reg_name,
770
+ )
771
+
772
+ # finally, recover the calling convention of the current function
773
+ if self.function.prototype is None or self.function.calling_convention is None:
774
+ self.project.analyses.CompleteCallingConventions(
775
+ recover_variables=True,
776
+ prioritize_func_addrs=[self.function.addr],
777
+ skip_other_funcs=True,
778
+ skip_signature_matched_functions=False,
779
+ func_graphs={self.function.addr: func_graph} if func_graph is not None else None,
780
+ )
781
+
782
+ @timethis
783
+ def _track_stack_pointers(self):
784
+ """
785
+ For each instruction, track its stack pointer offset and stack base pointer offset.
786
+
787
+ :return: None
788
+ """
789
+
790
+ regs = {self.project.arch.sp_offset}
791
+ initial_reg_values = {
792
+ self.project.arch.sp_offset: OffsetVal(
793
+ Register(self.project.arch.sp_offset, self.project.arch.bits), self._sp_shift
794
+ )
795
+ }
796
+ if hasattr(self.project.arch, "bp_offset") and self.project.arch.bp_offset is not None:
797
+ regs.add(self.project.arch.bp_offset)
798
+ initial_reg_values[self.project.arch.bp_offset] = OffsetVal(
799
+ Register(self.project.arch.bp_offset, self.project.arch.bits), self._sp_shift
800
+ )
801
+
802
+ regs |= self._find_regs_compared_against_sp(self._func_graph)
803
+
804
+ spt = self.project.analyses.StackPointerTracker(
805
+ self.function,
806
+ regs,
807
+ track_memory=self._sp_tracker_track_memory,
808
+ cross_insn_opt=False,
809
+ initial_reg_values=initial_reg_values,
810
+ )
811
+
812
+ if spt.inconsistent_for(self.project.arch.sp_offset):
813
+ l.warning("Inconsistency found during stack pointer tracking. Decompilation results might be incorrect.")
814
+ return spt
815
+
816
+ @timethis
817
+ def _convert_all(self):
818
+ """
819
+ Convert all VEX blocks in the function graph to AIL blocks, and fill self._blocks.
820
+
821
+ :return: None
822
+ """
823
+
824
+ for block_node in self._func_graph.nodes():
825
+ ail_block = self._convert(block_node)
826
+
827
+ if type(ail_block) is ailment.Block:
828
+ # remove constant pc assignments
829
+ ail_block.statements = [
830
+ stmt
831
+ for stmt in ail_block.statements
832
+ if not (
833
+ isinstance(stmt, ailment.Stmt.Assignment)
834
+ and isinstance(stmt.dst, ailment.Expr.Register)
835
+ and stmt.dst.reg_offset == self.project.arch.ip_offset
836
+ and isinstance(stmt.src, ailment.Expr.Const)
837
+ )
838
+ ]
839
+
840
+ self._blocks_by_addr_and_size[(block_node.addr, block_node.size)] = ail_block
841
+
842
+ def _convert(self, block_node):
843
+ """
844
+ Convert a VEX block to an AIL block.
845
+
846
+ :param block_node: A BlockNode instance.
847
+ :return: An converted AIL block.
848
+ :rtype: ailment.Block
849
+ """
850
+
851
+ if type(block_node) is not BlockNode:
852
+ return block_node
853
+
854
+ block = self.project.factory.block(block_node.addr, block_node.size, cross_insn_opt=False)
855
+ if block.vex.jumpkind not in {"Ijk_Call", "Ijk_Boring", "Ijk_Ret"} and not block.vex.jumpkind.startswith(
856
+ "Ijk_Sys"
857
+ ):
858
+ # we don't support lifting this block. use a dummy block instead
859
+ statements = [
860
+ ailment.Stmt.DirtyStatement(
861
+ self._ail_manager.next_atom(),
862
+ f"Unsupported jumpkind {block.vex.jumpkind} at address {block_node.addr}",
863
+ ins_addr=block_node.addr,
864
+ )
865
+ ]
866
+ ail_block = ailment.Block(block_node.addr, block_node.size, statements=statements)
867
+ return ail_block
868
+
869
+ ail_block = ailment.IRSBConverter.convert(block.vex, self._ail_manager)
870
+ return ail_block
871
+
872
+ @timethis
873
+ def _replace_single_target_indirect_transitions(self, ail_graph: networkx.DiGraph) -> networkx.DiGraph:
874
+ """
875
+ Remove single-target indirect jumps and calls and replace them with direct jumps or calls.
876
+ """
877
+ if self._cfg is None:
878
+ return ail_graph
879
+
880
+ for block in ail_graph.nodes():
881
+ if not block.statements:
882
+ continue
883
+ last_stmt = block.statements[-1]
884
+ if isinstance(last_stmt, ailment.Stmt.Call) and not isinstance(last_stmt.target, ailment.Expr.Const):
885
+ # indirect call
886
+ # consult CFG to see if this is a call with a single successor
887
+ node = self._cfg.get_any_node(block.addr)
888
+ if node is None:
889
+ continue
890
+ successors = self._cfg.get_successors(node, excluding_fakeret=True, jumpkind="Ijk_Call")
891
+ if len(successors) == 1 and not isinstance(
892
+ self.project.hooked_by(successors[0].addr), UnresolvableCallTarget
893
+ ):
894
+ # found a single successor - replace the last statement
895
+ new_last_stmt = last_stmt.copy()
896
+ new_last_stmt.target = ailment.Expr.Const(None, None, successors[0].addr, last_stmt.target.bits)
897
+ block.statements[-1] = new_last_stmt
898
+
899
+ elif isinstance(last_stmt, ailment.Stmt.Jump) and not isinstance(last_stmt.target, ailment.Expr.Const):
900
+ # indirect jump
901
+ # consult CFG to see if there is a jump with a single successor
902
+ node = self._cfg.get_any_node(block.addr)
903
+ if node is None:
904
+ continue
905
+ successors = self._cfg.get_successors(node, excluding_fakeret=True, jumpkind="Ijk_Boring")
906
+ if len(successors) == 1 and not isinstance(
907
+ self.project.hooked_by(successors[0].addr), UnresolvableJumpTarget
908
+ ):
909
+ # found a single successor - replace the last statement
910
+ new_last_stmt = last_stmt.copy()
911
+ new_last_stmt.target = ailment.Expr.Const(None, None, successors[0].addr, last_stmt.target.bits)
912
+ block.statements[-1] = new_last_stmt
913
+
914
+ return ail_graph
915
+
916
+ @timethis
917
+ def _replace_tail_jumps_with_calls(self, ail_graph: networkx.DiGraph) -> networkx.DiGraph:
918
+ """
919
+ Replace tail jumps them with a return statement and a call expression.
920
+ """
921
+ for block in list(ail_graph.nodes()):
922
+ out_degree = ail_graph.out_degree[block]
923
+
924
+ if out_degree != 0:
925
+ continue
926
+
927
+ last_stmt = block.statements[-1]
928
+ if isinstance(last_stmt, ailment.Stmt.Jump):
929
+ # jumping to somewhere outside the current function
930
+ # rewrite it as a call *if and only if* the target is identified as a function
931
+ target = last_stmt.target
932
+ if isinstance(target, ailment.Const):
933
+ target_addr = target.value
934
+ if self.kb.functions.contains_addr(target_addr):
935
+ # replace the statement
936
+ target_func = self.kb.functions.get_by_addr(target_addr)
937
+ if target_func.returning:
938
+ ret_reg_offset = self.project.arch.ret_offset
939
+ ret_expr = ailment.Expr.Register(
940
+ None,
941
+ None,
942
+ ret_reg_offset,
943
+ self.project.arch.bits,
944
+ reg_name=self.project.arch.translate_register_name(
945
+ ret_reg_offset, size=self.project.arch.bits
946
+ ),
947
+ )
948
+ call_stmt = ailment.Stmt.Call(
949
+ None,
950
+ target,
951
+ calling_convention=None, # target_func.calling_convention,
952
+ prototype=None, # target_func.prototype,
953
+ ret_expr=ret_expr,
954
+ **last_stmt.tags,
955
+ )
956
+ block.statements[-1] = call_stmt
957
+
958
+ ret_stmt = ailment.Stmt.Return(None, [], **last_stmt.tags)
959
+ ret_block = ailment.Block(self.new_block_addr(), 1, statements=[ret_stmt])
960
+ ail_graph.add_edge(block, ret_block, type="fake_return")
961
+ else:
962
+ stmt = ailment.Stmt.Call(None, target, **last_stmt.tags)
963
+ block.statements[-1] = stmt
964
+
965
+ return ail_graph
966
+
967
+ @timethis
968
+ def _make_ailgraph(self) -> networkx.DiGraph:
969
+ graph = self._function_graph_to_ail_graph(self._func_graph)
970
+ return graph
971
+
972
+ @timethis
973
+ def _simplify_blocks(
974
+ self,
975
+ ail_graph: networkx.DiGraph,
976
+ remove_dead_memdefs=False,
977
+ stack_pointer_tracker=None,
978
+ cache: dict[ailment.Block, NamedTuple] | None = None,
979
+ ):
980
+ """
981
+ Simplify all blocks in self._blocks.
982
+
983
+ :param ail_graph: The AIL function graph.
984
+ :param stack_pointer_tracker: The RegisterDeltaTracker analysis instance.
985
+ :param cache: A block-level cache that stores reaching definition analysis results and
986
+ propagation results.
987
+ :return: None
988
+ """
989
+
990
+ blocks_by_addr_and_idx: dict[tuple[int, int | None], ailment.Block] = {}
991
+
992
+ for ail_block in ail_graph.nodes():
993
+ simplified = self._simplify_block(
994
+ ail_block,
995
+ remove_dead_memdefs=remove_dead_memdefs,
996
+ stack_pointer_tracker=stack_pointer_tracker,
997
+ cache=cache,
998
+ )
999
+ key = ail_block.addr, ail_block.idx
1000
+ blocks_by_addr_and_idx[key] = simplified
1001
+
1002
+ # update blocks_map to allow node_addr to node lookup
1003
+ def _replace_node_handler(node):
1004
+ key = node.addr, node.idx
1005
+ if key in blocks_by_addr_and_idx:
1006
+ return blocks_by_addr_and_idx[key]
1007
+ return None
1008
+
1009
+ AILGraphWalker(ail_graph, _replace_node_handler, replace_nodes=True).walk()
1010
+
1011
+ return ail_graph
1012
+
1013
+ def _simplify_block(self, ail_block, remove_dead_memdefs=False, stack_pointer_tracker=None, cache=None):
1014
+ """
1015
+ Simplify a single AIL block.
1016
+
1017
+ :param ailment.Block ail_block: The AIL block to simplify.
1018
+ :param stack_pointer_tracker: The RegisterDeltaTracker analysis instance.
1019
+ :return: A simplified AIL block.
1020
+ """
1021
+
1022
+ cached_rd, cached_prop = None, None
1023
+ cache_item = None
1024
+ if cache:
1025
+ cache_item = cache.get(ail_block, None)
1026
+ if cache_item:
1027
+ # cache hit
1028
+ cached_rd = cache_item.rd
1029
+ cached_prop = cache_item.prop
1030
+
1031
+ simp = self.project.analyses.AILBlockSimplifier(
1032
+ ail_block,
1033
+ self.function.addr,
1034
+ remove_dead_memdefs=remove_dead_memdefs,
1035
+ stack_pointer_tracker=stack_pointer_tracker,
1036
+ peephole_optimizations=self.peephole_optimizations,
1037
+ cached_reaching_definitions=cached_rd,
1038
+ cached_propagator=cached_prop,
1039
+ )
1040
+ # update the cache
1041
+ if cache is not None:
1042
+ if cache_item:
1043
+ del cache[ail_block]
1044
+ cache[simp.result_block] = BlockCache(simp._reaching_definitions, simp._propagator)
1045
+ return simp.result_block
1046
+
1047
+ @timethis
1048
+ def _simplify_function(
1049
+ self,
1050
+ ail_graph,
1051
+ remove_dead_memdefs=False,
1052
+ stack_arg_offsets=None,
1053
+ unify_variables=False,
1054
+ max_iterations: int = 8,
1055
+ narrow_expressions=False,
1056
+ only_consts=False,
1057
+ fold_callexprs_into_conditions=False,
1058
+ rewrite_ccalls=True,
1059
+ ) -> None:
1060
+ """
1061
+ Simplify the entire function until it reaches a fixed point.
1062
+ """
1063
+
1064
+ for idx in range(max_iterations):
1065
+ simplified = self._simplify_function_once(
1066
+ ail_graph,
1067
+ remove_dead_memdefs=remove_dead_memdefs,
1068
+ unify_variables=unify_variables,
1069
+ stack_arg_offsets=stack_arg_offsets,
1070
+ # only narrow once
1071
+ narrow_expressions=narrow_expressions and idx == 0,
1072
+ only_consts=only_consts,
1073
+ fold_callexprs_into_conditions=fold_callexprs_into_conditions,
1074
+ rewrite_ccalls=rewrite_ccalls,
1075
+ )
1076
+ if not simplified:
1077
+ break
1078
+
1079
+ @timethis
1080
+ def _simplify_function_once(
1081
+ self,
1082
+ ail_graph,
1083
+ remove_dead_memdefs=False,
1084
+ stack_arg_offsets=None,
1085
+ unify_variables=False,
1086
+ narrow_expressions=False,
1087
+ only_consts=False,
1088
+ fold_callexprs_into_conditions=False,
1089
+ rewrite_ccalls=True,
1090
+ ):
1091
+ """
1092
+ Simplify the entire function once.
1093
+
1094
+ :return: None
1095
+ """
1096
+
1097
+ simp = self.project.analyses.AILSimplifier(
1098
+ self.function,
1099
+ func_graph=ail_graph,
1100
+ remove_dead_memdefs=remove_dead_memdefs,
1101
+ unify_variables=unify_variables,
1102
+ stack_arg_offsets=stack_arg_offsets,
1103
+ ail_manager=self._ail_manager,
1104
+ gp=self.function.info.get("gp", None) if self.project.arch.name in {"MIPS32", "MIPS64"} else None,
1105
+ narrow_expressions=narrow_expressions,
1106
+ only_consts=only_consts,
1107
+ fold_callexprs_into_conditions=fold_callexprs_into_conditions,
1108
+ use_callee_saved_regs_at_return=not self._register_save_areas_removed,
1109
+ rewrite_ccalls=rewrite_ccalls,
1110
+ )
1111
+ # cache the simplifier's RDA analysis
1112
+ self.reaching_definitions = simp._reaching_definitions
1113
+
1114
+ # the function graph has been updated at this point
1115
+ return simp.simplified
1116
+
1117
+ @timethis
1118
+ def _run_simplification_passes(
1119
+ self,
1120
+ ail_graph,
1121
+ stage: OptimizationPassStage = OptimizationPassStage.AFTER_GLOBAL_SIMPLIFICATION,
1122
+ variable_kb=None,
1123
+ **kwargs,
1124
+ ):
1125
+ addr_and_idx_to_blocks: dict[tuple[int, int | None], ailment.Block] = {}
1126
+ addr_to_blocks: dict[int, set[ailment.Block]] = defaultdict(set)
1127
+
1128
+ # update blocks_map to allow node_addr to node lookup
1129
+ def _updatedict_handler(node):
1130
+ addr_and_idx_to_blocks[(node.addr, node.idx)] = node
1131
+ addr_to_blocks[node.addr].add(node)
1132
+
1133
+ AILGraphWalker(ail_graph, _updatedict_handler).walk()
1134
+
1135
+ # Run each pass
1136
+ for pass_ in self._optimization_passes:
1137
+ if pass_.STAGE != stage:
1138
+ continue
1139
+
1140
+ if pass_ in DUPLICATING_OPTS + CONDENSING_OPTS and self.unoptimized_graph is None:
1141
+ # we should save a copy at the first time any optimization that could alter the structure
1142
+ # of the graph is applied
1143
+ self.unoptimized_graph = self._copy_graph(ail_graph)
1144
+
1145
+ a = pass_(
1146
+ self.function,
1147
+ blocks_by_addr=addr_to_blocks,
1148
+ blocks_by_addr_and_idx=addr_and_idx_to_blocks,
1149
+ graph=ail_graph,
1150
+ variable_kb=variable_kb,
1151
+ **kwargs,
1152
+ )
1153
+ if a.out_graph:
1154
+ # use the new graph
1155
+ ail_graph = a.out_graph
1156
+ if isinstance(a, RegisterSaveAreaSimplifier):
1157
+ # register save area has been removed - we should no longer use callee-saved registers in RDA
1158
+ self._register_save_areas_removed = True
1159
+ # clear the cached RDA result
1160
+ self.reaching_definitions = None
1161
+
1162
+ return ail_graph
1163
+
1164
+ @timethis
1165
+ def _make_argument_list(self) -> list[SimVariable]:
1166
+ if self.function.calling_convention is not None and self.function.prototype is not None:
1167
+ args: list[SimFunctionArgument] = self.function.calling_convention.arg_locs(self.function.prototype)
1168
+ arg_vars: list[SimVariable] = []
1169
+ if args:
1170
+ arg_names = self.function.prototype.arg_names or [f"a{i}" for i in range(len(args))]
1171
+ for idx, arg in enumerate(args):
1172
+ if isinstance(arg, SimRegArg):
1173
+ argvar = SimRegisterVariable(
1174
+ self.project.arch.registers[arg.reg_name][0],
1175
+ arg.size,
1176
+ ident="arg_%d" % idx,
1177
+ name=arg_names[idx],
1178
+ region=self.function.addr,
1179
+ )
1180
+ elif isinstance(arg, SimStackArg):
1181
+ argvar = SimStackVariable(
1182
+ arg.stack_offset,
1183
+ arg.size,
1184
+ base="bp",
1185
+ ident="arg_%d" % idx,
1186
+ name=arg_names[idx],
1187
+ region=self.function.addr,
1188
+ )
1189
+ elif isinstance(arg, SimStructArg):
1190
+ argvar = SimVariable(
1191
+ ident="arg_%d" % idx,
1192
+ name=arg_names[idx],
1193
+ region=self.function.addr,
1194
+ size=arg.size,
1195
+ )
1196
+ else:
1197
+ raise TypeError("Unsupported function argument type %s." % type(arg))
1198
+ arg_vars.append(argvar)
1199
+ return arg_vars
1200
+ return []
1201
+
1202
+ @timethis
1203
+ def _make_callsites(self, ail_graph, stack_pointer_tracker=None):
1204
+ """
1205
+ Simplify all function call statements.
1206
+
1207
+ :return: None
1208
+ """
1209
+
1210
+ # Computing reaching definitions
1211
+ rd = self.project.analyses.ReachingDefinitions(
1212
+ subject=self.function,
1213
+ func_graph=ail_graph,
1214
+ observe_callback=self._make_callsites_rd_observe_callback,
1215
+ use_callee_saved_regs_at_return=not self._register_save_areas_removed,
1216
+ )
1217
+
1218
+ class TempClass: # pylint:disable=missing-class-docstring
1219
+ stack_arg_offsets = set()
1220
+
1221
+ def _handler(block):
1222
+ csm = self.project.analyses.AILCallSiteMaker(
1223
+ block,
1224
+ reaching_definitions=rd,
1225
+ stack_pointer_tracker=stack_pointer_tracker,
1226
+ ail_manager=self._ail_manager,
1227
+ )
1228
+ if csm.stack_arg_offsets is not None:
1229
+ TempClass.stack_arg_offsets |= csm.stack_arg_offsets
1230
+ if csm.result_block:
1231
+ if csm.result_block != block:
1232
+ ail_block = csm.result_block
1233
+ simp = self.project.analyses.AILBlockSimplifier(
1234
+ ail_block,
1235
+ self.function.addr,
1236
+ stack_pointer_tracker=stack_pointer_tracker,
1237
+ peephole_optimizations=self.peephole_optimizations,
1238
+ stack_arg_offsets=csm.stack_arg_offsets,
1239
+ )
1240
+ return simp.result_block
1241
+ return None
1242
+
1243
+ # rewriting call-sites at this point, pre-inlining, causes issues with incorrect call signatures
1244
+ if not self._inlining_parents:
1245
+ AILGraphWalker(ail_graph, _handler, replace_nodes=True).walk()
1246
+
1247
+ return ail_graph, TempClass.stack_arg_offsets
1248
+
1249
+ @timethis
1250
+ def _make_returns(self, ail_graph: networkx.DiGraph) -> networkx.DiGraph:
1251
+ """
1252
+ Work on each return statement and fill in its return expressions.
1253
+ """
1254
+ if self._inlining_parents:
1255
+ # for inlining, we want to keep the return statement separate from the return value, so that
1256
+ # the former can be removed while preserving the latter
1257
+ return ail_graph
1258
+
1259
+ if self.function.calling_convention is None:
1260
+ # unknown calling convention. cannot do much about return expressions.
1261
+ return ail_graph
1262
+
1263
+ ReturnMaker(self._ail_manager, self.project.arch, self.function, ail_graph)
1264
+
1265
+ return ail_graph
1266
+
1267
+ @timethis
1268
+ def _make_function_prototype(self, arg_list: list[SimVariable], variable_kb):
1269
+ if self.function.prototype is not None:
1270
+ if not self.function.is_prototype_guessed:
1271
+ # do not overwrite an existing function prototype
1272
+ # if you want to re-generate the prototype, clear the existing one first
1273
+ return
1274
+ if isinstance(self.function.prototype.returnty, SimTypeFloat) or any(
1275
+ isinstance(arg, SimTypeFloat) for arg in self.function.prototype.args
1276
+ ):
1277
+ # Type inference does not yet support floating point variables, but calling convention analysis does
1278
+ # FIXME: remove this branch once type inference supports floating point variables
1279
+ return
1280
+
1281
+ variables = variable_kb.variables[self.function.addr]
1282
+ func_args = []
1283
+ for arg in arg_list:
1284
+ func_arg = None
1285
+ arg_ty = variables.get_variable_type(arg)
1286
+ if arg_ty is None:
1287
+ # determine type based on size
1288
+ if isinstance(arg, (SimRegisterVariable, SimStackVariable)):
1289
+ if arg.size == 1:
1290
+ func_arg = SimTypeChar()
1291
+ elif arg.size == 2:
1292
+ func_arg = SimTypeShort()
1293
+ elif arg.size == 4:
1294
+ func_arg = SimTypeInt()
1295
+ elif arg.size == 8:
1296
+ func_arg = SimTypeLongLong()
1297
+ else:
1298
+ l.warning("Unsupported argument size %d.", arg.size)
1299
+ else:
1300
+ func_arg = arg_ty
1301
+
1302
+ func_args.append(func_arg)
1303
+
1304
+ if self.function.prototype is not None and self.function.prototype.returnty is not None:
1305
+ returnty = self.function.prototype.returnty
1306
+ else:
1307
+ returnty = SimTypeInt()
1308
+
1309
+ self.function.prototype = SimTypeFunction(func_args, returnty).with_arch(self.project.arch)
1310
+ self.function.is_prototype_guessed = False
1311
+
1312
+ @timethis
1313
+ def _recover_and_link_variables(self, ail_graph, arg_list):
1314
+ # variable recovery
1315
+ tmp_kb = KnowledgeBase(self.project) if self.variable_kb is None else self.variable_kb
1316
+ tmp_kb.functions = self.kb.functions
1317
+ vr = self.project.analyses.VariableRecoveryFast(
1318
+ self.function, # pylint:disable=unused-variable
1319
+ func_graph=ail_graph,
1320
+ kb=tmp_kb,
1321
+ track_sp=False,
1322
+ func_args=arg_list,
1323
+ unify_variables=False,
1324
+ )
1325
+ # get ground-truth types
1326
+ var_manager = tmp_kb.variables[self.function.addr]
1327
+ groundtruth = {}
1328
+ for variable in var_manager.variables_with_manual_types:
1329
+ vartype = var_manager.variable_to_types.get(variable, None)
1330
+ if vartype is not None:
1331
+ for tv in vr.var_to_typevars[variable]:
1332
+ groundtruth[tv] = vartype
1333
+ # clean up existing types for this function
1334
+ var_manager.remove_types()
1335
+ # TODO: Type inference for global variables
1336
+ # run type inference
1337
+ if self._must_struct:
1338
+ must_struct = set()
1339
+ for var, typevars in vr.var_to_typevars.items():
1340
+ if var.ident in self._must_struct:
1341
+ must_struct |= typevars
1342
+ else:
1343
+ must_struct = None
1344
+ try:
1345
+ tp = self.project.analyses.Typehoon(
1346
+ vr.type_constraints,
1347
+ vr.func_typevar,
1348
+ kb=tmp_kb,
1349
+ var_mapping=vr.var_to_typevars,
1350
+ must_struct=must_struct,
1351
+ ground_truth=groundtruth,
1352
+ )
1353
+ # tp.pp_constraints()
1354
+ # tp.pp_solution()
1355
+ tp.update_variable_types(
1356
+ self.function.addr,
1357
+ {v: t for v, t in vr.var_to_typevars.items() if isinstance(v, (SimRegisterVariable, SimStackVariable))},
1358
+ )
1359
+ tp.update_variable_types(
1360
+ "global",
1361
+ {
1362
+ v: t
1363
+ for v, t in vr.var_to_typevars.items()
1364
+ if isinstance(v, SimMemoryVariable) and not isinstance(v, SimStackVariable)
1365
+ },
1366
+ )
1367
+ except Exception: # pylint:disable=broad-except
1368
+ l.warning(
1369
+ "Typehoon analysis failed. Variables will not have types. Please report to GitHub.", exc_info=True
1370
+ )
1371
+
1372
+ # for any left-over variables, assign Bottom type (which will get "corrected" into a default type in
1373
+ # VariableManager)
1374
+ bottype = SimTypeBottom().with_arch(self.project.arch)
1375
+ for var in var_manager._variables:
1376
+ if var not in var_manager.variable_to_types:
1377
+ var_manager.set_variable_type(var, bottype)
1378
+
1379
+ # Unify SSA variables
1380
+ tmp_kb.variables.global_manager.assign_variable_names(labels=self.kb.labels, types={SimMemoryVariable})
1381
+ var_manager.unify_variables()
1382
+ var_manager.assign_unified_variable_names(
1383
+ labels=self.kb.labels,
1384
+ arg_names=self.function.prototype.arg_names if self.function.prototype else None,
1385
+ reset=self._reset_variable_names,
1386
+ )
1387
+
1388
+ # Link variables to each statement
1389
+ for block in ail_graph.nodes():
1390
+ self._link_variables_on_block(block, tmp_kb)
1391
+
1392
+ if self._cache is not None:
1393
+ self._cache.type_constraints = vr.type_constraints
1394
+ self._cache.func_typevar = vr.func_typevar
1395
+ self._cache.var_to_typevar = vr.var_to_typevars
1396
+
1397
+ return tmp_kb
1398
+
1399
+ def _link_variables_on_block(self, block, kb):
1400
+ """
1401
+ Link atoms (AIL expressions) in the given block to corresponding variables identified previously.
1402
+
1403
+ :param ailment.Block block: The AIL block to work on.
1404
+ :return: None
1405
+ """
1406
+
1407
+ variable_manager = kb.variables[self.function.addr]
1408
+ global_variables = kb.variables["global"]
1409
+
1410
+ for stmt_idx, stmt in enumerate(block.statements):
1411
+ stmt_type = type(stmt)
1412
+ if stmt_type is ailment.Stmt.Store:
1413
+ # find a memory variable
1414
+ mem_vars = variable_manager.find_variables_by_atom(block.addr, stmt_idx, stmt, block_idx=block.idx)
1415
+ if len(mem_vars) == 1:
1416
+ stmt.variable, stmt.offset = next(iter(mem_vars))
1417
+ else:
1418
+ # check if the dest address is a variable
1419
+ stmt: ailment.Stmt.Store
1420
+ # special handling for constant addresses
1421
+ if isinstance(stmt.addr, ailment.Expr.Const):
1422
+ # global variable?
1423
+ variables = global_variables.get_global_variables(stmt.addr.value)
1424
+ if variables:
1425
+ var = next(iter(variables))
1426
+ stmt.variable = var
1427
+ stmt.offset = 0
1428
+ else:
1429
+ self._link_variables_on_expr(
1430
+ variable_manager, global_variables, block, stmt_idx, stmt, stmt.addr
1431
+ )
1432
+ self._link_variables_on_expr(variable_manager, global_variables, block, stmt_idx, stmt, stmt.data)
1433
+
1434
+ elif stmt_type is ailment.Stmt.Assignment:
1435
+ self._link_variables_on_expr(variable_manager, global_variables, block, stmt_idx, stmt, stmt.dst)
1436
+ self._link_variables_on_expr(variable_manager, global_variables, block, stmt_idx, stmt, stmt.src)
1437
+
1438
+ elif stmt_type is ailment.Stmt.ConditionalJump:
1439
+ self._link_variables_on_expr(variable_manager, global_variables, block, stmt_idx, stmt, stmt.condition)
1440
+
1441
+ elif stmt_type is ailment.Stmt.Call:
1442
+ self._link_variables_on_call(variable_manager, global_variables, block, stmt_idx, stmt, is_expr=False)
1443
+
1444
+ elif stmt_type is ailment.Stmt.Return:
1445
+ self._link_variables_on_return(variable_manager, global_variables, block, stmt_idx, stmt)
1446
+
1447
+ def _link_variables_on_return(
1448
+ self, variable_manager, global_variables, block: ailment.Block, stmt_idx: int, stmt: ailment.Stmt.Return
1449
+ ):
1450
+ if stmt.ret_exprs:
1451
+ for ret_expr in stmt.ret_exprs:
1452
+ self._link_variables_on_expr(variable_manager, global_variables, block, stmt_idx, stmt, ret_expr)
1453
+
1454
+ def _link_variables_on_call(self, variable_manager, global_variables, block, stmt_idx, stmt, is_expr=False):
1455
+ if not isinstance(stmt.target, ailment.Expr.Const):
1456
+ self._link_variables_on_expr(variable_manager, global_variables, block, stmt_idx, stmt, stmt.target)
1457
+ if stmt.args:
1458
+ for arg in stmt.args:
1459
+ self._link_variables_on_expr(variable_manager, global_variables, block, stmt_idx, stmt, arg)
1460
+ if not is_expr and stmt.ret_expr:
1461
+ self._link_variables_on_expr(variable_manager, global_variables, block, stmt_idx, stmt, stmt.ret_expr)
1462
+
1463
+ def _link_variables_on_expr(self, variable_manager, global_variables, block, stmt_idx, stmt, expr):
1464
+ """
1465
+ Link atoms (AIL expressions) in the given expression to corresponding variables identified previously.
1466
+
1467
+ :param variable_manager: Variable manager of the function.
1468
+ :param ailment.Block block: AIL block.
1469
+ :param int stmt_idx: ID of the statement.
1470
+ :param stmt: The AIL statement that `expr` belongs to.
1471
+ :param expr: The AIl expression to work on.
1472
+ :return: None
1473
+ """
1474
+
1475
+ if type(expr) is ailment.Expr.Register:
1476
+ # find a register variable
1477
+ reg_vars = variable_manager.find_variables_by_atom(block.addr, stmt_idx, expr, block_idx=block.idx)
1478
+ final_reg_vars = set()
1479
+ if len(reg_vars) > 1:
1480
+ # take phi variables
1481
+ for reg_var in reg_vars:
1482
+ if variable_manager.is_phi_variable(reg_var[0]):
1483
+ final_reg_vars.add(reg_var)
1484
+ else:
1485
+ final_reg_vars = reg_vars
1486
+ if len(final_reg_vars) >= 1:
1487
+ reg_var, offset = next(iter(final_reg_vars))
1488
+ expr.variable = reg_var
1489
+ expr.variable_offset = offset
1490
+
1491
+ elif type(expr) is ailment.Expr.Load:
1492
+ variables = variable_manager.find_variables_by_atom(block.addr, stmt_idx, expr, block_idx=block.idx)
1493
+ if len(variables) == 0:
1494
+ # if it's a constant addr, maybe it's referencing an extern location
1495
+ base_addr, offset = self.parse_variable_addr(expr.addr)
1496
+ if offset is not None and isinstance(offset, ailment.Expr.Expression):
1497
+ self._link_variables_on_expr(variable_manager, global_variables, block, stmt_idx, stmt, offset)
1498
+ if base_addr is not None:
1499
+ self._link_variables_on_expr(variable_manager, global_variables, block, stmt_idx, stmt, base_addr)
1500
+
1501
+ # if we are accessing the variable directly (offset == 0), we link the variable onto this expression
1502
+ if offset == 0 or (isinstance(offset, ailment.Expr.Const) and offset.value == 0):
1503
+ if "reference_variable" in base_addr.tags:
1504
+ expr.variable = base_addr.reference_variable
1505
+ expr.variable_offset = base_addr.reference_variable_offset
1506
+
1507
+ if base_addr is None and offset is None:
1508
+ # this is a local variable
1509
+ self._link_variables_on_expr(variable_manager, global_variables, block, stmt_idx, stmt, expr.addr)
1510
+ if "reference_variable" in expr.addr.tags and expr.addr.reference_variable is not None:
1511
+ # copy over the variable to this expr since the variable on a constant is supposed to be a
1512
+ # reference variable.
1513
+ expr.variable = expr.addr.reference_variable
1514
+ expr.variable_offset = expr.addr.reference_variable_offset
1515
+ else:
1516
+ if len(variables) > 1:
1517
+ l.error(
1518
+ "More than one variable are available for atom %s. Consider fixing it using phi nodes.", expr
1519
+ )
1520
+ var, offset = next(iter(variables))
1521
+ expr.variable = var
1522
+ expr.variable_offset = offset
1523
+
1524
+ elif type(expr) is ailment.Expr.BinaryOp:
1525
+ variables = variable_manager.find_variables_by_atom(block.addr, stmt_idx, expr, block_idx=block.idx)
1526
+ if len(variables) >= 1:
1527
+ var, offset = next(iter(variables))
1528
+ expr.variable = var
1529
+ expr.variable_offset = offset
1530
+ else:
1531
+ self._link_variables_on_expr(
1532
+ variable_manager, global_variables, block, stmt_idx, stmt, expr.operands[0]
1533
+ )
1534
+ self._link_variables_on_expr(
1535
+ variable_manager, global_variables, block, stmt_idx, stmt, expr.operands[1]
1536
+ )
1537
+
1538
+ elif type(expr) is ailment.Expr.UnaryOp:
1539
+ variables = variable_manager.find_variables_by_atom(block.addr, stmt_idx, expr, block_idx=block.idx)
1540
+ if len(variables) >= 1:
1541
+ var, offset = next(iter(variables))
1542
+ expr.variable = var
1543
+ expr.variable_offset = offset
1544
+ else:
1545
+ self._link_variables_on_expr(variable_manager, global_variables, block, stmt_idx, stmt, expr.operand)
1546
+
1547
+ elif type(expr) is ailment.Expr.Convert:
1548
+ self._link_variables_on_expr(variable_manager, global_variables, block, stmt_idx, stmt, expr.operand)
1549
+
1550
+ elif type(expr) is ailment.Expr.ITE:
1551
+ variables = variable_manager.find_variables_by_atom(block.addr, stmt_idx, expr, block_idx=block.idx)
1552
+ if len(variables) >= 1:
1553
+ var, offset = next(iter(variables))
1554
+ expr.variable = var
1555
+ expr.variable_offset = offset
1556
+ else:
1557
+ self._link_variables_on_expr(variable_manager, global_variables, block, stmt_idx, stmt, expr.cond)
1558
+ self._link_variables_on_expr(variable_manager, global_variables, block, stmt_idx, stmt, expr.iftrue)
1559
+ self._link_variables_on_expr(variable_manager, global_variables, block, stmt_idx, stmt, expr.iffalse)
1560
+
1561
+ elif isinstance(expr, ailment.Expr.BasePointerOffset):
1562
+ variables = variable_manager.find_variables_by_atom(block.addr, stmt_idx, expr, block_idx=block.idx)
1563
+ if len(variables) >= 1:
1564
+ var, offset = next(iter(variables))
1565
+ expr.variable = var
1566
+ expr.variable_offset = offset
1567
+
1568
+ elif isinstance(expr, ailment.Expr.Const):
1569
+ # custom string?
1570
+ if hasattr(expr, "custom_string") and expr.custom_string is True:
1571
+ s = self.kb.custom_strings[expr.value]
1572
+ expr.tags["reference_values"] = {
1573
+ SimTypePointer(SimTypeChar().with_arch(self.project.arch)).with_arch(self.project.arch): s.decode(
1574
+ "ascii"
1575
+ ),
1576
+ }
1577
+ else:
1578
+ # global variable?
1579
+ global_vars = global_variables.get_global_variables(expr.value)
1580
+ if not global_vars:
1581
+ # detect if there is a related symbol
1582
+ if self.project.loader.find_object_containing(expr.value):
1583
+ symbol = self.project.loader.find_symbol(expr.value)
1584
+ if symbol is not None:
1585
+ # Create a new global variable if there isn't one already
1586
+ global_vars = global_variables.get_global_variables(symbol.rebased_addr)
1587
+ if not global_vars:
1588
+ global_var = SimMemoryVariable(symbol.rebased_addr, symbol.size, name=symbol.name)
1589
+ global_variables.add_variable("global", global_var.addr, global_var)
1590
+ global_vars = {global_var}
1591
+ if global_vars:
1592
+ global_var = next(iter(global_vars))
1593
+ expr.tags["reference_variable"] = global_var
1594
+ expr.tags["reference_variable_offset"] = 0
1595
+
1596
+ elif isinstance(expr, ailment.Stmt.Call):
1597
+ self._link_variables_on_call(variable_manager, global_variables, block, stmt_idx, expr, is_expr=True)
1598
+
1599
+ def _function_graph_to_ail_graph(self, func_graph, blocks_by_addr_and_size=None):
1600
+ if blocks_by_addr_and_size is None:
1601
+ blocks_by_addr_and_size = self._blocks_by_addr_and_size
1602
+
1603
+ node_to_block_mapping = {}
1604
+ graph = networkx.DiGraph()
1605
+
1606
+ for node in func_graph.nodes():
1607
+ ail_block = blocks_by_addr_and_size.get((node.addr, node.size), node)
1608
+ node_to_block_mapping[node] = ail_block
1609
+
1610
+ if ail_block is not None:
1611
+ graph.add_node(ail_block)
1612
+
1613
+ for src_node, dst_node, data in func_graph.edges(data=True):
1614
+ src = node_to_block_mapping[src_node]
1615
+ dst = node_to_block_mapping[dst_node]
1616
+
1617
+ if dst is not None:
1618
+ graph.add_edge(src, dst, **data)
1619
+
1620
+ return graph
1621
+
1622
+ def _rewrite_ite_expressions(self, ail_graph):
1623
+ cfg = self._cfg
1624
+ for block in list(ail_graph):
1625
+ if cfg is not None and block.addr in cfg.jump_tables:
1626
+ continue
1627
+
1628
+ ite_ins_addrs = []
1629
+ for stmt in block.statements:
1630
+ if isinstance(stmt, ailment.Stmt.Assignment) and isinstance(stmt.src, ailment.Expr.ITE):
1631
+ if stmt.ins_addr not in ite_ins_addrs:
1632
+ ite_ins_addrs.append(stmt.ins_addr)
1633
+
1634
+ if ite_ins_addrs:
1635
+ block_addr = block.addr
1636
+ for ite_ins_addr in ite_ins_addrs:
1637
+ block_addr = self._create_triangle_for_ite_expression(ail_graph, block_addr, ite_ins_addr)
1638
+ if block_addr is None or block_addr >= block.addr + block.original_size:
1639
+ break
1640
+
1641
+ def _create_triangle_for_ite_expression(self, ail_graph, block_addr: int, ite_ins_addr: int):
1642
+ # lift the ite instruction to get its size
1643
+ ite_insn_size = self.project.factory.block(ite_ins_addr, num_inst=1).size
1644
+ if ite_insn_size <= 2: # we need an address for true_block and another address for false_block
1645
+ return None
1646
+
1647
+ # relift the head and the ITE instruction
1648
+ new_head = self.project.factory.block(
1649
+ block_addr, size=ite_ins_addr - block_addr + ite_insn_size, cross_insn_opt=False
1650
+ )
1651
+ new_head_ail = ailment.IRSBConverter.convert(new_head.vex, self._ail_manager)
1652
+ # remove all statements between the ITE expression and the very end of the block
1653
+ ite_expr_stmt_idx = None
1654
+ ite_expr_stmt = None
1655
+ for idx, stmt in enumerate(new_head_ail.statements):
1656
+ if isinstance(stmt, ailment.Stmt.Assignment) and isinstance(stmt.src, ailment.Expr.ITE):
1657
+ ite_expr_stmt_idx = idx
1658
+ ite_expr_stmt = stmt
1659
+ break
1660
+ if ite_expr_stmt_idx is None:
1661
+ return None
1662
+
1663
+ ite_expr: ailment.Expr.ITE = ite_expr_stmt.src
1664
+ new_head_ail.statements = new_head_ail.statements[:ite_expr_stmt_idx]
1665
+ # build the conditional jump
1666
+ true_block_addr = ite_ins_addr + 1
1667
+ false_block_addr = ite_ins_addr + 2
1668
+ cond_jump_stmt = ailment.Stmt.ConditionalJump(
1669
+ ite_expr_stmt.idx,
1670
+ ite_expr.cond,
1671
+ ailment.Expr.Const(None, None, true_block_addr, self.project.arch.bits, **ite_expr_stmt.tags),
1672
+ ailment.Expr.Const(None, None, false_block_addr, self.project.arch.bits, **ite_expr_stmt.tags),
1673
+ **ite_expr_stmt.tags,
1674
+ )
1675
+ new_head_ail.statements.append(cond_jump_stmt)
1676
+
1677
+ # build the true block
1678
+ true_block = self.project.factory.block(ite_ins_addr, num_inst=1)
1679
+ true_block_ail = ailment.IRSBConverter.convert(true_block.vex, self._ail_manager)
1680
+ true_block_ail.addr = true_block_addr
1681
+
1682
+ ite_expr_stmt_idx = None
1683
+ ite_expr_stmt = None
1684
+ for idx, stmt in enumerate(true_block_ail.statements):
1685
+ if isinstance(stmt, ailment.Stmt.Assignment) and isinstance(stmt.src, ailment.Expr.ITE):
1686
+ ite_expr_stmt_idx = idx
1687
+ ite_expr_stmt = stmt
1688
+ break
1689
+ if ite_expr_stmt_idx is None:
1690
+ return None
1691
+
1692
+ true_block_ail.statements[ite_expr_stmt_idx] = ailment.Stmt.Assignment(
1693
+ ite_expr_stmt.idx, ite_expr_stmt.dst, ite_expr_stmt.src.iftrue, **ite_expr_stmt.tags
1694
+ )
1695
+
1696
+ # build the false block
1697
+ false_block = self.project.factory.block(ite_ins_addr, num_inst=1)
1698
+ false_block_ail = ailment.IRSBConverter.convert(false_block.vex, self._ail_manager)
1699
+ false_block_ail.addr = false_block_addr
1700
+
1701
+ ite_expr_stmt_idx = None
1702
+ ite_expr_stmt = None
1703
+ for idx, stmt in enumerate(false_block_ail.statements):
1704
+ if isinstance(stmt, ailment.Stmt.Assignment) and isinstance(stmt.src, ailment.Expr.ITE):
1705
+ ite_expr_stmt_idx = idx
1706
+ ite_expr_stmt = stmt
1707
+ break
1708
+ if ite_expr_stmt_idx is None:
1709
+ return None
1710
+
1711
+ false_block_ail.statements[ite_expr_stmt_idx] = ailment.Stmt.Assignment(
1712
+ ite_expr_stmt.idx, ite_expr_stmt.dst, ite_expr_stmt.src.iffalse, **ite_expr_stmt.tags
1713
+ )
1714
+
1715
+ original_block = next(iter(b for b in ail_graph if b.addr == block_addr))
1716
+
1717
+ original_block_in_edges = list(ail_graph.in_edges(original_block))
1718
+ original_block_out_edges = list(ail_graph.out_edges(original_block))
1719
+
1720
+ # build the target block if the target block does not exist in the current function
1721
+ end_block_addr = ite_ins_addr + ite_insn_size
1722
+ if block_addr < end_block_addr < block_addr + original_block.original_size:
1723
+ end_block = self.project.factory.block(
1724
+ ite_ins_addr + ite_insn_size,
1725
+ size=block_addr + original_block.original_size - (ite_ins_addr + ite_insn_size),
1726
+ cross_insn_opt=False,
1727
+ )
1728
+ end_block_ail = ailment.IRSBConverter.convert(end_block.vex, self._ail_manager)
1729
+ else:
1730
+ try:
1731
+ end_block_ail = next(iter(b for b in ail_graph if b.addr == end_block_addr))
1732
+ except StopIteration:
1733
+ return None
1734
+
1735
+ # last check: if the first instruction of the end block has Sar, then we bail (due to the peephole optimization
1736
+ # SarToSignedDiv)
1737
+ for stmt in end_block_ail.statements:
1738
+ if stmt.ins_addr > end_block_ail.addr:
1739
+ break
1740
+ if (
1741
+ isinstance(stmt, ailment.Stmt.Assignment)
1742
+ and isinstance(stmt.src, ailment.Expr.BinaryOp)
1743
+ and stmt.src.op == "Sar"
1744
+ ):
1745
+ return None
1746
+
1747
+ ail_graph.remove_node(original_block)
1748
+
1749
+ if end_block_ail not in ail_graph:
1750
+ # newly created. add it and the necessary edges into the graph
1751
+ for _, dst in original_block_out_edges:
1752
+ if dst is original_block:
1753
+ ail_graph.add_edge(end_block_ail, new_head_ail)
1754
+ else:
1755
+ ail_graph.add_edge(end_block_ail, dst)
1756
+
1757
+ # in edges
1758
+ for src, _ in original_block_in_edges:
1759
+ if src is original_block:
1760
+ # loop
1761
+ ail_graph.add_edge(end_block_ail, new_head_ail)
1762
+ else:
1763
+ ail_graph.add_edge(src, new_head_ail)
1764
+
1765
+ # triangle
1766
+ ail_graph.add_edge(new_head_ail, true_block_ail)
1767
+ ail_graph.add_edge(new_head_ail, false_block_ail)
1768
+ ail_graph.add_edge(true_block_ail, end_block_ail)
1769
+ ail_graph.add_edge(false_block_ail, end_block_ail)
1770
+
1771
+ return end_block_ail.addr
1772
+
1773
+ @staticmethod
1774
+ def _remove_redundant_jump_blocks(ail_graph):
1775
+ def first_conditional_jump(block: ailment.Block) -> ailment.Stmt.ConditionalJump | None:
1776
+ for stmt in block.statements:
1777
+ if isinstance(stmt, ailment.Stmt.ConditionalJump):
1778
+ return stmt
1779
+ return None
1780
+
1781
+ def patch_conditional_jump_target(cond_jump_stmt: ailment.Stmt.ConditionalJump, old_addr: int, new_addr: int):
1782
+ if (
1783
+ isinstance(cond_jump_stmt.true_target, ailment.Expr.Const)
1784
+ and cond_jump_stmt.true_target.value == old_addr
1785
+ ):
1786
+ cond_jump_stmt.true_target.value = new_addr
1787
+ if (
1788
+ isinstance(cond_jump_stmt.false_target, ailment.Expr.Const)
1789
+ and cond_jump_stmt.false_target.value == old_addr
1790
+ ):
1791
+ cond_jump_stmt.false_target.value = new_addr
1792
+
1793
+ # note that blocks don't have labels inserted at this point
1794
+ for node in list(ail_graph.nodes):
1795
+ if (
1796
+ len(node.statements) == 1
1797
+ and isinstance(node.statements[0], ailment.Stmt.Jump)
1798
+ and isinstance(node.statements[0].target, ailment.Expr.Const)
1799
+ ):
1800
+ jump_target = node.statements[0].target.value
1801
+ succs = list(ail_graph.successors(node))
1802
+ if len(succs) == 1 and succs[0].addr == jump_target:
1803
+ preds = list(ail_graph.predecessors(node))
1804
+ if len(preds) == 1 and ail_graph.out_degree[preds[0]] == 2:
1805
+ # remove this node
1806
+ for pred in preds:
1807
+ if pred.statements:
1808
+ last_stmt = pred.statements[-1]
1809
+ if (
1810
+ isinstance(last_stmt, ailment.Stmt.Jump)
1811
+ and isinstance(last_stmt.target, ailment.Expr.Const)
1812
+ and last_stmt.target.value == node.addr
1813
+ ):
1814
+ last_stmt.target.value = succs[0].addr
1815
+ elif isinstance(last_stmt, ailment.Stmt.ConditionalJump):
1816
+ patch_conditional_jump_target(last_stmt, node.addr, succs[0].addr)
1817
+ first_cond_jump = first_conditional_jump(pred)
1818
+ if first_cond_jump is not None and first_cond_jump is not last_stmt:
1819
+ patch_conditional_jump_target(first_cond_jump, node.addr, succs[0].addr)
1820
+ ail_graph.add_edge(pred, succs[0])
1821
+ ail_graph.remove_node(node)
1822
+
1823
+ @staticmethod
1824
+ def _insert_block_labels(ail_graph):
1825
+ for node in ail_graph.nodes:
1826
+ node: ailment.Block
1827
+ lbl = ailment.Stmt.Label(None, f"LABEL_{node.addr:x}", node.addr, block_idx=node.idx)
1828
+ node.statements.insert(0, lbl)
1829
+
1830
+ @staticmethod
1831
+ def _collect_externs(ail_graph, variable_kb):
1832
+ global_vars = variable_kb.variables.global_manager.get_variables()
1833
+ walker = ailment.AILBlockWalker()
1834
+ variables = set()
1835
+
1836
+ def handle_expr(
1837
+ expr_idx: int,
1838
+ expr: ailment.expression.Expression,
1839
+ stmt_idx: int,
1840
+ stmt: ailment.statement.Statement,
1841
+ block: ailment.Block | None,
1842
+ ):
1843
+ if expr is None:
1844
+ return None
1845
+ for v in [
1846
+ getattr(expr, "variable", None),
1847
+ expr.tags.get("reference_variable", None) if hasattr(expr, "tags") else None,
1848
+ ]:
1849
+ if v and v in global_vars:
1850
+ variables.add(v)
1851
+ return ailment.AILBlockWalker._handle_expr(walker, expr_idx, expr, stmt_idx, stmt, block)
1852
+
1853
+ def handle_Store(stmt_idx: int, stmt: ailment.statement.Store, block: ailment.Block | None):
1854
+ if stmt.variable and stmt.variable in global_vars:
1855
+ variables.add(stmt.variable)
1856
+ return ailment.AILBlockWalker._handle_Store(walker, stmt_idx, stmt, block)
1857
+
1858
+ walker.stmt_handlers[ailment.statement.Store] = handle_Store
1859
+ walker._handle_expr = handle_expr
1860
+ AILGraphWalker(ail_graph, walker.walk).walk()
1861
+ return variables
1862
+
1863
+ @staticmethod
1864
+ def _collect_data_refs(ail_graph) -> dict[int, list[DataRefDesc]]:
1865
+ # pylint:disable=unused-argument
1866
+ walker = ailment.AILBlockWalker()
1867
+ data_refs: dict[int, list[DataRefDesc]] = defaultdict(list)
1868
+
1869
+ def handle_Const(
1870
+ expr_idx: int,
1871
+ expr: ailment.expression.Const,
1872
+ stmt_idx: int,
1873
+ stmt: ailment.statement.Statement,
1874
+ block: ailment.Block | None,
1875
+ ):
1876
+ if isinstance(expr.value, int) and hasattr(expr, "ins_addr"):
1877
+ data_refs[block.addr].append(
1878
+ DataRefDesc(expr.value, 1, block.addr, stmt_idx, expr.ins_addr, MemoryDataSort.Unknown)
1879
+ )
1880
+ if hasattr(expr, "deref_src_addr"):
1881
+ data_refs[block.addr].append(
1882
+ DataRefDesc(
1883
+ expr.deref_src_addr, expr.size, block.addr, stmt_idx, expr.ins_addr, MemoryDataSort.Unknown
1884
+ )
1885
+ )
1886
+
1887
+ def handle_Load(
1888
+ expr_idx: int,
1889
+ expr: ailment.expression.Load,
1890
+ stmt_idx: int,
1891
+ stmt: ailment.statement.Statement,
1892
+ block: ailment.Block | None,
1893
+ ):
1894
+ if isinstance(expr.addr, ailment.expression.Const):
1895
+ addr = expr.addr
1896
+ if isinstance(addr.value, int) and hasattr(addr, "ins_addr"):
1897
+ data_refs[block.addr].append(
1898
+ DataRefDesc(
1899
+ addr.value,
1900
+ expr.size,
1901
+ block.addr,
1902
+ stmt_idx,
1903
+ addr.ins_addr,
1904
+ MemoryDataSort.Integer if expr.size == 4 else MemoryDataSort.Unknown,
1905
+ )
1906
+ )
1907
+ if hasattr(addr, "deref_src_addr"):
1908
+ data_refs[block.addr].append(
1909
+ DataRefDesc(
1910
+ addr.deref_src_addr,
1911
+ expr.size,
1912
+ block.addr,
1913
+ stmt_idx,
1914
+ addr.ins_addr,
1915
+ MemoryDataSort.Integer if expr.size == 4 else MemoryDataSort.Unknown,
1916
+ )
1917
+ )
1918
+ return None
1919
+
1920
+ return ailment.AILBlockWalker._handle_Load(walker, expr_idx, expr, stmt_idx, stmt, block)
1921
+
1922
+ def handle_Store(stmt_idx: int, stmt: ailment.statement.Store, block: ailment.Block | None):
1923
+ if isinstance(stmt.addr, ailment.expression.Const):
1924
+ addr = stmt.addr
1925
+ if isinstance(addr.value, int) and hasattr(addr, "ins_addr"):
1926
+ data_refs[block.addr].append(
1927
+ DataRefDesc(
1928
+ addr.value,
1929
+ stmt.size,
1930
+ block.addr,
1931
+ stmt_idx,
1932
+ addr.ins_addr,
1933
+ MemoryDataSort.Integer if stmt.size == 4 else MemoryDataSort.Unknown,
1934
+ )
1935
+ )
1936
+ if hasattr(addr, "deref_src_addr"):
1937
+ data_refs[block.addr].append(
1938
+ DataRefDesc(
1939
+ addr.deref_src_addr,
1940
+ stmt.size,
1941
+ block.addr,
1942
+ stmt_idx,
1943
+ addr.ins_addr,
1944
+ MemoryDataSort.Integer if stmt.size == 4 else MemoryDataSort.Unknown,
1945
+ )
1946
+ )
1947
+ return None
1948
+
1949
+ return ailment.AILBlockWalker._handle_Store(walker, stmt_idx, stmt, block)
1950
+
1951
+ walker.stmt_handlers[ailment.statement.Store] = handle_Store
1952
+ walker.expr_handlers[ailment.expression.Load] = handle_Load
1953
+ walker.expr_handlers[ailment.expression.Const] = handle_Const
1954
+ AILGraphWalker(ail_graph, walker.walk).walk()
1955
+ return data_refs
1956
+
1957
+ def _next_atom(self) -> int:
1958
+ return self._ail_manager.next_atom()
1959
+
1960
+ @staticmethod
1961
+ def _make_callsites_rd_observe_callback(ob_type, **kwargs):
1962
+ if ob_type != "insn":
1963
+ return False
1964
+ stmt = kwargs.pop("stmt")
1965
+ op_type = kwargs.pop("op_type")
1966
+ return isinstance(stmt, ailment.Stmt.Call) and op_type == OP_BEFORE
1967
+
1968
+ def parse_variable_addr(self, addr: ailment.Expr.Expression) -> tuple[Any, Any] | None:
1969
+ if isinstance(addr, ailment.Expr.Const):
1970
+ return addr, 0
1971
+ if isinstance(addr, ailment.Expr.BinaryOp):
1972
+ if addr.op == "Add":
1973
+ op0, op1 = addr.operands
1974
+ if (
1975
+ isinstance(op0, ailment.Expr.Const)
1976
+ and self.project.loader.find_object_containing(op0.value) is not None
1977
+ ):
1978
+ return op0, op1
1979
+ elif (
1980
+ isinstance(op1, ailment.Expr.Const)
1981
+ and self.project.loader.find_object_containing(op1.value) is not None
1982
+ ):
1983
+ return op1, op0
1984
+ return op0, op1 # best-effort guess
1985
+ return None, None
1986
+
1987
+ def new_block_addr(self) -> int:
1988
+ """
1989
+ Return a block address that does not conflict with any existing blocks.
1990
+
1991
+ :return: The block address.
1992
+ """
1993
+ if self._new_block_addrs:
1994
+ new_addr = max(self._new_block_addrs) + 1
1995
+ else:
1996
+ new_addr = max(self.function.block_addrs_set) + 2048
1997
+ self._new_block_addrs.add(new_addr)
1998
+ return new_addr
1999
+
2000
+ @staticmethod
2001
+ @timethis
2002
+ def remove_empty_nodes(graph: networkx.DiGraph) -> networkx.DiGraph:
2003
+ def handle_node(node: ailment.Block):
2004
+ if not node.statements:
2005
+ preds = list(pred for pred in graph.predecessors(node) if pred is not node)
2006
+ succs = list(succ for succ in graph.successors(node) if succ is not node)
2007
+ if len(preds) == 1 and len(succs) == 1:
2008
+ pred = preds[0]
2009
+ succ = succs[0]
2010
+ value_updated = False
2011
+ # update the last statement of pred
2012
+ if pred.statements and isinstance(pred.statements[-1], ailment.Stmt.ConditionalJump):
2013
+ last_stmt = pred.statements[-1]
2014
+ if (
2015
+ isinstance(last_stmt.true_target, ailment.Expr.Const)
2016
+ and last_stmt.true_target.value == node.addr
2017
+ ):
2018
+ last_stmt.true_target.value = succ.addr
2019
+ value_updated = True
2020
+ if (
2021
+ isinstance(last_stmt.false_target, ailment.Expr.Const)
2022
+ and last_stmt.false_target.value == node.addr
2023
+ ):
2024
+ last_stmt.false_target.value = succ.addr
2025
+ value_updated = True
2026
+
2027
+ if value_updated:
2028
+ graph.add_edge(pred, succ)
2029
+ raise RemoveNodeNotice()
2030
+ elif len(preds) >= 1 and len(succs) == 1:
2031
+ succ = succs[0]
2032
+ branch_updates = 0
2033
+ for pred in preds:
2034
+ # test how many last statements of pred can potentially be updated
2035
+ if pred.statements and isinstance(pred.statements[-1], ailment.Stmt.ConditionalJump):
2036
+ last_stmt = pred.statements[-1]
2037
+ if (
2038
+ isinstance(last_stmt.true_target, ailment.Expr.Const)
2039
+ and last_stmt.true_target.value == node.addr
2040
+ ):
2041
+ branch_updates += 1
2042
+ if (
2043
+ isinstance(last_stmt.false_target, ailment.Expr.Const)
2044
+ and last_stmt.false_target.value == node.addr
2045
+ ):
2046
+ branch_updates += 1
2047
+
2048
+ if branch_updates == len(preds):
2049
+ # actually do the update
2050
+ for pred in preds:
2051
+ graph.add_edge(pred, succ)
2052
+ if pred.statements and isinstance(pred.statements[-1], ailment.Stmt.ConditionalJump):
2053
+ last_stmt = pred.statements[-1]
2054
+ if (
2055
+ isinstance(last_stmt.true_target, ailment.Expr.Const)
2056
+ and last_stmt.true_target.value == node.addr
2057
+ ):
2058
+ last_stmt.true_target.value = succ.addr
2059
+ if (
2060
+ isinstance(last_stmt.false_target, ailment.Expr.Const)
2061
+ and last_stmt.false_target.value == node.addr
2062
+ ):
2063
+ last_stmt.false_target.value = succ.addr
2064
+ raise RemoveNodeNotice()
2065
+ elif not preds or not succs:
2066
+ raise RemoveNodeNotice()
2067
+
2068
+ AILGraphWalker(graph, handle_node, replace_nodes=True).walk()
2069
+ return graph
2070
+
2071
+ def _find_regs_compared_against_sp(self, func_graph):
2072
+ # TODO: Implement this function for architectures beyond amd64
2073
+ extra_regs = set()
2074
+ if self.project.arch.name == "AMD64":
2075
+ for node in func_graph.nodes:
2076
+ block = self.project.factory.block(node.addr, size=node.size).capstone
2077
+ for insn in block.insns:
2078
+ if insn.mnemonic == "cmp":
2079
+ capstone_reg_offset = None
2080
+ if (
2081
+ insn.operands[0].type == capstone.x86.X86_OP_REG
2082
+ and insn.operands[0].reg == capstone.x86.X86_REG_RSP
2083
+ and insn.operands[1].type == capstone.x86.X86_OP_REG
2084
+ ):
2085
+ capstone_reg_offset = insn.operands[1].reg
2086
+ elif (
2087
+ insn.operands[1].type == capstone.x86.X86_OP_REG
2088
+ and insn.operands[1].reg == capstone.x86.X86_REG_RSP
2089
+ and insn.operands[0].type == capstone.x86.X86_OP_REG
2090
+ ):
2091
+ capstone_reg_offset = insn.operands[0].reg
2092
+
2093
+ if capstone_reg_offset is not None:
2094
+ reg_name = insn.reg_name(capstone_reg_offset)
2095
+ extra_regs.add(self.project.arch.registers[reg_name][0])
2096
+
2097
+ return extra_regs
2098
+
2099
+ def _rewrite_alloca(self, ail_graph):
2100
+ # pylint:disable=too-many-boolean-expressions
2101
+ alloca_node = None
2102
+ sp_equal_to = None
2103
+
2104
+ for node in ail_graph:
2105
+ if ail_graph.in_degree[node] == 2 and ail_graph.out_degree[node] == 2:
2106
+ succs = ail_graph.successors(node)
2107
+ if node in succs:
2108
+ # self loop!
2109
+ if len(node.statements) >= 6:
2110
+ stmt0 = node.statements[1] # skip the LABEL statement
2111
+ stmt1 = node.statements[2]
2112
+ last_stmt = node.statements[-1]
2113
+ if (
2114
+ isinstance(stmt0, ailment.Stmt.Assignment)
2115
+ and isinstance(stmt0.dst, ailment.Expr.Register)
2116
+ and isinstance(stmt0.src, ailment.Expr.StackBaseOffset)
2117
+ and stmt0.src.offset == -0x1000
2118
+ ):
2119
+ if (
2120
+ isinstance(stmt1, ailment.Stmt.Store)
2121
+ and isinstance(stmt1.addr, ailment.Expr.StackBaseOffset)
2122
+ and stmt1.addr.offset == -0x1000
2123
+ and isinstance(stmt1.data, ailment.Expr.Load)
2124
+ and isinstance(stmt1.data.addr, ailment.Expr.StackBaseOffset)
2125
+ and stmt1.data.addr.offset == -0x1000
2126
+ ):
2127
+ if (
2128
+ isinstance(last_stmt, ailment.Stmt.ConditionalJump)
2129
+ and isinstance(last_stmt.condition, ailment.Expr.BinaryOp)
2130
+ and last_stmt.condition.op == "CmpEQ"
2131
+ and isinstance(last_stmt.condition.operands[0], ailment.Expr.StackBaseOffset)
2132
+ and last_stmt.condition.operands[0].offset == -0x1000
2133
+ and isinstance(last_stmt.condition.operands[1], ailment.Expr.Register)
2134
+ and isinstance(last_stmt.false_target, ailment.Expr.Const)
2135
+ and last_stmt.false_target.value == node.addr
2136
+ ):
2137
+ # found it!
2138
+ alloca_node = node
2139
+ sp_equal_to = ailment.Expr.BinaryOp(
2140
+ None,
2141
+ "Sub",
2142
+ [
2143
+ ailment.Expr.Register(
2144
+ None, None, self.project.arch.sp_offset, self.project.arch.bits
2145
+ ),
2146
+ last_stmt.condition.operands[1],
2147
+ ],
2148
+ False,
2149
+ )
2150
+ break
2151
+
2152
+ if alloca_node is not None:
2153
+ stmt0 = alloca_node.statements[1]
2154
+ statements = [ailment.Stmt.Call(stmt0.idx, "alloca", args=[sp_equal_to], **stmt0.tags)]
2155
+ new_node = ailment.Block(alloca_node.addr, alloca_node.original_size, statements=statements)
2156
+ # replace the node
2157
+ preds = [pred for pred in ail_graph.predecessors(alloca_node) if pred is not alloca_node]
2158
+ succs = [succ for succ in ail_graph.successors(alloca_node) if succ is not alloca_node]
2159
+ ail_graph.remove_node(alloca_node)
2160
+ for pred in preds:
2161
+ ail_graph.add_edge(pred, new_node)
2162
+ for succ in succs:
2163
+ ail_graph.add_edge(new_node, succ)
2164
+
2165
+
2166
+ register_analysis(Clinic, "Clinic")