angr 9.2.103__py3-none-manylinux2014_aarch64.whl

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

Potentially problematic release.


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

Files changed (1300) hide show
  1. angr/__init__.py +153 -0
  2. angr/__main__.py +59 -0
  3. angr/analyses/__init__.py +46 -0
  4. angr/analyses/analysis.py +359 -0
  5. angr/analyses/backward_slice.py +691 -0
  6. angr/analyses/binary_optimizer.py +683 -0
  7. angr/analyses/bindiff.py +1251 -0
  8. angr/analyses/boyscout.py +77 -0
  9. angr/analyses/callee_cleanup_finder.py +75 -0
  10. angr/analyses/calling_convention.py +956 -0
  11. angr/analyses/cdg.py +197 -0
  12. angr/analyses/cfg/__init__.py +11 -0
  13. angr/analyses/cfg/cfb.py +436 -0
  14. angr/analyses/cfg/cfg.py +73 -0
  15. angr/analyses/cfg/cfg_arch_options.py +82 -0
  16. angr/analyses/cfg/cfg_base.py +2917 -0
  17. angr/analyses/cfg/cfg_emulated.py +3570 -0
  18. angr/analyses/cfg/cfg_fast.py +5053 -0
  19. angr/analyses/cfg/cfg_fast_soot.py +669 -0
  20. angr/analyses/cfg/cfg_job_base.py +204 -0
  21. angr/analyses/cfg/indirect_jump_resolvers/__init__.py +8 -0
  22. angr/analyses/cfg/indirect_jump_resolvers/amd64_elf_got.py +63 -0
  23. angr/analyses/cfg/indirect_jump_resolvers/amd64_pe_iat.py +52 -0
  24. angr/analyses/cfg/indirect_jump_resolvers/arm_elf_fast.py +151 -0
  25. angr/analyses/cfg/indirect_jump_resolvers/const_resolver.py +141 -0
  26. angr/analyses/cfg/indirect_jump_resolvers/default_resolvers.py +68 -0
  27. angr/analyses/cfg/indirect_jump_resolvers/jumptable.py +2368 -0
  28. angr/analyses/cfg/indirect_jump_resolvers/mips_elf_fast.py +517 -0
  29. angr/analyses/cfg/indirect_jump_resolvers/propagator_utils.py +26 -0
  30. angr/analyses/cfg/indirect_jump_resolvers/resolver.py +74 -0
  31. angr/analyses/cfg/indirect_jump_resolvers/x86_elf_pic_plt.py +93 -0
  32. angr/analyses/cfg/indirect_jump_resolvers/x86_pe_iat.py +51 -0
  33. angr/analyses/cfg_slice_to_sink/__init__.py +2 -0
  34. angr/analyses/cfg_slice_to_sink/cfg_slice_to_sink.py +117 -0
  35. angr/analyses/cfg_slice_to_sink/graph.py +84 -0
  36. angr/analyses/cfg_slice_to_sink/transitions.py +25 -0
  37. angr/analyses/class_identifier.py +62 -0
  38. angr/analyses/code_tagging.py +123 -0
  39. angr/analyses/complete_calling_conventions.py +424 -0
  40. angr/analyses/congruency_check.py +384 -0
  41. angr/analyses/data_dep/__init__.py +2 -0
  42. angr/analyses/data_dep/data_dependency_analysis.py +605 -0
  43. angr/analyses/data_dep/dep_nodes.py +170 -0
  44. angr/analyses/data_dep/sim_act_location.py +46 -0
  45. angr/analyses/datagraph_meta.py +105 -0
  46. angr/analyses/ddg.py +1695 -0
  47. angr/analyses/decompiler/__init__.py +13 -0
  48. angr/analyses/decompiler/ail_simplifier.py +1408 -0
  49. angr/analyses/decompiler/ailgraph_walker.py +48 -0
  50. angr/analyses/decompiler/block_io_finder.py +293 -0
  51. angr/analyses/decompiler/block_similarity.py +188 -0
  52. angr/analyses/decompiler/block_simplifier.py +434 -0
  53. angr/analyses/decompiler/call_counter.py +43 -0
  54. angr/analyses/decompiler/callsite_maker.py +403 -0
  55. angr/analyses/decompiler/ccall_rewriters/__init__.py +6 -0
  56. angr/analyses/decompiler/ccall_rewriters/amd64_ccalls.py +489 -0
  57. angr/analyses/decompiler/ccall_rewriters/rewriter_base.py +19 -0
  58. angr/analyses/decompiler/clinic.py +2166 -0
  59. angr/analyses/decompiler/condition_processor.py +1184 -0
  60. angr/analyses/decompiler/decompilation_cache.py +38 -0
  61. angr/analyses/decompiler/decompilation_options.py +274 -0
  62. angr/analyses/decompiler/decompiler.py +544 -0
  63. angr/analyses/decompiler/empty_node_remover.py +211 -0
  64. angr/analyses/decompiler/expression_counters.py +76 -0
  65. angr/analyses/decompiler/expression_narrower.py +92 -0
  66. angr/analyses/decompiler/goto_manager.py +73 -0
  67. angr/analyses/decompiler/graph_region.py +413 -0
  68. angr/analyses/decompiler/jump_target_collector.py +36 -0
  69. angr/analyses/decompiler/jumptable_entry_condition_rewriter.py +66 -0
  70. angr/analyses/decompiler/optimization_passes/__init__.py +108 -0
  71. angr/analyses/decompiler/optimization_passes/base_ptr_save_simplifier.py +144 -0
  72. angr/analyses/decompiler/optimization_passes/code_motion.py +360 -0
  73. angr/analyses/decompiler/optimization_passes/const_derefs.py +265 -0
  74. angr/analyses/decompiler/optimization_passes/cross_jump_reverter.py +108 -0
  75. angr/analyses/decompiler/optimization_passes/deadblock_remover.py +73 -0
  76. angr/analyses/decompiler/optimization_passes/div_simplifier.py +391 -0
  77. angr/analyses/decompiler/optimization_passes/engine_base.py +303 -0
  78. angr/analyses/decompiler/optimization_passes/expr_op_swapper.py +136 -0
  79. angr/analyses/decompiler/optimization_passes/flip_boolean_cmp.py +91 -0
  80. angr/analyses/decompiler/optimization_passes/inlined_string_transformation_simplifier.py +386 -0
  81. angr/analyses/decompiler/optimization_passes/ite_expr_converter.py +226 -0
  82. angr/analyses/decompiler/optimization_passes/ite_region_converter.py +189 -0
  83. angr/analyses/decompiler/optimization_passes/lowered_switch_simplifier.py +757 -0
  84. angr/analyses/decompiler/optimization_passes/mod_simplifier.py +86 -0
  85. angr/analyses/decompiler/optimization_passes/multi_simplifier.py +227 -0
  86. angr/analyses/decompiler/optimization_passes/optimization_pass.py +397 -0
  87. angr/analyses/decompiler/optimization_passes/register_save_area_simplifier.py +198 -0
  88. angr/analyses/decompiler/optimization_passes/ret_addr_save_simplifier.py +172 -0
  89. angr/analyses/decompiler/optimization_passes/ret_deduplicator.py +219 -0
  90. angr/analyses/decompiler/optimization_passes/return_duplicator_base.py +448 -0
  91. angr/analyses/decompiler/optimization_passes/return_duplicator_high.py +57 -0
  92. angr/analyses/decompiler/optimization_passes/return_duplicator_low.py +121 -0
  93. angr/analyses/decompiler/optimization_passes/spilled_register_finder.py +18 -0
  94. angr/analyses/decompiler/optimization_passes/stack_canary_simplifier.py +293 -0
  95. angr/analyses/decompiler/optimization_passes/switch_default_case_duplicator.py +110 -0
  96. angr/analyses/decompiler/optimization_passes/win_stack_canary_simplifier.py +281 -0
  97. angr/analyses/decompiler/optimization_passes/x86_gcc_getpc_simplifier.py +87 -0
  98. angr/analyses/decompiler/peephole_optimizations/__init__.py +69 -0
  99. angr/analyses/decompiler/peephole_optimizations/a_div_const_add_a_mul_n_div_const.py +38 -0
  100. angr/analyses/decompiler/peephole_optimizations/a_mul_const_div_shr_const.py +38 -0
  101. angr/analyses/decompiler/peephole_optimizations/a_shl_const_sub_a.py +31 -0
  102. angr/analyses/decompiler/peephole_optimizations/a_sub_a_div.py +25 -0
  103. angr/analyses/decompiler/peephole_optimizations/a_sub_a_div_const_mul_const.py +56 -0
  104. angr/analyses/decompiler/peephole_optimizations/a_sub_a_sub_n.py +19 -0
  105. angr/analyses/decompiler/peephole_optimizations/arm_cmpf.py +235 -0
  106. angr/analyses/decompiler/peephole_optimizations/base.py +120 -0
  107. angr/analyses/decompiler/peephole_optimizations/basepointeroffset_add_n.py +33 -0
  108. angr/analyses/decompiler/peephole_optimizations/basepointeroffset_and_mask.py +35 -0
  109. angr/analyses/decompiler/peephole_optimizations/bitwise_or_to_logical_or.py +34 -0
  110. angr/analyses/decompiler/peephole_optimizations/bool_expr_xor_1.py +27 -0
  111. angr/analyses/decompiler/peephole_optimizations/bswap.py +131 -0
  112. angr/analyses/decompiler/peephole_optimizations/cmpord_rewriter.py +72 -0
  113. angr/analyses/decompiler/peephole_optimizations/coalesce_same_cascading_ifs.py +27 -0
  114. angr/analyses/decompiler/peephole_optimizations/const_mull_a_shift.py +91 -0
  115. angr/analyses/decompiler/peephole_optimizations/constant_derefs.py +43 -0
  116. angr/analyses/decompiler/peephole_optimizations/conv_a_sub0_shr_and.py +70 -0
  117. angr/analyses/decompiler/peephole_optimizations/conv_shl_shr.py +51 -0
  118. angr/analyses/decompiler/peephole_optimizations/eager_eval.py +225 -0
  119. angr/analyses/decompiler/peephole_optimizations/extended_byte_and_mask.py +55 -0
  120. angr/analyses/decompiler/peephole_optimizations/inlined_strcpy.py +146 -0
  121. angr/analyses/decompiler/peephole_optimizations/inlined_strcpy_consolidation.py +102 -0
  122. angr/analyses/decompiler/peephole_optimizations/inlined_wstrcpy.py +159 -0
  123. angr/analyses/decompiler/peephole_optimizations/invert_negated_logical_conjuction_disjunction.py +50 -0
  124. angr/analyses/decompiler/peephole_optimizations/one_sub_bool.py +33 -0
  125. angr/analyses/decompiler/peephole_optimizations/remove_cascading_conversions.py +19 -0
  126. angr/analyses/decompiler/peephole_optimizations/remove_empty_if_body.py +45 -0
  127. angr/analyses/decompiler/peephole_optimizations/remove_noop_conversions.py +26 -0
  128. angr/analyses/decompiler/peephole_optimizations/remove_redundant_bitmasks.py +48 -0
  129. angr/analyses/decompiler/peephole_optimizations/remove_redundant_conversions.py +160 -0
  130. angr/analyses/decompiler/peephole_optimizations/remove_redundant_ite_branch.py +29 -0
  131. angr/analyses/decompiler/peephole_optimizations/remove_redundant_ite_comparisons.py +54 -0
  132. angr/analyses/decompiler/peephole_optimizations/remove_redundant_nots.py +17 -0
  133. angr/analyses/decompiler/peephole_optimizations/remove_redundant_reinterprets.py +43 -0
  134. angr/analyses/decompiler/peephole_optimizations/remove_redundant_shifts.py +44 -0
  135. angr/analyses/decompiler/peephole_optimizations/remove_redundant_shifts_around_comparators.py +40 -0
  136. angr/analyses/decompiler/peephole_optimizations/rewrite_bit_extractions.py +85 -0
  137. angr/analyses/decompiler/peephole_optimizations/rewrite_mips_gp_loads.py +47 -0
  138. angr/analyses/decompiler/peephole_optimizations/rol_ror.py +77 -0
  139. angr/analyses/decompiler/peephole_optimizations/sar_to_signed_div.py +105 -0
  140. angr/analyses/decompiler/peephole_optimizations/simplify_pc_relative_loads.py +37 -0
  141. angr/analyses/decompiler/peephole_optimizations/single_bit_cond_to_boolexpr.py +52 -0
  142. angr/analyses/decompiler/peephole_optimizations/single_bit_xor.py +26 -0
  143. angr/analyses/decompiler/peephole_optimizations/tidy_stack_addr.py +133 -0
  144. angr/analyses/decompiler/redundant_label_remover.py +116 -0
  145. angr/analyses/decompiler/region_identifier.py +1098 -0
  146. angr/analyses/decompiler/region_simplifiers/__init__.py +1 -0
  147. angr/analyses/decompiler/region_simplifiers/cascading_cond_transformer.py +93 -0
  148. angr/analyses/decompiler/region_simplifiers/cascading_ifs.py +81 -0
  149. angr/analyses/decompiler/region_simplifiers/expr_folding.py +606 -0
  150. angr/analyses/decompiler/region_simplifiers/goto.py +177 -0
  151. angr/analyses/decompiler/region_simplifiers/if_.py +142 -0
  152. angr/analyses/decompiler/region_simplifiers/ifelse.py +90 -0
  153. angr/analyses/decompiler/region_simplifiers/loop.py +135 -0
  154. angr/analyses/decompiler/region_simplifiers/node_address_finder.py +23 -0
  155. angr/analyses/decompiler/region_simplifiers/region_simplifier.py +211 -0
  156. angr/analyses/decompiler/region_simplifiers/switch_cluster_simplifier.py +644 -0
  157. angr/analyses/decompiler/region_simplifiers/switch_expr_simplifier.py +83 -0
  158. angr/analyses/decompiler/region_walker.py +23 -0
  159. angr/analyses/decompiler/return_maker.py +70 -0
  160. angr/analyses/decompiler/seq_to_blocks.py +19 -0
  161. angr/analyses/decompiler/sequence_walker.py +235 -0
  162. angr/analyses/decompiler/structured_codegen/__init__.py +10 -0
  163. angr/analyses/decompiler/structured_codegen/base.py +132 -0
  164. angr/analyses/decompiler/structured_codegen/c.py +3811 -0
  165. angr/analyses/decompiler/structured_codegen/dummy.py +14 -0
  166. angr/analyses/decompiler/structured_codegen/dwarf_import.py +186 -0
  167. angr/analyses/decompiler/structuring/__init__.py +15 -0
  168. angr/analyses/decompiler/structuring/dream.py +1225 -0
  169. angr/analyses/decompiler/structuring/phoenix.py +2546 -0
  170. angr/analyses/decompiler/structuring/recursive_structurer.py +186 -0
  171. angr/analyses/decompiler/structuring/structurer_base.py +954 -0
  172. angr/analyses/decompiler/structuring/structurer_nodes.py +414 -0
  173. angr/analyses/decompiler/utils.py +787 -0
  174. angr/analyses/disassembly.py +1302 -0
  175. angr/analyses/disassembly_utils.py +104 -0
  176. angr/analyses/dominance_frontier.py +39 -0
  177. angr/analyses/find_objects_static.py +203 -0
  178. angr/analyses/flirt.py +185 -0
  179. angr/analyses/forward_analysis/__init__.py +2 -0
  180. angr/analyses/forward_analysis/forward_analysis.py +527 -0
  181. angr/analyses/forward_analysis/job_info.py +64 -0
  182. angr/analyses/forward_analysis/visitors/__init__.py +4 -0
  183. angr/analyses/forward_analysis/visitors/call_graph.py +28 -0
  184. angr/analyses/forward_analysis/visitors/function_graph.py +85 -0
  185. angr/analyses/forward_analysis/visitors/graph.py +250 -0
  186. angr/analyses/forward_analysis/visitors/loop.py +28 -0
  187. angr/analyses/forward_analysis/visitors/single_node_graph.py +38 -0
  188. angr/analyses/identifier/__init__.py +1 -0
  189. angr/analyses/identifier/custom_callable.py +138 -0
  190. angr/analyses/identifier/errors.py +9 -0
  191. angr/analyses/identifier/func.py +57 -0
  192. angr/analyses/identifier/functions/__init__.py +36 -0
  193. angr/analyses/identifier/functions/atoi.py +75 -0
  194. angr/analyses/identifier/functions/based_atoi.py +128 -0
  195. angr/analyses/identifier/functions/fdprintf.py +122 -0
  196. angr/analyses/identifier/functions/free.py +64 -0
  197. angr/analyses/identifier/functions/int2str.py +302 -0
  198. angr/analyses/identifier/functions/malloc.py +113 -0
  199. angr/analyses/identifier/functions/memcmp.py +69 -0
  200. angr/analyses/identifier/functions/memcpy.py +89 -0
  201. angr/analyses/identifier/functions/memset.py +43 -0
  202. angr/analyses/identifier/functions/printf.py +122 -0
  203. angr/analyses/identifier/functions/recv_until.py +315 -0
  204. angr/analyses/identifier/functions/skip_calloc.py +72 -0
  205. angr/analyses/identifier/functions/skip_realloc.py +99 -0
  206. angr/analyses/identifier/functions/skip_recv_n.py +107 -0
  207. angr/analyses/identifier/functions/snprintf.py +114 -0
  208. angr/analyses/identifier/functions/sprintf.py +115 -0
  209. angr/analyses/identifier/functions/strcasecmp.py +32 -0
  210. angr/analyses/identifier/functions/strcmp.py +112 -0
  211. angr/analyses/identifier/functions/strcpy.py +43 -0
  212. angr/analyses/identifier/functions/strlen.py +26 -0
  213. angr/analyses/identifier/functions/strncmp.py +103 -0
  214. angr/analyses/identifier/functions/strncpy.py +65 -0
  215. angr/analyses/identifier/functions/strtol.py +91 -0
  216. angr/analyses/identifier/identify.py +848 -0
  217. angr/analyses/identifier/runner.py +359 -0
  218. angr/analyses/init_finder.py +264 -0
  219. angr/analyses/loop_analysis.py +353 -0
  220. angr/analyses/loopfinder.py +174 -0
  221. angr/analyses/propagator/__init__.py +1 -0
  222. angr/analyses/propagator/engine_ail.py +1560 -0
  223. angr/analyses/propagator/engine_base.py +53 -0
  224. angr/analyses/propagator/engine_vex.py +328 -0
  225. angr/analyses/propagator/outdated_definition_walker.py +158 -0
  226. angr/analyses/propagator/propagator.py +422 -0
  227. angr/analyses/propagator/tmpvar_finder.py +17 -0
  228. angr/analyses/propagator/top_checker_mixin.py +14 -0
  229. angr/analyses/propagator/values.py +116 -0
  230. angr/analyses/propagator/vex_vars.py +67 -0
  231. angr/analyses/proximity_graph.py +452 -0
  232. angr/analyses/reaching_definitions/__init__.py +65 -0
  233. angr/analyses/reaching_definitions/call_trace.py +72 -0
  234. angr/analyses/reaching_definitions/dep_graph.py +392 -0
  235. angr/analyses/reaching_definitions/engine_ail.py +1172 -0
  236. angr/analyses/reaching_definitions/engine_vex.py +1102 -0
  237. angr/analyses/reaching_definitions/external_codeloc.py +0 -0
  238. angr/analyses/reaching_definitions/function_handler.py +603 -0
  239. angr/analyses/reaching_definitions/heap_allocator.py +69 -0
  240. angr/analyses/reaching_definitions/rd_initializer.py +235 -0
  241. angr/analyses/reaching_definitions/rd_state.py +613 -0
  242. angr/analyses/reaching_definitions/reaching_definitions.py +594 -0
  243. angr/analyses/reaching_definitions/subject.py +64 -0
  244. angr/analyses/reassembler.py +2970 -0
  245. angr/analyses/soot_class_hierarchy.py +283 -0
  246. angr/analyses/stack_pointer_tracker.py +832 -0
  247. angr/analyses/static_hooker.py +51 -0
  248. angr/analyses/typehoon/__init__.py +1 -0
  249. angr/analyses/typehoon/dfa.py +108 -0
  250. angr/analyses/typehoon/lifter.py +91 -0
  251. angr/analyses/typehoon/simple_solver.py +1258 -0
  252. angr/analyses/typehoon/translator.py +242 -0
  253. angr/analyses/typehoon/typeconsts.py +294 -0
  254. angr/analyses/typehoon/typehoon.py +239 -0
  255. angr/analyses/typehoon/typevars.py +565 -0
  256. angr/analyses/typehoon/variance.py +10 -0
  257. angr/analyses/variable_recovery/__init__.py +2 -0
  258. angr/analyses/variable_recovery/annotations.py +57 -0
  259. angr/analyses/variable_recovery/engine_ail.py +746 -0
  260. angr/analyses/variable_recovery/engine_base.py +962 -0
  261. angr/analyses/variable_recovery/engine_vex.py +580 -0
  262. angr/analyses/variable_recovery/irsb_scanner.py +131 -0
  263. angr/analyses/variable_recovery/variable_recovery.py +552 -0
  264. angr/analyses/variable_recovery/variable_recovery_base.py +452 -0
  265. angr/analyses/variable_recovery/variable_recovery_fast.py +589 -0
  266. angr/analyses/veritesting.py +635 -0
  267. angr/analyses/vfg.py +1945 -0
  268. angr/analyses/vsa_ddg.py +423 -0
  269. angr/analyses/vtable.py +92 -0
  270. angr/analyses/xrefs.py +263 -0
  271. angr/angrdb/__init__.py +9 -0
  272. angr/angrdb/db.py +208 -0
  273. angr/angrdb/models.py +183 -0
  274. angr/angrdb/serializers/__init__.py +2 -0
  275. angr/angrdb/serializers/cfg_model.py +41 -0
  276. angr/angrdb/serializers/comments.py +59 -0
  277. angr/angrdb/serializers/funcs.py +60 -0
  278. angr/angrdb/serializers/kb.py +110 -0
  279. angr/angrdb/serializers/labels.py +58 -0
  280. angr/angrdb/serializers/loader.py +81 -0
  281. angr/angrdb/serializers/structured_code.py +128 -0
  282. angr/angrdb/serializers/variables.py +58 -0
  283. angr/angrdb/serializers/xrefs.py +48 -0
  284. angr/annocfg.py +320 -0
  285. angr/blade.py +430 -0
  286. angr/block.py +506 -0
  287. angr/callable.py +162 -0
  288. angr/calling_conventions.py +2383 -0
  289. angr/code_location.py +168 -0
  290. angr/codenode.py +140 -0
  291. angr/concretization_strategies/__init__.py +97 -0
  292. angr/concretization_strategies/any.py +15 -0
  293. angr/concretization_strategies/any_named.py +32 -0
  294. angr/concretization_strategies/controlled_data.py +54 -0
  295. angr/concretization_strategies/eval.py +18 -0
  296. angr/concretization_strategies/logging.py +32 -0
  297. angr/concretization_strategies/max.py +24 -0
  298. angr/concretization_strategies/nonzero.py +14 -0
  299. angr/concretization_strategies/nonzero_range.py +20 -0
  300. angr/concretization_strategies/norepeats.py +35 -0
  301. angr/concretization_strategies/norepeats_range.py +35 -0
  302. angr/concretization_strategies/range.py +17 -0
  303. angr/concretization_strategies/signed_add.py +24 -0
  304. angr/concretization_strategies/single.py +12 -0
  305. angr/concretization_strategies/solutions.py +18 -0
  306. angr/concretization_strategies/unlimited_range.py +15 -0
  307. angr/distributed/__init__.py +3 -0
  308. angr/distributed/server.py +198 -0
  309. angr/distributed/worker.py +183 -0
  310. angr/engines/__init__.py +41 -0
  311. angr/engines/concrete.py +178 -0
  312. angr/engines/engine.py +212 -0
  313. angr/engines/failure.py +27 -0
  314. angr/engines/hook.py +67 -0
  315. angr/engines/light/__init__.py +2 -0
  316. angr/engines/light/data.py +715 -0
  317. angr/engines/light/engine.py +1441 -0
  318. angr/engines/pcode/__init__.py +2 -0
  319. angr/engines/pcode/behavior.py +995 -0
  320. angr/engines/pcode/cc.py +123 -0
  321. angr/engines/pcode/emulate.py +446 -0
  322. angr/engines/pcode/engine.py +256 -0
  323. angr/engines/pcode/lifter.py +1423 -0
  324. angr/engines/procedure.py +71 -0
  325. angr/engines/soot/__init__.py +1 -0
  326. angr/engines/soot/engine.py +415 -0
  327. angr/engines/soot/exceptions.py +14 -0
  328. angr/engines/soot/expressions/__init__.py +56 -0
  329. angr/engines/soot/expressions/arrayref.py +21 -0
  330. angr/engines/soot/expressions/base.py +22 -0
  331. angr/engines/soot/expressions/binop.py +27 -0
  332. angr/engines/soot/expressions/cast.py +21 -0
  333. angr/engines/soot/expressions/condition.py +34 -0
  334. angr/engines/soot/expressions/constants.py +45 -0
  335. angr/engines/soot/expressions/instanceOf.py +11 -0
  336. angr/engines/soot/expressions/instancefieldref.py +7 -0
  337. angr/engines/soot/expressions/invoke.py +117 -0
  338. angr/engines/soot/expressions/length.py +7 -0
  339. angr/engines/soot/expressions/local.py +7 -0
  340. angr/engines/soot/expressions/new.py +15 -0
  341. angr/engines/soot/expressions/newArray.py +51 -0
  342. angr/engines/soot/expressions/newMultiArray.py +84 -0
  343. angr/engines/soot/expressions/paramref.py +7 -0
  344. angr/engines/soot/expressions/phi.py +29 -0
  345. angr/engines/soot/expressions/staticfieldref.py +7 -0
  346. angr/engines/soot/expressions/thisref.py +6 -0
  347. angr/engines/soot/expressions/unsupported.py +6 -0
  348. angr/engines/soot/field_dispatcher.py +49 -0
  349. angr/engines/soot/method_dispatcher.py +49 -0
  350. angr/engines/soot/statements/__init__.py +30 -0
  351. angr/engines/soot/statements/assign.py +29 -0
  352. angr/engines/soot/statements/base.py +80 -0
  353. angr/engines/soot/statements/goto.py +11 -0
  354. angr/engines/soot/statements/identity.py +14 -0
  355. angr/engines/soot/statements/if_.py +16 -0
  356. angr/engines/soot/statements/invoke.py +11 -0
  357. angr/engines/soot/statements/return_.py +19 -0
  358. angr/engines/soot/statements/switch.py +38 -0
  359. angr/engines/soot/statements/throw.py +12 -0
  360. angr/engines/soot/values/__init__.py +24 -0
  361. angr/engines/soot/values/arrayref.py +124 -0
  362. angr/engines/soot/values/base.py +4 -0
  363. angr/engines/soot/values/constants.py +17 -0
  364. angr/engines/soot/values/instancefieldref.py +42 -0
  365. angr/engines/soot/values/local.py +17 -0
  366. angr/engines/soot/values/paramref.py +17 -0
  367. angr/engines/soot/values/staticfieldref.py +37 -0
  368. angr/engines/soot/values/strref.py +37 -0
  369. angr/engines/soot/values/thisref.py +148 -0
  370. angr/engines/successors.py +540 -0
  371. angr/engines/syscall.py +53 -0
  372. angr/engines/unicorn.py +483 -0
  373. angr/engines/vex/__init__.py +4 -0
  374. angr/engines/vex/claripy/__init__.py +1 -0
  375. angr/engines/vex/claripy/ccall.py +2097 -0
  376. angr/engines/vex/claripy/datalayer.py +149 -0
  377. angr/engines/vex/claripy/irop.py +1279 -0
  378. angr/engines/vex/heavy/__init__.py +5 -0
  379. angr/engines/vex/heavy/actions.py +237 -0
  380. angr/engines/vex/heavy/concretizers.py +394 -0
  381. angr/engines/vex/heavy/dirty.py +467 -0
  382. angr/engines/vex/heavy/heavy.py +379 -0
  383. angr/engines/vex/heavy/inspect.py +51 -0
  384. angr/engines/vex/heavy/resilience.py +85 -0
  385. angr/engines/vex/heavy/super_fastpath.py +34 -0
  386. angr/engines/vex/lifter.py +424 -0
  387. angr/engines/vex/light/__init__.py +3 -0
  388. angr/engines/vex/light/light.py +555 -0
  389. angr/engines/vex/light/resilience.py +73 -0
  390. angr/engines/vex/light/slicing.py +51 -0
  391. angr/errors.py +604 -0
  392. angr/exploration_techniques/__init__.py +176 -0
  393. angr/exploration_techniques/bucketizer.py +96 -0
  394. angr/exploration_techniques/common.py +56 -0
  395. angr/exploration_techniques/dfs.py +34 -0
  396. angr/exploration_techniques/director.py +523 -0
  397. angr/exploration_techniques/driller_core.py +102 -0
  398. angr/exploration_techniques/explorer.py +146 -0
  399. angr/exploration_techniques/lengthlimiter.py +20 -0
  400. angr/exploration_techniques/local_loop_seer.py +64 -0
  401. angr/exploration_techniques/loop_seer.py +239 -0
  402. angr/exploration_techniques/manual_mergepoint.py +80 -0
  403. angr/exploration_techniques/memory_watcher.py +40 -0
  404. angr/exploration_techniques/oppologist.py +93 -0
  405. angr/exploration_techniques/slicecutor.py +115 -0
  406. angr/exploration_techniques/spiller.py +282 -0
  407. angr/exploration_techniques/spiller_db.py +27 -0
  408. angr/exploration_techniques/stochastic.py +57 -0
  409. angr/exploration_techniques/suggestions.py +156 -0
  410. angr/exploration_techniques/symbion.py +78 -0
  411. angr/exploration_techniques/tech_builder.py +47 -0
  412. angr/exploration_techniques/threading.py +77 -0
  413. angr/exploration_techniques/timeout.py +31 -0
  414. angr/exploration_techniques/tracer.py +1101 -0
  415. angr/exploration_techniques/unique.py +104 -0
  416. angr/exploration_techniques/veritesting.py +36 -0
  417. angr/factory.py +385 -0
  418. angr/flirt/__init__.py +126 -0
  419. angr/flirt/build_sig.py +316 -0
  420. angr/graph_utils.py +0 -0
  421. angr/keyed_region.py +532 -0
  422. angr/knowledge_base/__init__.py +1 -0
  423. angr/knowledge_base/knowledge_base.py +145 -0
  424. angr/knowledge_plugins/__init__.py +18 -0
  425. angr/knowledge_plugins/callsite_prototypes.py +52 -0
  426. angr/knowledge_plugins/cfg/__init__.py +16 -0
  427. angr/knowledge_plugins/cfg/cfg_manager.py +94 -0
  428. angr/knowledge_plugins/cfg/cfg_model.py +1057 -0
  429. angr/knowledge_plugins/cfg/cfg_node.py +541 -0
  430. angr/knowledge_plugins/cfg/indirect_jump.py +67 -0
  431. angr/knowledge_plugins/cfg/memory_data.py +156 -0
  432. angr/knowledge_plugins/comments.py +15 -0
  433. angr/knowledge_plugins/custom_strings.py +37 -0
  434. angr/knowledge_plugins/data.py +21 -0
  435. angr/knowledge_plugins/debug_variables.py +221 -0
  436. angr/knowledge_plugins/functions/__init__.py +2 -0
  437. angr/knowledge_plugins/functions/function.py +1694 -0
  438. angr/knowledge_plugins/functions/function_manager.py +501 -0
  439. angr/knowledge_plugins/functions/function_parser.py +295 -0
  440. angr/knowledge_plugins/functions/soot_function.py +131 -0
  441. angr/knowledge_plugins/indirect_jumps.py +34 -0
  442. angr/knowledge_plugins/key_definitions/__init__.py +16 -0
  443. angr/knowledge_plugins/key_definitions/atoms.py +314 -0
  444. angr/knowledge_plugins/key_definitions/constants.py +23 -0
  445. angr/knowledge_plugins/key_definitions/definition.py +217 -0
  446. angr/knowledge_plugins/key_definitions/environment.py +92 -0
  447. angr/knowledge_plugins/key_definitions/heap_address.py +32 -0
  448. angr/knowledge_plugins/key_definitions/key_definition_manager.py +81 -0
  449. angr/knowledge_plugins/key_definitions/live_definitions.py +1074 -0
  450. angr/knowledge_plugins/key_definitions/liveness.py +170 -0
  451. angr/knowledge_plugins/key_definitions/rd_model.py +176 -0
  452. angr/knowledge_plugins/key_definitions/tag.py +77 -0
  453. angr/knowledge_plugins/key_definitions/undefined.py +67 -0
  454. angr/knowledge_plugins/key_definitions/unknown_size.py +83 -0
  455. angr/knowledge_plugins/key_definitions/uses.py +180 -0
  456. angr/knowledge_plugins/labels.py +109 -0
  457. angr/knowledge_plugins/patches.py +125 -0
  458. angr/knowledge_plugins/plugin.py +23 -0
  459. angr/knowledge_plugins/propagations/__init__.py +2 -0
  460. angr/knowledge_plugins/propagations/prop_value.py +193 -0
  461. angr/knowledge_plugins/propagations/propagation_manager.py +60 -0
  462. angr/knowledge_plugins/propagations/propagation_model.py +74 -0
  463. angr/knowledge_plugins/propagations/states.py +1064 -0
  464. angr/knowledge_plugins/structured_code/__init__.py +1 -0
  465. angr/knowledge_plugins/structured_code/manager.py +59 -0
  466. angr/knowledge_plugins/sync/__init__.py +1 -0
  467. angr/knowledge_plugins/sync/sync_controller.py +329 -0
  468. angr/knowledge_plugins/types.py +87 -0
  469. angr/knowledge_plugins/variables/__init__.py +1 -0
  470. angr/knowledge_plugins/variables/variable_access.py +114 -0
  471. angr/knowledge_plugins/variables/variable_manager.py +1191 -0
  472. angr/knowledge_plugins/xrefs/__init__.py +3 -0
  473. angr/knowledge_plugins/xrefs/xref.py +157 -0
  474. angr/knowledge_plugins/xrefs/xref_manager.py +122 -0
  475. angr/knowledge_plugins/xrefs/xref_types.py +13 -0
  476. angr/lib/angr_native.so +0 -0
  477. angr/misc/__init__.py +8 -0
  478. angr/misc/ansi.py +46 -0
  479. angr/misc/autoimport.py +89 -0
  480. angr/misc/bug_report.py +125 -0
  481. angr/misc/hookset.py +106 -0
  482. angr/misc/import_hooks.py +63 -0
  483. angr/misc/loggers.py +130 -0
  484. angr/misc/picklable_lock.py +45 -0
  485. angr/misc/plugins.py +291 -0
  486. angr/misc/range.py +21 -0
  487. angr/misc/testing.py +23 -0
  488. angr/misc/ux.py +31 -0
  489. angr/misc/weakpatch.py +58 -0
  490. angr/procedures/__init__.py +2 -0
  491. angr/procedures/advapi32/__init__.py +0 -0
  492. angr/procedures/cgc/__init__.py +3 -0
  493. angr/procedures/cgc/_terminate.py +10 -0
  494. angr/procedures/cgc/allocate.py +76 -0
  495. angr/procedures/cgc/deallocate.py +59 -0
  496. angr/procedures/cgc/fdwait.py +62 -0
  497. angr/procedures/cgc/random.py +60 -0
  498. angr/procedures/cgc/receive.py +91 -0
  499. angr/procedures/cgc/transmit.py +63 -0
  500. angr/procedures/definitions/__init__.py +784 -0
  501. angr/procedures/definitions/cgc.py +19 -0
  502. angr/procedures/definitions/glibc.py +8384 -0
  503. angr/procedures/definitions/gnulib.py +35 -0
  504. angr/procedures/definitions/libstdcpp.py +20 -0
  505. angr/procedures/definitions/linux_kernel.py +6167 -0
  506. angr/procedures/definitions/linux_loader.py +6 -0
  507. angr/procedures/definitions/msvcr.py +15 -0
  508. angr/procedures/definitions/parse_syscalls_from_local_system.py +49 -0
  509. angr/procedures/definitions/parse_win32json.py +2556 -0
  510. angr/procedures/definitions/types_win32.py +34481 -0
  511. angr/procedures/definitions/wdk_api-ms-win-dx-d3dkmt-l1-1-4.py +44 -0
  512. angr/procedures/definitions/wdk_api-ms-win-dx-d3dkmt-l1-1-6.py +40 -0
  513. angr/procedures/definitions/wdk_clfs.py +154 -0
  514. angr/procedures/definitions/wdk_fltmgr.py +570 -0
  515. angr/procedures/definitions/wdk_fwpkclnt.py +44 -0
  516. angr/procedures/definitions/wdk_fwpuclnt.py +330 -0
  517. angr/procedures/definitions/wdk_gdi32.py +380 -0
  518. angr/procedures/definitions/wdk_hal.py +92 -0
  519. angr/procedures/definitions/wdk_ksecdd.py +76 -0
  520. angr/procedures/definitions/wdk_ndis.py +252 -0
  521. angr/procedures/definitions/wdk_ntoskrnl.py +3463 -0
  522. angr/procedures/definitions/wdk_offreg.py +86 -0
  523. angr/procedures/definitions/wdk_pshed.py +50 -0
  524. angr/procedures/definitions/wdk_secur32.py +54 -0
  525. angr/procedures/definitions/wdk_vhfum.py +48 -0
  526. angr/procedures/definitions/win32_aclui.py +44 -0
  527. angr/procedures/definitions/win32_activeds.py +82 -0
  528. angr/procedures/definitions/win32_advapi32.py +1698 -0
  529. angr/procedures/definitions/win32_advpack.py +138 -0
  530. angr/procedures/definitions/win32_amsi.py +52 -0
  531. angr/procedures/definitions/win32_api-ms-win-appmodel-runtime-l1-1-1.py +58 -0
  532. angr/procedures/definitions/win32_api-ms-win-appmodel-runtime-l1-1-3.py +48 -0
  533. angr/procedures/definitions/win32_api-ms-win-appmodel-runtime-l1-1-6.py +40 -0
  534. angr/procedures/definitions/win32_api-ms-win-core-apiquery-l2-1-0.py +40 -0
  535. angr/procedures/definitions/win32_api-ms-win-core-backgroundtask-l1-1-0.py +40 -0
  536. angr/procedures/definitions/win32_api-ms-win-core-comm-l1-1-1.py +40 -0
  537. angr/procedures/definitions/win32_api-ms-win-core-comm-l1-1-2.py +40 -0
  538. angr/procedures/definitions/win32_api-ms-win-core-enclave-l1-1-1.py +44 -0
  539. angr/procedures/definitions/win32_api-ms-win-core-errorhandling-l1-1-3.py +40 -0
  540. angr/procedures/definitions/win32_api-ms-win-core-featurestaging-l1-1-0.py +48 -0
  541. angr/procedures/definitions/win32_api-ms-win-core-featurestaging-l1-1-1.py +40 -0
  542. angr/procedures/definitions/win32_api-ms-win-core-file-fromapp-l1-1-0.py +60 -0
  543. angr/procedures/definitions/win32_api-ms-win-core-handle-l1-1-0.py +40 -0
  544. angr/procedures/definitions/win32_api-ms-win-core-ioring-l1-1-0.py +62 -0
  545. angr/procedures/definitions/win32_api-ms-win-core-marshal-l1-1-0.py +46 -0
  546. angr/procedures/definitions/win32_api-ms-win-core-memory-l1-1-3.py +46 -0
  547. angr/procedures/definitions/win32_api-ms-win-core-memory-l1-1-4.py +40 -0
  548. angr/procedures/definitions/win32_api-ms-win-core-memory-l1-1-5.py +44 -0
  549. angr/procedures/definitions/win32_api-ms-win-core-memory-l1-1-6.py +46 -0
  550. angr/procedures/definitions/win32_api-ms-win-core-memory-l1-1-7.py +42 -0
  551. angr/procedures/definitions/win32_api-ms-win-core-memory-l1-1-8.py +44 -0
  552. angr/procedures/definitions/win32_api-ms-win-core-path-l1-1-0.py +82 -0
  553. angr/procedures/definitions/win32_api-ms-win-core-psm-appnotify-l1-1-0.py +42 -0
  554. angr/procedures/definitions/win32_api-ms-win-core-psm-appnotify-l1-1-1.py +42 -0
  555. angr/procedures/definitions/win32_api-ms-win-core-realtime-l1-1-1.py +44 -0
  556. angr/procedures/definitions/win32_api-ms-win-core-realtime-l1-1-2.py +44 -0
  557. angr/procedures/definitions/win32_api-ms-win-core-slapi-l1-1-0.py +40 -0
  558. angr/procedures/definitions/win32_api-ms-win-core-state-helpers-l1-1-0.py +40 -0
  559. angr/procedures/definitions/win32_api-ms-win-core-synch-l1-2-0.py +44 -0
  560. angr/procedures/definitions/win32_api-ms-win-core-sysinfo-l1-2-0.py +40 -0
  561. angr/procedures/definitions/win32_api-ms-win-core-sysinfo-l1-2-3.py +42 -0
  562. angr/procedures/definitions/win32_api-ms-win-core-sysinfo-l1-2-4.py +42 -0
  563. angr/procedures/definitions/win32_api-ms-win-core-sysinfo-l1-2-6.py +40 -0
  564. angr/procedures/definitions/win32_api-ms-win-core-util-l1-1-1.py +42 -0
  565. angr/procedures/definitions/win32_api-ms-win-core-winrt-error-l1-1-0.py +43 -0
  566. angr/procedures/definitions/win32_api-ms-win-core-winrt-error-l1-1-1.py +37 -0
  567. angr/procedures/definitions/win32_api-ms-win-core-winrt-l1-1-0.py +39 -0
  568. angr/procedures/definitions/win32_api-ms-win-core-winrt-registration-l1-1-0.py +23 -0
  569. angr/procedures/definitions/win32_api-ms-win-core-winrt-robuffer-l1-1-0.py +23 -0
  570. angr/procedures/definitions/win32_api-ms-win-core-winrt-roparameterizediid-l1-1-0.py +27 -0
  571. angr/procedures/definitions/win32_api-ms-win-core-winrt-string-l1-1-0.py +75 -0
  572. angr/procedures/definitions/win32_api-ms-win-core-winrt-string-l1-1-1.py +23 -0
  573. angr/procedures/definitions/win32_api-ms-win-core-wow64-l1-1-1.py +44 -0
  574. angr/procedures/definitions/win32_api-ms-win-devices-query-l1-1-0.py +56 -0
  575. angr/procedures/definitions/win32_api-ms-win-devices-query-l1-1-1.py +48 -0
  576. angr/procedures/definitions/win32_api-ms-win-dx-d3dkmt-l1-1-0.py +40 -0
  577. angr/procedures/definitions/win32_api-ms-win-gaming-deviceinformation-l1-1-0.py +40 -0
  578. angr/procedures/definitions/win32_api-ms-win-gaming-expandedresources-l1-1-0.py +44 -0
  579. angr/procedures/definitions/win32_api-ms-win-gaming-tcui-l1-1-0.py +52 -0
  580. angr/procedures/definitions/win32_api-ms-win-gaming-tcui-l1-1-1.py +42 -0
  581. angr/procedures/definitions/win32_api-ms-win-gaming-tcui-l1-1-2.py +52 -0
  582. angr/procedures/definitions/win32_api-ms-win-gaming-tcui-l1-1-3.py +42 -0
  583. angr/procedures/definitions/win32_api-ms-win-gaming-tcui-l1-1-4.py +54 -0
  584. angr/procedures/definitions/win32_api-ms-win-mm-misc-l1-1-1.py +40 -0
  585. angr/procedures/definitions/win32_api-ms-win-net-isolation-l1-1-0.py +54 -0
  586. angr/procedures/definitions/win32_api-ms-win-security-base-l1-2-2.py +40 -0
  587. angr/procedures/definitions/win32_api-ms-win-security-isolatedcontainer-l1-1-0.py +40 -0
  588. angr/procedures/definitions/win32_api-ms-win-security-isolatedcontainer-l1-1-1.py +40 -0
  589. angr/procedures/definitions/win32_api-ms-win-service-core-l1-1-3.py +40 -0
  590. angr/procedures/definitions/win32_api-ms-win-service-core-l1-1-4.py +40 -0
  591. angr/procedures/definitions/win32_api-ms-win-service-core-l1-1-5.py +42 -0
  592. angr/procedures/definitions/win32_api-ms-win-shcore-scaling-l1-1-0.py +44 -0
  593. angr/procedures/definitions/win32_api-ms-win-shcore-scaling-l1-1-1.py +50 -0
  594. angr/procedures/definitions/win32_api-ms-win-shcore-scaling-l1-1-2.py +40 -0
  595. angr/procedures/definitions/win32_api-ms-win-shcore-stream-winrt-l1-1-0.py +27 -0
  596. angr/procedures/definitions/win32_api-ms-win-wsl-api-l1-1-0.py +52 -0
  597. angr/procedures/definitions/win32_apphelp.py +40 -0
  598. angr/procedures/definitions/win32_authz.py +104 -0
  599. angr/procedures/definitions/win32_avicap32.py +46 -0
  600. angr/procedures/definitions/win32_avifil32.py +158 -0
  601. angr/procedures/definitions/win32_avrt.py +66 -0
  602. angr/procedures/definitions/win32_bcp47mrm.py +42 -0
  603. angr/procedures/definitions/win32_bcrypt.py +144 -0
  604. angr/procedures/definitions/win32_bcryptprimitives.py +42 -0
  605. angr/procedures/definitions/win32_bluetoothapis.py +120 -0
  606. angr/procedures/definitions/win32_bthprops.py +33 -0
  607. angr/procedures/definitions/win32_bthprops_cpl.py +50 -0
  608. angr/procedures/definitions/win32_cabinet.py +82 -0
  609. angr/procedures/definitions/win32_certadm.py +74 -0
  610. angr/procedures/definitions/win32_certpoleng.py +54 -0
  611. angr/procedures/definitions/win32_cfgmgr32.py +516 -0
  612. angr/procedures/definitions/win32_chakra.py +212 -0
  613. angr/procedures/definitions/win32_cldapi.py +110 -0
  614. angr/procedures/definitions/win32_clfsw32.py +156 -0
  615. angr/procedures/definitions/win32_clusapi.py +598 -0
  616. angr/procedures/definitions/win32_comctl32.py +268 -0
  617. angr/procedures/definitions/win32_comdlg32.py +80 -0
  618. angr/procedures/definitions/win32_compstui.py +46 -0
  619. angr/procedures/definitions/win32_computecore.py +146 -0
  620. angr/procedures/definitions/win32_computenetwork.py +124 -0
  621. angr/procedures/definitions/win32_computestorage.py +62 -0
  622. angr/procedures/definitions/win32_comsvcs.py +52 -0
  623. angr/procedures/definitions/win32_coremessaging.py +23 -0
  624. angr/procedures/definitions/win32_credui.py +76 -0
  625. angr/procedures/definitions/win32_crypt32.py +496 -0
  626. angr/procedures/definitions/win32_cryptnet.py +48 -0
  627. angr/procedures/definitions/win32_cryptui.py +58 -0
  628. angr/procedures/definitions/win32_cryptxml.py +76 -0
  629. angr/procedures/definitions/win32_cscapi.py +46 -0
  630. angr/procedures/definitions/win32_d2d1.py +64 -0
  631. angr/procedures/definitions/win32_d3d10.py +92 -0
  632. angr/procedures/definitions/win32_d3d10_1.py +42 -0
  633. angr/procedures/definitions/win32_d3d11.py +44 -0
  634. angr/procedures/definitions/win32_d3d12.py +54 -0
  635. angr/procedures/definitions/win32_d3d9.py +60 -0
  636. angr/procedures/definitions/win32_d3dcompiler_47.py +90 -0
  637. angr/procedures/definitions/win32_d3dcsx.py +56 -0
  638. angr/procedures/definitions/win32_davclnt.py +74 -0
  639. angr/procedures/definitions/win32_dbgeng.py +46 -0
  640. angr/procedures/definitions/win32_dbghelp.py +476 -0
  641. angr/procedures/definitions/win32_dbgmodel.py +40 -0
  642. angr/procedures/definitions/win32_dciman32.py +78 -0
  643. angr/procedures/definitions/win32_dcomp.py +62 -0
  644. angr/procedures/definitions/win32_ddraw.py +52 -0
  645. angr/procedures/definitions/win32_deviceaccess.py +40 -0
  646. angr/procedures/definitions/win32_dflayout.py +40 -0
  647. angr/procedures/definitions/win32_dhcpcsvc.py +68 -0
  648. angr/procedures/definitions/win32_dhcpcsvc6.py +50 -0
  649. angr/procedures/definitions/win32_dhcpsapi.py +430 -0
  650. angr/procedures/definitions/win32_diagnosticdataquery.py +108 -0
  651. angr/procedures/definitions/win32_dinput8.py +40 -0
  652. angr/procedures/definitions/win32_directml.py +42 -0
  653. angr/procedures/definitions/win32_dmprocessxmlfiltered.py +40 -0
  654. angr/procedures/definitions/win32_dnsapi.py +166 -0
  655. angr/procedures/definitions/win32_drt.py +70 -0
  656. angr/procedures/definitions/win32_drtprov.py +56 -0
  657. angr/procedures/definitions/win32_drttransport.py +42 -0
  658. angr/procedures/definitions/win32_dsound.py +58 -0
  659. angr/procedures/definitions/win32_dsparse.py +76 -0
  660. angr/procedures/definitions/win32_dsprop.py +52 -0
  661. angr/procedures/definitions/win32_dssec.py +46 -0
  662. angr/procedures/definitions/win32_dsuiext.py +46 -0
  663. angr/procedures/definitions/win32_dwmapi.py +100 -0
  664. angr/procedures/definitions/win32_dwrite.py +40 -0
  665. angr/procedures/definitions/win32_dxcompiler.py +42 -0
  666. angr/procedures/definitions/win32_dxcore.py +40 -0
  667. angr/procedures/definitions/win32_dxgi.py +50 -0
  668. angr/procedures/definitions/win32_dxva2.py +114 -0
  669. angr/procedures/definitions/win32_eappcfg.py +66 -0
  670. angr/procedures/definitions/win32_eappprxy.py +74 -0
  671. angr/procedures/definitions/win32_efswrt.py +42 -0
  672. angr/procedures/definitions/win32_elscore.py +48 -0
  673. angr/procedures/definitions/win32_esent.py +496 -0
  674. angr/procedures/definitions/win32_evr.py +52 -0
  675. angr/procedures/definitions/win32_faultrep.py +46 -0
  676. angr/procedures/definitions/win32_fhsvcctl.py +52 -0
  677. angr/procedures/definitions/win32_firewallapi.py +44 -0
  678. angr/procedures/definitions/win32_fltlib.py +94 -0
  679. angr/procedures/definitions/win32_fontsub.py +42 -0
  680. angr/procedures/definitions/win32_forceinline.py +44 -0
  681. angr/procedures/definitions/win32_fwpuclnt.py +422 -0
  682. angr/procedures/definitions/win32_fxsutility.py +42 -0
  683. angr/procedures/definitions/win32_gdi32.py +900 -0
  684. angr/procedures/definitions/win32_gdiplus.py +1296 -0
  685. angr/procedures/definitions/win32_glu32.py +142 -0
  686. angr/procedures/definitions/win32_gpedit.py +50 -0
  687. angr/procedures/definitions/win32_hhctrl_ocx.py +42 -0
  688. angr/procedures/definitions/win32_hid.py +128 -0
  689. angr/procedures/definitions/win32_hlink.py +94 -0
  690. angr/procedures/definitions/win32_hrtfapo.py +40 -0
  691. angr/procedures/definitions/win32_httpapi.py +124 -0
  692. angr/procedures/definitions/win32_icm32.py +80 -0
  693. angr/procedures/definitions/win32_icmui.py +42 -0
  694. angr/procedures/definitions/win32_icu.py +2088 -0
  695. angr/procedures/definitions/win32_ieframe.py +96 -0
  696. angr/procedures/definitions/win32_imagehlp.py +90 -0
  697. angr/procedures/definitions/win32_imgutil.py +56 -0
  698. angr/procedures/definitions/win32_imm32.py +202 -0
  699. angr/procedures/definitions/win32_infocardapi.py +72 -0
  700. angr/procedures/definitions/win32_inkobjcore.py +92 -0
  701. angr/procedures/definitions/win32_iphlpapi.py +440 -0
  702. angr/procedures/definitions/win32_iscsidsc.py +196 -0
  703. angr/procedures/definitions/win32_isolatedwindowsenvironmentutils.py +42 -0
  704. angr/procedures/definitions/win32_kernel32.py +3199 -0
  705. angr/procedures/definitions/win32_kernelbase.py +50 -0
  706. angr/procedures/definitions/win32_keycredmgr.py +46 -0
  707. angr/procedures/definitions/win32_ksproxy_ax.py +50 -0
  708. angr/procedures/definitions/win32_ksuser.py +54 -0
  709. angr/procedures/definitions/win32_ktmw32.py +116 -0
  710. angr/procedures/definitions/win32_licenseprotection.py +42 -0
  711. angr/procedures/definitions/win32_loadperf.py +62 -0
  712. angr/procedures/definitions/win32_magnification.py +76 -0
  713. angr/procedures/definitions/win32_mapi32.py +170 -0
  714. angr/procedures/definitions/win32_mdmlocalmanagement.py +44 -0
  715. angr/procedures/definitions/win32_mdmregistration.py +68 -0
  716. angr/procedures/definitions/win32_mf.py +162 -0
  717. angr/procedures/definitions/win32_mfcore.py +42 -0
  718. angr/procedures/definitions/win32_mfplat.py +328 -0
  719. angr/procedures/definitions/win32_mfplay.py +40 -0
  720. angr/procedures/definitions/win32_mfreadwrite.py +48 -0
  721. angr/procedures/definitions/win32_mfsensorgroup.py +58 -0
  722. angr/procedures/definitions/win32_mfsrcsnk.py +42 -0
  723. angr/procedures/definitions/win32_mgmtapi.py +56 -0
  724. angr/procedures/definitions/win32_mi.py +40 -0
  725. angr/procedures/definitions/win32_mmdevapi.py +40 -0
  726. angr/procedures/definitions/win32_mpr.py +132 -0
  727. angr/procedures/definitions/win32_mprapi.py +262 -0
  728. angr/procedures/definitions/win32_mqrt.py +106 -0
  729. angr/procedures/definitions/win32_mrmsupport.py +92 -0
  730. angr/procedures/definitions/win32_msacm32.py +122 -0
  731. angr/procedures/definitions/win32_msajapi.py +1132 -0
  732. angr/procedures/definitions/win32_mscms.py +196 -0
  733. angr/procedures/definitions/win32_mscoree.py +92 -0
  734. angr/procedures/definitions/win32_msctfmonitor.py +44 -0
  735. angr/procedures/definitions/win32_msdelta.py +70 -0
  736. angr/procedures/definitions/win32_msdmo.py +60 -0
  737. angr/procedures/definitions/win32_msdrm.py +206 -0
  738. angr/procedures/definitions/win32_msi.py +566 -0
  739. angr/procedures/definitions/win32_msimg32.py +44 -0
  740. angr/procedures/definitions/win32_mspatcha.py +70 -0
  741. angr/procedures/definitions/win32_mspatchc.py +56 -0
  742. angr/procedures/definitions/win32_msports.py +52 -0
  743. angr/procedures/definitions/win32_msrating.py +76 -0
  744. angr/procedures/definitions/win32_mssign32.py +58 -0
  745. angr/procedures/definitions/win32_mstask.py +42 -0
  746. angr/procedures/definitions/win32_msvfw32.py +124 -0
  747. angr/procedures/definitions/win32_mswsock.py +70 -0
  748. angr/procedures/definitions/win32_mtxdm.py +40 -0
  749. angr/procedures/definitions/win32_ncrypt.py +116 -0
  750. angr/procedures/definitions/win32_ndfapi.py +70 -0
  751. angr/procedures/definitions/win32_netapi32.py +450 -0
  752. angr/procedures/definitions/win32_netsh.py +54 -0
  753. angr/procedures/definitions/win32_netshell.py +42 -0
  754. angr/procedures/definitions/win32_newdev.py +60 -0
  755. angr/procedures/definitions/win32_ninput.py +98 -0
  756. angr/procedures/definitions/win32_normaliz.py +42 -0
  757. angr/procedures/definitions/win32_ntdll.py +185 -0
  758. angr/procedures/definitions/win32_ntdllk.py +40 -0
  759. angr/procedures/definitions/win32_ntdsapi.py +200 -0
  760. angr/procedures/definitions/win32_ntlanman.py +58 -0
  761. angr/procedures/definitions/win32_odbc32.py +406 -0
  762. angr/procedures/definitions/win32_odbcbcp.py +92 -0
  763. angr/procedures/definitions/win32_ole32.py +672 -0
  764. angr/procedures/definitions/win32_oleacc.py +72 -0
  765. angr/procedures/definitions/win32_oleaut32.py +848 -0
  766. angr/procedures/definitions/win32_oledlg.py +84 -0
  767. angr/procedures/definitions/win32_ondemandconnroutehelper.py +48 -0
  768. angr/procedures/definitions/win32_opengl32.py +748 -0
  769. angr/procedures/definitions/win32_opmxbox.py +44 -0
  770. angr/procedures/definitions/win32_p2p.py +254 -0
  771. angr/procedures/definitions/win32_p2pgraph.py +112 -0
  772. angr/procedures/definitions/win32_pdh.py +234 -0
  773. angr/procedures/definitions/win32_peerdist.py +94 -0
  774. angr/procedures/definitions/win32_powrprof.py +206 -0
  775. angr/procedures/definitions/win32_prntvpt.py +60 -0
  776. angr/procedures/definitions/win32_projectedfslib.py +76 -0
  777. angr/procedures/definitions/win32_propsys.py +474 -0
  778. angr/procedures/definitions/win32_psapi.py +92 -0
  779. angr/procedures/definitions/win32_quartz.py +42 -0
  780. angr/procedures/definitions/win32_query.py +46 -0
  781. angr/procedures/definitions/win32_qwave.py +60 -0
  782. angr/procedures/definitions/win32_rasapi32.py +206 -0
  783. angr/procedures/definitions/win32_rasdlg.py +50 -0
  784. angr/procedures/definitions/win32_resutils.py +278 -0
  785. angr/procedures/definitions/win32_rometadata.py +23 -0
  786. angr/procedures/definitions/win32_rpcns4.py +160 -0
  787. angr/procedures/definitions/win32_rpcproxy.py +46 -0
  788. angr/procedures/definitions/win32_rpcrt4.py +932 -0
  789. angr/procedures/definitions/win32_rstrtmgr.py +60 -0
  790. angr/procedures/definitions/win32_rtm.py +190 -0
  791. angr/procedures/definitions/win32_rtutils.py +120 -0
  792. angr/procedures/definitions/win32_rtworkq.py +104 -0
  793. angr/procedures/definitions/win32_sas.py +40 -0
  794. angr/procedures/definitions/win32_scarddlg.py +48 -0
  795. angr/procedures/definitions/win32_schannel.py +56 -0
  796. angr/procedures/definitions/win32_sechost.py +42 -0
  797. angr/procedures/definitions/win32_secur32.py +216 -0
  798. angr/procedures/definitions/win32_sensapi.py +44 -0
  799. angr/procedures/definitions/win32_sensorsutilsv2.py +118 -0
  800. angr/procedures/definitions/win32_setupapi.py +706 -0
  801. angr/procedures/definitions/win32_sfc.py +50 -0
  802. angr/procedures/definitions/win32_shdocvw.py +44 -0
  803. angr/procedures/definitions/win32_shell32.py +526 -0
  804. angr/procedures/definitions/win32_shlwapi.py +758 -0
  805. angr/procedures/definitions/win32_slc.py +102 -0
  806. angr/procedures/definitions/win32_slcext.py +46 -0
  807. angr/procedures/definitions/win32_slwga.py +40 -0
  808. angr/procedures/definitions/win32_snmpapi.py +90 -0
  809. angr/procedures/definitions/win32_spoolss.py +90 -0
  810. angr/procedures/definitions/win32_srclient.py +40 -0
  811. angr/procedures/definitions/win32_srpapi.py +60 -0
  812. angr/procedures/definitions/win32_sspicli.py +52 -0
  813. angr/procedures/definitions/win32_sti.py +40 -0
  814. angr/procedures/definitions/win32_t2embed.py +66 -0
  815. angr/procedures/definitions/win32_tapi32.py +536 -0
  816. angr/procedures/definitions/win32_tbs.py +66 -0
  817. angr/procedures/definitions/win32_tdh.py +92 -0
  818. angr/procedures/definitions/win32_tokenbinding.py +58 -0
  819. angr/procedures/definitions/win32_traffic.py +78 -0
  820. angr/procedures/definitions/win32_txfw32.py +56 -0
  821. angr/procedures/definitions/win32_ualapi.py +46 -0
  822. angr/procedures/definitions/win32_uiautomationcore.py +234 -0
  823. angr/procedures/definitions/win32_urlmon.py +192 -0
  824. angr/procedures/definitions/win32_user32.py +1565 -0
  825. angr/procedures/definitions/win32_userenv.py +126 -0
  826. angr/procedures/definitions/win32_usp10.py +118 -0
  827. angr/procedures/definitions/win32_uxtheme.py +192 -0
  828. angr/procedures/definitions/win32_verifier.py +40 -0
  829. angr/procedures/definitions/win32_version.py +66 -0
  830. angr/procedures/definitions/win32_vertdll.py +52 -0
  831. angr/procedures/definitions/win32_virtdisk.py +96 -0
  832. angr/procedures/definitions/win32_vmdevicehost.py +64 -0
  833. angr/procedures/definitions/win32_vmsavedstatedumpprovider.py +124 -0
  834. angr/procedures/definitions/win32_vssapi.py +40 -0
  835. angr/procedures/definitions/win32_wcmapi.py +48 -0
  836. angr/procedures/definitions/win32_wdsbp.py +52 -0
  837. angr/procedures/definitions/win32_wdsclientapi.py +112 -0
  838. angr/procedures/definitions/win32_wdsmc.py +50 -0
  839. angr/procedures/definitions/win32_wdspxe.py +100 -0
  840. angr/procedures/definitions/win32_wdstptc.py +64 -0
  841. angr/procedures/definitions/win32_webauthn.py +64 -0
  842. angr/procedures/definitions/win32_webservices.py +424 -0
  843. angr/procedures/definitions/win32_websocket.py +64 -0
  844. angr/procedures/definitions/win32_wecapi.py +68 -0
  845. angr/procedures/definitions/win32_wer.py +80 -0
  846. angr/procedures/definitions/win32_wevtapi.py +108 -0
  847. angr/procedures/definitions/win32_winbio.py +146 -0
  848. angr/procedures/definitions/win32_windows_ai_machinelearning.py +40 -0
  849. angr/procedures/definitions/win32_windows_data_pdf.py +23 -0
  850. angr/procedures/definitions/win32_windows_media_mediacontrol.py +54 -0
  851. angr/procedures/definitions/win32_windows_networking.py +40 -0
  852. angr/procedures/definitions/win32_windows_ui_xaml.py +42 -0
  853. angr/procedures/definitions/win32_windowscodecs.py +56 -0
  854. angr/procedures/definitions/win32_winfax.py +150 -0
  855. angr/procedures/definitions/win32_winhttp.py +150 -0
  856. angr/procedures/definitions/win32_winhvemulation.py +46 -0
  857. angr/procedures/definitions/win32_winhvplatform.py +170 -0
  858. angr/procedures/definitions/win32_wininet.py +630 -0
  859. angr/procedures/definitions/win32_winml.py +40 -0
  860. angr/procedures/definitions/win32_winmm.py +390 -0
  861. angr/procedures/definitions/win32_winscard.py +178 -0
  862. angr/procedures/definitions/win32_winspool.py +363 -0
  863. angr/procedures/definitions/win32_winspool_drv.py +382 -0
  864. angr/procedures/definitions/win32_wintrust.py +158 -0
  865. angr/procedures/definitions/win32_winusb.py +106 -0
  866. angr/procedures/definitions/win32_wlanapi.py +158 -0
  867. angr/procedures/definitions/win32_wlanui.py +40 -0
  868. angr/procedures/definitions/win32_wldap32.py +524 -0
  869. angr/procedures/definitions/win32_wldp.py +56 -0
  870. angr/procedures/definitions/win32_wmvcore.py +60 -0
  871. angr/procedures/definitions/win32_wnvapi.py +42 -0
  872. angr/procedures/definitions/win32_wofutil.py +60 -0
  873. angr/procedures/definitions/win32_ws2_32.py +358 -0
  874. angr/procedures/definitions/win32_wscapi.py +50 -0
  875. angr/procedures/definitions/win32_wsclient.py +44 -0
  876. angr/procedures/definitions/win32_wsdapi.py +102 -0
  877. angr/procedures/definitions/win32_wsmsvc.py +104 -0
  878. angr/procedures/definitions/win32_wsnmp32.py +136 -0
  879. angr/procedures/definitions/win32_wtsapi32.py +164 -0
  880. angr/procedures/definitions/win32_xaudio2_8.py +46 -0
  881. angr/procedures/definitions/win32_xinput1_4.py +52 -0
  882. angr/procedures/definitions/win32_xinputuap.py +35 -0
  883. angr/procedures/definitions/win32_xmllite.py +50 -0
  884. angr/procedures/definitions/win32_xolehlp.py +46 -0
  885. angr/procedures/definitions/win32_xpsprint.py +42 -0
  886. angr/procedures/glibc/__ctype_b_loc.py +22 -0
  887. angr/procedures/glibc/__ctype_tolower_loc.py +22 -0
  888. angr/procedures/glibc/__ctype_toupper_loc.py +22 -0
  889. angr/procedures/glibc/__errno_location.py +6 -0
  890. angr/procedures/glibc/__init__.py +3 -0
  891. angr/procedures/glibc/__libc_init.py +36 -0
  892. angr/procedures/glibc/__libc_start_main.py +294 -0
  893. angr/procedures/glibc/dynamic_loading.py +19 -0
  894. angr/procedures/glibc/scanf.py +10 -0
  895. angr/procedures/glibc/sscanf.py +5 -0
  896. angr/procedures/gnulib/__init__.py +3 -0
  897. angr/procedures/gnulib/xalloc_die.py +13 -0
  898. angr/procedures/gnulib/xstrtol_fatal.py +13 -0
  899. angr/procedures/java/__init__.py +38 -0
  900. angr/procedures/java/unconstrained.py +64 -0
  901. angr/procedures/java_io/__init__.py +0 -0
  902. angr/procedures/java_io/read.py +11 -0
  903. angr/procedures/java_io/write.py +16 -0
  904. angr/procedures/java_jni/__init__.py +475 -0
  905. angr/procedures/java_jni/array_operations.py +309 -0
  906. angr/procedures/java_jni/class_and_interface_operations.py +31 -0
  907. angr/procedures/java_jni/field_access.py +176 -0
  908. angr/procedures/java_jni/global_and_local_refs.py +56 -0
  909. angr/procedures/java_jni/method_calls.py +364 -0
  910. angr/procedures/java_jni/not_implemented.py +25 -0
  911. angr/procedures/java_jni/object_operations.py +95 -0
  912. angr/procedures/java_jni/string_operations.py +86 -0
  913. angr/procedures/java_jni/version_information.py +11 -0
  914. angr/procedures/java_lang/__init__.py +0 -0
  915. angr/procedures/java_lang/character.py +31 -0
  916. angr/procedures/java_lang/double.py +24 -0
  917. angr/procedures/java_lang/exit.py +12 -0
  918. angr/procedures/java_lang/getsimplename.py +15 -0
  919. angr/procedures/java_lang/integer.py +42 -0
  920. angr/procedures/java_lang/load_library.py +8 -0
  921. angr/procedures/java_lang/math.py +14 -0
  922. angr/procedures/java_lang/string.py +78 -0
  923. angr/procedures/java_lang/stringbuilder.py +43 -0
  924. angr/procedures/java_lang/system.py +17 -0
  925. angr/procedures/java_util/__init__.py +0 -0
  926. angr/procedures/java_util/collection.py +34 -0
  927. angr/procedures/java_util/iterator.py +45 -0
  928. angr/procedures/java_util/list.py +98 -0
  929. angr/procedures/java_util/map.py +132 -0
  930. angr/procedures/java_util/random.py +11 -0
  931. angr/procedures/java_util/scanner_nextline.py +22 -0
  932. angr/procedures/libc/__init__.py +3 -0
  933. angr/procedures/libc/abort.py +8 -0
  934. angr/procedures/libc/access.py +10 -0
  935. angr/procedures/libc/atoi.py +14 -0
  936. angr/procedures/libc/atol.py +12 -0
  937. angr/procedures/libc/calloc.py +7 -0
  938. angr/procedures/libc/closelog.py +9 -0
  939. angr/procedures/libc/err.py +13 -0
  940. angr/procedures/libc/error.py +55 -0
  941. angr/procedures/libc/exit.py +10 -0
  942. angr/procedures/libc/fclose.py +20 -0
  943. angr/procedures/libc/feof.py +19 -0
  944. angr/procedures/libc/fflush.py +15 -0
  945. angr/procedures/libc/fgetc.py +24 -0
  946. angr/procedures/libc/fgets.py +68 -0
  947. angr/procedures/libc/fopen.py +64 -0
  948. angr/procedures/libc/fprintf.py +24 -0
  949. angr/procedures/libc/fputc.py +22 -0
  950. angr/procedures/libc/fputs.py +23 -0
  951. angr/procedures/libc/fread.py +22 -0
  952. angr/procedures/libc/free.py +8 -0
  953. angr/procedures/libc/fscanf.py +20 -0
  954. angr/procedures/libc/fseek.py +32 -0
  955. angr/procedures/libc/ftell.py +21 -0
  956. angr/procedures/libc/fwrite.py +18 -0
  957. angr/procedures/libc/getchar.py +13 -0
  958. angr/procedures/libc/getdelim.py +96 -0
  959. angr/procedures/libc/getegid.py +7 -0
  960. angr/procedures/libc/geteuid.py +7 -0
  961. angr/procedures/libc/getgid.py +7 -0
  962. angr/procedures/libc/gets.py +66 -0
  963. angr/procedures/libc/getuid.py +7 -0
  964. angr/procedures/libc/malloc.py +11 -0
  965. angr/procedures/libc/memcmp.py +69 -0
  966. angr/procedures/libc/memcpy.py +37 -0
  967. angr/procedures/libc/memset.py +69 -0
  968. angr/procedures/libc/openlog.py +9 -0
  969. angr/procedures/libc/perror.py +12 -0
  970. angr/procedures/libc/printf.py +33 -0
  971. angr/procedures/libc/putchar.py +12 -0
  972. angr/procedures/libc/puts.py +16 -0
  973. angr/procedures/libc/rand.py +7 -0
  974. angr/procedures/libc/realloc.py +7 -0
  975. angr/procedures/libc/rewind.py +11 -0
  976. angr/procedures/libc/scanf.py +20 -0
  977. angr/procedures/libc/setbuf.py +8 -0
  978. angr/procedures/libc/setvbuf.py +6 -0
  979. angr/procedures/libc/snprintf.py +33 -0
  980. angr/procedures/libc/sprintf.py +22 -0
  981. angr/procedures/libc/srand.py +6 -0
  982. angr/procedures/libc/sscanf.py +13 -0
  983. angr/procedures/libc/stpcpy.py +18 -0
  984. angr/procedures/libc/strcat.py +13 -0
  985. angr/procedures/libc/strchr.py +44 -0
  986. angr/procedures/libc/strcmp.py +28 -0
  987. angr/procedures/libc/strcpy.py +13 -0
  988. angr/procedures/libc/strlen.py +99 -0
  989. angr/procedures/libc/strncat.py +18 -0
  990. angr/procedures/libc/strncmp.py +180 -0
  991. angr/procedures/libc/strncpy.py +18 -0
  992. angr/procedures/libc/strnlen.py +13 -0
  993. angr/procedures/libc/strstr.py +94 -0
  994. angr/procedures/libc/strtol.py +263 -0
  995. angr/procedures/libc/strtoul.py +9 -0
  996. angr/procedures/libc/system.py +12 -0
  997. angr/procedures/libc/time.py +9 -0
  998. angr/procedures/libc/tmpnam.py +19 -0
  999. angr/procedures/libc/tolower.py +7 -0
  1000. angr/procedures/libc/toupper.py +7 -0
  1001. angr/procedures/libc/ungetc.py +19 -0
  1002. angr/procedures/libc/vsnprintf.py +16 -0
  1003. angr/procedures/libc/wchar.py +15 -0
  1004. angr/procedures/libstdcpp/__init__.py +0 -0
  1005. angr/procedures/libstdcpp/_unwind_resume.py +10 -0
  1006. angr/procedures/libstdcpp/std____throw_bad_alloc.py +12 -0
  1007. angr/procedures/libstdcpp/std____throw_bad_cast.py +12 -0
  1008. angr/procedures/libstdcpp/std____throw_length_error.py +12 -0
  1009. angr/procedures/libstdcpp/std____throw_logic_error.py +12 -0
  1010. angr/procedures/libstdcpp/std__terminate.py +12 -0
  1011. angr/procedures/linux_kernel/__init__.py +3 -0
  1012. angr/procedures/linux_kernel/access.py +17 -0
  1013. angr/procedures/linux_kernel/arch_prctl.py +33 -0
  1014. angr/procedures/linux_kernel/arm_user_helpers.py +58 -0
  1015. angr/procedures/linux_kernel/brk.py +17 -0
  1016. angr/procedures/linux_kernel/cwd.py +27 -0
  1017. angr/procedures/linux_kernel/fstat.py +137 -0
  1018. angr/procedures/linux_kernel/fstat64.py +169 -0
  1019. angr/procedures/linux_kernel/futex.py +17 -0
  1020. angr/procedures/linux_kernel/getegid.py +16 -0
  1021. angr/procedures/linux_kernel/geteuid.py +16 -0
  1022. angr/procedures/linux_kernel/getgid.py +16 -0
  1023. angr/procedures/linux_kernel/getpid.py +13 -0
  1024. angr/procedures/linux_kernel/getrlimit.py +24 -0
  1025. angr/procedures/linux_kernel/gettid.py +8 -0
  1026. angr/procedures/linux_kernel/getuid.py +16 -0
  1027. angr/procedures/linux_kernel/iovec.py +43 -0
  1028. angr/procedures/linux_kernel/lseek.py +39 -0
  1029. angr/procedures/linux_kernel/mmap.py +15 -0
  1030. angr/procedures/linux_kernel/mprotect.py +41 -0
  1031. angr/procedures/linux_kernel/munmap.py +7 -0
  1032. angr/procedures/linux_kernel/openat.py +28 -0
  1033. angr/procedures/linux_kernel/set_tid_address.py +7 -0
  1034. angr/procedures/linux_kernel/sigaction.py +16 -0
  1035. angr/procedures/linux_kernel/sigprocmask.py +20 -0
  1036. angr/procedures/linux_kernel/stat.py +22 -0
  1037. angr/procedures/linux_kernel/sysinfo.py +58 -0
  1038. angr/procedures/linux_kernel/tgkill.py +7 -0
  1039. angr/procedures/linux_kernel/time.py +30 -0
  1040. angr/procedures/linux_kernel/uid.py +29 -0
  1041. angr/procedures/linux_kernel/uname.py +28 -0
  1042. angr/procedures/linux_kernel/unlink.py +22 -0
  1043. angr/procedures/linux_kernel/vsyscall.py +15 -0
  1044. angr/procedures/linux_loader/__init__.py +3 -0
  1045. angr/procedures/linux_loader/_dl_initial_error_catch_tsd.py +6 -0
  1046. angr/procedures/linux_loader/_dl_rtld_lock.py +14 -0
  1047. angr/procedures/linux_loader/sim_loader.py +53 -0
  1048. angr/procedures/linux_loader/tls.py +40 -0
  1049. angr/procedures/msvcr/__getmainargs.py +15 -0
  1050. angr/procedures/msvcr/__init__.py +4 -0
  1051. angr/procedures/msvcr/_initterm.py +37 -0
  1052. angr/procedures/msvcr/fmode.py +28 -0
  1053. angr/procedures/ntdll/__init__.py +0 -0
  1054. angr/procedures/ntdll/exceptions.py +57 -0
  1055. angr/procedures/posix/__init__.py +3 -0
  1056. angr/procedures/posix/accept.py +29 -0
  1057. angr/procedures/posix/bind.py +12 -0
  1058. angr/procedures/posix/bzero.py +6 -0
  1059. angr/procedures/posix/chroot.py +26 -0
  1060. angr/procedures/posix/close.py +9 -0
  1061. angr/procedures/posix/closedir.py +6 -0
  1062. angr/procedures/posix/dup.py +55 -0
  1063. angr/procedures/posix/fcntl.py +9 -0
  1064. angr/procedures/posix/fdopen.py +77 -0
  1065. angr/procedures/posix/fileno.py +17 -0
  1066. angr/procedures/posix/fork.py +10 -0
  1067. angr/procedures/posix/getenv.py +34 -0
  1068. angr/procedures/posix/gethostbyname.py +42 -0
  1069. angr/procedures/posix/getpass.py +18 -0
  1070. angr/procedures/posix/getsockopt.py +10 -0
  1071. angr/procedures/posix/htonl.py +11 -0
  1072. angr/procedures/posix/htons.py +11 -0
  1073. angr/procedures/posix/inet_ntoa.py +61 -0
  1074. angr/procedures/posix/listen.py +12 -0
  1075. angr/procedures/posix/mmap.py +140 -0
  1076. angr/procedures/posix/open.py +17 -0
  1077. angr/procedures/posix/opendir.py +9 -0
  1078. angr/procedures/posix/poll.py +54 -0
  1079. angr/procedures/posix/pread64.py +45 -0
  1080. angr/procedures/posix/pthread.py +87 -0
  1081. angr/procedures/posix/pwrite64.py +45 -0
  1082. angr/procedures/posix/read.py +12 -0
  1083. angr/procedures/posix/readdir.py +59 -0
  1084. angr/procedures/posix/recv.py +12 -0
  1085. angr/procedures/posix/recvfrom.py +12 -0
  1086. angr/procedures/posix/select.py +46 -0
  1087. angr/procedures/posix/send.py +22 -0
  1088. angr/procedures/posix/setsockopt.py +8 -0
  1089. angr/procedures/posix/sigaction.py +20 -0
  1090. angr/procedures/posix/sim_time.py +45 -0
  1091. angr/procedures/posix/sleep.py +7 -0
  1092. angr/procedures/posix/socket.py +18 -0
  1093. angr/procedures/posix/strcasecmp.py +23 -0
  1094. angr/procedures/posix/strdup.py +17 -0
  1095. angr/procedures/posix/strtok_r.py +65 -0
  1096. angr/procedures/posix/syslog.py +15 -0
  1097. angr/procedures/posix/tz.py +8 -0
  1098. angr/procedures/posix/unlink.py +10 -0
  1099. angr/procedures/posix/usleep.py +7 -0
  1100. angr/procedures/posix/write.py +12 -0
  1101. angr/procedures/procedure_dict.py +48 -0
  1102. angr/procedures/stubs/CallReturn.py +12 -0
  1103. angr/procedures/stubs/NoReturnUnconstrained.py +12 -0
  1104. angr/procedures/stubs/Nop.py +6 -0
  1105. angr/procedures/stubs/PathTerminator.py +8 -0
  1106. angr/procedures/stubs/Redirect.py +15 -0
  1107. angr/procedures/stubs/ReturnChar.py +10 -0
  1108. angr/procedures/stubs/ReturnUnconstrained.py +24 -0
  1109. angr/procedures/stubs/UnresolvableCallTarget.py +8 -0
  1110. angr/procedures/stubs/UnresolvableJumpTarget.py +8 -0
  1111. angr/procedures/stubs/UserHook.py +15 -0
  1112. angr/procedures/stubs/__init__.py +3 -0
  1113. angr/procedures/stubs/b64_decode.py +12 -0
  1114. angr/procedures/stubs/caller.py +13 -0
  1115. angr/procedures/stubs/crazy_scanf.py +17 -0
  1116. angr/procedures/stubs/format_parser.py +677 -0
  1117. angr/procedures/stubs/syscall_stub.py +26 -0
  1118. angr/procedures/testing/__init__.py +3 -0
  1119. angr/procedures/testing/manyargs.py +8 -0
  1120. angr/procedures/testing/retreg.py +8 -0
  1121. angr/procedures/tracer/__init__.py +4 -0
  1122. angr/procedures/tracer/random.py +8 -0
  1123. angr/procedures/tracer/receive.py +21 -0
  1124. angr/procedures/tracer/transmit.py +24 -0
  1125. angr/procedures/uclibc/__init__.py +3 -0
  1126. angr/procedures/uclibc/__uClibc_main.py +9 -0
  1127. angr/procedures/win32/EncodePointer.py +6 -0
  1128. angr/procedures/win32/ExitProcess.py +8 -0
  1129. angr/procedures/win32/GetCommandLine.py +11 -0
  1130. angr/procedures/win32/GetCurrentProcessId.py +6 -0
  1131. angr/procedures/win32/GetCurrentThreadId.py +6 -0
  1132. angr/procedures/win32/GetLastInputInfo.py +37 -0
  1133. angr/procedures/win32/GetModuleHandle.py +30 -0
  1134. angr/procedures/win32/GetProcessAffinityMask.py +34 -0
  1135. angr/procedures/win32/InterlockedExchange.py +14 -0
  1136. angr/procedures/win32/IsProcessorFeaturePresent.py +6 -0
  1137. angr/procedures/win32/VirtualAlloc.py +113 -0
  1138. angr/procedures/win32/VirtualProtect.py +59 -0
  1139. angr/procedures/win32/__init__.py +3 -0
  1140. angr/procedures/win32/critical_section.py +11 -0
  1141. angr/procedures/win32/dynamic_loading.py +103 -0
  1142. angr/procedures/win32/file_handles.py +47 -0
  1143. angr/procedures/win32/gethostbyname.py +10 -0
  1144. angr/procedures/win32/heap.py +42 -0
  1145. angr/procedures/win32/is_bad_ptr.py +25 -0
  1146. angr/procedures/win32/local_storage.py +85 -0
  1147. angr/procedures/win32/mutex.py +10 -0
  1148. angr/procedures/win32/sim_time.py +135 -0
  1149. angr/procedures/win32/system_paths.py +34 -0
  1150. angr/procedures/win32_kernel/ExAllocatePool.py +12 -0
  1151. angr/procedures/win32_kernel/ExFreePoolWithTag.py +7 -0
  1152. angr/procedures/win32_kernel/__init__.py +3 -0
  1153. angr/procedures/win_user32/__init__.py +0 -0
  1154. angr/procedures/win_user32/chars.py +12 -0
  1155. angr/procedures/win_user32/keyboard.py +13 -0
  1156. angr/procedures/win_user32/messagebox.py +49 -0
  1157. angr/project.py +834 -0
  1158. angr/protos/__init__.py +13 -0
  1159. angr/protos/cfg_pb2.py +31 -0
  1160. angr/protos/function_pb2.py +37 -0
  1161. angr/protos/primitives_pb2.py +124 -0
  1162. angr/protos/variables_pb2.py +126 -0
  1163. angr/protos/xrefs_pb2.py +34 -0
  1164. angr/py.typed +1 -0
  1165. angr/serializable.py +63 -0
  1166. angr/service.py +35 -0
  1167. angr/sim_manager.py +971 -0
  1168. angr/sim_options.py +444 -0
  1169. angr/sim_procedure.py +606 -0
  1170. angr/sim_state.py +1003 -0
  1171. angr/sim_state_options.py +409 -0
  1172. angr/sim_type.py +3372 -0
  1173. angr/sim_variable.py +562 -0
  1174. angr/simos/__init__.py +31 -0
  1175. angr/simos/cgc.py +152 -0
  1176. angr/simos/javavm.py +471 -0
  1177. angr/simos/linux.py +519 -0
  1178. angr/simos/simos.py +450 -0
  1179. angr/simos/snimmuc_nxp.py +152 -0
  1180. angr/simos/userland.py +163 -0
  1181. angr/simos/windows.py +562 -0
  1182. angr/slicer.py +353 -0
  1183. angr/state_hierarchy.py +262 -0
  1184. angr/state_plugins/__init__.py +29 -0
  1185. angr/state_plugins/callstack.py +404 -0
  1186. angr/state_plugins/cgc.py +153 -0
  1187. angr/state_plugins/concrete.py +297 -0
  1188. angr/state_plugins/debug_variables.py +194 -0
  1189. angr/state_plugins/filesystem.py +469 -0
  1190. angr/state_plugins/gdb.py +146 -0
  1191. angr/state_plugins/globals.py +62 -0
  1192. angr/state_plugins/heap/__init__.py +5 -0
  1193. angr/state_plugins/heap/heap_base.py +126 -0
  1194. angr/state_plugins/heap/heap_brk.py +134 -0
  1195. angr/state_plugins/heap/heap_freelist.py +210 -0
  1196. angr/state_plugins/heap/heap_libc.py +45 -0
  1197. angr/state_plugins/heap/heap_ptmalloc.py +646 -0
  1198. angr/state_plugins/heap/utils.py +21 -0
  1199. angr/state_plugins/history.py +548 -0
  1200. angr/state_plugins/inspect.py +376 -0
  1201. angr/state_plugins/javavm_classloader.py +133 -0
  1202. angr/state_plugins/jni_references.py +93 -0
  1203. angr/state_plugins/libc.py +1263 -0
  1204. angr/state_plugins/light_registers.py +170 -0
  1205. angr/state_plugins/log.py +85 -0
  1206. angr/state_plugins/loop_data.py +92 -0
  1207. angr/state_plugins/plugin.py +155 -0
  1208. angr/state_plugins/posix.py +709 -0
  1209. angr/state_plugins/preconstrainer.py +195 -0
  1210. angr/state_plugins/scratch.py +175 -0
  1211. angr/state_plugins/sim_action.py +334 -0
  1212. angr/state_plugins/sim_action_object.py +148 -0
  1213. angr/state_plugins/sim_event.py +58 -0
  1214. angr/state_plugins/solver.py +1129 -0
  1215. angr/state_plugins/symbolizer.py +292 -0
  1216. angr/state_plugins/trace_additions.py +752 -0
  1217. angr/state_plugins/uc_manager.py +85 -0
  1218. angr/state_plugins/unicorn_engine.py +1899 -0
  1219. angr/state_plugins/view.py +341 -0
  1220. angr/storage/__init__.py +9 -0
  1221. angr/storage/file.py +1219 -0
  1222. angr/storage/memory_mixins/__init__.py +393 -0
  1223. angr/storage/memory_mixins/__init__.pyi +49 -0
  1224. angr/storage/memory_mixins/actions_mixin.py +69 -0
  1225. angr/storage/memory_mixins/address_concretization_mixin.py +388 -0
  1226. angr/storage/memory_mixins/bvv_conversion_mixin.py +74 -0
  1227. angr/storage/memory_mixins/clouseau_mixin.py +131 -0
  1228. angr/storage/memory_mixins/conditional_store_mixin.py +24 -0
  1229. angr/storage/memory_mixins/convenient_mappings_mixin.py +257 -0
  1230. angr/storage/memory_mixins/default_filler_mixin.py +146 -0
  1231. angr/storage/memory_mixins/dirty_addrs_mixin.py +9 -0
  1232. angr/storage/memory_mixins/hex_dumper_mixin.py +85 -0
  1233. angr/storage/memory_mixins/javavm_memory/__init__.py +1 -0
  1234. angr/storage/memory_mixins/javavm_memory/javavm_memory_mixin.py +394 -0
  1235. angr/storage/memory_mixins/keyvalue_memory/__init__.py +1 -0
  1236. angr/storage/memory_mixins/keyvalue_memory/keyvalue_memory_mixin.py +36 -0
  1237. angr/storage/memory_mixins/label_merger_mixin.py +31 -0
  1238. angr/storage/memory_mixins/multi_value_merger_mixin.py +68 -0
  1239. angr/storage/memory_mixins/name_resolution_mixin.py +70 -0
  1240. angr/storage/memory_mixins/paged_memory/__init__.py +0 -0
  1241. angr/storage/memory_mixins/paged_memory/page_backer_mixins.py +266 -0
  1242. angr/storage/memory_mixins/paged_memory/paged_memory_mixin.py +750 -0
  1243. angr/storage/memory_mixins/paged_memory/paged_memory_multivalue_mixin.py +63 -0
  1244. angr/storage/memory_mixins/paged_memory/pages/__init__.py +33 -0
  1245. angr/storage/memory_mixins/paged_memory/pages/cooperation.py +330 -0
  1246. angr/storage/memory_mixins/paged_memory/pages/history_tracking_mixin.py +87 -0
  1247. angr/storage/memory_mixins/paged_memory/pages/ispo_mixin.py +53 -0
  1248. angr/storage/memory_mixins/paged_memory/pages/list_page.py +346 -0
  1249. angr/storage/memory_mixins/paged_memory/pages/multi_values.py +290 -0
  1250. angr/storage/memory_mixins/paged_memory/pages/mv_list_page.py +434 -0
  1251. angr/storage/memory_mixins/paged_memory/pages/permissions_mixin.py +33 -0
  1252. angr/storage/memory_mixins/paged_memory/pages/refcount_mixin.py +51 -0
  1253. angr/storage/memory_mixins/paged_memory/pages/ultra_page.py +468 -0
  1254. angr/storage/memory_mixins/paged_memory/privileged_mixin.py +36 -0
  1255. angr/storage/memory_mixins/paged_memory/stack_allocation_mixin.py +73 -0
  1256. angr/storage/memory_mixins/regioned_memory/__init__.py +6 -0
  1257. angr/storage/memory_mixins/regioned_memory/abstract_address_descriptor.py +35 -0
  1258. angr/storage/memory_mixins/regioned_memory/abstract_merger_mixin.py +43 -0
  1259. angr/storage/memory_mixins/regioned_memory/region_category_mixin.py +7 -0
  1260. angr/storage/memory_mixins/regioned_memory/region_data.py +245 -0
  1261. angr/storage/memory_mixins/regioned_memory/region_meta_mixin.py +125 -0
  1262. angr/storage/memory_mixins/regioned_memory/regioned_address_concretization_mixin.py +118 -0
  1263. angr/storage/memory_mixins/regioned_memory/regioned_memory_mixin.py +462 -0
  1264. angr/storage/memory_mixins/regioned_memory/static_find_mixin.py +70 -0
  1265. angr/storage/memory_mixins/simple_interface_mixin.py +73 -0
  1266. angr/storage/memory_mixins/simplification_mixin.py +13 -0
  1267. angr/storage/memory_mixins/size_resolution_mixin.py +140 -0
  1268. angr/storage/memory_mixins/slotted_memory.py +140 -0
  1269. angr/storage/memory_mixins/smart_find_mixin.py +159 -0
  1270. angr/storage/memory_mixins/symbolic_merger_mixin.py +12 -0
  1271. angr/storage/memory_mixins/top_merger_mixin.py +24 -0
  1272. angr/storage/memory_mixins/underconstrained_mixin.py +67 -0
  1273. angr/storage/memory_mixins/unwrapper_mixin.py +26 -0
  1274. angr/storage/memory_object.py +194 -0
  1275. angr/storage/pcap.py +65 -0
  1276. angr/tablespecs.py +90 -0
  1277. angr/utils/__init__.py +33 -0
  1278. angr/utils/algo.py +33 -0
  1279. angr/utils/constants.py +7 -0
  1280. angr/utils/cowdict.py +64 -0
  1281. angr/utils/dynamic_dictlist.py +92 -0
  1282. angr/utils/enums_conv.py +80 -0
  1283. angr/utils/env.py +11 -0
  1284. angr/utils/formatting.py +124 -0
  1285. angr/utils/funcid.py +133 -0
  1286. angr/utils/graph.py +822 -0
  1287. angr/utils/lazy_import.py +12 -0
  1288. angr/utils/library.py +214 -0
  1289. angr/utils/loader.py +55 -0
  1290. angr/utils/mp.py +64 -0
  1291. angr/utils/segment_list.py +558 -0
  1292. angr/utils/timing.py +45 -0
  1293. angr/utils/typing.py +17 -0
  1294. angr/vaults.py +370 -0
  1295. angr-9.2.103.dist-info/LICENSE +24 -0
  1296. angr-9.2.103.dist-info/METADATA +119 -0
  1297. angr-9.2.103.dist-info/RECORD +1300 -0
  1298. angr-9.2.103.dist-info/WHEEL +5 -0
  1299. angr-9.2.103.dist-info/entry_points.txt +2 -0
  1300. angr-9.2.103.dist-info/top_level.txt +1 -0
