angr 9.2.156__cp310-cp310-manylinux2014_aarch64.whl

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

Potentially problematic release.


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

Files changed (1393) hide show
  1. angr/__init__.py +363 -0
  2. angr/__main__.py +152 -0
  3. angr/analyses/__init__.py +113 -0
  4. angr/analyses/analysis.py +407 -0
  5. angr/analyses/backward_slice.py +686 -0
  6. angr/analyses/binary_optimizer.py +670 -0
  7. angr/analyses/bindiff.py +1512 -0
  8. angr/analyses/boyscout.py +76 -0
  9. angr/analyses/callee_cleanup_finder.py +74 -0
  10. angr/analyses/calling_convention/__init__.py +6 -0
  11. angr/analyses/calling_convention/calling_convention.py +1092 -0
  12. angr/analyses/calling_convention/fact_collector.py +636 -0
  13. angr/analyses/calling_convention/utils.py +60 -0
  14. angr/analyses/cdg.py +189 -0
  15. angr/analyses/cfg/__init__.py +23 -0
  16. angr/analyses/cfg/cfb.py +428 -0
  17. angr/analyses/cfg/cfg.py +74 -0
  18. angr/analyses/cfg/cfg_arch_options.py +95 -0
  19. angr/analyses/cfg/cfg_base.py +2886 -0
  20. angr/analyses/cfg/cfg_emulated.py +3447 -0
  21. angr/analyses/cfg/cfg_fast.py +5273 -0
  22. angr/analyses/cfg/cfg_fast_soot.py +662 -0
  23. angr/analyses/cfg/cfg_job_base.py +203 -0
  24. angr/analyses/cfg/indirect_jump_resolvers/__init__.py +28 -0
  25. angr/analyses/cfg/indirect_jump_resolvers/amd64_elf_got.py +62 -0
  26. angr/analyses/cfg/indirect_jump_resolvers/amd64_pe_iat.py +51 -0
  27. angr/analyses/cfg/indirect_jump_resolvers/arm_elf_fast.py +149 -0
  28. angr/analyses/cfg/indirect_jump_resolvers/const_resolver.py +186 -0
  29. angr/analyses/cfg/indirect_jump_resolvers/constant_value_manager.py +107 -0
  30. angr/analyses/cfg/indirect_jump_resolvers/default_resolvers.py +76 -0
  31. angr/analyses/cfg/indirect_jump_resolvers/jumptable.py +2367 -0
  32. angr/analyses/cfg/indirect_jump_resolvers/memload_resolver.py +81 -0
  33. angr/analyses/cfg/indirect_jump_resolvers/mips_elf_fast.py +286 -0
  34. angr/analyses/cfg/indirect_jump_resolvers/mips_elf_got.py +148 -0
  35. angr/analyses/cfg/indirect_jump_resolvers/propagator_utils.py +46 -0
  36. angr/analyses/cfg/indirect_jump_resolvers/resolver.py +74 -0
  37. angr/analyses/cfg/indirect_jump_resolvers/syscall_resolver.py +92 -0
  38. angr/analyses/cfg/indirect_jump_resolvers/x86_elf_pic_plt.py +88 -0
  39. angr/analyses/cfg/indirect_jump_resolvers/x86_pe_iat.py +47 -0
  40. angr/analyses/cfg_slice_to_sink/__init__.py +11 -0
  41. angr/analyses/cfg_slice_to_sink/cfg_slice_to_sink.py +117 -0
  42. angr/analyses/cfg_slice_to_sink/graph.py +87 -0
  43. angr/analyses/cfg_slice_to_sink/transitions.py +27 -0
  44. angr/analyses/class_identifier.py +63 -0
  45. angr/analyses/code_tagging.py +123 -0
  46. angr/analyses/codecave.py +77 -0
  47. angr/analyses/complete_calling_conventions.py +461 -0
  48. angr/analyses/congruency_check.py +377 -0
  49. angr/analyses/data_dep/__init__.py +16 -0
  50. angr/analyses/data_dep/data_dependency_analysis.py +595 -0
  51. angr/analyses/data_dep/dep_nodes.py +171 -0
  52. angr/analyses/data_dep/sim_act_location.py +49 -0
  53. angr/analyses/datagraph_meta.py +105 -0
  54. angr/analyses/ddg.py +1670 -0
  55. angr/analyses/decompiler/__init__.py +41 -0
  56. angr/analyses/decompiler/ail_simplifier.py +1872 -0
  57. angr/analyses/decompiler/ailgraph_walker.py +49 -0
  58. angr/analyses/decompiler/block_io_finder.py +302 -0
  59. angr/analyses/decompiler/block_similarity.py +196 -0
  60. angr/analyses/decompiler/block_simplifier.py +371 -0
  61. angr/analyses/decompiler/callsite_maker.py +555 -0
  62. angr/analyses/decompiler/ccall_rewriters/__init__.py +9 -0
  63. angr/analyses/decompiler/ccall_rewriters/amd64_ccalls.py +580 -0
  64. angr/analyses/decompiler/ccall_rewriters/rewriter_base.py +20 -0
  65. angr/analyses/decompiler/ccall_rewriters/x86_ccalls.py +313 -0
  66. angr/analyses/decompiler/clinic.py +3222 -0
  67. angr/analyses/decompiler/condition_processor.py +1245 -0
  68. angr/analyses/decompiler/counters/__init__.py +16 -0
  69. angr/analyses/decompiler/counters/boolean_counter.py +27 -0
  70. angr/analyses/decompiler/counters/call_counter.py +47 -0
  71. angr/analyses/decompiler/counters/expression_counters.py +77 -0
  72. angr/analyses/decompiler/counters/seq_cf_structure_counter.py +63 -0
  73. angr/analyses/decompiler/decompilation_cache.py +46 -0
  74. angr/analyses/decompiler/decompilation_options.py +275 -0
  75. angr/analyses/decompiler/decompiler.py +692 -0
  76. angr/analyses/decompiler/dephication/__init__.py +6 -0
  77. angr/analyses/decompiler/dephication/dephication_base.py +89 -0
  78. angr/analyses/decompiler/dephication/graph_dephication.py +63 -0
  79. angr/analyses/decompiler/dephication/graph_rewriting.py +116 -0
  80. angr/analyses/decompiler/dephication/graph_vvar_mapping.py +326 -0
  81. angr/analyses/decompiler/dephication/rewriting_engine.py +504 -0
  82. angr/analyses/decompiler/dephication/seqnode_dephication.py +134 -0
  83. angr/analyses/decompiler/empty_node_remover.py +212 -0
  84. angr/analyses/decompiler/expression_narrower.py +287 -0
  85. angr/analyses/decompiler/goto_manager.py +112 -0
  86. angr/analyses/decompiler/graph_region.py +398 -0
  87. angr/analyses/decompiler/jump_target_collector.py +37 -0
  88. angr/analyses/decompiler/jumptable_entry_condition_rewriter.py +67 -0
  89. angr/analyses/decompiler/label_collector.py +32 -0
  90. angr/analyses/decompiler/optimization_passes/__init__.py +151 -0
  91. angr/analyses/decompiler/optimization_passes/base_ptr_save_simplifier.py +157 -0
  92. angr/analyses/decompiler/optimization_passes/call_stmt_rewriter.py +46 -0
  93. angr/analyses/decompiler/optimization_passes/code_motion.py +362 -0
  94. angr/analyses/decompiler/optimization_passes/condition_constprop.py +219 -0
  95. angr/analyses/decompiler/optimization_passes/const_derefs.py +266 -0
  96. angr/analyses/decompiler/optimization_passes/const_prop_reverter.py +365 -0
  97. angr/analyses/decompiler/optimization_passes/cross_jump_reverter.py +106 -0
  98. angr/analyses/decompiler/optimization_passes/deadblock_remover.py +82 -0
  99. angr/analyses/decompiler/optimization_passes/determine_load_sizes.py +64 -0
  100. angr/analyses/decompiler/optimization_passes/div_simplifier.py +425 -0
  101. angr/analyses/decompiler/optimization_passes/duplication_reverter/__init__.py +5 -0
  102. angr/analyses/decompiler/optimization_passes/duplication_reverter/ail_merge_graph.py +503 -0
  103. angr/analyses/decompiler/optimization_passes/duplication_reverter/duplication_reverter.py +1218 -0
  104. angr/analyses/decompiler/optimization_passes/duplication_reverter/errors.py +16 -0
  105. angr/analyses/decompiler/optimization_passes/duplication_reverter/similarity.py +126 -0
  106. angr/analyses/decompiler/optimization_passes/duplication_reverter/utils.py +167 -0
  107. angr/analyses/decompiler/optimization_passes/eager_std_string_concatenation.py +165 -0
  108. angr/analyses/decompiler/optimization_passes/engine_base.py +500 -0
  109. angr/analyses/decompiler/optimization_passes/expr_op_swapper.py +135 -0
  110. angr/analyses/decompiler/optimization_passes/flip_boolean_cmp.py +113 -0
  111. angr/analyses/decompiler/optimization_passes/inlined_string_transformation_simplifier.py +615 -0
  112. angr/analyses/decompiler/optimization_passes/ite_expr_converter.py +224 -0
  113. angr/analyses/decompiler/optimization_passes/ite_region_converter.py +335 -0
  114. angr/analyses/decompiler/optimization_passes/lowered_switch_simplifier.py +922 -0
  115. angr/analyses/decompiler/optimization_passes/mod_simplifier.py +99 -0
  116. angr/analyses/decompiler/optimization_passes/optimization_pass.py +659 -0
  117. angr/analyses/decompiler/optimization_passes/register_save_area_simplifier.py +221 -0
  118. angr/analyses/decompiler/optimization_passes/ret_addr_save_simplifier.py +171 -0
  119. angr/analyses/decompiler/optimization_passes/ret_deduplicator.py +222 -0
  120. angr/analyses/decompiler/optimization_passes/return_duplicator_base.py +640 -0
  121. angr/analyses/decompiler/optimization_passes/return_duplicator_high.py +61 -0
  122. angr/analyses/decompiler/optimization_passes/return_duplicator_low.py +235 -0
  123. angr/analyses/decompiler/optimization_passes/stack_canary_simplifier.py +333 -0
  124. angr/analyses/decompiler/optimization_passes/switch_default_case_duplicator.py +149 -0
  125. angr/analyses/decompiler/optimization_passes/switch_reused_entry_rewriter.py +102 -0
  126. angr/analyses/decompiler/optimization_passes/tag_slicer.py +41 -0
  127. angr/analyses/decompiler/optimization_passes/win_stack_canary_simplifier.py +421 -0
  128. angr/analyses/decompiler/optimization_passes/x86_gcc_getpc_simplifier.py +88 -0
  129. angr/analyses/decompiler/peephole_optimizations/__init__.py +127 -0
  130. angr/analyses/decompiler/peephole_optimizations/a_div_const_add_a_mul_n_div_const.py +42 -0
  131. angr/analyses/decompiler/peephole_optimizations/a_mul_const_div_shr_const.py +38 -0
  132. angr/analyses/decompiler/peephole_optimizations/a_mul_const_sub_a.py +34 -0
  133. angr/analyses/decompiler/peephole_optimizations/a_shl_const_sub_a.py +34 -0
  134. angr/analyses/decompiler/peephole_optimizations/a_sub_a_div.py +25 -0
  135. angr/analyses/decompiler/peephole_optimizations/a_sub_a_div_const_mul_const.py +57 -0
  136. angr/analyses/decompiler/peephole_optimizations/a_sub_a_shr_const_shr_const.py +37 -0
  137. angr/analyses/decompiler/peephole_optimizations/a_sub_a_sub_n.py +23 -0
  138. angr/analyses/decompiler/peephole_optimizations/arm_cmpf.py +236 -0
  139. angr/analyses/decompiler/peephole_optimizations/base.py +157 -0
  140. angr/analyses/decompiler/peephole_optimizations/basepointeroffset_add_n.py +34 -0
  141. angr/analyses/decompiler/peephole_optimizations/basepointeroffset_and_mask.py +36 -0
  142. angr/analyses/decompiler/peephole_optimizations/bitwise_or_to_logical_or.py +34 -0
  143. angr/analyses/decompiler/peephole_optimizations/bool_expr_xor_1.py +27 -0
  144. angr/analyses/decompiler/peephole_optimizations/bswap.py +142 -0
  145. angr/analyses/decompiler/peephole_optimizations/cas_intrinsics.py +115 -0
  146. angr/analyses/decompiler/peephole_optimizations/cmpord_rewriter.py +71 -0
  147. angr/analyses/decompiler/peephole_optimizations/coalesce_adjacent_shrs.py +39 -0
  148. angr/analyses/decompiler/peephole_optimizations/coalesce_same_cascading_ifs.py +28 -0
  149. angr/analyses/decompiler/peephole_optimizations/const_mull_a_shift.py +189 -0
  150. angr/analyses/decompiler/peephole_optimizations/constant_derefs.py +44 -0
  151. angr/analyses/decompiler/peephole_optimizations/conv_a_sub0_shr_and.py +69 -0
  152. angr/analyses/decompiler/peephole_optimizations/conv_shl_shr.py +52 -0
  153. angr/analyses/decompiler/peephole_optimizations/eager_eval.py +372 -0
  154. angr/analyses/decompiler/peephole_optimizations/extended_byte_and_mask.py +56 -0
  155. angr/analyses/decompiler/peephole_optimizations/inlined_strcpy.py +160 -0
  156. angr/analyses/decompiler/peephole_optimizations/inlined_strcpy_consolidation.py +109 -0
  157. angr/analyses/decompiler/peephole_optimizations/inlined_wstrcpy.py +170 -0
  158. angr/analyses/decompiler/peephole_optimizations/invert_negated_logical_conjuction_disjunction.py +50 -0
  159. angr/analyses/decompiler/peephole_optimizations/one_sub_bool.py +33 -0
  160. angr/analyses/decompiler/peephole_optimizations/remove_cascading_conversions.py +45 -0
  161. angr/analyses/decompiler/peephole_optimizations/remove_cxx_destructor_calls.py +32 -0
  162. angr/analyses/decompiler/peephole_optimizations/remove_empty_if_body.py +46 -0
  163. angr/analyses/decompiler/peephole_optimizations/remove_noop_conversions.py +47 -0
  164. angr/analyses/decompiler/peephole_optimizations/remove_redundant_bitmasks.py +116 -0
  165. angr/analyses/decompiler/peephole_optimizations/remove_redundant_conversions.py +247 -0
  166. angr/analyses/decompiler/peephole_optimizations/remove_redundant_ite_branch.py +30 -0
  167. angr/analyses/decompiler/peephole_optimizations/remove_redundant_ite_comparisons.py +54 -0
  168. angr/analyses/decompiler/peephole_optimizations/remove_redundant_nots.py +36 -0
  169. angr/analyses/decompiler/peephole_optimizations/remove_redundant_reinterprets.py +44 -0
  170. angr/analyses/decompiler/peephole_optimizations/remove_redundant_shifts.py +95 -0
  171. angr/analyses/decompiler/peephole_optimizations/remove_redundant_shifts_around_comparators.py +44 -0
  172. angr/analyses/decompiler/peephole_optimizations/rewrite_bit_extractions.py +85 -0
  173. angr/analyses/decompiler/peephole_optimizations/rewrite_conv_mul.py +40 -0
  174. angr/analyses/decompiler/peephole_optimizations/rewrite_cxx_operator_calls.py +90 -0
  175. angr/analyses/decompiler/peephole_optimizations/rewrite_mips_gp_loads.py +49 -0
  176. angr/analyses/decompiler/peephole_optimizations/rol_ror.py +130 -0
  177. angr/analyses/decompiler/peephole_optimizations/sar_to_signed_div.py +112 -0
  178. angr/analyses/decompiler/peephole_optimizations/shl_to_mul.py +25 -0
  179. angr/analyses/decompiler/peephole_optimizations/simplify_pc_relative_loads.py +51 -0
  180. angr/analyses/decompiler/peephole_optimizations/single_bit_cond_to_boolexpr.py +53 -0
  181. angr/analyses/decompiler/peephole_optimizations/single_bit_xor.py +29 -0
  182. angr/analyses/decompiler/peephole_optimizations/tidy_stack_addr.py +131 -0
  183. angr/analyses/decompiler/peephole_optimizations/utils.py +18 -0
  184. angr/analyses/decompiler/presets/__init__.py +20 -0
  185. angr/analyses/decompiler/presets/basic.py +32 -0
  186. angr/analyses/decompiler/presets/fast.py +58 -0
  187. angr/analyses/decompiler/presets/full.py +68 -0
  188. angr/analyses/decompiler/presets/preset.py +37 -0
  189. angr/analyses/decompiler/redundant_label_remover.py +134 -0
  190. angr/analyses/decompiler/region_identifier.py +1218 -0
  191. angr/analyses/decompiler/region_simplifiers/__init__.py +5 -0
  192. angr/analyses/decompiler/region_simplifiers/cascading_cond_transformer.py +95 -0
  193. angr/analyses/decompiler/region_simplifiers/cascading_ifs.py +82 -0
  194. angr/analyses/decompiler/region_simplifiers/expr_folding.py +789 -0
  195. angr/analyses/decompiler/region_simplifiers/goto.py +178 -0
  196. angr/analyses/decompiler/region_simplifiers/if_.py +135 -0
  197. angr/analyses/decompiler/region_simplifiers/ifelse.py +91 -0
  198. angr/analyses/decompiler/region_simplifiers/loop.py +143 -0
  199. angr/analyses/decompiler/region_simplifiers/node_address_finder.py +24 -0
  200. angr/analyses/decompiler/region_simplifiers/region_simplifier.py +234 -0
  201. angr/analyses/decompiler/region_simplifiers/switch_cluster_simplifier.py +654 -0
  202. angr/analyses/decompiler/region_simplifiers/switch_expr_simplifier.py +87 -0
  203. angr/analyses/decompiler/region_walker.py +24 -0
  204. angr/analyses/decompiler/return_maker.py +72 -0
  205. angr/analyses/decompiler/seq_to_blocks.py +20 -0
  206. angr/analyses/decompiler/sequence_walker.py +257 -0
  207. angr/analyses/decompiler/ssailification/__init__.py +4 -0
  208. angr/analyses/decompiler/ssailification/rewriting.py +379 -0
  209. angr/analyses/decompiler/ssailification/rewriting_engine.py +1053 -0
  210. angr/analyses/decompiler/ssailification/rewriting_state.py +61 -0
  211. angr/analyses/decompiler/ssailification/ssailification.py +276 -0
  212. angr/analyses/decompiler/ssailification/traversal.py +124 -0
  213. angr/analyses/decompiler/ssailification/traversal_engine.py +297 -0
  214. angr/analyses/decompiler/ssailification/traversal_state.py +48 -0
  215. angr/analyses/decompiler/stack_item.py +36 -0
  216. angr/analyses/decompiler/structured_codegen/__init__.py +25 -0
  217. angr/analyses/decompiler/structured_codegen/base.py +132 -0
  218. angr/analyses/decompiler/structured_codegen/c.py +4069 -0
  219. angr/analyses/decompiler/structured_codegen/dummy.py +15 -0
  220. angr/analyses/decompiler/structured_codegen/dwarf_import.py +190 -0
  221. angr/analyses/decompiler/structuring/__init__.py +30 -0
  222. angr/analyses/decompiler/structuring/dream.py +1217 -0
  223. angr/analyses/decompiler/structuring/phoenix.py +2999 -0
  224. angr/analyses/decompiler/structuring/recursive_structurer.py +187 -0
  225. angr/analyses/decompiler/structuring/sailr.py +112 -0
  226. angr/analyses/decompiler/structuring/structurer_base.py +1067 -0
  227. angr/analyses/decompiler/structuring/structurer_nodes.py +438 -0
  228. angr/analyses/decompiler/utils.py +1106 -0
  229. angr/analyses/deobfuscator/__init__.py +18 -0
  230. angr/analyses/deobfuscator/api_obf_finder.py +325 -0
  231. angr/analyses/deobfuscator/api_obf_peephole_optimizer.py +51 -0
  232. angr/analyses/deobfuscator/api_obf_type2_finder.py +166 -0
  233. angr/analyses/deobfuscator/irsb_reg_collector.py +54 -0
  234. angr/analyses/deobfuscator/string_obf_finder.py +861 -0
  235. angr/analyses/deobfuscator/string_obf_opt_passes.py +133 -0
  236. angr/analyses/deobfuscator/string_obf_peephole_optimizer.py +47 -0
  237. angr/analyses/disassembly.py +1301 -0
  238. angr/analyses/disassembly_utils.py +101 -0
  239. angr/analyses/dominance_frontier.py +57 -0
  240. angr/analyses/fcp/__init__.py +4 -0
  241. angr/analyses/fcp/fcp.py +426 -0
  242. angr/analyses/find_objects_static.py +205 -0
  243. angr/analyses/flirt/__init__.py +47 -0
  244. angr/analyses/flirt/consts.py +160 -0
  245. angr/analyses/flirt/flirt.py +244 -0
  246. angr/analyses/flirt/flirt_function.py +20 -0
  247. angr/analyses/flirt/flirt_matcher.py +351 -0
  248. angr/analyses/flirt/flirt_module.py +32 -0
  249. angr/analyses/flirt/flirt_node.py +23 -0
  250. angr/analyses/flirt/flirt_sig.py +356 -0
  251. angr/analyses/flirt/flirt_utils.py +31 -0
  252. angr/analyses/forward_analysis/__init__.py +12 -0
  253. angr/analyses/forward_analysis/forward_analysis.py +530 -0
  254. angr/analyses/forward_analysis/job_info.py +64 -0
  255. angr/analyses/forward_analysis/visitors/__init__.py +14 -0
  256. angr/analyses/forward_analysis/visitors/call_graph.py +29 -0
  257. angr/analyses/forward_analysis/visitors/function_graph.py +86 -0
  258. angr/analyses/forward_analysis/visitors/graph.py +242 -0
  259. angr/analyses/forward_analysis/visitors/loop.py +29 -0
  260. angr/analyses/forward_analysis/visitors/single_node_graph.py +38 -0
  261. angr/analyses/identifier/__init__.py +5 -0
  262. angr/analyses/identifier/custom_callable.py +137 -0
  263. angr/analyses/identifier/errors.py +10 -0
  264. angr/analyses/identifier/func.py +60 -0
  265. angr/analyses/identifier/functions/__init__.py +37 -0
  266. angr/analyses/identifier/functions/atoi.py +73 -0
  267. angr/analyses/identifier/functions/based_atoi.py +125 -0
  268. angr/analyses/identifier/functions/fdprintf.py +123 -0
  269. angr/analyses/identifier/functions/free.py +64 -0
  270. angr/analyses/identifier/functions/int2str.py +287 -0
  271. angr/analyses/identifier/functions/malloc.py +111 -0
  272. angr/analyses/identifier/functions/memcmp.py +67 -0
  273. angr/analyses/identifier/functions/memcpy.py +89 -0
  274. angr/analyses/identifier/functions/memset.py +43 -0
  275. angr/analyses/identifier/functions/printf.py +123 -0
  276. angr/analyses/identifier/functions/recv_until.py +312 -0
  277. angr/analyses/identifier/functions/skip_calloc.py +73 -0
  278. angr/analyses/identifier/functions/skip_realloc.py +97 -0
  279. angr/analyses/identifier/functions/skip_recv_n.py +105 -0
  280. angr/analyses/identifier/functions/snprintf.py +112 -0
  281. angr/analyses/identifier/functions/sprintf.py +116 -0
  282. angr/analyses/identifier/functions/strcasecmp.py +33 -0
  283. angr/analyses/identifier/functions/strcmp.py +113 -0
  284. angr/analyses/identifier/functions/strcpy.py +43 -0
  285. angr/analyses/identifier/functions/strlen.py +27 -0
  286. angr/analyses/identifier/functions/strncmp.py +104 -0
  287. angr/analyses/identifier/functions/strncpy.py +65 -0
  288. angr/analyses/identifier/functions/strtol.py +89 -0
  289. angr/analyses/identifier/identify.py +825 -0
  290. angr/analyses/identifier/runner.py +360 -0
  291. angr/analyses/init_finder.py +289 -0
  292. angr/analyses/loop_analysis.py +349 -0
  293. angr/analyses/loopfinder.py +171 -0
  294. angr/analyses/patchfinder.py +137 -0
  295. angr/analyses/pathfinder.py +282 -0
  296. angr/analyses/propagator/__init__.py +5 -0
  297. angr/analyses/propagator/engine_base.py +62 -0
  298. angr/analyses/propagator/engine_vex.py +297 -0
  299. angr/analyses/propagator/propagator.py +361 -0
  300. angr/analyses/propagator/top_checker_mixin.py +218 -0
  301. angr/analyses/propagator/values.py +117 -0
  302. angr/analyses/propagator/vex_vars.py +68 -0
  303. angr/analyses/proximity_graph.py +444 -0
  304. angr/analyses/reaching_definitions/__init__.py +67 -0
  305. angr/analyses/reaching_definitions/call_trace.py +73 -0
  306. angr/analyses/reaching_definitions/dep_graph.py +433 -0
  307. angr/analyses/reaching_definitions/engine_ail.py +1130 -0
  308. angr/analyses/reaching_definitions/engine_vex.py +1127 -0
  309. angr/analyses/reaching_definitions/external_codeloc.py +0 -0
  310. angr/analyses/reaching_definitions/function_handler.py +637 -0
  311. angr/analyses/reaching_definitions/function_handler_library/__init__.py +12 -0
  312. angr/analyses/reaching_definitions/function_handler_library/stdio.py +268 -0
  313. angr/analyses/reaching_definitions/function_handler_library/stdlib.py +189 -0
  314. angr/analyses/reaching_definitions/function_handler_library/string.py +147 -0
  315. angr/analyses/reaching_definitions/function_handler_library/unistd.py +44 -0
  316. angr/analyses/reaching_definitions/heap_allocator.py +70 -0
  317. angr/analyses/reaching_definitions/rd_initializer.py +237 -0
  318. angr/analyses/reaching_definitions/rd_state.py +579 -0
  319. angr/analyses/reaching_definitions/reaching_definitions.py +581 -0
  320. angr/analyses/reaching_definitions/subject.py +65 -0
  321. angr/analyses/reassembler.py +2900 -0
  322. angr/analyses/s_liveness.py +203 -0
  323. angr/analyses/s_propagator.py +544 -0
  324. angr/analyses/s_reaching_definitions/__init__.py +12 -0
  325. angr/analyses/s_reaching_definitions/s_rda_model.py +135 -0
  326. angr/analyses/s_reaching_definitions/s_rda_view.py +315 -0
  327. angr/analyses/s_reaching_definitions/s_reaching_definitions.py +174 -0
  328. angr/analyses/smc.py +161 -0
  329. angr/analyses/soot_class_hierarchy.py +273 -0
  330. angr/analyses/stack_pointer_tracker.py +957 -0
  331. angr/analyses/static_hooker.py +53 -0
  332. angr/analyses/typehoon/__init__.py +5 -0
  333. angr/analyses/typehoon/dfa.py +118 -0
  334. angr/analyses/typehoon/lifter.py +122 -0
  335. angr/analyses/typehoon/simple_solver.py +1450 -0
  336. angr/analyses/typehoon/translator.py +279 -0
  337. angr/analyses/typehoon/typeconsts.py +336 -0
  338. angr/analyses/typehoon/typehoon.py +305 -0
  339. angr/analyses/typehoon/typevars.py +578 -0
  340. angr/analyses/typehoon/variance.py +11 -0
  341. angr/analyses/unpacker/__init__.py +6 -0
  342. angr/analyses/unpacker/obfuscation_detector.py +103 -0
  343. angr/analyses/unpacker/packing_detector.py +138 -0
  344. angr/analyses/variable_recovery/__init__.py +9 -0
  345. angr/analyses/variable_recovery/annotations.py +58 -0
  346. angr/analyses/variable_recovery/engine_ail.py +891 -0
  347. angr/analyses/variable_recovery/engine_base.py +1185 -0
  348. angr/analyses/variable_recovery/engine_vex.py +593 -0
  349. angr/analyses/variable_recovery/irsb_scanner.py +143 -0
  350. angr/analyses/variable_recovery/variable_recovery.py +573 -0
  351. angr/analyses/variable_recovery/variable_recovery_base.py +461 -0
  352. angr/analyses/variable_recovery/variable_recovery_fast.py +652 -0
  353. angr/analyses/veritesting.py +626 -0
  354. angr/analyses/vfg.py +1898 -0
  355. angr/analyses/vsa_ddg.py +420 -0
  356. angr/analyses/vtable.py +92 -0
  357. angr/analyses/xrefs.py +286 -0
  358. angr/angrdb/__init__.py +14 -0
  359. angr/angrdb/db.py +206 -0
  360. angr/angrdb/models.py +184 -0
  361. angr/angrdb/serializers/__init__.py +10 -0
  362. angr/angrdb/serializers/cfg_model.py +41 -0
  363. angr/angrdb/serializers/comments.py +60 -0
  364. angr/angrdb/serializers/funcs.py +61 -0
  365. angr/angrdb/serializers/kb.py +111 -0
  366. angr/angrdb/serializers/labels.py +59 -0
  367. angr/angrdb/serializers/loader.py +165 -0
  368. angr/angrdb/serializers/structured_code.py +125 -0
  369. angr/angrdb/serializers/variables.py +58 -0
  370. angr/angrdb/serializers/xrefs.py +48 -0
  371. angr/annocfg.py +317 -0
  372. angr/blade.py +426 -0
  373. angr/block.py +509 -0
  374. angr/callable.py +168 -0
  375. angr/calling_conventions.py +2580 -0
  376. angr/code_location.py +163 -0
  377. angr/codenode.py +145 -0
  378. angr/concretization_strategies/__init__.py +32 -0
  379. angr/concretization_strategies/any.py +17 -0
  380. angr/concretization_strategies/any_named.py +35 -0
  381. angr/concretization_strategies/base.py +81 -0
  382. angr/concretization_strategies/controlled_data.py +58 -0
  383. angr/concretization_strategies/eval.py +19 -0
  384. angr/concretization_strategies/logging.py +35 -0
  385. angr/concretization_strategies/max.py +25 -0
  386. angr/concretization_strategies/nonzero.py +16 -0
  387. angr/concretization_strategies/nonzero_range.py +22 -0
  388. angr/concretization_strategies/norepeats.py +37 -0
  389. angr/concretization_strategies/norepeats_range.py +37 -0
  390. angr/concretization_strategies/range.py +19 -0
  391. angr/concretization_strategies/signed_add.py +31 -0
  392. angr/concretization_strategies/single.py +15 -0
  393. angr/concretization_strategies/solutions.py +20 -0
  394. angr/concretization_strategies/unlimited_range.py +17 -0
  395. angr/distributed/__init__.py +9 -0
  396. angr/distributed/server.py +197 -0
  397. angr/distributed/worker.py +185 -0
  398. angr/engines/__init__.py +67 -0
  399. angr/engines/engine.py +29 -0
  400. angr/engines/failure.py +27 -0
  401. angr/engines/hook.py +68 -0
  402. angr/engines/light/__init__.py +23 -0
  403. angr/engines/light/data.py +681 -0
  404. angr/engines/light/engine.py +1285 -0
  405. angr/engines/pcode/__init__.py +9 -0
  406. angr/engines/pcode/behavior.py +997 -0
  407. angr/engines/pcode/cc.py +128 -0
  408. angr/engines/pcode/emulate.py +443 -0
  409. angr/engines/pcode/engine.py +242 -0
  410. angr/engines/pcode/lifter.py +1428 -0
  411. angr/engines/procedure.py +70 -0
  412. angr/engines/soot/__init__.py +5 -0
  413. angr/engines/soot/engine.py +410 -0
  414. angr/engines/soot/exceptions.py +17 -0
  415. angr/engines/soot/expressions/__init__.py +87 -0
  416. angr/engines/soot/expressions/arrayref.py +22 -0
  417. angr/engines/soot/expressions/base.py +21 -0
  418. angr/engines/soot/expressions/binop.py +28 -0
  419. angr/engines/soot/expressions/cast.py +22 -0
  420. angr/engines/soot/expressions/condition.py +35 -0
  421. angr/engines/soot/expressions/constants.py +47 -0
  422. angr/engines/soot/expressions/instanceOf.py +15 -0
  423. angr/engines/soot/expressions/instancefieldref.py +8 -0
  424. angr/engines/soot/expressions/invoke.py +114 -0
  425. angr/engines/soot/expressions/length.py +8 -0
  426. angr/engines/soot/expressions/local.py +8 -0
  427. angr/engines/soot/expressions/new.py +16 -0
  428. angr/engines/soot/expressions/newArray.py +54 -0
  429. angr/engines/soot/expressions/newMultiArray.py +86 -0
  430. angr/engines/soot/expressions/paramref.py +8 -0
  431. angr/engines/soot/expressions/phi.py +30 -0
  432. angr/engines/soot/expressions/staticfieldref.py +8 -0
  433. angr/engines/soot/expressions/thisref.py +7 -0
  434. angr/engines/soot/expressions/unsupported.py +7 -0
  435. angr/engines/soot/field_dispatcher.py +46 -0
  436. angr/engines/soot/method_dispatcher.py +46 -0
  437. angr/engines/soot/statements/__init__.py +44 -0
  438. angr/engines/soot/statements/assign.py +30 -0
  439. angr/engines/soot/statements/base.py +79 -0
  440. angr/engines/soot/statements/goto.py +14 -0
  441. angr/engines/soot/statements/identity.py +15 -0
  442. angr/engines/soot/statements/if_.py +19 -0
  443. angr/engines/soot/statements/invoke.py +12 -0
  444. angr/engines/soot/statements/return_.py +20 -0
  445. angr/engines/soot/statements/switch.py +41 -0
  446. angr/engines/soot/statements/throw.py +15 -0
  447. angr/engines/soot/values/__init__.py +38 -0
  448. angr/engines/soot/values/arrayref.py +122 -0
  449. angr/engines/soot/values/base.py +7 -0
  450. angr/engines/soot/values/constants.py +18 -0
  451. angr/engines/soot/values/instancefieldref.py +44 -0
  452. angr/engines/soot/values/local.py +18 -0
  453. angr/engines/soot/values/paramref.py +18 -0
  454. angr/engines/soot/values/staticfieldref.py +38 -0
  455. angr/engines/soot/values/strref.py +38 -0
  456. angr/engines/soot/values/thisref.py +149 -0
  457. angr/engines/successors.py +654 -0
  458. angr/engines/syscall.py +51 -0
  459. angr/engines/unicorn.py +490 -0
  460. angr/engines/vex/__init__.py +20 -0
  461. angr/engines/vex/claripy/__init__.py +5 -0
  462. angr/engines/vex/claripy/ccall.py +2097 -0
  463. angr/engines/vex/claripy/datalayer.py +141 -0
  464. angr/engines/vex/claripy/irop.py +1276 -0
  465. angr/engines/vex/heavy/__init__.py +16 -0
  466. angr/engines/vex/heavy/actions.py +231 -0
  467. angr/engines/vex/heavy/concretizers.py +403 -0
  468. angr/engines/vex/heavy/dirty.py +466 -0
  469. angr/engines/vex/heavy/heavy.py +370 -0
  470. angr/engines/vex/heavy/inspect.py +52 -0
  471. angr/engines/vex/heavy/resilience.py +85 -0
  472. angr/engines/vex/heavy/super_fastpath.py +34 -0
  473. angr/engines/vex/lifter.py +420 -0
  474. angr/engines/vex/light/__init__.py +11 -0
  475. angr/engines/vex/light/light.py +551 -0
  476. angr/engines/vex/light/resilience.py +74 -0
  477. angr/engines/vex/light/slicing.py +52 -0
  478. angr/errors.py +609 -0
  479. angr/exploration_techniques/__init__.py +53 -0
  480. angr/exploration_techniques/base.py +126 -0
  481. angr/exploration_techniques/bucketizer.py +94 -0
  482. angr/exploration_techniques/common.py +56 -0
  483. angr/exploration_techniques/dfs.py +37 -0
  484. angr/exploration_techniques/director.py +520 -0
  485. angr/exploration_techniques/driller_core.py +100 -0
  486. angr/exploration_techniques/explorer.py +152 -0
  487. angr/exploration_techniques/lengthlimiter.py +22 -0
  488. angr/exploration_techniques/local_loop_seer.py +65 -0
  489. angr/exploration_techniques/loop_seer.py +236 -0
  490. angr/exploration_techniques/manual_mergepoint.py +82 -0
  491. angr/exploration_techniques/memory_watcher.py +43 -0
  492. angr/exploration_techniques/oppologist.py +92 -0
  493. angr/exploration_techniques/slicecutor.py +118 -0
  494. angr/exploration_techniques/spiller.py +280 -0
  495. angr/exploration_techniques/spiller_db.py +27 -0
  496. angr/exploration_techniques/stochastic.py +56 -0
  497. angr/exploration_techniques/stub_stasher.py +19 -0
  498. angr/exploration_techniques/suggestions.py +159 -0
  499. angr/exploration_techniques/tech_builder.py +49 -0
  500. angr/exploration_techniques/threading.py +69 -0
  501. angr/exploration_techniques/timeout.py +34 -0
  502. angr/exploration_techniques/tracer.py +1098 -0
  503. angr/exploration_techniques/unique.py +106 -0
  504. angr/exploration_techniques/veritesting.py +37 -0
  505. angr/factory.py +404 -0
  506. angr/flirt/__init__.py +97 -0
  507. angr/flirt/build_sig.py +305 -0
  508. angr/graph_utils.py +0 -0
  509. angr/keyed_region.py +525 -0
  510. angr/knowledge_base.py +143 -0
  511. angr/knowledge_plugins/__init__.py +43 -0
  512. angr/knowledge_plugins/callsite_prototypes.py +53 -0
  513. angr/knowledge_plugins/cfg/__init__.py +18 -0
  514. angr/knowledge_plugins/cfg/cfg_manager.py +95 -0
  515. angr/knowledge_plugins/cfg/cfg_model.py +1045 -0
  516. angr/knowledge_plugins/cfg/cfg_node.py +536 -0
  517. angr/knowledge_plugins/cfg/indirect_jump.py +65 -0
  518. angr/knowledge_plugins/cfg/memory_data.py +156 -0
  519. angr/knowledge_plugins/comments.py +16 -0
  520. angr/knowledge_plugins/custom_strings.py +38 -0
  521. angr/knowledge_plugins/data.py +22 -0
  522. angr/knowledge_plugins/debug_variables.py +216 -0
  523. angr/knowledge_plugins/functions/__init__.py +9 -0
  524. angr/knowledge_plugins/functions/function.py +1772 -0
  525. angr/knowledge_plugins/functions/function_manager.py +526 -0
  526. angr/knowledge_plugins/functions/function_parser.py +299 -0
  527. angr/knowledge_plugins/functions/soot_function.py +128 -0
  528. angr/knowledge_plugins/indirect_jumps.py +35 -0
  529. angr/knowledge_plugins/key_definitions/__init__.py +17 -0
  530. angr/knowledge_plugins/key_definitions/atoms.py +374 -0
  531. angr/knowledge_plugins/key_definitions/constants.py +29 -0
  532. angr/knowledge_plugins/key_definitions/definition.py +214 -0
  533. angr/knowledge_plugins/key_definitions/environment.py +96 -0
  534. angr/knowledge_plugins/key_definitions/heap_address.py +33 -0
  535. angr/knowledge_plugins/key_definitions/key_definition_manager.py +82 -0
  536. angr/knowledge_plugins/key_definitions/live_definitions.py +1010 -0
  537. angr/knowledge_plugins/key_definitions/liveness.py +165 -0
  538. angr/knowledge_plugins/key_definitions/rd_model.py +171 -0
  539. angr/knowledge_plugins/key_definitions/tag.py +78 -0
  540. angr/knowledge_plugins/key_definitions/undefined.py +70 -0
  541. angr/knowledge_plugins/key_definitions/unknown_size.py +86 -0
  542. angr/knowledge_plugins/key_definitions/uses.py +178 -0
  543. angr/knowledge_plugins/labels.py +110 -0
  544. angr/knowledge_plugins/obfuscations.py +37 -0
  545. angr/knowledge_plugins/patches.py +126 -0
  546. angr/knowledge_plugins/plugin.py +24 -0
  547. angr/knowledge_plugins/propagations/__init__.py +10 -0
  548. angr/knowledge_plugins/propagations/prop_value.py +191 -0
  549. angr/knowledge_plugins/propagations/propagation_manager.py +60 -0
  550. angr/knowledge_plugins/propagations/propagation_model.py +73 -0
  551. angr/knowledge_plugins/propagations/states.py +552 -0
  552. angr/knowledge_plugins/structured_code.py +63 -0
  553. angr/knowledge_plugins/types.py +88 -0
  554. angr/knowledge_plugins/variables/__init__.py +8 -0
  555. angr/knowledge_plugins/variables/variable_access.py +113 -0
  556. angr/knowledge_plugins/variables/variable_manager.py +1368 -0
  557. angr/knowledge_plugins/xrefs/__init__.py +12 -0
  558. angr/knowledge_plugins/xrefs/xref.py +150 -0
  559. angr/knowledge_plugins/xrefs/xref_manager.py +127 -0
  560. angr/knowledge_plugins/xrefs/xref_types.py +16 -0
  561. angr/lib/angr_native.so +0 -0
  562. angr/misc/__init__.py +19 -0
  563. angr/misc/ansi.py +47 -0
  564. angr/misc/autoimport.py +90 -0
  565. angr/misc/bug_report.py +117 -0
  566. angr/misc/hookset.py +106 -0
  567. angr/misc/loggers.py +130 -0
  568. angr/misc/picklable_lock.py +46 -0
  569. angr/misc/plugins.py +289 -0
  570. angr/misc/telemetry.py +54 -0
  571. angr/misc/testing.py +24 -0
  572. angr/misc/ux.py +31 -0
  573. angr/procedures/__init__.py +12 -0
  574. angr/procedures/advapi32/__init__.py +0 -0
  575. angr/procedures/cgc/__init__.py +3 -0
  576. angr/procedures/cgc/_terminate.py +11 -0
  577. angr/procedures/cgc/allocate.py +75 -0
  578. angr/procedures/cgc/deallocate.py +67 -0
  579. angr/procedures/cgc/fdwait.py +65 -0
  580. angr/procedures/cgc/random.py +67 -0
  581. angr/procedures/cgc/receive.py +93 -0
  582. angr/procedures/cgc/transmit.py +65 -0
  583. angr/procedures/definitions/__init__.py +779 -0
  584. angr/procedures/definitions/cgc.py +20 -0
  585. angr/procedures/definitions/glibc.py +8372 -0
  586. angr/procedures/definitions/gnulib.py +32 -0
  587. angr/procedures/definitions/libstdcpp.py +21 -0
  588. angr/procedures/definitions/linux_kernel.py +6171 -0
  589. angr/procedures/definitions/linux_loader.py +7 -0
  590. angr/procedures/definitions/msvcr.py +16 -0
  591. angr/procedures/definitions/parse_syscalls_from_local_system.py +50 -0
  592. angr/procedures/definitions/parse_win32json.py +2553 -0
  593. angr/procedures/definitions/types_stl.py +22 -0
  594. angr/procedures/definitions/types_win32.py +34482 -0
  595. angr/procedures/definitions/wdk_api-ms-win-dx-d3dkmt-l1-1-4.py +30 -0
  596. angr/procedures/definitions/wdk_api-ms-win-dx-d3dkmt-l1-1-6.py +26 -0
  597. angr/procedures/definitions/wdk_clfs.py +140 -0
  598. angr/procedures/definitions/wdk_fltmgr.py +556 -0
  599. angr/procedures/definitions/wdk_fwpkclnt.py +30 -0
  600. angr/procedures/definitions/wdk_fwpuclnt.py +316 -0
  601. angr/procedures/definitions/wdk_gdi32.py +366 -0
  602. angr/procedures/definitions/wdk_hal.py +78 -0
  603. angr/procedures/definitions/wdk_ksecdd.py +62 -0
  604. angr/procedures/definitions/wdk_ndis.py +238 -0
  605. angr/procedures/definitions/wdk_ntoskrnl.py +3451 -0
  606. angr/procedures/definitions/wdk_offreg.py +72 -0
  607. angr/procedures/definitions/wdk_pshed.py +36 -0
  608. angr/procedures/definitions/wdk_secur32.py +40 -0
  609. angr/procedures/definitions/wdk_vhfum.py +34 -0
  610. angr/procedures/definitions/win32_aclui.py +30 -0
  611. angr/procedures/definitions/win32_activeds.py +68 -0
  612. angr/procedures/definitions/win32_advapi32.py +1684 -0
  613. angr/procedures/definitions/win32_advpack.py +124 -0
  614. angr/procedures/definitions/win32_amsi.py +38 -0
  615. angr/procedures/definitions/win32_api-ms-win-appmodel-runtime-l1-1-1.py +44 -0
  616. angr/procedures/definitions/win32_api-ms-win-appmodel-runtime-l1-1-3.py +34 -0
  617. angr/procedures/definitions/win32_api-ms-win-appmodel-runtime-l1-1-6.py +26 -0
  618. angr/procedures/definitions/win32_api-ms-win-core-apiquery-l2-1-0.py +26 -0
  619. angr/procedures/definitions/win32_api-ms-win-core-backgroundtask-l1-1-0.py +26 -0
  620. angr/procedures/definitions/win32_api-ms-win-core-comm-l1-1-1.py +26 -0
  621. angr/procedures/definitions/win32_api-ms-win-core-comm-l1-1-2.py +26 -0
  622. angr/procedures/definitions/win32_api-ms-win-core-enclave-l1-1-1.py +30 -0
  623. angr/procedures/definitions/win32_api-ms-win-core-errorhandling-l1-1-3.py +26 -0
  624. angr/procedures/definitions/win32_api-ms-win-core-featurestaging-l1-1-0.py +34 -0
  625. angr/procedures/definitions/win32_api-ms-win-core-featurestaging-l1-1-1.py +26 -0
  626. angr/procedures/definitions/win32_api-ms-win-core-file-fromapp-l1-1-0.py +46 -0
  627. angr/procedures/definitions/win32_api-ms-win-core-handle-l1-1-0.py +26 -0
  628. angr/procedures/definitions/win32_api-ms-win-core-ioring-l1-1-0.py +48 -0
  629. angr/procedures/definitions/win32_api-ms-win-core-marshal-l1-1-0.py +32 -0
  630. angr/procedures/definitions/win32_api-ms-win-core-memory-l1-1-3.py +32 -0
  631. angr/procedures/definitions/win32_api-ms-win-core-memory-l1-1-4.py +26 -0
  632. angr/procedures/definitions/win32_api-ms-win-core-memory-l1-1-5.py +30 -0
  633. angr/procedures/definitions/win32_api-ms-win-core-memory-l1-1-6.py +32 -0
  634. angr/procedures/definitions/win32_api-ms-win-core-memory-l1-1-7.py +28 -0
  635. angr/procedures/definitions/win32_api-ms-win-core-memory-l1-1-8.py +30 -0
  636. angr/procedures/definitions/win32_api-ms-win-core-path-l1-1-0.py +68 -0
  637. angr/procedures/definitions/win32_api-ms-win-core-psm-appnotify-l1-1-0.py +28 -0
  638. angr/procedures/definitions/win32_api-ms-win-core-psm-appnotify-l1-1-1.py +28 -0
  639. angr/procedures/definitions/win32_api-ms-win-core-realtime-l1-1-1.py +30 -0
  640. angr/procedures/definitions/win32_api-ms-win-core-realtime-l1-1-2.py +30 -0
  641. angr/procedures/definitions/win32_api-ms-win-core-slapi-l1-1-0.py +26 -0
  642. angr/procedures/definitions/win32_api-ms-win-core-state-helpers-l1-1-0.py +26 -0
  643. angr/procedures/definitions/win32_api-ms-win-core-synch-l1-2-0.py +30 -0
  644. angr/procedures/definitions/win32_api-ms-win-core-sysinfo-l1-2-0.py +26 -0
  645. angr/procedures/definitions/win32_api-ms-win-core-sysinfo-l1-2-3.py +28 -0
  646. angr/procedures/definitions/win32_api-ms-win-core-sysinfo-l1-2-4.py +28 -0
  647. angr/procedures/definitions/win32_api-ms-win-core-sysinfo-l1-2-6.py +26 -0
  648. angr/procedures/definitions/win32_api-ms-win-core-util-l1-1-1.py +28 -0
  649. angr/procedures/definitions/win32_api-ms-win-core-winrt-error-l1-1-0.py +44 -0
  650. angr/procedures/definitions/win32_api-ms-win-core-winrt-error-l1-1-1.py +38 -0
  651. angr/procedures/definitions/win32_api-ms-win-core-winrt-l1-1-0.py +40 -0
  652. angr/procedures/definitions/win32_api-ms-win-core-winrt-registration-l1-1-0.py +24 -0
  653. angr/procedures/definitions/win32_api-ms-win-core-winrt-robuffer-l1-1-0.py +24 -0
  654. angr/procedures/definitions/win32_api-ms-win-core-winrt-roparameterizediid-l1-1-0.py +28 -0
  655. angr/procedures/definitions/win32_api-ms-win-core-winrt-string-l1-1-0.py +76 -0
  656. angr/procedures/definitions/win32_api-ms-win-core-winrt-string-l1-1-1.py +24 -0
  657. angr/procedures/definitions/win32_api-ms-win-core-wow64-l1-1-1.py +30 -0
  658. angr/procedures/definitions/win32_api-ms-win-devices-query-l1-1-0.py +42 -0
  659. angr/procedures/definitions/win32_api-ms-win-devices-query-l1-1-1.py +34 -0
  660. angr/procedures/definitions/win32_api-ms-win-dx-d3dkmt-l1-1-0.py +26 -0
  661. angr/procedures/definitions/win32_api-ms-win-gaming-deviceinformation-l1-1-0.py +26 -0
  662. angr/procedures/definitions/win32_api-ms-win-gaming-expandedresources-l1-1-0.py +30 -0
  663. angr/procedures/definitions/win32_api-ms-win-gaming-tcui-l1-1-0.py +38 -0
  664. angr/procedures/definitions/win32_api-ms-win-gaming-tcui-l1-1-1.py +28 -0
  665. angr/procedures/definitions/win32_api-ms-win-gaming-tcui-l1-1-2.py +38 -0
  666. angr/procedures/definitions/win32_api-ms-win-gaming-tcui-l1-1-3.py +28 -0
  667. angr/procedures/definitions/win32_api-ms-win-gaming-tcui-l1-1-4.py +40 -0
  668. angr/procedures/definitions/win32_api-ms-win-mm-misc-l1-1-1.py +26 -0
  669. angr/procedures/definitions/win32_api-ms-win-net-isolation-l1-1-0.py +40 -0
  670. angr/procedures/definitions/win32_api-ms-win-security-base-l1-2-2.py +26 -0
  671. angr/procedures/definitions/win32_api-ms-win-security-isolatedcontainer-l1-1-0.py +26 -0
  672. angr/procedures/definitions/win32_api-ms-win-security-isolatedcontainer-l1-1-1.py +26 -0
  673. angr/procedures/definitions/win32_api-ms-win-service-core-l1-1-3.py +26 -0
  674. angr/procedures/definitions/win32_api-ms-win-service-core-l1-1-4.py +26 -0
  675. angr/procedures/definitions/win32_api-ms-win-service-core-l1-1-5.py +28 -0
  676. angr/procedures/definitions/win32_api-ms-win-shcore-scaling-l1-1-0.py +30 -0
  677. angr/procedures/definitions/win32_api-ms-win-shcore-scaling-l1-1-1.py +36 -0
  678. angr/procedures/definitions/win32_api-ms-win-shcore-scaling-l1-1-2.py +26 -0
  679. angr/procedures/definitions/win32_api-ms-win-shcore-stream-winrt-l1-1-0.py +28 -0
  680. angr/procedures/definitions/win32_api-ms-win-wsl-api-l1-1-0.py +38 -0
  681. angr/procedures/definitions/win32_apphelp.py +26 -0
  682. angr/procedures/definitions/win32_authz.py +90 -0
  683. angr/procedures/definitions/win32_avicap32.py +32 -0
  684. angr/procedures/definitions/win32_avifil32.py +144 -0
  685. angr/procedures/definitions/win32_avrt.py +52 -0
  686. angr/procedures/definitions/win32_bcp47mrm.py +28 -0
  687. angr/procedures/definitions/win32_bcrypt.py +130 -0
  688. angr/procedures/definitions/win32_bcryptprimitives.py +28 -0
  689. angr/procedures/definitions/win32_bluetoothapis.py +106 -0
  690. angr/procedures/definitions/win32_bthprops.py +34 -0
  691. angr/procedures/definitions/win32_bthprops_cpl.py +36 -0
  692. angr/procedures/definitions/win32_cabinet.py +68 -0
  693. angr/procedures/definitions/win32_certadm.py +60 -0
  694. angr/procedures/definitions/win32_certpoleng.py +40 -0
  695. angr/procedures/definitions/win32_cfgmgr32.py +502 -0
  696. angr/procedures/definitions/win32_chakra.py +198 -0
  697. angr/procedures/definitions/win32_cldapi.py +96 -0
  698. angr/procedures/definitions/win32_clfsw32.py +142 -0
  699. angr/procedures/definitions/win32_clusapi.py +584 -0
  700. angr/procedures/definitions/win32_comctl32.py +254 -0
  701. angr/procedures/definitions/win32_comdlg32.py +66 -0
  702. angr/procedures/definitions/win32_compstui.py +32 -0
  703. angr/procedures/definitions/win32_computecore.py +132 -0
  704. angr/procedures/definitions/win32_computenetwork.py +110 -0
  705. angr/procedures/definitions/win32_computestorage.py +48 -0
  706. angr/procedures/definitions/win32_comsvcs.py +38 -0
  707. angr/procedures/definitions/win32_coremessaging.py +24 -0
  708. angr/procedures/definitions/win32_credui.py +62 -0
  709. angr/procedures/definitions/win32_crypt32.py +482 -0
  710. angr/procedures/definitions/win32_cryptnet.py +34 -0
  711. angr/procedures/definitions/win32_cryptui.py +44 -0
  712. angr/procedures/definitions/win32_cryptxml.py +62 -0
  713. angr/procedures/definitions/win32_cscapi.py +32 -0
  714. angr/procedures/definitions/win32_d2d1.py +50 -0
  715. angr/procedures/definitions/win32_d3d10.py +78 -0
  716. angr/procedures/definitions/win32_d3d10_1.py +28 -0
  717. angr/procedures/definitions/win32_d3d11.py +30 -0
  718. angr/procedures/definitions/win32_d3d12.py +40 -0
  719. angr/procedures/definitions/win32_d3d9.py +46 -0
  720. angr/procedures/definitions/win32_d3dcompiler_47.py +76 -0
  721. angr/procedures/definitions/win32_d3dcsx.py +42 -0
  722. angr/procedures/definitions/win32_davclnt.py +60 -0
  723. angr/procedures/definitions/win32_dbgeng.py +32 -0
  724. angr/procedures/definitions/win32_dbghelp.py +462 -0
  725. angr/procedures/definitions/win32_dbgmodel.py +26 -0
  726. angr/procedures/definitions/win32_dciman32.py +64 -0
  727. angr/procedures/definitions/win32_dcomp.py +48 -0
  728. angr/procedures/definitions/win32_ddraw.py +38 -0
  729. angr/procedures/definitions/win32_deviceaccess.py +26 -0
  730. angr/procedures/definitions/win32_dflayout.py +26 -0
  731. angr/procedures/definitions/win32_dhcpcsvc.py +54 -0
  732. angr/procedures/definitions/win32_dhcpcsvc6.py +36 -0
  733. angr/procedures/definitions/win32_dhcpsapi.py +416 -0
  734. angr/procedures/definitions/win32_diagnosticdataquery.py +94 -0
  735. angr/procedures/definitions/win32_dinput8.py +26 -0
  736. angr/procedures/definitions/win32_directml.py +28 -0
  737. angr/procedures/definitions/win32_dmprocessxmlfiltered.py +26 -0
  738. angr/procedures/definitions/win32_dnsapi.py +152 -0
  739. angr/procedures/definitions/win32_drt.py +56 -0
  740. angr/procedures/definitions/win32_drtprov.py +42 -0
  741. angr/procedures/definitions/win32_drttransport.py +28 -0
  742. angr/procedures/definitions/win32_dsound.py +44 -0
  743. angr/procedures/definitions/win32_dsparse.py +62 -0
  744. angr/procedures/definitions/win32_dsprop.py +38 -0
  745. angr/procedures/definitions/win32_dssec.py +32 -0
  746. angr/procedures/definitions/win32_dsuiext.py +32 -0
  747. angr/procedures/definitions/win32_dwmapi.py +86 -0
  748. angr/procedures/definitions/win32_dwrite.py +26 -0
  749. angr/procedures/definitions/win32_dxcompiler.py +28 -0
  750. angr/procedures/definitions/win32_dxcore.py +26 -0
  751. angr/procedures/definitions/win32_dxgi.py +36 -0
  752. angr/procedures/definitions/win32_dxva2.py +100 -0
  753. angr/procedures/definitions/win32_eappcfg.py +52 -0
  754. angr/procedures/definitions/win32_eappprxy.py +60 -0
  755. angr/procedures/definitions/win32_efswrt.py +28 -0
  756. angr/procedures/definitions/win32_elscore.py +34 -0
  757. angr/procedures/definitions/win32_esent.py +482 -0
  758. angr/procedures/definitions/win32_evr.py +38 -0
  759. angr/procedures/definitions/win32_faultrep.py +32 -0
  760. angr/procedures/definitions/win32_fhsvcctl.py +38 -0
  761. angr/procedures/definitions/win32_firewallapi.py +30 -0
  762. angr/procedures/definitions/win32_fltlib.py +80 -0
  763. angr/procedures/definitions/win32_fontsub.py +28 -0
  764. angr/procedures/definitions/win32_forceinline.py +30 -0
  765. angr/procedures/definitions/win32_fwpuclnt.py +408 -0
  766. angr/procedures/definitions/win32_fxsutility.py +28 -0
  767. angr/procedures/definitions/win32_gdi32.py +886 -0
  768. angr/procedures/definitions/win32_gdiplus.py +1282 -0
  769. angr/procedures/definitions/win32_glu32.py +128 -0
  770. angr/procedures/definitions/win32_gpedit.py +36 -0
  771. angr/procedures/definitions/win32_hhctrl_ocx.py +28 -0
  772. angr/procedures/definitions/win32_hid.py +114 -0
  773. angr/procedures/definitions/win32_hlink.py +80 -0
  774. angr/procedures/definitions/win32_hrtfapo.py +26 -0
  775. angr/procedures/definitions/win32_httpapi.py +110 -0
  776. angr/procedures/definitions/win32_icm32.py +66 -0
  777. angr/procedures/definitions/win32_icmui.py +28 -0
  778. angr/procedures/definitions/win32_icu.py +2074 -0
  779. angr/procedures/definitions/win32_ieframe.py +82 -0
  780. angr/procedures/definitions/win32_imagehlp.py +76 -0
  781. angr/procedures/definitions/win32_imgutil.py +42 -0
  782. angr/procedures/definitions/win32_imm32.py +188 -0
  783. angr/procedures/definitions/win32_infocardapi.py +58 -0
  784. angr/procedures/definitions/win32_inkobjcore.py +78 -0
  785. angr/procedures/definitions/win32_iphlpapi.py +426 -0
  786. angr/procedures/definitions/win32_iscsidsc.py +182 -0
  787. angr/procedures/definitions/win32_isolatedwindowsenvironmentutils.py +28 -0
  788. angr/procedures/definitions/win32_kernel32.py +3185 -0
  789. angr/procedures/definitions/win32_kernelbase.py +36 -0
  790. angr/procedures/definitions/win32_keycredmgr.py +32 -0
  791. angr/procedures/definitions/win32_ksproxy_ax.py +36 -0
  792. angr/procedures/definitions/win32_ksuser.py +40 -0
  793. angr/procedures/definitions/win32_ktmw32.py +102 -0
  794. angr/procedures/definitions/win32_licenseprotection.py +28 -0
  795. angr/procedures/definitions/win32_loadperf.py +48 -0
  796. angr/procedures/definitions/win32_magnification.py +62 -0
  797. angr/procedures/definitions/win32_mapi32.py +156 -0
  798. angr/procedures/definitions/win32_mdmlocalmanagement.py +30 -0
  799. angr/procedures/definitions/win32_mdmregistration.py +54 -0
  800. angr/procedures/definitions/win32_mf.py +148 -0
  801. angr/procedures/definitions/win32_mfcore.py +28 -0
  802. angr/procedures/definitions/win32_mfplat.py +314 -0
  803. angr/procedures/definitions/win32_mfplay.py +26 -0
  804. angr/procedures/definitions/win32_mfreadwrite.py +34 -0
  805. angr/procedures/definitions/win32_mfsensorgroup.py +44 -0
  806. angr/procedures/definitions/win32_mfsrcsnk.py +28 -0
  807. angr/procedures/definitions/win32_mgmtapi.py +42 -0
  808. angr/procedures/definitions/win32_mi.py +26 -0
  809. angr/procedures/definitions/win32_mmdevapi.py +26 -0
  810. angr/procedures/definitions/win32_mpr.py +118 -0
  811. angr/procedures/definitions/win32_mprapi.py +248 -0
  812. angr/procedures/definitions/win32_mqrt.py +92 -0
  813. angr/procedures/definitions/win32_mrmsupport.py +78 -0
  814. angr/procedures/definitions/win32_msacm32.py +108 -0
  815. angr/procedures/definitions/win32_msajapi.py +1118 -0
  816. angr/procedures/definitions/win32_mscms.py +182 -0
  817. angr/procedures/definitions/win32_mscoree.py +78 -0
  818. angr/procedures/definitions/win32_msctfmonitor.py +30 -0
  819. angr/procedures/definitions/win32_msdelta.py +56 -0
  820. angr/procedures/definitions/win32_msdmo.py +46 -0
  821. angr/procedures/definitions/win32_msdrm.py +192 -0
  822. angr/procedures/definitions/win32_msi.py +552 -0
  823. angr/procedures/definitions/win32_msimg32.py +30 -0
  824. angr/procedures/definitions/win32_mspatcha.py +56 -0
  825. angr/procedures/definitions/win32_mspatchc.py +42 -0
  826. angr/procedures/definitions/win32_msports.py +38 -0
  827. angr/procedures/definitions/win32_msrating.py +62 -0
  828. angr/procedures/definitions/win32_mssign32.py +44 -0
  829. angr/procedures/definitions/win32_mstask.py +28 -0
  830. angr/procedures/definitions/win32_msvfw32.py +110 -0
  831. angr/procedures/definitions/win32_mswsock.py +56 -0
  832. angr/procedures/definitions/win32_mtxdm.py +26 -0
  833. angr/procedures/definitions/win32_ncrypt.py +102 -0
  834. angr/procedures/definitions/win32_ndfapi.py +56 -0
  835. angr/procedures/definitions/win32_netapi32.py +436 -0
  836. angr/procedures/definitions/win32_netsh.py +40 -0
  837. angr/procedures/definitions/win32_netshell.py +28 -0
  838. angr/procedures/definitions/win32_newdev.py +46 -0
  839. angr/procedures/definitions/win32_ninput.py +84 -0
  840. angr/procedures/definitions/win32_normaliz.py +28 -0
  841. angr/procedures/definitions/win32_ntdll.py +171 -0
  842. angr/procedures/definitions/win32_ntdllk.py +26 -0
  843. angr/procedures/definitions/win32_ntdsapi.py +186 -0
  844. angr/procedures/definitions/win32_ntlanman.py +44 -0
  845. angr/procedures/definitions/win32_odbc32.py +392 -0
  846. angr/procedures/definitions/win32_odbcbcp.py +78 -0
  847. angr/procedures/definitions/win32_ole32.py +658 -0
  848. angr/procedures/definitions/win32_oleacc.py +58 -0
  849. angr/procedures/definitions/win32_oleaut32.py +834 -0
  850. angr/procedures/definitions/win32_oledlg.py +70 -0
  851. angr/procedures/definitions/win32_ondemandconnroutehelper.py +34 -0
  852. angr/procedures/definitions/win32_opengl32.py +734 -0
  853. angr/procedures/definitions/win32_opmxbox.py +30 -0
  854. angr/procedures/definitions/win32_p2p.py +240 -0
  855. angr/procedures/definitions/win32_p2pgraph.py +98 -0
  856. angr/procedures/definitions/win32_pdh.py +220 -0
  857. angr/procedures/definitions/win32_peerdist.py +80 -0
  858. angr/procedures/definitions/win32_powrprof.py +192 -0
  859. angr/procedures/definitions/win32_prntvpt.py +46 -0
  860. angr/procedures/definitions/win32_projectedfslib.py +62 -0
  861. angr/procedures/definitions/win32_propsys.py +460 -0
  862. angr/procedures/definitions/win32_psapi.py +78 -0
  863. angr/procedures/definitions/win32_quartz.py +28 -0
  864. angr/procedures/definitions/win32_query.py +32 -0
  865. angr/procedures/definitions/win32_qwave.py +46 -0
  866. angr/procedures/definitions/win32_rasapi32.py +192 -0
  867. angr/procedures/definitions/win32_rasdlg.py +36 -0
  868. angr/procedures/definitions/win32_resutils.py +264 -0
  869. angr/procedures/definitions/win32_rometadata.py +24 -0
  870. angr/procedures/definitions/win32_rpcns4.py +146 -0
  871. angr/procedures/definitions/win32_rpcproxy.py +32 -0
  872. angr/procedures/definitions/win32_rpcrt4.py +918 -0
  873. angr/procedures/definitions/win32_rstrtmgr.py +46 -0
  874. angr/procedures/definitions/win32_rtm.py +176 -0
  875. angr/procedures/definitions/win32_rtutils.py +106 -0
  876. angr/procedures/definitions/win32_rtworkq.py +90 -0
  877. angr/procedures/definitions/win32_sas.py +26 -0
  878. angr/procedures/definitions/win32_scarddlg.py +34 -0
  879. angr/procedures/definitions/win32_schannel.py +42 -0
  880. angr/procedures/definitions/win32_sechost.py +28 -0
  881. angr/procedures/definitions/win32_secur32.py +202 -0
  882. angr/procedures/definitions/win32_sensapi.py +30 -0
  883. angr/procedures/definitions/win32_sensorsutilsv2.py +104 -0
  884. angr/procedures/definitions/win32_setupapi.py +692 -0
  885. angr/procedures/definitions/win32_sfc.py +36 -0
  886. angr/procedures/definitions/win32_shdocvw.py +30 -0
  887. angr/procedures/definitions/win32_shell32.py +512 -0
  888. angr/procedures/definitions/win32_shlwapi.py +744 -0
  889. angr/procedures/definitions/win32_slc.py +88 -0
  890. angr/procedures/definitions/win32_slcext.py +32 -0
  891. angr/procedures/definitions/win32_slwga.py +26 -0
  892. angr/procedures/definitions/win32_snmpapi.py +76 -0
  893. angr/procedures/definitions/win32_spoolss.py +76 -0
  894. angr/procedures/definitions/win32_srclient.py +26 -0
  895. angr/procedures/definitions/win32_srpapi.py +46 -0
  896. angr/procedures/definitions/win32_sspicli.py +38 -0
  897. angr/procedures/definitions/win32_sti.py +26 -0
  898. angr/procedures/definitions/win32_t2embed.py +52 -0
  899. angr/procedures/definitions/win32_tapi32.py +522 -0
  900. angr/procedures/definitions/win32_tbs.py +52 -0
  901. angr/procedures/definitions/win32_tdh.py +78 -0
  902. angr/procedures/definitions/win32_tokenbinding.py +44 -0
  903. angr/procedures/definitions/win32_traffic.py +64 -0
  904. angr/procedures/definitions/win32_txfw32.py +42 -0
  905. angr/procedures/definitions/win32_ualapi.py +32 -0
  906. angr/procedures/definitions/win32_uiautomationcore.py +220 -0
  907. angr/procedures/definitions/win32_urlmon.py +178 -0
  908. angr/procedures/definitions/win32_user32.py +1551 -0
  909. angr/procedures/definitions/win32_userenv.py +112 -0
  910. angr/procedures/definitions/win32_usp10.py +104 -0
  911. angr/procedures/definitions/win32_uxtheme.py +178 -0
  912. angr/procedures/definitions/win32_verifier.py +26 -0
  913. angr/procedures/definitions/win32_version.py +52 -0
  914. angr/procedures/definitions/win32_vertdll.py +38 -0
  915. angr/procedures/definitions/win32_virtdisk.py +82 -0
  916. angr/procedures/definitions/win32_vmdevicehost.py +50 -0
  917. angr/procedures/definitions/win32_vmsavedstatedumpprovider.py +110 -0
  918. angr/procedures/definitions/win32_vssapi.py +26 -0
  919. angr/procedures/definitions/win32_wcmapi.py +34 -0
  920. angr/procedures/definitions/win32_wdsbp.py +38 -0
  921. angr/procedures/definitions/win32_wdsclientapi.py +98 -0
  922. angr/procedures/definitions/win32_wdsmc.py +36 -0
  923. angr/procedures/definitions/win32_wdspxe.py +86 -0
  924. angr/procedures/definitions/win32_wdstptc.py +50 -0
  925. angr/procedures/definitions/win32_webauthn.py +50 -0
  926. angr/procedures/definitions/win32_webservices.py +410 -0
  927. angr/procedures/definitions/win32_websocket.py +50 -0
  928. angr/procedures/definitions/win32_wecapi.py +54 -0
  929. angr/procedures/definitions/win32_wer.py +66 -0
  930. angr/procedures/definitions/win32_wevtapi.py +94 -0
  931. angr/procedures/definitions/win32_winbio.py +132 -0
  932. angr/procedures/definitions/win32_windows_ai_machinelearning.py +26 -0
  933. angr/procedures/definitions/win32_windows_data_pdf.py +24 -0
  934. angr/procedures/definitions/win32_windows_media_mediacontrol.py +40 -0
  935. angr/procedures/definitions/win32_windows_networking.py +26 -0
  936. angr/procedures/definitions/win32_windows_ui_xaml.py +28 -0
  937. angr/procedures/definitions/win32_windowscodecs.py +42 -0
  938. angr/procedures/definitions/win32_winfax.py +136 -0
  939. angr/procedures/definitions/win32_winhttp.py +136 -0
  940. angr/procedures/definitions/win32_winhvemulation.py +32 -0
  941. angr/procedures/definitions/win32_winhvplatform.py +156 -0
  942. angr/procedures/definitions/win32_wininet.py +616 -0
  943. angr/procedures/definitions/win32_winml.py +26 -0
  944. angr/procedures/definitions/win32_winmm.py +376 -0
  945. angr/procedures/definitions/win32_winscard.py +164 -0
  946. angr/procedures/definitions/win32_winspool.py +364 -0
  947. angr/procedures/definitions/win32_winspool_drv.py +368 -0
  948. angr/procedures/definitions/win32_wintrust.py +144 -0
  949. angr/procedures/definitions/win32_winusb.py +92 -0
  950. angr/procedures/definitions/win32_wlanapi.py +144 -0
  951. angr/procedures/definitions/win32_wlanui.py +26 -0
  952. angr/procedures/definitions/win32_wldap32.py +510 -0
  953. angr/procedures/definitions/win32_wldp.py +42 -0
  954. angr/procedures/definitions/win32_wmvcore.py +46 -0
  955. angr/procedures/definitions/win32_wnvapi.py +28 -0
  956. angr/procedures/definitions/win32_wofutil.py +46 -0
  957. angr/procedures/definitions/win32_ws2_32.py +344 -0
  958. angr/procedures/definitions/win32_wscapi.py +36 -0
  959. angr/procedures/definitions/win32_wsclient.py +30 -0
  960. angr/procedures/definitions/win32_wsdapi.py +88 -0
  961. angr/procedures/definitions/win32_wsmsvc.py +90 -0
  962. angr/procedures/definitions/win32_wsnmp32.py +122 -0
  963. angr/procedures/definitions/win32_wtsapi32.py +150 -0
  964. angr/procedures/definitions/win32_xaudio2_8.py +32 -0
  965. angr/procedures/definitions/win32_xinput1_4.py +38 -0
  966. angr/procedures/definitions/win32_xinputuap.py +36 -0
  967. angr/procedures/definitions/win32_xmllite.py +36 -0
  968. angr/procedures/definitions/win32_xolehlp.py +32 -0
  969. angr/procedures/definitions/win32_xpsprint.py +28 -0
  970. angr/procedures/glibc/__ctype_b_loc.py +21 -0
  971. angr/procedures/glibc/__ctype_tolower_loc.py +21 -0
  972. angr/procedures/glibc/__ctype_toupper_loc.py +21 -0
  973. angr/procedures/glibc/__errno_location.py +7 -0
  974. angr/procedures/glibc/__init__.py +3 -0
  975. angr/procedures/glibc/__libc_init.py +37 -0
  976. angr/procedures/glibc/__libc_start_main.py +301 -0
  977. angr/procedures/glibc/dynamic_loading.py +20 -0
  978. angr/procedures/glibc/scanf.py +11 -0
  979. angr/procedures/glibc/sscanf.py +6 -0
  980. angr/procedures/gnulib/__init__.py +3 -0
  981. angr/procedures/gnulib/xalloc_die.py +14 -0
  982. angr/procedures/gnulib/xstrtol_fatal.py +14 -0
  983. angr/procedures/java/__init__.py +42 -0
  984. angr/procedures/java/unconstrained.py +65 -0
  985. angr/procedures/java_io/__init__.py +0 -0
  986. angr/procedures/java_io/read.py +12 -0
  987. angr/procedures/java_io/write.py +17 -0
  988. angr/procedures/java_jni/__init__.py +482 -0
  989. angr/procedures/java_jni/array_operations.py +312 -0
  990. angr/procedures/java_jni/class_and_interface_operations.py +31 -0
  991. angr/procedures/java_jni/field_access.py +173 -0
  992. angr/procedures/java_jni/global_and_local_refs.py +57 -0
  993. angr/procedures/java_jni/method_calls.py +365 -0
  994. angr/procedures/java_jni/not_implemented.py +26 -0
  995. angr/procedures/java_jni/object_operations.py +94 -0
  996. angr/procedures/java_jni/string_operations.py +87 -0
  997. angr/procedures/java_jni/version_information.py +12 -0
  998. angr/procedures/java_lang/__init__.py +0 -0
  999. angr/procedures/java_lang/character.py +30 -0
  1000. angr/procedures/java_lang/double.py +24 -0
  1001. angr/procedures/java_lang/exit.py +13 -0
  1002. angr/procedures/java_lang/getsimplename.py +18 -0
  1003. angr/procedures/java_lang/integer.py +43 -0
  1004. angr/procedures/java_lang/load_library.py +9 -0
  1005. angr/procedures/java_lang/math.py +15 -0
  1006. angr/procedures/java_lang/string.py +78 -0
  1007. angr/procedures/java_lang/stringbuilder.py +44 -0
  1008. angr/procedures/java_lang/system.py +18 -0
  1009. angr/procedures/java_util/__init__.py +0 -0
  1010. angr/procedures/java_util/collection.py +35 -0
  1011. angr/procedures/java_util/iterator.py +46 -0
  1012. angr/procedures/java_util/list.py +99 -0
  1013. angr/procedures/java_util/map.py +131 -0
  1014. angr/procedures/java_util/random.py +14 -0
  1015. angr/procedures/java_util/scanner_nextline.py +23 -0
  1016. angr/procedures/libc/__init__.py +3 -0
  1017. angr/procedures/libc/abort.py +9 -0
  1018. angr/procedures/libc/access.py +13 -0
  1019. angr/procedures/libc/atoi.py +14 -0
  1020. angr/procedures/libc/atol.py +13 -0
  1021. angr/procedures/libc/calloc.py +8 -0
  1022. angr/procedures/libc/closelog.py +10 -0
  1023. angr/procedures/libc/err.py +14 -0
  1024. angr/procedures/libc/error.py +54 -0
  1025. angr/procedures/libc/exit.py +11 -0
  1026. angr/procedures/libc/fclose.py +19 -0
  1027. angr/procedures/libc/feof.py +21 -0
  1028. angr/procedures/libc/fflush.py +16 -0
  1029. angr/procedures/libc/fgetc.py +27 -0
  1030. angr/procedures/libc/fgets.py +68 -0
  1031. angr/procedures/libc/fopen.py +63 -0
  1032. angr/procedures/libc/fprintf.py +25 -0
  1033. angr/procedures/libc/fputc.py +23 -0
  1034. angr/procedures/libc/fputs.py +24 -0
  1035. angr/procedures/libc/fread.py +24 -0
  1036. angr/procedures/libc/free.py +9 -0
  1037. angr/procedures/libc/fscanf.py +20 -0
  1038. angr/procedures/libc/fseek.py +34 -0
  1039. angr/procedures/libc/ftell.py +22 -0
  1040. angr/procedures/libc/fwrite.py +19 -0
  1041. angr/procedures/libc/getchar.py +13 -0
  1042. angr/procedures/libc/getdelim.py +99 -0
  1043. angr/procedures/libc/getegid.py +8 -0
  1044. angr/procedures/libc/geteuid.py +8 -0
  1045. angr/procedures/libc/getgid.py +8 -0
  1046. angr/procedures/libc/gets.py +68 -0
  1047. angr/procedures/libc/getuid.py +8 -0
  1048. angr/procedures/libc/malloc.py +12 -0
  1049. angr/procedures/libc/memcmp.py +69 -0
  1050. angr/procedures/libc/memcpy.py +38 -0
  1051. angr/procedures/libc/memset.py +72 -0
  1052. angr/procedures/libc/openlog.py +10 -0
  1053. angr/procedures/libc/perror.py +13 -0
  1054. angr/procedures/libc/printf.py +34 -0
  1055. angr/procedures/libc/putchar.py +13 -0
  1056. angr/procedures/libc/puts.py +19 -0
  1057. angr/procedures/libc/rand.py +8 -0
  1058. angr/procedures/libc/realloc.py +8 -0
  1059. angr/procedures/libc/rewind.py +12 -0
  1060. angr/procedures/libc/scanf.py +20 -0
  1061. angr/procedures/libc/setbuf.py +9 -0
  1062. angr/procedures/libc/setvbuf.py +7 -0
  1063. angr/procedures/libc/snprintf.py +36 -0
  1064. angr/procedures/libc/sprintf.py +25 -0
  1065. angr/procedures/libc/srand.py +7 -0
  1066. angr/procedures/libc/sscanf.py +13 -0
  1067. angr/procedures/libc/stpcpy.py +18 -0
  1068. angr/procedures/libc/strcat.py +14 -0
  1069. angr/procedures/libc/strchr.py +48 -0
  1070. angr/procedures/libc/strcmp.py +31 -0
  1071. angr/procedures/libc/strcpy.py +13 -0
  1072. angr/procedures/libc/strlen.py +114 -0
  1073. angr/procedures/libc/strncat.py +19 -0
  1074. angr/procedures/libc/strncmp.py +183 -0
  1075. angr/procedures/libc/strncpy.py +22 -0
  1076. angr/procedures/libc/strnlen.py +13 -0
  1077. angr/procedures/libc/strstr.py +101 -0
  1078. angr/procedures/libc/strtol.py +261 -0
  1079. angr/procedures/libc/strtoul.py +9 -0
  1080. angr/procedures/libc/system.py +13 -0
  1081. angr/procedures/libc/time.py +9 -0
  1082. angr/procedures/libc/tmpnam.py +20 -0
  1083. angr/procedures/libc/tolower.py +10 -0
  1084. angr/procedures/libc/toupper.py +10 -0
  1085. angr/procedures/libc/ungetc.py +20 -0
  1086. angr/procedures/libc/vsnprintf.py +17 -0
  1087. angr/procedures/libc/wchar.py +16 -0
  1088. angr/procedures/libstdcpp/__init__.py +0 -0
  1089. angr/procedures/libstdcpp/_unwind_resume.py +11 -0
  1090. angr/procedures/libstdcpp/std____throw_bad_alloc.py +13 -0
  1091. angr/procedures/libstdcpp/std____throw_bad_cast.py +13 -0
  1092. angr/procedures/libstdcpp/std____throw_length_error.py +13 -0
  1093. angr/procedures/libstdcpp/std____throw_logic_error.py +13 -0
  1094. angr/procedures/libstdcpp/std__terminate.py +13 -0
  1095. angr/procedures/linux_kernel/__init__.py +3 -0
  1096. angr/procedures/linux_kernel/access.py +18 -0
  1097. angr/procedures/linux_kernel/arch_prctl.py +34 -0
  1098. angr/procedures/linux_kernel/arm_user_helpers.py +59 -0
  1099. angr/procedures/linux_kernel/brk.py +18 -0
  1100. angr/procedures/linux_kernel/cwd.py +28 -0
  1101. angr/procedures/linux_kernel/fstat.py +138 -0
  1102. angr/procedures/linux_kernel/fstat64.py +170 -0
  1103. angr/procedures/linux_kernel/futex.py +17 -0
  1104. angr/procedures/linux_kernel/getegid.py +17 -0
  1105. angr/procedures/linux_kernel/geteuid.py +17 -0
  1106. angr/procedures/linux_kernel/getgid.py +17 -0
  1107. angr/procedures/linux_kernel/getpid.py +14 -0
  1108. angr/procedures/linux_kernel/getrlimit.py +24 -0
  1109. angr/procedures/linux_kernel/gettid.py +9 -0
  1110. angr/procedures/linux_kernel/getuid.py +17 -0
  1111. angr/procedures/linux_kernel/iovec.py +47 -0
  1112. angr/procedures/linux_kernel/lseek.py +42 -0
  1113. angr/procedures/linux_kernel/mmap.py +16 -0
  1114. angr/procedures/linux_kernel/mprotect.py +42 -0
  1115. angr/procedures/linux_kernel/munmap.py +8 -0
  1116. angr/procedures/linux_kernel/openat.py +26 -0
  1117. angr/procedures/linux_kernel/set_tid_address.py +8 -0
  1118. angr/procedures/linux_kernel/sigaction.py +19 -0
  1119. angr/procedures/linux_kernel/sigprocmask.py +23 -0
  1120. angr/procedures/linux_kernel/stat.py +23 -0
  1121. angr/procedures/linux_kernel/sysinfo.py +59 -0
  1122. angr/procedures/linux_kernel/tgkill.py +10 -0
  1123. angr/procedures/linux_kernel/time.py +34 -0
  1124. angr/procedures/linux_kernel/uid.py +30 -0
  1125. angr/procedures/linux_kernel/uname.py +29 -0
  1126. angr/procedures/linux_kernel/unlink.py +22 -0
  1127. angr/procedures/linux_kernel/vsyscall.py +16 -0
  1128. angr/procedures/linux_loader/__init__.py +3 -0
  1129. angr/procedures/linux_loader/_dl_initial_error_catch_tsd.py +7 -0
  1130. angr/procedures/linux_loader/_dl_rtld_lock.py +15 -0
  1131. angr/procedures/linux_loader/sim_loader.py +54 -0
  1132. angr/procedures/linux_loader/tls.py +40 -0
  1133. angr/procedures/msvcr/__getmainargs.py +16 -0
  1134. angr/procedures/msvcr/__init__.py +4 -0
  1135. angr/procedures/msvcr/_initterm.py +38 -0
  1136. angr/procedures/msvcr/fmode.py +31 -0
  1137. angr/procedures/ntdll/__init__.py +0 -0
  1138. angr/procedures/ntdll/exceptions.py +60 -0
  1139. angr/procedures/posix/__init__.py +3 -0
  1140. angr/procedures/posix/accept.py +29 -0
  1141. angr/procedures/posix/bind.py +13 -0
  1142. angr/procedures/posix/bzero.py +9 -0
  1143. angr/procedures/posix/chroot.py +27 -0
  1144. angr/procedures/posix/close.py +9 -0
  1145. angr/procedures/posix/closedir.py +7 -0
  1146. angr/procedures/posix/dup.py +56 -0
  1147. angr/procedures/posix/fcntl.py +10 -0
  1148. angr/procedures/posix/fdopen.py +76 -0
  1149. angr/procedures/posix/fileno.py +18 -0
  1150. angr/procedures/posix/fork.py +13 -0
  1151. angr/procedures/posix/getenv.py +35 -0
  1152. angr/procedures/posix/gethostbyname.py +43 -0
  1153. angr/procedures/posix/getpass.py +19 -0
  1154. angr/procedures/posix/getsockopt.py +11 -0
  1155. angr/procedures/posix/htonl.py +11 -0
  1156. angr/procedures/posix/htons.py +11 -0
  1157. angr/procedures/posix/inet_ntoa.py +59 -0
  1158. angr/procedures/posix/listen.py +13 -0
  1159. angr/procedures/posix/mmap.py +144 -0
  1160. angr/procedures/posix/open.py +18 -0
  1161. angr/procedures/posix/opendir.py +10 -0
  1162. angr/procedures/posix/poll.py +55 -0
  1163. angr/procedures/posix/pread64.py +46 -0
  1164. angr/procedures/posix/pthread.py +87 -0
  1165. angr/procedures/posix/pwrite64.py +46 -0
  1166. angr/procedures/posix/read.py +13 -0
  1167. angr/procedures/posix/readdir.py +62 -0
  1168. angr/procedures/posix/recv.py +13 -0
  1169. angr/procedures/posix/recvfrom.py +13 -0
  1170. angr/procedures/posix/select.py +48 -0
  1171. angr/procedures/posix/send.py +23 -0
  1172. angr/procedures/posix/setsockopt.py +9 -0
  1173. angr/procedures/posix/sigaction.py +23 -0
  1174. angr/procedures/posix/sim_time.py +48 -0
  1175. angr/procedures/posix/sleep.py +8 -0
  1176. angr/procedures/posix/socket.py +18 -0
  1177. angr/procedures/posix/strcasecmp.py +26 -0
  1178. angr/procedures/posix/strdup.py +18 -0
  1179. angr/procedures/posix/strtok_r.py +64 -0
  1180. angr/procedures/posix/syslog.py +15 -0
  1181. angr/procedures/posix/tz.py +9 -0
  1182. angr/procedures/posix/unlink.py +11 -0
  1183. angr/procedures/posix/usleep.py +8 -0
  1184. angr/procedures/posix/write.py +13 -0
  1185. angr/procedures/procedure_dict.py +50 -0
  1186. angr/procedures/stubs/CallReturn.py +13 -0
  1187. angr/procedures/stubs/NoReturnUnconstrained.py +13 -0
  1188. angr/procedures/stubs/Nop.py +7 -0
  1189. angr/procedures/stubs/PathTerminator.py +9 -0
  1190. angr/procedures/stubs/Redirect.py +18 -0
  1191. angr/procedures/stubs/ReturnChar.py +11 -0
  1192. angr/procedures/stubs/ReturnUnconstrained.py +24 -0
  1193. angr/procedures/stubs/UnresolvableCallTarget.py +9 -0
  1194. angr/procedures/stubs/UnresolvableJumpTarget.py +9 -0
  1195. angr/procedures/stubs/UserHook.py +18 -0
  1196. angr/procedures/stubs/__init__.py +3 -0
  1197. angr/procedures/stubs/b64_decode.py +15 -0
  1198. angr/procedures/stubs/caller.py +14 -0
  1199. angr/procedures/stubs/crazy_scanf.py +20 -0
  1200. angr/procedures/stubs/format_parser.py +669 -0
  1201. angr/procedures/stubs/syscall_stub.py +24 -0
  1202. angr/procedures/testing/__init__.py +3 -0
  1203. angr/procedures/testing/manyargs.py +9 -0
  1204. angr/procedures/testing/retreg.py +8 -0
  1205. angr/procedures/tracer/__init__.py +4 -0
  1206. angr/procedures/tracer/random.py +9 -0
  1207. angr/procedures/tracer/receive.py +23 -0
  1208. angr/procedures/tracer/transmit.py +26 -0
  1209. angr/procedures/uclibc/__init__.py +3 -0
  1210. angr/procedures/uclibc/__uClibc_main.py +10 -0
  1211. angr/procedures/win32/EncodePointer.py +7 -0
  1212. angr/procedures/win32/ExitProcess.py +9 -0
  1213. angr/procedures/win32/GetCommandLine.py +12 -0
  1214. angr/procedures/win32/GetCurrentProcessId.py +7 -0
  1215. angr/procedures/win32/GetCurrentThreadId.py +7 -0
  1216. angr/procedures/win32/GetLastInputInfo.py +40 -0
  1217. angr/procedures/win32/GetModuleHandle.py +29 -0
  1218. angr/procedures/win32/GetProcessAffinityMask.py +37 -0
  1219. angr/procedures/win32/InterlockedExchange.py +15 -0
  1220. angr/procedures/win32/IsProcessorFeaturePresent.py +7 -0
  1221. angr/procedures/win32/VirtualAlloc.py +114 -0
  1222. angr/procedures/win32/VirtualProtect.py +60 -0
  1223. angr/procedures/win32/__init__.py +3 -0
  1224. angr/procedures/win32/critical_section.py +12 -0
  1225. angr/procedures/win32/dynamic_loading.py +104 -0
  1226. angr/procedures/win32/file_handles.py +47 -0
  1227. angr/procedures/win32/gethostbyname.py +12 -0
  1228. angr/procedures/win32/heap.py +45 -0
  1229. angr/procedures/win32/is_bad_ptr.py +26 -0
  1230. angr/procedures/win32/local_storage.py +88 -0
  1231. angr/procedures/win32/mutex.py +11 -0
  1232. angr/procedures/win32/sim_time.py +135 -0
  1233. angr/procedures/win32/system_paths.py +35 -0
  1234. angr/procedures/win32_kernel/ExAllocatePool.py +13 -0
  1235. angr/procedures/win32_kernel/ExFreePoolWithTag.py +8 -0
  1236. angr/procedures/win32_kernel/__fastfail.py +15 -0
  1237. angr/procedures/win32_kernel/__init__.py +3 -0
  1238. angr/procedures/win_user32/__init__.py +0 -0
  1239. angr/procedures/win_user32/chars.py +15 -0
  1240. angr/procedures/win_user32/keyboard.py +14 -0
  1241. angr/procedures/win_user32/messagebox.py +49 -0
  1242. angr/project.py +837 -0
  1243. angr/protos/__init__.py +19 -0
  1244. angr/protos/cfg_pb2.py +31 -0
  1245. angr/protos/function_pb2.py +27 -0
  1246. angr/protos/primitives_pb2.py +52 -0
  1247. angr/protos/variables_pb2.py +44 -0
  1248. angr/protos/xrefs_pb2.py +25 -0
  1249. angr/py.typed +1 -0
  1250. angr/rustylib.cpython-310-aarch64-linux-gnu.so +0 -0
  1251. angr/rustylib.pyi +165 -0
  1252. angr/serializable.py +66 -0
  1253. angr/sim_manager.py +971 -0
  1254. angr/sim_options.py +438 -0
  1255. angr/sim_procedure.py +606 -0
  1256. angr/sim_state.py +901 -0
  1257. angr/sim_state_options.py +403 -0
  1258. angr/sim_type.py +3679 -0
  1259. angr/sim_variable.py +434 -0
  1260. angr/simos/__init__.py +47 -0
  1261. angr/simos/cgc.py +153 -0
  1262. angr/simos/javavm.py +458 -0
  1263. angr/simos/linux.py +509 -0
  1264. angr/simos/simos.py +444 -0
  1265. angr/simos/snimmuc_nxp.py +149 -0
  1266. angr/simos/userland.py +163 -0
  1267. angr/simos/windows.py +601 -0
  1268. angr/simos/xbox.py +32 -0
  1269. angr/slicer.py +352 -0
  1270. angr/state_hierarchy.py +262 -0
  1271. angr/state_plugins/__init__.py +84 -0
  1272. angr/state_plugins/callstack.py +398 -0
  1273. angr/state_plugins/cgc.py +155 -0
  1274. angr/state_plugins/debug_variables.py +192 -0
  1275. angr/state_plugins/filesystem.py +463 -0
  1276. angr/state_plugins/gdb.py +148 -0
  1277. angr/state_plugins/globals.py +65 -0
  1278. angr/state_plugins/heap/__init__.py +15 -0
  1279. angr/state_plugins/heap/heap_base.py +128 -0
  1280. angr/state_plugins/heap/heap_brk.py +136 -0
  1281. angr/state_plugins/heap/heap_freelist.py +213 -0
  1282. angr/state_plugins/heap/heap_libc.py +46 -0
  1283. angr/state_plugins/heap/heap_ptmalloc.py +620 -0
  1284. angr/state_plugins/heap/utils.py +22 -0
  1285. angr/state_plugins/history.py +548 -0
  1286. angr/state_plugins/inspect.py +375 -0
  1287. angr/state_plugins/javavm_classloader.py +134 -0
  1288. angr/state_plugins/jni_references.py +95 -0
  1289. angr/state_plugins/libc.py +1263 -0
  1290. angr/state_plugins/light_registers.py +168 -0
  1291. angr/state_plugins/log.py +84 -0
  1292. angr/state_plugins/loop_data.py +92 -0
  1293. angr/state_plugins/plugin.py +170 -0
  1294. angr/state_plugins/posix.py +703 -0
  1295. angr/state_plugins/preconstrainer.py +196 -0
  1296. angr/state_plugins/scratch.py +173 -0
  1297. angr/state_plugins/sim_action.py +326 -0
  1298. angr/state_plugins/sim_action_object.py +271 -0
  1299. angr/state_plugins/sim_event.py +59 -0
  1300. angr/state_plugins/solver.py +1127 -0
  1301. angr/state_plugins/symbolizer.py +291 -0
  1302. angr/state_plugins/trace_additions.py +738 -0
  1303. angr/state_plugins/uc_manager.py +94 -0
  1304. angr/state_plugins/unicorn_engine.py +1886 -0
  1305. angr/state_plugins/view.py +340 -0
  1306. angr/storage/__init__.py +15 -0
  1307. angr/storage/file.py +1210 -0
  1308. angr/storage/memory_mixins/__init__.py +317 -0
  1309. angr/storage/memory_mixins/actions_mixin.py +72 -0
  1310. angr/storage/memory_mixins/address_concretization_mixin.py +384 -0
  1311. angr/storage/memory_mixins/bvv_conversion_mixin.py +73 -0
  1312. angr/storage/memory_mixins/clouseau_mixin.py +137 -0
  1313. angr/storage/memory_mixins/conditional_store_mixin.py +25 -0
  1314. angr/storage/memory_mixins/convenient_mappings_mixin.py +256 -0
  1315. angr/storage/memory_mixins/default_filler_mixin.py +144 -0
  1316. angr/storage/memory_mixins/dirty_addrs_mixin.py +11 -0
  1317. angr/storage/memory_mixins/hex_dumper_mixin.py +82 -0
  1318. angr/storage/memory_mixins/javavm_memory_mixin.py +392 -0
  1319. angr/storage/memory_mixins/keyvalue_memory_mixin.py +42 -0
  1320. angr/storage/memory_mixins/label_merger_mixin.py +31 -0
  1321. angr/storage/memory_mixins/memory_mixin.py +174 -0
  1322. angr/storage/memory_mixins/multi_value_merger_mixin.py +79 -0
  1323. angr/storage/memory_mixins/name_resolution_mixin.py +67 -0
  1324. angr/storage/memory_mixins/paged_memory/__init__.py +0 -0
  1325. angr/storage/memory_mixins/paged_memory/page_backer_mixins.py +266 -0
  1326. angr/storage/memory_mixins/paged_memory/paged_memory_mixin.py +743 -0
  1327. angr/storage/memory_mixins/paged_memory/paged_memory_multivalue_mixin.py +65 -0
  1328. angr/storage/memory_mixins/paged_memory/pages/__init__.py +26 -0
  1329. angr/storage/memory_mixins/paged_memory/pages/base.py +31 -0
  1330. angr/storage/memory_mixins/paged_memory/pages/cooperation.py +341 -0
  1331. angr/storage/memory_mixins/paged_memory/pages/history_tracking_mixin.py +92 -0
  1332. angr/storage/memory_mixins/paged_memory/pages/ispo_mixin.py +55 -0
  1333. angr/storage/memory_mixins/paged_memory/pages/list_page.py +338 -0
  1334. angr/storage/memory_mixins/paged_memory/pages/multi_values.py +324 -0
  1335. angr/storage/memory_mixins/paged_memory/pages/mv_list_page.py +419 -0
  1336. angr/storage/memory_mixins/paged_memory/pages/permissions_mixin.py +36 -0
  1337. angr/storage/memory_mixins/paged_memory/pages/refcount_mixin.py +52 -0
  1338. angr/storage/memory_mixins/paged_memory/pages/ultra_page.py +503 -0
  1339. angr/storage/memory_mixins/paged_memory/privileged_mixin.py +36 -0
  1340. angr/storage/memory_mixins/paged_memory/stack_allocation_mixin.py +74 -0
  1341. angr/storage/memory_mixins/regioned_memory/__init__.py +17 -0
  1342. angr/storage/memory_mixins/regioned_memory/abstract_address_descriptor.py +36 -0
  1343. angr/storage/memory_mixins/regioned_memory/abstract_merger_mixin.py +31 -0
  1344. angr/storage/memory_mixins/regioned_memory/region_category_mixin.py +9 -0
  1345. angr/storage/memory_mixins/regioned_memory/region_data.py +246 -0
  1346. angr/storage/memory_mixins/regioned_memory/region_meta_mixin.py +241 -0
  1347. angr/storage/memory_mixins/regioned_memory/regioned_address_concretization_mixin.py +119 -0
  1348. angr/storage/memory_mixins/regioned_memory/regioned_memory_mixin.py +441 -0
  1349. angr/storage/memory_mixins/regioned_memory/static_find_mixin.py +69 -0
  1350. angr/storage/memory_mixins/simple_interface_mixin.py +71 -0
  1351. angr/storage/memory_mixins/simplification_mixin.py +15 -0
  1352. angr/storage/memory_mixins/size_resolution_mixin.py +143 -0
  1353. angr/storage/memory_mixins/slotted_memory.py +140 -0
  1354. angr/storage/memory_mixins/smart_find_mixin.py +161 -0
  1355. angr/storage/memory_mixins/symbolic_merger_mixin.py +16 -0
  1356. angr/storage/memory_mixins/top_merger_mixin.py +25 -0
  1357. angr/storage/memory_mixins/underconstrained_mixin.py +67 -0
  1358. angr/storage/memory_mixins/unwrapper_mixin.py +26 -0
  1359. angr/storage/memory_object.py +195 -0
  1360. angr/tablespecs.py +91 -0
  1361. angr/utils/__init__.py +46 -0
  1362. angr/utils/ail.py +70 -0
  1363. angr/utils/algo.py +34 -0
  1364. angr/utils/bits.py +46 -0
  1365. angr/utils/constants.py +9 -0
  1366. angr/utils/cowdict.py +63 -0
  1367. angr/utils/cpp.py +17 -0
  1368. angr/utils/doms.py +149 -0
  1369. angr/utils/dynamic_dictlist.py +89 -0
  1370. angr/utils/endness.py +18 -0
  1371. angr/utils/enums_conv.py +97 -0
  1372. angr/utils/env.py +12 -0
  1373. angr/utils/formatting.py +128 -0
  1374. angr/utils/funcid.py +159 -0
  1375. angr/utils/graph.py +898 -0
  1376. angr/utils/lazy_import.py +13 -0
  1377. angr/utils/library.py +211 -0
  1378. angr/utils/loader.py +55 -0
  1379. angr/utils/mp.py +66 -0
  1380. angr/utils/orderedset.py +74 -0
  1381. angr/utils/ssa/__init__.py +395 -0
  1382. angr/utils/ssa/tmp_uses_collector.py +23 -0
  1383. angr/utils/ssa/vvar_uses_collector.py +37 -0
  1384. angr/utils/tagged_interval_map.py +112 -0
  1385. angr/utils/timing.py +74 -0
  1386. angr/utils/types.py +151 -0
  1387. angr/vaults.py +367 -0
  1388. angr-9.2.156.dist-info/METADATA +112 -0
  1389. angr-9.2.156.dist-info/RECORD +1393 -0
  1390. angr-9.2.156.dist-info/WHEEL +5 -0
  1391. angr-9.2.156.dist-info/entry_points.txt +2 -0
  1392. angr-9.2.156.dist-info/licenses/LICENSE +27 -0
  1393. angr-9.2.156.dist-info/top_level.txt +1 -0
