angr 9.2.166__cp310-abi3-manylinux_2_28_x86_64.whl

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

Potentially problematic release.


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

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