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,2970 @@
1
+ from typing import TYPE_CHECKING
2
+ import logging
3
+ import re
4
+ import string
5
+ import struct
6
+ from collections import defaultdict
7
+ from itertools import count
8
+
9
+ import capstone
10
+ import cle
11
+ import networkx
12
+ import pyvex
13
+
14
+ from . import Analysis
15
+ from .cfg.cfg_emulated import CFGEmulated
16
+ from .ddg import DDG
17
+ from .cfg.cfg_fast import CFGFast
18
+ from ..codenode import CodeNode
19
+ from ..knowledge_plugins.cfg.memory_data import MemoryDataSort
20
+ from ..knowledge_plugins.functions import Function
21
+ from ..knowledge_base import KnowledgeBase
22
+ from ..sim_variable import SimMemoryVariable, SimTemporaryVariable
23
+
24
+ if TYPE_CHECKING:
25
+ from .cfg import CFGNode
26
+
27
+ l = logging.getLogger(name=__name__)
28
+
29
+
30
+ #
31
+ # Exceptions
32
+ #
33
+
34
+
35
+ class BinaryError(Exception):
36
+ pass
37
+
38
+
39
+ class InstructionError(BinaryError):
40
+ pass
41
+
42
+
43
+ class ReassemblerFailureNotice(BinaryError):
44
+ pass
45
+
46
+
47
+ #
48
+ # Constants
49
+ #
50
+
51
+ OP_TYPE_REG = 1
52
+ OP_TYPE_IMM = 2
53
+ OP_TYPE_MEM = 3
54
+ OP_TYPE_RAW = 4
55
+
56
+ OP_TYPE_MAP = {
57
+ OP_TYPE_REG: "REG",
58
+ OP_TYPE_IMM: "IMM",
59
+ OP_TYPE_MEM: "MEM",
60
+ OP_TYPE_RAW: "RAW",
61
+ }
62
+
63
+ CAPSTONE_OP_TYPE_MAP = {
64
+ "X86": {
65
+ capstone.x86.X86_OP_REG: OP_TYPE_REG,
66
+ capstone.x86.X86_OP_IMM: OP_TYPE_IMM,
67
+ capstone.x86.X86_OP_MEM: OP_TYPE_MEM,
68
+ },
69
+ "AMD64": {
70
+ capstone.x86.X86_OP_REG: OP_TYPE_REG,
71
+ capstone.x86.X86_OP_IMM: OP_TYPE_IMM,
72
+ capstone.x86.X86_OP_MEM: OP_TYPE_MEM,
73
+ },
74
+ }
75
+
76
+ CAPSTONE_REG_MAP = {
77
+ # will be filled up by fill_reg_map()
78
+ "X86": {},
79
+ "AMD64": {},
80
+ }
81
+
82
+ # Utils
83
+
84
+
85
+ def string_escape(s):
86
+ if isinstance(s, bytes):
87
+ s = "".join(chr(i) for i in s)
88
+
89
+ s = s.encode("unicode_escape").decode("utf-8")
90
+
91
+ s = s.replace("\\'", "'")
92
+ s = s.replace('"', '\\"')
93
+
94
+ return s
95
+
96
+
97
+ def fill_reg_map():
98
+ # TODO: Support more architectures
99
+ for attr in dir(capstone.x86):
100
+ if attr.startswith("X86_REG_"):
101
+ reg_name = attr[8:]
102
+ reg_offset = getattr(capstone.x86, attr)
103
+ CAPSTONE_REG_MAP["X86"][reg_offset] = reg_name.lower()
104
+
105
+ for attr in dir(capstone.x86):
106
+ if attr.startswith("X86_REG_"):
107
+ reg_name = attr[8:]
108
+ reg_offset = getattr(capstone.x86, attr)
109
+ CAPSTONE_REG_MAP["AMD64"][reg_offset] = reg_name.lower()
110
+
111
+
112
+ def split_operands(s):
113
+ operands = []
114
+ operand = ""
115
+ in_paranthesis = False
116
+ for i, c in enumerate(s):
117
+ if in_paranthesis and c == ")":
118
+ in_paranthesis = False
119
+ if c == "(":
120
+ in_paranthesis = True
121
+ if not in_paranthesis and c == "," and (i == len(s) - 1 or s[i + 1] == " "):
122
+ operands.append(operand)
123
+ operand = ""
124
+ continue
125
+ operand += c
126
+
127
+ if operand:
128
+ operands.append(operand)
129
+
130
+ return operands
131
+
132
+
133
+ def is_hex(s):
134
+ try:
135
+ int(s, 16)
136
+ return True
137
+ except ValueError:
138
+ return False
139
+
140
+
141
+ fill_reg_map()
142
+
143
+
144
+ class Label:
145
+ g_label_ctr = count()
146
+
147
+ def __init__(self, binary, name, original_addr=None):
148
+ self.binary = binary
149
+ self.name = name
150
+
151
+ self.assigned = False
152
+
153
+ self.var_size = None
154
+
155
+ if self.name is None:
156
+ self.name = "label_%d" % next(Label.g_label_ctr)
157
+
158
+ self.original_addr = original_addr
159
+ self.base_addr = None
160
+
161
+ #
162
+ # Overridden predefined methods
163
+ #
164
+
165
+ def __str__(self):
166
+ """
167
+
168
+ :return:
169
+ """
170
+
171
+ # if self.var_size is not None:
172
+ # s = ".type {name},@object\n.comm {name},{size},{size}".format(name=self.name, size=self.var_size)
173
+ # else:
174
+ s = f".{self.name}:"
175
+ return s
176
+
177
+ def __hash__(self):
178
+ return hash(self.name)
179
+
180
+ def __eq__(self, other):
181
+ return self.name == other.name
182
+
183
+ #
184
+ # Properties
185
+ #
186
+
187
+ @property
188
+ def operand_str(self):
189
+ if self.base_addr is None:
190
+ return ".%s" % self.name
191
+ else:
192
+ offset = self.offset
193
+ sign = "+" if offset >= 0 else "-"
194
+ offset = abs(offset)
195
+ return ".%s%s%d" % (self.name, sign, offset)
196
+
197
+ @property
198
+ def offset(self):
199
+ if self.base_addr is None:
200
+ return 0
201
+ return self.original_addr - self.base_addr
202
+
203
+ #
204
+ # Static methods
205
+ #
206
+
207
+ @staticmethod
208
+ def new_label(binary, name=None, function_name=None, original_addr=None, data_label=False):
209
+ if function_name is not None:
210
+ return FunctionLabel(binary, function_name, original_addr)
211
+ elif data_label:
212
+ return DataLabel(binary, original_addr)
213
+ else:
214
+ return Label(binary, name, original_addr=original_addr)
215
+
216
+
217
+ class DataLabel(Label):
218
+ def __init__(self, binary, original_addr, name=None):
219
+ Label.__init__(self, binary, name, original_addr=original_addr)
220
+
221
+ @property
222
+ def operand_str(self):
223
+ if self.base_addr is None:
224
+ return self.name
225
+ else:
226
+ offset = self.offset
227
+ sign = "+" if offset >= 0 else "-"
228
+ offset = abs(offset)
229
+ return f"({self.name}{sign}{offset})"
230
+
231
+ def __str__(self):
232
+ # if self.var_size is not None:
233
+ # s = ".comm {name},{size},{size}".format(name=self.name, size=self.var_size)
234
+ # else:
235
+ s = "%s:" % (self.name)
236
+ return s
237
+
238
+
239
+ class FunctionLabel(Label):
240
+ def __init__(self, binary, function_name, original_addr, plt=False):
241
+ Label.__init__(self, binary, function_name, original_addr=original_addr)
242
+
243
+ self.plt = plt
244
+
245
+ @property
246
+ def function_name(self):
247
+ return self.name
248
+
249
+ @property
250
+ def operand_str(self):
251
+ return self.name
252
+
253
+ def __str__(self):
254
+ return ("\t.globl {func_name}\n" + "\t.type {func_name}, @function\n" + "{func_name}:").format(
255
+ func_name=self.function_name
256
+ )
257
+
258
+
259
+ class ObjectLabel(Label):
260
+ def __init__(self, binary, symbol_name, original_addr, plt=False):
261
+ Label.__init__(self, binary, symbol_name, original_addr=original_addr)
262
+
263
+ self.plt = plt
264
+
265
+ @property
266
+ def symbol_name(self):
267
+ return self.name
268
+
269
+ @property
270
+ def operand_str(self):
271
+ return self.name
272
+
273
+ def __str__(self):
274
+ return ("\t.globl {symbol_name}\n" + "\t.type {symbol_name}, @object\n" + "{symbol_name}:").format(
275
+ symbol_name=self.symbol_name
276
+ )
277
+
278
+
279
+ class NotypeLabel(Label):
280
+ def __init__(self, binary, symbol_name, original_addr, plt=False):
281
+ Label.__init__(self, binary, symbol_name, original_addr=original_addr)
282
+
283
+ self.plt = plt
284
+
285
+ @property
286
+ def symbol_name(self):
287
+ return self.name
288
+
289
+ @property
290
+ def operand_str(self):
291
+ return self.name
292
+
293
+ def __str__(self):
294
+ return ("\t.globl {symbol_name}\n" + "\t.type {symbol_name}, @notype\n" + "{symbol_name}:").format(
295
+ symbol_name=self.symbol_name
296
+ )
297
+
298
+
299
+ class SymbolManager:
300
+ """
301
+ SymbolManager manages all symbols in the binary.
302
+ """
303
+
304
+ def __init__(self, binary, cfg):
305
+ """
306
+ Constructor.
307
+
308
+ :param Reassembler binary: The Binary analysis instance.
309
+ :param angr.analyses.CFG cfg: The CFG analysis instance.
310
+ :return: None
311
+ """
312
+
313
+ self.binary = binary
314
+ self.project = binary.project
315
+ self.cfg = cfg
316
+
317
+ self.addr_to_label = defaultdict(list)
318
+ self.symbol_names = set() # deduplicate symbol names
319
+
320
+ def get_unique_symbol_name(self, symbol_name):
321
+ if symbol_name not in self.symbol_names:
322
+ self.symbol_names.add(symbol_name)
323
+ return symbol_name
324
+
325
+ i = 0
326
+ while True:
327
+ name = "%s_%d" % (symbol_name, i)
328
+ if name not in self.symbol_names:
329
+ self.symbol_names.add(name)
330
+ return name
331
+ i += 1
332
+
333
+ def new_label(self, addr, name=None, is_function=None, force=False):
334
+ if force:
335
+ if self.binary.main_nonexecutable_regions_contain(addr):
336
+ label = DataLabel(self.binary, addr, name=name)
337
+ else:
338
+ label = Label.new_label(self.binary, name=name, original_addr=addr)
339
+ self.addr_to_label[addr].append(label)
340
+ return label
341
+
342
+ if addr in self.addr_to_label:
343
+ return self.addr_to_label[addr][0]
344
+
345
+ # Check if the address points to a function by checking the plt of main binary
346
+ reverse_plt = self.project.loader.main_object.reverse_plt
347
+
348
+ if addr in reverse_plt:
349
+ # It's a PLT entry!
350
+ label = FunctionLabel(self.binary, reverse_plt[addr], addr, plt=True)
351
+ elif addr is not None and self.project.loader.find_symbol(addr) is not None:
352
+ # It's an extern symbol
353
+ symbol = self.project.loader.find_symbol(addr)
354
+ if symbol.owner is self.project.loader.main_object:
355
+ symbol_name = symbol.name
356
+ if "@" in symbol_name:
357
+ symbol_name = symbol_name[: symbol_name.index("@")]
358
+
359
+ # check the type...
360
+ if symbol.type == cle.SymbolType.TYPE_FUNCTION:
361
+ # it's a function!
362
+ unique_symbol_name = self.get_unique_symbol_name(symbol_name)
363
+ label = FunctionLabel(self.binary, unique_symbol_name, addr)
364
+ elif symbol.type == cle.SymbolType.TYPE_OBJECT:
365
+ # it's an object
366
+ unique_symbol_name = self.get_unique_symbol_name(symbol_name)
367
+ label = ObjectLabel(self.binary, unique_symbol_name, addr)
368
+ elif symbol.type == cle.SymbolType.TYPE_NONE:
369
+ # notype
370
+ unique_symbol_name = self.get_unique_symbol_name(symbol_name)
371
+ label = NotypeLabel(self.binary, unique_symbol_name, addr)
372
+ elif symbol.type == cle.SymbolType.TYPE_SECTION:
373
+ # section label
374
+ # use a normal label instead
375
+ if not name:
376
+ # handle empty names
377
+ name = None
378
+ label = Label.new_label(self.binary, name=name, original_addr=addr)
379
+ else:
380
+ raise Exception("Unsupported symbol type %s. Bug Fish about it!" % symbol.type)
381
+
382
+ else:
383
+ raise Exception(
384
+ "the symbol %s is not owned by the main object. Try reload the project with"
385
+ '"auto_load_libs=False". If that does not solve the issue, please report to GitHub.' % symbol.name
386
+ )
387
+
388
+ elif (addr is not None and addr in self.cfg.functions) or is_function:
389
+ # It's a function identified by angr's CFG recovery
390
+
391
+ if is_function and name is not None:
392
+ function_name = name
393
+ else:
394
+ function_name = self.cfg.functions[addr].name
395
+
396
+ # special function name for entry point
397
+ if addr == self.project.entry:
398
+ function_name = "_start"
399
+
400
+ label = FunctionLabel(self.binary, function_name, addr)
401
+ elif addr is not None and self.binary.main_nonexecutable_regions_contain(addr):
402
+ label = DataLabel(self.binary, addr)
403
+ else:
404
+ label = Label.new_label(self.binary, name=name, original_addr=addr)
405
+
406
+ if addr is not None:
407
+ self.addr_to_label[addr].append(label)
408
+
409
+ return label
410
+
411
+ def label_got(self, addr, label):
412
+ """
413
+ Mark a certain label as assigned (to an instruction or a block of data).
414
+
415
+ :param int addr: The address of the label.
416
+ :param angr.analyses.reassembler.Label label:
417
+ The label that is just assigned.
418
+ :return: None
419
+ """
420
+
421
+ if label in self.addr_to_label[addr]:
422
+ label.assigned = True
423
+
424
+
425
+ class Operand:
426
+ def __init__(
427
+ self, binary, insn_addr, insn_size, capstone_operand, operand_str, mnemonic, operand_offset, syntax=None
428
+ ):
429
+ """
430
+ Constructor.
431
+
432
+ :param Reassembler binary: The Binary analysis.
433
+ :param int insn_addr: Address of the instruction.
434
+ :param capstone_operand:
435
+ :param str operand_str: the string representation of this operand
436
+ :param str mnemonic: Mnemonic of the instruction that this operand belongs to.
437
+ :param int operand_offset: offset of the operand into the instruction.
438
+ :param str syntax: Provide a way to override the default syntax coming from `binary`.
439
+ :return: None
440
+ """
441
+
442
+ self.binary = binary
443
+ self.project = binary.project
444
+ self.insn_addr = insn_addr
445
+ self.insn_size = insn_size
446
+ self.operand_str = operand_str
447
+ self.mnemonic = mnemonic
448
+ self.operand_offset = operand_offset
449
+ self.syntax = self.binary.syntax if syntax is None else syntax
450
+ self.type = None
451
+ self.size = capstone_operand.size
452
+
453
+ # IMM
454
+ self.is_coderef = None
455
+ self.is_dataref = None
456
+ self.label = None
457
+ self.label_offset = 0
458
+
459
+ # MEM
460
+ self.base = None
461
+ self.index = None
462
+ self.scale = None
463
+ self.disp = None
464
+
465
+ # RAW
466
+ self.raw_asm = None
467
+
468
+ self.disp_is_coderef = None
469
+ self.disp_is_dataref = None
470
+ self.disp_label = None
471
+ self.disp_label_offset = 0
472
+
473
+ self._initialize(capstone_operand)
474
+
475
+ #
476
+ # Public methods
477
+ #
478
+
479
+ def assembly(self):
480
+ if self.type == OP_TYPE_IMM and self.label:
481
+ if self.label_offset > 0:
482
+ return "%s + %d" % (self.label.operand_str, self.label_offset)
483
+ elif self.label_offset < 0:
484
+ return "%s - %d" % (self.label.operand_str, abs(self.label_offset))
485
+ else:
486
+ return self.label.operand_str
487
+
488
+ elif self.type == OP_TYPE_MEM:
489
+ disp = ""
490
+ if self.disp:
491
+ if self.disp_label:
492
+ if self.disp_label_offset > 0:
493
+ disp = "%s + %d" % (self.disp_label.operand_str, self.disp_label_offset)
494
+ elif self.disp_label_offset < 0:
495
+ disp = "%s - %d" % (self.disp_label.operand_str, abs(self.disp_label_offset))
496
+ else:
497
+ disp = self.disp_label.operand_str
498
+ else:
499
+ disp = "%d" % self.disp
500
+
501
+ base = ""
502
+ if self.base:
503
+ base = CAPSTONE_REG_MAP[self.project.arch.name][self.base]
504
+
505
+ if self.syntax == "at&t":
506
+ # displacement(base, index, scale)
507
+ base = "%%%s" % base if base else ""
508
+
509
+ if "*" in self.operand_str and disp:
510
+ # absolute memory address
511
+ disp = "*" + disp
512
+
513
+ if self.index:
514
+ s = "%s(%s, %%%s, %d)" % (
515
+ disp,
516
+ base,
517
+ CAPSTONE_REG_MAP[self.project.arch.name][self.index],
518
+ self.scale,
519
+ )
520
+ elif self.base: # not self.index
521
+ s = f"{disp}({base})"
522
+ else:
523
+ s = disp
524
+
525
+ return s
526
+
527
+ else:
528
+ s = []
529
+ if base:
530
+ s.append(base)
531
+
532
+ if self.index and self.scale:
533
+ if s:
534
+ s.append("+")
535
+ s.append("(%s * %d)" % (CAPSTONE_REG_MAP[self.project.arch.name][self.index], self.scale))
536
+
537
+ if disp:
538
+ if disp.startswith("-"):
539
+ s.append("-")
540
+ s.append(disp[1:])
541
+ else:
542
+ if s:
543
+ s.append("+")
544
+ s.append(disp)
545
+
546
+ asm = " ".join(s)
547
+
548
+ # we need to specify the size here
549
+ if self.size == 16:
550
+ asm = "xmmword ptr [%s]" % asm
551
+ elif self.size == 10:
552
+ asm = "xword ptr [%s]" % asm
553
+ elif self.size == 8:
554
+ asm = "qword ptr [%s]" % asm
555
+ elif self.size == 4:
556
+ asm = "dword ptr [%s]" % asm
557
+ elif self.size == 2:
558
+ asm = "word ptr [%s]" % asm
559
+ elif self.size == 1:
560
+ asm = "byte ptr [%s]" % asm
561
+ else:
562
+ raise BinaryError('Unsupported memory operand size for operand "%s"' % self.operand_str)
563
+
564
+ return asm
565
+
566
+ elif self.type == OP_TYPE_RAW:
567
+ return self.raw_asm
568
+
569
+ else:
570
+ # Nothing special
571
+ return None
572
+
573
+ #
574
+ # Overridden predefined methods
575
+ #
576
+
577
+ def __str__(self):
578
+ """
579
+
580
+ :return:
581
+ """
582
+
583
+ op_type = OP_TYPE_MAP[self.type]
584
+
585
+ ref_type = ""
586
+ if self.is_coderef:
587
+ ref_type = "CODEREF"
588
+ elif self.is_dataref:
589
+ ref_type = "DATAREF"
590
+
591
+ if ref_type:
592
+ return f"{op_type} <{ref_type}>"
593
+ else:
594
+ return op_type
595
+
596
+ #
597
+ # Properties
598
+ #
599
+
600
+ @property
601
+ def is_immediate(self):
602
+ return self.type == OP_TYPE_IMM
603
+
604
+ @property
605
+ def symbolized(self):
606
+ return self.label is not None or self.disp_label is not None
607
+
608
+ #
609
+ # Private methods
610
+ #
611
+
612
+ def _initialize(self, capstone_operand):
613
+ arch_name = self.project.arch.name
614
+ self.type = CAPSTONE_OP_TYPE_MAP[arch_name][capstone_operand.type]
615
+
616
+ if self.type == OP_TYPE_IMM:
617
+ # Check if this is a reference to code
618
+ imm = capstone_operand.imm
619
+
620
+ self.is_coderef, self.is_dataref, baseaddr = self._imm_to_ptr(imm, self.type, self.mnemonic)
621
+
622
+ if self.is_coderef or self.is_dataref:
623
+ self.label = self.binary.symbol_manager.new_label(addr=baseaddr)
624
+ self.label_offset = imm - baseaddr
625
+
626
+ if self.mnemonic.startswith("j") or self.mnemonic.startswith("loop"):
627
+ sort = "jump"
628
+ elif self.mnemonic.startswith("call"):
629
+ sort = "call"
630
+ else:
631
+ sort = "absolute"
632
+ self.binary.register_instruction_reference(self.insn_addr, imm, sort, self.operand_offset)
633
+
634
+ elif self.type == OP_TYPE_MEM:
635
+ self.base = capstone_operand.mem.base
636
+ self.index = capstone_operand.mem.index
637
+ self.scale = capstone_operand.mem.scale
638
+ self.disp = capstone_operand.mem.disp
639
+
640
+ if self.binary.project.arch.name == "AMD64" and CAPSTONE_REG_MAP["AMD64"][self.base] == "rip":
641
+ # rip-relative addressing
642
+ self.disp += self.insn_addr + self.insn_size
643
+
644
+ self.disp_is_coderef, self.disp_is_dataref, baseaddr = self._imm_to_ptr(self.disp, self.type, self.mnemonic)
645
+
646
+ if self.disp_is_coderef or self.disp_is_dataref:
647
+ self.disp_label = self.binary.symbol_manager.new_label(addr=baseaddr)
648
+ self.disp_label_offset = self.disp - baseaddr
649
+
650
+ self.binary.register_instruction_reference(self.insn_addr, self.disp, "absolute", self.operand_offset)
651
+
652
+ def _imm_to_ptr(self, imm, operand_type, mnemonic): # pylint:disable=no-self-use,unused-argument
653
+ """
654
+ Try to classify an immediate as a pointer.
655
+
656
+ :param int imm: The immediate to test.
657
+ :param int operand_type: Operand type of this operand, can either be IMM or MEM.
658
+ :param str mnemonic: Mnemonic of the instruction that this operand belongs to.
659
+ :return: A tuple of (is code reference, is data reference, base address, offset)
660
+ :rtype: tuple
661
+ """
662
+
663
+ is_coderef, is_dataref = False, False
664
+ baseaddr = None
665
+
666
+ if not is_coderef and not is_dataref:
667
+ if self.binary.main_executable_regions_contain(imm):
668
+ # does it point to the beginning of an instruction?
669
+ if imm in self.binary.all_insn_addrs:
670
+ is_coderef = True
671
+ baseaddr = imm
672
+
673
+ if not is_coderef and not is_dataref:
674
+ if self.binary.main_nonexecutable_regions_contain(imm):
675
+ is_dataref = True
676
+ baseaddr = imm
677
+
678
+ if not is_coderef and not is_dataref:
679
+ tolerance_before = 1024 if operand_type == OP_TYPE_MEM else 64
680
+ contains_, baseaddr_ = self.binary.main_nonexecutable_region_limbos_contain(
681
+ imm, tolerance_before=tolerance_before, tolerance_after=1024
682
+ )
683
+ if contains_:
684
+ is_dataref = True
685
+ baseaddr = baseaddr_
686
+
687
+ if not contains_:
688
+ contains_, baseaddr_ = self.binary.main_executable_region_limbos_contain(imm)
689
+ if contains_:
690
+ is_coderef = True
691
+ baseaddr = baseaddr_
692
+
693
+ return (is_coderef, is_dataref, baseaddr)
694
+
695
+
696
+ class Instruction:
697
+ """
698
+ High-level representation of an instruction in the binary
699
+ """
700
+
701
+ def __init__(self, binary, addr, size, insn_bytes, capstone_instr):
702
+ """
703
+
704
+ :param Reassembler binary: The Binary analysis
705
+ :param int addr: Address of the instruction
706
+ :param int size: Size of the instruction
707
+ :param str insn_bytes: Instruction bytes
708
+ :param capstone_instr: Capstone Instr object.
709
+ :return: None
710
+ """
711
+
712
+ self.binary = binary
713
+ self.project = binary.project
714
+ self.addr = addr
715
+ self.size = size
716
+ self.bytes = insn_bytes
717
+
718
+ self.mnemonic = capstone_instr.mnemonic
719
+ self.op_str = capstone_instr.op_str
720
+ self.capstone_operand_types = [operand.type for operand in capstone_instr.operands]
721
+
722
+ self.operands = []
723
+
724
+ self.labels = []
725
+
726
+ operand_offsets = []
727
+ for operand in capstone_instr.operands:
728
+ if operand.type == capstone.CS_OP_IMM:
729
+ operand_offsets.append(capstone_instr.imm_offset)
730
+ elif operand.type == capstone.CS_OP_MEM:
731
+ operand_offsets.append(capstone_instr.disp_offset)
732
+ else:
733
+ operand_offsets.append(0)
734
+
735
+ if self.addr is not None:
736
+ self._initialize(capstone_instr.operands, operand_offsets)
737
+
738
+ #
739
+ # Overridden predefined instructions
740
+ #
741
+ def __str__(self):
742
+ """
743
+
744
+ :return:
745
+ """
746
+
747
+ assembly = self.assembly(comments=True, symbolized=False)
748
+ return assembly
749
+
750
+ #
751
+ # Public methods
752
+ #
753
+
754
+ def assign_labels(self):
755
+ if self.addr in self.binary.symbol_manager.addr_to_label:
756
+ labels = self.binary.symbol_manager.addr_to_label[self.addr]
757
+ for label in labels:
758
+ if label not in self.labels:
759
+ self.labels.append(label)
760
+
761
+ def dbg_comments(self):
762
+ operands = ", ".join([str(operand) for operand in self.operands])
763
+ capstone_str = f"{self.addr:#08x}:\t{self.mnemonic}\t{self.op_str}"
764
+ comments = f"\t# {capstone_str} [{operands}]"
765
+
766
+ return comments
767
+
768
+ def assembly(self, comments=False, symbolized=True):
769
+ """
770
+
771
+ :return:
772
+ """
773
+
774
+ if comments:
775
+ dbg_comments = self.dbg_comments()
776
+ else:
777
+ dbg_comments = ""
778
+
779
+ labels = "\n".join([str(lbl) for lbl in self.labels])
780
+
781
+ inserted_asm_before_label = ""
782
+ if self.addr in self.binary.inserted_asm_before_label:
783
+ # put all assembly code there
784
+ if comments:
785
+ inserted_asm_before_label += "\t# Inserted assembly code (before label):\n"
786
+ inserted_asm_before_label = "\n".join(self.binary.inserted_asm_before_label[self.addr])
787
+ inserted_asm_before_label += "\n"
788
+
789
+ inserted_asm_after_label = ""
790
+ if self.addr in self.binary.inserted_asm_after_label:
791
+ # put all assembly code there
792
+ if comments:
793
+ inserted_asm_after_label += "\t# Inserted assembly code (after label):\n"
794
+ inserted_asm_after_label = "\n".join(self.binary.inserted_asm_after_label[self.addr])
795
+ inserted_asm_after_label += "\n"
796
+
797
+ not_symbolized = f"\t{self.mnemonic}\t{self.op_str}"
798
+ if not symbolized:
799
+ asm = not_symbolized
800
+
801
+ elif not any([(operand.symbolized or operand.type == OP_TYPE_RAW) for operand in self.operands]):
802
+ # No label is involved
803
+ asm = not_symbolized
804
+
805
+ elif not self.operands:
806
+ # There is no operand
807
+ asm = not_symbolized
808
+
809
+ else:
810
+ # Now it's the tricky part. capstone doesn't give us anyway to print individual operand. We gotta parse it
811
+ # by ourselves
812
+ # Remove the address
813
+ # capstone_str = capstone_str[capstone_str.find('\t') + 1 : ]
814
+
815
+ all_operands = [operand.operand_str for operand in self.operands]
816
+ mnemonic = self.mnemonic
817
+
818
+ for i, op in enumerate(self.operands):
819
+ op_asm = op.assembly()
820
+ if op_asm is not None:
821
+ if op.type in (OP_TYPE_IMM, OP_TYPE_MEM, OP_TYPE_RAW):
822
+ all_operands[i] = op_asm
823
+ else:
824
+ raise BinaryError("Unsupported operand type %d." % op.type)
825
+
826
+ if op.type != OP_TYPE_RAW and self.capstone_operand_types[i] == capstone.CS_OP_IMM:
827
+ if mnemonic.startswith("j") or mnemonic.startswith("call") or mnemonic.startswith("loop"):
828
+ pass
829
+ else:
830
+ # mark the size of the variable
831
+ if op.is_dataref:
832
+ op.label.var_size = op.size
833
+ if self.binary.syntax == "at&t":
834
+ all_operands[i] = "$" + all_operands[i]
835
+ else:
836
+ all_operands[i] = "OFFSET FLAT:" + all_operands[i]
837
+
838
+ asm = "\t{}{}".format(mnemonic, "\t" + ", ".join(all_operands))
839
+
840
+ if self.addr in self.binary._removed_instructions:
841
+ contents = [dbg_comments, inserted_asm_before_label, labels, inserted_asm_after_label]
842
+ else:
843
+ contents = [dbg_comments, inserted_asm_before_label, labels, inserted_asm_after_label, asm]
844
+ contents = [a for a in contents if a]
845
+
846
+ return "\n".join(contents)
847
+
848
+ #
849
+ # Private methods
850
+ #
851
+
852
+ def _initialize(self, capstone_operands, operand_offsets):
853
+ """
854
+ Initialize this object
855
+
856
+ :return: None
857
+ """
858
+
859
+ if self.addr is None:
860
+ raise InstructionError("self.addr must be specified")
861
+
862
+ self._initialize_operands(capstone_operands, operand_offsets)
863
+
864
+ def _initialize_operands(self, capstone_operands, operand_offsets):
865
+ """
866
+
867
+ :return:
868
+ """
869
+
870
+ all_operands = split_operands(self.op_str)
871
+ capstone_operands = capstone_operands[
872
+ -len(all_operands) :
873
+ ] # sometimes there are more operands than expected...
874
+ operand_offsets = operand_offsets[-len(all_operands) :]
875
+
876
+ for operand, operand_str, offset in zip(capstone_operands, all_operands, operand_offsets):
877
+ self.operands.append(
878
+ Operand(self.binary, self.addr, self.size, operand, operand_str, self.mnemonic, offset)
879
+ )
880
+
881
+
882
+ class BasicBlock:
883
+ """
884
+ BasicBlock represents a basic block in the binary.
885
+ """
886
+
887
+ def __init__(self, binary, addr, size, x86_getpc_retsite: bool = False):
888
+ """
889
+ Constructor.
890
+
891
+ :param Reassembler binary: The Binary analysis.
892
+ :param int addr: Address of the block
893
+ :param int size: Size of the block
894
+ :return: None
895
+ """
896
+
897
+ self.binary = binary
898
+ self.project = binary.project
899
+
900
+ self.addr = addr
901
+ self.size = size
902
+ self.x86_getpc_retsite = x86_getpc_retsite
903
+
904
+ self.instructions = []
905
+
906
+ self._initialize()
907
+
908
+ #
909
+ # Overridden predefined methods
910
+ #
911
+
912
+ def __str__(self):
913
+ """
914
+ Return a linear representation of all instructions in this block.
915
+ :return:
916
+ """
917
+
918
+ return self.assembly(symbolized=False)
919
+
920
+ def __repr__(self):
921
+ return "<BasicBlock %#08x>" % self.addr
922
+
923
+ #
924
+ # Public methods
925
+ #
926
+
927
+ def assign_labels(self):
928
+ for ins in self.instructions:
929
+ ins.assign_labels()
930
+
931
+ def assembly(self, comments=False, symbolized=True):
932
+ s = "\n".join([ins.assembly(comments=comments, symbolized=symbolized) for ins in self.instructions])
933
+
934
+ return s
935
+
936
+ def instruction_addresses(self):
937
+ return sorted([(ins.addr, ins.size) for ins in self.instructions], key=lambda x: x[0])
938
+
939
+ #
940
+ # Private methods
941
+ #
942
+
943
+ def _initialize(self):
944
+ """
945
+
946
+ :return:
947
+ """
948
+
949
+ # re-lifting
950
+ block = self.project.factory.fresh_block(self.addr, self.size)
951
+ capstone_obj = block.capstone
952
+
953
+ # Fill in instructions
954
+ for idx, instr in enumerate(capstone_obj.insns):
955
+ # special handling for X86 PIE binaries
956
+ instruction = Instruction(self.binary, instr.address, instr.size, None, instr)
957
+
958
+ if self.x86_getpc_retsite and idx == 0:
959
+ if (
960
+ self.binary.syntax == "at&t"
961
+ and instr.mnemonic == "addl"
962
+ and instr.operands[1].type == capstone.CS_OP_REG
963
+ and instr.operands[0].type == capstone.CS_OP_IMM
964
+ ):
965
+ instruction.operands[0].type = OP_TYPE_RAW
966
+ instruction.operands[0].raw_asm = "$_GLOBAL_OFFSET_TABLE_"
967
+ elif (
968
+ self.binary.syntax == "intel"
969
+ and instr.mnemonic == "add"
970
+ and instr.operands[0].type == capstone.CS_OP_REG
971
+ and instr.operands[1].type == capstone.CS_OP_IMM
972
+ ):
973
+ instruction.operands[1].type == OP_TYPE_RAW
974
+ instruction.operands[1].raw_asm = "OFFSET FLAG:_GLOBAL_OFFSET_TABLE_"
975
+
976
+ self.instructions.append(instruction)
977
+
978
+ self.instructions = sorted(self.instructions, key=lambda x: x.addr)
979
+
980
+
981
+ class Procedure:
982
+ """
983
+ Procedure in the binary.
984
+ """
985
+
986
+ def __init__(self, binary, function=None, addr=None, size=None, name=None, section=".text", asm_code=None):
987
+ """
988
+ Constructor.
989
+
990
+ :param Reassembler binary: The Binary analysis.
991
+ :param angr.knowledge.Function function: The function it represents
992
+ :param int addr: Address of the function. Not required if `function` is provided.
993
+ :param int size: Size of the function. Not required if `function` is provided.
994
+ :param str section: Which section this function comes from.
995
+ :return: None
996
+ """
997
+
998
+ self.binary = binary
999
+ self.project = binary.project
1000
+
1001
+ if function is None:
1002
+ self.addr = addr
1003
+ self.size = size
1004
+
1005
+ self.function = None
1006
+ self._name = name
1007
+
1008
+ else:
1009
+ self.addr = function.addr
1010
+ self.size = None # FIXME:
1011
+
1012
+ self.function = function
1013
+ self._name = function.name
1014
+
1015
+ self.asm_code = asm_code
1016
+ self.section = section
1017
+
1018
+ self.blocks = []
1019
+
1020
+ self._initialize()
1021
+
1022
+ #
1023
+ # Attributes
1024
+ #
1025
+
1026
+ @property
1027
+ def name(self):
1028
+ """
1029
+ Get function name from the labels of the very first block.
1030
+ :return: Function name if there is any, None otherwise
1031
+ :rtype: string
1032
+ """
1033
+
1034
+ if self._name is not None:
1035
+ return self._name
1036
+
1037
+ if not self.blocks:
1038
+ return None
1039
+
1040
+ if not self.blocks[0].instructions:
1041
+ return None
1042
+
1043
+ if not self.blocks[0].instructions[0].labels:
1044
+ return None
1045
+
1046
+ lbl = self.blocks[0].instructions[0].labels[0]
1047
+
1048
+ if isinstance(lbl, FunctionLabel):
1049
+ return lbl.function_name
1050
+
1051
+ return None
1052
+
1053
+ @property
1054
+ def is_plt(self):
1055
+ """
1056
+ If this function is a PLT entry or not.
1057
+ :return: True if this function is a PLT entry, False otherwise
1058
+ :rtype: bool
1059
+ """
1060
+
1061
+ if self.section == ".plt":
1062
+ return True
1063
+
1064
+ if not self.blocks:
1065
+ return False
1066
+
1067
+ initial_block = next((b for b in self.blocks if b.addr == self.addr), None)
1068
+ if initial_block is None:
1069
+ return False
1070
+
1071
+ if not initial_block.instructions:
1072
+ return False
1073
+
1074
+ if not initial_block.instructions[0].labels:
1075
+ return False
1076
+
1077
+ lbl = initial_block.instructions[0].labels[0]
1078
+
1079
+ if isinstance(lbl, FunctionLabel):
1080
+ return lbl.plt
1081
+
1082
+ return False
1083
+
1084
+ #
1085
+ # Overridden predefined methods
1086
+ #
1087
+ def __str__(self):
1088
+ """
1089
+ Output all instructions of the current procedure
1090
+ :return:
1091
+ """
1092
+
1093
+ return self.assembly(symbolized=False)
1094
+
1095
+ #
1096
+ # Public methods
1097
+ #
1098
+
1099
+ def assign_labels(self):
1100
+ for block in self.blocks:
1101
+ block.assign_labels()
1102
+
1103
+ def assembly(self, comments=False, symbolized=True):
1104
+ """
1105
+ Get the assembly manifest of the procedure.
1106
+
1107
+ :param comments:
1108
+ :param symbolized:
1109
+ :return: A list of tuples (address, basic block assembly), ordered by basic block addresses
1110
+ :rtype: list
1111
+ """
1112
+
1113
+ assembly = []
1114
+
1115
+ header = "\t.section\t{section}\n\t.align\t{alignment}\n".format(
1116
+ section=self.section, alignment=self.binary.section_alignment(self.section)
1117
+ )
1118
+ if self.addr is not None:
1119
+ procedure_name = "%#x" % self.addr
1120
+ else:
1121
+ procedure_name = self._name
1122
+ header += "\t#Procedure %s\n" % procedure_name
1123
+
1124
+ if self._output_function_label:
1125
+ if self.addr:
1126
+ function_label = self.binary.symbol_manager.new_label(self.addr)
1127
+ else:
1128
+ function_label = self.binary.symbol_manager.new_label(None, name=procedure_name, is_function=True)
1129
+ header += str(function_label) + "\n"
1130
+
1131
+ assembly.append((self.addr, header))
1132
+
1133
+ if self.asm_code:
1134
+ s = self.asm_code
1135
+ assembly.append((self.addr, s))
1136
+ elif self.blocks:
1137
+ b: BasicBlock
1138
+ for b in sorted(self.blocks, key=lambda x: x.addr):
1139
+ s = b.assembly(comments=comments, symbolized=symbolized)
1140
+ assembly.append((b.addr, s))
1141
+
1142
+ return assembly
1143
+
1144
+ def instruction_addresses(self):
1145
+ """
1146
+ Get all instruction addresses in the binary.
1147
+
1148
+ :return: A list of sorted instruction addresses.
1149
+ :rtype: list
1150
+ """
1151
+
1152
+ addrs = []
1153
+ b: BasicBlock
1154
+ for b in sorted(self.blocks, key=lambda x: x.addr):
1155
+ addrs.extend(b.instruction_addresses())
1156
+
1157
+ return sorted(set(addrs), key=lambda x: x[0])
1158
+
1159
+ #
1160
+ # Private methods
1161
+ #
1162
+
1163
+ def _initialize(self):
1164
+ if self.function is None:
1165
+ if not self.asm_code:
1166
+ raise BinaryError(
1167
+ "Unsupported procedure type. You must either specify a angr.knowledge.Function "
1168
+ "object, or specify assembly code."
1169
+ )
1170
+
1171
+ else:
1172
+ x86_getpc_retsites = set()
1173
+ if self.project.arch.name == "X86":
1174
+ if "pc_reg" in self.function.info:
1175
+ # this is an x86-PIC function that calls a get_pc thunk
1176
+ # we need to fix the "add e{a,b,c}x, offset" instruction right after the get_pc call
1177
+ # first let's identify which function is the get_pc function
1178
+ for src, dst, data in self.function.transition_graph.edges(data=True):
1179
+ if isinstance(src, CodeNode) and isinstance(dst, Function):
1180
+ if "get_pc" in dst.info:
1181
+ # found it!
1182
+ x86_getpc_retsites.add(src.addr + src.size)
1183
+ for block_addr in self.function.block_addrs:
1184
+ b = BasicBlock(
1185
+ self.binary,
1186
+ block_addr,
1187
+ self.function._block_sizes[block_addr],
1188
+ x86_getpc_retsite=block_addr in x86_getpc_retsites,
1189
+ )
1190
+ self.blocks.append(b)
1191
+
1192
+ self.blocks = sorted(self.blocks, key=lambda x: x.addr)
1193
+
1194
+ @property
1195
+ def _output_function_label(self):
1196
+ """
1197
+ Determines if we want to output the function label in assembly. We output the function label only when the
1198
+ original instruction does not output the function label.
1199
+
1200
+ :return: True if we should output the function label, False otherwise.
1201
+ :rtype: bool
1202
+ """
1203
+
1204
+ if self.asm_code:
1205
+ return True
1206
+ if not self.blocks:
1207
+ return True
1208
+
1209
+ the_block = next((b for b in self.blocks if b.addr == self.addr), None)
1210
+ if the_block is None:
1211
+ return True
1212
+ if not the_block.instructions:
1213
+ return True
1214
+ if not the_block.instructions[0].labels:
1215
+ return True
1216
+ return False
1217
+
1218
+
1219
+ class ProcedureChunk(Procedure):
1220
+ """
1221
+ Procedure chunk.
1222
+ """
1223
+
1224
+ def __init__(self, project, addr, size):
1225
+ """
1226
+ Constructor.
1227
+
1228
+ :param project:
1229
+ :param addr:
1230
+ :param size:
1231
+ :return:
1232
+ """
1233
+
1234
+ Procedure.__init__(self, project, addr=addr, size=size)
1235
+
1236
+
1237
+ class Data:
1238
+ def __init__(
1239
+ self,
1240
+ binary,
1241
+ memory_data=None,
1242
+ section=None,
1243
+ section_name=None,
1244
+ name=None,
1245
+ size=None,
1246
+ sort=None,
1247
+ addr=None,
1248
+ initial_content=None,
1249
+ ):
1250
+ self.binary = binary
1251
+ self.project = binary.project
1252
+ self.memory_data = memory_data
1253
+ self.section = section
1254
+ self.section_name = section.name if section else section_name
1255
+
1256
+ self.addr = addr
1257
+ self.name = name
1258
+ self.size = size
1259
+ self.sort = sort
1260
+ self._initial_content = initial_content # only used by patcherex
1261
+
1262
+ self._content = None
1263
+
1264
+ self.labels = [] # a list of tuples like (address, label)
1265
+ self.end_labels = [] # a list of labels only show up at the end of this memory data entry. mostly because the
1266
+ # data block after this one is removed for some reason. only assigned by other methods.
1267
+
1268
+ self.null_terminated = None
1269
+
1270
+ self.skip = False
1271
+
1272
+ self._initialize()
1273
+
1274
+ def __repr__(self):
1275
+ return "<DataItem %s@%#08x, %d bytes>" % (self.sort, self.addr, self.size)
1276
+
1277
+ @property
1278
+ def content(self):
1279
+ return self._content
1280
+
1281
+ @content.setter
1282
+ def content(self, v):
1283
+ self._content = v
1284
+
1285
+ def shrink(self, new_size):
1286
+ """
1287
+ Reduce the size of this block
1288
+
1289
+ :param int new_size: The new size
1290
+ :return: None
1291
+ """
1292
+ self.size = new_size
1293
+
1294
+ if self.sort == MemoryDataSort.String:
1295
+ self.null_terminated = False # string without the null byte terminator
1296
+ self._content[0] = self._content[0][: self.size]
1297
+
1298
+ elif self.sort == MemoryDataSort.PointerArray:
1299
+ pointer_size = self.binary.project.arch.bytes
1300
+
1301
+ if self.size % pointer_size != 0:
1302
+ # it's not aligned?
1303
+ raise BinaryError("Fails at Data.shrink()")
1304
+
1305
+ pointers = self.size // pointer_size
1306
+ self._content = self._content[:pointers]
1307
+
1308
+ else:
1309
+ # unknown
1310
+ self._content = [self._content[0][: self.size]]
1311
+
1312
+ def desymbolize(self):
1313
+ """
1314
+ We believe this was a pointer and symbolized it before. Now we want to desymbolize it.
1315
+
1316
+ The following actions are performed:
1317
+ - Reload content from memory
1318
+ - Mark the sort as 'unknown'
1319
+
1320
+ :return: None
1321
+ """
1322
+
1323
+ self.sort = MemoryDataSort.Unknown
1324
+ content = self.binary.fast_memory_load(self.addr, self.size, bytes)
1325
+ self.content = [content]
1326
+
1327
+ def assign_labels(self):
1328
+ # TODO: What if it's not aligned for some sort of data, like pointer array?
1329
+
1330
+ if self.addr is None:
1331
+ # this piece of data comes from a patch, not from the original binary
1332
+ return
1333
+
1334
+ # Put labels to self.labels
1335
+ for i in range(self.size):
1336
+ addr = self.addr + i
1337
+ if addr in self.binary.symbol_manager.addr_to_label:
1338
+ labels = self.binary.symbol_manager.addr_to_label[addr]
1339
+
1340
+ for label in labels:
1341
+ if self.sort == MemoryDataSort.PointerArray and addr % (self.project.arch.bytes) != 0:
1342
+ # we need to modify the base address of the label
1343
+ base_addr = addr - (addr % (self.project.arch.bytes))
1344
+ label.base_addr = base_addr
1345
+ tpl = (base_addr, label)
1346
+ if tpl not in self.labels:
1347
+ self.labels.append(tpl)
1348
+ else:
1349
+ tpl = (addr, label)
1350
+ if tpl not in self.labels:
1351
+ self.labels.append(tpl)
1352
+
1353
+ def assembly(self, comments=False, symbolized=True):
1354
+ s = ""
1355
+
1356
+ if comments:
1357
+ if self.addr is not None:
1358
+ s += "\t# data @ %#08x\n" % self.addr
1359
+ else:
1360
+ s += "\t# data (%s)\n" % self.name
1361
+
1362
+ if self.skip:
1363
+ return s
1364
+
1365
+ if self.sort == MemoryDataSort.String:
1366
+ if symbolized:
1367
+ ss = []
1368
+ last_pos = 0
1369
+ for i, tpl in enumerate(self.labels):
1370
+ addr, lbl = tpl
1371
+
1372
+ # split the string
1373
+ pos = addr - self.addr
1374
+ # endpos = self.labels[i + 1][0] - self.addr + 1 if i < len(self.labels) - 1 else self.size
1375
+ string_piece = self.content[0][last_pos:pos]
1376
+
1377
+ last_pos = pos
1378
+
1379
+ if i == len(self.labels) - 1 and pos == self.size:
1380
+ directive = ".asciz" # null at the end
1381
+ else:
1382
+ directive = ".ascii"
1383
+
1384
+ if string_piece:
1385
+ ss.append(
1386
+ '\t{directive} "{str}"'.format(
1387
+ str=string_escape(string_piece),
1388
+ directive=directive,
1389
+ )
1390
+ )
1391
+ ss.append("%s" % str(lbl))
1392
+
1393
+ if last_pos <= self.size - 1:
1394
+ string_piece = self.content[0][last_pos:]
1395
+ directive = ".ascii" if self.null_terminated is False else ".asciz"
1396
+
1397
+ ss.append(
1398
+ '\t{directive} "{str}"'.format(
1399
+ str=string_escape(string_piece),
1400
+ directive=directive,
1401
+ )
1402
+ )
1403
+
1404
+ s += "\n".join(ss)
1405
+ else:
1406
+ if self.null_terminated is False:
1407
+ directive = ".ascii"
1408
+ else:
1409
+ directive = ".asciz"
1410
+ s += f'\t.{directive} "{string_escape(self.content[0])}"'
1411
+ s += "\n"
1412
+
1413
+ elif self.sort == MemoryDataSort.PointerArray:
1414
+ if self.binary.project.arch.bits == 32:
1415
+ directive = ".long"
1416
+ elif self.binary.project.arch.bits == 64:
1417
+ directive = ".quad"
1418
+ else:
1419
+ raise BinaryError("Unsupported pointer size %d", self.binary.project.arch.bits)
1420
+
1421
+ if symbolized:
1422
+ addr_to_labels = {}
1423
+ for k, v in self.labels:
1424
+ if k not in addr_to_labels:
1425
+ addr_to_labels[k] = []
1426
+ addr_to_labels[k].append(v)
1427
+
1428
+ i = 0
1429
+ if self.name is not None:
1430
+ s += "%s:\n" % self.name
1431
+ for symbolized_label in self.content:
1432
+ if self.addr is not None and (self.addr + i) in addr_to_labels:
1433
+ for label in addr_to_labels[self.addr + i]:
1434
+ s += "%s\n" % str(label)
1435
+ elif self.addr is not None and (self.addr + i) in self.binary.symbol_manager.addr_to_label:
1436
+ labels = self.binary.symbol_manager.addr_to_label[self.addr + i]
1437
+ for label in labels:
1438
+ s += "%s\n" % str(label)
1439
+ i += self.project.arch.bytes
1440
+
1441
+ if isinstance(symbolized_label, int):
1442
+ s += "\t%s %d\n" % (directive, symbolized_label)
1443
+ else:
1444
+ s += f"\t{directive} {symbolized_label.operand_str}\n"
1445
+
1446
+ else:
1447
+ for label in self.content:
1448
+ s += f"\t{directive} {label.operand_str}\n"
1449
+
1450
+ elif self.sort == MemoryDataSort.SegmentBoundary:
1451
+ if symbolized:
1452
+ for _, label in self.labels:
1453
+ s += "\t%s\n" % str(label)
1454
+
1455
+ elif self.sort == MemoryDataSort.Integer:
1456
+ # display it as bytes only when there are references pointing to the middle
1457
+ content = []
1458
+
1459
+ if self.size == 1:
1460
+ directive = ".byte"
1461
+ fmt_str = "B"
1462
+ elif self.size == 2:
1463
+ directive = ".short"
1464
+ fmt_str = "<H"
1465
+ elif self.size == 4:
1466
+ directive = ".long"
1467
+ fmt_str = "<I"
1468
+ elif self.size == 8:
1469
+ directive = ".quad"
1470
+ fmt_str = "<Q"
1471
+ else:
1472
+ # we'll have to display it as a bunch of bytes
1473
+ directive = None
1474
+ fmt_str = None
1475
+
1476
+ if symbolized:
1477
+ addr_to_labels = {}
1478
+ for k, v in self.labels:
1479
+ if k not in addr_to_labels:
1480
+ addr_to_labels[k] = []
1481
+ addr_to_labels[k].append(v)
1482
+
1483
+ show_integer = False
1484
+ if len(addr_to_labels) == 0:
1485
+ show_integer = True
1486
+ elif len(addr_to_labels) == 1:
1487
+ if self.addr is not None and next(iter(addr_to_labels.keys())) == self.addr:
1488
+ show_integer = True
1489
+ elif self.addr is None and next(iter(addr_to_labels.keys())) == 0:
1490
+ show_integer = True
1491
+
1492
+ if directive is not None and show_integer:
1493
+ # nice, we should display it as an integer
1494
+ if addr_to_labels:
1495
+ for label in next(iter(addr_to_labels.values())):
1496
+ content += ["%s" % str(label)]
1497
+
1498
+ integer = struct.unpack(fmt_str, self.content[0])[0]
1499
+ content += [
1500
+ "\t{directive} {integer}".format(
1501
+ directive=directive,
1502
+ integer="%#x" % integer,
1503
+ )
1504
+ ]
1505
+
1506
+ else:
1507
+ # display it as bytes...
1508
+ addr = self.addr if self.addr is not None else 0
1509
+ for piece in self.content:
1510
+ for c in piece:
1511
+ if addr in addr_to_labels:
1512
+ for label in addr_to_labels[addr]:
1513
+ content += ["%s" % str(label)]
1514
+ addr += 1
1515
+
1516
+ content += ["\t.byte %d" % c]
1517
+
1518
+ else:
1519
+ integer = struct.unpack(fmt_str, self.content[0])[0]
1520
+ content += [
1521
+ "\t{directive} {integer}".format(
1522
+ directive=directive,
1523
+ integer="%#x" % integer,
1524
+ )
1525
+ ]
1526
+
1527
+ s += "\n".join(content)
1528
+ s += "\n"
1529
+
1530
+ elif self.sort == MemoryDataSort.FloatingPoint:
1531
+ # we have to display it as bytes...
1532
+ # TODO: switch to "ten byes" whenever time permits
1533
+ content = []
1534
+
1535
+ if symbolized:
1536
+ addr_to_labels = {}
1537
+ for k, v in self.labels:
1538
+ if k not in addr_to_labels:
1539
+ addr_to_labels[k] = []
1540
+ addr_to_labels[k].append(v)
1541
+
1542
+ addr = self.addr if self.addr is not None else 0
1543
+ for piece in self.content:
1544
+ for c in piece:
1545
+ if addr in addr_to_labels:
1546
+ for label in addr_to_labels[addr]:
1547
+ content += ["%s" % str(label)]
1548
+ addr += 1
1549
+
1550
+ content += ["\t.byte %d" % c]
1551
+ else:
1552
+ for piece in self.content:
1553
+ content += ["\t.byte %d" % c for c in piece]
1554
+
1555
+ s += "\n".join(content)
1556
+ s += "\n"
1557
+
1558
+ else:
1559
+ content = []
1560
+
1561
+ if symbolized:
1562
+ addr_to_labels = {}
1563
+ for k, v in self.labels:
1564
+ if k not in addr_to_labels:
1565
+ addr_to_labels[k] = []
1566
+ addr_to_labels[k].append(v)
1567
+
1568
+ addr = self.addr if self.addr is not None else 0
1569
+ for piece in self.content:
1570
+ for c in piece:
1571
+ if addr in addr_to_labels:
1572
+ for label in addr_to_labels[addr]:
1573
+ content += ["%s" % str(label)]
1574
+ addr += 1
1575
+
1576
+ content += ["\t.byte %d" % c]
1577
+ else:
1578
+ for piece in self.content:
1579
+ content += ["\t.byte %d" % c for c in piece]
1580
+
1581
+ s += "\n".join(content)
1582
+ s += "\n"
1583
+
1584
+ if self.end_labels:
1585
+ for label in self.end_labels:
1586
+ s += "%s\n" % label
1587
+
1588
+ return s.strip("\n")
1589
+
1590
+ #
1591
+ # Private methods
1592
+ #
1593
+
1594
+ def _initialize(self):
1595
+ if self.memory_data is None:
1596
+ if self.size is None or self._initial_content is None and self.sort is None:
1597
+ raise BinaryError("You must at least specify size, initial_content, and sort.")
1598
+
1599
+ if self.sort == MemoryDataSort.PointerArray:
1600
+ lbl = DataLabel(self.binary, -1, name=self.name)
1601
+ self.labels.append((0, lbl))
1602
+
1603
+ # symbolize the pointer array
1604
+
1605
+ self._content = []
1606
+
1607
+ fmt_str = ""
1608
+ if self.project.arch.memory_endness == "Iend_LE":
1609
+ fmt_str += "<"
1610
+ else:
1611
+ fmt_str += ">"
1612
+ if self.project.arch.bits == 32:
1613
+ fmt_str += "I"
1614
+ pointer_size = 4
1615
+ else:
1616
+ fmt_str += "Q"
1617
+ pointer_size = 8
1618
+
1619
+ for i in range(0, len(self._initial_content), pointer_size):
1620
+ addr_str = self._initial_content[i : i + pointer_size]
1621
+ addr = struct.unpack(fmt_str, addr_str)[0]
1622
+ if addr != 0 and (
1623
+ self.binary.main_executable_regions_contain(addr)
1624
+ or self.binary.main_nonexecutable_regions_contain(addr)
1625
+ ):
1626
+ label = self.binary.symbol_manager.new_label(addr)
1627
+ else:
1628
+ # it might be a pointer pointing to the binary base address or something
1629
+ # just keep it as it is
1630
+ # TODO: some more delicate logic should be applied here. For example, if the pointer is very
1631
+ # TODO: close to the beginning of .text, but after reassembling, it might be pointing to
1632
+ # TODO: somewhere inside .text. In this case we'd like to fix up the reference and make it
1633
+ # TODO: point to the beginning of .text minus an offset, instead of keeping the original header.
1634
+ label = addr
1635
+ self._content.append(label)
1636
+
1637
+ elif self.sort in {MemoryDataSort.String, MemoryDataSort.Unknown, MemoryDataSort.Integer}:
1638
+ lbl = DataLabel(self.binary, -1, name=self.name)
1639
+ self.labels.append((0, lbl))
1640
+
1641
+ self._content = [self._initial_content]
1642
+
1643
+ elif self.sort == MemoryDataSort.SegmentBoundary:
1644
+ label = self.binary.symbol_manager.new_label(self.addr)
1645
+ self.labels.append((self.addr, label))
1646
+ self._content = []
1647
+
1648
+ else:
1649
+ raise BinaryError('Unsupported data sort "%s"' % self.sort)
1650
+
1651
+ else:
1652
+ self.addr = self.memory_data.address
1653
+ self.size = self.memory_data.size
1654
+ self.sort = self.memory_data.sort
1655
+
1656
+ # Symbolize the content
1657
+ if self.sort == MemoryDataSort.PointerArray:
1658
+ # read out the address
1659
+ pointer_size = self.project.arch.bytes
1660
+ pointers = self.size // pointer_size
1661
+
1662
+ self._content = []
1663
+ for i in range(pointers):
1664
+ addr = self.binary.fast_memory_load(
1665
+ self.addr + i * pointer_size, pointer_size, int, endness=self.project.arch.memory_endness
1666
+ )
1667
+ if addr is None:
1668
+ continue
1669
+ obj = self.project.loader.find_object_containing(addr)
1670
+ if obj is self.project.loader.main_object:
1671
+ # a dynamic pointer
1672
+ if self.binary.main_executable_regions_contain(
1673
+ addr
1674
+ ) or self.binary.main_nonexecutable_regions_contain(addr):
1675
+ label = self.binary.symbol_manager.new_label(addr)
1676
+ self._content.append(label)
1677
+
1678
+ self.binary.register_data_reference(self.addr + i * pointer_size, addr)
1679
+
1680
+ else:
1681
+ # it's a pointer pointing to a segment, but not any section. keep it as it is
1682
+ self._content.append(addr)
1683
+ else:
1684
+ # it's a static pointer. we should use the original pointer value.
1685
+ self._content.append(addr)
1686
+
1687
+ elif self.sort == MemoryDataSort.String:
1688
+ data = self.binary.fast_memory_load(self.addr, self.size, bytes)
1689
+ if data[-1] == 0:
1690
+ self.null_terminated = True
1691
+ data = data[:-1] # remove the null-byte. we'll use .asciz for it instead.
1692
+ else:
1693
+ self.null_terminated = False
1694
+
1695
+ self._content = [data]
1696
+
1697
+ elif self.sort == MemoryDataSort.Integer:
1698
+ data = self.binary.fast_memory_load(self.addr, self.size, bytes)
1699
+ self._content = [data]
1700
+
1701
+ elif self.sort == MemoryDataSort.SegmentBoundary:
1702
+ label = self.binary.symbol_manager.new_label(self.addr)
1703
+ self.labels.append((self.addr, label))
1704
+
1705
+ self._content = []
1706
+
1707
+ elif self.sort == MemoryDataSort.FloatingPoint:
1708
+ # floating-point integers
1709
+ # Python has some trouble in dealing with floating point numbers
1710
+ # just store them as bytes
1711
+ data = self.binary.fast_memory_load(self.addr, self.size, bytes)
1712
+ self._content = [data]
1713
+
1714
+ else:
1715
+ # other sorts
1716
+ content = self.binary.fast_memory_load(self.addr, self.size, bytes)
1717
+ if content is not None:
1718
+ self._content = [content]
1719
+ else:
1720
+ self._content = []
1721
+
1722
+
1723
+ class Relocation:
1724
+ def __init__(self, addr, ref_addr, sort):
1725
+ self.addr = addr
1726
+ self.ref_addr = ref_addr
1727
+ self.sort = sort
1728
+
1729
+ def __repr__(self):
1730
+ s = f"<Reloc {self.sort} {self.addr:#x} ({self.ref_addr:#x})>"
1731
+ return s
1732
+
1733
+
1734
+ class Reassembler(Analysis):
1735
+ """
1736
+ High-level representation of a binary with a linear representation of all instructions and data regions. After
1737
+ calling "symbolize", it essentially acts as a binary reassembler.
1738
+
1739
+ Tested on CGC, x86 and x86-64 binaries.
1740
+
1741
+ Discliamer: The reassembler is an empirical solution. Don't be surprised if it does not work on some binaries.
1742
+ """
1743
+
1744
+ def __init__(self, syntax="intel", remove_cgc_attachments=True, log_relocations=True):
1745
+ self.syntax = syntax
1746
+ self._remove_cgc_attachments = remove_cgc_attachments
1747
+
1748
+ self.symbol_manager = None
1749
+ self.cfg = None
1750
+ self._cgc_attachments_removed = False
1751
+ self.log_relocations = log_relocations
1752
+
1753
+ self.procedures = []
1754
+ self.data = []
1755
+
1756
+ self.extra_rodata = []
1757
+ self.extra_data = []
1758
+
1759
+ self._main_executable_regions = None
1760
+ self._main_nonexecutable_regions = None
1761
+
1762
+ self._symbolization_needed = True
1763
+
1764
+ # section names to alignments
1765
+ self._section_alignments = {}
1766
+
1767
+ # all instruction addresses
1768
+ self.all_insn_addrs = set()
1769
+
1770
+ self._relocations = []
1771
+
1772
+ self._inserted_asm_before_label = defaultdict(list)
1773
+ self._inserted_asm_after_label = defaultdict(list)
1774
+ self._removed_instructions = set()
1775
+ self._extra_memory_regions = [(0x4347C000, 0x4347C000 + 0x1000)]
1776
+
1777
+ self._initialize()
1778
+
1779
+ #
1780
+ # Overridden predefined methods
1781
+ #
1782
+
1783
+ def __str__(self):
1784
+ """
1785
+ Return a linear representation of all instructions in the binary
1786
+ :return:
1787
+ """
1788
+
1789
+ s = "\n".join([str(proc) for proc in self.procedures])
1790
+
1791
+ return s
1792
+
1793
+ #
1794
+ # Properties
1795
+ #
1796
+ @property
1797
+ def instructions(self):
1798
+ """
1799
+ Get a list of all instructions in the binary
1800
+
1801
+ :return: A list of (address, instruction)
1802
+ :rtype: tuple
1803
+ """
1804
+
1805
+ raise NotImplementedError()
1806
+
1807
+ @property
1808
+ def relocations(self):
1809
+ return self._relocations
1810
+
1811
+ @property
1812
+ def inserted_asm_before_label(self):
1813
+ return self._inserted_asm_before_label
1814
+
1815
+ @property
1816
+ def inserted_asm_after_label(self):
1817
+ return self._inserted_asm_after_label
1818
+
1819
+ @property
1820
+ def main_executable_regions(self):
1821
+ """
1822
+
1823
+ :return:
1824
+ """
1825
+
1826
+ if self._main_executable_regions is None:
1827
+ self._main_executable_regions = []
1828
+
1829
+ obj = self.project.loader.main_object
1830
+
1831
+ if obj.sections:
1832
+ for sec in obj.sections:
1833
+ if sec.is_executable:
1834
+ min_addr = sec.min_addr
1835
+ max_addr = sec.max_addr + 1
1836
+ if max_addr <= min_addr or min_addr == 0:
1837
+ continue
1838
+ self._main_executable_regions.append((min_addr, max_addr))
1839
+
1840
+ else:
1841
+ for seg in obj.segments:
1842
+ if seg.is_executable:
1843
+ min_addr = seg.min_addr
1844
+ max_addr = seg.max_addr + 1
1845
+ self._main_executable_regions.append((min_addr, max_addr))
1846
+
1847
+ return self._main_executable_regions
1848
+
1849
+ @property
1850
+ def main_nonexecutable_regions(self):
1851
+ """
1852
+
1853
+ :return:
1854
+ """
1855
+
1856
+ if self._main_nonexecutable_regions is None:
1857
+ self._main_nonexecutable_regions = []
1858
+
1859
+ obj = self.project.loader.main_object
1860
+
1861
+ if obj.sections:
1862
+ for sec in obj.sections:
1863
+ if sec.name in {".eh_frame", ".eh_frame_hdr"}:
1864
+ # hack for ELF binaries...
1865
+ continue
1866
+ if not sec.is_executable:
1867
+ min_addr = sec.min_addr
1868
+ max_addr = sec.max_addr + 1
1869
+ if max_addr <= min_addr or min_addr == 0:
1870
+ continue
1871
+ self._main_nonexecutable_regions.append((min_addr, max_addr))
1872
+
1873
+ else:
1874
+ for seg in obj.segments:
1875
+ if not seg.is_executable:
1876
+ min_addr = seg.min_addr
1877
+ max_addr = seg.max_addr + 1
1878
+ self._main_nonexecutable_regions.append((min_addr, max_addr))
1879
+
1880
+ return self._main_nonexecutable_regions
1881
+
1882
+ #
1883
+ # Public methods
1884
+ #
1885
+
1886
+ def section_alignment(self, section_name):
1887
+ """
1888
+ Get the alignment for the specific section. If the section is not found, 16 is used as default.
1889
+
1890
+ :param str section_name: The section.
1891
+ :return: The alignment in bytes.
1892
+ :rtype: int
1893
+ """
1894
+
1895
+ return self._section_alignments.get(section_name, 16)
1896
+
1897
+ def main_executable_regions_contain(self, addr):
1898
+ """
1899
+
1900
+ :param addr:
1901
+ :return:
1902
+ """
1903
+ for start, end in self.main_executable_regions:
1904
+ if start <= addr < end:
1905
+ return True
1906
+ return False
1907
+
1908
+ def main_executable_region_limbos_contain(self, addr):
1909
+ """
1910
+ Sometimes there exists a pointer that points to a few bytes before the beginning of a section, or a few bytes
1911
+ after the beginning of the section. We take care of that here.
1912
+
1913
+ :param int addr: The address to check.
1914
+ :return: A 2-tuple of (bool, the closest base address)
1915
+ :rtype: tuple
1916
+ """
1917
+
1918
+ TOLERANCE = 64
1919
+
1920
+ closest_region = None
1921
+ least_limbo = None
1922
+
1923
+ for start, end in self.main_executable_regions:
1924
+ if start - TOLERANCE <= addr < start:
1925
+ if least_limbo is None or start - addr < least_limbo:
1926
+ closest_region = (True, start)
1927
+ least_limbo = start - addr
1928
+ if end <= addr < end + TOLERANCE:
1929
+ if least_limbo is None or addr - end < least_limbo:
1930
+ closest_region = (True, end)
1931
+ least_limbo = addr - end
1932
+
1933
+ if closest_region is not None:
1934
+ return closest_region
1935
+ return (False, None)
1936
+
1937
+ def main_nonexecutable_regions_contain(self, addr):
1938
+ """
1939
+
1940
+ :param int addr: The address to check.
1941
+ :return: True if the address is inside a non-executable region, False otherwise.
1942
+ :rtype: bool
1943
+ """
1944
+ for start, end in self.main_nonexecutable_regions:
1945
+ if start <= addr < end:
1946
+ return True
1947
+ return False
1948
+
1949
+ def main_nonexecutable_region_limbos_contain(self, addr, tolerance_before=64, tolerance_after=64):
1950
+ """
1951
+ Sometimes there exists a pointer that points to a few bytes before the beginning of a section, or a few bytes
1952
+ after the beginning of the section. We take care of that here.
1953
+
1954
+ :param int addr: The address to check.
1955
+ :return: A 2-tuple of (bool, the closest base address)
1956
+ :rtype: tuple
1957
+ """
1958
+
1959
+ closest_region = None
1960
+ least_limbo = None
1961
+
1962
+ for start, end in self.main_nonexecutable_regions:
1963
+ if start - tolerance_before <= addr < start:
1964
+ if least_limbo is None or start - addr < least_limbo:
1965
+ closest_region = (True, start)
1966
+ least_limbo = start - addr
1967
+ if end <= addr < end + tolerance_after:
1968
+ if least_limbo is None or addr - end < least_limbo:
1969
+ closest_region = (True, end)
1970
+ least_limbo = addr - end
1971
+
1972
+ if closest_region is not None:
1973
+ return closest_region
1974
+ return False, None
1975
+
1976
+ def register_instruction_reference(self, insn_addr, ref_addr, sort, operand_offset):
1977
+ if not self.log_relocations:
1978
+ return
1979
+
1980
+ addr = insn_addr + operand_offset
1981
+ r = Relocation(addr, ref_addr, sort)
1982
+
1983
+ self._relocations.append(r)
1984
+
1985
+ def register_data_reference(self, data_addr, ref_addr):
1986
+ if not self.log_relocations:
1987
+ return
1988
+
1989
+ r = Relocation(data_addr, ref_addr, "absolute")
1990
+
1991
+ self._relocations.append(r)
1992
+
1993
+ def add_label(self, name, addr):
1994
+ """
1995
+ Add a new label to the symbol manager.
1996
+
1997
+ :param str name: Name of the label.
1998
+ :param int addr: Address of the label.
1999
+ :return: None
2000
+ """
2001
+
2002
+ # set the label
2003
+ self._symbolization_needed = True
2004
+
2005
+ self.symbol_manager.new_label(addr, name=name, force=True)
2006
+
2007
+ def insert_asm(self, addr, asm_code, before_label=False):
2008
+ """
2009
+ Insert some assembly code at the specific address. There must be an instruction starting at that address.
2010
+
2011
+ :param int addr: Address of insertion
2012
+ :param str asm_code: The assembly code to insert
2013
+ :return: None
2014
+ """
2015
+
2016
+ if before_label:
2017
+ self._inserted_asm_before_label[addr].append(asm_code)
2018
+ else:
2019
+ self._inserted_asm_after_label[addr].append(asm_code)
2020
+
2021
+ def append_procedure(self, name, asm_code):
2022
+ """
2023
+ Add a new procedure with specific name and assembly code.
2024
+
2025
+ :param str name: The name of the new procedure.
2026
+ :param str asm_code: The assembly code of the procedure
2027
+ :return: None
2028
+ """
2029
+
2030
+ proc = Procedure(self, name=name, asm_code=asm_code)
2031
+ self.procedures.append(proc)
2032
+
2033
+ def append_data(
2034
+ self, name, initial_content, size, readonly=False, sort="unknown"
2035
+ ): # pylint:disable=unused-argument
2036
+ """
2037
+ Append a new data entry into the binary with specific name, content, and size.
2038
+
2039
+ :param str name: Name of the data entry. Will be used as the label.
2040
+ :param bytes initial_content: The initial content of the data entry.
2041
+ :param int size: Size of the data entry.
2042
+ :param bool readonly: If the data entry belongs to the readonly region.
2043
+ :param str sort: Type of the data.
2044
+ :return: None
2045
+ """
2046
+
2047
+ if readonly:
2048
+ section_name = ".rodata"
2049
+ else:
2050
+ section_name = ".data"
2051
+
2052
+ if initial_content is None:
2053
+ initial_content = b""
2054
+ initial_content = initial_content.ljust(size, b"\x00")
2055
+ data = Data(
2056
+ self,
2057
+ memory_data=None,
2058
+ section_name=section_name,
2059
+ name=name,
2060
+ initial_content=initial_content,
2061
+ size=size,
2062
+ sort=sort,
2063
+ )
2064
+
2065
+ if section_name == ".rodata":
2066
+ self.extra_rodata.append(data)
2067
+ else:
2068
+ self.extra_data.append(data)
2069
+
2070
+ def remove_instruction(self, ins_addr):
2071
+ """
2072
+
2073
+ :param ins_addr:
2074
+ :return:
2075
+ """
2076
+
2077
+ self._removed_instructions.add(ins_addr)
2078
+
2079
+ def randomize_procedures(self):
2080
+ """
2081
+
2082
+ :return:
2083
+ """
2084
+
2085
+ raise NotImplementedError()
2086
+
2087
+ def symbolize(self):
2088
+ # clear the flag
2089
+ self._symbolization_needed = False
2090
+
2091
+ # sanity checks
2092
+ # if self._has_integer_used_as_pointers():
2093
+ # raise ReassemblerFailureNotice('Integer-used-as-pointer detected. Reassembler will not work safely on '
2094
+ # 'this binary. Ping Fish if you believe the detection is wrong.'
2095
+ # )
2096
+
2097
+ for proc in self.procedures:
2098
+ proc.assign_labels()
2099
+
2100
+ for data in self.data:
2101
+ data.assign_labels()
2102
+
2103
+ # Get all instruction addresses, and modify those labels pointing to the middle of an instruction
2104
+ insn_addrs = []
2105
+ proc: Procedure
2106
+ for proc in self.procedures:
2107
+ insn_addrs.extend(proc.instruction_addresses())
2108
+ # just to be safe
2109
+ insn_addrs = sorted(set(insn_addrs), key=lambda x: x[0])
2110
+
2111
+ pos = 0
2112
+
2113
+ changed_labels = []
2114
+
2115
+ for label_addr in sorted(self.symbol_manager.addr_to_label.keys()):
2116
+ while pos < len(insn_addrs) and label_addr > insn_addrs[pos][0]:
2117
+ pos += 1
2118
+
2119
+ if pos >= len(insn_addrs):
2120
+ break
2121
+
2122
+ if pos == 0:
2123
+ continue
2124
+
2125
+ insn_addr, insn_size = insn_addrs[pos - 1]
2126
+
2127
+ if insn_addr < label_addr < insn_addr + insn_size:
2128
+ # this label should be converted to something like 0x8000040+1
2129
+ labels = self.symbol_manager.addr_to_label[label_addr]
2130
+ for label in labels:
2131
+ label.base_addr = insn_addrs[pos][0]
2132
+ changed_labels.append(label)
2133
+
2134
+ for label in changed_labels:
2135
+ self.symbol_manager.addr_to_label[label.original_addr].remove(label)
2136
+ if not self.symbol_manager.addr_to_label[label.original_addr]:
2137
+ del self.symbol_manager.addr_to_label[label.original_addr]
2138
+ self.symbol_manager.addr_to_label[label.base_addr].append(label)
2139
+
2140
+ if changed_labels:
2141
+ for proc in self.procedures:
2142
+ proc.assign_labels()
2143
+
2144
+ def assembly(self, comments=False, symbolized=True):
2145
+ if symbolized and self._symbolization_needed:
2146
+ self.symbolize()
2147
+
2148
+ if self._remove_cgc_attachments:
2149
+ self._cgc_attachments_removed = self.remove_cgc_attachments()
2150
+
2151
+ s = ""
2152
+
2153
+ if self.syntax == "intel":
2154
+ s += "\t.intel_syntax noprefix\n"
2155
+
2156
+ all_assembly_lines = []
2157
+
2158
+ addr_and_assembly = []
2159
+ for proc in self.procedures:
2160
+ addr_and_assembly.extend(proc.assembly(comments=comments, symbolized=symbolized))
2161
+ # sort it by the address - must be a stable sort!
2162
+ addr_and_assembly = sorted(addr_and_assembly, key=lambda x: x[0] if x[0] is not None else -1)
2163
+ all_assembly_lines.extend(line for _, line in addr_and_assembly)
2164
+
2165
+ last_section = None
2166
+
2167
+ if self._cgc_attachments_removed:
2168
+ all_data = self.data + self.extra_rodata + self.extra_data
2169
+ else:
2170
+ # to reduce memory usage, we put extra data in front of the original data in binary
2171
+ all_data = self.extra_data + self.data + self.extra_rodata
2172
+
2173
+ for data in all_data:
2174
+ if last_section is None or data.section_name != last_section:
2175
+ last_section = data.section_name
2176
+ all_assembly_lines.append(
2177
+ "\t.section {section}\n\t.align {alignment}".format(
2178
+ section=(last_section if last_section != ".init_array" else ".data"),
2179
+ alignment=self.section_alignment(last_section),
2180
+ )
2181
+ )
2182
+ all_assembly_lines.append(data.assembly(comments=comments, symbolized=symbolized))
2183
+
2184
+ s = "\n".join(all_assembly_lines)
2185
+
2186
+ return s
2187
+
2188
+ def remove_cgc_attachments(self):
2189
+ """
2190
+ Remove CGC attachments.
2191
+
2192
+ :return: True if CGC attachments are found and removed, False otherwise
2193
+ :rtype: bool
2194
+ """
2195
+
2196
+ cgc_package_list = None
2197
+ cgc_extended_application = None
2198
+
2199
+ for data in self.data:
2200
+ if data.sort == "cgc-package-list":
2201
+ cgc_package_list = data
2202
+ elif data.sort == "cgc-extended-application":
2203
+ cgc_extended_application = data
2204
+
2205
+ if not cgc_package_list or not cgc_extended_application:
2206
+ return False
2207
+
2208
+ if cgc_package_list.skip or cgc_extended_application.skip:
2209
+ # they have already been removed
2210
+ # so we still return True to indicate that CGC attachments have been removed
2211
+ return True
2212
+
2213
+ # there is a single function referencing them
2214
+ cgcpl_memory_data = self.cfg.memory_data.get(cgc_package_list.addr, None)
2215
+ cgcea_memory_data = self.cfg.memory_data.get(cgc_extended_application.addr, None)
2216
+ refs = self.cfg.kb.xrefs
2217
+
2218
+ if cgcpl_memory_data is None or cgcea_memory_data is None:
2219
+ return False
2220
+
2221
+ if len(refs.get_xrefs_by_dst(cgcpl_memory_data.addr)) != 1:
2222
+ return False
2223
+ if len(refs.get_xrefs_by_dst(cgcea_memory_data.addr)) != 1:
2224
+ return False
2225
+
2226
+ # check if the irsb addresses are the same
2227
+ if (
2228
+ next(iter(refs.get_xrefs_by_dst(cgcpl_memory_data.addr))).block_addr
2229
+ != next(iter(refs.get_xrefs_by_dst(cgcea_memory_data.addr))).block_addr
2230
+ ):
2231
+ return False
2232
+
2233
+ insn_addr = next(iter(refs.get_xrefs_by_dst(cgcpl_memory_data.addr))).ins_addr
2234
+ # get the basic block
2235
+ cfg_node = self.cfg.model.get_any_node(insn_addr, anyaddr=True)
2236
+ if not cfg_node:
2237
+ return False
2238
+
2239
+ func_addr = cfg_node.function_address
2240
+
2241
+ # this function should be calling another function
2242
+ sub_func_addr = None
2243
+ if func_addr not in self.cfg.functions:
2244
+ return False
2245
+ function = self.cfg.functions[func_addr]
2246
+ # traverse the graph and make sure there is only one call edge
2247
+ calling_targets = []
2248
+ for _, dst, data in function.transition_graph.edges(data=True):
2249
+ if "type" in data and data["type"] == "call":
2250
+ calling_targets.append(dst.addr)
2251
+
2252
+ if len(calling_targets) != 1:
2253
+ return False
2254
+
2255
+ sub_func_addr = calling_targets[0]
2256
+
2257
+ # alright. We want to nop this function, as well as the subfunction
2258
+ proc = next((p for p in self.procedures if p.addr == func_addr), None)
2259
+ if proc is None:
2260
+ return False
2261
+
2262
+ subproc = next((p for p in self.procedures if p.addr == sub_func_addr), None)
2263
+ if subproc is None:
2264
+ return False
2265
+
2266
+ # if those two data entries have any label, we should properly modify them
2267
+ # at this point, we are fairly confident that none of those labels are direct data references to either package
2268
+ # list or extended application
2269
+ has_label = True
2270
+ lowest_address = min(cgc_package_list.addr, cgc_extended_application.addr)
2271
+ for obj in (cgc_package_list, cgc_extended_application):
2272
+ labels = obj.labels
2273
+ for addr, label in labels:
2274
+ if addr != lowest_address:
2275
+ label.base_addr = lowest_address
2276
+
2277
+ if has_label:
2278
+ # is there any memory data entry that ends right at the lowest address?
2279
+ data = next((d for d in self.data if d.addr is not None and d.addr + d.size == lowest_address), None)
2280
+ if data is None:
2281
+ # since there is no gap between memory data entries (we guarantee that), this can only be that no other
2282
+ # data resides in the same memory region that CGC attachments are in
2283
+ pass
2284
+ else:
2285
+ lbl = self.symbol_manager.addr_to_label[lowest_address][0]
2286
+ if lbl not in data.end_labels:
2287
+ data.end_labels.append(lbl)
2288
+
2289
+ # practically nop the function
2290
+ proc.asm_code = "\tret\n"
2291
+ subproc.asm_code = "\tret\n"
2292
+
2293
+ # remove those two data entries
2294
+ cgc_package_list.skip = True
2295
+ cgc_extended_application.skip = True
2296
+
2297
+ l.info("CGC attachments are removed.")
2298
+
2299
+ return True
2300
+
2301
+ def remove_unnecessary_stuff(self):
2302
+ """
2303
+ Remove unnecessary functions and data
2304
+
2305
+ :return: None
2306
+ """
2307
+
2308
+ # determine if the binary is compiled against glibc
2309
+ is_glibc = False
2310
+ for dep in self.project.loader.main_object.deps:
2311
+ if dep.lower() in {"libc.so.6", "libc.so"}:
2312
+ is_glibc = True
2313
+ break
2314
+ if is_glibc:
2315
+ self.remove_unnecessary_stuff_glibc()
2316
+
2317
+ def remove_unnecessary_stuff_glibc(self):
2318
+ glibc_functions_blacklist = {
2319
+ "_start",
2320
+ "init",
2321
+ "_init",
2322
+ "fini",
2323
+ "_fini",
2324
+ "__gmon_start__",
2325
+ "__do_global_dtors_aux",
2326
+ "frame_dummy",
2327
+ "atexit",
2328
+ "deregister_tm_clones",
2329
+ "register_tm_clones",
2330
+ "__x86.get_pc_thunk.bx",
2331
+ "__libc_csu_init",
2332
+ "__libc_csu_fini",
2333
+ }
2334
+
2335
+ glibc_data_blacklist = {
2336
+ "__TMC_END__",
2337
+ "_GLOBAL_OFFSET_TABLE_",
2338
+ "__JCR_END__",
2339
+ "__dso_handle",
2340
+ "__init_array_start",
2341
+ "__init_array_end",
2342
+ #
2343
+ "stdout",
2344
+ "stderr",
2345
+ "stdin",
2346
+ "program_invocation_short_",
2347
+ "program_invocation_short_name",
2348
+ "program_invocation_name",
2349
+ "__progname_full",
2350
+ "_IO_stdin_used",
2351
+ "obstack_alloc_failed_hand",
2352
+ "optind",
2353
+ "optarg",
2354
+ "__progname",
2355
+ "_environ",
2356
+ "environ",
2357
+ "__environ",
2358
+ }
2359
+
2360
+ glibc_references_blacklist = {
2361
+ "frame_dummy",
2362
+ "__do_global_dtors_aux",
2363
+ }
2364
+
2365
+ self.procedures = [p for p in self.procedures if p.name not in glibc_functions_blacklist and not p.is_plt]
2366
+
2367
+ # special handling for _init_proc
2368
+ try:
2369
+ init_func = self.cfg.functions["init"]
2370
+ callees = [
2371
+ node
2372
+ for node in init_func.transition_graph.nodes()
2373
+ if isinstance(node, Function) and node.addr != self.cfg._unresolvable_call_target_addr
2374
+ ]
2375
+ # special handling for GCC-generated X86 PIE binaries
2376
+ non_getpc_callees = [callee for callee in callees if "get_pc" not in callee.info]
2377
+ if len(non_getpc_callees) == 1:
2378
+ # we found the _init_proc
2379
+ _init_proc = non_getpc_callees[0]
2380
+ self.procedures = [p for p in self.procedures if p.addr != _init_proc.addr]
2381
+ except KeyError:
2382
+ pass
2383
+
2384
+ self.data = [d for d in self.data if not any(lbl.name in glibc_data_blacklist for _, lbl in d.labels)]
2385
+
2386
+ for d in self.data:
2387
+ if d.sort == MemoryDataSort.PointerArray:
2388
+ for i in range(len(d.content)):
2389
+ ptr = d.content[i]
2390
+ if isinstance(ptr, Label) and ptr.name in glibc_references_blacklist:
2391
+ d.content[i] = 0
2392
+ elif d.sort == MemoryDataSort.SegmentBoundary:
2393
+ if d.labels:
2394
+ new_labels = []
2395
+ for rebased_addr, label in d.labels:
2396
+ # check if this label belongs to a removed function
2397
+ if (
2398
+ self.cfg.functions.contains_addr(rebased_addr)
2399
+ and self.cfg.functions[rebased_addr].name in glibc_functions_blacklist
2400
+ ):
2401
+ # we need to remove this label...
2402
+ continue
2403
+ else:
2404
+ new_labels.append((rebased_addr, label))
2405
+ d.labels = new_labels
2406
+
2407
+ #
2408
+ # Private methods
2409
+ #
2410
+
2411
+ def _initialize(self):
2412
+ """
2413
+ Initialize the binary.
2414
+
2415
+ :return: None
2416
+ """
2417
+
2418
+ # figure out section alignments
2419
+ for section in self.project.loader.main_object.sections:
2420
+ in_segment = False
2421
+ for segment in self.project.loader.main_object.segments:
2422
+ segment_addr = segment.vaddr
2423
+ if segment_addr <= section.vaddr < segment_addr + segment.memsize:
2424
+ in_segment = True
2425
+ break
2426
+ if not in_segment:
2427
+ continue
2428
+
2429
+ # calculate alignments
2430
+ if section.vaddr % 0x20 == 0:
2431
+ alignment = 0x20
2432
+ elif section.vaddr % 0x10 == 0:
2433
+ alignment = 0x10
2434
+ elif section.vaddr % 0x8 == 0:
2435
+ alignment = 0x8
2436
+ elif section.vaddr % 0x4 == 0:
2437
+ alignment = 0x4
2438
+ else:
2439
+ alignment = 2
2440
+
2441
+ self._section_alignments[section.name] = alignment
2442
+
2443
+ l.debug("Generating CFG...")
2444
+ cfg = self.project.analyses[CFGFast].prep()(
2445
+ normalize=True,
2446
+ resolve_indirect_jumps=True,
2447
+ data_references=True,
2448
+ extra_memory_regions=self._extra_memory_regions,
2449
+ data_type_guessing_handlers=[
2450
+ self._sequence_handler,
2451
+ self._cgc_extended_application_handler,
2452
+ self._unknown_data_size_handler,
2453
+ ],
2454
+ )
2455
+
2456
+ self.cfg = cfg
2457
+
2458
+ old_capstone_syntax = self.project.arch.capstone_x86_syntax
2459
+ if old_capstone_syntax is None:
2460
+ old_capstone_syntax = "intel"
2461
+
2462
+ if self.syntax == "at&t":
2463
+ # switch capstone to AT&T style
2464
+ self.project.arch.capstone_x86_syntax = "at&t"
2465
+ # clear the block cache in lifter!
2466
+ self.project.factory.default_engine.clear_cache()
2467
+
2468
+ # initialize symbol manager
2469
+ self.symbol_manager = SymbolManager(self, cfg)
2470
+
2471
+ # collect address of all instructions
2472
+ l.debug("Collecting instruction addresses...")
2473
+ for cfg_node in self.cfg.nodes():
2474
+ self.all_insn_addrs |= set(cfg_node.instruction_addrs)
2475
+
2476
+ # Functions
2477
+
2478
+ l.debug("Creating functions...")
2479
+ for f in cfg.kb.functions.values():
2480
+ # Skip all SimProcedures
2481
+ if self.project.is_hooked(f.addr):
2482
+ continue
2483
+ elif self.project.simos.is_syscall_addr(f.addr):
2484
+ continue
2485
+
2486
+ # Check which section the start address belongs to
2487
+ section = next(
2488
+ iter(
2489
+ sec.name
2490
+ for sec in self.project.loader.main_object.sections
2491
+ if f.addr >= sec.vaddr and f.addr < sec.vaddr + sec.memsize
2492
+ ),
2493
+ ".text",
2494
+ )
2495
+
2496
+ if section in {".got", ".plt", "init", "fini", ".init", ".fini"}:
2497
+ continue
2498
+
2499
+ procedure = Procedure(self, function=f, section=section)
2500
+ self.procedures.append(procedure)
2501
+
2502
+ self.procedures = sorted(self.procedures, key=lambda x: x.addr)
2503
+
2504
+ # Data
2505
+
2506
+ has_sections = len(self.project.loader.main_object.sections) > 0
2507
+
2508
+ l.debug("Creating data entries...")
2509
+ for addr, memory_data in cfg._memory_data.items():
2510
+ if memory_data.sort in ("code reference",):
2511
+ continue
2512
+
2513
+ if memory_data.sort == "string":
2514
+ # it might be the CGC package list
2515
+ new_sort, new_size = self._cgc_package_list_identifier(memory_data.address, memory_data.size)
2516
+ if new_sort is not None:
2517
+ # oh we got it!
2518
+ memory_data = memory_data.copy()
2519
+ memory_data.sort = new_sort
2520
+
2521
+ if has_sections:
2522
+ # Check which section the start address belongs to
2523
+ section = next(
2524
+ iter(
2525
+ sec
2526
+ for sec in self.project.loader.main_object.sections
2527
+ if sec.vaddr <= addr < sec.vaddr + sec.memsize
2528
+ ),
2529
+ None,
2530
+ )
2531
+
2532
+ if section is not None and section.name not in (".note.gnu.build-id",): # ignore certain section names
2533
+ data = Data(self, memory_data, section=section)
2534
+ self.data.append(data)
2535
+ elif memory_data.sort == "segment-boundary":
2536
+ # it just points to the end of the segment or a section
2537
+ section = next(
2538
+ iter(
2539
+ sec for sec in self.project.loader.main_object.sections if addr == sec.vaddr + sec.memsize
2540
+ ),
2541
+ None,
2542
+ )
2543
+ if section is not None:
2544
+ data = Data(self, memory_data, section=section)
2545
+ self.data.append(data)
2546
+
2547
+ else:
2548
+ # data = Data(self, memory_data, section_name='.data')
2549
+ # the data is not really within any existing section. weird. ignored it.
2550
+ pass
2551
+ else:
2552
+ # the binary does not have any section
2553
+ # we use segment information instead
2554
+ # TODO: this logic needs reviewing
2555
+ segment = next(
2556
+ iter(
2557
+ seg
2558
+ for seg in self.project.loader.main_object.segments
2559
+ if seg.vaddr <= addr <= seg.vaddr + seg.memsize
2560
+ ),
2561
+ None,
2562
+ )
2563
+
2564
+ if segment is not None:
2565
+ data = Data(self, memory_data, section_name=".data")
2566
+ self.data.append(data)
2567
+
2568
+ # remove all data that belong to GCC-specific sections
2569
+ section_names_to_ignore = {
2570
+ ".init",
2571
+ ".fini",
2572
+ ".fini_array",
2573
+ ".jcr",
2574
+ ".dynamic",
2575
+ ".got",
2576
+ ".got.plt",
2577
+ ".eh_frame_hdr",
2578
+ ".eh_frame",
2579
+ ".rel.dyn",
2580
+ ".rel.plt",
2581
+ ".rela.dyn",
2582
+ ".rela.plt",
2583
+ ".dynstr",
2584
+ ".dynsym",
2585
+ ".interp",
2586
+ ".note.ABI-tag",
2587
+ ".note.gnu.build-id",
2588
+ ".gnu.hash",
2589
+ ".gnu.version",
2590
+ ".gnu.version_r",
2591
+ }
2592
+
2593
+ # make sure there are always memory data entries pointing at the end of sections
2594
+ all_data_addrs = {d.addr for d in self.data}
2595
+ all_procedure_addrs = {f.addr for f in self.procedures}
2596
+ all_addrs = all_data_addrs | all_procedure_addrs
2597
+
2598
+ if has_sections:
2599
+ for section in self.project.loader.main_object.sections:
2600
+ if section.name in section_names_to_ignore:
2601
+ # skip all sections that are CGC specific
2602
+ continue
2603
+
2604
+ # make sure this section is not empty
2605
+ if section.memsize == 0:
2606
+ continue
2607
+
2608
+ # make sure this section is inside a segment
2609
+ for segment in self.project.loader.main_object.segments:
2610
+ segment_start = segment.vaddr
2611
+ segment_end = segment_start + segment.memsize
2612
+ if segment_start <= section.vaddr < segment_end:
2613
+ break
2614
+ else:
2615
+ # this section is not mapped into memory
2616
+ continue
2617
+
2618
+ section_boundary_addr = section.vaddr + section.memsize
2619
+ if section_boundary_addr not in all_addrs:
2620
+ data = Data(
2621
+ self, addr=section_boundary_addr, size=0, sort="segment-boundary", section_name=section.name
2622
+ )
2623
+ self.data.append(data)
2624
+ # add the address to all_data_addrs so we don't end up adding another boundary in
2625
+ all_data_addrs.add(section_boundary_addr)
2626
+
2627
+ self.data = sorted(self.data, key=lambda x: x.addr)
2628
+
2629
+ data_indices_to_remove = set()
2630
+
2631
+ # Go through data entry list and refine them
2632
+ for i, data in enumerate(self.data):
2633
+ if i in data_indices_to_remove:
2634
+ continue
2635
+
2636
+ # process the overlapping ones
2637
+ if i < len(self.data) - 1:
2638
+ if data.addr + data.size > self.data[i + 1].addr:
2639
+ # they are overlapping :-(
2640
+
2641
+ # TODO: make sure new_size makes sense
2642
+ new_size = self.data[i + 1].addr - data.addr
2643
+
2644
+ # there are cases that legit data is misclassified as pointers
2645
+ # we are able to detect some of them here
2646
+ if data.sort == "pointer-array":
2647
+ pointer_size = self.project.arch.bytes
2648
+ if new_size % pointer_size != 0:
2649
+ # the self.data[i+1] cannot be pointed to by a pointer
2650
+ # remove that guy later
2651
+ data_indices_to_remove.add(i + 1)
2652
+ # mark the source as a non-pointer
2653
+ # apparently the original Reassembleable Disassembler paper cannot get this case
2654
+ source_addr = self.data[i + 1].memory_data.pointer_addr
2655
+ if source_addr is not None:
2656
+ # find the original data
2657
+ original_data = next(
2658
+ (d for d in self.data if d.addr <= source_addr < d.addr + d.size), None
2659
+ )
2660
+ if original_data is not None:
2661
+ original_data.desymbolize()
2662
+
2663
+ continue
2664
+
2665
+ data.shrink(new_size)
2666
+
2667
+ # process those ones whose type is unknown
2668
+ if data.sort == "unknown" and data.size == 0:
2669
+ # increase its size until reaching the next item
2670
+
2671
+ if i + 1 == len(self.data):
2672
+ if data.section is None:
2673
+ continue
2674
+ data.size = data.section.vaddr + data.section.memsize - data.addr
2675
+ else:
2676
+ data.size = self.data[i + 1].addr - data.addr
2677
+
2678
+ for i in sorted(data_indices_to_remove, reverse=True):
2679
+ self.data = self.data[:i] + self.data[i + 1 :]
2680
+
2681
+ # CGC-specific data filtering
2682
+ self.data = [d for d in self.data if d.section_name not in section_names_to_ignore]
2683
+
2684
+ # restore capstone X86 syntax at the end
2685
+ if self.project.arch.capstone_x86_syntax != old_capstone_syntax:
2686
+ self.project.arch.capstone_x86_syntax = old_capstone_syntax
2687
+ self.project.factory.default_engine.clear_cache()
2688
+
2689
+ l.debug("Initialized.")
2690
+
2691
+ def _is_sequence(self, cfg, addr, size):
2692
+ data = self.fast_memory_load(addr, size, bytes)
2693
+ if data is None:
2694
+ return False
2695
+ ints = [i for i in data]
2696
+ if len({(i - j) for i, j in zip(ints, ints[1:])}) == 1:
2697
+ # arithmetic progression
2698
+ # backoff: it should not be ending with a pointer
2699
+ closest_aligned_addr = (addr + size - 1) & 0xFFFFFFFC
2700
+ ptr = self.fast_memory_load(closest_aligned_addr, 4, int, endness=self.project.arch.memory_endness)
2701
+ if ptr is None:
2702
+ return False
2703
+ if self._is_pointer(cfg, ptr):
2704
+ return False
2705
+ return True
2706
+ return False
2707
+
2708
+ def _is_pointer(self, cfg, ptr):
2709
+ if (
2710
+ cfg.project.loader.find_section_containing(ptr) is not None
2711
+ or cfg.project.loader.find_segment_containing(ptr) is not None
2712
+ or (self._extra_memory_regions and next(((a < ptr < b) for (a, b) in self._extra_memory_regions), None))
2713
+ ):
2714
+ return True
2715
+ return False
2716
+
2717
+ def _sequence_handler(self, cfg, irsb, irsb_addr, stmt_idx, data_addr, max_size): # pylint:disable=unused-argument
2718
+ """
2719
+ Find sequences in binary data.
2720
+
2721
+ :param angr.analyses.CFG cfg: The control flow graph.
2722
+ :param pyvex.IRSB irsb: The IRSB object.
2723
+ :param int irsb_addr: Address of the block.
2724
+ :param int stmt_idx: Statement ID.
2725
+ :param int data_addr: Address of the data in memory.
2726
+ :param int max_size: Maximum size possible.
2727
+ :return: A 2-tuple of data type and size.
2728
+ :rtype: tuple
2729
+ """
2730
+
2731
+ if not self._is_sequence(cfg, data_addr, 5):
2732
+ # fail-fast
2733
+ return None, None
2734
+
2735
+ sequence_max_size = min(256, max_size)
2736
+
2737
+ for i in range(5, min(256, max_size)):
2738
+ if not self._is_sequence(cfg, data_addr, i):
2739
+ return "sequence", i - 1
2740
+
2741
+ return "sequence", sequence_max_size
2742
+
2743
+ def _cgc_package_list_identifier(self, data_addr, data_size):
2744
+ """
2745
+ Identifies the CGC package list associated with the CGC binary.
2746
+
2747
+ :param int data_addr: Address of the data in memory.
2748
+ :param int data_size: Maximum size possible.
2749
+ :return: A 2-tuple of data type and size.
2750
+ :rtype: tuple
2751
+ """
2752
+
2753
+ if data_size < 100:
2754
+ return None, None
2755
+
2756
+ data = self.fast_memory_load(data_addr, data_size, str)
2757
+
2758
+ if data[:10] != "The DECREE":
2759
+ return None, None
2760
+
2761
+ if not all(i in string.printable for i in data):
2762
+ return None, None
2763
+
2764
+ if not re.match(r"The DECREE packages used in the creation of this challenge binary were:", data):
2765
+ return None, None
2766
+
2767
+ return "cgc-package-list", data_size
2768
+
2769
+ def _cgc_extended_application_handler(
2770
+ self, cfg, irsb, irsb_addr, stmt_idx, data_addr, max_size
2771
+ ): # pylint:disable=unused-argument
2772
+ """
2773
+ Identifies the extended application (a PDF file) associated with the CGC binary.
2774
+
2775
+ :param angr.analyses.CFG cfg: The control flow graph.
2776
+ :param pyvex.IRSB irsb: The IRSB object.
2777
+ :param int irsb_addr: Address of the block.
2778
+ :param int stmt_idx: Statement ID.
2779
+ :param int data_addr: Address of the data in memory.
2780
+ :param int max_size: Maximum size possible.
2781
+ :return: A 2-tuple of data type and size.
2782
+ :rtype: tuple
2783
+ """
2784
+
2785
+ if max_size < 100:
2786
+ return None, None
2787
+
2788
+ data = self.fast_memory_load(data_addr, 20, bytes)
2789
+
2790
+ if data is not None and data[:4] != b"The ":
2791
+ return None, None
2792
+
2793
+ # read everything in
2794
+ data = self.fast_memory_load(data_addr, max_size, str)
2795
+
2796
+ m = re.match(r"The ([\d]+) byte CGC Extended Application follows.", data)
2797
+ if not m:
2798
+ return None, None
2799
+ pdf_size = int(m.group(1))
2800
+
2801
+ if "%PDF" not in data:
2802
+ return None, None
2803
+ if "%%EOF" not in data:
2804
+ return None, None
2805
+
2806
+ pdf_data = data[data.index("%PDF") : data.index("%%EOF") + 6]
2807
+
2808
+ if len(pdf_data) != pdf_size:
2809
+ return None, None
2810
+
2811
+ return "cgc-extended-application", max_size
2812
+
2813
+ def _unknown_data_size_handler(
2814
+ self, cfg, irsb, irsb_addr, stmt_idx, data_addr, max_size
2815
+ ): # pylint:disable=unused-argument
2816
+ """
2817
+ Return the maximum number of bytes until a potential pointer or a potential sequence is found.
2818
+
2819
+ :param angr.analyses.CFG cfg: The control flow graph.
2820
+ :param pyvex.IRSB irsb: The IRSB object.
2821
+ :param int irsb_addr: Address of the block.
2822
+ :param int stmt_idx: Statement ID.
2823
+ :param int data_addr: Address of the data in memory.
2824
+ :param int max_size: Maximum size possible.
2825
+ :return: A 2-tuple of data type and size.
2826
+ :rtype: tuple
2827
+ """
2828
+
2829
+ sequence_offset = None
2830
+
2831
+ for offset in range(1, max_size):
2832
+ if self._is_sequence(cfg, data_addr + offset, 5):
2833
+ # a potential sequence is found
2834
+ sequence_offset = offset
2835
+ break
2836
+
2837
+ if sequence_offset is not None:
2838
+ if self.project.arch.bits == 32:
2839
+ max_size = min(max_size, sequence_offset)
2840
+ elif self.project.arch.bits == 64:
2841
+ max_size = min(max_size, sequence_offset + 5) # high 5 bytes might be all zeros...
2842
+
2843
+ ptr_size = cfg.project.arch.bytes
2844
+
2845
+ size = None
2846
+
2847
+ for offset in range(1, max_size - ptr_size + 1):
2848
+ ptr = self.fast_memory_load(data_addr + offset, ptr_size, int, endness=cfg.project.arch.memory_endness)
2849
+ if self._is_pointer(cfg, ptr):
2850
+ size = offset
2851
+ break
2852
+
2853
+ if size is not None:
2854
+ return "unknown", size
2855
+ elif sequence_offset is not None:
2856
+ return "unknown", sequence_offset
2857
+ else:
2858
+ return None, None
2859
+
2860
+ def _has_integer_used_as_pointers(self):
2861
+ """
2862
+ Test if there is any (suspicious) pointer decryption in the code.
2863
+
2864
+ :return: True if there is any pointer decryption, False otherwise.
2865
+ :rtype: bool
2866
+ """
2867
+
2868
+ # check all integer accesses and see if there is any integer being used as a pointer later, but it wasn't
2869
+ # classified as a pointer reference
2870
+
2871
+ # we only care about unknown memory data that are 4 bytes long, and is directly referenced from an IRSB
2872
+ candidates = [
2873
+ i
2874
+ for i in self.cfg.memory_data.values()
2875
+ if i.sort in ("unknown", "integer") and i.size == self.project.arch.bytes and i.irsb_addr is not None
2876
+ ]
2877
+
2878
+ if not candidates:
2879
+ return False
2880
+
2881
+ for candidate in candidates:
2882
+ # if the candidate is in .bss, we don't care about it
2883
+ sec = self.cfg.project.loader.find_section_containing(candidate.address)
2884
+ if sec.name in (".bss", ".got.plt"):
2885
+ continue
2886
+
2887
+ # execute the single basic block and see how the value is used
2888
+ base_graph = networkx.DiGraph()
2889
+ candidate_node: CFGNode = self.cfg.model.get_any_node(candidate.irsb_addr)
2890
+ if candidate_node is None:
2891
+ continue
2892
+ base_graph.add_node(candidate_node)
2893
+ tmp_kb = KnowledgeBase(self.project)
2894
+ cfg = self.project.analyses[CFGEmulated].prep(kb=tmp_kb)(
2895
+ starts=(candidate.irsb_addr,), keep_state=True, base_graph=base_graph
2896
+ )
2897
+ candidate_irsb = cfg.get_any_irsb(candidate.irsb_addr)
2898
+ ddg = self.project.analyses[DDG].prep(kb=tmp_kb)(cfg=cfg)
2899
+
2900
+ mem_var_node = None
2901
+ for node in ddg.simplified_data_graph.nodes():
2902
+ if isinstance(node.variable, SimMemoryVariable) and node.location.ins_addr == candidate.insn_addr:
2903
+ # found it!
2904
+ mem_var_node = node
2905
+ break
2906
+ else:
2907
+ # mem_var_node is not found
2908
+ continue
2909
+
2910
+ # get a sub graph
2911
+ subgraph = ddg.data_sub_graph(
2912
+ mem_var_node,
2913
+ simplified=False,
2914
+ killing_edges=False,
2915
+ excluding_types={"mem_addr"},
2916
+ )
2917
+
2918
+ # is it used as a memory address anywhere?
2919
+ # TODO:
2920
+
2921
+ # is it used as a jump target?
2922
+ next_tmp = None
2923
+ if isinstance(candidate_irsb.irsb.next, pyvex.IRExpr.RdTmp):
2924
+ next_tmp = candidate_irsb.irsb.next.tmp
2925
+
2926
+ if next_tmp is not None:
2927
+ next_tmp_node = next(
2928
+ (
2929
+ node
2930
+ for node in subgraph.nodes()
2931
+ if isinstance(node.variable, SimTemporaryVariable) and node.variable.tmp_id == next_tmp
2932
+ ),
2933
+ None,
2934
+ )
2935
+ if next_tmp_node is not None:
2936
+ # ouch it's used as a jump target
2937
+ return True
2938
+
2939
+ return False
2940
+
2941
+ def fast_memory_load(self, addr, size, data_type, endness="Iend_LE"):
2942
+ """
2943
+ Load memory bytes from loader's memory backend.
2944
+
2945
+ :param int addr: The address to begin memory loading.
2946
+ :param int size: Size in bytes.
2947
+ :param data_type: Type of the data.
2948
+ :param str endness: Endianness of this memory load.
2949
+ :return: Data read out of the memory.
2950
+ :rtype: int or bytes or str or None
2951
+ """
2952
+
2953
+ if data_type is int:
2954
+ try:
2955
+ return self.project.loader.memory.unpack_word(addr, size=size, endness=endness)
2956
+ except KeyError:
2957
+ return None
2958
+
2959
+ try:
2960
+ data = self.project.loader.memory.load(addr, size)
2961
+ if data_type is str:
2962
+ return "".join(chr(i) for i in data)
2963
+ return data
2964
+ except KeyError:
2965
+ return None
2966
+
2967
+
2968
+ from angr.analyses import AnalysesHub
2969
+
2970
+ AnalysesHub.register_default("Reassembler", Reassembler)