@@ -0,0 +1,2368 @@
1
+ # pylint:disable=wrong-import-position,wrong-import-order
2
+ import enum
3
+ from typing import TYPE_CHECKING
4
+ from collections.abc import Sequence
5
+ import logging
6
+ import functools
7
+ from collections import defaultdict, OrderedDict
8
+
9
+ import pyvex
10
+ import claripy
11
+ from archinfo.arch_arm import is_arm_arch
12
+
13
+ from .... import sim_options as o
14
+ from .... import BP, BP_BEFORE, BP_AFTER
15
+ from ....misc.ux import once
16
+ from ....code_location import CodeLocation
17
+ from ....concretization_strategies import SimConcretizationStrategyAny
18
+ from ....knowledge_plugins.cfg import IndirectJump, IndirectJumpType
19
+ from ....engines.vex.claripy import ccall
20
+ from ....engines.light import SimEngineLightVEXMixin, SimEngineLight, SpOffset, RegisterOffset
21
+ from ....errors import AngrError, SimError
22
+ from ....blade import Blade
23
+ from ....annocfg import AnnotatedCFG
24
+ from ....exploration_techniques.slicecutor import Slicecutor
25
+ from ....exploration_techniques.local_loop_seer import LocalLoopSeer
26
+ from ....exploration_techniques.explorer import Explorer
27
+ from ....utils.constants import DEFAULT_STATEMENT
28
+ from ...propagator.vex_vars import VEXReg
29
+ from .resolver import IndirectJumpResolver
30
+ from .propagator_utils import PropagatorLoadCallback
31
+
32
+ try:
33
+ from ....engines import pcode
34
+ except ImportError:
35
+ pcode = None
36
+
37
+ if TYPE_CHECKING:
38
+ from angr import SimState
39
+ from angr.knowledge_plugins import Function
40
+
41
+ l = logging.getLogger(name=__name__)
42
+
43
+
44
+ class NotAJumpTableNotification(AngrError):
45
+ """
46
+ Exception raised to indicate this is not (or does not appear to be) a jump table.
47
+ """
48
+
49
+
50
+ class UninitReadMeta:
51
+ """
52
+ Uninitialized read remapping details.
53
+ """
54
+
55
+ uninit_read_base = 0xC000000
56
+
57
+
58
+ class AddressTransformationTypes(int, enum.Enum):
59
+ """
60
+ Address transformation operations.
61
+ """
62
+
63
+ Assignment = 0
64
+ SignedExtension = 1
65
+ UnsignedExtension = 2
66
+ Truncation = 3
67
+ Or1 = 4
68
+ ShiftLeft = 5
69
+ ShiftRight = 6
70
+ Add = 7
71
+ Load = 8
72
+
73
+
74
+ class AddressTransformation:
75
+ """
76
+ Describe and record an address transformation operation.
77
+ """
78
+
79
+ def __init__(self, op: AddressTransformationTypes, operands: list, first_load: bool = False):
80
+ self.op = op
81
+ self.operands = operands
82
+ self.first_load = first_load
83
+
84
+ def __repr__(self):
85
+ return f"<Transformation: {self.op} {self.operands}>"
86
+
87
+
88
+ class AddressOperand:
89
+ """
90
+ The class for the singleton class AddressSingleton. It represents the address being transformed before using as an
91
+ indirect jump target.
92
+ """
93
+
94
+ def __repr__(self):
95
+ return "ADDR"
96
+
97
+
98
+ AddressSingleton = AddressOperand()
99
+
100
+
101
+ class Tmp:
102
+ """
103
+ For modeling Tmp variables.
104
+ """
105
+
106
+ def __init__(self, tmp_idx):
107
+ self.tmp_idx = tmp_idx
108
+
109
+
110
+ class JumpTargetBaseAddr:
111
+ """
112
+ Model for jump targets and their data origin.
113
+ """
114
+
115
+ def __init__(self, stmt_loc, stmt, tmp, base_addr=None, tmp_1=None):
116
+ self.stmt_loc = stmt_loc
117
+ self.stmt = stmt
118
+ self.tmp: int = tmp
119
+ self.tmp_1 = tmp_1
120
+ self.base_addr: int = base_addr
121
+
122
+ assert base_addr is not None or tmp_1 is not None
123
+
124
+ @property
125
+ def base_addr_available(self):
126
+ return self.base_addr is not None
127
+
128
+
129
+ #
130
+ # Constant register resolving support
131
+ #
132
+
133
+
134
+ class ConstantValueManager:
135
+ """
136
+ Manages the loading of registers who hold constant values.
137
+ """
138
+
139
+ __slots__ = (
140
+ "project",
141
+ "kb",
142
+ "func",
143
+ "mapping",
144
+ )
145
+
146
+ def __init__(self, project, kb, func: "Function"):
147
+ self.project = project
148
+ self.kb = kb
149
+ self.func = func
150
+
151
+ self.mapping = None
152
+
153
+ def reg_read_callback(self, state: "SimState"):
154
+ if not self.mapping:
155
+ self._build_mapping()
156
+
157
+ codeloc = CodeLocation(state.scratch.bbl_addr, state.scratch.stmt_idx, ins_addr=state.scratch.ins_addr)
158
+ if codeloc in self.mapping:
159
+ reg_read_offset = state.inspect.reg_read_offset
160
+ if isinstance(reg_read_offset, claripy.ast.BV) and reg_read_offset.op == "BVV":
161
+ reg_read_offset = reg_read_offset.args[0]
162
+ variable = VEXReg(reg_read_offset, state.inspect.reg_read_length)
163
+ if variable in self.mapping[codeloc]:
164
+ state.inspect.reg_read_expr = self.mapping[codeloc][variable]
165
+
166
+ def _build_mapping(self):
167
+ # constant propagation
168
+ l.debug("JumpTable: Propagating for %r.", self.func)
169
+ prop = self.project.analyses[PropagatorAnalysis].prep()(
170
+ func=self.func,
171
+ only_consts=True,
172
+ vex_cross_insn_opt=True,
173
+ load_callback=PropagatorLoadCallback(self.project).propagator_load_callback,
174
+ cache_results=True,
175
+ key_prefix="cfg_intermediate",
176
+ )
177
+ self.mapping = prop.replacements
178
+
179
+
180
+ #
181
+ # Jump table pre-check
182
+ #
183
+
184
+ _x86_ct = ccall.data["X86"]["CondTypes"]
185
+ _amd64_ct = ccall.data["AMD64"]["CondTypes"]
186
+ EXPECTED_COND_TYPES = {
187
+ "X86": {
188
+ _x86_ct["CondB"],
189
+ _x86_ct["CondNB"],
190
+ _x86_ct["CondBE"],
191
+ _x86_ct["CondNBE"],
192
+ _x86_ct["CondL"],
193
+ _x86_ct["CondNL"],
194
+ _x86_ct["CondLE"],
195
+ _x86_ct["CondNLE"],
196
+ },
197
+ "AMD64": {
198
+ _amd64_ct["CondB"],
199
+ _amd64_ct["CondNB"],
200
+ _amd64_ct["CondBE"],
201
+ _amd64_ct["CondNBE"],
202
+ _amd64_ct["CondL"],
203
+ _amd64_ct["CondNL"],
204
+ _amd64_ct["CondLE"],
205
+ _amd64_ct["CondNLE"],
206
+ },
207
+ "ARM": {
208
+ ccall.ARMCondHS,
209
+ ccall.ARMCondLO,
210
+ ccall.ARMCondHI,
211
+ ccall.ARMCondLS,
212
+ ccall.ARMCondGE,
213
+ ccall.ARMCondLT,
214
+ ccall.ARMCondGT,
215
+ ccall.ARMCondLE,
216
+ },
217
+ "AARCH64": {
218
+ ccall.ARM64CondCS,
219
+ ccall.ARM64CondCC,
220
+ ccall.ARM64CondHI,
221
+ ccall.ARM64CondLS,
222
+ ccall.ARM64CondGE,
223
+ ccall.ARM64CondLT,
224
+ ccall.ARM64CondGT,
225
+ ccall.ARM64CondLE,
226
+ },
227
+ }
228
+
229
+
230
+ class JumpTableProcessorState:
231
+ """
232
+ The state used in JumpTableProcessor.
233
+ """
234
+
235
+ __slots__ = (
236
+ "arch",
237
+ "_registers",
238
+ "_stack",
239
+ "_tmpvar_source",
240
+ "is_jumptable",
241
+ "stmts_to_instrument",
242
+ "regs_to_initialize",
243
+ )
244
+
245
+ def __init__(self, arch):
246
+ self.arch = arch
247
+
248
+ self._registers = {}
249
+ self._stack = {}
250
+ self._tmpvar_source = {} # a mapping from temporary variables to their origins
251
+
252
+ self.is_jumptable = None # is the current slice representing a jump table?
253
+ self.stmts_to_instrument = [] # Store/Put statements that we should instrument
254
+ self.regs_to_initialize = [] # registers that we should initialize
255
+
256
+
257
+ class RegOffsetAnnotation(claripy.Annotation):
258
+ """
259
+ Register Offset annotation.
260
+ """
261
+
262
+ __slots__ = ("reg_offset",)
263
+
264
+ def __init__(self, reg_offset: RegisterOffset):
265
+ self.reg_offset = reg_offset
266
+
267
+ @property
268
+ def relocatable(self):
269
+ return False
270
+
271
+ @property
272
+ def eliminatable(self):
273
+ return False
274
+
275
+
276
+ class JumpTableProcessor(
277
+ SimEngineLightVEXMixin,
278
+ SimEngineLight,
279
+ ): # pylint:disable=abstract-method
280
+ """
281
+ Implements a simple and stupid data dependency tracking for stack and register variables.
282
+
283
+ Also determines which statements to instrument during static execution of the slice later. For example, the
284
+ following example is not uncommon in non-optimized binaries::
285
+
286
+ mov [rbp+var_54], 1
287
+ loc_4051a6:
288
+ cmp [rbp+var_54], 6
289
+ ja loc_405412 (default)
290
+ loc_4051b0:
291
+ mov eax, [rbp+var_54]
292
+ mov rax, qword [rax*8+0x223a01]
293
+ jmp rax
294
+
295
+ We want to instrument the first instruction and replace the constant 1 with a symbolic variable, otherwise we will
296
+ not be able to recover all jump targets later in block 0x4051b0.
297
+ """
298
+
299
+ def __init__(self, project, indirect_jump_node_pred_addrs: set[int], bp_sp_diff=0x100):
300
+ super().__init__()
301
+ self.project = project
302
+ self._bp_sp_diff = bp_sp_diff # bp - sp
303
+ self._tsrc = set() # a scratch variable to store source information for values
304
+ self._indirect_jump_node_pred_addrs = indirect_jump_node_pred_addrs
305
+
306
+ self._SPOFFSET_BASE = claripy.BVS("SpOffset", self.project.arch.bits, explicit_name=True)
307
+ self._REGOFFSET_BASE: dict[int, claripy.ast.BV] = {}
308
+
309
+ def _top(self, size: int):
310
+ return None
311
+
312
+ def _is_top(self, expr) -> bool:
313
+ return expr is None
314
+
315
+ @staticmethod
316
+ def _is_spoffset(expr) -> bool:
317
+ return "SpOffset" in expr.variables
318
+
319
+ def _get_spoffset_expr(self, sp_offset: SpOffset) -> claripy.ast.BV:
320
+ v = self._SPOFFSET_BASE.annotate(RegOffsetAnnotation(sp_offset))
321
+ return v
322
+
323
+ @staticmethod
324
+ def _extract_spoffset_from_expr(expr: claripy.ast.Base) -> SpOffset | None:
325
+ if expr.op == "BVS":
326
+ for anno in expr.annotations:
327
+ if isinstance(anno, RegOffsetAnnotation):
328
+ return anno.reg_offset
329
+ elif expr.op == "__add__":
330
+ if len(expr.args) == 1:
331
+ return JumpTableProcessor._extract_spoffset_from_expr(expr.args[0])
332
+ elif len(expr.args) == 2 and expr.args[1].op == "BVV":
333
+ sp_offset = JumpTableProcessor._extract_spoffset_from_expr(expr.args[0])
334
+ if sp_offset is not None:
335
+ delta = expr.args[1].concrete_value
336
+ sp_offset += delta
337
+ return sp_offset
338
+ elif expr.op == "__and__":
339
+ if len(expr.args) == 2 and expr.args[1].op == "BVV":
340
+ # ignore all masking on SpOffsets
341
+ return JumpTableProcessor._extract_spoffset_from_expr(expr.args[0])
342
+ return None
343
+
344
+ @staticmethod
345
+ def _is_registeroffset(expr) -> bool:
346
+ return "RegisterOffset" in expr.variables
347
+
348
+ def _get_regoffset_expr(self, reg_offset: RegisterOffset, bits: int) -> claripy.ast.BV:
349
+ if bits not in self._REGOFFSET_BASE:
350
+ self._REGOFFSET_BASE[bits] = claripy.BVS("RegisterOffset", bits, explicit_name=True)
351
+ v = self._REGOFFSET_BASE[bits].annotate(RegOffsetAnnotation(reg_offset))
352
+ return v
353
+
354
+ @staticmethod
355
+ def _extract_regoffset_from_expr(expr: claripy.ast.Base) -> RegisterOffset | None:
356
+ if expr.op == "BVS":
357
+ for anno in expr.annotations:
358
+ if isinstance(anno, RegOffsetAnnotation):
359
+ return anno.reg_offset
360
+ elif expr.op == "__add__":
361
+ if len(expr.args) == 1:
362
+ return JumpTableProcessor._extract_regoffset_from_expr(expr.args[0])
363
+ elif len(expr.args) == 2 and expr.args[1].op == "BVV":
364
+ reg_offset = JumpTableProcessor._extract_regoffset_from_expr(expr.args[0])
365
+ if reg_offset is not None:
366
+ delta = expr.args[1].concrete_value
367
+ reg_offset += delta
368
+ return reg_offset
369
+ elif expr.op == "__and__":
370
+ if len(expr.args) == 2 and expr.args[1].op == "BVV":
371
+ # ignore all masking on SpOffsets
372
+ return JumpTableProcessor._extract_spoffset_from_expr(expr.args[0])
373
+ return None
374
+
375
+ def _handle_WrTmp(self, stmt):
376
+ self._tsrc = set()
377
+ super()._handle_WrTmp(stmt)
378
+
379
+ if self._tsrc:
380
+ self.state._tmpvar_source[stmt.tmp] = self._tsrc
381
+
382
+ def _handle_Put(self, stmt):
383
+ self._tsrc = set()
384
+ offset = stmt.offset
385
+ data = self._expr(stmt.data)
386
+ if self._tsrc is not None:
387
+ r = (self._tsrc, data)
388
+ else:
389
+ r = ((self.block.addr, self.stmt_idx), data)
390
+ self.state._registers[offset] = r
391
+
392
+ def _handle_Store(self, stmt):
393
+ self._tsrc = set()
394
+ addr = self._expr(stmt.addr)
395
+ data = self._expr(stmt.data)
396
+
397
+ if addr is None:
398
+ return
399
+
400
+ if isinstance(addr, SpOffset):
401
+ self.state._stack[addr.offset] = ((self.block.addr, self.stmt_idx), data)
402
+
403
+ def _handle_RdTmp(self, expr):
404
+ v = super()._handle_RdTmp(expr)
405
+ if expr.tmp in self.state._tmpvar_source:
406
+ self._tsrc |= set(self.state._tmpvar_source[expr.tmp])
407
+ return v
408
+
409
+ def _handle_Get(self, expr):
410
+ if expr.offset == self.arch.bp_offset:
411
+ v = self._get_spoffset_expr(SpOffset(self.arch.bits, self._bp_sp_diff))
412
+ elif expr.offset == self.arch.sp_offset:
413
+ v = self._get_spoffset_expr(SpOffset(self.arch.bits, 0))
414
+ else:
415
+ if expr.offset in self.state._registers:
416
+ self._tsrc |= set(self.state._registers[expr.offset][0])
417
+ v = self.state._registers[expr.offset][1]
418
+ else:
419
+ # the register does not exist
420
+ # we initialize it here
421
+ v = RegisterOffset(expr.result_size(self.tyenv), expr.offset, 0)
422
+ v = self._get_regoffset_expr(v, expr.result_size(self.tyenv))
423
+ src = (self.block.addr, self.stmt_idx)
424
+ self._tsrc.add(src)
425
+ self.state._registers[expr.offset] = ([src], v)
426
+
427
+ # make sure the size matches
428
+ # note that this is sometimes incorrect. for example, we do not differentiate between reads at ah and al...
429
+ # but it should be good enough for now (without switching state._registers to a real SimMemory, which will
430
+ # surely slow down stuff quite a bit)
431
+ if v is not None:
432
+ bits = expr.result_size(self.tyenv)
433
+ if v.size() > bits:
434
+ v = v[bits - 1 : 0]
435
+ elif v.size() < bits:
436
+ v = claripy.ZeroExt(bits - v.size(), v)
437
+ return v
438
+
439
+ def _handle_function(self, expr): # pylint:disable=unused-argument,no-self-use
440
+ return None # This analysis is not interprocedural
441
+
442
+ def _handle_Load(self, expr):
443
+ addr = self._expr(expr.addr)
444
+ size = expr.result_size(self.tyenv) // 8
445
+ return self._do_load(addr, size)
446
+
447
+ def _handle_LoadG(self, stmt):
448
+ guard = self._expr(stmt.guard)
449
+ if guard is True:
450
+ return self._do_load(stmt.addr, stmt.addr.result_size(self.tyenv) // 8)
451
+ elif guard is False:
452
+ return self._do_load(stmt.alt, stmt.alt.result_size(self.tyenv) // 8)
453
+ else:
454
+ return None
455
+
456
+ def _handle_Const(self, expr):
457
+ v = super()._handle_Const(expr)
458
+ self._tsrc.add("const")
459
+ return v
460
+
461
+ def _handle_CmpLE(self, expr):
462
+ self._handle_Comparison(*expr.args)
463
+
464
+ def _handle_CmpGE(self, expr):
465
+ self._handle_Comparison(*expr.args)
466
+
467
+ def _handle_CmpLT(self, expr):
468
+ self._handle_Comparison(*expr.args)
469
+
470
+ def _handle_CmpGT(self, expr):
471
+ self._handle_Comparison(*expr.args)
472
+
473
+ def _handle_CCall(self, expr):
474
+ if not isinstance(expr.args[0], pyvex.IRExpr.Const):
475
+ return
476
+ cond_type_enum = expr.args[0].con.value
477
+
478
+ if self.arch.name in {"X86", "AMD64", "AARCH64"}:
479
+ if cond_type_enum in EXPECTED_COND_TYPES[self.arch.name]:
480
+ self._handle_Comparison(expr.args[2], expr.args[3])
481
+ elif is_arm_arch(self.arch):
482
+ if cond_type_enum in EXPECTED_COND_TYPES["ARM"]:
483
+ self._handle_Comparison(expr.args[2], expr.args[3])
484
+ else:
485
+ # other architectures
486
+ l.warning("Please fill in EXPECTED_COND_TYPES for %s.", self.arch.name)
487
+ self._handle_Comparison(expr.args[2], expr.args[3])
488
+
489
+ def _handle_Comparison(self, arg0, arg1):
490
+ if self.block.addr not in self._indirect_jump_node_pred_addrs:
491
+ return
492
+
493
+ # found the comparison
494
+ arg0_src, arg1_src = None, None
495
+
496
+ if isinstance(arg0, pyvex.IRExpr.RdTmp):
497
+ if arg0.tmp in self.state._tmpvar_source:
498
+ arg0_src = self.state._tmpvar_source[arg0.tmp]
499
+ if not arg0_src or len(arg0_src) > 1:
500
+ arg0_src = None
501
+ else:
502
+ arg0_src = next(iter(arg0_src))
503
+ elif isinstance(arg0, pyvex.IRExpr.Const):
504
+ arg0_src = "const"
505
+ if isinstance(arg1, pyvex.IRExpr.RdTmp):
506
+ if arg1.tmp in self.state._tmpvar_source:
507
+ arg1_src = self.state._tmpvar_source[arg1.tmp]
508
+ if not arg1_src or len(arg1_src) > 1:
509
+ arg1_src = None
510
+ else:
511
+ arg1_src = next(iter(arg1_src))
512
+ elif isinstance(arg1, pyvex.IRExpr.Const):
513
+ arg1_src = "const"
514
+
515
+ if arg0_src == "const" and arg1_src == "const":
516
+ # comparison of two consts... there is nothing we can do
517
+ self.state.is_jumptable = True
518
+ return
519
+ if arg0_src not in {"const", None} and arg1_src not in {"const", None}:
520
+ # this is probably not a jump table
521
+ return
522
+ if arg1_src == "const":
523
+ # make sure arg0_src is const
524
+ arg0_src, arg1_src = arg1_src, arg0_src
525
+
526
+ self.state.is_jumptable = True
527
+
528
+ if arg0_src != "const":
529
+ # we failed during dependency tracking so arg0_src couldn't be determined
530
+ # but we will still try to resolve it as a jump table as a fall back
531
+ return
532
+
533
+ if isinstance(arg1_src, tuple):
534
+ arg1_src_stmt = self.project.factory.block(arg1_src[0], cross_insn_opt=True).vex.statements[arg1_src[1]]
535
+ if isinstance(arg1_src_stmt, pyvex.IRStmt.Store):
536
+ # Storing a constant/variable in memory
537
+ # We will need to overwrite it when executing the slice to guarantee the full recovery of jump table
538
+ # targets.
539
+ #
540
+ # Here is an example:
541
+ # mov [rbp+var_54], 1
542
+ # loc_4051a6:
543
+ # cmp [rbp+var_54], 6
544
+ # ja loc_405412 (default)
545
+ #
546
+ # Instead of writing 1 to [rbp+var_54], we want to write a symbolic variable there instead. Otherwise
547
+ # we will only recover the second jump target instead of all 7 targets.
548
+ self.state.stmts_to_instrument.append(("mem_write",) + arg1_src)
549
+ elif isinstance(arg1_src_stmt, pyvex.IRStmt.WrTmp) and isinstance(arg1_src_stmt.data, pyvex.IRExpr.Load):
550
+ # Loading a constant/variable from memory (and later the value is stored in a register)
551
+ # Same as above, we will need to overwrite it when executing the slice to guarantee the full recovery
552
+ # of jump table targets.
553
+ #
554
+ # Here is an example:
555
+ # mov eax, [0x625a3c]
556
+ # cmp eax, 0x4
557
+ # ja 0x40899d (default)
558
+ # loc_408899:
559
+ # mov eax, eax
560
+ # mov rax, qword [rax*8+0x220741]
561
+ # jmp rax
562
+ #
563
+ self.state.stmts_to_instrument.append(("mem_read",) + arg1_src)
564
+ elif isinstance(arg1_src_stmt, pyvex.IRStmt.Put):
565
+ # Storing a constant/variable in register
566
+ # Same as above...
567
+ #
568
+ # Here is an example:
569
+ # movzx eax, byte ptr [rax+12h]
570
+ # movzx eax, al
571
+ # cmp eax, 0xe
572
+ # ja 0x405b9f (default)
573
+ # loc_405b34:
574
+ # mov eax, eax
575
+ # mov rax, qword [rax*8+0x2231ae]
576
+ #
577
+ self.state.stmts_to_instrument.append(("reg_write",) + arg1_src)
578
+
579
+ def _do_load(self, addr, size):
580
+ src = (self.block.addr, self.stmt_idx)
581
+ self._tsrc = {src}
582
+ if addr is None:
583
+ return None
584
+
585
+ if self._is_spoffset(addr):
586
+ spoffset = self._extract_spoffset_from_expr(addr)
587
+ if spoffset is not None and spoffset.offset in self.state._stack:
588
+ self._tsrc = {self.state._stack[spoffset.offset][0]}
589
+ return self.state._stack[spoffset.offset][1]
590
+ elif isinstance(addr, int):
591
+ # Load data from memory if it is mapped
592
+ try:
593
+ v = self.project.loader.memory.unpack_word(addr, size=size)
594
+ return v
595
+ except KeyError:
596
+ return None
597
+ elif self._is_registeroffset(addr):
598
+ # Load data from a register, but this register hasn't been initialized at this point
599
+ # We will need to initialize this register during slice execution later
600
+
601
+ # Try to get where this register is first accessed
602
+ reg_offset = self._extract_regoffset_from_expr(addr)
603
+ if reg_offset is not None and reg_offset.reg in self.state._registers:
604
+ try:
605
+ source = next(iter(src for src in self.state._registers[reg_offset.reg][0] if src != "const"))
606
+ assert isinstance(source, tuple)
607
+ self.state.regs_to_initialize.append(source + (reg_offset.reg, reg_offset.bits))
608
+ except StopIteration:
609
+ # we don't need to initialize this register
610
+ # it might be caused by an incorrect analysis result
611
+ # e.g. PN-337140.bin 11e918 r0 comes from r4, r4 comes from r0@11e8c0, and r0@11e8c0 comes from
612
+ # function call sub_375c04. Since we do not analyze sub_375c04, we treat r0@11e918 as a constant 0.
613
+ pass
614
+
615
+ return None
616
+
617
+ return None
618
+
619
+
620
+ #
621
+ # State hooks
622
+ #
623
+
624
+
625
+ class StoreHook:
626
+ """
627
+ Hook for memory stores.
628
+ """
629
+
630
+ @staticmethod
631
+ def hook(state):
632
+ write_length = state.inspect.mem_write_length
633
+ if write_length is None:
634
+ write_length = len(state.inspect.mem_write_expr)
635
+ else:
636
+ write_length = write_length * state.arch.byte_width
637
+ state.inspect.mem_write_expr = state.solver.BVS("instrumented_store", write_length)
638
+
639
+
640
+ class LoadHook:
641
+ """
642
+ Hook for memory loads.
643
+ """
644
+
645
+ def __init__(self):
646
+ self._var = None
647
+
648
+ def hook_before(self, state):
649
+ addr = state.inspect.mem_read_address
650
+ size = state.solver.eval(state.inspect.mem_read_length)
651
+ self._var = state.solver.BVS("instrumented_load", size * 8)
652
+ state.memory.store(addr, self._var, endness=state.arch.memory_endness)
653
+
654
+ def hook_after(self, state):
655
+ state.inspect.mem_read_expr = self._var
656
+
657
+
658
+ class PutHook:
659
+ """
660
+ Hook for register writes.
661
+ """
662
+
663
+ @staticmethod
664
+ def hook(state):
665
+ state.inspect.reg_write_expr = state.solver.BVS(
666
+ "instrumented_put", state.solver.eval(state.inspect.reg_write_length) * 8
667
+ )
668
+
669
+
670
+ class RegisterInitializerHook:
671
+ """
672
+ Hook for register init.
673
+ """
674
+
675
+ def __init__(self, reg_offset, reg_bits, value):
676
+ self.reg_offset = reg_offset
677
+ self.reg_bits = reg_bits
678
+ self.value = value
679
+
680
+ def hook(self, state):
681
+ state.registers.store(self.reg_offset, state.solver.BVV(self.value, self.reg_bits))
682
+
683
+
684
+ class BSSHook:
685
+ """
686
+ Hook for BSS read/write.
687
+ """
688
+
689
+ def __init__(self, project, bss_regions):
690
+ self.project = project
691
+ self._bss_regions = bss_regions
692
+ self._written_addrs = set()
693
+
694
+ def bss_memory_read_hook(self, state):
695
+ if not self._bss_regions:
696
+ return
697
+
698
+ read_addr = state.inspect.mem_read_address
699
+ read_length = state.inspect.mem_read_length
700
+
701
+ if not isinstance(read_addr, int) and read_addr.symbolic:
702
+ # don't touch it
703
+ return
704
+
705
+ concrete_read_addr = state.solver.eval(read_addr)
706
+ concrete_read_length = state.solver.eval(read_length)
707
+
708
+ for start, size in self._bss_regions:
709
+ if start <= concrete_read_addr < start + size:
710
+ # this is a read from the .bss section
711
+ break
712
+ else:
713
+ return
714
+
715
+ if concrete_read_addr not in self._written_addrs:
716
+ # it was never written to before. we overwrite it with unconstrained bytes
717
+ for i in range(0, concrete_read_length, self.project.arch.bytes):
718
+ state.memory.store(
719
+ concrete_read_addr + i,
720
+ state.solver.Unconstrained("unconstrained", self.project.arch.bits),
721
+ endness=self.project.arch.memory_endness,
722
+ )
723
+
724
+ # job done :-)
725
+
726
+ def bss_memory_write_hook(self, state):
727
+ if not self._bss_regions:
728
+ return
729
+
730
+ write_addr = state.inspect.mem_write_address
731
+
732
+ if not isinstance(write_addr, int) and write_addr.symbolic:
733
+ return
734
+
735
+ concrete_write_addr = state.solver.eval(write_addr)
736
+ concrete_write_length = (
737
+ state.solver.eval(state.inspect.mem_write_length)
738
+ if state.inspect.mem_write_length is not None
739
+ else len(state.inspect.mem_write_expr) // state.arch.byte_width
740
+ )
741
+
742
+ for start, size in self._bss_regions:
743
+ if start <= concrete_write_addr < start + size:
744
+ # hit a BSS section
745
+ break
746
+ else:
747
+ return
748
+
749
+ if concrete_write_length > 1024:
750
+ l.warning("Writing more 1024 bytes to the BSS region, only considering the first 1024 bytes.")
751
+ concrete_write_length = 1024
752
+
753
+ for i in range(concrete_write_addr, concrete_write_length):
754
+ self._written_addrs.add(i)
755
+
756
+
757
+ class MIPSGPHook:
758
+ """
759
+ Hooks all reads from and writes into the gp register for MIPS32 binaries.
760
+ """
761
+
762
+ def __init__(self, gp_offset: int, gp: int):
763
+ self.gp_offset = gp_offset
764
+ self.gp = gp
765
+
766
+ def gp_register_read_hook(self, state):
767
+ read_offset = state.inspect.reg_read_offset
768
+ read_length = state.inspect.reg_read_length
769
+ if state.solver.eval(read_offset) == self.gp_offset and read_length == 4:
770
+ state.inspect.reg_read_expr = claripy.BVV(self.gp, size=32)
771
+
772
+ def gp_register_write_hook(self, state):
773
+ write_offset = state.inspect.reg_write_offset
774
+ write_length = state.inspect.reg_write_length
775
+ if state.solver.eval(write_offset) == self.gp_offset and write_length == 4:
776
+ state.inspect.reg_write_expr = claripy.BVV(self.gp, size=32)
777
+
778
+
779
+ #
780
+ # Main class
781
+ #
782
+
783
+
784
+ class JumpTableResolver(IndirectJumpResolver):
785
+ """
786
+ A generic jump table resolver.
787
+
788
+ This is a fast jump table resolution. For performance concerns, we made the following assumptions:
789
+ - The final jump target comes from the memory.
790
+ - The final jump target must be directly read out of the memory, without any further modification or altering.
791
+
792
+ Progressively larger program slices will be analyzed to determine jump table location and size. If the size of the
793
+ table cannot be determined, a *guess* will be made based on how many entries in the table *appear* valid.
794
+ """
795
+
796
+ def __init__(self, project, resolve_calls: bool = True):
797
+ super().__init__(project, timeless=False)
798
+
799
+ self.resolve_calls = resolve_calls
800
+
801
+ self._bss_regions = None
802
+ # the maximum number of resolved targets. Will be initialized from CFG.
803
+ self._max_targets = None
804
+
805
+ # cached memory read addresses that are used to initialize uninitialized registers
806
+ # should be cleared before every symbolic execution run on the slice
807
+ self._cached_memread_addrs = {}
808
+
809
+ self._find_bss_region()
810
+
811
+ def filter(self, cfg, addr, func_addr, block, jumpkind):
812
+ if pcode is not None and isinstance(block.vex, pcode.lifter.IRSB):
813
+ if once("pcode__indirect_jump_resolver"):
814
+ l.warning("JumpTableResolver does not support P-Code IR yet; CFG may be incomplete.")
815
+ return False
816
+
817
+ if jumpkind == "Ijk_Boring":
818
+ return True
819
+ if self.resolve_calls and jumpkind == "Ijk_Call":
820
+ return True
821
+ return False
822
+
823
+ def resolve(self, cfg, addr, func_addr, block, jumpkind, func_graph_complete: bool = True, **kwargs):
824
+ """
825
+ Resolves jump tables.
826
+
827
+ :param cfg: A CFG instance.
828
+ :param int addr: IRSB address.
829
+ :param int func_addr: The function address.
830
+ :param pyvex.IRSB block: The IRSB.
831
+ :return: A bool indicating whether the indirect jump is resolved successfully, and a list of resolved targets
832
+ :rtype: tuple
833
+ """
834
+
835
+ if not cfg.kb.functions.contains_addr(func_addr):
836
+ # fix for angr issue #3768
837
+ # the function must exist in the KB
838
+ return False, None
839
+
840
+ func: "Function" = cfg.kb.functions[func_addr]
841
+ self._max_targets = cfg._indirect_jump_target_limit
842
+
843
+ # this is an indirect call if (1) the instruction is a call, or (2) the instruction is a tail jump (we detect
844
+ # sp moving up to approximate)
845
+ potential_call_table = jumpkind == "Ijk_Call" or self._sp_moved_up(block) or len(func.block_addrs_set) <= 5
846
+ # we only perform full-function propagation for jump tables or call tables in really small functions
847
+ if not potential_call_table or len(func.block_addrs_set) <= 5:
848
+ cv_manager = ConstantValueManager(self.project, cfg.kb, func)
849
+ else:
850
+ cv_manager = None
851
+
852
+ for slice_steps in range(1, 5):
853
+ # Perform a backward slicing from the jump target
854
+ # Important: Do not go across function call boundaries
855
+ b = Blade(
856
+ cfg.graph,
857
+ addr,
858
+ -1,
859
+ cfg=cfg,
860
+ project=self.project,
861
+ ignore_sp=False,
862
+ ignore_bp=False,
863
+ max_level=slice_steps,
864
+ base_state=self.base_state,
865
+ stop_at_calls=True,
866
+ cross_insn_opt=True,
867
+ )
868
+
869
+ l.debug("Try resolving %#x with a %d-level backward slice...", addr, slice_steps)
870
+ r, targets = self._resolve(
871
+ cfg, addr, func, b, cv_manager, potential_call_table=False, func_graph_complete=func_graph_complete
872
+ )
873
+ if r:
874
+ return r, targets
875
+
876
+ if potential_call_table:
877
+ b = Blade(
878
+ cfg.graph,
879
+ addr,
880
+ -1,
881
+ cfg=cfg,
882
+ project=self.project,
883
+ ignore_sp=False,
884
+ ignore_bp=False,
885
+ max_level=1,
886
+ base_state=self.base_state,
887
+ stop_at_calls=True,
888
+ cross_insn_opt=True,
889
+ )
890
+ return self._resolve(
891
+ cfg, addr, func, b, cv_manager, potential_call_table=True, func_graph_complete=func_graph_complete
892
+ )
893
+
894
+ return False, None
895
+
896
+ #
897
+ # Private methods
898
+ #
899
+
900
+ def _resolve(
901
+ self,
902
+ cfg,
903
+ addr: int,
904
+ func: "Function",
905
+ b: Blade,
906
+ cv_manager: ConstantValueManager | None,
907
+ potential_call_table: bool = False,
908
+ func_graph_complete: bool = True,
909
+ ) -> tuple[bool, Sequence[int] | None]:
910
+ """
911
+ Internal method for resolving jump tables.
912
+
913
+ :param cfg: A CFG instance.
914
+ :param addr: Address of the block where the indirect jump is.
915
+ :param func: The Function instance.
916
+ :param b: The generated backward slice.
917
+ :return: A bool indicating whether the indirect jump is resolved successfully, and a list of
918
+ resolved targets.
919
+ """
920
+
921
+ project = self.project # short-hand
922
+ func_addr = func.addr
923
+ is_arm = is_arm_arch(self.project.arch)
924
+
925
+ stmt_loc = (addr, DEFAULT_STATEMENT)
926
+ if stmt_loc not in b.slice:
927
+ return False, None
928
+
929
+ (
930
+ load_stmt_loc,
931
+ load_stmt,
932
+ load_size,
933
+ stmts_to_remove,
934
+ stmts_adding_base_addr,
935
+ transformations,
936
+ ) = self._find_load_statement(b, stmt_loc)
937
+ ite_stmt, ite_stmt_loc = None, None
938
+
939
+ if load_stmt_loc is None:
940
+ # the load statement is not found
941
+ # maybe it's a typical ARM-style jump table like the following:
942
+ # SUB R3, R5, #34
943
+ # CMP R3, #28
944
+ # ADDLS PC, PC, R3,LSL#2
945
+ if is_arm:
946
+ ite_stmt, ite_stmt_loc, stmts_to_remove = self._find_load_pc_ite_statement(b, stmt_loc)
947
+ if ite_stmt is None:
948
+ l.debug("Could not find load statement in this slice")
949
+ return False, None
950
+
951
+ # more sanity checks
952
+
953
+ # for a typical jump table, the current block has only one predecessor, and the predecessor to the current
954
+ # block has two successors (not including itself)
955
+ # for a typical vtable call (or jump if at the end of a function), the block as two predecessors that form a
956
+ # diamond shape
957
+ curr_node = func.get_node(addr)
958
+ if curr_node is None or curr_node not in func.graph:
959
+ l.debug("Could not find the node %#x in the function transition graph", addr)
960
+ return False, None
961
+ preds = list(func.graph.predecessors(curr_node))
962
+ pred_endaddrs = {pred.addr + pred.size for pred in preds} # handle non-normalized CFGs
963
+ if func_graph_complete and not is_arm and not potential_call_table:
964
+ # on ARM you can do a single-block jump table...
965
+ if len(pred_endaddrs) == 1:
966
+ pred_succs = [succ for succ in func.graph.successors(preds[0]) if succ.addr != preds[0].addr]
967
+ if len(pred_succs) != 2:
968
+ l.debug("Expect two successors to the single predecessor, found %d.", len(pred_succs))
969
+ return False, None
970
+ elif len(pred_endaddrs) == 2 and len(preds) == 2:
971
+ pred_succs = set(
972
+ [succ for succ in func.graph.successors(preds[0]) if succ.addr != preds[0].addr]
973
+ + [succ for succ in func.graph.successors(preds[1]) if succ.addr != preds[1].addr]
974
+ )
975
+ is_diamond = False
976
+ if len(pred_succs) == 2:
977
+ non_node_succ = next(iter(pred_succ for pred_succ in pred_succs if pred_succ is not curr_node))
978
+ while func.graph.out_degree[non_node_succ] == 1:
979
+ non_node_succ = list(func.graph.successors(non_node_succ))[0]
980
+ if non_node_succ == curr_node:
981
+ is_diamond = True
982
+ break
983
+ if not is_diamond:
984
+ l.debug("Expect a diamond shape.")
985
+ return False, None
986
+ else:
987
+ l.debug("The predecessor-successor shape does not look like a jump table or a vtable jump/call.")
988
+ return False, None
989
+
990
+ try:
991
+ jump_target = self._try_resolve_single_constant_loads(load_stmt, cfg, addr)
992
+ except NotAJumpTableNotification:
993
+ return False, None
994
+ if jump_target is not None:
995
+ if self._is_target_valid(cfg, jump_target):
996
+ ij = cfg.indirect_jumps.get(addr, None)
997
+ if ij is not None:
998
+ ij.jumptable = False
999
+ ij.resolved_targets = {jump_target}
1000
+ return True, [jump_target]
1001
+ else:
1002
+ l.debug("Found single constant load, but it does not appear to be a valid target")
1003
+ return False, None
1004
+
1005
+ # Well, we have a real jump table to resolve!
1006
+
1007
+ # skip all statements after the load statement
1008
+ # We want to leave the final loaded value as symbolic, so we can
1009
+ # get the full range of possibilities
1010
+ b.slice.remove_nodes_from(stmts_to_remove)
1011
+
1012
+ stmts_to_instrument, regs_to_initialize = [], []
1013
+ try:
1014
+ stmts_to_instrument, regs_to_initialize = self._jumptable_precheck(b, {pred.addr for pred in preds})
1015
+ l.debug(
1016
+ "jumptable_precheck provides stmts_to_instrument = %s, regs_to_initialize = %s",
1017
+ stmts_to_instrument,
1018
+ regs_to_initialize,
1019
+ )
1020
+ except NotAJumpTableNotification:
1021
+ if not potential_call_table and not is_arm:
1022
+ l.debug("Indirect jump at %#x does not look like a jump table. Skip.", addr)
1023
+ return False, None
1024
+
1025
+ # Debugging output
1026
+ if l.level == logging.DEBUG:
1027
+ self._dbg_repr_slice(b)
1028
+
1029
+ # Get all sources
1030
+ sources = [n_ for n_ in b.slice.nodes() if b.slice.in_degree(n_) == 0]
1031
+
1032
+ # Create the annotated CFG
1033
+ annotatedcfg = AnnotatedCFG(project, None, detect_loops=False)
1034
+ annotatedcfg.from_digraph(b.slice)
1035
+
1036
+ # pylint: disable=too-many-nested-blocks
1037
+ for block_addr, _ in sources:
1038
+ # Use slicecutor to execute each one, and get the address
1039
+ # We simply give up if any exception occurs on the way
1040
+ start_state = self._initial_state(block_addr, cfg, func_addr)
1041
+
1042
+ # instrument specified store/put/load statements
1043
+ self._instrument_statements(start_state, stmts_to_instrument, regs_to_initialize)
1044
+
1045
+ self._cached_memread_addrs.clear()
1046
+ init_registers_on_demand_bp = BP(when=BP_BEFORE, enabled=True, action=self._init_registers_on_demand)
1047
+ start_state.inspect.add_breakpoint("mem_read", init_registers_on_demand_bp)
1048
+
1049
+ # constant value manager
1050
+ if cv_manager is not None:
1051
+ constant_value_reg_read_bp = BP(when=BP_AFTER, enabled=True, action=cv_manager.reg_read_callback)
1052
+ start_state.inspect.add_breakpoint("reg_read", constant_value_reg_read_bp)
1053
+
1054
+ # use Any as the concretization strategy
1055
+ start_state.memory.read_strategies = [SimConcretizationStrategyAny()]
1056
+ start_state.memory.write_strategies = [SimConcretizationStrategyAny()]
1057
+
1058
+ # Create the slicecutor
1059
+ simgr = self.project.factory.simulation_manager(start_state, resilience=True)
1060
+ slicecutor = Slicecutor(annotatedcfg, force_taking_exit=True)
1061
+ simgr.use_technique(slicecutor)
1062
+ simgr.use_technique(LocalLoopSeer(bound=1))
1063
+ if load_stmt is not None:
1064
+ explorer = Explorer(find=load_stmt_loc[0])
1065
+ elif ite_stmt is not None:
1066
+ explorer = Explorer(find=ite_stmt_loc[0])
1067
+ else:
1068
+ raise TypeError("Unsupported type of jump table.")
1069
+ simgr.use_technique(explorer)
1070
+
1071
+ # Run it!
1072
+ try:
1073
+ simgr.run()
1074
+ except KeyError as ex:
1075
+ # This is because the program slice is incomplete.
1076
+ # Blade will support more IRExprs and IRStmts in the future
1077
+ l.debug("KeyError occurred due to incomplete program slice.", exc_info=ex)
1078
+ continue
1079
+
1080
+ # Get the jumping targets
1081
+ for r in simgr.found:
1082
+ if load_stmt is not None:
1083
+ ret = self._try_resolve_targets_load(
1084
+ r,
1085
+ addr,
1086
+ cfg,
1087
+ annotatedcfg,
1088
+ load_stmt,
1089
+ load_size,
1090
+ stmts_adding_base_addr,
1091
+ transformations,
1092
+ potential_call_table,
1093
+ )
1094
+ if ret is None:
1095
+ # Try the next state
1096
+ continue
1097
+ jump_table, jumptable_addr, entry_size, jumptable_size, all_targets, sort = ret
1098
+ if sort == "jumptable":
1099
+ ij_type = IndirectJumpType.Jumptable_AddressLoadedFromMemory
1100
+ elif sort == "vtable":
1101
+ ij_type = IndirectJumpType.Vtable
1102
+ else:
1103
+ ij_type = IndirectJumpType.Unknown
1104
+ elif ite_stmt is not None:
1105
+ ret = self._try_resolve_targets_ite(r, addr, cfg, annotatedcfg, ite_stmt)
1106
+ if ret is None:
1107
+ # Try the next state
1108
+ continue
1109
+ jumptable_addr = None
1110
+ jump_table, jumptable_size, entry_size = ret
1111
+ all_targets = jump_table
1112
+ ij_type = IndirectJumpType.Jumptable_AddressComputed
1113
+ else:
1114
+ raise TypeError("Unsupported type of jump table.")
1115
+
1116
+ assert ret is not None
1117
+
1118
+ # finally, we filter jump targets according to the alignment of the architecture
1119
+ if is_arm_arch(self.project.arch):
1120
+ alignment = 4 if addr % 2 == 0 else 2
1121
+ else:
1122
+ alignment = self.project.arch.instruction_alignment
1123
+ if alignment != 1:
1124
+ if is_arm_arch(self.project.arch) and addr % 2 == 1:
1125
+ # Special logic for handling THUMB addresses
1126
+ all_targets = [t_ for t_ in all_targets if (t_ - 1) % alignment == 0]
1127
+ else:
1128
+ all_targets = [t_ for t_ in all_targets if t_ % alignment == 0]
1129
+
1130
+ l.info(
1131
+ "Jump table at %#x has %d targets: %s",
1132
+ addr,
1133
+ len(all_targets),
1134
+ ", ".join([hex(a) for a in all_targets]),
1135
+ )
1136
+
1137
+ # write to the IndirectJump object in CFG
1138
+ ij: IndirectJump = cfg.indirect_jumps.get(addr, None)
1139
+ if ij is not None:
1140
+ if len(all_targets) > 1:
1141
+ # It can be considered a jump table only if there are more than one jump target
1142
+ if ij_type in {
1143
+ IndirectJumpType.Jumptable_AddressComputed,
1144
+ IndirectJumpType.Jumptable_AddressLoadedFromMemory,
1145
+ }:
1146
+ ij.jumptable = True
1147
+ else:
1148
+ ij.jumptable = False
1149
+ ij.jumptable_addr = jumptable_addr
1150
+ ij.jumptable_size = jumptable_size
1151
+ ij.jumptable_entry_size = entry_size
1152
+ ij.resolved_targets = set(jump_table)
1153
+ ij.jumptable_entries = jump_table
1154
+ ij.type = ij_type
1155
+ else:
1156
+ ij.jumptable = False
1157
+ ij.resolved_targets = set(jump_table)
1158
+
1159
+ return True, all_targets
1160
+
1161
+ l.info("Could not resolve indirect jump %#x in function %#x.", addr, func_addr)
1162
+ return False, None
1163
+
1164
+ def _find_load_statement(self, b, stmt_loc):
1165
+ """
1166
+ Find the location of the final Load statement that loads indirect jump targets from the jump table.
1167
+ """
1168
+
1169
+ # pylint:disable=no-else-continue
1170
+
1171
+ # shorthand
1172
+ project = self.project
1173
+
1174
+ # initialization
1175
+ load_stmt_loc, load_stmt, load_size = None, None, None
1176
+ stmts_to_remove = [stmt_loc]
1177
+ stmts_adding_base_addr: list[JumpTargetBaseAddr] = []
1178
+ # All temporary variables that hold indirect addresses loaded out of the memory
1179
+ # Obviously, load_stmt.tmp must be here
1180
+ # if there are additional data transferring statements between the Load statement and the base-address-adding
1181
+ # statement, all_addr_holders will have more than one temporary variables
1182
+ #
1183
+ # Here is an example:
1184
+ #
1185
+ # IRSB 0x4c64c4
1186
+ # + 06 | t12 = LDle:I32(t7)
1187
+ # + 07 | t11 = 32Sto64(t12)
1188
+ # + 10 | t2 = Add64(0x0000000000571df0,t11)
1189
+ #
1190
+ # all_addr_holders will be {(0x4c64c4, 11): (AddressTransferringTypes.SignedExtension, 32, 64,),
1191
+ # (0x4c64c4, 12); (AddressTransferringTypes.Assignment,),
1192
+ # }
1193
+ transformations: dict[tuple[int, int], AddressTransformation] = OrderedDict()
1194
+
1195
+ initial_block_addr = stmt_loc[0]
1196
+ all_load_stmts = sorted(self._all_qualified_load_stmts_in_slice(b, stmt_loc[0]))
1197
+
1198
+ while True:
1199
+ preds = list(b.slice.predecessors(stmt_loc))
1200
+ if len(preds) != 1:
1201
+ break
1202
+ block_addr, stmt_idx = stmt_loc = preds[0]
1203
+ block = project.factory.block(block_addr, cross_insn_opt=True, backup_state=self.base_state).vex
1204
+ if stmt_idx == DEFAULT_STATEMENT:
1205
+ # it's the default exit. continue
1206
+ continue
1207
+ stmt = block.statements[stmt_idx]
1208
+ if isinstance(stmt, (pyvex.IRStmt.WrTmp, pyvex.IRStmt.Put)):
1209
+ if isinstance(stmt.data, (pyvex.IRExpr.Get, pyvex.IRExpr.RdTmp)):
1210
+ # data transferring
1211
+ stmts_to_remove.append(stmt_loc)
1212
+ if isinstance(stmt, pyvex.IRStmt.WrTmp):
1213
+ transformations[(stmt_loc[0], stmt.tmp)] = AddressTransformation(
1214
+ AddressTransformationTypes.Assignment, [stmt.tmp, AddressSingleton]
1215
+ )
1216
+ continue
1217
+ elif isinstance(stmt.data, pyvex.IRExpr.ITE):
1218
+ # data transferring
1219
+ # t16 = if (t43) ILGop_Ident32(LDle(t29)) else 0x0000c844
1220
+ # > t44 = ITE(t43,t16,0x0000c844)
1221
+ stmts_to_remove.append(stmt_loc)
1222
+ if isinstance(stmt, pyvex.IRStmt.WrTmp):
1223
+ transformations[(stmt_loc[0], stmt.tmp)] = AddressTransformation(
1224
+ AddressTransformationTypes.Assignment, [stmt.tmp, AddressSingleton]
1225
+ )
1226
+ continue
1227
+ elif isinstance(stmt.data, pyvex.IRExpr.Unop):
1228
+ if stmt.data.op == "Iop_32Sto64":
1229
+ # data transferring with conversion
1230
+ # t11 = 32Sto64(t12)
1231
+ stmts_to_remove.append(stmt_loc)
1232
+ if isinstance(stmt, pyvex.IRStmt.WrTmp):
1233
+ transformations[(stmt_loc[0], stmt.tmp)] = AddressTransformation(
1234
+ AddressTransformationTypes.SignedExtension, [32, 64, AddressSingleton]
1235
+ )
1236
+ continue
1237
+ elif stmt.data.op == "Iop_64to32":
1238
+ # data transferring with conversion
1239
+ # t24 = 64to32(t21)
1240
+ stmts_to_remove.append(stmt_loc)
1241
+ if isinstance(stmt, pyvex.IRStmt.WrTmp):
1242
+ transformations[(stmt_loc[0], stmt.tmp)] = AddressTransformation(
1243
+ AddressTransformationTypes.Truncation, [64, 32, AddressSingleton]
1244
+ )
1245
+ continue
1246
+ elif stmt.data.op == "Iop_32Uto64":
1247
+ # data transferring with conversion
1248
+ # t21 = 32Uto64(t22)
1249
+ stmts_to_remove.append(stmt_loc)
1250
+ if isinstance(stmt, pyvex.IRStmt.WrTmp):
1251
+ transformations[(stmt_loc[0], stmt.tmp)] = AddressTransformation(
1252
+ AddressTransformationTypes.UnsignedExtension, [32, 64, AddressSingleton]
1253
+ )
1254
+ continue
1255
+ elif stmt.data.op == "Iop_16Uto32":
1256
+ # data transferring with conversion
1257
+ stmts_to_remove.append(stmt_loc)
1258
+ if isinstance(stmt, pyvex.IRStmt.WrTmp):
1259
+ transformations[(stmt_loc[0], stmt.tmp)] = AddressTransformation(
1260
+ AddressTransformationTypes.UnsignedExtension, [16, 32, AddressSingleton]
1261
+ )
1262
+ continue
1263
+ elif stmt.data.op == "Iop_8Uto32":
1264
+ # data transferring with conversion
1265
+ stmts_to_remove.append(stmt_loc)
1266
+ if isinstance(stmt, pyvex.IRStmt.WrTmp):
1267
+ transformations[(stmt_loc[0], stmt.tmp)] = AddressTransformation(
1268
+ AddressTransformationTypes.UnsignedExtension, [8, 32, AddressSingleton]
1269
+ )
1270
+ continue
1271
+ elif stmt.data.op == "Iop_8Uto64":
1272
+ stmts_to_remove.append(stmt_loc)
1273
+ if isinstance(stmt, pyvex.IRStmt.WrTmp):
1274
+ transformations[(stmt_loc[0], stmt.tmp)] = AddressTransformation(
1275
+ AddressTransformationTypes.UnsignedExtension, [8, 64, AddressSingleton]
1276
+ )
1277
+ continue
1278
+ elif isinstance(stmt.data, pyvex.IRExpr.Binop):
1279
+ if stmt.data.op.startswith("Iop_Add"):
1280
+ # GitHub issue #1289, an S390X binary
1281
+ # jump_label = &jump_table + *(jump_table[index])
1282
+ # IRSB 0x4007c0
1283
+ # 00 | ------ IMark(0x4007c0, 4, 0) ------
1284
+ # + 01 | t0 = GET:I32(212)
1285
+ # + 02 | t1 = Add32(t0,0xffffffff)
1286
+ # 03 | PUT(352) = 0x0000000000000003
1287
+ # 04 | t13 = 32Sto64(t0)
1288
+ # 05 | t6 = t13
1289
+ # 06 | PUT(360) = t6
1290
+ # 07 | PUT(368) = 0xffffffffffffffff
1291
+ # 08 | PUT(376) = 0x0000000000000000
1292
+ # 09 | PUT(212) = t1
1293
+ # 10 | PUT(ia) = 0x00000000004007c4
1294
+ # 11 | ------ IMark(0x4007c4, 6, 0) ------
1295
+ # + 12 | t14 = 32Uto64(t1)
1296
+ # + 13 | t8 = t14
1297
+ # + 14 | t16 = CmpLE64U(t8,0x000000000000000b)
1298
+ # + 15 | t15 = 1Uto32(t16)
1299
+ # + 16 | t10 = t15
1300
+ # + 17 | t11 = CmpNE32(t10,0x00000000)
1301
+ # + 18 | if (t11) { PUT(offset=336) = 0x4007d4; Ijk_Boring }
1302
+ # Next: 0x4007ca
1303
+ #
1304
+ # IRSB 0x4007d4
1305
+ # 00 | ------ IMark(0x4007d4, 6, 0) ------
1306
+ # + 01 | t8 = GET:I64(r2)
1307
+ # + 02 | t7 = Shr64(t8,0x3d)
1308
+ # + 03 | t9 = Shl64(t8,0x03)
1309
+ # + 04 | t6 = Or64(t9,t7)
1310
+ # + 05 | t11 = And64(t6,0x00000007fffffff8)
1311
+ # 06 | ------ IMark(0x4007da, 6, 0) ------
1312
+ # 07 | PUT(r1) = 0x0000000000400a50
1313
+ # 08 | PUT(ia) = 0x00000000004007e0
1314
+ # 09 | ------ IMark(0x4007e0, 6, 0) ------
1315
+ # + 10 | t12 = Add64(0x0000000000400a50,t11)
1316
+ # + 11 | t16 = LDbe:I64(t12)
1317
+ # 12 | PUT(r2) = t16
1318
+ # 13 | ------ IMark(0x4007e6, 4, 0) ------
1319
+ # + 14 | t17 = Add64(0x0000000000400a50,t16)
1320
+ # + Next: t17
1321
+ #
1322
+ # Special case: a base address is added to the loaded offset before jumping to it.
1323
+ if isinstance(stmt.data.args[0], pyvex.IRExpr.Const) and isinstance(
1324
+ stmt.data.args[1], pyvex.IRExpr.RdTmp
1325
+ ):
1326
+ transformations[(stmt_loc[0], stmt.tmp)] = AddressTransformation(
1327
+ AddressTransformationTypes.Add, [stmt.data.args[0].con.value, AddressSingleton]
1328
+ )
1329
+ # we no longer update stmts_adding_base_addr in this case because it's replaced by
1330
+ # transformations
1331
+ stmts_to_remove.append(stmt_loc)
1332
+ elif isinstance(stmt.data.args[0], pyvex.IRExpr.RdTmp) and isinstance(
1333
+ stmt.data.args[1], pyvex.IRExpr.Const
1334
+ ):
1335
+ transformations[(stmt_loc[0], stmt.tmp)] = AddressTransformation(
1336
+ AddressTransformationTypes.Add, [AddressSingleton, stmt.data.args[1].con.value]
1337
+ )
1338
+ # we no longer update stmts_adding_base_addr in this case because it's replaced by
1339
+ # transformations
1340
+ stmts_to_remove.append(stmt_loc)
1341
+ elif isinstance(stmt.data.args[0], pyvex.IRExpr.RdTmp) and isinstance(
1342
+ stmt.data.args[1], pyvex.IRExpr.RdTmp
1343
+ ):
1344
+ # one of the tmps must be holding a concrete value at this point. we will know this when
1345
+ # we perform constant propagation before running JumpTableResolver. this can act as an
1346
+ # indicator that we need to run constant propagation for this function.
1347
+ # for now, we don't support it :)
1348
+ # FIXME: Run constant propagation for the function when necessary. we can also remove
1349
+ # stmts_adding_base_addr and the surrounding logic then.
1350
+ # transformations[(stmt_loc[0], stmt.tmp)] = AddressTransformation(
1351
+ # AddressTransferringTypes.Add,
1352
+ # [Tmp(stmt.data.args[0].tmp), Tmp(stmt.data.args[1].tmp)],
1353
+ # )
1354
+ stmts_adding_base_addr.append(
1355
+ JumpTargetBaseAddr(stmt_loc, stmt, stmt.data.args[0].tmp, tmp_1=stmt.data.args[1].tmp)
1356
+ )
1357
+ stmts_to_remove.append(stmt_loc)
1358
+ else:
1359
+ # not supported
1360
+ pass
1361
+ continue
1362
+ elif stmt.data.op.startswith("Iop_Or"):
1363
+ # this is sometimes used in VEX statements in THUMB mode code to adjust the address to an odd
1364
+ # number
1365
+ # e.g.
1366
+ # IRSB 0x4b63
1367
+ # 00 | ------ IMark(0x4b62, 4, 1) ------
1368
+ # 01 | PUT(itstate) = 0x00000000
1369
+ # + 02 | t11 = GET:I32(r2)
1370
+ # + 03 | t10 = Shl32(t11,0x01)
1371
+ # + 04 | t9 = Add32(0x00004b66,t10)
1372
+ # + 05 | t8 = LDle:I16(t9)
1373
+ # + 06 | t7 = 16Uto32(t8)
1374
+ # + 07 | t14 = Shl32(t7,0x01)
1375
+ # + 08 | t13 = Add32(0x00004b66,t14)
1376
+ # + 09 | t12 = Or32(t13,0x00000001)
1377
+ # + Next: t12
1378
+ if (
1379
+ isinstance(stmt.data.args[0], pyvex.IRExpr.RdTmp)
1380
+ and isinstance(stmt.data.args[1], pyvex.IRExpr.Const)
1381
+ and stmt.data.args[1].con.value == 1
1382
+ ):
1383
+ # great. here it is
1384
+ stmts_to_remove.append(stmt_loc)
1385
+ transformations[(stmt_loc[0], stmt.tmp)] = AddressTransformation(
1386
+ AddressTransformationTypes.Or1, [AddressSingleton]
1387
+ )
1388
+ continue
1389
+ elif stmt.data.op.startswith("Iop_Shl"):
1390
+ # this is sometimes used when dealing with TBx instructions in ARM code.
1391
+ # e.g.
1392
+ # IRSB 0x4b63
1393
+ # 00 | ------ IMark(0x4b62, 4, 1) ------
1394
+ # 01 | PUT(itstate) = 0x00000000
1395
+ # + 02 | t11 = GET:I32(r2)
1396
+ # + 03 | t10 = Shl32(t11,0x01)
1397
+ # + 04 | t9 = Add32(0x00004b66,t10)
1398
+ # + 05 | t8 = LDle:I16(t9)
1399
+ # + 06 | t7 = 16Uto32(t8)
1400
+ # + 07 | t14 = Shl32(t7,0x01)
1401
+ # + 08 | t13 = Add32(0x00004b66,t14)
1402
+ # + 09 | t12 = Or32(t13,0x00000001)
1403
+ # + Next: t12
1404
+ if isinstance(stmt.data.args[0], pyvex.IRExpr.RdTmp) and isinstance(
1405
+ stmt.data.args[1], pyvex.IRExpr.Const
1406
+ ):
1407
+ # found it
1408
+ stmts_to_remove.append(stmt_loc)
1409
+ transformations[(stmt_loc[0], stmt.tmp)] = AddressTransformation(
1410
+ AddressTransformationTypes.ShiftLeft, [AddressSingleton, stmt.data.args[1].con.value]
1411
+ )
1412
+ continue
1413
+ elif stmt.data.op.startswith("Iop_Sar"):
1414
+ # AArch64
1415
+ #
1416
+ # LDRB W0, [X20,W26,UXTW]
1417
+ # ADR X1, loc_11F85C
1418
+ # ADD X0, X1, W0,SXTB#2
1419
+ # BR X0
1420
+ #
1421
+ # IRSB 0x51f84c
1422
+ # + 00 | ------ IMark(0x51f84c, 4, 0) ------
1423
+ # + 01 | t8 = GET:I64(x26)
1424
+ # + 02 | t7 = 64to32(t8)
1425
+ # + 03 | t6 = 32Uto64(t7)
1426
+ # + 04 | t9 = GET:I64(x20)
1427
+ # + 05 | t5 = Add64(t9,t6)
1428
+ # + 06 | t11 = LDle:I8(t5)
1429
+ # + 07 | t10 = 8Uto64(t11)
1430
+ # + 08 | ------ IMark(0x51f850, 4, 0) ------
1431
+ # 09 | PUT(x1) = 0x000000000051f85c
1432
+ # + 10 | ------ IMark(0x51f854, 4, 0) ------
1433
+ # + 11 | t14 = Shl64(t10,0x38)
1434
+ # + 12 | t13 = Sar64(t14,0x38)
1435
+ # + 13 | t12 = Shl64(t13,0x02)
1436
+ # + 14 | t4 = Add64(0x000000000051f85c,t12)
1437
+ # 15 | PUT(x0) = t4
1438
+ # + 16 | ------ IMark(0x51f858, 4, 0) ------
1439
+ # + Next: t4
1440
+ if isinstance(stmt.data.args[0], pyvex.IRExpr.RdTmp) and isinstance(
1441
+ stmt.data.args[1], pyvex.IRExpr.Const
1442
+ ):
1443
+ # found it
1444
+ stmts_to_remove.append(stmt_loc)
1445
+ transformations[(stmt_loc[0], stmt.tmp)] = AddressTransformation(
1446
+ AddressTransformationTypes.ShiftRight, [AddressSingleton, stmt.data.args[1].con.value]
1447
+ )
1448
+ continue
1449
+ elif isinstance(stmt.data, pyvex.IRExpr.Load):
1450
+ # Got it!
1451
+ load_stmt, load_stmt_loc, load_size = (
1452
+ stmt,
1453
+ stmt_loc,
1454
+ block.tyenv.sizeof(stmt.tmp) // self.project.arch.byte_width,
1455
+ )
1456
+ stmts_to_remove.append(stmt_loc)
1457
+ is_first_load_stmt = (
1458
+ True if not all_load_stmts else (stmt_loc == (initial_block_addr, all_load_stmts[0]))
1459
+ )
1460
+ transformations[(stmt_loc[0], stmt.tmp)] = AddressTransformation(
1461
+ AddressTransformationTypes.Load, [AddressSingleton, load_size], first_load=is_first_load_stmt
1462
+ )
1463
+ if not is_first_load_stmt:
1464
+ # This is not the first load statement in the block. more to go
1465
+ continue
1466
+ elif isinstance(stmt, pyvex.IRStmt.LoadG):
1467
+ # Got it!
1468
+ #
1469
+ # this is how an ARM jump table is translated to VEX
1470
+ # > t16 = if (t43) ILGop_Ident32(LDle(t29)) else 0x0000c844
1471
+ load_stmt, load_stmt_loc, load_size = (
1472
+ stmt,
1473
+ stmt_loc,
1474
+ block.tyenv.sizeof(stmt.dst) // self.project.arch.byte_width,
1475
+ )
1476
+ stmts_to_remove.append(stmt_loc)
1477
+ elif isinstance(stmt, pyvex.IRStmt.IMark):
1478
+ continue
1479
+
1480
+ break
1481
+
1482
+ return load_stmt_loc, load_stmt, load_size, stmts_to_remove, stmts_adding_base_addr, transformations
1483
+
1484
+ def _find_load_pc_ite_statement(self, b: Blade, stmt_loc: tuple[int, int]):
1485
+ """
1486
+ Find the location of the final ITE statement that loads indirect jump targets into a tmp.
1487
+
1488
+ The slice looks like the following:
1489
+
1490
+ IRSB 0x41d0fc
1491
+ 00 | ------ IMark(0x41d0fc, 4, 0) ------
1492
+ + 01 | t0 = GET:I32(r5)
1493
+ + 02 | t2 = Sub32(t0,0x00000022)
1494
+ 03 | PUT(r3) = t2
1495
+ 04 | ------ IMark(0x41d100, 4, 0) ------
1496
+ 05 | PUT(cc_op) = 0x00000002
1497
+ 06 | PUT(cc_dep1) = t2
1498
+ 07 | PUT(cc_dep2) = 0x0000001c
1499
+ 08 | PUT(cc_ndep) = 0x00000000
1500
+ 09 | ------ IMark(0x41d104, 4, 0) ------
1501
+ + 10 | t25 = CmpLE32U(t2,0x0000001c)
1502
+ 11 | t24 = 1Uto32(t25)
1503
+ + 12 | t8 = Shl32(t2,0x02)
1504
+ + 13 | t10 = Add32(0x0041d10c,t8)
1505
+ + 14 | t26 = ITE(t25,t10,0x0041d104) <---- this is the statement that we are looking for. Note that
1506
+ 0x0041d104 *must* be ignored since it is a side effect generated
1507
+ by the VEX ARM lifter
1508
+ 15 | PUT(pc) = t26
1509
+ 16 | t21 = Xor32(t24,0x00000001)
1510
+ 17 | t27 = 32to1(t21)
1511
+ 18 | if (t27) { PUT(offset=68) = 0x41d108; Ijk_Boring }
1512
+ + Next: t26
1513
+
1514
+ :param b: The Blade instance, which comes with the slice.
1515
+ :param stmt_loc: The location of the final statement.
1516
+ :return:
1517
+ """
1518
+
1519
+ project = self.project
1520
+ ite_stmt, ite_stmt_loc = None, None
1521
+ stmts_to_remove = [stmt_loc]
1522
+
1523
+ while True:
1524
+ preds = list(b.slice.predecessors(stmt_loc))
1525
+ if len(preds) != 1:
1526
+ break
1527
+ block_addr, stmt_idx = stmt_loc = preds[0]
1528
+ stmts_to_remove.append(stmt_loc)
1529
+ block = project.factory.block(block_addr, cross_insn_opt=True).vex
1530
+ if stmt_idx == DEFAULT_STATEMENT:
1531
+ # we should not reach the default exit (which belongs to a predecessor block)
1532
+ break
1533
+ if not isinstance(block.next, pyvex.IRExpr.RdTmp):
1534
+ # next must be an RdTmp
1535
+ break
1536
+ stmt = block.statements[stmt_idx]
1537
+ if (
1538
+ isinstance(stmt, pyvex.IRStmt.WrTmp)
1539
+ and stmt.tmp == block.next.tmp
1540
+ and isinstance(stmt.data, pyvex.IRExpr.ITE)
1541
+ ):
1542
+ # yes!
1543
+ ite_stmt, ite_stmt_loc = stmt, stmt_loc
1544
+ break
1545
+
1546
+ return ite_stmt, ite_stmt_loc, stmts_to_remove
1547
+
1548
+ def _jumptable_precheck(self, b, indirect_jump_node_pred_addrs):
1549
+ """
1550
+ Perform a pre-check on the slice to determine whether it is a jump table or not. Please refer to the docstring
1551
+ of JumpTableProcessor for how precheck and statement instrumentation works. A NotAJumpTableNotification
1552
+ exception will be raised if the slice fails this precheck.
1553
+
1554
+ :param b: The statement slice generated by Blade.
1555
+ :return: A list of statements to instrument, and a list of registers to initialize.
1556
+ :rtype: tuple of lists
1557
+ """
1558
+
1559
+ # pylint:disable=no-else-continue
1560
+
1561
+ engine = JumpTableProcessor(self.project, indirect_jump_node_pred_addrs)
1562
+
1563
+ sources = [n for n in b.slice.nodes() if b.slice.in_degree(n) == 0]
1564
+
1565
+ annotatedcfg = AnnotatedCFG(self.project, None, detect_loops=False)
1566
+ annotatedcfg.from_digraph(b.slice)
1567
+
1568
+ for src in sources:
1569
+ state = JumpTableProcessorState(self.project.arch)
1570
+ traced = {src[0]}
1571
+ while src is not None:
1572
+ state._tmpvar_source.clear()
1573
+ block_addr, _ = src
1574
+
1575
+ block = self.project.factory.block(block_addr, cross_insn_opt=True, backup_state=self.base_state)
1576
+ stmt_whitelist = annotatedcfg.get_whitelisted_statements(block_addr)
1577
+ try:
1578
+ engine.process(state, block=block, whitelist=stmt_whitelist)
1579
+ except (claripy.errors.ClaripyError, SimError, AngrError):
1580
+ # anything can happen
1581
+ break
1582
+
1583
+ if state.is_jumptable:
1584
+ return state.stmts_to_instrument, state.regs_to_initialize
1585
+ if state.is_jumptable is False:
1586
+ raise NotAJumpTableNotification()
1587
+
1588
+ # find the next block
1589
+ src = None
1590
+ for idx in reversed(stmt_whitelist):
1591
+ loc = (block_addr, idx)
1592
+ successors = list(b.slice.successors(loc))
1593
+ if len(successors) == 1:
1594
+ block_addr_ = successors[0][0]
1595
+ if block_addr_ not in traced:
1596
+ src = successors[0]
1597
+ traced.add(block_addr_)
1598
+ break
1599
+
1600
+ raise NotAJumpTableNotification()
1601
+
1602
+ @staticmethod
1603
+ def _try_resolve_single_constant_loads(load_stmt, cfg, addr):
1604
+ """
1605
+ Resolve cases where only a single constant load is required to resolve the indirect jump. Strictly speaking, it
1606
+ is not a jump table, but we resolve it here anyway.
1607
+
1608
+ :param load_stmt: The pyvex.IRStmt.Load statement that loads an address.
1609
+ :param cfg: The CFG instance.
1610
+ :param int addr: Address of the jump table block.
1611
+ :return: A jump target, or None if it cannot be resolved.
1612
+ :rtype: int or None
1613
+ """
1614
+
1615
+ # If we're just reading a constant, don't bother with the rest of this mess!
1616
+ if isinstance(load_stmt, pyvex.IRStmt.WrTmp):
1617
+ if type(load_stmt.data.addr) is pyvex.IRExpr.Const:
1618
+ # It's directly loading from a constant address
1619
+ # e.g.,
1620
+ # ldr r0, =main+1
1621
+ # blx r0
1622
+ # It's not a jump table, but we resolve it anyway
1623
+ jump_target_addr = load_stmt.data.addr.con.value
1624
+ jump_target = cfg._fast_memory_load_pointer(jump_target_addr)
1625
+ if jump_target is None:
1626
+ l.info(
1627
+ "Constant indirect jump %#x points outside of loaded memory to %#08x", addr, jump_target_addr
1628
+ )
1629
+ raise NotAJumpTableNotification()
1630
+
1631
+ l.info("Resolved constant indirect jump from %#08x to %#08x", addr, jump_target_addr)
1632
+ return jump_target
1633
+
1634
+ elif isinstance(load_stmt, pyvex.IRStmt.LoadG):
1635
+ if type(load_stmt.addr) is pyvex.IRExpr.Const:
1636
+ # It's directly loading from a constant address
1637
+ # e.g.,
1638
+ # 4352c SUB R1, R11, #0x1000
1639
+ # 43530 LDRHI R3, =loc_45450
1640
+ # ...
1641
+ # 43540 MOV PC, R3
1642
+ #
1643
+ # It's not a jump table, but we resolve it anyway
1644
+ # Note that this block has two branches: One goes to 45450, the other one goes to whatever the original
1645
+ # value of R3 is. Some intensive data-flow analysis is required in this case.
1646
+ jump_target_addr = load_stmt.addr.con.value
1647
+ jump_target = cfg._fast_memory_load_pointer(jump_target_addr)
1648
+ l.info("Resolved constant indirect jump from %#08x to %#08x", addr, jump_target_addr)
1649
+ return jump_target
1650
+
1651
+ return None
1652
+
1653
+ def _try_resolve_targets_load(
1654
+ self,
1655
+ r,
1656
+ addr,
1657
+ cfg,
1658
+ annotatedcfg,
1659
+ load_stmt,
1660
+ load_size,
1661
+ stmts_adding_base_addr,
1662
+ transformations: dict[tuple[int, int], AddressTransformation],
1663
+ potential_call_table: bool = False,
1664
+ ):
1665
+ """
1666
+ Try loading all jump targets from a jump table or a vtable.
1667
+ """
1668
+
1669
+ # shorthand
1670
+ project = self.project
1671
+
1672
+ try:
1673
+ whitelist = annotatedcfg.get_whitelisted_statements(r.addr)
1674
+ last_stmt = annotatedcfg.get_last_statement_index(r.addr)
1675
+ succ = project.factory.successors(r, whitelist=whitelist, last_stmt=last_stmt)
1676
+ except (AngrError, SimError):
1677
+ # oops there are errors
1678
+ l.debug("Cannot get jump successor states from a path that has reached the target. Skip it.")
1679
+ return None
1680
+
1681
+ all_states = succ.flat_successors + succ.unconstrained_successors
1682
+ if not all_states:
1683
+ l.debug("Slicecutor failed to execute the program slice. No output state is available.")
1684
+ return None
1685
+
1686
+ state = all_states[0] # Just take the first state
1687
+ self._cached_memread_addrs.clear() # clear the cache to save some memory (and avoid confusion when debugging)
1688
+
1689
+ # Parse the memory load statement and get the memory address of where the jump table is stored
1690
+ jumptable_addr = self._parse_load_statement(load_stmt, state)
1691
+ if jumptable_addr is None:
1692
+ return None
1693
+
1694
+ # sanity check and necessary pre-processing
1695
+ jump_base_addr = None
1696
+ if stmts_adding_base_addr:
1697
+ if len(stmts_adding_base_addr) == 1:
1698
+ jump_base_addr = stmts_adding_base_addr[0]
1699
+ if jump_base_addr.base_addr_available:
1700
+ addr_holders = {(jump_base_addr.stmt_loc[0], jump_base_addr.tmp)}
1701
+ else:
1702
+ addr_holders = {
1703
+ (jump_base_addr.stmt_loc[0], jump_base_addr.tmp),
1704
+ (jump_base_addr.stmt_loc[0], jump_base_addr.tmp_1),
1705
+ }
1706
+ if len(set(transformations.keys()).intersection(addr_holders)) != 1:
1707
+ # for some reason it's trying to add a base address onto a different temporary variable that we
1708
+ # are not aware of. skip.
1709
+ return None
1710
+
1711
+ if not jump_base_addr.base_addr_available:
1712
+ # we need to decide which tmp is the address holder and which tmp holds the base address
1713
+ addr_holder = next(iter(set(transformations.keys()).intersection(addr_holders)))
1714
+ if jump_base_addr.tmp_1 == addr_holder[1]:
1715
+ # swap the two tmps
1716
+ jump_base_addr.tmp, jump_base_addr.tmp_1 = jump_base_addr.tmp_1, jump_base_addr.tmp
1717
+ # Load the concrete base address
1718
+ jump_base_addr.base_addr = state.solver.eval(state.scratch.temps[jump_base_addr.tmp_1])
1719
+ else:
1720
+ # We do not support the cases where the base address involves more than one addition.
1721
+ # One such case exists in libc-2.27.so shipped with Ubuntu x86 where esi is used as the address of the
1722
+ # data region.
1723
+ #
1724
+ # .text:00047316 mov eax, esi
1725
+ # .text:00047318 mov esi, [ebp+data_region_ptr]
1726
+ # .text:0004731E movsx eax, al
1727
+ # .text:00047321 movzx eax, byte ptr [esi+eax-603A0h]
1728
+ # .text:00047329 mov eax, ds:(jpt_47337 - 1D8000h)[esi+eax*4] ; switch 32 cases
1729
+ # .text:00047330 lea eax, (loc_47033 - 1D8000h)[esi+eax] ; jumptable 00047337 cases 0-13,27-31
1730
+ # .text:00047337 jmp eax ; switch
1731
+ #
1732
+ # the proper solution requires angr to correctly determine that esi is the beginning address of the data
1733
+ # region (in this case, 0x1d8000). we give up in such cases until we can reasonably perform a
1734
+ # full-function data propagation before performing jump table recovery.
1735
+ l.debug("Multiple statements adding bases, not supported yet") # FIXME: Just check the addresses?
1736
+
1737
+ jumptable_addr_vsa = jumptable_addr._model_vsa
1738
+
1739
+ if not isinstance(jumptable_addr_vsa, claripy.vsa.StridedInterval):
1740
+ return None
1741
+
1742
+ all_targets = []
1743
+ jump_table = []
1744
+
1745
+ # we may resolve a vtable (in C, e.g., the IO_JUMPS_FUNC in libc), but the stride of this load is usually 1
1746
+ # while the read statement reads a word size at a time.
1747
+ # we use this to differentiate between traditional jump tables (where each entry is some blocks that belong to
1748
+ # the current function) and vtables (where each entry is a function).
1749
+ if jumptable_addr_vsa.stride < load_size:
1750
+ stride = load_size
1751
+ total_cases = jumptable_addr_vsa.cardinality // load_size
1752
+ sort = "vtable" # it's probably a vtable!
1753
+ else:
1754
+ stride = jumptable_addr_vsa.stride
1755
+ total_cases = jumptable_addr_vsa.cardinality
1756
+ sort = "jumptable"
1757
+
1758
+ if total_cases > self._max_targets:
1759
+ if (
1760
+ potential_call_table
1761
+ and sort == "jumptable"
1762
+ and stride * 8 == state.arch.bits
1763
+ and jumptable_addr.op == "__add__"
1764
+ ):
1765
+ # Undetermined table size. Take a guess based on target plausibility.
1766
+ table_base_addr = None
1767
+ for arg in jumptable_addr.args:
1768
+ if arg.concrete:
1769
+ table_base_addr = state.solver.eval(arg)
1770
+ break
1771
+
1772
+ if table_base_addr is not None:
1773
+ addr = table_base_addr
1774
+ # FIXME: May want to support NULL targets for handlers that are not filled in / placeholders
1775
+ # FIXME: Try negative offsets too? (this would be unusual)
1776
+ l.debug("Inspecting table at %#x for plausible targets...", addr)
1777
+ for i in range(self._max_targets):
1778
+ target = cfg._fast_memory_load_pointer(addr, size=load_size)
1779
+ if target is None or not self._is_jumptarget_legal(target):
1780
+ break
1781
+ l.debug("- %#x[%d] -> %#x", table_base_addr, i, target)
1782
+ jump_table.append(target)
1783
+ addr += jumptable_addr_vsa.stride
1784
+ num_targets = len(jump_table)
1785
+ if num_targets == 0:
1786
+ l.debug("Didn't find any plausible targets in suspected jump table %#x", table_base_addr)
1787
+ elif num_targets == self._max_targets:
1788
+ l.debug(
1789
+ "Reached maximum number of targets (%d) while scanning jump table %#x. It might not be "
1790
+ "a jump table, or the limit might be too low.",
1791
+ num_targets,
1792
+ table_base_addr,
1793
+ )
1794
+ else:
1795
+ l.debug("Table at %#x has %d plausible targets", table_base_addr, num_targets)
1796
+ return jump_table, table_base_addr, load_size, num_targets * load_size, jump_table, sort
1797
+
1798
+ # We resolved too many targets for this indirect jump. Something might have gone wrong.
1799
+ l.debug(
1800
+ "%d targets are resolved for the indirect jump at %#x. It may not be a jump table. Try the "
1801
+ "next source, if there is any.",
1802
+ total_cases,
1803
+ addr,
1804
+ )
1805
+ return None
1806
+
1807
+ # Or alternatively, we can ask user, which is meh...
1808
+ #
1809
+ # jump_base_addr = int(raw_input("please give me the jump base addr: "), 16)
1810
+ # total_cases = int(raw_input("please give me the total cases: "))
1811
+ # jump_target = state.solver.SI(bits=64, lower_bound=jump_base_addr, upper_bound=jump_base_addr +
1812
+ # (total_cases - 1) * 8, stride=8)
1813
+
1814
+ min_jumptable_addr = state.solver.min(jumptable_addr)
1815
+ max_jumptable_addr = state.solver.max(jumptable_addr)
1816
+
1817
+ # Both the min jump target and the max jump target should be within a mapped memory region
1818
+ # i.e., we shouldn't be jumping to the stack or somewhere unmapped
1819
+ if not project.loader.find_segment_containing(min_jumptable_addr) or not project.loader.find_segment_containing(
1820
+ max_jumptable_addr
1821
+ ):
1822
+ if not project.loader.find_section_containing(
1823
+ min_jumptable_addr
1824
+ ) or not project.loader.find_section_containing(max_jumptable_addr):
1825
+ l.debug(
1826
+ "Jump table %#x might have jump targets outside mapped memory regions. "
1827
+ "Continue to resolve it from the next data source.",
1828
+ addr,
1829
+ )
1830
+ return None
1831
+
1832
+ # Load the jump table from memory
1833
+ should_skip = False
1834
+ for idx, a in enumerate(range(min_jumptable_addr, max_jumptable_addr + 1, stride)):
1835
+ if idx % 100 == 0 and idx != 0:
1836
+ l.debug("%d targets have been resolved for the indirect jump at %#x...", idx, addr)
1837
+ if idx >= total_cases:
1838
+ break
1839
+ target = cfg._fast_memory_load_pointer(a, size=load_size)
1840
+ if target is None:
1841
+ l.debug("Cannot load pointer from address %#x. Skip.", a)
1842
+ should_skip = True
1843
+ break
1844
+ all_targets.append(target)
1845
+ if should_skip:
1846
+ return None
1847
+
1848
+ # Adjust entries inside the jump table
1849
+ mask = (2**self.project.arch.bits) - 1
1850
+ transformation_list = list(reversed(list(v for v in transformations.values() if not v.first_load)))
1851
+ if transformation_list:
1852
+
1853
+ def handle_signed_ext(a):
1854
+ return (a | 0xFFFFFFFF00000000) if a >= 0x80000000 else a
1855
+
1856
+ def handle_unsigned_ext(a):
1857
+ return a
1858
+
1859
+ def handle_trunc_64_32(a):
1860
+ return a & 0xFFFFFFFF
1861
+
1862
+ def handle_or1(a):
1863
+ return a | 1
1864
+
1865
+ def handle_lshift(num_bits, a):
1866
+ return a << num_bits
1867
+
1868
+ def handle_rshift(num_bits, a):
1869
+ return a >> num_bits
1870
+
1871
+ def handle_add(con, a):
1872
+ return (a + con) & mask
1873
+
1874
+ def handle_load(size, a):
1875
+ return cfg._fast_memory_load_pointer(a, size=size)
1876
+
1877
+ invert_conversion_ops = []
1878
+ for tran in transformation_list:
1879
+ tran_op, args = tran.op, tran.operands
1880
+ if tran_op is AddressTransformationTypes.SignedExtension:
1881
+ if args == [32, 64, AddressSingleton]:
1882
+ lam = handle_signed_ext
1883
+ else:
1884
+ raise NotImplementedError("Unsupported signed extension operation.")
1885
+ elif tran_op is AddressTransformationTypes.UnsignedExtension:
1886
+ lam = handle_unsigned_ext
1887
+ elif tran_op is AddressTransformationTypes.Truncation:
1888
+ if args == [64, 32, AddressSingleton]:
1889
+ lam = handle_trunc_64_32
1890
+ else:
1891
+ raise NotImplementedError("Unsupported truncation operation.")
1892
+ elif tran_op is AddressTransformationTypes.Or1:
1893
+ lam = handle_or1
1894
+ elif tran_op is AddressTransformationTypes.ShiftLeft:
1895
+ lam = functools.partial(
1896
+ handle_lshift, next(iter(arg for arg in args if arg is not AddressSingleton))
1897
+ )
1898
+ elif tran_op is AddressTransformationTypes.ShiftRight:
1899
+ lam = functools.partial(
1900
+ handle_rshift, next(iter(arg for arg in args if arg is not AddressSingleton))
1901
+ )
1902
+ elif tran_op is AddressTransformationTypes.Add:
1903
+ add_arg = next(iter(arg for arg in args if arg is not AddressSingleton))
1904
+ if not isinstance(add_arg, int):
1905
+ # unsupported cases (Tmp, for example). abort
1906
+ return None
1907
+ lam = functools.partial(handle_add, add_arg)
1908
+ elif tran_op is AddressTransformationTypes.Load:
1909
+ lam = functools.partial(handle_load, args[1])
1910
+ elif tran_op is AddressTransformationTypes.Assignment:
1911
+ continue
1912
+ else:
1913
+ raise NotImplementedError("Unsupported transformation operation.")
1914
+ invert_conversion_ops.append(lam)
1915
+ all_targets_copy = all_targets
1916
+ all_targets = []
1917
+ for target_ in all_targets_copy:
1918
+ for lam in invert_conversion_ops:
1919
+ target_ = lam(target_)
1920
+ if target_ is None:
1921
+ # transformation failed. abort
1922
+ return None
1923
+ all_targets.append(target_)
1924
+ if None in all_targets:
1925
+ return None
1926
+ if len(stmts_adding_base_addr) == 1:
1927
+ stmt_adding_base_addr = stmts_adding_base_addr[0]
1928
+ base_addr = stmt_adding_base_addr.base_addr
1929
+ all_targets = [(target + base_addr) & mask for target in all_targets]
1930
+
1931
+ # special case for ARM: if the source block is in THUMB mode, all jump targets should be in THUMB mode, too
1932
+ if is_arm_arch(self.project.arch) and (addr & 1) == 1:
1933
+ all_targets = [target | 1 for target in all_targets]
1934
+
1935
+ if len(all_targets) == 0:
1936
+ l.debug("Could not recover jump table")
1937
+ return None
1938
+
1939
+ # Finally... all targets are ready
1940
+ illegal_target_found = False
1941
+ for target in all_targets:
1942
+ # if the total number of targets is suspicious (it usually implies a failure in applying the
1943
+ # constraints), check if all jump targets are legal
1944
+ if len(all_targets) in {1, 0x100, 0x10000} and not self._is_jumptarget_legal(target):
1945
+ l.info(
1946
+ "Jump target %#x is probably illegal. Try to resolve indirect jump at %#x from the next source.",
1947
+ target,
1948
+ addr,
1949
+ )
1950
+ illegal_target_found = True
1951
+ break
1952
+ jump_table.append(target)
1953
+ if illegal_target_found:
1954
+ return None
1955
+
1956
+ return jump_table, min_jumptable_addr, load_size, total_cases * load_size, all_targets, sort
1957
+
1958
+ def _try_resolve_targets_ite(
1959
+ self, r, addr, cfg, annotatedcfg, ite_stmt: pyvex.IRStmt.WrTmp
1960
+ ): # pylint:disable=unused-argument
1961
+ """
1962
+ Try loading all jump targets from parsing an ITE block.
1963
+ """
1964
+ project = self.project
1965
+
1966
+ try:
1967
+ whitelist = annotatedcfg.get_whitelisted_statements(r.addr)
1968
+ last_stmt = annotatedcfg.get_last_statement_index(r.addr)
1969
+ succ = project.factory.successors(r, whitelist=whitelist, last_stmt=last_stmt)
1970
+ except (AngrError, SimError):
1971
+ # oops there are errors
1972
+ l.warning("Cannot get jump successor states from a path that has reached the target. Skip it.")
1973
+ return None
1974
+
1975
+ all_states = succ.flat_successors + succ.unconstrained_successors
1976
+ if not all_states:
1977
+ l.warning("Slicecutor failed to execute the program slice. No output state is available.")
1978
+ return None
1979
+
1980
+ state = all_states[0] # Just take the first state
1981
+ temps = state.scratch.temps
1982
+ if not isinstance(ite_stmt.data, pyvex.IRExpr.ITE):
1983
+ return None
1984
+ # load the default
1985
+ if not isinstance(ite_stmt.data.iffalse, pyvex.IRExpr.Const):
1986
+ return None
1987
+ # ite_stmt.data.iffalse.con.value is garbage introduced by the VEX ARM lifter and should be ignored
1988
+ if not isinstance(ite_stmt.data.iftrue, pyvex.IRExpr.RdTmp):
1989
+ return None
1990
+ if not isinstance(ite_stmt.data.cond, pyvex.IRExpr.RdTmp):
1991
+ return None
1992
+ cond = temps[ite_stmt.data.cond.tmp]
1993
+ # apply the constraint
1994
+ state.add_constraints(cond == 1)
1995
+ # load the target
1996
+ target_expr = temps[ite_stmt.data.iftrue.tmp]
1997
+ try:
1998
+ jump_table = state.solver.eval_upto(target_expr, self._max_targets + 1)
1999
+ except SimError:
2000
+ return None
2001
+ entry_size = len(target_expr) // self.project.arch.byte_width
2002
+
2003
+ if len(jump_table) == self._max_targets + 1:
2004
+ # so many targets! failed
2005
+ return None
2006
+
2007
+ return jump_table, len(jump_table), entry_size
2008
+
2009
+ @staticmethod
2010
+ def _instrument_statements(state, stmts_to_instrument, regs_to_initialize):
2011
+ """
2012
+ Hook statements as specified in stmts_to_instrument and overwrite values loaded in those statements.
2013
+
2014
+ :param SimState state: The program state to insert hooks to.
2015
+ :param list stmts_to_instrument: A list of statements to instrument.
2016
+ :param list regs_to_initialize: A list of registers to initialize.
2017
+ :return: None
2018
+ """
2019
+
2020
+ for sort, block_addr, stmt_idx in stmts_to_instrument:
2021
+ l.debug("Add a %s hook to overwrite memory/register values at %#x:%d.", sort, block_addr, stmt_idx)
2022
+ if sort == "mem_write":
2023
+ bp = BP(
2024
+ when=BP_BEFORE,
2025
+ enabled=True,
2026
+ action=StoreHook.hook,
2027
+ condition=lambda _s, a=block_addr, idx=stmt_idx: _s.scratch.bbl_addr == a
2028
+ and _s.scratch.stmt_idx == idx,
2029
+ )
2030
+ state.inspect.add_breakpoint("mem_write", bp)
2031
+ elif sort == "mem_read":
2032
+ hook = LoadHook()
2033
+ bp0 = BP(
2034
+ when=BP_BEFORE,
2035
+ enabled=True,
2036
+ action=hook.hook_before,
2037
+ condition=lambda _s, a=block_addr, idx=stmt_idx: _s.scratch.bbl_addr == a
2038
+ and _s.scratch.stmt_idx == idx,
2039
+ )
2040
+ state.inspect.add_breakpoint("mem_read", bp0)
2041
+ bp1 = BP(
2042
+ when=BP_AFTER,
2043
+ enabled=True,
2044
+ action=hook.hook_after,
2045
+ condition=lambda _s, a=block_addr, idx=stmt_idx: _s.scratch.bbl_addr == a
2046
+ and _s.scratch.stmt_idx == idx,
2047
+ )
2048
+ state.inspect.add_breakpoint("mem_read", bp1)
2049
+ elif sort == "reg_write":
2050
+ bp = BP(
2051
+ when=BP_BEFORE,
2052
+ enabled=True,
2053
+ action=PutHook.hook,
2054
+ condition=lambda _s, a=block_addr, idx=stmt_idx: _s.scratch.bbl_addr == a
2055
+ and _s.scratch.stmt_idx == idx,
2056
+ )
2057
+ state.inspect.add_breakpoint("reg_write", bp)
2058
+ else:
2059
+ raise NotImplementedError("Unsupported sort %s in stmts_to_instrument." % sort)
2060
+
2061
+ reg_val = 0x13370000
2062
+
2063
+ def bp_condition(block_addr, stmt_idx, _s):
2064
+ return _s.scratch.bbl_addr == block_addr and _s.inspect.statement == stmt_idx
2065
+
2066
+ for block_addr, stmt_idx, reg_offset, reg_bits in regs_to_initialize:
2067
+ l.debug(
2068
+ "Add a hook to initialize register %s at %x:%d.",
2069
+ state.arch.translate_register_name(reg_offset, size=reg_bits),
2070
+ block_addr,
2071
+ stmt_idx,
2072
+ )
2073
+ bp = BP(
2074
+ when=BP_BEFORE,
2075
+ enabled=True,
2076
+ action=RegisterInitializerHook(reg_offset, reg_bits, reg_val).hook,
2077
+ condition=functools.partial(bp_condition, block_addr, stmt_idx),
2078
+ )
2079
+ state.inspect.add_breakpoint("statement", bp)
2080
+ reg_val += 16
2081
+
2082
+ def _find_bss_region(self):
2083
+ self._bss_regions = []
2084
+
2085
+ # TODO: support other sections other than '.bss'.
2086
+ # TODO: this is very hackish. fix it after the chaos.
2087
+ for section in self.project.loader.main_object.sections:
2088
+ if section.name == ".bss":
2089
+ self._bss_regions.append((section.vaddr, section.memsize))
2090
+ break
2091
+
2092
+ def _init_registers_on_demand(self, state):
2093
+ # for uninitialized read using a register as the source address, we replace them in memory on demand
2094
+ read_addr = state.inspect.mem_read_address
2095
+ cond = state.inspect.mem_read_condition
2096
+
2097
+ if not isinstance(read_addr, int) and read_addr.uninitialized and cond is None:
2098
+ # if this AST has been initialized before, just use the cached addr
2099
+ cached_addr = self._cached_memread_addrs.get(read_addr, None)
2100
+ if cached_addr is not None:
2101
+ state.inspect.mem_read_address = cached_addr
2102
+ return
2103
+
2104
+ read_length = state.inspect.mem_read_length
2105
+ if not isinstance(read_length, int):
2106
+ read_length = read_length._model_vsa.upper_bound
2107
+ if read_length > 16:
2108
+ return
2109
+ new_read_addr = state.solver.BVV(UninitReadMeta.uninit_read_base, state.arch.bits)
2110
+ UninitReadMeta.uninit_read_base += read_length
2111
+
2112
+ # replace the expression in registers
2113
+ state.registers.replace_all(read_addr, new_read_addr)
2114
+
2115
+ # extra caution: if this read_addr AST comes up again in the future, we want to replace it with the same
2116
+ # address again.
2117
+ self._cached_memread_addrs[read_addr] = new_read_addr
2118
+
2119
+ state.inspect.mem_read_address = new_read_addr
2120
+
2121
+ # job done :-)
2122
+
2123
+ def _dbg_repr_slice(self, blade, in_slice_stmts_only=False):
2124
+ stmts = defaultdict(set)
2125
+
2126
+ for addr, stmt_idx in sorted(list(blade.slice.nodes())):
2127
+ stmts[addr].add(stmt_idx)
2128
+
2129
+ for addr in sorted(stmts.keys()):
2130
+ stmt_ids = stmts[addr]
2131
+ irsb = self.project.factory.block(addr, cross_insn_opt=True, backup_state=self.base_state).vex
2132
+
2133
+ print(" ####")
2134
+ print(" #### Block %#x" % addr)
2135
+ print(" ####")
2136
+
2137
+ for i, stmt in enumerate(irsb.statements):
2138
+ stmt_taken = i in stmt_ids
2139
+ display = stmt_taken if in_slice_stmts_only else True
2140
+ if display:
2141
+ s = "%s %x:%02d | " % ("+" if stmt_taken else " ", addr, i)
2142
+ s += "%s " % stmt.pp_str(arch=self.project.arch, tyenv=irsb.tyenv)
2143
+ if stmt_taken:
2144
+ s += "IN: %d" % blade.slice.in_degree((addr, i))
2145
+ print(s)
2146
+
2147
+ # the default exit
2148
+ default_exit_taken = DEFAULT_STATEMENT in stmt_ids
2149
+ s = "{} {:x}:default | PUT({}) = {}; {}".format(
2150
+ "+" if default_exit_taken else " ", addr, irsb.offsIP, irsb.next, irsb.jumpkind
2151
+ )
2152
+ print(s)
2153
+
2154
+ def _initial_state(self, block_addr, cfg, func_addr: int):
2155
+ add_options = {
2156
+ o.DO_RET_EMULATION,
2157
+ o.TRUE_RET_EMULATION_GUARD,
2158
+ o.AVOID_MULTIVALUED_READS,
2159
+ # Keep IP symbolic to avoid unnecessary concretization
2160
+ o.KEEP_IP_SYMBOLIC,
2161
+ o.NO_IP_CONCRETIZATION,
2162
+ # be quiet!!!!!!
2163
+ o.SYMBOL_FILL_UNCONSTRAINED_REGISTERS,
2164
+ o.SYMBOL_FILL_UNCONSTRAINED_MEMORY,
2165
+ }
2166
+ state = self.project.factory.blank_state(
2167
+ addr=block_addr,
2168
+ mode="static",
2169
+ add_options=add_options,
2170
+ remove_options={
2171
+ o.CGC_ZERO_FILL_UNCONSTRAINED_MEMORY,
2172
+ o.UNINITIALIZED_ACCESS_AWARENESS,
2173
+ }
2174
+ | o.refs,
2175
+ )
2176
+ state.regs._sp = 0x7FFF_FFF0
2177
+
2178
+ # any read from an uninitialized segment should be unconstrained
2179
+ if self._bss_regions:
2180
+ bss_hook = BSSHook(self.project, self._bss_regions)
2181
+ bss_memory_write_bp = BP(when=BP_AFTER, enabled=True, action=bss_hook.bss_memory_write_hook)
2182
+ state.inspect.add_breakpoint("mem_write", bss_memory_write_bp)
2183
+ bss_memory_read_bp = BP(when=BP_BEFORE, enabled=True, action=bss_hook.bss_memory_read_hook)
2184
+ state.inspect.add_breakpoint("mem_read", bss_memory_read_bp)
2185
+
2186
+ if self.project.arch.name == "MIPS32":
2187
+ try:
2188
+ func = cfg.kb.functions.get_by_addr(func_addr)
2189
+ if func.info and "gp" in func.info:
2190
+ state.regs._gp = func.info["gp"]
2191
+ except KeyError:
2192
+ pass
2193
+
2194
+ # instrument all reads from gp and all writes to gp
2195
+ gp = None
2196
+ try:
2197
+ func = cfg.kb.functions.get_by_addr(func_addr)
2198
+ if func.info and "gp" in func.info:
2199
+ gp = func.info["gp"]
2200
+ except KeyError:
2201
+ pass
2202
+ if gp is not None:
2203
+ mips_gp_hook = MIPSGPHook(self.project.arch.registers["gp"][0], gp)
2204
+ mips_gp_read_bp = BP(when=BP_AFTER, enabled=True, action=mips_gp_hook.gp_register_read_hook)
2205
+ mips_gp_write_bp = BP(when=BP_AFTER, enabled=True, action=mips_gp_hook.gp_register_write_hook)
2206
+ state.inspect.add_breakpoint("reg_read", mips_gp_read_bp)
2207
+ state.inspect.add_breakpoint("reg_write", mips_gp_write_bp)
2208
+
2209
+ # FIXME:
2210
+ # this is a hack: for certain architectures, we do not initialize the base pointer, since the jump table on
2211
+ # those architectures may use the bp register to store value
2212
+ if self.project.arch.name not in {"S390X"}:
2213
+ state.regs.bp = state.arch.initial_sp + 0x2000
2214
+
2215
+ return state
2216
+
2217
+ @staticmethod
2218
+ def _parse_load_statement(load_stmt, state):
2219
+ """
2220
+ Parse a memory load VEX statement and get the jump target addresses.
2221
+
2222
+ :param load_stmt: The VEX statement for loading the jump target addresses.
2223
+ :param state: The SimState instance (in static mode).
2224
+ :return: An abstract value (or a concrete value) representing the jump target addresses. Return None
2225
+ if we fail to parse the statement.
2226
+ """
2227
+
2228
+ # The jump table address is stored in a tmp. In this case, we find the jump-target loading tmp.
2229
+ load_addr_tmp = None
2230
+
2231
+ if isinstance(load_stmt, pyvex.IRStmt.WrTmp):
2232
+ if type(load_stmt.data.addr) is pyvex.IRExpr.RdTmp:
2233
+ load_addr_tmp = load_stmt.data.addr.tmp
2234
+ elif type(load_stmt.data.addr) is pyvex.IRExpr.Const:
2235
+ # It's directly loading from a constant address
2236
+ # e.g.,
2237
+ # ldr r0, =main+1
2238
+ # blx r0
2239
+ # It's not a jump table, but we resolve it anyway
2240
+ jump_target_addr = load_stmt.data.addr.con.value
2241
+ return state.solver.BVV(jump_target_addr, state.arch.bits)
2242
+ elif isinstance(load_stmt, pyvex.IRStmt.LoadG):
2243
+ if type(load_stmt.addr) is pyvex.IRExpr.RdTmp:
2244
+ load_addr_tmp = load_stmt.addr.tmp
2245
+ elif type(load_stmt.addr) is pyvex.IRExpr.Const:
2246
+ # It's directly loading from a constant address
2247
+ # e.g.,
2248
+ # 4352c SUB R1, R11, #0x1000
2249
+ # 43530 LDRHI R3, =loc_45450
2250
+ # ...
2251
+ # 43540 MOV PC, R3
2252
+ #
2253
+ # It's not a jump table, but we resolve it anyway
2254
+ # Note that this block has two branches: One goes to 45450, the other one goes to whatever the original
2255
+ # value of R3 is. Some intensive data-flow analysis is required in this case.
2256
+ jump_target_addr = load_stmt.addr.con.value
2257
+ return state.solver.BVV(jump_target_addr, state.arch.bits)
2258
+ else:
2259
+ raise TypeError("Unsupported address loading statement type %s." % type(load_stmt))
2260
+
2261
+ if state.scratch.temps[load_addr_tmp] is None:
2262
+ # the tmp variable is not there... umm...
2263
+ return None
2264
+
2265
+ jump_addr = state.scratch.temps[load_addr_tmp]
2266
+
2267
+ if isinstance(load_stmt, pyvex.IRStmt.LoadG) and not isinstance(load_stmt.guard, pyvex.IRExpr.Const):
2268
+ # LoadG comes with a guard. We should apply this guard to the load expression
2269
+ guard_tmp = load_stmt.guard.tmp
2270
+ guard = state.scratch.temps[guard_tmp] != 0
2271
+ try:
2272
+ jump_addr = state.memory._apply_condition_to_symbolic_addr(jump_addr, guard)
2273
+ except Exception: # pylint: disable=broad-except
2274
+ l.exception("Error computing jump table address!")
2275
+ return None
2276
+ return jump_addr
2277
+
2278
+ def _sp_moved_up(self, block) -> bool:
2279
+ """
2280
+ Examine if the stack pointer moves up (if any values are popped out of the stack) within a single block.
2281
+ """
2282
+
2283
+ spt = self.project.analyses.StackPointerTracker(
2284
+ None, {self.project.arch.sp_offset}, block=block, track_memory=False
2285
+ )
2286
+ offset_after = spt.offset_after(block.addr, self.project.arch.sp_offset)
2287
+ return offset_after is not None and offset_after > 0
2288
+
2289
+ def _is_jumptarget_legal(self, target):
2290
+ try:
2291
+ vex_block = self.project.factory.block(target, cross_insn_opt=True).vex_nostmt
2292
+ except (AngrError, SimError):
2293
+ return False
2294
+ if vex_block.jumpkind == "Ijk_NoDecode":
2295
+ return False
2296
+ if vex_block.size == 0:
2297
+ return False
2298
+ return True
2299
+
2300
+ def _is_address_mapped(self, addr: int) -> bool:
2301
+ return (
2302
+ self.project.loader.find_segment_containing(addr) is not None
2303
+ or self.project.loader.find_section_containing(addr) is not None
2304
+ )
2305
+
2306
+ def _all_qualified_load_stmts_in_slice(self, b: Blade, addr: int) -> list[int]:
2307
+ """
2308
+ Recognize all qualified load statements in a slice. A qualified load statements refers to those that are
2309
+ loading jump targets (or jump offsets) from a jump table, or loading jump table offsets from a jump-table
2310
+ offset table.
2311
+
2312
+ :param b: The Blade object.
2313
+ :param addr: Address of the last block.
2314
+ :return: A list of qualified load statement IDs.
2315
+ """
2316
+
2317
+ stmt_ids = []
2318
+ for block_addr, stmt_id in b.slice.nodes:
2319
+ if block_addr == addr and stmt_id != DEFAULT_STATEMENT:
2320
+ stmt_ids.append(stmt_id)
2321
+
2322
+ if not stmt_ids:
2323
+ return []
2324
+ stmt_ids = sorted(stmt_ids)
2325
+ qualified_load_stmt_ids = []
2326
+ load_stmt_ids = []
2327
+ block = self.project.factory.block(addr, cross_insn_opt=True, backup_state=self.base_state).vex
2328
+ tmp_values = {}
2329
+ mask = (2**self.project.arch.bits) - 1
2330
+ for stmt_id in stmt_ids:
2331
+ stmt = block.statements[stmt_id]
2332
+ if isinstance(stmt, pyvex.IRStmt.WrTmp):
2333
+ if isinstance(stmt.data, pyvex.IRExpr.Const):
2334
+ tmp_values[stmt.tmp] = stmt.data.con.value
2335
+ elif isinstance(stmt.data, pyvex.IRExpr.Binop) and stmt.data.op.startswith("Iop_Add"):
2336
+ op0 = None
2337
+ if isinstance(stmt.data.args[0], pyvex.IRExpr.RdTmp):
2338
+ op0 = tmp_values.get(stmt.data.args[0].tmp, None)
2339
+ elif isinstance(stmt.data.args[0], pyvex.IRExpr.Const):
2340
+ op0 = stmt.data.args[0].con.value
2341
+ op1 = None
2342
+ if isinstance(stmt.data.args[1], pyvex.IRExpr.RdTmp):
2343
+ op1 = tmp_values.get(stmt.data.args[1].tmp, None)
2344
+ elif isinstance(stmt.data.args[1], pyvex.IRExpr.Const):
2345
+ op1 = stmt.data.args[1].con.value
2346
+ if isinstance(op1, int) and not isinstance(op0, int):
2347
+ op0, op1 = op1, op0
2348
+ if isinstance(op0, int):
2349
+ if op1 is None:
2350
+ tmp_values[stmt.tmp] = ("+", op0, op1)
2351
+ elif isinstance(op1, int):
2352
+ tmp_values[stmt.tmp] = (op0 + op1) & mask
2353
+ elif isinstance(op1, tuple) and op1[0] == "+":
2354
+ tmp_values[stmt.tmp] = ("+", (op0 + op1[1]) & mask, op1[2])
2355
+ elif isinstance(stmt.data, pyvex.IRExpr.Load) and isinstance(stmt.data.addr, pyvex.IRExpr.RdTmp):
2356
+ # is this load statement loading from a static address + an offset?
2357
+ v = tmp_values.get(stmt.data.addr.tmp, None)
2358
+ if isinstance(v, tuple) and v[0] == "+" and v[2] is None and self._is_address_mapped(v[1]):
2359
+ qualified_load_stmt_ids.append(stmt_id)
2360
+ load_stmt_ids.append(stmt_id)
2361
+ if qualified_load_stmt_ids and len(qualified_load_stmt_ids) <= 2:
2362
+ return qualified_load_stmt_ids
2363
+ if load_stmt_ids:
2364
+ return [load_stmt_ids[-1]]
2365
+ return []
2366
+
2367
+
2368
+ from angr.analyses.propagator import PropagatorAnalysis