@@ -0,0 +1,4069 @@
1
+ # pylint:disable=missing-class-docstring,too-many-boolean-expressions,unused-argument,no-self-use
2
+ from __future__ import annotations
3
+ from typing import cast, Any, TYPE_CHECKING
4
+ from collections.abc import Callable
5
+ from collections import defaultdict, Counter
6
+ import logging
7
+ import struct
8
+ import re
9
+
10
+ from ailment import Block, Expr, Stmt, Tmp
11
+ from ailment.constant import UNDETERMINED_SIZE
12
+ from ailment.expression import StackBaseOffset, BinaryOp
13
+ from unique_log_filter import UniqueLogFilter
14
+
15
+ from angr.sim_type import (
16
+ SimTypeLongLong,
17
+ SimTypeInt,
18
+ SimTypeShort,
19
+ SimTypeChar,
20
+ SimTypeWideChar,
21
+ SimTypePointer,
22
+ SimStruct,
23
+ SimType,
24
+ SimTypeBottom,
25
+ SimTypeArray,
26
+ SimTypeFunction,
27
+ SimTypeFloat,
28
+ SimTypeDouble,
29
+ TypeRef,
30
+ SimTypeNum,
31
+ SimTypeFixedSizeArray,
32
+ SimTypeLength,
33
+ SimTypeReg,
34
+ SimTypeInt128,
35
+ SimTypeInt256,
36
+ SimTypeInt512,
37
+ SimCppClass,
38
+ )
39
+ from angr.knowledge_plugins.functions import Function
40
+ from angr.sim_variable import SimVariable, SimTemporaryVariable, SimStackVariable, SimMemoryVariable
41
+ from angr.utils.constants import is_alignment_mask
42
+ from angr.utils.library import get_cpp_function_name
43
+ from angr.utils.loader import is_in_readonly_segment, is_in_readonly_section
44
+ from angr.utils.types import unpack_typeref, unpack_pointer_and_array, dereference_simtype_by_lib
45
+ from angr.analyses.decompiler.utils import structured_node_is_simple_return
46
+ from angr.errors import UnsupportedNodeTypeError, AngrRuntimeError
47
+ from angr.knowledge_plugins.cfg.memory_data import MemoryData, MemoryDataSort
48
+ from angr.analyses import Analysis, register_analysis
49
+ from angr.analyses.decompiler.region_identifier import MultiNode
50
+ from angr.analyses.decompiler.structuring.structurer_nodes import (
51
+ SequenceNode,
52
+ CodeNode,
53
+ ConditionNode,
54
+ ConditionalBreakNode,
55
+ LoopNode,
56
+ BreakNode,
57
+ SwitchCaseNode,
58
+ IncompleteSwitchCaseNode,
59
+ ContinueNode,
60
+ CascadingConditionNode,
61
+ )
62
+ from .base import BaseStructuredCodeGenerator, InstructionMapping, PositionMapping, PositionMappingElement
63
+
64
+ if TYPE_CHECKING:
65
+ import archinfo
66
+ import angr
67
+ from angr.knowledge_plugins.variables.variable_manager import VariableManagerInternal
68
+
69
+
70
+ l = logging.getLogger(name=__name__)
71
+ l.addFilter(UniqueLogFilter())
72
+
73
+
74
+ INDENT_DELTA = 4
75
+
76
+
77
+ def qualifies_for_simple_cast(ty1, ty2):
78
+ # converting ty1 to ty2 - can this happen precisely?
79
+ # used to decide whether to add explicit typecasts instead of doing *(int*)&v1
80
+ return (
81
+ ty1.size == ty2.size
82
+ and isinstance(ty1, (SimTypeInt, SimTypeChar, SimTypeNum, SimTypePointer))
83
+ and isinstance(ty2, (SimTypeInt, SimTypeChar, SimTypeNum, SimTypePointer))
84
+ )
85
+
86
+
87
+ def qualifies_for_implicit_cast(ty1, ty2):
88
+ # converting ty1 to ty2 - can this happen without a cast?
89
+ # used to decide whether to omit typecasts from output during promotion
90
+ # this function need to answer the question:
91
+ # when does having a cast vs having an implicit promotion affect the result?
92
+ # the answer: I DON'T KNOW
93
+ if not isinstance(ty1, (SimTypeInt, SimTypeChar, SimTypeNum)) or not isinstance(
94
+ ty2, (SimTypeInt, SimTypeChar, SimTypeNum)
95
+ ):
96
+ return False
97
+
98
+ return ty1.size <= ty2.size if ty1.size is not None and ty2.size is not None else False
99
+
100
+
101
+ def extract_terms(expr: CExpression) -> tuple[int, list[tuple[int, CExpression]]]:
102
+ # handle unnecessary type casts
103
+ if isinstance(expr, CTypeCast):
104
+ expr = MakeTypecastsImplicit.collapse(expr.dst_type, expr.expr)
105
+ if (
106
+ isinstance(expr, CTypeCast)
107
+ and isinstance(expr.dst_type, SimTypeInt)
108
+ and isinstance(expr.src_type, SimTypeInt)
109
+ and expr.dst_type.size == expr.src_type.size
110
+ and expr.dst_type.signed != expr.src_type.signed
111
+ ):
112
+ # (unsigned int)(a + 60) ==> a + 60, assuming a + 60 is an int
113
+ expr = expr.expr
114
+
115
+ if isinstance(expr, CConstant):
116
+ return expr.value, []
117
+ # elif isinstance(expr, CUnaryOp) and expr.op == 'Minus'
118
+ if isinstance(expr, CBinaryOp) and expr.op == "Add":
119
+ c1, t1 = extract_terms(expr.lhs)
120
+ c2, t2 = extract_terms(expr.rhs)
121
+ return c1 + c2, t1 + t2
122
+ if isinstance(expr, CBinaryOp) and expr.op == "Sub":
123
+ c1, t1 = extract_terms(expr.lhs)
124
+ c2, t2 = extract_terms(expr.rhs)
125
+ return c1 - c2, t1 + [(-c, t) for c, t in t2]
126
+ if isinstance(expr, CBinaryOp) and expr.op == "Mul":
127
+ if isinstance(expr.lhs, CConstant):
128
+ c, t = extract_terms(expr.rhs)
129
+ return c * expr.lhs.value, [(c1 * expr.lhs.value, t1) for c1, t1 in t]
130
+ if isinstance(expr.rhs, CConstant):
131
+ c, t = extract_terms(expr.lhs)
132
+ return c * expr.rhs.value, [(c1 * expr.rhs.value, t1) for c1, t1 in t]
133
+ return 0, [(1, expr)]
134
+ if isinstance(expr, CBinaryOp) and expr.op == "Shl":
135
+ if isinstance(expr.rhs, CConstant):
136
+ c, t = extract_terms(expr.lhs)
137
+ return c << expr.rhs.value, [(c1 << expr.rhs.value, t1) for c1, t1 in t]
138
+ return 0, [(1, expr)]
139
+ return 0, [(1, expr)]
140
+
141
+
142
+ def is_machine_word_size_type(type_: SimType, arch: archinfo.Arch) -> bool:
143
+ return isinstance(type_, SimTypeReg) and type_.size == arch.bits
144
+
145
+
146
+ def guess_value_type(value: int, project: angr.Project) -> SimType | None:
147
+ if project.kb.functions.contains_addr(value):
148
+ # might be a function pointer
149
+ return SimTypePointer(SimTypeBottom(label="void")).with_arch(project.arch)
150
+ if value > 4096:
151
+ sec = project.loader.find_section_containing(value)
152
+ if sec is not None and sec.is_readable:
153
+ return SimTypePointer(SimTypeBottom(label="void")).with_arch(project.arch)
154
+ seg = project.loader.find_segment_containing(value)
155
+ if seg is not None and seg.is_readable:
156
+ return SimTypePointer(SimTypeBottom(label="void")).with_arch(project.arch)
157
+ return None
158
+
159
+
160
+ def type_equals(t0: SimType, t1: SimType) -> bool:
161
+ # special logic for C++ classes
162
+ if isinstance(t0, SimCppClass) and isinstance(t1, SimCppClass): # noqa: SIM102
163
+ # TODO: Use the information (class names, etc.) in types_stl
164
+ if {t1.name, t0.name} == {
165
+ "std::string",
166
+ "class std::basic_string<char, struct std::char_traits<char>, class std::allocator<char>>",
167
+ }:
168
+ return True
169
+ return t0 == t1
170
+
171
+
172
+ def type_to_c_repr_chunks(ty: SimType, name=None, name_type=None, full=False, indent_str=""):
173
+ """
174
+ Helper generator function to turn a SimType into generated tuples of (C-string, AST node).
175
+ """
176
+ if isinstance(ty, SimStruct):
177
+ if full:
178
+ # struct def preamble
179
+ yield indent_str, None
180
+ if isinstance(ty, SimCppClass):
181
+ yield "class ", None
182
+ else:
183
+ yield "typedef struct ", None
184
+ yield ty.name, ty
185
+ yield " {\n", None
186
+
187
+ # each of the fields
188
+ # fields should be indented
189
+ new_indent_str = (
190
+ " " * 4
191
+ ) + indent_str # TODO: hardcoded as 4 character space indents, which is same as SimStruct.c_repr
192
+ for k, v in ty.fields.items():
193
+ yield new_indent_str, None
194
+ yield from type_to_c_repr_chunks(v, name=k, name_type=CStructFieldNameDef(k), full=False, indent_str="")
195
+ yield ";\n", None
196
+
197
+ # struct def postamble
198
+ yield "} ", None
199
+ yield ty.name, ty
200
+ yield ";\n\n", None
201
+
202
+ else:
203
+ assert name
204
+ assert name_type
205
+ yield indent_str, None
206
+ yield ty.name, ty
207
+ yield " ", None
208
+ if name:
209
+ yield name, name_type
210
+ elif isinstance(ty, SimType):
211
+ assert name
212
+ assert name_type
213
+ raw_type_str = ty.c_repr(name=name)
214
+ assert name in raw_type_str
215
+
216
+ type_pre, type_post = raw_type_str.split(name, 1)
217
+
218
+ if type_pre.endswith(" "):
219
+ type_pre_spaces = " " * (len(type_pre) - len(type_pre.rstrip(" ")))
220
+ type_pre = type_pre.rstrip(" ")
221
+ else:
222
+ type_pre_spaces = ""
223
+
224
+ yield indent_str, None
225
+ yield type_pre, ty
226
+ if type_pre_spaces:
227
+ yield type_pre_spaces, None
228
+ yield name, name_type
229
+ yield type_post, CArrayTypeLength(type_post)
230
+ # This case was used when generating externs, apparently there can be cases where the name is not known
231
+ elif ty is None:
232
+ assert name
233
+ assert name_type
234
+ yield "<missing-type> ", None
235
+ yield name, name_type
236
+ else:
237
+ assert False
238
+
239
+
240
+ #
241
+ # C Representation Classes
242
+ #
243
+
244
+
245
+ class CConstruct:
246
+ """
247
+ Represents a program construct in C.
248
+ Acts as the base class for all other representation constructions.
249
+ """
250
+
251
+ __slots__ = ("codegen", "tags")
252
+
253
+ def __init__(self, codegen, tags=None):
254
+ self.tags = tags or {}
255
+ self.codegen: StructuredCodeGenerator = codegen
256
+
257
+ def c_repr(self, indent=0, pos_to_node=None, pos_to_addr=None, addr_to_pos=None):
258
+ """
259
+ Creates the C representation of the code and displays it by
260
+ constructing a large string. This function is called by each program function that needs to be decompiled.
261
+ The map_pos_to_node and map_pos_to_addr act as position maps for the location of each variable and statement to
262
+ be tracked for later GUI operations. The map_pos_to_addr also contains expressions that are nested inside of
263
+ statements.
264
+ """
265
+
266
+ pending_stmt_comments = dict(self.codegen.stmt_comments)
267
+ pending_expr_comments = dict(self.codegen.expr_comments)
268
+
269
+ def mapper(chunks):
270
+ # start all positions at beginning of document
271
+ pos = 0
272
+
273
+ last_insn_addr = None
274
+
275
+ # track all variables so we can tell if this is a declaration or not
276
+ used_vars = set()
277
+
278
+ # get each string and object representation of the chunks
279
+ for s, obj in chunks:
280
+ # filter out anything that is not a statement or expression object
281
+ if isinstance(obj, (CStatement, CExpression)):
282
+ # only add statements/expressions that can be address tracked into map_pos_to_addr
283
+ if hasattr(obj, "tags") and obj.tags is not None and "ins_addr" in obj.tags:
284
+ if isinstance(obj, CVariable) and obj not in used_vars:
285
+ used_vars.add(obj)
286
+ else:
287
+ last_insn_addr = obj.tags["ins_addr"]
288
+
289
+ # all valid statements and expressions should be added to map_pos_to_addr and
290
+ # tracked for instruction mapping from disassembly
291
+ if pos_to_addr is not None:
292
+ pos_to_addr.add_mapping(pos, len(s), obj)
293
+ if addr_to_pos is not None:
294
+ addr_to_pos.add_mapping(obj.tags["ins_addr"], pos)
295
+
296
+ # add all variables, constants, and function calls to map_pos_to_node for highlighting
297
+ # add ops to pos_to_node but NOT ast_to_pos
298
+ if (
299
+ isinstance(
300
+ obj,
301
+ (
302
+ CVariable,
303
+ CConstant,
304
+ CStructField,
305
+ CIndexedVariable,
306
+ CVariableField,
307
+ CBinaryOp,
308
+ CUnaryOp,
309
+ CAssignment,
310
+ CFunctionCall,
311
+ CLabel,
312
+ ),
313
+ )
314
+ and pos_to_node is not None
315
+ ):
316
+ pos_to_node.add_mapping(pos, len(s), obj)
317
+
318
+ # add (), {}, [], and [20] to mapping for highlighting as well as the full functions name
319
+ elif isinstance(obj, (CClosingObject, CFunction, CArrayTypeLength, CStructFieldNameDef)):
320
+ if s is None:
321
+ continue
322
+
323
+ if pos_to_node is not None:
324
+ pos_to_node.add_mapping(pos, len(s), obj)
325
+
326
+ elif isinstance(obj, SimType):
327
+ if pos_to_node is not None:
328
+ if isinstance(obj, TypeRef):
329
+ pos_to_node.add_mapping(pos, len(s), obj.type)
330
+ else:
331
+ pos_to_node.add_mapping(pos, len(s), obj)
332
+
333
+ if s.endswith("\n"):
334
+ text = pending_stmt_comments.pop(last_insn_addr, None) if isinstance(last_insn_addr, int) else None
335
+ if text is not None:
336
+ todo = " // " + text
337
+ pos += len(s) - 1
338
+ yield s[:-1]
339
+ pos += len(todo)
340
+ yield todo
341
+ s = "\n"
342
+
343
+ pos += len(s)
344
+ yield s
345
+
346
+ if isinstance(obj, CExpression):
347
+ text = pending_expr_comments.pop(last_insn_addr, None) if isinstance(last_insn_addr, int) else None
348
+ if text is not None:
349
+ todo = " /*" + text + "*/ "
350
+ pos += len(todo)
351
+ yield todo
352
+
353
+ if pending_expr_comments or pending_stmt_comments:
354
+ yield "// Orphaned comments\n"
355
+ for text in pending_stmt_comments.values():
356
+ yield "// " + text + "\n"
357
+ for text in pending_expr_comments.values():
358
+ yield "/* " + text + "*/\n"
359
+
360
+ # A special note about this line:
361
+ # Polymorphism allows that the c_repr_chunks() call will be called
362
+ # by the CFunction class, which will then call each statement within it and construct
363
+ # the chunks that get printed in qccode_edit in angr-management.
364
+ return "".join(mapper(self.c_repr_chunks(indent)))
365
+
366
+ def c_repr_chunks(self, indent=0, asexpr=False):
367
+ raise NotImplementedError
368
+
369
+ @staticmethod
370
+ def indent_str(indent=0):
371
+ return " " * indent
372
+
373
+
374
+ class CFunction(CConstruct): # pylint:disable=abstract-method
375
+ """
376
+ Represents a function in C.
377
+ """
378
+
379
+ __slots__ = (
380
+ "addr",
381
+ "arg_list",
382
+ "demangled_name",
383
+ "functy",
384
+ "name",
385
+ "omit_header",
386
+ "show_demangled_name",
387
+ "statements",
388
+ "unified_local_vars",
389
+ "variable_manager",
390
+ "variables_in_use",
391
+ )
392
+
393
+ def __init__(
394
+ self,
395
+ addr,
396
+ name,
397
+ functy: SimTypeFunction,
398
+ arg_list: list[CVariable],
399
+ statements,
400
+ variables_in_use,
401
+ variable_manager,
402
+ demangled_name=None,
403
+ show_demangled_name=True,
404
+ omit_header=False,
405
+ **kwargs,
406
+ ):
407
+ super().__init__(**kwargs)
408
+
409
+ self.addr = addr
410
+ self.name = name
411
+ self.functy = functy
412
+ self.arg_list = arg_list
413
+ self.statements = statements
414
+ self.variables_in_use = variables_in_use
415
+ self.variable_manager: VariableManagerInternal = variable_manager
416
+ self.demangled_name = demangled_name
417
+ self.unified_local_vars: dict[SimVariable, set[tuple[CVariable, SimType]]] = self.get_unified_local_vars()
418
+ self.show_demangled_name = show_demangled_name
419
+ self.omit_header = omit_header
420
+
421
+ def get_unified_local_vars(self) -> dict[SimVariable, set[tuple[CVariable, SimType]]]:
422
+ unified_to_var_and_types: dict[SimVariable, set[tuple[CVariable, SimType]]] = defaultdict(set)
423
+
424
+ arg_set: set[SimVariable] = set()
425
+ for arg in self.arg_list:
426
+ # TODO: Handle CIndexedVariable
427
+ if isinstance(arg, CVariable):
428
+ if arg.unified_variable is not None:
429
+ arg_set.add(arg.unified_variable)
430
+ else:
431
+ arg_set.add(arg.variable)
432
+
433
+ # output each variable and its type
434
+ for var, cvar in self.variables_in_use.items():
435
+ if isinstance(var, SimMemoryVariable) and not isinstance(var, SimStackVariable):
436
+ # Skip all global variables
437
+ continue
438
+
439
+ if var in arg_set or cvar.unified_variable in arg_set:
440
+ continue
441
+
442
+ unified_var = self.variable_manager.unified_variable(var)
443
+ if unified_var is not None:
444
+ key = unified_var
445
+ var_type = self.variable_manager.get_variable_type(var) # FIXME
446
+ else:
447
+ key = var
448
+ var_type = self.variable_manager.get_variable_type(var)
449
+
450
+ if var_type is None:
451
+ var_type = SimTypeBottom().with_arch(self.codegen.project.arch)
452
+
453
+ unified_to_var_and_types[key].add((cvar, var_type))
454
+
455
+ return unified_to_var_and_types
456
+
457
+ def variable_list_repr_chunks(self, indent=0):
458
+ def _varname_to_id(varname: str) -> int:
459
+ # extract id from default variable name "v{id}"
460
+ if varname.startswith("v"):
461
+ try:
462
+ return int(varname[1:])
463
+ except ValueError:
464
+ pass
465
+ return 0
466
+
467
+ indent_str = self.indent_str(indent)
468
+
469
+ for variable, cvar_and_vartypes in sorted(
470
+ self.unified_local_vars.items(), key=lambda x: _varname_to_id(x[0].name) if x[0].name else 0
471
+ ):
472
+ yield indent_str, None
473
+
474
+ # pick the first cvariable
475
+ # picking any cvariable is enough since highlighting works on the unified variable
476
+ try:
477
+ cvariable = next(iter(cvar_and_vartypes))[0]
478
+ except StopIteration:
479
+ # this should never happen, but pylint complains
480
+ continue
481
+
482
+ if variable.name:
483
+ name = variable.name
484
+ elif isinstance(variable, SimTemporaryVariable):
485
+ name = f"tmp_{variable.tmp_id}"
486
+ else:
487
+ name = str(variable)
488
+
489
+ # sort by the following:
490
+ # * if it's a a non-basic type
491
+ # * the number of occurrences
492
+ # * the repr of the type itself
493
+ # TODO: The type selection should actually happen during variable unification
494
+ vartypes = [x[1] for x in cvar_and_vartypes]
495
+ count = Counter(vartypes)
496
+ vartypes = sorted(
497
+ count.copy(),
498
+ key=lambda x, ct=count: (isinstance(x, (SimTypeChar, SimTypeInt, SimTypeFloat)), ct[x], repr(x)),
499
+ )
500
+
501
+ for i, var_type in enumerate(vartypes):
502
+ if i == 0:
503
+ yield from type_to_c_repr_chunks(var_type, name=name, name_type=cvariable)
504
+ yield "; // ", None
505
+ yield variable.loc_repr(self.codegen.project.arch), None
506
+ # multiple types
507
+ else:
508
+ if i == 1:
509
+ yield ", Other Possible Types: ", None
510
+ else:
511
+ yield ", ", None
512
+ if isinstance(var_type, SimType):
513
+ yield var_type.c_repr(), var_type
514
+ else:
515
+ yield str(var_type), var_type
516
+ yield "\n", None
517
+
518
+ if self.unified_local_vars:
519
+ yield "\n", None
520
+
521
+ def c_repr_chunks(self, indent=0, asexpr=False):
522
+ if self.omit_header:
523
+ yield from self.headerless_c_repr_chunks(indent=indent)
524
+ else:
525
+ yield from self.full_c_repr_chunks(indent=indent, asexpr=asexpr)
526
+
527
+ def headerless_c_repr_chunks(self, indent=0):
528
+ yield from self.statements.c_repr_chunks(indent=indent)
529
+ yield "\n", None
530
+
531
+ def full_c_repr_chunks(self, indent=0, asexpr=False):
532
+ indent_str = self.indent_str(indent)
533
+ if self.codegen.show_local_types:
534
+ local_types = [unpack_typeref(ty) for ty in self.variable_manager.types.iter_own()]
535
+ name_to_structtypes = {}
536
+ for ty in local_types:
537
+ if isinstance(ty, SimStruct):
538
+ name_to_structtypes[ty.name] = ty
539
+ for field in ty.fields.values():
540
+ if isinstance(field, SimTypePointer):
541
+ if isinstance(field.pts_to, (SimTypeArray, SimTypeFixedSizeArray)):
542
+ field = field.pts_to.elem_type
543
+ else:
544
+ field = field.pts_to
545
+ if isinstance(field, SimStruct) and field not in local_types:
546
+ if field.name and not field.fields and field.name in name_to_structtypes:
547
+ # we use SimStruct types with empty fields to refer to already defined struct types
548
+ # for example, see how struct _IO_marker is defined in sim_type.py
549
+ continue
550
+ if field.name:
551
+ name_to_structtypes[field.name] = field
552
+ local_types.append(field)
553
+
554
+ yield from type_to_c_repr_chunks(ty, full=True, indent_str=indent_str)
555
+
556
+ if self.codegen.show_externs and self.codegen.cexterns:
557
+ for v in sorted(self.codegen.cexterns, key=lambda v: str(v.variable.name)):
558
+ if v.variable not in self.variables_in_use:
559
+ continue
560
+ varname = v.c_repr() if v.type is None else v.variable.name
561
+ yield "extern ", None
562
+ yield from type_to_c_repr_chunks(v.type, name=varname, name_type=v, full=False)
563
+ yield ";\n", None
564
+ yield "\n", None
565
+
566
+ yield indent_str, None
567
+
568
+ # header comments (if they exist)
569
+ assert self.codegen.cfunc is not None and self.codegen.cfunc.addr is not None
570
+ header_comments = self.codegen.kb.comments.get(self.codegen.cfunc.addr, [])
571
+ if header_comments:
572
+ header_cmt = self._line_wrap_comment("".join(header_comments))
573
+ yield header_cmt, None
574
+
575
+ if self.codegen._func.is_plt:
576
+ yield "// attributes: PLT stub\n", None
577
+
578
+ # return type
579
+ assert self.functy.returnty is not None
580
+ yield self.functy.returnty.c_repr(name="").strip(" "), self.functy.returnty
581
+ yield " ", None
582
+ # function name
583
+ if self.demangled_name and self.show_demangled_name:
584
+ normalized_name = get_cpp_function_name(self.demangled_name, specialized=False, qualified=True)
585
+ else:
586
+ normalized_name = self.name
587
+ yield normalized_name, self
588
+ # argument list
589
+ paren = CClosingObject("(")
590
+ brace = CClosingObject("{")
591
+ yield "(", paren
592
+ for i, (arg_type, cvariable) in enumerate(zip(self.functy.args, self.arg_list)):
593
+ if i:
594
+ yield ", ", None
595
+
596
+ variable = cvariable.unified_variable or cvariable.variable
597
+ yield from type_to_c_repr_chunks(arg_type, name=variable.name, name_type=cvariable, full=False)
598
+
599
+ yield ")", paren
600
+ # function body
601
+ if self.codegen.braces_on_own_lines:
602
+ yield "\n", None
603
+ yield indent_str, None
604
+ else:
605
+ yield " ", None
606
+ yield "{", brace
607
+ yield "\n", None
608
+ yield from self.variable_list_repr_chunks(indent=indent + INDENT_DELTA)
609
+ yield from self.statements.c_repr_chunks(indent=indent + INDENT_DELTA)
610
+ yield indent_str, None
611
+ yield "}", brace
612
+ yield "\n", None
613
+
614
+ @staticmethod
615
+ def _line_wrap_comment(comment: str, width=80) -> str:
616
+ lines = comment.splitlines()
617
+ wrapped_cmt = ""
618
+
619
+ for line in lines:
620
+ if len(line) < width:
621
+ wrapped_cmt += line + "\n"
622
+ continue
623
+
624
+ for i, c in enumerate(line):
625
+ if i % width == 0 and i != 0:
626
+ wrapped_cmt += "\n"
627
+ wrapped_cmt += c
628
+
629
+ wrapped_cmt += "\n"
630
+
631
+ return "".join([f"// {line}\n" for line in wrapped_cmt.splitlines()])
632
+
633
+
634
+ class CStatement(CConstruct): # pylint:disable=abstract-method
635
+ """
636
+ Represents a statement in C.
637
+ """
638
+
639
+ def __init__(self, tags=None, codegen=None):
640
+ super().__init__(codegen=codegen, tags=tags)
641
+
642
+
643
+ class CExpression(CConstruct):
644
+ """
645
+ Base class for C expressions.
646
+ """
647
+
648
+ __slots__ = ("_type", "collapsed")
649
+
650
+ def __init__(self, collapsed=False, tags=None, codegen=None):
651
+ super().__init__(codegen=codegen, tags=tags)
652
+ self._type = None
653
+ self.collapsed = collapsed
654
+
655
+ @property
656
+ def type(self):
657
+ raise NotImplementedError(f"Class {type(self)} does not implement type().")
658
+
659
+ def set_type(self, v):
660
+ self._type = v
661
+
662
+ @staticmethod
663
+ def _try_c_repr_chunks(expr):
664
+ if hasattr(expr, "c_repr_chunks"):
665
+ yield from expr.c_repr_chunks()
666
+ else:
667
+ yield str(expr), expr
668
+
669
+
670
+ class CStatements(CStatement):
671
+ """
672
+ Represents a sequence of statements in C.
673
+ """
674
+
675
+ __slots__ = (
676
+ "addr",
677
+ "statements",
678
+ )
679
+
680
+ def __init__(self, statements, addr=None, **kwargs):
681
+ super().__init__(**kwargs)
682
+
683
+ self.statements = statements
684
+ self.addr = addr
685
+
686
+ def c_repr_chunks(self, indent=0, asexpr=False):
687
+ indent_str = self.indent_str(indent)
688
+ if self.codegen.display_block_addrs:
689
+ yield indent_str, None
690
+ yield f"/* Block {hex(self.addr) if self.addr is not None else 'unknown'} */", None
691
+ yield "\n", None
692
+ for stmt in self.statements:
693
+ yield from stmt.c_repr_chunks(indent=indent, asexpr=asexpr)
694
+ if asexpr:
695
+ yield ", ", None
696
+
697
+
698
+ class CAILBlock(CStatement):
699
+ """
700
+ Represents a block of AIL statements.
701
+ """
702
+
703
+ __slots__ = ("block",)
704
+
705
+ def __init__(self, block, **kwargs):
706
+ super().__init__(**kwargs)
707
+
708
+ self.block = block
709
+
710
+ def c_repr_chunks(self, indent=0, asexpr=False):
711
+ indent_str = self.indent_str(indent=indent)
712
+ r = str(self.block)
713
+ for stmt in r.split("\n"):
714
+ yield indent_str, None
715
+ yield stmt, None
716
+ yield "\n", None
717
+
718
+
719
+ class CLoop(CStatement): # pylint:disable=abstract-method
720
+ """
721
+ Represents a loop in C.
722
+ """
723
+
724
+ __slots__ = ()
725
+
726
+
727
+ class CWhileLoop(CLoop):
728
+ """
729
+ Represents a while loop in C.
730
+ """
731
+
732
+ __slots__ = (
733
+ "body",
734
+ "condition",
735
+ )
736
+
737
+ def __init__(self, condition, body, **kwargs):
738
+ super().__init__(**kwargs)
739
+
740
+ self.condition = condition
741
+ self.body = body
742
+
743
+ def c_repr_chunks(self, indent=0, asexpr=False):
744
+ indent_str = self.indent_str(indent=indent)
745
+
746
+ yield indent_str, None
747
+ yield "while ", None
748
+ paren = CClosingObject("(")
749
+ brace = CClosingObject("{")
750
+ yield "(", paren
751
+ if self.condition is None:
752
+ yield "true", self
753
+ else:
754
+ yield from self.condition.c_repr_chunks()
755
+ yield ")", paren
756
+ if self.codegen.braces_on_own_lines:
757
+ yield "\n", None
758
+ yield indent_str, None
759
+ else:
760
+ yield " ", None
761
+ if self.body is None:
762
+ yield ";", None
763
+ yield "\n", None
764
+ else:
765
+ yield "{", brace
766
+ yield "\n", None
767
+ yield from self.body.c_repr_chunks(indent=indent + INDENT_DELTA)
768
+ yield indent_str, None
769
+ yield "}", brace
770
+ yield "\n", None
771
+
772
+
773
+ class CDoWhileLoop(CLoop):
774
+ """
775
+ Represents a do-while loop in C.
776
+ """
777
+
778
+ __slots__ = (
779
+ "body",
780
+ "condition",
781
+ )
782
+
783
+ def __init__(self, condition, body, **kwargs):
784
+ super().__init__(**kwargs)
785
+
786
+ self.condition = condition
787
+ self.body = body
788
+
789
+ def c_repr_chunks(self, indent=0, asexpr=False):
790
+ indent_str = self.indent_str(indent=indent)
791
+ brace = CClosingObject("{")
792
+ paren = CClosingObject("(")
793
+
794
+ yield indent_str, None
795
+ yield "do", self
796
+ if self.codegen.braces_on_own_lines:
797
+ yield "\n", None
798
+ yield indent_str, None
799
+ else:
800
+ yield " ", None
801
+ if self.body is not None:
802
+ yield "{", brace
803
+ yield "\n", None
804
+ yield from self.body.c_repr_chunks(indent=indent + INDENT_DELTA)
805
+ yield indent_str, None
806
+ yield "}", brace
807
+ else:
808
+ yield "{", brace
809
+ yield " ", None
810
+ yield "}", brace
811
+ yield " ", None
812
+ yield "while ", self
813
+ yield "(", paren
814
+ if self.condition is None:
815
+ yield "true", self
816
+ else:
817
+ yield from self.condition.c_repr_chunks()
818
+ yield ")", paren
819
+ yield ";\n", self
820
+
821
+
822
+ class CForLoop(CStatement):
823
+ """
824
+ Represents a for-loop in C.
825
+ """
826
+
827
+ __slots__ = (
828
+ "body",
829
+ "condition",
830
+ "initializer",
831
+ "iterator",
832
+ )
833
+
834
+ def __init__(self, initializer, condition, iterator, body, **kwargs):
835
+ super().__init__(**kwargs)
836
+
837
+ self.initializer = initializer
838
+ self.condition = condition
839
+ self.iterator = iterator
840
+ self.body = body
841
+
842
+ def c_repr_chunks(self, indent=0, asexpr=False):
843
+ indent_str = self.indent_str(indent=indent)
844
+ brace = CClosingObject("{")
845
+ paren = CClosingObject("(")
846
+
847
+ yield indent_str, None
848
+ yield "for ", self
849
+ yield "(", paren
850
+ if self.initializer is not None:
851
+ yield from self.initializer.c_repr_chunks(indent=0, asexpr=True)
852
+ yield "; ", None
853
+ if self.condition is not None:
854
+ yield from self.condition.c_repr_chunks(indent=0)
855
+ yield "; ", None
856
+ if self.iterator is not None:
857
+ yield from self.iterator.c_repr_chunks(indent=0, asexpr=True)
858
+ yield ")", paren
859
+
860
+ if self.body is not None:
861
+ if self.codegen.braces_on_own_lines:
862
+ yield "\n", None
863
+ yield indent_str, None
864
+ else:
865
+ yield " ", None
866
+
867
+ yield "{", brace
868
+ yield "\n", None
869
+ yield from self.body.c_repr_chunks(indent=indent + INDENT_DELTA)
870
+ yield indent_str, None
871
+ yield "}", brace
872
+ else:
873
+ yield ";", None
874
+ yield "\n", None
875
+
876
+
877
+ class CIfElse(CStatement):
878
+ """
879
+ Represents an if-else construct in C.
880
+ """
881
+
882
+ __slots__ = (
883
+ "condition_and_nodes",
884
+ "cstyle_ifs",
885
+ "else_node",
886
+ "simplify_else_scope",
887
+ )
888
+
889
+ def __init__(
890
+ self,
891
+ condition_and_nodes: list[tuple[CExpression, CStatement | None]],
892
+ else_node=None,
893
+ simplify_else_scope=False,
894
+ cstyle_ifs=True,
895
+ **kwargs,
896
+ ):
897
+ super().__init__(**kwargs)
898
+
899
+ self.condition_and_nodes = condition_and_nodes
900
+ self.else_node = else_node
901
+ self.simplify_else_scope = simplify_else_scope
902
+ self.cstyle_ifs = cstyle_ifs
903
+
904
+ if not self.condition_and_nodes:
905
+ raise ValueError("You must specify at least one condition")
906
+
907
+ @staticmethod
908
+ def _is_single_stmt_node(node):
909
+ return (isinstance(node, CStatements) and len(node.statements) == 1) or isinstance(
910
+ node, (CBreak, CContinue, CReturn, CGoto)
911
+ )
912
+
913
+ def c_repr_chunks(self, indent=0, asexpr=False):
914
+ indent_str = self.indent_str(indent=indent)
915
+ paren = CClosingObject("(")
916
+ brace = CClosingObject("{")
917
+
918
+ first_node = True
919
+ first_node_is_single_stmt_if = False
920
+ for condition, node in self.condition_and_nodes:
921
+ # omit braces in the event that you want c-style if-statements that have only a single statement
922
+ # and have no else scope or an else with also a single statement
923
+ omit_braces = (
924
+ self.cstyle_ifs
925
+ and first_node
926
+ and len(self.condition_and_nodes) == 1
927
+ # no else-if tree can exist
928
+ and self._is_single_stmt_node(node)
929
+ # no else, else is also single-stmt, or else will not exist after pass
930
+ and (self.else_node is None or self._is_single_stmt_node(self.else_node) or self.simplify_else_scope)
931
+ )
932
+
933
+ if first_node:
934
+ first_node = False
935
+ first_node_is_single_stmt_if = omit_braces
936
+ yield indent_str, None
937
+ else:
938
+ if self.codegen.braces_on_own_lines:
939
+ yield "\n", None
940
+ yield indent_str, None
941
+ else:
942
+ yield " ", None
943
+ yield "else ", self
944
+
945
+ yield "if ", self
946
+ yield "(", paren
947
+ yield from condition.c_repr_chunks()
948
+ yield ")", paren
949
+ if omit_braces:
950
+ yield "\n", None
951
+ else:
952
+ if self.codegen.braces_on_own_lines:
953
+ yield "\n", None
954
+ yield indent_str, None
955
+ else:
956
+ yield " ", None
957
+
958
+ yield "{", brace
959
+ yield "\n", None
960
+
961
+ if node is not None:
962
+ yield from node.c_repr_chunks(indent=INDENT_DELTA + indent)
963
+
964
+ if not omit_braces:
965
+ yield indent_str, None
966
+ yield "}", brace
967
+
968
+ single_stmt_else = first_node_is_single_stmt_if and len(self.condition_and_nodes) == 1
969
+ if self.else_node is not None:
970
+ brace = CClosingObject("{")
971
+ if self.simplify_else_scope:
972
+ if not single_stmt_else:
973
+ yield "\n", None
974
+ yield from self.else_node.c_repr_chunks(indent=indent)
975
+ else:
976
+ if single_stmt_else:
977
+ yield indent_str, None
978
+ elif self.codegen.braces_on_own_lines:
979
+ yield "\n", None
980
+ yield indent_str, None
981
+ else:
982
+ yield " ", None
983
+
984
+ yield "else", self
985
+ if self.codegen.braces_on_own_lines or single_stmt_else:
986
+ yield "\n", None
987
+ yield indent_str, None
988
+ else:
989
+ yield " ", None
990
+
991
+ if single_stmt_else:
992
+ yield from self.else_node.c_repr_chunks(indent=INDENT_DELTA)
993
+ else:
994
+ yield "{", brace
995
+ yield "\n", None
996
+ yield from self.else_node.c_repr_chunks(indent=indent + INDENT_DELTA)
997
+ yield indent_str, None
998
+ yield "}", brace
999
+
1000
+ if not first_node_is_single_stmt_if and not self.simplify_else_scope:
1001
+ yield "\n", None
1002
+
1003
+
1004
+ class CIfBreak(CStatement):
1005
+ """
1006
+ Represents an if-break statement in C.
1007
+ """
1008
+
1009
+ __slots__ = (
1010
+ "condition",
1011
+ "cstyle_ifs",
1012
+ )
1013
+
1014
+ def __init__(self, condition, cstyle_ifs=True, **kwargs):
1015
+ super().__init__(**kwargs)
1016
+
1017
+ self.condition = condition
1018
+ self.cstyle_ifs = cstyle_ifs
1019
+
1020
+ def c_repr_chunks(self, indent=0, asexpr=False):
1021
+ indent_str = self.indent_str(indent=indent)
1022
+ paren = CClosingObject("(")
1023
+ brace = CClosingObject("{")
1024
+
1025
+ yield indent_str, None
1026
+ yield "if ", self
1027
+ yield "(", paren
1028
+ yield from self.condition.c_repr_chunks()
1029
+ yield ")", paren
1030
+ if self.codegen.braces_on_own_lines or self.cstyle_ifs:
1031
+ yield "\n", None
1032
+ yield indent_str, None
1033
+ else:
1034
+ yield " ", None
1035
+ if self.cstyle_ifs:
1036
+ yield self.indent_str(indent=INDENT_DELTA), self
1037
+ yield "break;\n", self
1038
+ else:
1039
+ yield "{", brace
1040
+ yield "\n", None
1041
+ yield self.indent_str(indent=indent + INDENT_DELTA), self
1042
+ yield "break;\n", self
1043
+ yield indent_str, None
1044
+ yield "}", brace
1045
+ if not self.cstyle_ifs:
1046
+ yield "\n", None
1047
+
1048
+
1049
+ class CBreak(CStatement):
1050
+ """
1051
+ Represents a break statement in C.
1052
+ """
1053
+
1054
+ __slots__ = ()
1055
+
1056
+ def __init__(self, **kwargs):
1057
+ super().__init__(**kwargs)
1058
+
1059
+ def c_repr_chunks(self, indent=0, asexpr=False):
1060
+ indent_str = self.indent_str(indent=indent)
1061
+
1062
+ yield indent_str, None
1063
+ yield "break;\n", self
1064
+
1065
+
1066
+ class CContinue(CStatement):
1067
+ """
1068
+ Represents a continue statement in C.
1069
+ """
1070
+
1071
+ __slots__ = ()
1072
+
1073
+ def __init__(self, **kwargs):
1074
+ super().__init__(**kwargs)
1075
+
1076
+ def c_repr_chunks(self, indent=0, asexpr=False):
1077
+ indent_str = self.indent_str(indent=indent)
1078
+
1079
+ yield indent_str, None
1080
+ yield "continue;\n", self
1081
+
1082
+
1083
+ class CSwitchCase(CStatement):
1084
+ """
1085
+ Represents a switch-case statement in C.
1086
+ """
1087
+
1088
+ __slots__ = ("cases", "default", "switch")
1089
+
1090
+ def __init__(self, switch, cases, default, **kwargs):
1091
+ super().__init__(**kwargs)
1092
+
1093
+ self.switch = switch
1094
+ self.cases: list[tuple[int | tuple[int], CStatements]] = cases
1095
+ self.default = default
1096
+
1097
+ def c_repr_chunks(self, indent=0, asexpr=False):
1098
+ indent_str = self.indent_str(indent=indent)
1099
+ paren = CClosingObject("(")
1100
+ brace = CClosingObject("{")
1101
+
1102
+ yield indent_str, None
1103
+ yield "switch ", self
1104
+ yield "(", paren
1105
+ yield from self.switch.c_repr_chunks()
1106
+ yield ")", paren
1107
+ if self.codegen.braces_on_own_lines:
1108
+ yield "\n", None
1109
+ yield indent_str, None
1110
+ else:
1111
+ yield " ", None
1112
+ yield "{", brace
1113
+ yield "\n", None
1114
+
1115
+ # cases
1116
+ for id_or_ids, case in self.cases:
1117
+ yield indent_str, None
1118
+ if isinstance(id_or_ids, int):
1119
+ yield f"case {id_or_ids}", self
1120
+ yield ":\n", None
1121
+ else:
1122
+ for i, case_id in enumerate(id_or_ids):
1123
+ yield f"case {case_id}", self
1124
+ yield ":", None
1125
+ if i != len(id_or_ids) - 1:
1126
+ yield " ", None
1127
+ yield "\n", None
1128
+ yield from case.c_repr_chunks(indent=indent + INDENT_DELTA)
1129
+
1130
+ if self.default is not None:
1131
+ yield indent_str, None
1132
+ yield "default:\n", self
1133
+ yield from self.default.c_repr_chunks(indent=indent + INDENT_DELTA)
1134
+
1135
+ yield indent_str, None
1136
+ yield "}", brace
1137
+ yield "\n", None
1138
+
1139
+
1140
+ class CIncompleteSwitchCase(CStatement):
1141
+ """
1142
+ Represents an incomplete switch-case construct; this only appear in the decompilation output when switch-case
1143
+ structuring fails (for whatever reason).
1144
+ """
1145
+
1146
+ __slots__ = ("cases", "head")
1147
+
1148
+ def __init__(self, head, cases, **kwargs):
1149
+ super().__init__(**kwargs)
1150
+
1151
+ self.head = head
1152
+ self.cases: list[tuple[int, CStatements]] = cases
1153
+
1154
+ def c_repr_chunks(self, indent=0, asexpr=False):
1155
+ indent_str = self.indent_str(indent=indent)
1156
+ paren = CClosingObject("(")
1157
+ brace = CClosingObject("{")
1158
+
1159
+ yield from self.head.c_repr_chunks(indent=indent)
1160
+ yield "\n", None
1161
+ yield indent_str, None
1162
+ yield "switch ", self
1163
+ yield "(", paren
1164
+ yield "/* incomplete */", None
1165
+ yield ")", paren
1166
+ if self.codegen.braces_on_own_lines:
1167
+ yield "\n", None
1168
+ yield indent_str, None
1169
+ else:
1170
+ yield " ", None
1171
+ yield "{", brace
1172
+ yield "\n", None
1173
+
1174
+ # cases
1175
+ for case_addr, case in self.cases:
1176
+ yield indent_str, None
1177
+ yield f"case {case_addr:#x}", self
1178
+ yield ":\n", None
1179
+ yield from case.c_repr_chunks(indent=indent + INDENT_DELTA)
1180
+
1181
+ yield indent_str, None
1182
+ yield "}", brace
1183
+ yield "\n", None
1184
+
1185
+
1186
+ class CAssignment(CStatement):
1187
+ """
1188
+ a = b
1189
+ """
1190
+
1191
+ __slots__ = ("lhs", "rhs")
1192
+
1193
+ def __init__(self, lhs, rhs, **kwargs):
1194
+ super().__init__(**kwargs)
1195
+
1196
+ self.lhs = lhs
1197
+ self.rhs = rhs
1198
+
1199
+ def c_repr_chunks(self, indent=0, asexpr=False):
1200
+ indent_str = self.indent_str(indent=indent)
1201
+
1202
+ yield indent_str, None
1203
+ yield from CExpression._try_c_repr_chunks(self.lhs)
1204
+
1205
+ compound_assignment_ops = {
1206
+ "Add": "+",
1207
+ "Sub": "-",
1208
+ "Mul": "*",
1209
+ "Div": "/",
1210
+ "And": "&",
1211
+ "Xor": "^",
1212
+ "Or": "|",
1213
+ "Shr": ">>",
1214
+ "Shl": "<<",
1215
+ "Sar": ">>",
1216
+ }
1217
+ commutative_ops = {"Add", "Mul", "And", "Xor", "Or"}
1218
+
1219
+ compound_expr_rhs = None
1220
+ if (
1221
+ self.codegen.use_compound_assignments
1222
+ and isinstance(self.lhs, CVariable)
1223
+ and isinstance(self.rhs, CBinaryOp)
1224
+ and self.rhs.op in compound_assignment_ops
1225
+ and self.lhs.unified_variable is not None
1226
+ ):
1227
+ if isinstance(self.rhs.lhs, CVariable) and self.lhs.unified_variable is self.rhs.lhs.unified_variable:
1228
+ compound_expr_rhs = self.rhs.rhs
1229
+ elif (
1230
+ self.rhs.op in commutative_ops
1231
+ and isinstance(self.rhs.rhs, CVariable)
1232
+ and self.lhs.unified_variable is self.rhs.rhs.unified_variable
1233
+ ):
1234
+ compound_expr_rhs = self.rhs.lhs
1235
+
1236
+ if compound_expr_rhs is not None:
1237
+ # a = a + x => a += x
1238
+ # a = x + a => a += x
1239
+ yield f" {compound_assignment_ops[self.rhs.op]}= ", self
1240
+ yield from CExpression._try_c_repr_chunks(compound_expr_rhs)
1241
+ else:
1242
+ yield " = ", self
1243
+ yield from CExpression._try_c_repr_chunks(self.rhs)
1244
+ if not asexpr:
1245
+ yield ";\n", self
1246
+
1247
+
1248
+ class CFunctionCall(CStatement, CExpression):
1249
+ """
1250
+ func(arg0, arg1)
1251
+
1252
+ :ivar Function callee_func: The function getting called.
1253
+ :ivar is_expr: True if the return value of the function is written to ret_expr; Essentially, ret_expr = call().
1254
+ """
1255
+
1256
+ __slots__ = (
1257
+ "args",
1258
+ "callee_func",
1259
+ "callee_target",
1260
+ "is_expr",
1261
+ "prettify_thiscall",
1262
+ "ret_expr",
1263
+ "returning",
1264
+ "show_demangled_name",
1265
+ "show_disambiguated_name",
1266
+ )
1267
+
1268
+ def __init__(
1269
+ self,
1270
+ callee_target,
1271
+ callee_func,
1272
+ args,
1273
+ returning=True,
1274
+ ret_expr=None,
1275
+ is_expr: bool = False,
1276
+ show_demangled_name=True,
1277
+ show_disambiguated_name: bool = True,
1278
+ prettify_thiscall: bool = True,
1279
+ tags=None,
1280
+ codegen=None,
1281
+ **kwargs,
1282
+ ):
1283
+ super().__init__(tags=tags, codegen=codegen, **kwargs)
1284
+ CConstruct.__init__(self, tags=tags, codegen=codegen)
1285
+
1286
+ self.callee_target = callee_target
1287
+ self.callee_func: Function | None = callee_func
1288
+ self.args = args if args is not None else []
1289
+ self.returning = returning
1290
+ self.ret_expr = ret_expr
1291
+ self.is_expr = is_expr
1292
+ self.show_demangled_name = show_demangled_name
1293
+ self.show_disambiguated_name = show_disambiguated_name
1294
+ self.prettify_thiscall = prettify_thiscall
1295
+
1296
+ @property
1297
+ def prototype(self) -> SimTypeFunction | None: # TODO there should be a prototype for each callsite!
1298
+ if self.callee_func is not None and self.callee_func.prototype is not None:
1299
+ proto = self.callee_func.prototype
1300
+ if self.callee_func.prototype_libname is not None:
1301
+ # we need to deref the prototype in case it uses SimTypeRef internally
1302
+ proto = cast(SimTypeFunction, dereference_simtype_by_lib(proto, self.callee_func.prototype_libname))
1303
+ return proto
1304
+ returnty = SimTypeInt(signed=False)
1305
+ return SimTypeFunction([arg.type for arg in self.args], returnty).with_arch(self.codegen.project.arch)
1306
+
1307
+ @property
1308
+ def type(self):
1309
+ if self.is_expr:
1310
+ return (self.prototype.returnty if self.prototype is not None else None) or SimTypeInt(
1311
+ signed=False
1312
+ ).with_arch(self.codegen.project.arch)
1313
+ raise AngrRuntimeError("CFunctionCall.type should not be accessed if the function call is used as a statement.")
1314
+
1315
+ def _is_target_ambiguous(self, func_name: str) -> bool:
1316
+ """
1317
+ Check for call target name ambiguity.
1318
+ """
1319
+ caller, callee = self.codegen._func, self.callee_func
1320
+
1321
+ assert self.codegen._variables_in_use is not None
1322
+
1323
+ for var in self.codegen._variables_in_use.values():
1324
+ if func_name == var.name:
1325
+ return True
1326
+
1327
+ # FIXME: Handle name mangle
1328
+ for func in self.codegen.kb.functions.get_by_name(callee.name):
1329
+ if func is not callee and (caller.binary is not callee.binary or func.binary is callee.binary):
1330
+ return True
1331
+
1332
+ return False
1333
+
1334
+ @staticmethod
1335
+ def _is_func_likely_cxx_class_method(func_name: str) -> bool:
1336
+ if "::" not in func_name:
1337
+ return False
1338
+ chunks = func_name.split("::")
1339
+ return re.match(r"[a-zA-Z_][a-zA-Z0-9_]*", chunks[-1]) is not None
1340
+
1341
+ def c_repr_chunks(self, indent=0, asexpr: bool = False):
1342
+ """
1343
+
1344
+ :param indent: Number of whitespace indentation characters.
1345
+ :param asexpr: True if this call is used as an expression (which means we will skip the generation of
1346
+ semicolons and newlines at the end of the call).
1347
+ """
1348
+ indent_str = self.indent_str(indent=indent)
1349
+ yield indent_str, None
1350
+
1351
+ if not self.is_expr and self.ret_expr is not None:
1352
+ yield from CExpression._try_c_repr_chunks(self.ret_expr)
1353
+ yield " = ", None
1354
+
1355
+ if self.callee_func is not None:
1356
+ if self.callee_func.demangled_name and self.show_demangled_name:
1357
+ func_name = get_cpp_function_name(self.callee_func.demangled_name, specialized=False, qualified=True)
1358
+ else:
1359
+ func_name = self.callee_func.name
1360
+ if self.prettify_thiscall and self.args and self._is_func_likely_cxx_class_method(func_name):
1361
+ func_name = self.callee_func.short_name
1362
+ yield from self._c_repr_chunks_thiscall(func_name, asexpr=asexpr)
1363
+ return
1364
+ if self.show_disambiguated_name and self._is_target_ambiguous(func_name):
1365
+ func_name = self.callee_func.get_unambiguous_name(display_name=func_name)
1366
+
1367
+ yield func_name, self
1368
+ elif isinstance(self.callee_target, str):
1369
+ yield self.callee_target, self
1370
+ else:
1371
+ yield from CExpression._try_c_repr_chunks(self.callee_target)
1372
+
1373
+ paren = CClosingObject("(")
1374
+ yield "(", paren
1375
+
1376
+ for i, arg in enumerate(self.args):
1377
+ if i:
1378
+ yield ", ", None
1379
+ yield from CExpression._try_c_repr_chunks(arg)
1380
+
1381
+ yield ")", paren
1382
+
1383
+ if not self.is_expr and not asexpr:
1384
+ yield ";", None
1385
+ if not self.returning:
1386
+ yield " /* do not return */", None
1387
+ yield "\n", None
1388
+
1389
+ def _c_repr_chunks_thiscall(self, func_name: str, asexpr: bool = False):
1390
+ # The first argument is the `this` pointer
1391
+ assert self.args
1392
+ this_ref = self.args[0]
1393
+ if isinstance(this_ref, CUnaryOp) and this_ref.op == "Reference":
1394
+ yield from CExpression._try_c_repr_chunks(this_ref.operand)
1395
+ else:
1396
+ yield from CExpression._try_c_repr_chunks(this_ref)
1397
+
1398
+ yield ".", None
1399
+ yield func_name, self
1400
+
1401
+ # the remaining arguments
1402
+ paren = CClosingObject("(")
1403
+ yield "(", paren
1404
+
1405
+ for i, arg in enumerate(self.args):
1406
+ if i == 0:
1407
+ continue
1408
+ if i > 1:
1409
+ yield ", ", None
1410
+ yield from CExpression._try_c_repr_chunks(arg)
1411
+
1412
+ yield ")", paren
1413
+
1414
+ if not self.is_expr and not asexpr:
1415
+ yield ";", None
1416
+ if not self.returning:
1417
+ yield " /* do not return */", None
1418
+ yield "\n", None
1419
+
1420
+
1421
+ class CReturn(CStatement):
1422
+ __slots__ = ("retval",)
1423
+
1424
+ def __init__(self, retval, **kwargs):
1425
+ super().__init__(**kwargs)
1426
+
1427
+ self.retval = retval
1428
+
1429
+ def c_repr_chunks(self, indent=0, asexpr=False):
1430
+ indent_str = self.indent_str(indent=indent)
1431
+
1432
+ if not self.retval:
1433
+ yield indent_str, None
1434
+ yield "return;\n", self
1435
+ else:
1436
+ yield indent_str, None
1437
+ yield "return ", self
1438
+ yield from self.retval.c_repr_chunks()
1439
+ yield ";\n", self
1440
+
1441
+
1442
+ class CGoto(CStatement):
1443
+ __slots__ = (
1444
+ "target",
1445
+ "target_idx",
1446
+ )
1447
+
1448
+ def __init__(self, target, target_idx, **kwargs):
1449
+ super().__init__(**kwargs)
1450
+
1451
+ if isinstance(target, CConstant):
1452
+ # unpack target
1453
+ target = target.value
1454
+
1455
+ self.target: int | CExpression = target
1456
+ self.target_idx = target_idx
1457
+
1458
+ def c_repr_chunks(self, indent=0, asexpr=False):
1459
+ indent_str = self.indent_str(indent=indent)
1460
+ lbl = None
1461
+ if self.codegen is not None and isinstance(self.target, int):
1462
+ lbl = self.codegen.map_addr_to_label.get((self.target, self.target_idx))
1463
+
1464
+ yield indent_str, None
1465
+ if self.codegen.comment_gotos:
1466
+ yield "/* ", None
1467
+ yield "goto ", self
1468
+ if lbl is None:
1469
+ if isinstance(self.target, int):
1470
+ yield f"LABEL_{self.target:#x}", None
1471
+ else:
1472
+ yield from self.target.c_repr_chunks()
1473
+ else:
1474
+ yield lbl.name, lbl
1475
+ yield ";", self
1476
+ if self.codegen.comment_gotos:
1477
+ yield " */", None
1478
+ yield "\n", None
1479
+
1480
+
1481
+ class CUnsupportedStatement(CStatement):
1482
+ """
1483
+ A wrapper for unsupported AIL statement.
1484
+ """
1485
+
1486
+ __slots__ = ("stmt",)
1487
+
1488
+ def __init__(self, stmt, **kwargs):
1489
+ super().__init__(**kwargs)
1490
+
1491
+ self.stmt = stmt
1492
+
1493
+ def c_repr_chunks(self, indent=0, asexpr=False):
1494
+ indent_str = self.indent_str(indent=indent)
1495
+
1496
+ yield indent_str, None
1497
+ yield str(self.stmt), None
1498
+ yield "\n", None
1499
+
1500
+
1501
+ class CDirtyStatement(CExpression):
1502
+ __slots__ = ("dirty",)
1503
+
1504
+ def __init__(self, dirty: CDirtyExpression, **kwargs):
1505
+ super().__init__(**kwargs)
1506
+ self.dirty = dirty
1507
+
1508
+ @property
1509
+ def type(self):
1510
+ return SimTypeInt().with_arch(self.codegen.project.arch)
1511
+
1512
+ def c_repr_chunks(self, indent=0, asexpr=False):
1513
+ indent_str = self.indent_str(indent=indent)
1514
+
1515
+ yield indent_str, None
1516
+ yield from self.dirty.c_repr_chunks()
1517
+ yield "\n", None
1518
+
1519
+
1520
+ class CLabel(CStatement):
1521
+ """
1522
+ Represents a label in C code.
1523
+ """
1524
+
1525
+ __slots__ = (
1526
+ "block_idx",
1527
+ "ins_addr",
1528
+ "name",
1529
+ )
1530
+
1531
+ def __init__(self, name: str, ins_addr: int, block_idx: int | None, **kwargs):
1532
+ super().__init__(**kwargs)
1533
+ self.name = name
1534
+ self.ins_addr = ins_addr
1535
+ self.block_idx = block_idx
1536
+
1537
+ def c_repr_chunks(self, indent=0, asexpr=False):
1538
+ # indent-_str = self.indent_str(indent=indent)
1539
+
1540
+ yield self.name, self
1541
+ yield ":", None
1542
+ yield "\n", None
1543
+
1544
+
1545
+ class CStructField(CExpression):
1546
+ __slots__ = (
1547
+ "field",
1548
+ "offset",
1549
+ "struct_type",
1550
+ )
1551
+
1552
+ def __init__(self, struct_type: SimStruct, offset, field, **kwargs):
1553
+ super().__init__(**kwargs)
1554
+
1555
+ self.struct_type = struct_type
1556
+ self.offset = offset
1557
+ self.field = field
1558
+
1559
+ @property
1560
+ def type(self):
1561
+ return self.struct_type.fields[self.field]
1562
+
1563
+ def c_repr_chunks(self, indent=0, asexpr=False):
1564
+ if self.collapsed:
1565
+ yield "...", self
1566
+ return
1567
+ yield str(self.field), self
1568
+
1569
+
1570
+ class CFakeVariable(CExpression):
1571
+ """
1572
+ An uninterpreted name to display in the decompilation output. Pretty much always represents an error?
1573
+ """
1574
+
1575
+ __slots__ = ("name",)
1576
+
1577
+ def __init__(self, name: str, ty: SimType, **kwargs):
1578
+ super().__init__(**kwargs)
1579
+ self.name = name
1580
+ self._type = ty.with_arch(self.codegen.project.arch)
1581
+
1582
+ @property
1583
+ def type(self):
1584
+ return self._type
1585
+
1586
+ def c_repr_chunks(self, indent=0, asexpr=False):
1587
+ yield self.name, self
1588
+
1589
+
1590
+ class CVariable(CExpression):
1591
+ """
1592
+ CVariable represents access to a variable with the specified type (`variable_type`).
1593
+
1594
+ `variable` must be a SimVariable.
1595
+ """
1596
+
1597
+ __slots__ = (
1598
+ "unified_variable",
1599
+ "variable",
1600
+ "variable_type",
1601
+ "vvar_id",
1602
+ )
1603
+
1604
+ def __init__(self, variable: SimVariable, unified_variable=None, variable_type=None, vvar_id=None, **kwargs):
1605
+ super().__init__(**kwargs)
1606
+
1607
+ self.variable: SimVariable = variable
1608
+ self.unified_variable: SimVariable | None = unified_variable
1609
+ self.variable_type: SimType | None = (
1610
+ variable_type.with_arch(self.codegen.project.arch) if variable_type is not None else None
1611
+ )
1612
+ self.vvar_id = vvar_id
1613
+
1614
+ @property
1615
+ def type(self):
1616
+ return self.variable_type
1617
+
1618
+ @property
1619
+ def name(self):
1620
+ v = self.variable if self.unified_variable is None else self.unified_variable
1621
+
1622
+ if v.name:
1623
+ return v.name
1624
+ if isinstance(v, SimTemporaryVariable):
1625
+ return f"tmp_{v.tmp_id}"
1626
+ return str(v)
1627
+
1628
+ def c_repr_chunks(self, indent=0, asexpr=False):
1629
+ yield self.name, self
1630
+ if self.codegen.display_vvar_ids:
1631
+ yield f"<vvar_{self.vvar_id}>", self
1632
+
1633
+
1634
+ class CIndexedVariable(CExpression):
1635
+ """
1636
+ Represent a variable (an array) that is indexed.
1637
+ """
1638
+
1639
+ def __init__(self, variable: CExpression, index: CExpression, variable_type=None, **kwargs):
1640
+ super().__init__(**kwargs)
1641
+ self.variable = variable
1642
+ self.index: CExpression = index
1643
+ self._type = variable_type
1644
+
1645
+ if self._type is None and self.variable.type is not None:
1646
+ u = unpack_typeref(self.variable.type)
1647
+ if isinstance(u, SimTypePointer):
1648
+ # special case: (&array)[x]
1649
+ u = u.pts_to.elem_type if isinstance(u.pts_to, (SimTypeArray, SimTypeFixedSizeArray)) else u.pts_to
1650
+ u = unpack_typeref(u)
1651
+ elif isinstance(u, (SimTypeArray, SimTypeFixedSizeArray)):
1652
+ u = u.elem_type
1653
+ u = unpack_typeref(u)
1654
+ else:
1655
+ u = None # this should REALLY be an assert false
1656
+ self._type = u
1657
+
1658
+ @property
1659
+ def type(self):
1660
+ return self._type
1661
+
1662
+ def c_repr_chunks(self, indent=0, asexpr=False):
1663
+ if self.collapsed:
1664
+ yield "...", self
1665
+ return
1666
+
1667
+ bracket = CClosingObject("[")
1668
+ if not isinstance(self.variable, (CVariable, CVariableField)):
1669
+ yield "(", None
1670
+ yield from self.variable.c_repr_chunks()
1671
+ if not isinstance(self.variable, (CVariable, CVariableField)):
1672
+ yield ")", None
1673
+ yield "[", bracket
1674
+ yield from CExpression._try_c_repr_chunks(self.index)
1675
+ yield "]", bracket
1676
+
1677
+
1678
+ class CVariableField(CExpression):
1679
+ """
1680
+ Represent a field of a variable.
1681
+ """
1682
+
1683
+ def __init__(self, variable: CExpression, field: CStructField, var_is_ptr: bool = False, **kwargs):
1684
+ super().__init__(**kwargs)
1685
+ self.variable = variable
1686
+ self.field = field
1687
+ self.var_is_ptr = var_is_ptr
1688
+
1689
+ @property
1690
+ def type(self):
1691
+ return self.field.type
1692
+
1693
+ def c_repr_chunks(self, indent=0, asexpr=False):
1694
+ if self.collapsed:
1695
+ yield "...", self
1696
+ return
1697
+ yield from self.variable.c_repr_chunks()
1698
+ if self.var_is_ptr:
1699
+ yield "->", self
1700
+ else:
1701
+ yield ".", self
1702
+ yield from self.field.c_repr_chunks()
1703
+
1704
+
1705
+ class CUnaryOp(CExpression):
1706
+ """
1707
+ Unary operations.
1708
+ """
1709
+
1710
+ __slots__ = (
1711
+ "op",
1712
+ "operand",
1713
+ )
1714
+
1715
+ def __init__(self, op, operand: CExpression, **kwargs):
1716
+ super().__init__(**kwargs)
1717
+
1718
+ self.op = op
1719
+ self.operand = operand
1720
+
1721
+ if operand.type is not None:
1722
+ var_type = unpack_typeref(operand.type)
1723
+ if op == "Reference":
1724
+ self._type = SimTypePointer(var_type).with_arch(self.codegen.project.arch)
1725
+ elif op == "Dereference":
1726
+ if isinstance(var_type, SimTypePointer):
1727
+ self._type = unpack_typeref(var_type.pts_to)
1728
+ elif isinstance(var_type, (SimTypeArray, SimTypeFixedSizeArray)):
1729
+ self._type = unpack_typeref(var_type.elem_type)
1730
+
1731
+ @property
1732
+ def type(self):
1733
+ if self._type is None and self.operand is not None and hasattr(self.operand, "type"):
1734
+ self._type = self.operand.type
1735
+ return self._type
1736
+
1737
+ def c_repr_chunks(self, indent=0, asexpr=False):
1738
+ if self.collapsed:
1739
+ yield "...", self
1740
+ return
1741
+
1742
+ OP_MAP = {
1743
+ "Not": self._c_repr_chunks_not,
1744
+ "Neg": self._c_repr_chunks_neg,
1745
+ "BitwiseNeg": self._c_repr_chunks_bitwiseneg,
1746
+ "Reference": self._c_repr_chunks_reference,
1747
+ "Dereference": self._c_repr_chunks_dereference,
1748
+ "Clz": self._c_repr_chunks_clz,
1749
+ }
1750
+
1751
+ handler = OP_MAP.get(self.op, None)
1752
+ if handler is not None:
1753
+ yield from handler()
1754
+ else:
1755
+ yield f"UnaryOp {self.op}", self
1756
+
1757
+ #
1758
+ # Handlers
1759
+ #
1760
+
1761
+ def _c_repr_chunks_not(self):
1762
+ paren = CClosingObject("(")
1763
+ yield "!", self
1764
+ yield "(", paren
1765
+ yield from CExpression._try_c_repr_chunks(self.operand)
1766
+ yield ")", paren
1767
+
1768
+ def _c_repr_chunks_bitwiseneg(self):
1769
+ paren = CClosingObject("(")
1770
+ yield "~", self
1771
+ yield "(", paren
1772
+ yield from CExpression._try_c_repr_chunks(self.operand)
1773
+ yield ")", paren
1774
+
1775
+ def _c_repr_chunks_neg(self):
1776
+ paren = CClosingObject("(")
1777
+ yield "-", self
1778
+ yield "(", paren
1779
+ yield from CExpression._try_c_repr_chunks(self.operand)
1780
+ yield ")", paren
1781
+
1782
+ def _c_repr_chunks_reference(self):
1783
+ yield "&", self
1784
+ yield from CExpression._try_c_repr_chunks(self.operand)
1785
+
1786
+ def _c_repr_chunks_dereference(self):
1787
+ paren = CClosingObject("(")
1788
+ yield "*", self
1789
+ yield "(", paren
1790
+ yield from CExpression._try_c_repr_chunks(self.operand)
1791
+ yield ")", paren
1792
+
1793
+ def _c_repr_chunks_clz(self):
1794
+ paren = CClosingObject("(")
1795
+ yield "Clz", self
1796
+ yield "(", paren
1797
+ yield from CExpression._try_c_repr_chunks(self.operand)
1798
+ yield ")", paren
1799
+
1800
+
1801
+ class CBinaryOp(CExpression):
1802
+ """
1803
+ Binary operations.
1804
+ """
1805
+
1806
+ __slots__ = ("_cstyle_null_cmp", "common_type", "lhs", "op", "rhs")
1807
+
1808
+ def __init__(self, op, lhs, rhs, **kwargs):
1809
+ super().__init__(**kwargs)
1810
+
1811
+ self.op = op
1812
+ self.lhs = lhs
1813
+ self.rhs = rhs
1814
+ self._cstyle_null_cmp = self.codegen.cstyle_null_cmp
1815
+
1816
+ self.common_type = self.compute_common_type(self.op, self.lhs.type, self.rhs.type)
1817
+ if self.op.startswith("Cmp"):
1818
+ self._type = SimTypeChar().with_arch(self.codegen.project.arch)
1819
+ else:
1820
+ self._type = self.common_type
1821
+
1822
+ @staticmethod
1823
+ def compute_common_type(op: str, lhs_ty: SimType, rhs_ty: SimType) -> SimType:
1824
+ # C spec https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2596.pdf 6.3.1.8 Usual arithmetic conversions
1825
+ rhs_ptr = isinstance(rhs_ty, SimTypePointer)
1826
+ lhs_ptr = isinstance(lhs_ty, SimTypePointer)
1827
+ rhs_cls = isinstance(unpack_typeref(rhs_ty), SimCppClass)
1828
+ lhs_cls = isinstance(unpack_typeref(lhs_ty), SimCppClass)
1829
+
1830
+ if lhs_cls:
1831
+ return lhs_ty
1832
+ if rhs_cls:
1833
+ return rhs_ty
1834
+
1835
+ if op in ("Add", "Sub"):
1836
+ if lhs_ptr and rhs_ptr:
1837
+ return SimTypeLength().with_arch(rhs_ty._arch)
1838
+ if lhs_ptr:
1839
+ return lhs_ty
1840
+ if rhs_ptr:
1841
+ return rhs_ty
1842
+
1843
+ if lhs_ptr or rhs_ptr:
1844
+ # uh oh!
1845
+ return SimTypeLength().with_arch(rhs_ty._arch)
1846
+
1847
+ if lhs_ty == rhs_ty:
1848
+ return lhs_ty
1849
+
1850
+ lhs_signed = getattr(lhs_ty, "signed", None)
1851
+ rhs_signed = getattr(rhs_ty, "signed", None)
1852
+ # uhhhhhhhhhh idk
1853
+ if lhs_signed is None:
1854
+ return lhs_ty
1855
+ if rhs_signed is None:
1856
+ return rhs_ty
1857
+
1858
+ if lhs_signed == rhs_signed:
1859
+ if lhs_ty.size > rhs_ty.size:
1860
+ return lhs_ty
1861
+ return rhs_ty
1862
+
1863
+ if lhs_signed:
1864
+ signed_ty = lhs_ty
1865
+ unsigned_ty = rhs_ty
1866
+ else:
1867
+ signed_ty = rhs_ty
1868
+ unsigned_ty = lhs_ty
1869
+
1870
+ if unsigned_ty.size >= signed_ty.size:
1871
+ return unsigned_ty
1872
+ if signed_ty.size > unsigned_ty.size:
1873
+ return signed_ty
1874
+ # uh oh!!
1875
+ return signed_ty
1876
+
1877
+ @property
1878
+ def type(self):
1879
+ return self._type
1880
+
1881
+ @property
1882
+ def op_precedence(self):
1883
+ precedence_list = [
1884
+ # lowest precedence
1885
+ ["Concat"],
1886
+ ["LogicalOr"],
1887
+ ["LogicalXor"],
1888
+ ["LogicalAnd"],
1889
+ ["Or"],
1890
+ ["Xor"],
1891
+ ["And"],
1892
+ ["CmpEQ", "CmpNE"],
1893
+ ["CmpLE", "CmpLT", "CmpGT", "CmpGE"],
1894
+ ["Shl", "Shr", "Sar"],
1895
+ ["Add", "Sub"],
1896
+ ["Mul", "Div"],
1897
+ ["SBorrow", "SCarry", "Carry"],
1898
+ # highest precedence
1899
+ ]
1900
+ for i, sublist in enumerate(precedence_list):
1901
+ if self.op in sublist:
1902
+ return i
1903
+ return len(precedence_list)
1904
+
1905
+ def c_repr_chunks(self, indent=0, asexpr=False):
1906
+ if self.collapsed:
1907
+ yield "...", self
1908
+ return
1909
+
1910
+ OP_MAP = {
1911
+ "Add": self._c_repr_chunks_add,
1912
+ "Sub": self._c_repr_chunks_sub,
1913
+ "Mul": self._c_repr_chunks_mul,
1914
+ "Mull": self._c_repr_chunks_mull,
1915
+ "Div": self._c_repr_chunks_div,
1916
+ "Mod": self._c_repr_chunks_mod,
1917
+ "And": self._c_repr_chunks_and,
1918
+ "Xor": self._c_repr_chunks_xor,
1919
+ "Or": self._c_repr_chunks_or,
1920
+ "Shr": self._c_repr_chunks_shr,
1921
+ "Shl": self._c_repr_chunks_shl,
1922
+ "Sar": self._c_repr_chunks_sar,
1923
+ "LogicalAnd": self._c_repr_chunks_logicaland,
1924
+ "LogicalOr": self._c_repr_chunks_logicalor,
1925
+ "LogicalXor": self._c_repr_chunks_logicalxor,
1926
+ "CmpLE": self._c_repr_chunks_cmple,
1927
+ "CmpLEs": self._c_repr_chunks_cmple,
1928
+ "CmpLT": self._c_repr_chunks_cmplt,
1929
+ "CmpLTs": self._c_repr_chunks_cmplt,
1930
+ "CmpGT": self._c_repr_chunks_cmpgt,
1931
+ "CmpGTs": self._c_repr_chunks_cmpgt,
1932
+ "CmpGE": self._c_repr_chunks_cmpge,
1933
+ "CmpGEs": self._c_repr_chunks_cmpge,
1934
+ "CmpEQ": self._c_repr_chunks_cmpeq,
1935
+ "CmpNE": self._c_repr_chunks_cmpne,
1936
+ "Concat": self._c_repr_chunks_concat,
1937
+ "Rol": self._c_repr_chunks_rol,
1938
+ "Ror": self._c_repr_chunks_ror,
1939
+ }
1940
+
1941
+ handler = OP_MAP.get(self.op, None)
1942
+ if handler is not None:
1943
+ yield from handler()
1944
+ else:
1945
+ yield from self._c_repr_chunks_opfirst(self.op)
1946
+
1947
+ def _has_const_null_rhs(self) -> bool:
1948
+ return isinstance(self.rhs, CConstant) and self.rhs.value == 0
1949
+
1950
+ #
1951
+ # Handlers
1952
+ #
1953
+
1954
+ def _c_repr_chunks(self, op):
1955
+ skip_op_and_rhs = False
1956
+ if self._cstyle_null_cmp and self._has_const_null_rhs():
1957
+ if self.op == "CmpEQ":
1958
+ skip_op_and_rhs = True
1959
+ yield "!", None
1960
+ elif self.op == "CmpNE":
1961
+ skip_op_and_rhs = True
1962
+ # lhs
1963
+ if isinstance(self.lhs, CBinaryOp) and self.op_precedence > self.lhs.op_precedence:
1964
+ paren = CClosingObject("(")
1965
+ yield "(", paren
1966
+ yield from self._try_c_repr_chunks(self.lhs)
1967
+ yield ")", paren
1968
+ else:
1969
+ yield from self._try_c_repr_chunks(self.lhs)
1970
+
1971
+ if not skip_op_and_rhs:
1972
+ # operator
1973
+ yield op, self
1974
+ # rhs
1975
+ if isinstance(self.rhs, CBinaryOp) and self.op_precedence > self.rhs.op_precedence - (
1976
+ 1 if self.op in ["Sub", "Div"] else 0
1977
+ ):
1978
+ paren = CClosingObject("(")
1979
+ yield "(", paren
1980
+ yield from self._try_c_repr_chunks(self.rhs)
1981
+ yield ")", paren
1982
+ else:
1983
+ yield from self._try_c_repr_chunks(self.rhs)
1984
+
1985
+ def _c_repr_chunks_opfirst(self, op):
1986
+ yield op, self
1987
+ paren = CClosingObject("(")
1988
+ yield "(", paren
1989
+ yield from self._try_c_repr_chunks(self.lhs)
1990
+ yield ", ", None
1991
+ yield from self._try_c_repr_chunks(self.rhs)
1992
+ yield ")", paren
1993
+
1994
+ def _c_repr_chunks_add(self):
1995
+ yield from self._c_repr_chunks(" + ")
1996
+
1997
+ def _c_repr_chunks_sub(self):
1998
+ yield from self._c_repr_chunks(" - ")
1999
+
2000
+ def _c_repr_chunks_mul(self):
2001
+ yield from self._c_repr_chunks(" * ")
2002
+
2003
+ def _c_repr_chunks_mull(self):
2004
+ yield from self._c_repr_chunks(" * ")
2005
+
2006
+ def _c_repr_chunks_div(self):
2007
+ yield from self._c_repr_chunks(" / ")
2008
+
2009
+ def _c_repr_chunks_divmod(self):
2010
+ yield from self._c_repr_chunks(" /m ")
2011
+
2012
+ def _c_repr_chunks_mod(self):
2013
+ yield from self._c_repr_chunks(" % ")
2014
+
2015
+ def _c_repr_chunks_and(self):
2016
+ yield from self._c_repr_chunks(" & ")
2017
+
2018
+ def _c_repr_chunks_xor(self):
2019
+ yield from self._c_repr_chunks(" ^ ")
2020
+
2021
+ def _c_repr_chunks_or(self):
2022
+ yield from self._c_repr_chunks(" | ")
2023
+
2024
+ def _c_repr_chunks_shr(self):
2025
+ yield from self._c_repr_chunks(" >> ")
2026
+
2027
+ def _c_repr_chunks_shl(self):
2028
+ yield from self._c_repr_chunks(" << ")
2029
+
2030
+ def _c_repr_chunks_sar(self):
2031
+ yield from self._c_repr_chunks(" >> ")
2032
+
2033
+ def _c_repr_chunks_logicaland(self):
2034
+ yield from self._c_repr_chunks(" && ")
2035
+
2036
+ def _c_repr_chunks_logicalor(self):
2037
+ yield from self._c_repr_chunks(" || ")
2038
+
2039
+ def _c_repr_chunks_logicalxor(self):
2040
+ yield from self._c_repr_chunks(" ^ ")
2041
+
2042
+ def _c_repr_chunks_cmple(self):
2043
+ yield from self._c_repr_chunks(" <= ")
2044
+
2045
+ def _c_repr_chunks_cmplt(self):
2046
+ yield from self._c_repr_chunks(" < ")
2047
+
2048
+ def _c_repr_chunks_cmpgt(self):
2049
+ yield from self._c_repr_chunks(" > ")
2050
+
2051
+ def _c_repr_chunks_cmpge(self):
2052
+ yield from self._c_repr_chunks(" >= ")
2053
+
2054
+ def _c_repr_chunks_cmpeq(self):
2055
+ yield from self._c_repr_chunks(" == ")
2056
+
2057
+ def _c_repr_chunks_cmpne(self):
2058
+ yield from self._c_repr_chunks(" != ")
2059
+
2060
+ def _c_repr_chunks_concat(self):
2061
+ yield from self._c_repr_chunks(" CONCAT ")
2062
+
2063
+ def _c_repr_chunks_rol(self):
2064
+ yield "__ROL__", self
2065
+ paren = CClosingObject("(")
2066
+ yield "(", paren
2067
+ yield from self._try_c_repr_chunks(self.lhs)
2068
+ yield ", ", None
2069
+ yield from self._try_c_repr_chunks(self.rhs)
2070
+ yield ")", paren
2071
+
2072
+ def _c_repr_chunks_ror(self):
2073
+ yield "__ROR__", self
2074
+ paren = CClosingObject("(")
2075
+ yield "(", paren
2076
+ yield from self._try_c_repr_chunks(self.lhs)
2077
+ yield ", ", None
2078
+ yield from self._try_c_repr_chunks(self.rhs)
2079
+ yield ")", paren
2080
+
2081
+
2082
+ class CTypeCast(CExpression):
2083
+ __slots__ = (
2084
+ "dst_type",
2085
+ "expr",
2086
+ "src_type",
2087
+ )
2088
+
2089
+ def __init__(self, src_type: SimType | None, dst_type: SimType, expr: CExpression, **kwargs):
2090
+ super().__init__(**kwargs)
2091
+
2092
+ self.src_type = (src_type or expr.type).with_arch(self.codegen.project.arch)
2093
+ self.dst_type = dst_type.with_arch(self.codegen.project.arch)
2094
+ self.expr = expr
2095
+
2096
+ @property
2097
+ def type(self):
2098
+ if self._type is None:
2099
+ return self.dst_type
2100
+ return self._type
2101
+
2102
+ def c_repr_chunks(self, indent=0, asexpr=False):
2103
+ if self.collapsed:
2104
+ yield "...", self
2105
+ return
2106
+ paren = CClosingObject("(")
2107
+ if self.codegen.show_casts:
2108
+ yield "(", paren
2109
+ yield f"{self.dst_type.c_repr(name=None)}", self.dst_type
2110
+ yield ")", paren
2111
+
2112
+ if isinstance(self.expr, CBinaryOp):
2113
+ wrapping_paren = True
2114
+ yield "(", paren
2115
+ else:
2116
+ wrapping_paren = False
2117
+ yield from CExpression._try_c_repr_chunks(self.expr)
2118
+ if wrapping_paren:
2119
+ yield ")", paren
2120
+
2121
+
2122
+ class CConstant(CExpression):
2123
+ __slots__ = (
2124
+ "reference_values",
2125
+ "value",
2126
+ )
2127
+
2128
+ def __init__(self, value, type_: SimType, reference_values=None, **kwargs):
2129
+ super().__init__(**kwargs)
2130
+
2131
+ self.value = value
2132
+ self._type = type_.with_arch(self.codegen.project.arch)
2133
+ self.reference_values = reference_values
2134
+
2135
+ @property
2136
+ def _ident(self):
2137
+ ident = (self.tags or {}).get("ins_addr", None)
2138
+ if ident is not None:
2139
+ return ("inst", ident)
2140
+ return ("val", self.value)
2141
+
2142
+ @property
2143
+ def fmt(self):
2144
+ return self.codegen.const_formats.get(self._ident, {})
2145
+
2146
+ @property
2147
+ def _fmt_setter(self):
2148
+ result = self.codegen.const_formats.get(self._ident, None)
2149
+ if result is None:
2150
+ result = {}
2151
+ self.codegen.const_formats[self._ident] = result
2152
+
2153
+ return result
2154
+
2155
+ @property
2156
+ def fmt_hex(self):
2157
+ result = self.fmt.get("hex", None)
2158
+ if result is None:
2159
+ result = False
2160
+ if isinstance(self.value, int):
2161
+ result = hex(self.value).endswith("00") or is_alignment_mask(self.value)
2162
+ return result
2163
+
2164
+ @fmt_hex.setter
2165
+ def fmt_hex(self, v):
2166
+ self._fmt_setter["hex"] = v
2167
+
2168
+ @property
2169
+ def fmt_neg(self):
2170
+ result = self.fmt.get("neg", None)
2171
+ if result is None:
2172
+ result = False
2173
+ # guess it
2174
+ if isinstance(self._type, (SimTypeInt, SimTypeChar)) and self._type.signed and isinstance(self.value, int):
2175
+ value_size = self._type.size if self._type is not None else None
2176
+ if (value_size == 32 and 0xF000_0000 <= self.value <= 0xFFFF_FFFF) or (
2177
+ value_size == 64 and 0xF000_0000_0000_0000 <= self.value <= 0xFFFF_FFFF_FFFF_FFFF
2178
+ ):
2179
+ result = True
2180
+
2181
+ return result
2182
+
2183
+ @fmt_neg.setter
2184
+ def fmt_neg(self, v):
2185
+ self._fmt_setter["neg"] = v
2186
+
2187
+ @property
2188
+ def fmt_char(self):
2189
+ return self.fmt.get("char", False)
2190
+
2191
+ @fmt_char.setter
2192
+ def fmt_char(self, v: bool):
2193
+ self._fmt_setter["char"] = v
2194
+
2195
+ @property
2196
+ def fmt_float(self):
2197
+ return self.fmt.get("float", False)
2198
+
2199
+ @fmt_float.setter
2200
+ def fmt_float(self, v: bool):
2201
+ self._fmt_setter["float"] = v
2202
+
2203
+ @property
2204
+ def fmt_double(self):
2205
+ return self.fmt.get("double", False)
2206
+
2207
+ @fmt_double.setter
2208
+ def fmt_double(self, v: bool):
2209
+ self._fmt_setter["double"] = v
2210
+
2211
+ @property
2212
+ def type(self):
2213
+ return self._type
2214
+
2215
+ @staticmethod
2216
+ def str_to_c_str(_str, prefix: str = ""):
2217
+ repr_str = repr(_str)
2218
+ base_str = repr_str[1:-1]
2219
+ # check if there's double quotes in the body
2220
+ if repr_str[0] == "'" and '"' in base_str:
2221
+ base_str = base_str.replace('"', '\\"')
2222
+ return f'{prefix}"{base_str}"'
2223
+
2224
+ def c_repr_chunks(self, indent=0, asexpr=False):
2225
+ if self.collapsed:
2226
+ yield "...", self
2227
+ return
2228
+
2229
+ # default priority: string references -> variables -> other reference values
2230
+ if self.reference_values is not None:
2231
+ for _ty, v in self.reference_values.items(): # pylint:disable=unused-variable
2232
+ if isinstance(v, MemoryData) and v.sort == MemoryDataSort.String:
2233
+ yield CConstant.str_to_c_str(v.content.decode("utf-8")), self
2234
+ return
2235
+ elif isinstance(v, Function):
2236
+ yield get_cpp_function_name(v.demangled_name, specialized=False, qualified=True), self
2237
+ return
2238
+ elif isinstance(v, str):
2239
+ yield CConstant.str_to_c_str(v), self
2240
+ return
2241
+ elif isinstance(v, bytes):
2242
+ yield CConstant.str_to_c_str(v.replace(b"\x00", b"").decode("utf-8")), self
2243
+ return
2244
+
2245
+ if self.reference_values is not None and self._type is not None and self._type in self.reference_values:
2246
+ if isinstance(self._type, SimTypeInt):
2247
+ if isinstance(self.reference_values[self._type], int):
2248
+ yield self.fmt_int(self.reference_values[self._type]), self
2249
+ return
2250
+ yield hex(self.reference_values[self._type]), self
2251
+ elif isinstance(self._type, SimTypePointer) and isinstance(self._type.pts_to, SimTypeChar):
2252
+ refval = self.reference_values[self._type]
2253
+ if isinstance(refval, MemoryData):
2254
+ v = refval.content.decode("utf-8")
2255
+ else:
2256
+ # it's a string
2257
+ v = refval
2258
+ assert isinstance(v, str)
2259
+ yield CConstant.str_to_c_str(v), self
2260
+ elif isinstance(self._type, SimTypePointer) and isinstance(self._type.pts_to, SimTypeWideChar):
2261
+ refval = self.reference_values[self._type]
2262
+ v = refval.content.decode("utf_16_le") if isinstance(refval, MemoryData) else refval # it's a string
2263
+ yield CConstant.str_to_c_str(v, prefix="L"), self
2264
+ else:
2265
+ if isinstance(self.reference_values[self._type], int):
2266
+ yield self.fmt_int(self.reference_values[self._type]), self
2267
+ return
2268
+ yield self.reference_values[self.type], self
2269
+
2270
+ elif isinstance(self.value, int) and self.value == 0 and isinstance(self.type, SimTypePointer):
2271
+ # print NULL instead
2272
+ yield "NULL", self
2273
+
2274
+ elif isinstance(self._type, SimTypePointer) and isinstance(self.value, int):
2275
+ # Print pointers in hex
2276
+ yield hex(self.value), self
2277
+
2278
+ elif isinstance(self.value, bool):
2279
+ # C doesn't have true or false, but whatever...
2280
+ yield "true" if self.value else "false", self
2281
+
2282
+ elif isinstance(self.value, int):
2283
+ str_value = self.fmt_int(self.value)
2284
+ yield str_value, self
2285
+ else:
2286
+ yield str(self.value), self
2287
+
2288
+ def fmt_int(self, value: int) -> str:
2289
+ """
2290
+ Format an integer using the format setup of the current node.
2291
+
2292
+ :param value: The integer value to format.
2293
+ :return: The formatted string.
2294
+ """
2295
+
2296
+ if self.fmt_float and 0 < value <= 0xFFFF_FFFF:
2297
+ return str(struct.unpack("f", struct.pack("I", value))[0])
2298
+
2299
+ if self.fmt_char:
2300
+ if value < 0:
2301
+ value += 2**self._type.size
2302
+ value &= 0xFF
2303
+ return repr(chr(value)) if value < 0x80 else f"'\\x{value:x}'"
2304
+
2305
+ if self.fmt_double and 0 < value <= 0xFFFF_FFFF_FFFF_FFFF:
2306
+ return str(struct.unpack("d", struct.pack("Q", value))[0])
2307
+
2308
+ if self.fmt_neg:
2309
+ if value > 0:
2310
+ value -= 2**self._type.size
2311
+ elif value < 0:
2312
+ value += 2**self._type.size
2313
+
2314
+ if self.fmt_hex:
2315
+ return hex(value)
2316
+
2317
+ return str(value)
2318
+
2319
+
2320
+ class CRegister(CExpression):
2321
+ __slots__ = ("reg",)
2322
+
2323
+ def __init__(self, reg, **kwargs):
2324
+ super().__init__(**kwargs)
2325
+
2326
+ self.reg = reg
2327
+
2328
+ @property
2329
+ def type(self):
2330
+ # FIXME
2331
+ return SimTypeInt().with_arch(self.codegen.project.arch)
2332
+
2333
+ def c_repr_chunks(self, indent=0, asexpr=False):
2334
+ yield str(self.reg), None
2335
+
2336
+
2337
+ class CITE(CExpression):
2338
+ __slots__ = (
2339
+ "cond",
2340
+ "iffalse",
2341
+ "iftrue",
2342
+ )
2343
+
2344
+ def __init__(self, cond, iftrue, iffalse, **kwargs):
2345
+ super().__init__(**kwargs)
2346
+ self.cond = cond
2347
+ self.iftrue = iftrue
2348
+ self.iffalse = iffalse
2349
+
2350
+ @property
2351
+ def type(self):
2352
+ return SimTypeInt().with_arch(self.codegen.project.arch)
2353
+
2354
+ def c_repr_chunks(self, indent=0, asexpr=False):
2355
+ if self.collapsed:
2356
+ yield "...", self
2357
+ return
2358
+ paren = CClosingObject("(")
2359
+ yield "(", paren
2360
+ yield from self.cond.c_repr_chunks()
2361
+ yield " ? ", self
2362
+ yield from self.iftrue.c_repr_chunks()
2363
+ yield " : ", self
2364
+ yield from self.iffalse.c_repr_chunks()
2365
+ yield ")", paren
2366
+
2367
+
2368
+ class CMultiStatementExpression(CExpression):
2369
+ """
2370
+ (stmt0, stmt1, stmt2, expr)
2371
+ """
2372
+
2373
+ __slots__ = (
2374
+ "expr",
2375
+ "stmts",
2376
+ )
2377
+
2378
+ def __init__(self, stmts: CStatements, expr: CExpression, **kwargs):
2379
+ super().__init__(**kwargs)
2380
+ self.stmts = stmts
2381
+ self.expr = expr
2382
+
2383
+ @property
2384
+ def type(self):
2385
+ return self.expr.type
2386
+
2387
+ def c_repr_chunks(self, indent=0, asexpr=False):
2388
+ paren = CClosingObject("(")
2389
+ yield "(", paren
2390
+ yield from self.stmts.c_repr_chunks(indent=0, asexpr=True)
2391
+ yield from self.expr.c_repr_chunks()
2392
+ yield ")", paren
2393
+
2394
+
2395
+ class CVEXCCallExpression(CExpression):
2396
+ """
2397
+ ccall_name(arg0, arg1, ...)
2398
+ """
2399
+
2400
+ __slots__ = (
2401
+ "callee",
2402
+ "operands",
2403
+ )
2404
+
2405
+ def __init__(self, callee: str, operands: list[CExpression], **kwargs):
2406
+ super().__init__(**kwargs)
2407
+ self.callee = callee
2408
+ self.operands = operands
2409
+
2410
+ @property
2411
+ def type(self):
2412
+ return SimTypeInt().with_arch(self.codegen.project.arch)
2413
+
2414
+ def c_repr_chunks(self, indent=0, asexpr=False):
2415
+ paren = CClosingObject("(")
2416
+ yield f"{self.callee}", self
2417
+ yield "(", paren
2418
+ for idx, operand in enumerate(self.operands):
2419
+ if idx != 0:
2420
+ yield ", ", None
2421
+ yield from operand.c_repr_chunks()
2422
+ yield ")", paren
2423
+
2424
+
2425
+ class CDirtyExpression(CExpression):
2426
+ """
2427
+ Ideally all dirty expressions should be handled and converted to proper conversions during conversion from VEX to
2428
+ AIL. Eventually this class should not be used at all.
2429
+ """
2430
+
2431
+ __slots__ = ("dirty",)
2432
+
2433
+ def __init__(self, dirty, **kwargs):
2434
+ super().__init__(**kwargs)
2435
+ self.dirty = dirty
2436
+
2437
+ @property
2438
+ def type(self):
2439
+ return SimTypeInt().with_arch(self.codegen.project.arch)
2440
+
2441
+ def c_repr_chunks(self, indent=0, asexpr=False):
2442
+ if self.collapsed:
2443
+ yield "...", self
2444
+ return
2445
+ yield str(self.dirty), None
2446
+
2447
+
2448
+ class CClosingObject:
2449
+ """
2450
+ A class to represent all objects that can be closed by it's correspodning character.
2451
+ Examples: (), {}, []
2452
+ """
2453
+
2454
+ __slots__ = ("opening_symbol",)
2455
+
2456
+ def __init__(self, opening_symbol):
2457
+ self.opening_symbol = opening_symbol
2458
+
2459
+
2460
+ class CArrayTypeLength:
2461
+ """
2462
+ A class to represent the type information of fixed-size array lengths.
2463
+ Examples: In "char foo[20]", this would be the "[20]".
2464
+ """
2465
+
2466
+ __slots__ = ("text",)
2467
+
2468
+ def __init__(self, text):
2469
+ self.text = text
2470
+
2471
+
2472
+ class CStructFieldNameDef:
2473
+ """A class to represent the name of a defined field in a struct.
2474
+ Needed because it's not a CVariable or a CStructField (because
2475
+ CStructField is the access of a CStructField).
2476
+ Example: In "struct foo { int bar; }, this would be "bar".
2477
+ """
2478
+
2479
+ __slots__ = ("name",)
2480
+
2481
+ def __init__(self, name):
2482
+ self.name = name
2483
+
2484
+
2485
+ class CStructuredCodeGenerator(BaseStructuredCodeGenerator, Analysis):
2486
+ def __init__(
2487
+ self,
2488
+ func,
2489
+ sequence,
2490
+ indent=0,
2491
+ cfg=None,
2492
+ variable_kb=None,
2493
+ func_args: list[SimVariable] | None = None,
2494
+ binop_depth_cutoff: int = 16,
2495
+ show_casts=True,
2496
+ braces_on_own_lines=True,
2497
+ use_compound_assignments=True,
2498
+ show_local_types=True,
2499
+ comment_gotos=False,
2500
+ cstyle_null_cmp=True,
2501
+ flavor=None,
2502
+ stmt_comments=None,
2503
+ expr_comments=None,
2504
+ show_externs=True,
2505
+ externs=None,
2506
+ const_formats=None,
2507
+ show_demangled_name=True,
2508
+ show_disambiguated_name=True,
2509
+ ail_graph=None,
2510
+ simplify_else_scope=True,
2511
+ cstyle_ifs=True,
2512
+ omit_func_header=False,
2513
+ display_block_addrs=False,
2514
+ display_vvar_ids=False,
2515
+ min_data_addr: int = 0x400_000,
2516
+ ):
2517
+ super().__init__(flavor=flavor)
2518
+
2519
+ self._handlers = {
2520
+ CodeNode: self._handle_Code,
2521
+ SequenceNode: self._handle_Sequence,
2522
+ LoopNode: self._handle_Loop,
2523
+ ConditionNode: self._handle_Condition,
2524
+ CascadingConditionNode: self._handle_CascadingCondition,
2525
+ ConditionalBreakNode: self._handle_ConditionalBreak,
2526
+ MultiNode: self._handle_MultiNode,
2527
+ Block: self._handle_AILBlock,
2528
+ BreakNode: self._handle_Break,
2529
+ SwitchCaseNode: self._handle_SwitchCase,
2530
+ IncompleteSwitchCaseNode: self._handle_IncompleteSwitchCase,
2531
+ ContinueNode: self._handle_Continue,
2532
+ # AIL statements
2533
+ Stmt.Store: self._handle_Stmt_Store,
2534
+ Stmt.Assignment: self._handle_Stmt_Assignment,
2535
+ Stmt.WeakAssignment: self._handle_Stmt_WeakAssignment,
2536
+ Stmt.Call: self._handle_Stmt_Call,
2537
+ Stmt.Jump: self._handle_Stmt_Jump,
2538
+ Stmt.ConditionalJump: self._handle_Stmt_ConditionalJump,
2539
+ Stmt.Return: self._handle_Stmt_Return,
2540
+ Stmt.Label: self._handle_Stmt_Label,
2541
+ Stmt.DirtyStatement: self._handle_Stmt_Dirty,
2542
+ # AIL expressions
2543
+ Expr.Register: self._handle_Expr_Register,
2544
+ Expr.Load: self._handle_Expr_Load,
2545
+ Expr.Tmp: self._handle_Expr_Tmp,
2546
+ Expr.Const: self._handle_Expr_Const,
2547
+ Expr.UnaryOp: self._handle_Expr_UnaryOp,
2548
+ Expr.BinaryOp: self._handle_Expr_BinaryOp,
2549
+ Expr.Convert: self._handle_Expr_Convert,
2550
+ Expr.StackBaseOffset: self._handle_Expr_StackBaseOffset,
2551
+ Expr.VEXCCallExpression: self._handle_Expr_VEXCCallExpression,
2552
+ Expr.DirtyExpression: self._handle_Expr_Dirty,
2553
+ Expr.ITE: self._handle_Expr_ITE,
2554
+ Expr.Reinterpret: self._handle_Reinterpret,
2555
+ Expr.MultiStatementExpression: self._handle_MultiStatementExpression,
2556
+ Expr.VirtualVariable: self._handle_VirtualVariable,
2557
+ }
2558
+
2559
+ self._func = func
2560
+ self._func_args = func_args
2561
+ self._cfg = cfg
2562
+ self._sequence = sequence
2563
+ self._variable_kb = variable_kb if variable_kb is not None else self.kb
2564
+ self.binop_depth_cutoff = binop_depth_cutoff
2565
+
2566
+ self._variables_in_use: dict | None = None
2567
+ self._inlined_strings: set[SimMemoryVariable] = set()
2568
+ self._function_pointers: set[SimMemoryVariable] = set()
2569
+ self.ailexpr2cnode: dict[tuple[Expr.Expression, bool], CExpression] | None = None
2570
+ self.cnode2ailexpr: dict[CExpression, Expr.Expression] | None = None
2571
+ self._indent = indent
2572
+ self.show_casts = show_casts
2573
+ self.comment_gotos = comment_gotos
2574
+ self.braces_on_own_lines = braces_on_own_lines
2575
+ self.use_compound_assignments = use_compound_assignments
2576
+ self.show_local_types = show_local_types
2577
+ self.cstyle_null_cmp = cstyle_null_cmp
2578
+ self.expr_comments: dict[int, str] = expr_comments if expr_comments is not None else {}
2579
+ self.stmt_comments: dict[int, str] = stmt_comments if stmt_comments is not None else {}
2580
+ self.const_formats: dict[Any, dict[str, Any]] = const_formats if const_formats is not None else {}
2581
+ self.externs = externs or set()
2582
+ self.show_externs = show_externs
2583
+ self.show_demangled_name = show_demangled_name
2584
+ self.show_disambiguated_name = show_disambiguated_name
2585
+ self.ail_graph = ail_graph
2586
+ self.simplify_else_scope = simplify_else_scope
2587
+ self.cstyle_ifs = cstyle_ifs
2588
+ self.omit_func_header = omit_func_header
2589
+ self.display_block_addrs = display_block_addrs
2590
+ self.display_vvar_ids = display_vvar_ids
2591
+ self.min_data_addr = min_data_addr
2592
+ self.text = None
2593
+ self.map_pos_to_node = None
2594
+ self.map_pos_to_addr = None
2595
+ self.map_addr_to_pos = None
2596
+ self.map_ast_to_pos: dict[SimVariable, set[PositionMappingElement]] | None = None
2597
+ self.map_addr_to_label: dict[tuple[int, int | None], CLabel] = {}
2598
+ self.cfunc: CFunction | None = None
2599
+ self.cexterns: set[CVariable] | None = None
2600
+
2601
+ self._analyze()
2602
+
2603
+ def reapply_options(self, options):
2604
+ for option, value in options:
2605
+ if option.param == "braces_on_own_lines":
2606
+ self.braces_on_own_lines = value
2607
+ elif option.param == "show_casts":
2608
+ self.show_casts = value
2609
+ elif option.param == "comment_gotos":
2610
+ self.comment_gotos = value
2611
+ elif option.param == "use_compound_assignments":
2612
+ self.use_compound_assignments = value
2613
+ elif option.param == "show_local_types":
2614
+ self.show_local_types = value
2615
+ elif option.param == "show_externs":
2616
+ self.show_externs = value
2617
+ elif option.param == "show_demangled_name":
2618
+ self.show_demangled_name = value
2619
+ elif option.param == "cstyle_null_cmp":
2620
+ self.cstyle_null_cmp = value
2621
+ elif option.param == "simplify_else_scope":
2622
+ self.simplify_else_scope = value
2623
+ elif option.param == "cstyle_ifs":
2624
+ self.cstyle_ifs = value
2625
+
2626
+ def _analyze(self):
2627
+ self._variables_in_use = {}
2628
+
2629
+ # memo
2630
+ self.ailexpr2cnode = {}
2631
+
2632
+ arg_list = [self._variable(arg, None) for arg in self._func_args] if self._func_args else []
2633
+
2634
+ obj = self._handle(self._sequence)
2635
+
2636
+ self.cnode2ailexpr = {v: k[0] for k, v in self.ailexpr2cnode.items()}
2637
+
2638
+ self.cfunc = CFunction(
2639
+ self._func.addr,
2640
+ self._func.name,
2641
+ self._func.prototype,
2642
+ arg_list,
2643
+ obj,
2644
+ self._variables_in_use,
2645
+ self._variable_kb.variables[self._func.addr],
2646
+ demangled_name=self._func.demangled_name,
2647
+ show_demangled_name=self.show_demangled_name,
2648
+ codegen=self,
2649
+ omit_header=self.omit_func_header,
2650
+ )
2651
+ self.cfunc = FieldReferenceCleanup().handle(self.cfunc)
2652
+ self.cfunc = PointerArithmeticFixer().handle(self.cfunc)
2653
+ self.cfunc = MakeTypecastsImplicit().handle(self.cfunc)
2654
+
2655
+ # TODO store extern fallback size somewhere lol
2656
+ self.cexterns = {
2657
+ self._variable(v, 1, mark_used=False)
2658
+ for v in self.externs
2659
+ if v not in self._inlined_strings and v not in self._function_pointers
2660
+ }
2661
+
2662
+ self.regenerate_text()
2663
+
2664
+ def cleanup(self):
2665
+ """
2666
+ Remove existing rendering results.
2667
+ """
2668
+ self.map_pos_to_node = None
2669
+ self.map_pos_to_addr = None
2670
+ self.map_addr_to_pos = None
2671
+ self.map_ast_to_pos = None
2672
+ self.text = None
2673
+
2674
+ def regenerate_text(self) -> None:
2675
+ """
2676
+ Re-render text and re-generate all sorts of mapping information.
2677
+ """
2678
+ self.cleanup()
2679
+ (
2680
+ self.text,
2681
+ self.map_pos_to_node,
2682
+ self.map_pos_to_addr,
2683
+ self.map_addr_to_pos,
2684
+ self.map_ast_to_pos,
2685
+ ) = self.render_text(self.cfunc)
2686
+
2687
+ RENDER_TYPE = tuple[str, PositionMapping, PositionMapping, InstructionMapping, dict[Any, set[Any]]]
2688
+
2689
+ def render_text(self, cfunc: CFunction) -> RENDER_TYPE:
2690
+ pos_to_node = PositionMapping()
2691
+ pos_to_addr = PositionMapping()
2692
+ addr_to_pos = InstructionMapping()
2693
+ ast_to_pos = defaultdict(set)
2694
+
2695
+ text = cfunc.c_repr(
2696
+ indent=self._indent, pos_to_node=pos_to_node, pos_to_addr=pos_to_addr, addr_to_pos=addr_to_pos
2697
+ )
2698
+
2699
+ for elem, node in pos_to_node.items():
2700
+ if isinstance(node.obj, CConstant):
2701
+ ast_to_pos[node.obj.value].add(elem)
2702
+ elif isinstance(node.obj, CVariable):
2703
+ if node.obj.unified_variable is not None:
2704
+ ast_to_pos[node.obj.unified_variable].add(elem)
2705
+ else:
2706
+ ast_to_pos[node.obj.variable].add(elem)
2707
+ elif isinstance(node.obj, SimType):
2708
+ ast_to_pos[node.obj].add(elem)
2709
+ elif isinstance(node.obj, CFunctionCall):
2710
+ if node.obj.callee_func is not None:
2711
+ ast_to_pos[node.obj.callee_func].add(elem)
2712
+ else:
2713
+ ast_to_pos[node.obj.callee_target].add(elem)
2714
+ elif isinstance(node.obj, CStructField):
2715
+ key = (node.obj.struct_type, node.obj.offset)
2716
+ ast_to_pos[key].add(elem)
2717
+ else:
2718
+ ast_to_pos[node.obj].add(elem)
2719
+
2720
+ return text, pos_to_node, pos_to_addr, addr_to_pos, ast_to_pos
2721
+
2722
+ def _get_variable_type(self, var, is_global=False):
2723
+ if is_global:
2724
+ return self._variable_kb.variables["global"].get_variable_type(var)
2725
+ return self._variable_kb.variables[self._func.addr].get_variable_type(var)
2726
+
2727
+ def _get_derefed_type(self, ty: SimType) -> SimType | None:
2728
+ if ty is None:
2729
+ return None
2730
+ ty = unpack_typeref(ty)
2731
+ if isinstance(ty, SimTypePointer):
2732
+ return unpack_typeref(ty.pts_to).with_arch(self.project.arch)
2733
+ if isinstance(ty, SimTypeArray):
2734
+ return unpack_typeref(ty.elem_type).with_arch(self.project.arch)
2735
+ return ty
2736
+
2737
+ def reload_variable_types(self) -> None:
2738
+ for var in self._variables_in_use.values():
2739
+ if isinstance(var, CVariable):
2740
+ var.variable_type = self._get_variable_type(
2741
+ var.variable,
2742
+ is_global=isinstance(var.variable, SimMemoryVariable)
2743
+ and not isinstance(var.variable, SimStackVariable),
2744
+ )
2745
+
2746
+ for var in self.cexterns:
2747
+ if isinstance(var, CVariable):
2748
+ var.variable_type = self._get_variable_type(var.variable, is_global=True)
2749
+
2750
+ for cvar in self.cfunc.arg_list:
2751
+ vartype = self._get_variable_type(
2752
+ cvar.variable,
2753
+ is_global=isinstance(cvar.variable, SimMemoryVariable)
2754
+ and not isinstance(cvar.variable, SimStackVariable),
2755
+ )
2756
+ if vartype is not None:
2757
+ cvar.variable_type = vartype.with_arch(self.project.arch)
2758
+
2759
+ #
2760
+ # Util methods
2761
+ #
2762
+
2763
+ def default_simtype_from_bits(self, n: int, signed: bool = True) -> SimType:
2764
+ _mapping = {
2765
+ 64: SimTypeLongLong,
2766
+ 32: SimTypeInt,
2767
+ 16: SimTypeShort,
2768
+ 8: SimTypeChar,
2769
+ }
2770
+ if n in _mapping:
2771
+ return _mapping.get(n)(signed=signed).with_arch(self.project.arch)
2772
+ return SimTypeNum(n, signed=signed).with_arch(self.project.arch)
2773
+
2774
+ def _variable(
2775
+ self, variable: SimVariable, fallback_type_size: int | None, vvar_id: int | None = None, mark_used: bool = True
2776
+ ) -> CVariable:
2777
+ # TODO: we need to fucking make sure that variable recovery and type inference actually generates a size
2778
+ # TODO: for each variable it links into the fucking ail. then we can remove fallback_type_size.
2779
+ unified = self._variable_kb.variables[self._func.addr].unified_variable(variable)
2780
+ variable_type = self._get_variable_type(
2781
+ variable, is_global=isinstance(variable, SimMemoryVariable) and not isinstance(variable, SimStackVariable)
2782
+ )
2783
+ if variable_type is None:
2784
+ variable_type = self.default_simtype_from_bits(
2785
+ (fallback_type_size or self.project.arch.bytes) * self.project.arch.byte_width
2786
+ )
2787
+ cvar = CVariable(variable, unified_variable=unified, variable_type=variable_type, codegen=self, vvar_id=vvar_id)
2788
+ if mark_used:
2789
+ self._variables_in_use[variable] = cvar
2790
+ return cvar
2791
+
2792
+ def _get_variable_reference(self, cvar: CVariable) -> CExpression:
2793
+ """
2794
+ Return a reference to a CVariable instance with special handling of arrays and array pointers.
2795
+
2796
+ :param cvar: The CVariable object.
2797
+ :return: A reference to a CVariable object.
2798
+ """
2799
+
2800
+ if isinstance(cvar.type, (SimTypeArray, SimTypeFixedSizeArray)):
2801
+ return cvar
2802
+ if isinstance(cvar.type, SimTypePointer) and isinstance(
2803
+ cvar.type.pts_to, (SimTypeArray, SimTypeFixedSizeArray)
2804
+ ):
2805
+ return cvar
2806
+ return CUnaryOp("Reference", cvar, codegen=self)
2807
+
2808
+ def _access_reference(self, expr: CExpression, data_type: SimType) -> CExpression:
2809
+ result = self._access(expr, data_type, True)
2810
+ if isinstance(result, CUnaryOp) and result.op == "Dereference":
2811
+ result = result.operand
2812
+ else:
2813
+ result = CUnaryOp("Reference", result, codegen=self)
2814
+ return result
2815
+
2816
+ def _access_constant_offset_reference(
2817
+ self, expr: CExpression, offset: int, data_type: SimType | None
2818
+ ) -> CExpression:
2819
+ result = self._access_constant_offset(expr, offset, data_type or SimTypeBottom(), True)
2820
+ if isinstance(result, CTypeCast) and data_type is None:
2821
+ result = result.expr
2822
+ if isinstance(result, CUnaryOp) and result.op == "Dereference":
2823
+ result = result.operand
2824
+ if isinstance(result, CTypeCast) and data_type is None:
2825
+ result = result.expr
2826
+ else:
2827
+ result = CUnaryOp("Reference", result, codegen=self)
2828
+ return result
2829
+
2830
+ def _access_constant_offset(
2831
+ self,
2832
+ expr: CExpression,
2833
+ offset: int,
2834
+ data_type: SimType,
2835
+ lvalue: bool,
2836
+ renegotiate_type: Callable[[SimType, SimType], SimType] = lambda old, proposed: old,
2837
+ ) -> CExpression:
2838
+ def _force_type_cast(src_type_: SimType, dst_type_: SimType, expr_: CExpression) -> CUnaryOp:
2839
+ src_type_ptr = SimTypePointer(src_type_).with_arch(self.project.arch)
2840
+ dst_type_ptr = SimTypePointer(dst_type_).with_arch(self.project.arch)
2841
+ return CUnaryOp(
2842
+ "Dereference",
2843
+ CTypeCast(
2844
+ src_type_ptr,
2845
+ dst_type_ptr,
2846
+ CUnaryOp("Reference", expr_, codegen=self),
2847
+ codegen=self,
2848
+ ),
2849
+ codegen=self,
2850
+ )
2851
+
2852
+ # expr must express a POINTER to the base
2853
+ # returns a value which has a simtype of data_type as if it were dereferenced out of expr
2854
+ data_type = unpack_typeref(data_type)
2855
+ base_type = unpack_typeref(unpack_pointer_and_array(expr.type))
2856
+ if base_type is None:
2857
+ # well, not much we can do
2858
+ if data_type is None:
2859
+ raise TypeError("CStructuredCodeGenerator programming error: no type whatsoever for dereference")
2860
+ if offset:
2861
+ expr = CBinaryOp("Add", expr, CConstant(offset, SimTypeInt(), codegen=self), codegen=self)
2862
+ return CUnaryOp(
2863
+ "Dereference",
2864
+ CTypeCast(expr.type, SimTypePointer(data_type).with_arch(self.project.arch), expr, codegen=self),
2865
+ codegen=self,
2866
+ )
2867
+
2868
+ base_expr = expr.operand if isinstance(expr, CUnaryOp) and expr.op == "Reference" else None
2869
+
2870
+ if offset == 0:
2871
+ data_type = renegotiate_type(data_type, base_type)
2872
+ if type_equals(base_type, data_type) or (
2873
+ base_type.size is not None and data_type.size is not None and base_type.size < data_type.size
2874
+ ):
2875
+ # case 1: we're done because we found it
2876
+ # case 2: we're done because we can never find it and we might as well stop early
2877
+ if base_expr:
2878
+ if not type_equals(base_type, data_type):
2879
+ return _force_type_cast(base_type, data_type, base_expr)
2880
+ return base_expr
2881
+
2882
+ if not type_equals(base_type, data_type):
2883
+ return _force_type_cast(base_type, data_type, expr)
2884
+ return CUnaryOp("Dereference", expr, codegen=self)
2885
+
2886
+ stride = 1 if base_type.size is None else base_type.size // self.project.arch.byte_width or 1
2887
+ index, remainder = divmod(offset, stride)
2888
+ if index != 0:
2889
+ index = CConstant(index, SimTypeInt(), codegen=self)
2890
+ kernel = expr
2891
+ # create a CIndexedVariable indicating the index access
2892
+ if base_expr and isinstance(base_expr, CIndexedVariable):
2893
+ old_index = base_expr.index
2894
+ kernel = base_expr.variable
2895
+ if not isinstance(old_index, CConstant) or old_index.value != 0:
2896
+ index = CBinaryOp("Add", old_index, index, codegen=self)
2897
+ result = CUnaryOp(
2898
+ "Reference", CIndexedVariable(kernel, index, variable_type=base_type, codegen=self), codegen=self
2899
+ )
2900
+ return self._access_constant_offset(result, remainder, data_type, lvalue, renegotiate_type)
2901
+
2902
+ if isinstance(base_type, SimStruct):
2903
+ # find the field that we're accessing
2904
+ field_name, field_offset = max(
2905
+ ((x, y) for x, y in base_type.offsets.items() if y <= remainder), key=lambda x: x[1]
2906
+ )
2907
+ field = CStructField(base_type, field_offset, field_name, codegen=self)
2908
+ if base_expr:
2909
+ result = CUnaryOp("Reference", CVariableField(base_expr, field, False, codegen=self), codegen=self)
2910
+ else:
2911
+ result = CUnaryOp("Reference", CVariableField(expr, field, True, codegen=self), codegen=self)
2912
+ return self._access_constant_offset(result, remainder - field_offset, data_type, lvalue, renegotiate_type)
2913
+
2914
+ if isinstance(base_type, (SimTypeFixedSizeArray, SimTypeArray)):
2915
+ result = base_expr or expr # death to C
2916
+ if isinstance(result, CIndexedVariable):
2917
+ # unpack indexed variable
2918
+ var = result.variable
2919
+ result = CUnaryOp(
2920
+ "Reference",
2921
+ CIndexedVariable(var, result.index, variable_type=base_type.elem_type, codegen=self),
2922
+ codegen=self,
2923
+ )
2924
+ else:
2925
+ result = CUnaryOp(
2926
+ "Reference",
2927
+ CIndexedVariable(
2928
+ result,
2929
+ CConstant(0, SimTypeInt(), codegen=self),
2930
+ variable_type=base_type.elem_type,
2931
+ codegen=self,
2932
+ ),
2933
+ codegen=self,
2934
+ )
2935
+ return self._access_constant_offset(result, remainder, data_type, lvalue, renegotiate_type)
2936
+
2937
+ # TODO is it a big-endian downcast?
2938
+ # e.g. int x; *((char*)x + 3) is actually just (char)x
2939
+
2940
+ if remainder != 0:
2941
+ # pointer cast time!
2942
+ # TODO: BYTE2() and other ida-isms if we're okay with an rvalue
2943
+ if stride != 1:
2944
+ expr = CTypeCast(
2945
+ expr.type, SimTypePointer(SimTypeChar()).with_arch(self.project.arch), expr, codegen=self
2946
+ )
2947
+ expr_with_offset = CBinaryOp("Add", expr, CConstant(remainder, SimTypeInt(), codegen=self), codegen=self)
2948
+ return CUnaryOp(
2949
+ "Dereference",
2950
+ CTypeCast(
2951
+ expr_with_offset.type,
2952
+ SimTypePointer(data_type).with_arch(self.project.arch),
2953
+ expr_with_offset,
2954
+ codegen=self,
2955
+ ),
2956
+ codegen=self,
2957
+ )
2958
+
2959
+ # the case where we don't need a cast is handled at the start
2960
+ # if we've requested the result be an lvalue we have to do a pointer cast
2961
+ # if the value is not a trivial reference we have to do a pointer cast (?)
2962
+ if lvalue or not base_expr:
2963
+ return CUnaryOp(
2964
+ "Dereference", CTypeCast(expr.type, SimTypePointer(data_type), expr, codegen=self), codegen=self
2965
+ )
2966
+ # otherwise, normal cast
2967
+ return CTypeCast(base_type, data_type, base_expr, codegen=self)
2968
+
2969
+ def _access(
2970
+ self,
2971
+ expr: CExpression,
2972
+ data_type: SimType,
2973
+ lvalue: bool,
2974
+ renegotiate_type: Callable[[SimType, SimType], SimType] = lambda old, proposed: old,
2975
+ ) -> CExpression:
2976
+ # same rule as _access_constant_offset wrt pointer expressions
2977
+ data_type = unpack_typeref(data_type)
2978
+ base_type = unpack_pointer_and_array(expr.type)
2979
+ if base_type is None:
2980
+ # use the fallback from above
2981
+ return self._access_constant_offset(expr, 0, data_type, lvalue, renegotiate_type)
2982
+
2983
+ o_constant, o_terms = extract_terms(expr)
2984
+
2985
+ def bail_out():
2986
+ if len(o_terms) == 0:
2987
+ # probably a plain integer, return as is
2988
+ return expr
2989
+ result = None
2990
+ pointer_length_int_type = (
2991
+ SimTypeLongLong(signed=False) if self.project.arch.bits == 64 else SimTypeInt(signed=False)
2992
+ )
2993
+ for c, t in o_terms:
2994
+ op = "Add"
2995
+ if c == -1 and result is not None:
2996
+ op = "Sub"
2997
+ piece = (
2998
+ t
2999
+ if not isinstance(t.type, SimTypePointer)
3000
+ else CTypeCast(t.type, SimTypePointer(SimTypeChar()), t, codegen=self)
3001
+ )
3002
+ elif c == 1:
3003
+ piece = (
3004
+ t
3005
+ if not isinstance(t.type, SimTypePointer)
3006
+ else CTypeCast(t.type, SimTypePointer(SimTypeChar()), t, codegen=self)
3007
+ )
3008
+ else:
3009
+ piece = CBinaryOp(
3010
+ "Mul",
3011
+ CConstant(c, t.type, codegen=self),
3012
+ (
3013
+ t
3014
+ if not isinstance(t.type, SimTypePointer)
3015
+ else CTypeCast(t.type, pointer_length_int_type, t, codegen=self)
3016
+ ),
3017
+ codegen=self,
3018
+ )
3019
+ result = piece if result is None else CBinaryOp(op, result, piece, codegen=self)
3020
+ if o_constant != 0:
3021
+ result = CBinaryOp("Add", CConstant(o_constant, SimTypeInt(), codegen=self), result, codegen=self)
3022
+
3023
+ return CUnaryOp(
3024
+ "Dereference", CTypeCast(result.type, SimTypePointer(data_type), result, codegen=self), codegen=self
3025
+ )
3026
+
3027
+ # pain.
3028
+ # step 1 is split expr into a sum of terms, each of which is a product of a constant stride and an index
3029
+ # also identify the "kernel", the root of the expression
3030
+ constant, terms = o_constant, list(o_terms)
3031
+ if constant < 0:
3032
+ constant = -constant # TODO: This may not be correct. investigate later
3033
+
3034
+ i = 0
3035
+ kernel = None
3036
+ while i < len(terms):
3037
+ c, t = terms[i]
3038
+ if isinstance(unpack_typeref(t.type), (SimTypePointer, SimTypeArray)):
3039
+ if kernel is not None:
3040
+ l.warning("Summing two different pointers together. Uh oh!")
3041
+ return bail_out()
3042
+ if c == -1:
3043
+ # legit case: you can deduct a pointer from another pointer and get an integer as result in C
3044
+ return bail_out()
3045
+ if c != 1:
3046
+ l.warning("Multiplying a pointer by a constant??")
3047
+ return bail_out()
3048
+ kernel = t
3049
+ terms.pop(i)
3050
+ continue
3051
+ i += 1
3052
+
3053
+ if kernel is None:
3054
+ l.warning("Dereferencing a plain integer. Uh oh!")
3055
+ return bail_out()
3056
+
3057
+ terms.sort(key=lambda x: x[0])
3058
+
3059
+ # suffering.
3060
+ while terms:
3061
+ kernel_type = unpack_typeref(unpack_pointer_and_array(kernel.type))
3062
+ assert kernel_type
3063
+
3064
+ if kernel_type.size is None:
3065
+ return bail_out()
3066
+ kernel_stride = kernel_type.size // self.project.arch.byte_width
3067
+
3068
+ # if the constant offset is larger than the current fucker, uh, do something about that first
3069
+ if constant >= kernel_stride:
3070
+ index, remainder = divmod(constant, kernel_stride)
3071
+ kernel = CUnaryOp(
3072
+ "Reference",
3073
+ self._access_constant_offset(kernel, index * kernel_stride, kernel_type, True, renegotiate_type),
3074
+ codegen=self,
3075
+ )
3076
+ constant = remainder
3077
+ continue
3078
+
3079
+ # next, uh, check if there's an appropriately sized stride term that we can apply
3080
+ next_stride, next_term = terms[-1]
3081
+ if next_stride % kernel_stride == 0:
3082
+ index_multiplier = next_stride // kernel_stride
3083
+ if index_multiplier != 1:
3084
+ index = CBinaryOp(
3085
+ "Mul", CConstant(index_multiplier, SimTypeInt(), codegen=self), next_term, codegen=self
3086
+ )
3087
+ else:
3088
+ index = next_term
3089
+ if (
3090
+ isinstance(kernel, CUnaryOp)
3091
+ and kernel.op == "Reference"
3092
+ and isinstance(kernel.operand, CIndexedVariable)
3093
+ ):
3094
+ old_index = kernel.operand.index
3095
+ kernel = kernel.operand.variable
3096
+ if not isinstance(old_index, CConstant) or old_index.value != 0:
3097
+ index = CBinaryOp("Add", old_index, index, codegen=self)
3098
+ kernel = CUnaryOp("Reference", CIndexedVariable(kernel, index, codegen=self), codegen=self)
3099
+ terms.pop()
3100
+ continue
3101
+
3102
+ if next_stride > kernel_stride:
3103
+ l.warning("Oddly-sized array access stride. Uh oh!")
3104
+ return bail_out()
3105
+
3106
+ # nothing has the ability to escape the kernel
3107
+ # go in deeper
3108
+ if isinstance(kernel_type, SimStruct):
3109
+ field_name, field_offset = max(
3110
+ ((x, y) for x, y in kernel_type.offsets.items() if y <= constant), key=lambda x: x[1]
3111
+ )
3112
+ field_type = kernel_type.fields[field_name]
3113
+ kernel = CUnaryOp(
3114
+ "Reference",
3115
+ self._access_constant_offset(kernel, field_offset, field_type, True, renegotiate_type),
3116
+ codegen=self,
3117
+ )
3118
+ constant -= field_offset
3119
+ continue
3120
+
3121
+ if isinstance(kernel_type, (SimTypeArray, SimTypeFixedSizeArray)):
3122
+ inner = self._access_constant_offset(kernel, 0, kernel_type.elem_type, True, renegotiate_type)
3123
+ if isinstance(inner, CUnaryOp) and inner.op == "Dereference":
3124
+ # unpack
3125
+ kernel = inner.operand
3126
+ else:
3127
+ kernel = CUnaryOp("Reference", inner, codegen=self)
3128
+ if unpack_typeref(unpack_pointer_and_array(kernel.type)) == kernel_type:
3129
+ # we are not making progress
3130
+ pass
3131
+ else:
3132
+ continue
3133
+
3134
+ l.warning("There's a variable offset with stride shorter than the primitive type. What does this mean?")
3135
+ return bail_out()
3136
+
3137
+ return self._access_constant_offset(kernel, constant, data_type, lvalue, renegotiate_type)
3138
+
3139
+ #
3140
+ # Handlers
3141
+ #
3142
+
3143
+ def _handle(self, node, is_expr: bool = True, lvalue: bool = False, likely_signed=False):
3144
+ if (node, is_expr) in self.ailexpr2cnode:
3145
+ return self.ailexpr2cnode[(node, is_expr)]
3146
+
3147
+ handler: Callable | None = self._handlers.get(node.__class__, None)
3148
+ if handler is not None:
3149
+ # special case for Call
3150
+ converted = (
3151
+ handler(node, is_expr=is_expr)
3152
+ if isinstance(node, Stmt.Call)
3153
+ else handler(node, lvalue=lvalue, likely_signed=likely_signed)
3154
+ )
3155
+ self.ailexpr2cnode[(node, is_expr)] = converted
3156
+ return converted
3157
+ raise UnsupportedNodeTypeError(f"Node type {type(node)} is not supported yet.")
3158
+
3159
+ def _handle_Code(self, node, **kwargs):
3160
+ return self._handle(node.node, is_expr=False)
3161
+
3162
+ def _handle_Sequence(self, seq, **kwargs):
3163
+ lines = []
3164
+
3165
+ for node in seq.nodes:
3166
+ lines.append(self._handle(node, is_expr=False))
3167
+
3168
+ return lines[0] if len(lines) == 1 else CStatements(lines, codegen=self, addr=seq.addr)
3169
+
3170
+ def _handle_Loop(self, loop_node, **kwargs):
3171
+ tags = {"ins_addr": loop_node.addr}
3172
+
3173
+ if loop_node.sort == "while":
3174
+ return CWhileLoop(
3175
+ None if loop_node.condition is None else self._handle(loop_node.condition),
3176
+ None if loop_node.sequence_node is None else self._handle(loop_node.sequence_node, is_expr=False),
3177
+ tags=tags,
3178
+ codegen=self,
3179
+ )
3180
+ if loop_node.sort == "do-while":
3181
+ return CDoWhileLoop(
3182
+ self._handle(loop_node.condition),
3183
+ None if loop_node.sequence_node is None else self._handle(loop_node.sequence_node, is_expr=False),
3184
+ tags=tags,
3185
+ codegen=self,
3186
+ )
3187
+ if loop_node.sort == "for":
3188
+ return CForLoop(
3189
+ None if loop_node.initializer is None else self._handle(loop_node.initializer),
3190
+ None if loop_node.condition is None else self._handle(loop_node.condition),
3191
+ None if loop_node.iterator is None else self._handle(loop_node.iterator),
3192
+ None if loop_node.sequence_node is None else self._handle(loop_node.sequence_node, is_expr=False),
3193
+ tags=tags,
3194
+ codegen=self,
3195
+ )
3196
+
3197
+ raise NotImplementedError
3198
+
3199
+ def _handle_Condition(self, condition_node: ConditionNode, **kwargs):
3200
+ tags = {"ins_addr": condition_node.addr}
3201
+
3202
+ condition_and_nodes = [
3203
+ (
3204
+ self._handle(condition_node.condition),
3205
+ self._handle(condition_node.true_node, is_expr=False) if condition_node.true_node else None,
3206
+ )
3207
+ ]
3208
+
3209
+ else_node = self._handle(condition_node.false_node, is_expr=False) if condition_node.false_node else None
3210
+
3211
+ return CIfElse(
3212
+ condition_and_nodes,
3213
+ else_node=else_node,
3214
+ simplify_else_scope=self.simplify_else_scope
3215
+ and structured_node_is_simple_return(condition_node.true_node, self.ail_graph)
3216
+ and else_node is not None,
3217
+ cstyle_ifs=self.cstyle_ifs,
3218
+ tags=tags,
3219
+ codegen=self,
3220
+ )
3221
+
3222
+ def _handle_CascadingCondition(self, cond_node: CascadingConditionNode, **kwargs):
3223
+ tags = {"ins_addr": cond_node.addr}
3224
+
3225
+ condition_and_nodes = [
3226
+ (self._handle(cond), self._handle(node, is_expr=False)) for cond, node in cond_node.condition_and_nodes
3227
+ ]
3228
+ else_node = self._handle(cond_node.else_node) if cond_node.else_node is not None else None
3229
+
3230
+ return CIfElse(
3231
+ condition_and_nodes,
3232
+ else_node=else_node,
3233
+ tags=tags,
3234
+ cstyle_ifs=self.cstyle_ifs,
3235
+ codegen=self,
3236
+ )
3237
+
3238
+ def _handle_ConditionalBreak(self, node, **kwargs):
3239
+ tags = {"ins_addr": node.addr}
3240
+
3241
+ return CIfBreak(self._handle(node.condition), cstyle_ifs=self.cstyle_ifs, tags=tags, codegen=self)
3242
+
3243
+ def _handle_Break(self, node, **kwargs):
3244
+ tags = {"ins_addr": node.addr}
3245
+
3246
+ return CBreak(tags=tags, codegen=self)
3247
+
3248
+ def _handle_MultiNode(self, node, **kwargs):
3249
+ lines = []
3250
+
3251
+ for n in node.nodes:
3252
+ r = self._handle(n, is_expr=False)
3253
+ lines.append(r)
3254
+
3255
+ return lines[0] if len(lines) == 1 else CStatements(lines, codegen=self, addr=node.addr)
3256
+
3257
+ def _handle_SwitchCase(self, node, **kwargs):
3258
+ """
3259
+
3260
+ :param SwitchCaseNode node:
3261
+ :return:
3262
+ """
3263
+
3264
+ switch_expr = self._handle(node.switch_expr)
3265
+ cases = [(idx, self._handle(case, is_expr=False)) for idx, case in node.cases.items()]
3266
+ default = self._handle(node.default_node, is_expr=False) if node.default_node is not None else None
3267
+ tags = {"ins_addr": node.addr}
3268
+ return CSwitchCase(switch_expr, cases, default=default, tags=tags, codegen=self)
3269
+
3270
+ def _handle_IncompleteSwitchCase(self, node: IncompleteSwitchCaseNode, **kwargs):
3271
+ head = self._handle(node.head, is_expr=False)
3272
+ cases = [(case.addr, self._handle(case, is_expr=False)) for case in node.cases]
3273
+ tags = {"ins_addr": node.addr}
3274
+ return CIncompleteSwitchCase(head, cases, tags=tags, codegen=self)
3275
+
3276
+ def _handle_Continue(self, node, **kwargs):
3277
+ tags = {"ins_addr": node.addr}
3278
+
3279
+ return CContinue(tags=tags, codegen=self)
3280
+
3281
+ def _handle_AILBlock(self, node, **kwargs):
3282
+ """
3283
+
3284
+ :param Block node:
3285
+ :return:
3286
+ """
3287
+
3288
+ # return CStatements([ CAILBlock(node) ])
3289
+ cstmts = []
3290
+ for stmt in node.statements:
3291
+ try:
3292
+ cstmt = self._handle(stmt, is_expr=False)
3293
+ except UnsupportedNodeTypeError:
3294
+ l.warning("Unsupported AIL statement or expression %s.", type(stmt), exc_info=True)
3295
+ cstmt = CUnsupportedStatement(stmt, codegen=self)
3296
+ cstmts.append(cstmt)
3297
+
3298
+ return CStatements(cstmts, codegen=self, addr=node.addr)
3299
+
3300
+ #
3301
+ # AIL statement handlers
3302
+ #
3303
+
3304
+ def _handle_Stmt_Store(self, stmt: Stmt.Store, **kwargs):
3305
+ cdata = self._handle(stmt.data)
3306
+
3307
+ if cdata.type.size != stmt.size * self.project.arch.byte_width:
3308
+ l.error("Store data lifted to a C type with a different size. Decompilation output will be wrong.")
3309
+
3310
+ def negotiate(old_ty, proposed_ty):
3311
+ # transfer casts from the dst to the src if possible
3312
+ # if we see something like *(size_t*)&v4 = x; where v4 is a pointer, change to v4 = (void*)x;
3313
+ nonlocal cdata
3314
+ if old_ty != proposed_ty and qualifies_for_simple_cast(old_ty, proposed_ty):
3315
+ cdata = CTypeCast(cdata.type, proposed_ty, cdata, codegen=self)
3316
+ return proposed_ty
3317
+ return old_ty
3318
+
3319
+ if stmt.variable is not None:
3320
+ if "struct_member_info" in stmt.tags:
3321
+ offset, var, _ = stmt.struct_member_info
3322
+ cvar = self._variable(var, stmt.size)
3323
+ else:
3324
+ cvar = self._variable(stmt.variable, stmt.size)
3325
+ offset = stmt.offset or 0
3326
+ assert type(offset) is int # I refuse to deal with the alternative
3327
+
3328
+ cdst = self._access_constant_offset(self._get_variable_reference(cvar), offset, cdata.type, True, negotiate)
3329
+ else:
3330
+ addr_expr = self._handle(stmt.addr)
3331
+ cdst = self._access(addr_expr, cdata.type, True, negotiate)
3332
+
3333
+ return CAssignment(cdst, cdata, tags=stmt.tags, codegen=self)
3334
+
3335
+ def _handle_Stmt_Assignment(self, stmt, **kwargs):
3336
+ csrc = self._handle(stmt.src, lvalue=False)
3337
+ cdst = None
3338
+
3339
+ src_type = csrc.type
3340
+ dst_type = src_type
3341
+ if hasattr(stmt, "type"):
3342
+ src_type = stmt.type.get("src", None)
3343
+ dst_type = stmt.type.get("dst", None)
3344
+
3345
+ if isinstance(stmt.dst, Expr.VirtualVariable) and stmt.dst.was_stack:
3346
+
3347
+ def negotiate(old_ty, proposed_ty):
3348
+ # transfer casts from the dst to the src if possible
3349
+ # if we see something like *(size_t*)&v4 = x; where v4 is a pointer, change to v4 = (void*)x;
3350
+ nonlocal csrc
3351
+ if not type_equals(old_ty, proposed_ty) and qualifies_for_simple_cast(old_ty, proposed_ty):
3352
+ csrc = CTypeCast(csrc.type, proposed_ty, csrc, codegen=self)
3353
+ return proposed_ty
3354
+ return old_ty
3355
+
3356
+ if stmt.dst.variable is not None:
3357
+ if "struct_member_info" in stmt.dst.tags:
3358
+ offset, var, _ = stmt.dst.struct_member_info
3359
+ cvar = self._variable(var, stmt.dst.size, vvar_id=stmt.dst.varid)
3360
+ else:
3361
+ cvar = self._variable(stmt.dst.variable, stmt.dst.size, vvar_id=stmt.dst.varid)
3362
+ offset = stmt.dst.variable_offset or 0
3363
+ assert type(offset) is int # I refuse to deal with the alternative
3364
+
3365
+ cdst = self._access_constant_offset(
3366
+ self._get_variable_reference(cvar), offset, dst_type, True, negotiate
3367
+ )
3368
+
3369
+ if cdst is None:
3370
+ cdst = self._handle(stmt.dst, lvalue=True)
3371
+
3372
+ return CAssignment(cdst, csrc, tags=stmt.tags, codegen=self)
3373
+
3374
+ def _handle_Stmt_WeakAssignment(self, stmt, **kwargs):
3375
+ csrc = self._handle(stmt.src, lvalue=False)
3376
+ cdst = None
3377
+
3378
+ src_type = csrc.type
3379
+ dst_type = src_type
3380
+ if hasattr(stmt, "type"):
3381
+ src_type = stmt.type.get("src", None)
3382
+ dst_type = stmt.type.get("dst", None)
3383
+
3384
+ if isinstance(stmt.dst, Expr.VirtualVariable) and stmt.dst.was_stack:
3385
+
3386
+ def negotiate(old_ty, proposed_ty):
3387
+ # transfer casts from the dst to the src if possible
3388
+ # if we see something like *(size_t*)&v4 = x; where v4 is a pointer, change to v4 = (void*)x;
3389
+ nonlocal csrc
3390
+ if not type_equals(old_ty, proposed_ty) and qualifies_for_simple_cast(old_ty, proposed_ty):
3391
+ csrc = CTypeCast(csrc.type, proposed_ty, csrc, codegen=self)
3392
+ return proposed_ty
3393
+ return old_ty
3394
+
3395
+ if stmt.dst.variable is not None:
3396
+ if "struct_member_info" in stmt.dst.tags:
3397
+ offset, var, _ = stmt.dst.struct_member_info
3398
+ cvar = self._variable(var, stmt.dst.size, vvar_id=stmt.dst.varid)
3399
+ else:
3400
+ cvar = self._variable(stmt.dst.variable, stmt.dst.size, vvar_id=stmt.dst.varid)
3401
+ offset = stmt.dst.variable_offset or 0
3402
+ assert type(offset) is int # I refuse to deal with the alternative
3403
+
3404
+ cdst = self._access_constant_offset(
3405
+ self._get_variable_reference(cvar), offset, dst_type, True, negotiate
3406
+ )
3407
+
3408
+ if cdst is None:
3409
+ cdst = self._handle(stmt.dst, lvalue=True)
3410
+
3411
+ return CAssignment(cdst, csrc, tags=stmt.tags, codegen=self)
3412
+
3413
+ def _handle_Stmt_Call(self, stmt: Stmt.Call, is_expr: bool = False, **kwargs):
3414
+ try:
3415
+ # Try to handle it as a normal function call
3416
+ target = self._handle(stmt.target) if not isinstance(stmt.target, str) else stmt.target
3417
+ except UnsupportedNodeTypeError:
3418
+ target = stmt.target
3419
+
3420
+ target_func = self.kb.functions.function(addr=target.value) if isinstance(target, CConstant) else None
3421
+
3422
+ args = []
3423
+ if stmt.args is not None:
3424
+ for i, arg in enumerate(stmt.args):
3425
+ type_ = None
3426
+ if (
3427
+ target_func is not None
3428
+ and target_func.prototype is not None
3429
+ and i < len(target_func.prototype.args)
3430
+ ):
3431
+ type_ = target_func.prototype.args[i].with_arch(self.project.arch)
3432
+
3433
+ if isinstance(arg, Expr.Const):
3434
+ if type_ is None or is_machine_word_size_type(type_, self.project.arch):
3435
+ type_ = guess_value_type(arg.value, self.project) or type_
3436
+
3437
+ new_arg = self._handle_Expr_Const(arg, type_=type_)
3438
+ else:
3439
+ new_arg = self._handle(arg)
3440
+ args.append(new_arg)
3441
+
3442
+ ret_expr = None
3443
+ if not is_expr and stmt.ret_expr is not None:
3444
+ ret_expr = self._handle(stmt.ret_expr)
3445
+
3446
+ result = CFunctionCall(
3447
+ target,
3448
+ target_func,
3449
+ args,
3450
+ returning=target_func.returning if target_func is not None else True,
3451
+ ret_expr=ret_expr,
3452
+ tags=stmt.tags,
3453
+ is_expr=is_expr,
3454
+ show_demangled_name=self.show_demangled_name,
3455
+ show_disambiguated_name=self.show_disambiguated_name,
3456
+ codegen=self,
3457
+ )
3458
+
3459
+ if result.is_expr and result.type.size != stmt.size * self.project.arch.byte_width:
3460
+ result = CTypeCast(
3461
+ result.type,
3462
+ self.default_simtype_from_bits(
3463
+ stmt.size * self.project.arch.byte_width, signed=getattr(result.type, "signed", False)
3464
+ ),
3465
+ result,
3466
+ codegen=self,
3467
+ )
3468
+
3469
+ return result
3470
+
3471
+ def _handle_Stmt_Jump(self, stmt: Stmt.Jump, **kwargs):
3472
+ return CGoto(self._handle(stmt.target), stmt.target_idx, tags=stmt.tags, codegen=self)
3473
+
3474
+ def _handle_Stmt_ConditionalJump(self, stmt: Stmt.ConditionalJump, **kwargs):
3475
+ else_node = (
3476
+ None
3477
+ if stmt.false_target is None
3478
+ else CGoto(self._handle(stmt.false_target), None, tags=stmt.tags, codegen=self)
3479
+ )
3480
+ return CIfElse(
3481
+ [(self._handle(stmt.condition), CGoto(self._handle(stmt.true_target), None, tags=stmt.tags, codegen=self))],
3482
+ else_node=else_node,
3483
+ cstyle_ifs=self.cstyle_ifs,
3484
+ tags=stmt.tags,
3485
+ codegen=self,
3486
+ )
3487
+
3488
+ def _handle_Stmt_Return(self, stmt: Stmt.Return, **kwargs):
3489
+ if not stmt.ret_exprs:
3490
+ return CReturn(None, tags=stmt.tags, codegen=self)
3491
+ if len(stmt.ret_exprs) == 1:
3492
+ ret_expr = stmt.ret_exprs[0]
3493
+ return CReturn(self._handle(ret_expr), tags=stmt.tags, codegen=self)
3494
+ # TODO: Multiple return expressions
3495
+ l.warning("StructuredCodeGen does not support multiple return expressions yet. Only picking the first one.")
3496
+ ret_expr = stmt.ret_exprs[0]
3497
+ return CReturn(self._handle(ret_expr), tags=stmt.tags, codegen=self)
3498
+
3499
+ def _handle_Stmt_Label(self, stmt: Stmt.Label, **kwargs):
3500
+ clabel = CLabel(stmt.name, stmt.ins_addr, stmt.block_idx, tags=stmt.tags, codegen=self)
3501
+ self.map_addr_to_label[(stmt.ins_addr, stmt.block_idx)] = clabel
3502
+ return clabel
3503
+
3504
+ def _handle_Stmt_Dirty(self, stmt: Stmt.DirtyStatement, **kwargs):
3505
+ dirty = self._handle(stmt.dirty)
3506
+ return CDirtyStatement(dirty, codegen=self)
3507
+
3508
+ #
3509
+ # AIL expression handlers
3510
+ #
3511
+
3512
+ def _handle_Expr_Register(self, expr: Expr.Register, lvalue: bool = False, **kwargs):
3513
+ def negotiate(old_ty: SimType, proposed_ty: SimType) -> SimType:
3514
+ # we do not allow returning a struct for a primitive type
3515
+ if old_ty.size == proposed_ty.size and (
3516
+ not isinstance(proposed_ty, SimStruct) or isinstance(old_ty, SimStruct)
3517
+ ):
3518
+ return proposed_ty
3519
+ return old_ty
3520
+
3521
+ if expr.variable:
3522
+ cvar = self._variable(expr.variable, None)
3523
+ if expr.variable.size == expr.size:
3524
+ return cvar
3525
+ offset = 0 if expr.variable_offset is None else expr.variable_offset
3526
+ # FIXME: The type should be associated to the register expression itself
3527
+ type_ = self.default_simtype_from_bits(expr.bits, signed=False)
3528
+ return self._access_constant_offset(self._get_variable_reference(cvar), offset, type_, lvalue, negotiate)
3529
+ return CRegister(expr, tags=expr.tags, codegen=self)
3530
+
3531
+ def _handle_Expr_Load(self, expr: Expr.Load, **kwargs):
3532
+ if expr.size == UNDETERMINED_SIZE:
3533
+ # the size is undetermined; we force it to 1
3534
+ expr_size = 1
3535
+ expr_bits = 8
3536
+ else:
3537
+ expr_size = expr.size
3538
+ expr_bits = expr.bits
3539
+
3540
+ if expr.size > 100 and isinstance(expr.addr, Expr.Const):
3541
+ return self._handle_Expr_Const(expr.addr, type_=SimTypePointer(SimTypeChar()).with_arch(self.project.arch))
3542
+
3543
+ ty = self.default_simtype_from_bits(expr_bits)
3544
+
3545
+ def negotiate(old_ty: SimType, proposed_ty: SimType) -> SimType:
3546
+ # we do not allow returning a struct for a primitive type
3547
+ if (
3548
+ old_ty.size == proposed_ty.size
3549
+ and not isinstance(proposed_ty, SimStruct)
3550
+ and not isinstance(old_ty, SimStruct)
3551
+ ):
3552
+ return proposed_ty
3553
+ return old_ty
3554
+
3555
+ if expr.variable is not None:
3556
+ if "struct_member_info" in expr.tags:
3557
+ offset, var, _ = expr.struct_member_info
3558
+ cvar = self._variable(var, var.size)
3559
+ else:
3560
+ cvar = self._variable(expr.variable, expr_size)
3561
+ offset = expr.variable_offset or 0
3562
+
3563
+ assert type(offset) is int # I refuse to deal with the alternative
3564
+ return self._access_constant_offset(CUnaryOp("Reference", cvar, codegen=self), offset, ty, False, negotiate)
3565
+
3566
+ addr_expr = self._handle(expr.addr)
3567
+ return self._access(addr_expr, ty, False, negotiate)
3568
+
3569
+ def _handle_Expr_Tmp(self, expr: Tmp, **kwargs):
3570
+ l.warning("FIXME: Leftover Tmp expressions are found.")
3571
+ return self._variable(SimTemporaryVariable(expr.tmp_idx, expr.bits), expr.size)
3572
+
3573
+ def _handle_Expr_Const(
3574
+ self, expr: Expr.Const, type_=None, reference_values=None, variable=None, likely_signed=True, **kwargs
3575
+ ):
3576
+ inline_string = False
3577
+ function_pointer = False
3578
+
3579
+ if type_ is None and hasattr(expr, "type"):
3580
+ type_ = expr.type
3581
+
3582
+ if type_ is None and reference_values is None and hasattr(expr, "reference_values"):
3583
+ reference_values = expr.reference_values.copy()
3584
+ if reference_values:
3585
+ type_ = next(iter(reference_values))
3586
+
3587
+ if reference_values is None:
3588
+ reference_values = {}
3589
+ type_ = unpack_typeref(type_)
3590
+ if expr.value in self.kb.obfuscations.type1_deobfuscated_strings:
3591
+ reference_values[SimTypePointer(SimTypeChar())] = self.kb.obfuscations.type1_deobfuscated_strings[
3592
+ expr.value
3593
+ ]
3594
+ inline_string = True
3595
+ elif expr.value in self.kb.obfuscations.type2_deobfuscated_strings:
3596
+ reference_values[SimTypePointer(SimTypeChar())] = self.kb.obfuscations.type2_deobfuscated_strings[
3597
+ expr.value
3598
+ ]
3599
+ inline_string = True
3600
+ elif isinstance(type_, SimTypePointer) and isinstance(type_.pts_to, (SimTypeChar, SimTypeBottom)):
3601
+ # char* or void*
3602
+ # Try to get a string
3603
+ if (
3604
+ self._cfg is not None
3605
+ and expr.value in self._cfg.memory_data
3606
+ and self._cfg.memory_data[expr.value].sort == MemoryDataSort.String
3607
+ ):
3608
+ reference_values[type_] = self._cfg.memory_data[expr.value]
3609
+ inline_string = True
3610
+ elif isinstance(type_, SimTypeInt):
3611
+ # int
3612
+ reference_values[type_] = expr.value
3613
+
3614
+ # we don't know the type of this argument, or the type is not what we are expecting
3615
+ # edge cases: (void*)"this is a constant string pointer". in this case, the type_ will be a void*
3616
+ # (BOT*) instead of a char*.
3617
+
3618
+ if not reference_values and isinstance(expr.value, int):
3619
+ if expr.value in self.project.kb.functions:
3620
+ # It's a function pointer
3621
+ # We don't care about the actual prototype here
3622
+ type_ = SimTypePointer(SimTypeBottom(label="void")).with_arch(self.project.arch)
3623
+ reference_values[type_] = self.project.kb.functions[expr.value]
3624
+ function_pointer = True
3625
+
3626
+ # pure guessing: is it possible that it's a string?
3627
+ elif (
3628
+ self._cfg is not None
3629
+ and expr.bits == self.project.arch.bits
3630
+ and expr.value > 0x10000
3631
+ and expr.value in self._cfg.memory_data
3632
+ ):
3633
+ md = self._cfg.memory_data[expr.value]
3634
+ if md.sort == MemoryDataSort.String:
3635
+ type_ = SimTypePointer(SimTypeChar().with_arch(self.project.arch)).with_arch(self.project.arch)
3636
+ reference_values[type_] = self._cfg.memory_data[expr.value]
3637
+ # is it a constant string?
3638
+ if is_in_readonly_segment(self.project, expr.value) or is_in_readonly_section(
3639
+ self.project, expr.value
3640
+ ):
3641
+ inline_string = True
3642
+ elif md.sort == MemoryDataSort.UnicodeString:
3643
+ type_ = SimTypePointer(SimTypeWideChar().with_arch(self.project.arch)).with_arch(
3644
+ self.project.arch
3645
+ )
3646
+ reference_values[type_] = self._cfg.memory_data[expr.value]
3647
+ # is it a constant string?
3648
+ if is_in_readonly_segment(self.project, expr.value) or is_in_readonly_section(
3649
+ self.project, expr.value
3650
+ ):
3651
+ inline_string = True
3652
+
3653
+ if type_ is None:
3654
+ # default to int or unsigned int, determined by likely_signed
3655
+ type_ = self.default_simtype_from_bits(expr.bits, signed=likely_signed)
3656
+
3657
+ if variable is None and hasattr(expr, "reference_variable") and expr.reference_variable is not None:
3658
+ variable = expr.reference_variable
3659
+ if inline_string:
3660
+ self._inlined_strings.add(expr.reference_variable)
3661
+ elif function_pointer:
3662
+ self._function_pointers.add(expr.reference_variable)
3663
+
3664
+ var_access = None
3665
+ if variable is not None and not reference_values:
3666
+ cvar = self._variable(variable, None)
3667
+ offset = getattr(expr, "reference_variable_offset", 0)
3668
+ var_access = self._access_constant_offset_reference(self._get_variable_reference(cvar), offset, None)
3669
+
3670
+ if var_access is not None and expr.value >= self.min_data_addr:
3671
+ return var_access
3672
+
3673
+ reference_values["offset"] = var_access
3674
+ return CConstant(expr.value, type_, reference_values=reference_values, tags=expr.tags, codegen=self)
3675
+
3676
+ def _handle_Expr_UnaryOp(self, expr, **kwargs):
3677
+ return CUnaryOp(
3678
+ expr.op,
3679
+ self._handle(expr.operand),
3680
+ tags=expr.tags,
3681
+ codegen=self,
3682
+ )
3683
+
3684
+ def _handle_Expr_BinaryOp(self, expr: BinaryOp, **kwargs):
3685
+ if expr.variable is not None:
3686
+ cvar = self._variable(expr.variable, None)
3687
+ return self._access_constant_offset_reference(
3688
+ self._get_variable_reference(cvar), expr.variable_offset or 0, None
3689
+ )
3690
+
3691
+ lhs = self._handle(expr.operands[0])
3692
+ rhs = self._handle(expr.operands[1], likely_signed=expr.op not in {"And", "Or"})
3693
+
3694
+ return CBinaryOp(
3695
+ expr.op,
3696
+ lhs,
3697
+ rhs,
3698
+ tags=expr.tags,
3699
+ codegen=self,
3700
+ collapsed=expr.depth > self.binop_depth_cutoff,
3701
+ )
3702
+
3703
+ def _handle_Expr_Convert(self, expr: Expr.Convert, **kwargs):
3704
+ # width of converted type is easy
3705
+ dst_type: SimTypeInt | SimTypeChar
3706
+ if 512 >= expr.to_bits > 256:
3707
+ dst_type = SimTypeInt512()
3708
+ elif 256 >= expr.to_bits > 128:
3709
+ dst_type = SimTypeInt256()
3710
+ elif 128 >= expr.to_bits > 64:
3711
+ dst_type = SimTypeInt128()
3712
+ elif 64 >= expr.to_bits > 32:
3713
+ dst_type = SimTypeLongLong()
3714
+ elif 32 >= expr.to_bits > 16:
3715
+ dst_type = SimTypeInt()
3716
+ elif 16 >= expr.to_bits > 8:
3717
+ dst_type = SimTypeShort()
3718
+ elif 8 >= expr.to_bits > 1:
3719
+ dst_type = SimTypeChar()
3720
+ elif expr.to_bits == 1:
3721
+ dst_type = SimTypeChar() # FIXME: Add a SimTypeBit?
3722
+ else:
3723
+ raise UnsupportedNodeTypeError(f"Unsupported conversion bits {expr.to_bits}.")
3724
+
3725
+ # convert child
3726
+ child = self._handle(expr.operand)
3727
+ orig_child_signed = getattr(child.type, "signed", False)
3728
+
3729
+ # signedness of converted type is hard
3730
+ if expr.to_bits < expr.from_bits:
3731
+ # very sketchy. basically a guess
3732
+ # can we even generate signed downcasts?
3733
+ dst_type.signed = orig_child_signed | expr.is_signed
3734
+ else:
3735
+ dst_type.signed = expr.is_signed
3736
+
3737
+ # do we need an intermediate cast?
3738
+ if orig_child_signed != expr.is_signed and expr.to_bits > expr.from_bits:
3739
+ # this is a problem. sign-extension only happens when the SOURCE of the cast is signed
3740
+ child_ty = self.default_simtype_from_bits(child.type.size, expr.is_signed)
3741
+ child = CTypeCast(None, child_ty, child, codegen=self)
3742
+
3743
+ return CTypeCast(None, dst_type.with_arch(self.project.arch), child, tags=expr.tags, codegen=self)
3744
+
3745
+ def _handle_Expr_VEXCCallExpression(self, expr: Expr.VEXCCallExpression, **kwargs):
3746
+ operands = [self._handle(arg) for arg in expr.operands]
3747
+ return CVEXCCallExpression(expr.callee, operands, tags=expr.tags, codegen=self)
3748
+
3749
+ def _handle_Expr_Dirty(self, expr: Expr.DirtyExpression, **kwargs):
3750
+ return CDirtyExpression(expr, codegen=self)
3751
+
3752
+ def _handle_Expr_ITE(self, expr: Expr.ITE, **kwargs):
3753
+ return CITE(
3754
+ self._handle(expr.cond), self._handle(expr.iftrue), self._handle(expr.iffalse), tags=expr.tags, codegen=self
3755
+ )
3756
+
3757
+ def _handle_Reinterpret(self, expr: Expr.Reinterpret, **kwargs):
3758
+ def _to_type(bits, typestr):
3759
+ if typestr == "I":
3760
+ if bits == 32:
3761
+ r = SimTypeInt()
3762
+ elif bits == 64:
3763
+ r = SimTypeLongLong()
3764
+ else:
3765
+ raise TypeError(f"Unsupported integer type with bits {bits} in Reinterpret")
3766
+ elif typestr == "F":
3767
+ if bits == 32:
3768
+ r = SimTypeFloat()
3769
+ elif bits == 64:
3770
+ r = SimTypeDouble()
3771
+ else:
3772
+ raise TypeError(f"Unsupported floating-point type with bits {bits} in Reinterpret")
3773
+ else:
3774
+ raise TypeError(f"Unexpected reinterpret type {typestr}")
3775
+ return r.with_arch(self.project.arch)
3776
+
3777
+ src_type = _to_type(expr.from_bits, expr.from_type)
3778
+ dst_type = _to_type(expr.to_bits, expr.to_type)
3779
+ return CTypeCast(src_type, dst_type, self._handle(expr.operand), tags=expr.tags, codegen=self)
3780
+
3781
+ def _handle_MultiStatementExpression(self, expr: Expr.MultiStatementExpression, **kwargs):
3782
+ cstmts = CStatements([self._handle(stmt, is_expr=False) for stmt in expr.stmts], codegen=self)
3783
+ cexpr = self._handle(expr.expr)
3784
+ return CMultiStatementExpression(cstmts, cexpr, tags=expr.tags, codegen=self)
3785
+
3786
+ def _handle_VirtualVariable(self, expr: Expr.VirtualVariable, **kwargs):
3787
+ def negotiate(old_ty: SimType, proposed_ty: SimType) -> SimType:
3788
+ # we do not allow returning a struct for a primitive type
3789
+ if old_ty.size == proposed_ty.size and (
3790
+ not isinstance(proposed_ty, SimStruct) or isinstance(old_ty, SimStruct)
3791
+ ):
3792
+ return proposed_ty
3793
+ return old_ty
3794
+
3795
+ if expr.variable is not None:
3796
+ if "struct_member_info" in expr.tags:
3797
+ offset, var, _ = expr.struct_member_info
3798
+ cbasevar = self._variable(var, expr.size, vvar_id=expr.varid)
3799
+ cvar = self._access_constant_offset(
3800
+ self._get_variable_reference(cbasevar), offset, cbasevar.type, False, negotiate
3801
+ )
3802
+ else:
3803
+ cvar = self._variable(expr.variable, None, vvar_id=expr.varid)
3804
+
3805
+ if expr.variable.size != expr.size:
3806
+ l.warning(
3807
+ "VirtualVariable size (%d) and variable size (%d) do not match. Force a type cast.",
3808
+ expr.size,
3809
+ expr.variable.size,
3810
+ )
3811
+ src_type = cvar.type
3812
+ dst_type = {
3813
+ 64: SimTypeLongLong(signed=False),
3814
+ 32: SimTypeInt(signed=False),
3815
+ 16: SimTypeShort(signed=False),
3816
+ 8: SimTypeChar(signed=False),
3817
+ }.get(expr.bits, None)
3818
+ if dst_type is not None:
3819
+ dst_type = dst_type.with_arch(self.project.arch)
3820
+ return CTypeCast(src_type, dst_type, cvar, tags=expr.tags, codegen=self)
3821
+ return cvar
3822
+ return CDirtyExpression(expr, codegen=self)
3823
+
3824
+ def _handle_Expr_StackBaseOffset(self, expr: StackBaseOffset, **kwargs):
3825
+ if expr.variable is not None:
3826
+ var_thing = self._variable(expr.variable, expr.size)
3827
+ var_thing.tags = dict(expr.tags)
3828
+ if "def_at" in var_thing.tags and "ins_addr" not in var_thing.tags:
3829
+ var_thing.tags["ins_addr"] = var_thing.tags["def_at"].ins_addr
3830
+ return self._get_variable_reference(var_thing)
3831
+
3832
+ # FIXME
3833
+ stack_base = CFakeVariable("stack_base", SimTypePointer(SimTypeBottom()), codegen=self)
3834
+ return CBinaryOp("Add", stack_base, CConstant(expr.offset, SimTypeInt(), codegen=self), codegen=self)
3835
+
3836
+
3837
+ class CStructuredCodeWalker:
3838
+ def handle(self, obj):
3839
+ handler = getattr(self, "handle_" + type(obj).__name__, self.handle_default)
3840
+ return handler(obj)
3841
+
3842
+ def handle_default(self, obj):
3843
+ return obj
3844
+
3845
+ def handle_CFunction(self, obj):
3846
+ obj.statements = self.handle(obj.statements)
3847
+ return obj
3848
+
3849
+ def handle_CStatements(self, obj):
3850
+ obj.statements = [self.handle(stmt) for stmt in obj.statements]
3851
+ return obj
3852
+
3853
+ def handle_CWhileLoop(self, obj):
3854
+ obj.condition = self.handle(obj.condition)
3855
+ obj.body = self.handle(obj.body)
3856
+ return obj
3857
+
3858
+ def handle_CDoWhileLoop(self, obj):
3859
+ obj.condition = self.handle(obj.condition)
3860
+ obj.body = self.handle(obj.body)
3861
+ return obj
3862
+
3863
+ def handle_CForLoop(self, obj):
3864
+ obj.initializer = self.handle(obj.initializer)
3865
+ obj.condition = self.handle(obj.condition)
3866
+ obj.iterator = self.handle(obj.iterator)
3867
+ obj.body = self.handle(obj.body)
3868
+ return obj
3869
+
3870
+ def handle_CIfElse(self, obj):
3871
+ obj.condition_and_nodes = [
3872
+ (self.handle(condition), self.handle(node)) for condition, node in obj.condition_and_nodes
3873
+ ]
3874
+ obj.else_node = self.handle(obj.else_node)
3875
+ return obj
3876
+
3877
+ def handle_CIfBreak(self, obj):
3878
+ obj.condition = self.handle(obj.condition)
3879
+ return obj
3880
+
3881
+ def handle_CSwitchCase(self, obj):
3882
+ obj.switch = self.handle(obj.switch)
3883
+ obj.cases = [(case, self.handle(body)) for case, body in obj.cases]
3884
+ obj.default = self.handle(obj.default)
3885
+ return obj
3886
+
3887
+ def handle_CAssignment(self, obj):
3888
+ obj.lhs = self.handle(obj.lhs)
3889
+ obj.rhs = self.handle(obj.rhs)
3890
+ return obj
3891
+
3892
+ def handle_CFunctionCall(self, obj):
3893
+ obj.callee_target = self.handle(obj.callee_target)
3894
+ obj.args = [self.handle(arg) for arg in obj.args]
3895
+ obj.ret_expr = self.handle(obj.ret_expr)
3896
+ return obj
3897
+
3898
+ def handle_CReturn(self, obj):
3899
+ obj.retval = self.handle(obj.retval)
3900
+ return obj
3901
+
3902
+ def handle_CGoto(self, obj):
3903
+ obj.target = self.handle(obj.target)
3904
+ return obj
3905
+
3906
+ def handle_CIndexedVariable(self, obj):
3907
+ obj.variable = self.handle(obj.variable)
3908
+ obj.index = self.handle(obj.index)
3909
+ return obj
3910
+
3911
+ def handle_CVariableField(self, obj):
3912
+ obj.variable = self.handle(obj.variable)
3913
+ return obj
3914
+
3915
+ def handle_CUnaryOp(self, obj):
3916
+ obj.operand = self.handle(obj.operand)
3917
+ return obj
3918
+
3919
+ def handle_CBinaryOp(self, obj):
3920
+ obj.lhs = self.handle(obj.lhs)
3921
+ obj.rhs = self.handle(obj.rhs)
3922
+ return obj
3923
+
3924
+ def handle_CTypeCast(self, obj):
3925
+ obj.expr = self.handle(obj.expr)
3926
+ return obj
3927
+
3928
+ def handle_CITE(self, obj):
3929
+ obj.cond = self.handle(obj.cond)
3930
+ obj.iftrue = self.handle(obj.iftrue)
3931
+ obj.iffalse = self.handle(obj.iffalse)
3932
+ return obj
3933
+
3934
+
3935
+ class MakeTypecastsImplicit(CStructuredCodeWalker):
3936
+ @classmethod
3937
+ def collapse(cls, dst_ty: SimType, child: CExpression) -> CExpression:
3938
+ result = child
3939
+ if isinstance(child, CTypeCast):
3940
+ intermediate_ty = child.dst_type
3941
+ start_ty = child.src_type
3942
+
3943
+ # step 1: collapse pointer-integer casts of the same size
3944
+ if qualifies_for_simple_cast(intermediate_ty, dst_ty) and qualifies_for_simple_cast(start_ty, dst_ty):
3945
+ result = child.expr
3946
+ # step 2: collapse integer conversions which are redundant
3947
+ if (
3948
+ isinstance(dst_ty, (SimTypeChar, SimTypeInt, SimTypeNum))
3949
+ and isinstance(intermediate_ty, (SimTypeChar, SimTypeInt, SimTypeNum))
3950
+ and isinstance(start_ty, (SimTypeChar, SimTypeInt, SimTypeNum))
3951
+ ):
3952
+ assert dst_ty.size and start_ty.size and intermediate_ty.size
3953
+ if dst_ty.size <= start_ty.size and dst_ty.size <= intermediate_ty.size:
3954
+ # this is a down- or neutral-cast with an intermediate step that doesn't matter
3955
+ result = child.expr
3956
+ elif dst_ty.size >= intermediate_ty.size >= start_ty.size and intermediate_ty.signed == start_ty.signed:
3957
+ # this is an up- or neutral-cast which is monotonically ascending
3958
+ # we can leave out the dst_ty.signed check
3959
+ result = child.expr
3960
+ # more cases go here...
3961
+
3962
+ if result is not child:
3963
+ # TODO this is not the best since it prohibits things like the BinaryOp optimizer from working incrementally
3964
+ return cls.collapse(dst_ty, result)
3965
+ return result
3966
+
3967
+ def handle_CAssignment(self, obj):
3968
+ obj.rhs = self.collapse(obj.lhs.type, obj.rhs)
3969
+ return super().handle_CAssignment(obj)
3970
+
3971
+ def handle_CFunctionCall(self, obj: CFunctionCall):
3972
+ prototype_args = [] if obj.prototype is None else obj.prototype.args
3973
+ for i, (c_arg, arg_ty) in enumerate(zip(obj.args, prototype_args)):
3974
+ obj.args[i] = self.collapse(arg_ty, c_arg)
3975
+ return super().handle_CFunctionCall(obj)
3976
+
3977
+ def handle_CReturn(self, obj: CReturn):
3978
+ obj.retval = self.collapse(obj.codegen._func.prototype.returnty, obj.retval)
3979
+ return super().handle_CReturn(obj)
3980
+
3981
+ def handle_CBinaryOp(self, obj: CBinaryOp):
3982
+ obj = super().handle_CBinaryOp(obj)
3983
+ while True:
3984
+ new_lhs = self.collapse(obj.common_type, obj.lhs)
3985
+ if (
3986
+ new_lhs is not obj.lhs
3987
+ and CBinaryOp.compute_common_type(obj.op, new_lhs.type, obj.rhs.type) == obj.common_type
3988
+ ):
3989
+ obj.lhs = new_lhs
3990
+ else:
3991
+ new_rhs = self.collapse(obj.common_type, obj.rhs)
3992
+ if (
3993
+ new_rhs is not obj.rhs
3994
+ and CBinaryOp.compute_common_type(obj.op, obj.lhs.type, new_rhs.type) == obj.common_type
3995
+ ):
3996
+ obj.rhs = new_rhs
3997
+ else:
3998
+ break
3999
+ return obj
4000
+
4001
+ def handle_CTypeCast(self, obj: CTypeCast):
4002
+ # note that the expression that this method returns may no longer be a CTypeCast
4003
+ obj = super().handle_CTypeCast(obj)
4004
+ inner = self.collapse(obj.dst_type, obj.expr)
4005
+ if inner is not obj.expr:
4006
+ obj.src_type = inner.type
4007
+ obj.expr = inner
4008
+ if obj.src_type == obj.dst_type or qualifies_for_implicit_cast(obj.src_type, obj.dst_type):
4009
+ return obj.expr
4010
+ return obj
4011
+
4012
+
4013
+ class FieldReferenceCleanup(CStructuredCodeWalker):
4014
+ def handle_CTypeCast(self, obj):
4015
+ if isinstance(obj.dst_type, SimTypePointer) and not isinstance(obj.dst_type.pts_to, SimTypeBottom):
4016
+ obj = obj.codegen._access_reference(obj.expr, obj.dst_type.pts_to)
4017
+ if not isinstance(obj, CTypeCast):
4018
+ return self.handle(obj)
4019
+ return super().handle_CTypeCast(obj)
4020
+
4021
+
4022
+ class PointerArithmeticFixer(CStructuredCodeWalker):
4023
+ """
4024
+ Before calling this fixer class, pointer arithmetics are purely integer-based and ignoring the pointer type.
4025
+
4026
+ For example, in the following case:
4027
+
4028
+ struct A* a_ptr; // assume struct A is 24 bytes in size
4029
+ a_ptr = a_ptr + 24;
4030
+
4031
+ It means adding 24 to the address of a_ptr, without considering the size of struct A. This fixer class will make
4032
+ pointer arithmetics aware of the pointer type. In this case, the fixer class will convert the code to
4033
+ a_ptr = a_ptr + 1.
4034
+ """
4035
+
4036
+ def handle_CBinaryOp(self, obj: CBinaryOp): # type: ignore
4037
+ obj: CBinaryOp = super().handle_CBinaryOp(obj)
4038
+ if (
4039
+ obj.op in ("Add", "Sub")
4040
+ and isinstance(obj.type, SimTypePointer)
4041
+ and not isinstance(obj.type.pts_to, SimTypeBottom)
4042
+ ):
4043
+ out = obj.codegen._access_reference(obj, obj.type.pts_to)
4044
+ if (
4045
+ isinstance(out, CUnaryOp)
4046
+ and out.op == "Reference"
4047
+ and isinstance(out.operand, CIndexedVariable)
4048
+ and isinstance(out.operand.index, CConstant)
4049
+ ):
4050
+ # rewrite &a[1] to a + 1
4051
+ const = out.operand.index
4052
+ if isinstance(const.value, int) and const.value < 0:
4053
+ op = "Sub"
4054
+ const = CConstant(
4055
+ -const.value,
4056
+ const.type,
4057
+ reference_values=const.reference_values,
4058
+ tags=const.tags,
4059
+ codegen=const.codegen,
4060
+ )
4061
+ else:
4062
+ op = "Add"
4063
+ return CBinaryOp(op, out.operand.variable, const, tags=out.operand.tags, codegen=out.codegen)
4064
+ return out
4065
+ return obj
4066
+
4067
+
4068
+ StructuredCodeGenerator = CStructuredCodeGenerator
4069
+ register_analysis(StructuredCodeGenerator, "StructuredCodeGenerator")