angr 9.2.192__cp311-cp311-macosx_10_12_x86_64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- angr/__init__.py +366 -0
- angr/__main__.py +182 -0
- angr/ail_callable.py +79 -0
- angr/ailment/__init__.py +83 -0
- angr/ailment/block.py +88 -0
- angr/ailment/block_walker.py +856 -0
- angr/ailment/constant.py +3 -0
- angr/ailment/converter_common.py +11 -0
- angr/ailment/converter_pcode.py +648 -0
- angr/ailment/converter_vex.py +829 -0
- angr/ailment/expression.py +1655 -0
- angr/ailment/manager.py +34 -0
- angr/ailment/statement.py +973 -0
- angr/ailment/tagged_object.py +58 -0
- angr/ailment/utils.py +114 -0
- angr/analyses/__init__.py +117 -0
- angr/analyses/analysis.py +429 -0
- angr/analyses/backward_slice.py +686 -0
- angr/analyses/binary_optimizer.py +670 -0
- angr/analyses/bindiff.py +1512 -0
- angr/analyses/boyscout.py +76 -0
- angr/analyses/callee_cleanup_finder.py +74 -0
- angr/analyses/calling_convention/__init__.py +6 -0
- angr/analyses/calling_convention/calling_convention.py +1113 -0
- angr/analyses/calling_convention/fact_collector.py +647 -0
- angr/analyses/calling_convention/utils.py +60 -0
- angr/analyses/cdg.py +189 -0
- angr/analyses/cfg/__init__.py +23 -0
- angr/analyses/cfg/cfb.py +451 -0
- angr/analyses/cfg/cfg.py +74 -0
- angr/analyses/cfg/cfg_arch_options.py +95 -0
- angr/analyses/cfg/cfg_base.py +2954 -0
- angr/analyses/cfg/cfg_emulated.py +3451 -0
- angr/analyses/cfg/cfg_fast.py +5431 -0
- angr/analyses/cfg/cfg_fast_soot.py +662 -0
- angr/analyses/cfg/cfg_job_base.py +203 -0
- angr/analyses/cfg/indirect_jump_resolvers/__init__.py +30 -0
- angr/analyses/cfg/indirect_jump_resolvers/aarch64_macho_got.py +77 -0
- angr/analyses/cfg/indirect_jump_resolvers/amd64_elf_got.py +62 -0
- angr/analyses/cfg/indirect_jump_resolvers/amd64_pe_iat.py +51 -0
- angr/analyses/cfg/indirect_jump_resolvers/arm_elf_fast.py +159 -0
- angr/analyses/cfg/indirect_jump_resolvers/const_resolver.py +339 -0
- angr/analyses/cfg/indirect_jump_resolvers/constant_value_manager.py +107 -0
- angr/analyses/cfg/indirect_jump_resolvers/default_resolvers.py +82 -0
- angr/analyses/cfg/indirect_jump_resolvers/jumptable.py +2490 -0
- angr/analyses/cfg/indirect_jump_resolvers/memload_resolver.py +81 -0
- angr/analyses/cfg/indirect_jump_resolvers/mips_elf_fast.py +286 -0
- angr/analyses/cfg/indirect_jump_resolvers/mips_elf_got.py +148 -0
- angr/analyses/cfg/indirect_jump_resolvers/propagator_utils.py +46 -0
- angr/analyses/cfg/indirect_jump_resolvers/resolver.py +74 -0
- angr/analyses/cfg/indirect_jump_resolvers/syscall_resolver.py +92 -0
- angr/analyses/cfg/indirect_jump_resolvers/x86_elf_pic_plt.py +88 -0
- angr/analyses/cfg/indirect_jump_resolvers/x86_pe_iat.py +47 -0
- angr/analyses/cfg_slice_to_sink/__init__.py +11 -0
- angr/analyses/cfg_slice_to_sink/cfg_slice_to_sink.py +117 -0
- angr/analyses/cfg_slice_to_sink/graph.py +87 -0
- angr/analyses/cfg_slice_to_sink/transitions.py +27 -0
- angr/analyses/class_identifier.py +63 -0
- angr/analyses/code_tagging.py +123 -0
- angr/analyses/codecave.py +77 -0
- angr/analyses/complete_calling_conventions.py +475 -0
- angr/analyses/congruency_check.py +377 -0
- angr/analyses/data_dep/__init__.py +16 -0
- angr/analyses/data_dep/data_dependency_analysis.py +595 -0
- angr/analyses/data_dep/dep_nodes.py +171 -0
- angr/analyses/data_dep/sim_act_location.py +49 -0
- angr/analyses/datagraph_meta.py +105 -0
- angr/analyses/ddg.py +1670 -0
- angr/analyses/decompiler/__init__.py +41 -0
- angr/analyses/decompiler/ail_simplifier.py +2246 -0
- angr/analyses/decompiler/ailgraph_walker.py +49 -0
- angr/analyses/decompiler/block_io_finder.py +302 -0
- angr/analyses/decompiler/block_similarity.py +199 -0
- angr/analyses/decompiler/block_simplifier.py +397 -0
- angr/analyses/decompiler/callsite_maker.py +579 -0
- angr/analyses/decompiler/ccall_rewriters/__init__.py +9 -0
- angr/analyses/decompiler/ccall_rewriters/amd64_ccalls.py +618 -0
- angr/analyses/decompiler/ccall_rewriters/rewriter_base.py +24 -0
- angr/analyses/decompiler/ccall_rewriters/x86_ccalls.py +354 -0
- angr/analyses/decompiler/clinic.py +3662 -0
- angr/analyses/decompiler/condition_processor.py +1323 -0
- angr/analyses/decompiler/counters/__init__.py +16 -0
- angr/analyses/decompiler/counters/boolean_counter.py +27 -0
- angr/analyses/decompiler/counters/call_counter.py +77 -0
- angr/analyses/decompiler/counters/expression_counters.py +77 -0
- angr/analyses/decompiler/counters/seq_cf_structure_counter.py +63 -0
- angr/analyses/decompiler/decompilation_cache.py +54 -0
- angr/analyses/decompiler/decompilation_options.py +317 -0
- angr/analyses/decompiler/decompiler.py +796 -0
- angr/analyses/decompiler/dephication/__init__.py +6 -0
- angr/analyses/decompiler/dephication/dephication_base.py +100 -0
- angr/analyses/decompiler/dephication/graph_dephication.py +70 -0
- angr/analyses/decompiler/dephication/graph_rewriting.py +112 -0
- angr/analyses/decompiler/dephication/graph_vvar_mapping.py +357 -0
- angr/analyses/decompiler/dephication/rewriting_engine.py +528 -0
- angr/analyses/decompiler/dephication/seqnode_dephication.py +156 -0
- angr/analyses/decompiler/dirty_rewriters/__init__.py +7 -0
- angr/analyses/decompiler/dirty_rewriters/amd64_dirty.py +74 -0
- angr/analyses/decompiler/dirty_rewriters/rewriter_base.py +27 -0
- angr/analyses/decompiler/empty_node_remover.py +212 -0
- angr/analyses/decompiler/expression_narrower.py +290 -0
- angr/analyses/decompiler/goto_manager.py +112 -0
- angr/analyses/decompiler/graph_region.py +441 -0
- angr/analyses/decompiler/jump_target_collector.py +37 -0
- angr/analyses/decompiler/jumptable_entry_condition_rewriter.py +67 -0
- angr/analyses/decompiler/label_collector.py +32 -0
- angr/analyses/decompiler/node_replacer.py +42 -0
- angr/analyses/decompiler/notes/__init__.py +9 -0
- angr/analyses/decompiler/notes/decompilation_note.py +48 -0
- angr/analyses/decompiler/notes/deobfuscated_strings.py +56 -0
- angr/analyses/decompiler/optimization_passes/__init__.py +164 -0
- angr/analyses/decompiler/optimization_passes/base_ptr_save_simplifier.py +157 -0
- angr/analyses/decompiler/optimization_passes/call_stmt_rewriter.py +46 -0
- angr/analyses/decompiler/optimization_passes/code_motion.py +362 -0
- angr/analyses/decompiler/optimization_passes/condition_constprop.py +211 -0
- angr/analyses/decompiler/optimization_passes/const_derefs.py +127 -0
- angr/analyses/decompiler/optimization_passes/const_prop_reverter.py +365 -0
- angr/analyses/decompiler/optimization_passes/cross_jump_reverter.py +106 -0
- angr/analyses/decompiler/optimization_passes/deadblock_remover.py +82 -0
- angr/analyses/decompiler/optimization_passes/determine_load_sizes.py +64 -0
- angr/analyses/decompiler/optimization_passes/div_simplifier.py +425 -0
- angr/analyses/decompiler/optimization_passes/duplication_reverter/__init__.py +5 -0
- angr/analyses/decompiler/optimization_passes/duplication_reverter/ail_merge_graph.py +503 -0
- angr/analyses/decompiler/optimization_passes/duplication_reverter/duplication_reverter.py +1221 -0
- angr/analyses/decompiler/optimization_passes/duplication_reverter/errors.py +16 -0
- angr/analyses/decompiler/optimization_passes/duplication_reverter/similarity.py +126 -0
- angr/analyses/decompiler/optimization_passes/duplication_reverter/utils.py +167 -0
- angr/analyses/decompiler/optimization_passes/eager_std_string_concatenation.py +236 -0
- angr/analyses/decompiler/optimization_passes/eager_std_string_eval.py +186 -0
- angr/analyses/decompiler/optimization_passes/engine_base.py +502 -0
- angr/analyses/decompiler/optimization_passes/expr_op_swapper.py +138 -0
- angr/analyses/decompiler/optimization_passes/flip_boolean_cmp.py +113 -0
- angr/analyses/decompiler/optimization_passes/inlined_string_transformation_simplifier.py +618 -0
- angr/analyses/decompiler/optimization_passes/inlined_strlen_simplifier.py +274 -0
- angr/analyses/decompiler/optimization_passes/ite_expr_converter.py +224 -0
- angr/analyses/decompiler/optimization_passes/ite_region_converter.py +337 -0
- angr/analyses/decompiler/optimization_passes/lowered_switch_simplifier.py +939 -0
- angr/analyses/decompiler/optimization_passes/mod_simplifier.py +99 -0
- angr/analyses/decompiler/optimization_passes/optimization_pass.py +710 -0
- angr/analyses/decompiler/optimization_passes/peephole_simplifier.py +75 -0
- angr/analyses/decompiler/optimization_passes/register_save_area_simplifier.py +263 -0
- angr/analyses/decompiler/optimization_passes/register_save_area_simplifier_adv.py +198 -0
- angr/analyses/decompiler/optimization_passes/ret_addr_save_simplifier.py +171 -0
- angr/analyses/decompiler/optimization_passes/ret_deduplicator.py +222 -0
- angr/analyses/decompiler/optimization_passes/return_duplicator_base.py +632 -0
- angr/analyses/decompiler/optimization_passes/return_duplicator_high.py +61 -0
- angr/analyses/decompiler/optimization_passes/return_duplicator_low.py +166 -0
- angr/analyses/decompiler/optimization_passes/stack_canary_simplifier.py +333 -0
- angr/analyses/decompiler/optimization_passes/static_vvar_rewriter.py +336 -0
- angr/analyses/decompiler/optimization_passes/switch_default_case_duplicator.py +166 -0
- angr/analyses/decompiler/optimization_passes/switch_reused_entry_rewriter.py +102 -0
- angr/analyses/decompiler/optimization_passes/tag_slicer.py +41 -0
- angr/analyses/decompiler/optimization_passes/win_stack_canary_simplifier.py +477 -0
- angr/analyses/decompiler/optimization_passes/x86_gcc_getpc_simplifier.py +88 -0
- angr/analyses/decompiler/peephole_optimizations/__init__.py +136 -0
- angr/analyses/decompiler/peephole_optimizations/a_div_const_add_a_mul_n_div_const.py +42 -0
- angr/analyses/decompiler/peephole_optimizations/a_mul_const_div_shr_const.py +38 -0
- angr/analyses/decompiler/peephole_optimizations/a_mul_const_sub_a.py +34 -0
- angr/analyses/decompiler/peephole_optimizations/a_shl_const_sub_a.py +34 -0
- angr/analyses/decompiler/peephole_optimizations/a_sub_a_div.py +25 -0
- angr/analyses/decompiler/peephole_optimizations/a_sub_a_shr_const_shr_const.py +37 -0
- angr/analyses/decompiler/peephole_optimizations/a_sub_a_sub_n.py +23 -0
- angr/analyses/decompiler/peephole_optimizations/arm_cmpf.py +236 -0
- angr/analyses/decompiler/peephole_optimizations/base.py +157 -0
- angr/analyses/decompiler/peephole_optimizations/basepointeroffset_add_n.py +34 -0
- angr/analyses/decompiler/peephole_optimizations/basepointeroffset_and_mask.py +36 -0
- angr/analyses/decompiler/peephole_optimizations/bitwise_or_to_logical_or.py +34 -0
- angr/analyses/decompiler/peephole_optimizations/bool_expr_xor_1.py +27 -0
- angr/analyses/decompiler/peephole_optimizations/bswap.py +142 -0
- angr/analyses/decompiler/peephole_optimizations/cas_intrinsics.py +182 -0
- angr/analyses/decompiler/peephole_optimizations/cmpord_rewriter.py +71 -0
- angr/analyses/decompiler/peephole_optimizations/coalesce_adjacent_shrs.py +39 -0
- angr/analyses/decompiler/peephole_optimizations/coalesce_same_cascading_ifs.py +28 -0
- angr/analyses/decompiler/peephole_optimizations/constant_derefs.py +44 -0
- angr/analyses/decompiler/peephole_optimizations/conv_a_sub0_shr_and.py +69 -0
- angr/analyses/decompiler/peephole_optimizations/conv_shl_shr.py +52 -0
- angr/analyses/decompiler/peephole_optimizations/eager_eval.py +436 -0
- angr/analyses/decompiler/peephole_optimizations/extended_byte_and_mask.py +56 -0
- angr/analyses/decompiler/peephole_optimizations/inlined_memcpy.py +78 -0
- angr/analyses/decompiler/peephole_optimizations/inlined_memset.py +262 -0
- angr/analyses/decompiler/peephole_optimizations/inlined_strcpy.py +217 -0
- angr/analyses/decompiler/peephole_optimizations/inlined_strcpy_consolidation.py +106 -0
- angr/analyses/decompiler/peephole_optimizations/inlined_wcscpy.py +256 -0
- angr/analyses/decompiler/peephole_optimizations/inlined_wcscpy_consolidation.py +296 -0
- angr/analyses/decompiler/peephole_optimizations/invert_negated_logical_conjuction_disjunction.py +50 -0
- angr/analyses/decompiler/peephole_optimizations/modulo_simplifier.py +89 -0
- angr/analyses/decompiler/peephole_optimizations/one_sub_bool.py +33 -0
- angr/analyses/decompiler/peephole_optimizations/optimized_div_simplifier.py +356 -0
- angr/analyses/decompiler/peephole_optimizations/remove_cascading_conversions.py +45 -0
- angr/analyses/decompiler/peephole_optimizations/remove_cxx_destructor_calls.py +32 -0
- angr/analyses/decompiler/peephole_optimizations/remove_empty_if_body.py +46 -0
- angr/analyses/decompiler/peephole_optimizations/remove_noop_conversions.py +47 -0
- angr/analyses/decompiler/peephole_optimizations/remove_redundant_bitmasks.py +125 -0
- angr/analyses/decompiler/peephole_optimizations/remove_redundant_conversions.py +273 -0
- angr/analyses/decompiler/peephole_optimizations/remove_redundant_derefs.py +21 -0
- angr/analyses/decompiler/peephole_optimizations/remove_redundant_ite_branch.py +30 -0
- angr/analyses/decompiler/peephole_optimizations/remove_redundant_ite_comparisons.py +54 -0
- angr/analyses/decompiler/peephole_optimizations/remove_redundant_nots.py +36 -0
- angr/analyses/decompiler/peephole_optimizations/remove_redundant_reinterprets.py +44 -0
- angr/analyses/decompiler/peephole_optimizations/remove_redundant_shifts.py +95 -0
- angr/analyses/decompiler/peephole_optimizations/remove_redundant_shifts_around_comparators.py +115 -0
- angr/analyses/decompiler/peephole_optimizations/rewrite_bit_extractions.py +85 -0
- angr/analyses/decompiler/peephole_optimizations/rewrite_conv_mul.py +40 -0
- angr/analyses/decompiler/peephole_optimizations/rewrite_cxx_operator_calls.py +90 -0
- angr/analyses/decompiler/peephole_optimizations/rewrite_mips_gp_loads.py +49 -0
- angr/analyses/decompiler/peephole_optimizations/rol_ror.py +130 -0
- angr/analyses/decompiler/peephole_optimizations/sar_to_signed_div.py +143 -0
- angr/analyses/decompiler/peephole_optimizations/shl_to_mul.py +25 -0
- angr/analyses/decompiler/peephole_optimizations/simplify_pc_relative_loads.py +51 -0
- angr/analyses/decompiler/peephole_optimizations/single_bit_cond_to_boolexpr.py +28 -0
- angr/analyses/decompiler/peephole_optimizations/single_bit_xor.py +29 -0
- angr/analyses/decompiler/peephole_optimizations/tidy_stack_addr.py +131 -0
- angr/analyses/decompiler/peephole_optimizations/utils.py +18 -0
- angr/analyses/decompiler/presets/__init__.py +22 -0
- angr/analyses/decompiler/presets/basic.py +36 -0
- angr/analyses/decompiler/presets/fast.py +66 -0
- angr/analyses/decompiler/presets/full.py +76 -0
- angr/analyses/decompiler/presets/malware.py +70 -0
- angr/analyses/decompiler/presets/preset.py +37 -0
- angr/analyses/decompiler/redundant_label_remover.py +141 -0
- angr/analyses/decompiler/region_identifier.py +1319 -0
- angr/analyses/decompiler/region_simplifiers/__init__.py +5 -0
- angr/analyses/decompiler/region_simplifiers/cascading_cond_transformer.py +95 -0
- angr/analyses/decompiler/region_simplifiers/cascading_ifs.py +82 -0
- angr/analyses/decompiler/region_simplifiers/expr_folding.py +838 -0
- angr/analyses/decompiler/region_simplifiers/goto.py +178 -0
- angr/analyses/decompiler/region_simplifiers/if_.py +135 -0
- angr/analyses/decompiler/region_simplifiers/ifelse.py +91 -0
- angr/analyses/decompiler/region_simplifiers/loop.py +143 -0
- angr/analyses/decompiler/region_simplifiers/node_address_finder.py +24 -0
- angr/analyses/decompiler/region_simplifiers/region_simplifier.py +270 -0
- angr/analyses/decompiler/region_simplifiers/switch_cluster_simplifier.py +654 -0
- angr/analyses/decompiler/region_simplifiers/switch_expr_simplifier.py +87 -0
- angr/analyses/decompiler/region_walker.py +24 -0
- angr/analyses/decompiler/return_maker.py +72 -0
- angr/analyses/decompiler/semantic_naming/__init__.py +37 -0
- angr/analyses/decompiler/semantic_naming/array_index_naming.py +196 -0
- angr/analyses/decompiler/semantic_naming/boolean_naming.py +264 -0
- angr/analyses/decompiler/semantic_naming/call_result_naming.py +220 -0
- angr/analyses/decompiler/semantic_naming/naming_base.py +166 -0
- angr/analyses/decompiler/semantic_naming/orchestrator.py +107 -0
- angr/analyses/decompiler/semantic_naming/pointer_naming.py +334 -0
- angr/analyses/decompiler/semantic_naming/region_loop_counter_naming.py +246 -0
- angr/analyses/decompiler/semantic_naming/size_naming.py +137 -0
- angr/analyses/decompiler/seq_to_blocks.py +20 -0
- angr/analyses/decompiler/sequence_walker.py +261 -0
- angr/analyses/decompiler/ssailification/__init__.py +4 -0
- angr/analyses/decompiler/ssailification/rewriting.py +451 -0
- angr/analyses/decompiler/ssailification/rewriting_engine.py +1091 -0
- angr/analyses/decompiler/ssailification/rewriting_state.py +61 -0
- angr/analyses/decompiler/ssailification/ssailification.py +283 -0
- angr/analyses/decompiler/ssailification/traversal.py +127 -0
- angr/analyses/decompiler/ssailification/traversal_engine.py +323 -0
- angr/analyses/decompiler/ssailification/traversal_state.py +48 -0
- angr/analyses/decompiler/stack_item.py +36 -0
- angr/analyses/decompiler/structured_codegen/__init__.py +25 -0
- angr/analyses/decompiler/structured_codegen/base.py +193 -0
- angr/analyses/decompiler/structured_codegen/c.py +4257 -0
- angr/analyses/decompiler/structured_codegen/dummy.py +15 -0
- angr/analyses/decompiler/structured_codegen/dwarf_import.py +190 -0
- angr/analyses/decompiler/structuring/__init__.py +30 -0
- angr/analyses/decompiler/structuring/dream.py +1217 -0
- angr/analyses/decompiler/structuring/phoenix.py +3636 -0
- angr/analyses/decompiler/structuring/recursive_structurer.py +187 -0
- angr/analyses/decompiler/structuring/sailr.py +120 -0
- angr/analyses/decompiler/structuring/structurer_base.py +1140 -0
- angr/analyses/decompiler/structuring/structurer_nodes.py +442 -0
- angr/analyses/decompiler/utils.py +1224 -0
- angr/analyses/deobfuscator/__init__.py +23 -0
- angr/analyses/deobfuscator/api_obf_finder.py +333 -0
- angr/analyses/deobfuscator/api_obf_peephole_optimizer.py +80 -0
- angr/analyses/deobfuscator/api_obf_type2_finder.py +166 -0
- angr/analyses/deobfuscator/data_transformation_embedder.py +633 -0
- angr/analyses/deobfuscator/hash_lookup_api_deobfuscator.py +156 -0
- angr/analyses/deobfuscator/irsb_reg_collector.py +54 -0
- angr/analyses/deobfuscator/scope_ops_analyzer.py +68 -0
- angr/analyses/deobfuscator/string_obf_finder.py +983 -0
- angr/analyses/deobfuscator/string_obf_opt_passes.py +136 -0
- angr/analyses/deobfuscator/string_obf_peephole_optimizer.py +47 -0
- angr/analyses/disassembly.py +1351 -0
- angr/analyses/disassembly_utils.py +101 -0
- angr/analyses/dominance_frontier.py +57 -0
- angr/analyses/fcp/__init__.py +4 -0
- angr/analyses/fcp/fcp.py +427 -0
- angr/analyses/find_objects_static.py +205 -0
- angr/analyses/flirt/__init__.py +47 -0
- angr/analyses/flirt/consts.py +160 -0
- angr/analyses/flirt/flirt.py +249 -0
- angr/analyses/flirt/flirt_function.py +20 -0
- angr/analyses/flirt/flirt_matcher.py +352 -0
- angr/analyses/flirt/flirt_module.py +32 -0
- angr/analyses/flirt/flirt_node.py +23 -0
- angr/analyses/flirt/flirt_sig.py +359 -0
- angr/analyses/flirt/flirt_utils.py +31 -0
- angr/analyses/forward_analysis/__init__.py +12 -0
- angr/analyses/forward_analysis/forward_analysis.py +619 -0
- angr/analyses/forward_analysis/job_info.py +64 -0
- angr/analyses/forward_analysis/visitors/__init__.py +14 -0
- angr/analyses/forward_analysis/visitors/call_graph.py +29 -0
- angr/analyses/forward_analysis/visitors/function_graph.py +86 -0
- angr/analyses/forward_analysis/visitors/graph.py +242 -0
- angr/analyses/forward_analysis/visitors/loop.py +29 -0
- angr/analyses/forward_analysis/visitors/single_node_graph.py +38 -0
- angr/analyses/identifier/__init__.py +5 -0
- angr/analyses/identifier/custom_callable.py +137 -0
- angr/analyses/identifier/errors.py +10 -0
- angr/analyses/identifier/func.py +60 -0
- angr/analyses/identifier/functions/__init__.py +37 -0
- angr/analyses/identifier/functions/atoi.py +73 -0
- angr/analyses/identifier/functions/based_atoi.py +125 -0
- angr/analyses/identifier/functions/fdprintf.py +123 -0
- angr/analyses/identifier/functions/free.py +64 -0
- angr/analyses/identifier/functions/int2str.py +287 -0
- angr/analyses/identifier/functions/malloc.py +111 -0
- angr/analyses/identifier/functions/memcmp.py +67 -0
- angr/analyses/identifier/functions/memcpy.py +89 -0
- angr/analyses/identifier/functions/memset.py +43 -0
- angr/analyses/identifier/functions/printf.py +123 -0
- angr/analyses/identifier/functions/recv_until.py +312 -0
- angr/analyses/identifier/functions/skip_calloc.py +73 -0
- angr/analyses/identifier/functions/skip_realloc.py +97 -0
- angr/analyses/identifier/functions/skip_recv_n.py +105 -0
- angr/analyses/identifier/functions/snprintf.py +112 -0
- angr/analyses/identifier/functions/sprintf.py +116 -0
- angr/analyses/identifier/functions/strcasecmp.py +33 -0
- angr/analyses/identifier/functions/strcmp.py +113 -0
- angr/analyses/identifier/functions/strcpy.py +43 -0
- angr/analyses/identifier/functions/strlen.py +27 -0
- angr/analyses/identifier/functions/strncmp.py +104 -0
- angr/analyses/identifier/functions/strncpy.py +65 -0
- angr/analyses/identifier/functions/strtol.py +89 -0
- angr/analyses/identifier/identify.py +825 -0
- angr/analyses/identifier/runner.py +360 -0
- angr/analyses/init_finder.py +289 -0
- angr/analyses/loop_analysis/__init__.py +4 -0
- angr/analyses/loop_analysis/loop_analysis.py +464 -0
- angr/analyses/loop_analysis.py +349 -0
- angr/analyses/loop_unroller/__init__.py +4 -0
- angr/analyses/loop_unroller/loop_unroller.py +222 -0
- angr/analyses/loopfinder.py +171 -0
- angr/analyses/outliner/__init__.py +7 -0
- angr/analyses/outliner/outliner.py +402 -0
- angr/analyses/patchfinder.py +137 -0
- angr/analyses/pathfinder.py +282 -0
- angr/analyses/propagator/__init__.py +5 -0
- angr/analyses/propagator/engine_base.py +62 -0
- angr/analyses/propagator/engine_vex.py +297 -0
- angr/analyses/propagator/propagator.py +361 -0
- angr/analyses/propagator/top_checker_mixin.py +218 -0
- angr/analyses/propagator/values.py +117 -0
- angr/analyses/propagator/vex_vars.py +68 -0
- angr/analyses/proximity_graph.py +444 -0
- angr/analyses/purity/__init__.py +15 -0
- angr/analyses/purity/analysis.py +78 -0
- angr/analyses/purity/engine.py +593 -0
- angr/analyses/reaching_definitions/__init__.py +67 -0
- angr/analyses/reaching_definitions/call_trace.py +73 -0
- angr/analyses/reaching_definitions/dep_graph.py +433 -0
- angr/analyses/reaching_definitions/engine_ail.py +1128 -0
- angr/analyses/reaching_definitions/engine_vex.py +1128 -0
- angr/analyses/reaching_definitions/external_codeloc.py +0 -0
- angr/analyses/reaching_definitions/function_handler.py +639 -0
- angr/analyses/reaching_definitions/function_handler_library/__init__.py +12 -0
- angr/analyses/reaching_definitions/function_handler_library/stdio.py +269 -0
- angr/analyses/reaching_definitions/function_handler_library/stdlib.py +195 -0
- angr/analyses/reaching_definitions/function_handler_library/string.py +158 -0
- angr/analyses/reaching_definitions/function_handler_library/unistd.py +51 -0
- angr/analyses/reaching_definitions/heap_allocator.py +70 -0
- angr/analyses/reaching_definitions/rd_initializer.py +237 -0
- angr/analyses/reaching_definitions/rd_state.py +579 -0
- angr/analyses/reaching_definitions/reaching_definitions.py +581 -0
- angr/analyses/reaching_definitions/subject.py +65 -0
- angr/analyses/reassembler.py +2900 -0
- angr/analyses/s_liveness.py +254 -0
- angr/analyses/s_propagator.py +575 -0
- angr/analyses/s_reaching_definitions/__init__.py +12 -0
- angr/analyses/s_reaching_definitions/s_rda_model.py +145 -0
- angr/analyses/s_reaching_definitions/s_rda_view.py +344 -0
- angr/analyses/s_reaching_definitions/s_reaching_definitions.py +230 -0
- angr/analyses/smc.py +160 -0
- angr/analyses/soot_class_hierarchy.py +273 -0
- angr/analyses/stack_pointer_tracker.py +954 -0
- angr/analyses/static_hooker.py +53 -0
- angr/analyses/typehoon/__init__.py +5 -0
- angr/analyses/typehoon/dfa.py +118 -0
- angr/analyses/typehoon/lifter.py +133 -0
- angr/analyses/typehoon/simple_solver.py +2009 -0
- angr/analyses/typehoon/translator.py +283 -0
- angr/analyses/typehoon/typeconsts.py +439 -0
- angr/analyses/typehoon/typehoon.py +338 -0
- angr/analyses/typehoon/typevars.py +633 -0
- angr/analyses/typehoon/variance.py +11 -0
- angr/analyses/unpacker/__init__.py +6 -0
- angr/analyses/unpacker/obfuscation_detector.py +103 -0
- angr/analyses/unpacker/packing_detector.py +138 -0
- angr/analyses/variable_recovery/__init__.py +9 -0
- angr/analyses/variable_recovery/annotations.py +58 -0
- angr/analyses/variable_recovery/engine_ail.py +978 -0
- angr/analyses/variable_recovery/engine_base.py +1256 -0
- angr/analyses/variable_recovery/engine_vex.py +594 -0
- angr/analyses/variable_recovery/irsb_scanner.py +143 -0
- angr/analyses/variable_recovery/variable_recovery.py +574 -0
- angr/analyses/variable_recovery/variable_recovery_base.py +489 -0
- angr/analyses/variable_recovery/variable_recovery_fast.py +669 -0
- angr/analyses/veritesting.py +626 -0
- angr/analyses/vfg.py +1898 -0
- angr/analyses/vsa_ddg.py +420 -0
- angr/analyses/vtable.py +92 -0
- angr/analyses/xrefs.py +286 -0
- angr/angrdb/__init__.py +14 -0
- angr/angrdb/db.py +215 -0
- angr/angrdb/models.py +184 -0
- angr/angrdb/serializers/__init__.py +10 -0
- angr/angrdb/serializers/cfg_model.py +41 -0
- angr/angrdb/serializers/comments.py +60 -0
- angr/angrdb/serializers/funcs.py +61 -0
- angr/angrdb/serializers/kb.py +111 -0
- angr/angrdb/serializers/labels.py +59 -0
- angr/angrdb/serializers/loader.py +165 -0
- angr/angrdb/serializers/structured_code.py +167 -0
- angr/angrdb/serializers/variables.py +58 -0
- angr/angrdb/serializers/xrefs.py +48 -0
- angr/annocfg.py +317 -0
- angr/blade.py +431 -0
- angr/block.py +509 -0
- angr/callable.py +176 -0
- angr/calling_conventions.py +2613 -0
- angr/code_location.py +249 -0
- angr/codenode.py +145 -0
- angr/concretization_strategies/__init__.py +32 -0
- angr/concretization_strategies/any.py +17 -0
- angr/concretization_strategies/any_named.py +35 -0
- angr/concretization_strategies/base.py +81 -0
- angr/concretization_strategies/controlled_data.py +58 -0
- angr/concretization_strategies/eval.py +19 -0
- angr/concretization_strategies/logging.py +35 -0
- angr/concretization_strategies/max.py +25 -0
- angr/concretization_strategies/nonzero.py +16 -0
- angr/concretization_strategies/nonzero_range.py +22 -0
- angr/concretization_strategies/norepeats.py +37 -0
- angr/concretization_strategies/norepeats_range.py +37 -0
- angr/concretization_strategies/range.py +19 -0
- angr/concretization_strategies/signed_add.py +31 -0
- angr/concretization_strategies/single.py +15 -0
- angr/concretization_strategies/solutions.py +20 -0
- angr/concretization_strategies/unlimited_range.py +17 -0
- angr/distributed/__init__.py +9 -0
- angr/distributed/server.py +197 -0
- angr/distributed/worker.py +185 -0
- angr/emulator.py +144 -0
- angr/engines/__init__.py +69 -0
- angr/engines/ail/__init__.py +16 -0
- angr/engines/ail/callstack.py +58 -0
- angr/engines/ail/engine_light.py +903 -0
- angr/engines/ail/engine_successors.py +24 -0
- angr/engines/ail/setup.py +57 -0
- angr/engines/concrete.py +66 -0
- angr/engines/engine.py +29 -0
- angr/engines/failure.py +27 -0
- angr/engines/hook.py +93 -0
- angr/engines/icicle.py +294 -0
- angr/engines/light/__init__.py +23 -0
- angr/engines/light/data.py +681 -0
- angr/engines/light/engine.py +1297 -0
- angr/engines/pcode/__init__.py +9 -0
- angr/engines/pcode/behavior.py +998 -0
- angr/engines/pcode/cc.py +148 -0
- angr/engines/pcode/emulate.py +440 -0
- angr/engines/pcode/engine.py +242 -0
- angr/engines/pcode/lifter.py +1428 -0
- angr/engines/procedure.py +70 -0
- angr/engines/soot/__init__.py +5 -0
- angr/engines/soot/engine.py +410 -0
- angr/engines/soot/exceptions.py +17 -0
- angr/engines/soot/expressions/__init__.py +87 -0
- angr/engines/soot/expressions/arrayref.py +22 -0
- angr/engines/soot/expressions/base.py +21 -0
- angr/engines/soot/expressions/binop.py +28 -0
- angr/engines/soot/expressions/cast.py +22 -0
- angr/engines/soot/expressions/condition.py +35 -0
- angr/engines/soot/expressions/constants.py +47 -0
- angr/engines/soot/expressions/instanceOf.py +15 -0
- angr/engines/soot/expressions/instancefieldref.py +8 -0
- angr/engines/soot/expressions/invoke.py +114 -0
- angr/engines/soot/expressions/length.py +8 -0
- angr/engines/soot/expressions/local.py +8 -0
- angr/engines/soot/expressions/new.py +16 -0
- angr/engines/soot/expressions/newArray.py +54 -0
- angr/engines/soot/expressions/newMultiArray.py +86 -0
- angr/engines/soot/expressions/paramref.py +8 -0
- angr/engines/soot/expressions/phi.py +30 -0
- angr/engines/soot/expressions/staticfieldref.py +8 -0
- angr/engines/soot/expressions/thisref.py +7 -0
- angr/engines/soot/expressions/unsupported.py +7 -0
- angr/engines/soot/field_dispatcher.py +46 -0
- angr/engines/soot/method_dispatcher.py +46 -0
- angr/engines/soot/statements/__init__.py +44 -0
- angr/engines/soot/statements/assign.py +30 -0
- angr/engines/soot/statements/base.py +79 -0
- angr/engines/soot/statements/goto.py +14 -0
- angr/engines/soot/statements/identity.py +15 -0
- angr/engines/soot/statements/if_.py +19 -0
- angr/engines/soot/statements/invoke.py +12 -0
- angr/engines/soot/statements/return_.py +20 -0
- angr/engines/soot/statements/switch.py +41 -0
- angr/engines/soot/statements/throw.py +15 -0
- angr/engines/soot/values/__init__.py +38 -0
- angr/engines/soot/values/arrayref.py +122 -0
- angr/engines/soot/values/base.py +7 -0
- angr/engines/soot/values/constants.py +18 -0
- angr/engines/soot/values/instancefieldref.py +44 -0
- angr/engines/soot/values/local.py +18 -0
- angr/engines/soot/values/paramref.py +18 -0
- angr/engines/soot/values/staticfieldref.py +38 -0
- angr/engines/soot/values/strref.py +38 -0
- angr/engines/soot/values/thisref.py +149 -0
- angr/engines/successors.py +608 -0
- angr/engines/syscall.py +51 -0
- angr/engines/unicorn.py +490 -0
- angr/engines/vex/__init__.py +20 -0
- angr/engines/vex/claripy/__init__.py +5 -0
- angr/engines/vex/claripy/ccall.py +2097 -0
- angr/engines/vex/claripy/datalayer.py +141 -0
- angr/engines/vex/claripy/irop.py +1276 -0
- angr/engines/vex/heavy/__init__.py +16 -0
- angr/engines/vex/heavy/actions.py +231 -0
- angr/engines/vex/heavy/concretizers.py +403 -0
- angr/engines/vex/heavy/dirty.py +466 -0
- angr/engines/vex/heavy/heavy.py +370 -0
- angr/engines/vex/heavy/inspect.py +52 -0
- angr/engines/vex/heavy/resilience.py +85 -0
- angr/engines/vex/heavy/super_fastpath.py +34 -0
- angr/engines/vex/lifter.py +420 -0
- angr/engines/vex/light/__init__.py +11 -0
- angr/engines/vex/light/light.py +551 -0
- angr/engines/vex/light/resilience.py +74 -0
- angr/engines/vex/light/slicing.py +52 -0
- angr/errors.py +611 -0
- angr/exploration_techniques/__init__.py +53 -0
- angr/exploration_techniques/base.py +126 -0
- angr/exploration_techniques/bucketizer.py +94 -0
- angr/exploration_techniques/common.py +56 -0
- angr/exploration_techniques/dfs.py +37 -0
- angr/exploration_techniques/director.py +520 -0
- angr/exploration_techniques/driller_core.py +100 -0
- angr/exploration_techniques/explorer.py +152 -0
- angr/exploration_techniques/lengthlimiter.py +22 -0
- angr/exploration_techniques/local_loop_seer.py +65 -0
- angr/exploration_techniques/loop_seer.py +236 -0
- angr/exploration_techniques/manual_mergepoint.py +82 -0
- angr/exploration_techniques/memory_watcher.py +43 -0
- angr/exploration_techniques/oppologist.py +92 -0
- angr/exploration_techniques/slicecutor.py +118 -0
- angr/exploration_techniques/spiller.py +280 -0
- angr/exploration_techniques/spiller_db.py +27 -0
- angr/exploration_techniques/stochastic.py +56 -0
- angr/exploration_techniques/stub_stasher.py +19 -0
- angr/exploration_techniques/suggestions.py +159 -0
- angr/exploration_techniques/tech_builder.py +49 -0
- angr/exploration_techniques/threading.py +69 -0
- angr/exploration_techniques/timeout.py +34 -0
- angr/exploration_techniques/tracer.py +1098 -0
- angr/exploration_techniques/unique.py +106 -0
- angr/exploration_techniques/veritesting.py +37 -0
- angr/factory.py +413 -0
- angr/flirt/__init__.py +124 -0
- angr/flirt/build_sig.py +305 -0
- angr/graph_utils.py +0 -0
- angr/keyed_region.py +525 -0
- angr/knowledge_base.py +146 -0
- angr/knowledge_plugins/__init__.py +43 -0
- angr/knowledge_plugins/callsite_prototypes.py +95 -0
- angr/knowledge_plugins/cfg/__init__.py +18 -0
- angr/knowledge_plugins/cfg/cfg_manager.py +95 -0
- angr/knowledge_plugins/cfg/cfg_model.py +1043 -0
- angr/knowledge_plugins/cfg/cfg_node.py +536 -0
- angr/knowledge_plugins/cfg/indirect_jump.py +131 -0
- angr/knowledge_plugins/cfg/memory_data.py +156 -0
- angr/knowledge_plugins/comments.py +16 -0
- angr/knowledge_plugins/custom_strings.py +38 -0
- angr/knowledge_plugins/data.py +22 -0
- angr/knowledge_plugins/debug_variables.py +216 -0
- angr/knowledge_plugins/functions/__init__.py +9 -0
- angr/knowledge_plugins/functions/function.py +1830 -0
- angr/knowledge_plugins/functions/function_manager.py +621 -0
- angr/knowledge_plugins/functions/function_parser.py +360 -0
- angr/knowledge_plugins/functions/soot_function.py +128 -0
- angr/knowledge_plugins/indirect_jumps.py +35 -0
- angr/knowledge_plugins/key_definitions/__init__.py +17 -0
- angr/knowledge_plugins/key_definitions/atoms.py +374 -0
- angr/knowledge_plugins/key_definitions/constants.py +29 -0
- angr/knowledge_plugins/key_definitions/definition.py +216 -0
- angr/knowledge_plugins/key_definitions/environment.py +96 -0
- angr/knowledge_plugins/key_definitions/heap_address.py +33 -0
- angr/knowledge_plugins/key_definitions/key_definition_manager.py +82 -0
- angr/knowledge_plugins/key_definitions/live_definitions.py +1020 -0
- angr/knowledge_plugins/key_definitions/liveness.py +165 -0
- angr/knowledge_plugins/key_definitions/rd_model.py +171 -0
- angr/knowledge_plugins/key_definitions/tag.py +78 -0
- angr/knowledge_plugins/key_definitions/undefined.py +70 -0
- angr/knowledge_plugins/key_definitions/unknown_size.py +86 -0
- angr/knowledge_plugins/key_definitions/uses.py +178 -0
- angr/knowledge_plugins/labels.py +110 -0
- angr/knowledge_plugins/obfuscations.py +40 -0
- angr/knowledge_plugins/patches.py +126 -0
- angr/knowledge_plugins/plugin.py +24 -0
- angr/knowledge_plugins/propagations/__init__.py +10 -0
- angr/knowledge_plugins/propagations/prop_value.py +191 -0
- angr/knowledge_plugins/propagations/propagation_manager.py +60 -0
- angr/knowledge_plugins/propagations/propagation_model.py +80 -0
- angr/knowledge_plugins/propagations/states.py +552 -0
- angr/knowledge_plugins/structured_code.py +63 -0
- angr/knowledge_plugins/types.py +95 -0
- angr/knowledge_plugins/variables/__init__.py +8 -0
- angr/knowledge_plugins/variables/variable_access.py +113 -0
- angr/knowledge_plugins/variables/variable_manager.py +1375 -0
- angr/knowledge_plugins/xrefs/__init__.py +12 -0
- angr/knowledge_plugins/xrefs/xref.py +150 -0
- angr/knowledge_plugins/xrefs/xref_manager.py +127 -0
- angr/knowledge_plugins/xrefs/xref_types.py +16 -0
- angr/misc/__init__.py +19 -0
- angr/misc/ansi.py +47 -0
- angr/misc/autoimport.py +90 -0
- angr/misc/bug_report.py +126 -0
- angr/misc/hookset.py +106 -0
- angr/misc/loggers.py +130 -0
- angr/misc/picklable_lock.py +46 -0
- angr/misc/plugins.py +289 -0
- angr/misc/telemetry.py +54 -0
- angr/misc/testing.py +24 -0
- angr/misc/ux.py +31 -0
- angr/procedures/__init__.py +12 -0
- angr/procedures/advapi32/__init__.py +0 -0
- angr/procedures/cgc/__init__.py +3 -0
- angr/procedures/cgc/_terminate.py +11 -0
- angr/procedures/cgc/allocate.py +75 -0
- angr/procedures/cgc/deallocate.py +67 -0
- angr/procedures/cgc/fdwait.py +65 -0
- angr/procedures/cgc/random.py +67 -0
- angr/procedures/cgc/receive.py +93 -0
- angr/procedures/cgc/transmit.py +65 -0
- angr/procedures/definitions/__init__.py +1043 -0
- angr/procedures/definitions/cgc.py +23 -0
- angr/procedures/definitions/common/glibc.json +3516 -0
- angr/procedures/definitions/gnulib.py +41 -0
- angr/procedures/definitions/libstdcpp.py +25 -0
- angr/procedures/definitions/linux_kernel.py +8382 -0
- angr/procedures/definitions/linux_loader.py +7 -0
- angr/procedures/definitions/macho_libsystem.py +18 -0
- angr/procedures/definitions/msvcr.py +25 -0
- angr/procedures/definitions/parse_glibc.py +77 -0
- angr/procedures/definitions/parse_syscalls_from_local_system.py +54 -0
- angr/procedures/definitions/parse_win32json.py +2540 -0
- angr/procedures/definitions/types_stl.py +22 -0
- angr/procedures/definitions/wdk/api-ms-win-dx-d3dkmt-l1-1-4.json +24 -0
- angr/procedures/definitions/wdk/api-ms-win-dx-d3dkmt-l1-1-6.json +18 -0
- angr/procedures/definitions/wdk/clfs.json +189 -0
- angr/procedures/definitions/wdk/fltmgr.json +813 -0
- angr/procedures/definitions/wdk/fwpkclnt.json +24 -0
- angr/procedures/definitions/wdk/fwpuclnt.json +453 -0
- angr/procedures/definitions/wdk/gdi32.json +528 -0
- angr/procedures/definitions/wdk/hal.json +96 -0
- angr/procedures/definitions/wdk/ksecdd.json +72 -0
- angr/procedures/definitions/wdk/ndis.json +336 -0
- angr/procedures/definitions/wdk/ntoskrnl.json +5158 -0
- angr/procedures/definitions/wdk/offreg.json +87 -0
- angr/procedures/definitions/wdk/pshed.json +33 -0
- angr/procedures/definitions/wdk/secur32.json +39 -0
- angr/procedures/definitions/wdk/vhfum.json +30 -0
- angr/procedures/definitions/win32/_types_win32.json +34480 -0
- angr/procedures/definitions/win32/aclui.json +24 -0
- angr/procedures/definitions/win32/activeds.json +81 -0
- angr/procedures/definitions/win32/advapi32.json +2505 -0
- angr/procedures/definitions/win32/advpack.json +165 -0
- angr/procedures/definitions/win32/amsi.json +36 -0
- angr/procedures/definitions/win32/api-ms-win-appmodel-runtime-l1-1-1.json +45 -0
- angr/procedures/definitions/win32/api-ms-win-appmodel-runtime-l1-1-3.json +30 -0
- angr/procedures/definitions/win32/api-ms-win-appmodel-runtime-l1-1-6.json +18 -0
- angr/procedures/definitions/win32/api-ms-win-core-apiquery-l2-1-0.json +18 -0
- angr/procedures/definitions/win32/api-ms-win-core-backgroundtask-l1-1-0.json +18 -0
- angr/procedures/definitions/win32/api-ms-win-core-comm-l1-1-1.json +18 -0
- angr/procedures/definitions/win32/api-ms-win-core-comm-l1-1-2.json +18 -0
- angr/procedures/definitions/win32/api-ms-win-core-enclave-l1-1-1.json +24 -0
- angr/procedures/definitions/win32/api-ms-win-core-errorhandling-l1-1-3.json +18 -0
- angr/procedures/definitions/win32/api-ms-win-core-featurestaging-l1-1-0.json +30 -0
- angr/procedures/definitions/win32/api-ms-win-core-featurestaging-l1-1-1.json +18 -0
- angr/procedures/definitions/win32/api-ms-win-core-file-fromapp-l1-1-0.json +48 -0
- angr/procedures/definitions/win32/api-ms-win-core-handle-l1-1-0.json +18 -0
- angr/procedures/definitions/win32/api-ms-win-core-ioring-l1-1-0.json +51 -0
- angr/procedures/definitions/win32/api-ms-win-core-marshal-l1-1-0.json +27 -0
- angr/procedures/definitions/win32/api-ms-win-core-memory-l1-1-3.json +27 -0
- angr/procedures/definitions/win32/api-ms-win-core-memory-l1-1-4.json +18 -0
- angr/procedures/definitions/win32/api-ms-win-core-memory-l1-1-5.json +24 -0
- angr/procedures/definitions/win32/api-ms-win-core-memory-l1-1-6.json +27 -0
- angr/procedures/definitions/win32/api-ms-win-core-memory-l1-1-7.json +21 -0
- angr/procedures/definitions/win32/api-ms-win-core-memory-l1-1-8.json +24 -0
- angr/procedures/definitions/win32/api-ms-win-core-path-l1-1-0.json +81 -0
- angr/procedures/definitions/win32/api-ms-win-core-psm-appnotify-l1-1-0.json +21 -0
- angr/procedures/definitions/win32/api-ms-win-core-psm-appnotify-l1-1-1.json +21 -0
- angr/procedures/definitions/win32/api-ms-win-core-realtime-l1-1-1.json +24 -0
- angr/procedures/definitions/win32/api-ms-win-core-realtime-l1-1-2.json +24 -0
- angr/procedures/definitions/win32/api-ms-win-core-slapi-l1-1-0.json +18 -0
- angr/procedures/definitions/win32/api-ms-win-core-state-helpers-l1-1-0.json +18 -0
- angr/procedures/definitions/win32/api-ms-win-core-synch-l1-2-0.json +24 -0
- angr/procedures/definitions/win32/api-ms-win-core-sysinfo-l1-2-0.json +18 -0
- angr/procedures/definitions/win32/api-ms-win-core-sysinfo-l1-2-3.json +21 -0
- angr/procedures/definitions/win32/api-ms-win-core-sysinfo-l1-2-4.json +21 -0
- angr/procedures/definitions/win32/api-ms-win-core-sysinfo-l1-2-6.json +18 -0
- angr/procedures/definitions/win32/api-ms-win-core-util-l1-1-1.json +21 -0
- angr/procedures/definitions/win32/api-ms-win-core-wow64-l1-1-1.json +24 -0
- angr/procedures/definitions/win32/api-ms-win-devices-query-l1-1-0.json +42 -0
- angr/procedures/definitions/win32/api-ms-win-devices-query-l1-1-1.json +30 -0
- angr/procedures/definitions/win32/api-ms-win-dx-d3dkmt-l1-1-0.json +18 -0
- angr/procedures/definitions/win32/api-ms-win-gaming-deviceinformation-l1-1-0.json +18 -0
- angr/procedures/definitions/win32/api-ms-win-gaming-expandedresources-l1-1-0.json +24 -0
- angr/procedures/definitions/win32/api-ms-win-gaming-tcui-l1-1-0.json +36 -0
- angr/procedures/definitions/win32/api-ms-win-gaming-tcui-l1-1-1.json +21 -0
- angr/procedures/definitions/win32/api-ms-win-gaming-tcui-l1-1-2.json +36 -0
- angr/procedures/definitions/win32/api-ms-win-gaming-tcui-l1-1-3.json +21 -0
- angr/procedures/definitions/win32/api-ms-win-gaming-tcui-l1-1-4.json +39 -0
- angr/procedures/definitions/win32/api-ms-win-mm-misc-l1-1-1.json +18 -0
- angr/procedures/definitions/win32/api-ms-win-net-isolation-l1-1-0.json +39 -0
- angr/procedures/definitions/win32/api-ms-win-security-base-l1-2-2.json +18 -0
- angr/procedures/definitions/win32/api-ms-win-security-isolatedcontainer-l1-1-0.json +18 -0
- angr/procedures/definitions/win32/api-ms-win-security-isolatedcontainer-l1-1-1.json +18 -0
- angr/procedures/definitions/win32/api-ms-win-service-core-l1-1-3.json +18 -0
- angr/procedures/definitions/win32/api-ms-win-service-core-l1-1-4.json +18 -0
- angr/procedures/definitions/win32/api-ms-win-service-core-l1-1-5.json +21 -0
- angr/procedures/definitions/win32/api-ms-win-shcore-scaling-l1-1-0.json +24 -0
- angr/procedures/definitions/win32/api-ms-win-shcore-scaling-l1-1-1.json +33 -0
- angr/procedures/definitions/win32/api-ms-win-shcore-scaling-l1-1-2.json +18 -0
- angr/procedures/definitions/win32/api-ms-win-wsl-api-l1-1-0.json +36 -0
- angr/procedures/definitions/win32/apphelp.json +18 -0
- angr/procedures/definitions/win32/authz.json +114 -0
- angr/procedures/definitions/win32/avicap32.json +27 -0
- angr/procedures/definitions/win32/avifil32.json +195 -0
- angr/procedures/definitions/win32/avrt.json +57 -0
- angr/procedures/definitions/win32/bcp47mrm.json +21 -0
- angr/procedures/definitions/win32/bcrypt.json +174 -0
- angr/procedures/definitions/win32/bcryptprimitives.json +21 -0
- angr/procedures/definitions/win32/bluetoothapis.json +138 -0
- angr/procedures/definitions/win32/bthprops_cpl.json +33 -0
- angr/procedures/definitions/win32/cabinet.json +81 -0
- angr/procedures/definitions/win32/certadm.json +69 -0
- angr/procedures/definitions/win32/certpoleng.json +39 -0
- angr/procedures/definitions/win32/cfgmgr32.json +732 -0
- angr/procedures/definitions/win32/chakra.json +270 -0
- angr/procedures/definitions/win32/cldapi.json +123 -0
- angr/procedures/definitions/win32/clfsw32.json +192 -0
- angr/procedures/definitions/win32/clusapi.json +855 -0
- angr/procedures/definitions/win32/comctl32.json +360 -0
- angr/procedures/definitions/win32/comdlg32.json +78 -0
- angr/procedures/definitions/win32/compstui.json +27 -0
- angr/procedures/definitions/win32/computecore.json +177 -0
- angr/procedures/definitions/win32/computenetwork.json +144 -0
- angr/procedures/definitions/win32/computestorage.json +51 -0
- angr/procedures/definitions/win32/comsvcs.json +36 -0
- angr/procedures/definitions/win32/credui.json +72 -0
- angr/procedures/definitions/win32/crypt32.json +702 -0
- angr/procedures/definitions/win32/cryptnet.json +30 -0
- angr/procedures/definitions/win32/cryptui.json +45 -0
- angr/procedures/definitions/win32/cryptxml.json +72 -0
- angr/procedures/definitions/win32/cscapi.json +27 -0
- angr/procedures/definitions/win32/d2d1.json +54 -0
- angr/procedures/definitions/win32/d3d10.json +96 -0
- angr/procedures/definitions/win32/d3d10_1.json +21 -0
- angr/procedures/definitions/win32/d3d11.json +24 -0
- angr/procedures/definitions/win32/d3d12.json +39 -0
- angr/procedures/definitions/win32/d3d9.json +48 -0
- angr/procedures/definitions/win32/d3dcompiler_47.json +93 -0
- angr/procedures/definitions/win32/d3dcsx.json +42 -0
- angr/procedures/definitions/win32/davclnt.json +69 -0
- angr/procedures/definitions/win32/dbgeng.json +27 -0
- angr/procedures/definitions/win32/dbghelp.json +663 -0
- angr/procedures/definitions/win32/dbgmodel.json +18 -0
- angr/procedures/definitions/win32/dciman32.json +75 -0
- angr/procedures/definitions/win32/dcomp.json +51 -0
- angr/procedures/definitions/win32/ddraw.json +36 -0
- angr/procedures/definitions/win32/deviceaccess.json +18 -0
- angr/procedures/definitions/win32/dflayout.json +18 -0
- angr/procedures/definitions/win32/dhcpcsvc.json +60 -0
- angr/procedures/definitions/win32/dhcpcsvc6.json +33 -0
- angr/procedures/definitions/win32/dhcpsapi.json +603 -0
- angr/procedures/definitions/win32/diagnosticdataquery.json +120 -0
- angr/procedures/definitions/win32/dinput8.json +18 -0
- angr/procedures/definitions/win32/directml.json +21 -0
- angr/procedures/definitions/win32/dmprocessxmlfiltered.json +18 -0
- angr/procedures/definitions/win32/dnsapi.json +207 -0
- angr/procedures/definitions/win32/drt.json +63 -0
- angr/procedures/definitions/win32/drtprov.json +42 -0
- angr/procedures/definitions/win32/drttransport.json +21 -0
- angr/procedures/definitions/win32/dsound.json +45 -0
- angr/procedures/definitions/win32/dsparse.json +72 -0
- angr/procedures/definitions/win32/dsprop.json +36 -0
- angr/procedures/definitions/win32/dssec.json +27 -0
- angr/procedures/definitions/win32/dsuiext.json +27 -0
- angr/procedures/definitions/win32/dwmapi.json +108 -0
- angr/procedures/definitions/win32/dwrite.json +18 -0
- angr/procedures/definitions/win32/dxcompiler.json +21 -0
- angr/procedures/definitions/win32/dxcore.json +18 -0
- angr/procedures/definitions/win32/dxgi.json +33 -0
- angr/procedures/definitions/win32/dxva2.json +129 -0
- angr/procedures/definitions/win32/eappcfg.json +57 -0
- angr/procedures/definitions/win32/eappprxy.json +69 -0
- angr/procedures/definitions/win32/efswrt.json +21 -0
- angr/procedures/definitions/win32/elscore.json +30 -0
- angr/procedures/definitions/win32/esent.json +702 -0
- angr/procedures/definitions/win32/evr.json +36 -0
- angr/procedures/definitions/win32/faultrep.json +27 -0
- angr/procedures/definitions/win32/fhsvcctl.json +36 -0
- angr/procedures/definitions/win32/firewallapi.json +24 -0
- angr/procedures/definitions/win32/fltlib.json +99 -0
- angr/procedures/definitions/win32/fontsub.json +21 -0
- angr/procedures/definitions/win32/forceinline.json +24 -0
- angr/procedures/definitions/win32/fwpuclnt.json +591 -0
- angr/procedures/definitions/win32/fxsutility.json +21 -0
- angr/procedures/definitions/win32/gdi32.json +1308 -0
- angr/procedures/definitions/win32/gdiplus.json +1902 -0
- angr/procedures/definitions/win32/glu32.json +171 -0
- angr/procedures/definitions/win32/gpedit.json +33 -0
- angr/procedures/definitions/win32/hhctrl_ocx.json +21 -0
- angr/procedures/definitions/win32/hid.json +150 -0
- angr/procedures/definitions/win32/hlink.json +99 -0
- angr/procedures/definitions/win32/hrtfapo.json +18 -0
- angr/procedures/definitions/win32/httpapi.json +144 -0
- angr/procedures/definitions/win32/icm32.json +78 -0
- angr/procedures/definitions/win32/icmui.json +21 -0
- angr/procedures/definitions/win32/icu.json +3090 -0
- angr/procedures/definitions/win32/ieframe.json +102 -0
- angr/procedures/definitions/win32/imagehlp.json +84 -0
- angr/procedures/definitions/win32/imgutil.json +42 -0
- angr/procedures/definitions/win32/imm32.json +261 -0
- angr/procedures/definitions/win32/infocardapi.json +66 -0
- angr/procedures/definitions/win32/inkobjcore.json +96 -0
- angr/procedures/definitions/win32/iphlpapi.json +618 -0
- angr/procedures/definitions/win32/iscsidsc.json +252 -0
- angr/procedures/definitions/win32/isolatedwindowsenvironmentutils.json +21 -0
- angr/procedures/definitions/win32/kernel32.json +4566 -0
- angr/procedures/definitions/win32/kernelbase.json +33 -0
- angr/procedures/definitions/win32/keycredmgr.json +27 -0
- angr/procedures/definitions/win32/ksproxy_ax.json +33 -0
- angr/procedures/definitions/win32/ksuser.json +39 -0
- angr/procedures/definitions/win32/ktmw32.json +132 -0
- angr/procedures/definitions/win32/licenseprotection.json +21 -0
- angr/procedures/definitions/win32/loadperf.json +51 -0
- angr/procedures/definitions/win32/magnification.json +72 -0
- angr/procedures/definitions/win32/mapi32.json +213 -0
- angr/procedures/definitions/win32/mdmlocalmanagement.json +24 -0
- angr/procedures/definitions/win32/mdmregistration.json +60 -0
- angr/procedures/definitions/win32/mf.json +201 -0
- angr/procedures/definitions/win32/mfcore.json +21 -0
- angr/procedures/definitions/win32/mfplat.json +450 -0
- angr/procedures/definitions/win32/mfplay.json +18 -0
- angr/procedures/definitions/win32/mfreadwrite.json +30 -0
- angr/procedures/definitions/win32/mfsensorgroup.json +45 -0
- angr/procedures/definitions/win32/mfsrcsnk.json +21 -0
- angr/procedures/definitions/win32/mgmtapi.json +42 -0
- angr/procedures/definitions/win32/mi.json +18 -0
- angr/procedures/definitions/win32/mmdevapi.json +18 -0
- angr/procedures/definitions/win32/mpr.json +156 -0
- angr/procedures/definitions/win32/mprapi.json +351 -0
- angr/procedures/definitions/win32/mqrt.json +117 -0
- angr/procedures/definitions/win32/mrmsupport.json +96 -0
- angr/procedures/definitions/win32/msacm32.json +141 -0
- angr/procedures/definitions/win32/msajapi.json +1656 -0
- angr/procedures/definitions/win32/mscms.json +252 -0
- angr/procedures/definitions/win32/mscoree.json +96 -0
- angr/procedures/definitions/win32/msctfmonitor.json +24 -0
- angr/procedures/definitions/win32/msdelta.json +63 -0
- angr/procedures/definitions/win32/msdmo.json +48 -0
- angr/procedures/definitions/win32/msdrm.json +267 -0
- angr/procedures/definitions/win32/msi.json +807 -0
- angr/procedures/definitions/win32/msimg32.json +24 -0
- angr/procedures/definitions/win32/mspatcha.json +63 -0
- angr/procedures/definitions/win32/mspatchc.json +42 -0
- angr/procedures/definitions/win32/msports.json +36 -0
- angr/procedures/definitions/win32/msrating.json +72 -0
- angr/procedures/definitions/win32/mssign32.json +45 -0
- angr/procedures/definitions/win32/mstask.json +21 -0
- angr/procedures/definitions/win32/msvfw32.json +144 -0
- angr/procedures/definitions/win32/mswsock.json +63 -0
- angr/procedures/definitions/win32/mtxdm.json +18 -0
- angr/procedures/definitions/win32/ncrypt.json +132 -0
- angr/procedures/definitions/win32/ndfapi.json +63 -0
- angr/procedures/definitions/win32/netapi32.json +633 -0
- angr/procedures/definitions/win32/netsh.json +39 -0
- angr/procedures/definitions/win32/netshell.json +21 -0
- angr/procedures/definitions/win32/newdev.json +48 -0
- angr/procedures/definitions/win32/ninput.json +105 -0
- angr/procedures/definitions/win32/normaliz.json +21 -0
- angr/procedures/definitions/win32/ntdll.json +234 -0
- angr/procedures/definitions/win32/ntdllk.json +18 -0
- angr/procedures/definitions/win32/ntdsapi.json +258 -0
- angr/procedures/definitions/win32/ntlanman.json +45 -0
- angr/procedures/definitions/win32/odbc32.json +477 -0
- angr/procedures/definitions/win32/odbcbcp.json +96 -0
- angr/procedures/definitions/win32/ole32.json +966 -0
- angr/procedures/definitions/win32/oleacc.json +66 -0
- angr/procedures/definitions/win32/oleaut32.json +1230 -0
- angr/procedures/definitions/win32/oledlg.json +84 -0
- angr/procedures/definitions/win32/ondemandconnroutehelper.json +30 -0
- angr/procedures/definitions/win32/opengl32.json +1080 -0
- angr/procedures/definitions/win32/opmxbox.json +24 -0
- angr/procedures/definitions/win32/p2p.json +339 -0
- angr/procedures/definitions/win32/p2pgraph.json +126 -0
- angr/procedures/definitions/win32/pdh.json +309 -0
- angr/procedures/definitions/win32/peerdist.json +99 -0
- angr/procedures/definitions/win32/powrprof.json +267 -0
- angr/procedures/definitions/win32/prntvpt.json +48 -0
- angr/procedures/definitions/win32/projectedfslib.json +72 -0
- angr/procedures/definitions/win32/propsys.json +669 -0
- angr/procedures/definitions/win32/psapi.json +96 -0
- angr/procedures/definitions/win32/quartz.json +21 -0
- angr/procedures/definitions/win32/query.json +27 -0
- angr/procedures/definitions/win32/qwave.json +48 -0
- angr/procedures/definitions/win32/rasapi32.json +267 -0
- angr/procedures/definitions/win32/rasdlg.json +33 -0
- angr/procedures/definitions/win32/resutils.json +375 -0
- angr/procedures/definitions/win32/rpcns4.json +198 -0
- angr/procedures/definitions/win32/rpcproxy.json +27 -0
- angr/procedures/definitions/win32/rpcrt4.json +1356 -0
- angr/procedures/definitions/win32/rstrtmgr.json +48 -0
- angr/procedures/definitions/win32/rtm.json +243 -0
- angr/procedures/definitions/win32/rtutils.json +138 -0
- angr/procedures/definitions/win32/rtworkq.json +114 -0
- angr/procedures/definitions/win32/sas.json +18 -0
- angr/procedures/definitions/win32/scarddlg.json +30 -0
- angr/procedures/definitions/win32/schannel.json +42 -0
- angr/procedures/definitions/win32/sechost.json +21 -0
- angr/procedures/definitions/win32/secur32.json +282 -0
- angr/procedures/definitions/win32/sensapi.json +24 -0
- angr/procedures/definitions/win32/sensorsutilsv2.json +135 -0
- angr/procedures/definitions/win32/setupapi.json +1017 -0
- angr/procedures/definitions/win32/sfc.json +33 -0
- angr/procedures/definitions/win32/shdocvw.json +24 -0
- angr/procedures/definitions/win32/shell32.json +747 -0
- angr/procedures/definitions/win32/shlwapi.json +1095 -0
- angr/procedures/definitions/win32/slc.json +111 -0
- angr/procedures/definitions/win32/slcext.json +27 -0
- angr/procedures/definitions/win32/slwga.json +18 -0
- angr/procedures/definitions/win32/snmpapi.json +93 -0
- angr/procedures/definitions/win32/spoolss.json +93 -0
- angr/procedures/definitions/win32/srclient.json +18 -0
- angr/procedures/definitions/win32/srpapi.json +48 -0
- angr/procedures/definitions/win32/sspicli.json +36 -0
- angr/procedures/definitions/win32/sti.json +18 -0
- angr/procedures/definitions/win32/t2embed.json +57 -0
- angr/procedures/definitions/win32/tapi32.json +762 -0
- angr/procedures/definitions/win32/tbs.json +57 -0
- angr/procedures/definitions/win32/tdh.json +96 -0
- angr/procedures/definitions/win32/tokenbinding.json +45 -0
- angr/procedures/definitions/win32/traffic.json +75 -0
- angr/procedures/definitions/win32/txfw32.json +42 -0
- angr/procedures/definitions/win32/ualapi.json +27 -0
- angr/procedures/definitions/win32/uiautomationcore.json +309 -0
- angr/procedures/definitions/win32/urlmon.json +246 -0
- angr/procedures/definitions/win32/user32.json +2298 -0
- angr/procedures/definitions/win32/userenv.json +147 -0
- angr/procedures/definitions/win32/usp10.json +135 -0
- angr/procedures/definitions/win32/uxtheme.json +246 -0
- angr/procedures/definitions/win32/verifier.json +18 -0
- angr/procedures/definitions/win32/version.json +57 -0
- angr/procedures/definitions/win32/vertdll.json +36 -0
- angr/procedures/definitions/win32/virtdisk.json +102 -0
- angr/procedures/definitions/win32/vmdevicehost.json +54 -0
- angr/procedures/definitions/win32/vmsavedstatedumpprovider.json +144 -0
- angr/procedures/definitions/win32/vssapi.json +18 -0
- angr/procedures/definitions/win32/wcmapi.json +30 -0
- angr/procedures/definitions/win32/wdsbp.json +36 -0
- angr/procedures/definitions/win32/wdsclientapi.json +126 -0
- angr/procedures/definitions/win32/wdsmc.json +33 -0
- angr/procedures/definitions/win32/wdspxe.json +108 -0
- angr/procedures/definitions/win32/wdstptc.json +54 -0
- angr/procedures/definitions/win32/webauthn.json +54 -0
- angr/procedures/definitions/win32/webservices.json +594 -0
- angr/procedures/definitions/win32/websocket.json +54 -0
- angr/procedures/definitions/win32/wecapi.json +60 -0
- angr/procedures/definitions/win32/wer.json +78 -0
- angr/procedures/definitions/win32/wevtapi.json +120 -0
- angr/procedures/definitions/win32/winbio.json +177 -0
- angr/procedures/definitions/win32/windows_ai_machinelearning.json +18 -0
- angr/procedures/definitions/win32/windows_media_mediacontrol.json +39 -0
- angr/procedures/definitions/win32/windows_networking.json +18 -0
- angr/procedures/definitions/win32/windows_ui_xaml.json +21 -0
- angr/procedures/definitions/win32/windowscodecs.json +42 -0
- angr/procedures/definitions/win32/winfax.json +183 -0
- angr/procedures/definitions/win32/winhttp.json +183 -0
- angr/procedures/definitions/win32/winhvemulation.json +27 -0
- angr/procedures/definitions/win32/winhvplatform.json +213 -0
- angr/procedures/definitions/win32/wininet.json +903 -0
- angr/procedures/definitions/win32/winml.json +18 -0
- angr/procedures/definitions/win32/winmm.json +543 -0
- angr/procedures/definitions/win32/winscard.json +225 -0
- angr/procedures/definitions/win32/winspool_drv.json +531 -0
- angr/procedures/definitions/win32/wintrust.json +195 -0
- angr/procedures/definitions/win32/winusb.json +117 -0
- angr/procedures/definitions/win32/wlanapi.json +195 -0
- angr/procedures/definitions/win32/wlanui.json +18 -0
- angr/procedures/definitions/win32/wldap32.json +744 -0
- angr/procedures/definitions/win32/wldp.json +42 -0
- angr/procedures/definitions/win32/wmvcore.json +48 -0
- angr/procedures/definitions/win32/wnvapi.json +21 -0
- angr/procedures/definitions/win32/wofutil.json +48 -0
- angr/procedures/definitions/win32/ws2_32.json +495 -0
- angr/procedures/definitions/win32/wscapi.json +33 -0
- angr/procedures/definitions/win32/wsclient.json +24 -0
- angr/procedures/definitions/win32/wsdapi.json +111 -0
- angr/procedures/definitions/win32/wsmsvc.json +114 -0
- angr/procedures/definitions/win32/wsnmp32.json +162 -0
- angr/procedures/definitions/win32/wtsapi32.json +204 -0
- angr/procedures/definitions/win32/xaudio2_8.json +27 -0
- angr/procedures/definitions/win32/xinput1_4.json +36 -0
- angr/procedures/definitions/win32/xmllite.json +33 -0
- angr/procedures/definitions/win32/xolehlp.json +27 -0
- angr/procedures/definitions/win32/xpsprint.json +21 -0
- angr/procedures/glibc/__ctype_b_loc.py +21 -0
- angr/procedures/glibc/__ctype_tolower_loc.py +21 -0
- angr/procedures/glibc/__ctype_toupper_loc.py +21 -0
- angr/procedures/glibc/__errno_location.py +7 -0
- angr/procedures/glibc/__init__.py +3 -0
- angr/procedures/glibc/__libc_init.py +37 -0
- angr/procedures/glibc/__libc_start_main.py +301 -0
- angr/procedures/glibc/dynamic_loading.py +20 -0
- angr/procedures/glibc/scanf.py +19 -0
- angr/procedures/glibc/sscanf.py +10 -0
- angr/procedures/gnulib/__init__.py +3 -0
- angr/procedures/gnulib/xalloc_die.py +14 -0
- angr/procedures/gnulib/xstrtol_fatal.py +14 -0
- angr/procedures/java/__init__.py +42 -0
- angr/procedures/java/unconstrained.py +65 -0
- angr/procedures/java_io/__init__.py +0 -0
- angr/procedures/java_io/read.py +12 -0
- angr/procedures/java_io/write.py +17 -0
- angr/procedures/java_jni/__init__.py +482 -0
- angr/procedures/java_jni/array_operations.py +312 -0
- angr/procedures/java_jni/class_and_interface_operations.py +31 -0
- angr/procedures/java_jni/field_access.py +173 -0
- angr/procedures/java_jni/global_and_local_refs.py +57 -0
- angr/procedures/java_jni/method_calls.py +365 -0
- angr/procedures/java_jni/not_implemented.py +26 -0
- angr/procedures/java_jni/object_operations.py +94 -0
- angr/procedures/java_jni/string_operations.py +87 -0
- angr/procedures/java_jni/version_information.py +12 -0
- angr/procedures/java_lang/__init__.py +0 -0
- angr/procedures/java_lang/character.py +30 -0
- angr/procedures/java_lang/double.py +24 -0
- angr/procedures/java_lang/exit.py +13 -0
- angr/procedures/java_lang/getsimplename.py +18 -0
- angr/procedures/java_lang/integer.py +43 -0
- angr/procedures/java_lang/load_library.py +9 -0
- angr/procedures/java_lang/math.py +15 -0
- angr/procedures/java_lang/string.py +78 -0
- angr/procedures/java_lang/stringbuilder.py +44 -0
- angr/procedures/java_lang/system.py +18 -0
- angr/procedures/java_util/__init__.py +0 -0
- angr/procedures/java_util/collection.py +35 -0
- angr/procedures/java_util/iterator.py +46 -0
- angr/procedures/java_util/list.py +99 -0
- angr/procedures/java_util/map.py +131 -0
- angr/procedures/java_util/random.py +14 -0
- angr/procedures/java_util/scanner_nextline.py +23 -0
- angr/procedures/libc/__init__.py +3 -0
- angr/procedures/libc/abort.py +9 -0
- angr/procedures/libc/access.py +13 -0
- angr/procedures/libc/atoi.py +14 -0
- angr/procedures/libc/atol.py +13 -0
- angr/procedures/libc/calloc.py +8 -0
- angr/procedures/libc/closelog.py +10 -0
- angr/procedures/libc/err.py +14 -0
- angr/procedures/libc/error.py +54 -0
- angr/procedures/libc/exit.py +11 -0
- angr/procedures/libc/fclose.py +19 -0
- angr/procedures/libc/feof.py +21 -0
- angr/procedures/libc/fflush.py +16 -0
- angr/procedures/libc/fgetc.py +27 -0
- angr/procedures/libc/fgets.py +69 -0
- angr/procedures/libc/fopen.py +63 -0
- angr/procedures/libc/fprintf.py +25 -0
- angr/procedures/libc/fputc.py +23 -0
- angr/procedures/libc/fputs.py +24 -0
- angr/procedures/libc/fread.py +24 -0
- angr/procedures/libc/free.py +9 -0
- angr/procedures/libc/fscanf.py +20 -0
- angr/procedures/libc/fseek.py +34 -0
- angr/procedures/libc/ftell.py +22 -0
- angr/procedures/libc/fwrite.py +19 -0
- angr/procedures/libc/getchar.py +13 -0
- angr/procedures/libc/getdelim.py +99 -0
- angr/procedures/libc/getegid.py +8 -0
- angr/procedures/libc/geteuid.py +8 -0
- angr/procedures/libc/getgid.py +8 -0
- angr/procedures/libc/gets.py +68 -0
- angr/procedures/libc/getuid.py +8 -0
- angr/procedures/libc/malloc.py +12 -0
- angr/procedures/libc/memcmp.py +69 -0
- angr/procedures/libc/memcpy.py +45 -0
- angr/procedures/libc/memset.py +72 -0
- angr/procedures/libc/openlog.py +10 -0
- angr/procedures/libc/perror.py +13 -0
- angr/procedures/libc/printf.py +34 -0
- angr/procedures/libc/putchar.py +13 -0
- angr/procedures/libc/puts.py +19 -0
- angr/procedures/libc/rand.py +8 -0
- angr/procedures/libc/realloc.py +8 -0
- angr/procedures/libc/rewind.py +12 -0
- angr/procedures/libc/scanf.py +20 -0
- angr/procedures/libc/setbuf.py +9 -0
- angr/procedures/libc/setvbuf.py +7 -0
- angr/procedures/libc/snprintf.py +36 -0
- angr/procedures/libc/sprintf.py +25 -0
- angr/procedures/libc/srand.py +7 -0
- angr/procedures/libc/sscanf.py +13 -0
- angr/procedures/libc/stpcpy.py +18 -0
- angr/procedures/libc/strcat.py +14 -0
- angr/procedures/libc/strchr.py +48 -0
- angr/procedures/libc/strcmp.py +31 -0
- angr/procedures/libc/strcpy.py +13 -0
- angr/procedures/libc/strlen.py +114 -0
- angr/procedures/libc/strncat.py +19 -0
- angr/procedures/libc/strncmp.py +183 -0
- angr/procedures/libc/strncpy.py +22 -0
- angr/procedures/libc/strnlen.py +13 -0
- angr/procedures/libc/strstr.py +101 -0
- angr/procedures/libc/strtol.py +261 -0
- angr/procedures/libc/strtoul.py +9 -0
- angr/procedures/libc/system.py +13 -0
- angr/procedures/libc/time.py +9 -0
- angr/procedures/libc/tmpnam.py +20 -0
- angr/procedures/libc/tolower.py +10 -0
- angr/procedures/libc/toupper.py +10 -0
- angr/procedures/libc/ungetc.py +20 -0
- angr/procedures/libc/vsnprintf.py +17 -0
- angr/procedures/libc/wchar.py +16 -0
- angr/procedures/libstdcpp/__init__.py +0 -0
- angr/procedures/libstdcpp/_unwind_resume.py +11 -0
- angr/procedures/libstdcpp/std____throw_bad_alloc.py +13 -0
- angr/procedures/libstdcpp/std____throw_bad_cast.py +13 -0
- angr/procedures/libstdcpp/std____throw_length_error.py +13 -0
- angr/procedures/libstdcpp/std____throw_logic_error.py +13 -0
- angr/procedures/libstdcpp/std__terminate.py +13 -0
- angr/procedures/linux_kernel/__init__.py +3 -0
- angr/procedures/linux_kernel/access.py +18 -0
- angr/procedures/linux_kernel/arch_prctl.py +34 -0
- angr/procedures/linux_kernel/arm_user_helpers.py +59 -0
- angr/procedures/linux_kernel/brk.py +18 -0
- angr/procedures/linux_kernel/cwd.py +28 -0
- angr/procedures/linux_kernel/fstat.py +138 -0
- angr/procedures/linux_kernel/fstat64.py +170 -0
- angr/procedures/linux_kernel/futex.py +17 -0
- angr/procedures/linux_kernel/getegid.py +17 -0
- angr/procedures/linux_kernel/geteuid.py +17 -0
- angr/procedures/linux_kernel/getgid.py +17 -0
- angr/procedures/linux_kernel/getpid.py +14 -0
- angr/procedures/linux_kernel/getrlimit.py +24 -0
- angr/procedures/linux_kernel/gettid.py +9 -0
- angr/procedures/linux_kernel/getuid.py +17 -0
- angr/procedures/linux_kernel/iovec.py +47 -0
- angr/procedures/linux_kernel/lseek.py +42 -0
- angr/procedures/linux_kernel/mmap.py +16 -0
- angr/procedures/linux_kernel/mprotect.py +42 -0
- angr/procedures/linux_kernel/munmap.py +8 -0
- angr/procedures/linux_kernel/openat.py +26 -0
- angr/procedures/linux_kernel/set_tid_address.py +8 -0
- angr/procedures/linux_kernel/sigaction.py +19 -0
- angr/procedures/linux_kernel/sigprocmask.py +23 -0
- angr/procedures/linux_kernel/stat.py +23 -0
- angr/procedures/linux_kernel/sysinfo.py +59 -0
- angr/procedures/linux_kernel/tgkill.py +10 -0
- angr/procedures/linux_kernel/time.py +34 -0
- angr/procedures/linux_kernel/uid.py +30 -0
- angr/procedures/linux_kernel/uname.py +29 -0
- angr/procedures/linux_kernel/unlink.py +22 -0
- angr/procedures/linux_kernel/vsyscall.py +16 -0
- angr/procedures/linux_loader/__init__.py +3 -0
- angr/procedures/linux_loader/_dl_initial_error_catch_tsd.py +7 -0
- angr/procedures/linux_loader/_dl_rtld_lock.py +15 -0
- angr/procedures/linux_loader/sim_loader.py +54 -0
- angr/procedures/linux_loader/tls.py +40 -0
- angr/procedures/msvcr/__getmainargs.py +16 -0
- angr/procedures/msvcr/__init__.py +4 -0
- angr/procedures/msvcr/_initterm.py +38 -0
- angr/procedures/msvcr/fmode.py +31 -0
- angr/procedures/ntdll/__init__.py +0 -0
- angr/procedures/ntdll/exceptions.py +60 -0
- angr/procedures/posix/__init__.py +3 -0
- angr/procedures/posix/accept.py +29 -0
- angr/procedures/posix/bind.py +13 -0
- angr/procedures/posix/bzero.py +9 -0
- angr/procedures/posix/chroot.py +27 -0
- angr/procedures/posix/close.py +9 -0
- angr/procedures/posix/closedir.py +7 -0
- angr/procedures/posix/dup.py +56 -0
- angr/procedures/posix/fcntl.py +10 -0
- angr/procedures/posix/fdopen.py +76 -0
- angr/procedures/posix/fileno.py +18 -0
- angr/procedures/posix/fork.py +13 -0
- angr/procedures/posix/getenv.py +35 -0
- angr/procedures/posix/gethostbyname.py +43 -0
- angr/procedures/posix/getpass.py +19 -0
- angr/procedures/posix/getsockopt.py +11 -0
- angr/procedures/posix/htonl.py +11 -0
- angr/procedures/posix/htons.py +11 -0
- angr/procedures/posix/inet_ntoa.py +59 -0
- angr/procedures/posix/listen.py +13 -0
- angr/procedures/posix/mmap.py +144 -0
- angr/procedures/posix/open.py +18 -0
- angr/procedures/posix/opendir.py +10 -0
- angr/procedures/posix/poll.py +55 -0
- angr/procedures/posix/pread64.py +46 -0
- angr/procedures/posix/pthread.py +87 -0
- angr/procedures/posix/pwrite64.py +46 -0
- angr/procedures/posix/read.py +13 -0
- angr/procedures/posix/readdir.py +62 -0
- angr/procedures/posix/recv.py +13 -0
- angr/procedures/posix/recvfrom.py +13 -0
- angr/procedures/posix/select.py +48 -0
- angr/procedures/posix/send.py +23 -0
- angr/procedures/posix/setsockopt.py +9 -0
- angr/procedures/posix/sigaction.py +23 -0
- angr/procedures/posix/sim_time.py +48 -0
- angr/procedures/posix/sleep.py +8 -0
- angr/procedures/posix/socket.py +18 -0
- angr/procedures/posix/strcasecmp.py +26 -0
- angr/procedures/posix/strdup.py +18 -0
- angr/procedures/posix/strtok_r.py +64 -0
- angr/procedures/posix/syslog.py +15 -0
- angr/procedures/posix/tz.py +9 -0
- angr/procedures/posix/unlink.py +11 -0
- angr/procedures/posix/usleep.py +8 -0
- angr/procedures/posix/write.py +13 -0
- angr/procedures/procedure_dict.py +50 -0
- angr/procedures/stubs/CallReturn.py +13 -0
- angr/procedures/stubs/NoReturnUnconstrained.py +13 -0
- angr/procedures/stubs/Nop.py +7 -0
- angr/procedures/stubs/PathTerminator.py +9 -0
- angr/procedures/stubs/Redirect.py +18 -0
- angr/procedures/stubs/ReturnChar.py +11 -0
- angr/procedures/stubs/ReturnUnconstrained.py +24 -0
- angr/procedures/stubs/UnresolvableCallTarget.py +9 -0
- angr/procedures/stubs/UnresolvableJumpTarget.py +9 -0
- angr/procedures/stubs/UserHook.py +18 -0
- angr/procedures/stubs/__init__.py +3 -0
- angr/procedures/stubs/b64_decode.py +15 -0
- angr/procedures/stubs/caller.py +14 -0
- angr/procedures/stubs/crazy_scanf.py +20 -0
- angr/procedures/stubs/format_parser.py +669 -0
- angr/procedures/stubs/syscall_stub.py +24 -0
- angr/procedures/testing/__init__.py +3 -0
- angr/procedures/testing/manyargs.py +9 -0
- angr/procedures/testing/retreg.py +8 -0
- angr/procedures/tracer/__init__.py +4 -0
- angr/procedures/tracer/random.py +9 -0
- angr/procedures/tracer/receive.py +23 -0
- angr/procedures/tracer/transmit.py +26 -0
- angr/procedures/uclibc/__init__.py +3 -0
- angr/procedures/uclibc/__uClibc_main.py +10 -0
- angr/procedures/win32/EncodePointer.py +7 -0
- angr/procedures/win32/ExitProcess.py +9 -0
- angr/procedures/win32/GetCommandLine.py +12 -0
- angr/procedures/win32/GetCurrentProcessId.py +7 -0
- angr/procedures/win32/GetCurrentThreadId.py +7 -0
- angr/procedures/win32/GetLastInputInfo.py +40 -0
- angr/procedures/win32/GetModuleHandle.py +29 -0
- angr/procedures/win32/GetProcessAffinityMask.py +37 -0
- angr/procedures/win32/InterlockedExchange.py +15 -0
- angr/procedures/win32/IsProcessorFeaturePresent.py +7 -0
- angr/procedures/win32/VirtualAlloc.py +114 -0
- angr/procedures/win32/VirtualProtect.py +60 -0
- angr/procedures/win32/__init__.py +3 -0
- angr/procedures/win32/critical_section.py +12 -0
- angr/procedures/win32/dynamic_loading.py +104 -0
- angr/procedures/win32/file_handles.py +47 -0
- angr/procedures/win32/gethostbyname.py +12 -0
- angr/procedures/win32/heap.py +45 -0
- angr/procedures/win32/is_bad_ptr.py +26 -0
- angr/procedures/win32/local_storage.py +88 -0
- angr/procedures/win32/mutex.py +11 -0
- angr/procedures/win32/sim_time.py +135 -0
- angr/procedures/win32/system_paths.py +35 -0
- angr/procedures/win32_kernel/ExAllocatePool.py +13 -0
- angr/procedures/win32_kernel/ExFreePoolWithTag.py +8 -0
- angr/procedures/win32_kernel/__fastfail.py +15 -0
- angr/procedures/win32_kernel/__init__.py +3 -0
- angr/procedures/win_user32/__init__.py +0 -0
- angr/procedures/win_user32/chars.py +15 -0
- angr/procedures/win_user32/keyboard.py +14 -0
- angr/procedures/win_user32/messagebox.py +49 -0
- angr/project.py +860 -0
- angr/protos/__init__.py +19 -0
- angr/protos/cfg_pb2.py +42 -0
- angr/protos/function_pb2.py +38 -0
- angr/protos/primitives_pb2.py +59 -0
- angr/protos/variables_pb2.py +55 -0
- angr/protos/xrefs_pb2.py +36 -0
- angr/py.typed +1 -0
- angr/rustylib.cpython-311-darwin.so +0 -0
- angr/serializable.py +66 -0
- angr/sim_manager.py +971 -0
- angr/sim_options.py +436 -0
- angr/sim_procedure.py +626 -0
- angr/sim_state.py +926 -0
- angr/sim_state_options.py +403 -0
- angr/sim_type.py +4026 -0
- angr/sim_variable.py +470 -0
- angr/simos/__init__.py +47 -0
- angr/simos/cgc.py +153 -0
- angr/simos/javavm.py +458 -0
- angr/simos/linux.py +509 -0
- angr/simos/simos.py +444 -0
- angr/simos/snimmuc_nxp.py +149 -0
- angr/simos/userland.py +163 -0
- angr/simos/windows.py +615 -0
- angr/simos/xbox.py +32 -0
- angr/slicer.py +352 -0
- angr/state_hierarchy.py +262 -0
- angr/state_plugins/__init__.py +84 -0
- angr/state_plugins/callstack.py +478 -0
- angr/state_plugins/cgc.py +155 -0
- angr/state_plugins/debug_variables.py +192 -0
- angr/state_plugins/filesystem.py +463 -0
- angr/state_plugins/gdb.py +148 -0
- angr/state_plugins/globals.py +65 -0
- angr/state_plugins/heap/__init__.py +15 -0
- angr/state_plugins/heap/heap_base.py +128 -0
- angr/state_plugins/heap/heap_brk.py +136 -0
- angr/state_plugins/heap/heap_freelist.py +213 -0
- angr/state_plugins/heap/heap_libc.py +46 -0
- angr/state_plugins/heap/heap_ptmalloc.py +620 -0
- angr/state_plugins/heap/utils.py +22 -0
- angr/state_plugins/history.py +564 -0
- angr/state_plugins/inspect.py +375 -0
- angr/state_plugins/javavm_classloader.py +134 -0
- angr/state_plugins/jni_references.py +95 -0
- angr/state_plugins/libc.py +1263 -0
- angr/state_plugins/light_registers.py +168 -0
- angr/state_plugins/log.py +84 -0
- angr/state_plugins/loop_data.py +92 -0
- angr/state_plugins/plugin.py +176 -0
- angr/state_plugins/posix.py +703 -0
- angr/state_plugins/preconstrainer.py +196 -0
- angr/state_plugins/scratch.py +173 -0
- angr/state_plugins/sim_action.py +326 -0
- angr/state_plugins/sim_action_object.py +271 -0
- angr/state_plugins/sim_event.py +59 -0
- angr/state_plugins/solver.py +1128 -0
- angr/state_plugins/symbolizer.py +291 -0
- angr/state_plugins/trace_additions.py +738 -0
- angr/state_plugins/uc_manager.py +94 -0
- angr/state_plugins/unicorn_engine.py +1920 -0
- angr/state_plugins/view.py +340 -0
- angr/storage/__init__.py +15 -0
- angr/storage/file.py +1210 -0
- angr/storage/memory_mixins/__init__.py +317 -0
- angr/storage/memory_mixins/actions_mixin.py +72 -0
- angr/storage/memory_mixins/address_concretization_mixin.py +384 -0
- angr/storage/memory_mixins/bvv_conversion_mixin.py +73 -0
- angr/storage/memory_mixins/clouseau_mixin.py +137 -0
- angr/storage/memory_mixins/conditional_store_mixin.py +25 -0
- angr/storage/memory_mixins/convenient_mappings_mixin.py +256 -0
- angr/storage/memory_mixins/default_filler_mixin.py +144 -0
- angr/storage/memory_mixins/dirty_addrs_mixin.py +11 -0
- angr/storage/memory_mixins/hex_dumper_mixin.py +82 -0
- angr/storage/memory_mixins/javavm_memory_mixin.py +392 -0
- angr/storage/memory_mixins/keyvalue_memory_mixin.py +43 -0
- angr/storage/memory_mixins/label_merger_mixin.py +31 -0
- angr/storage/memory_mixins/memory_mixin.py +175 -0
- angr/storage/memory_mixins/multi_value_merger_mixin.py +79 -0
- angr/storage/memory_mixins/name_resolution_mixin.py +67 -0
- angr/storage/memory_mixins/paged_memory/__init__.py +0 -0
- angr/storage/memory_mixins/paged_memory/page_backer_mixins.py +266 -0
- angr/storage/memory_mixins/paged_memory/paged_memory_mixin.py +743 -0
- angr/storage/memory_mixins/paged_memory/paged_memory_multivalue_mixin.py +65 -0
- angr/storage/memory_mixins/paged_memory/pages/__init__.py +26 -0
- angr/storage/memory_mixins/paged_memory/pages/base.py +31 -0
- angr/storage/memory_mixins/paged_memory/pages/cooperation.py +341 -0
- angr/storage/memory_mixins/paged_memory/pages/history_tracking_mixin.py +92 -0
- angr/storage/memory_mixins/paged_memory/pages/ispo_mixin.py +55 -0
- angr/storage/memory_mixins/paged_memory/pages/list_page.py +338 -0
- angr/storage/memory_mixins/paged_memory/pages/multi_values.py +324 -0
- angr/storage/memory_mixins/paged_memory/pages/mv_list_page.py +419 -0
- angr/storage/memory_mixins/paged_memory/pages/permissions_mixin.py +36 -0
- angr/storage/memory_mixins/paged_memory/pages/refcount_mixin.py +52 -0
- angr/storage/memory_mixins/paged_memory/pages/ultra_page.py +529 -0
- angr/storage/memory_mixins/paged_memory/privileged_mixin.py +36 -0
- angr/storage/memory_mixins/paged_memory/stack_allocation_mixin.py +74 -0
- angr/storage/memory_mixins/regioned_memory/__init__.py +17 -0
- angr/storage/memory_mixins/regioned_memory/abstract_address_descriptor.py +36 -0
- angr/storage/memory_mixins/regioned_memory/abstract_merger_mixin.py +31 -0
- angr/storage/memory_mixins/regioned_memory/region_category_mixin.py +9 -0
- angr/storage/memory_mixins/regioned_memory/region_data.py +246 -0
- angr/storage/memory_mixins/regioned_memory/region_meta_mixin.py +241 -0
- angr/storage/memory_mixins/regioned_memory/regioned_address_concretization_mixin.py +119 -0
- angr/storage/memory_mixins/regioned_memory/regioned_memory_mixin.py +442 -0
- angr/storage/memory_mixins/regioned_memory/static_find_mixin.py +69 -0
- angr/storage/memory_mixins/simple_interface_mixin.py +71 -0
- angr/storage/memory_mixins/simplification_mixin.py +15 -0
- angr/storage/memory_mixins/size_resolution_mixin.py +143 -0
- angr/storage/memory_mixins/slotted_memory.py +140 -0
- angr/storage/memory_mixins/smart_find_mixin.py +161 -0
- angr/storage/memory_mixins/symbolic_merger_mixin.py +16 -0
- angr/storage/memory_mixins/top_merger_mixin.py +25 -0
- angr/storage/memory_mixins/underconstrained_mixin.py +67 -0
- angr/storage/memory_mixins/unwrapper_mixin.py +26 -0
- angr/storage/memory_object.py +195 -0
- angr/tablespecs.py +91 -0
- angr/unicornlib.dylib +0 -0
- angr/utils/__init__.py +46 -0
- angr/utils/ail.py +176 -0
- angr/utils/algo.py +34 -0
- angr/utils/balancer.py +776 -0
- angr/utils/bits.py +46 -0
- angr/utils/constants.py +9 -0
- angr/utils/cowdict.py +63 -0
- angr/utils/cpp.py +17 -0
- angr/utils/doms.py +150 -0
- angr/utils/dynamic_dictlist.py +89 -0
- angr/utils/endness.py +18 -0
- angr/utils/enums_conv.py +97 -0
- angr/utils/env.py +12 -0
- angr/utils/formatting.py +128 -0
- angr/utils/funcid.py +244 -0
- angr/utils/graph.py +981 -0
- angr/utils/lazy_import.py +13 -0
- angr/utils/library.py +236 -0
- angr/utils/loader.py +55 -0
- angr/utils/mp.py +66 -0
- angr/utils/orderedset.py +74 -0
- angr/utils/ssa/__init__.py +455 -0
- angr/utils/ssa/tmp_uses_collector.py +23 -0
- angr/utils/ssa/vvar_uses_collector.py +36 -0
- angr/utils/strings.py +20 -0
- angr/utils/tagged_interval_map.py +112 -0
- angr/utils/timing.py +74 -0
- angr/utils/types.py +193 -0
- angr/utils/vex.py +11 -0
- angr/vaults.py +367 -0
- angr-9.2.192.dist-info/METADATA +112 -0
- angr-9.2.192.dist-info/RECORD +1442 -0
- angr-9.2.192.dist-info/WHEEL +6 -0
- angr-9.2.192.dist-info/entry_points.txt +2 -0
- angr-9.2.192.dist-info/licenses/LICENSE +27 -0
- angr-9.2.192.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,1319 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
from typing import Any, Literal, TypeAlias, cast, overload, TypeVar
|
|
3
|
+
from collections.abc import Iterable
|
|
4
|
+
from itertools import count
|
|
5
|
+
from collections import defaultdict
|
|
6
|
+
import logging
|
|
7
|
+
|
|
8
|
+
import networkx
|
|
9
|
+
|
|
10
|
+
from angr import ailment
|
|
11
|
+
from angr.ailment import Block
|
|
12
|
+
from angr.ailment.statement import ConditionalJump, Jump
|
|
13
|
+
from angr.ailment.expression import Const
|
|
14
|
+
from angr.knowledge_plugins.functions.function import Function
|
|
15
|
+
from angr.utils.graph import GraphUtils
|
|
16
|
+
from angr.utils.graph import dfs_back_edges, subgraph_between_nodes, dominates
|
|
17
|
+
from angr.utils.doms import IncrementalDominators
|
|
18
|
+
from angr.errors import AngrRuntimeError
|
|
19
|
+
from angr.analyses import Analysis, register_analysis
|
|
20
|
+
from .structuring.structurer_nodes import MultiNode, ConditionNode, IncompleteSwitchCaseHeadStatement
|
|
21
|
+
from .graph_region import GraphRegion
|
|
22
|
+
from .condition_processor import ConditionProcessor
|
|
23
|
+
from .utils import replace_last_statement, first_nonlabel_nonphi_statement, copy_graph
|
|
24
|
+
|
|
25
|
+
l = logging.getLogger(name=__name__)
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
# an ever-incrementing counter
|
|
29
|
+
CONDITIONNODE_ADDR = count(0xFF000000)
|
|
30
|
+
|
|
31
|
+
TNode: TypeAlias = Block | GraphRegion | MultiNode | ConditionNode
|
|
32
|
+
TGraph: TypeAlias = "networkx.DiGraph[TNode]"
|
|
33
|
+
T = TypeVar("T")
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
class RegionIdentifier(Analysis):
|
|
37
|
+
"""
|
|
38
|
+
A region is a single-entry-single-exit subgraph of control flow. The region identifier recursively identifies the
|
|
39
|
+
smallest possible regions within a function graph and creates a GraphRegion object whose nodes are either Blocks
|
|
40
|
+
or GraphRegions.
|
|
41
|
+
|
|
42
|
+
Note, that the analysis may modify the graph in-place. If you want to keep the original graph,
|
|
43
|
+
set the `update_graph` parameter to False.
|
|
44
|
+
"""
|
|
45
|
+
|
|
46
|
+
def __init__(
|
|
47
|
+
self,
|
|
48
|
+
func: Function,
|
|
49
|
+
cond_proc: ConditionProcessor | None = None,
|
|
50
|
+
graph: networkx.DiGraph[Block] | None = None,
|
|
51
|
+
update_graph=True,
|
|
52
|
+
largest_successor_tree_outside_loop=True,
|
|
53
|
+
force_loop_single_exit=True,
|
|
54
|
+
refine_loops_with_single_successor=False,
|
|
55
|
+
complete_successors=False,
|
|
56
|
+
entry_node_addr: tuple[int, int | None] | None = None,
|
|
57
|
+
):
|
|
58
|
+
self.function = func
|
|
59
|
+
self.entry_node_addr: tuple[int, int | None] | None = (
|
|
60
|
+
entry_node_addr if entry_node_addr is not None else (func.addr, None) if func is not None else None
|
|
61
|
+
)
|
|
62
|
+
self.cond_proc = (
|
|
63
|
+
cond_proc
|
|
64
|
+
if cond_proc is not None
|
|
65
|
+
else ConditionProcessor(
|
|
66
|
+
self.project.arch
|
|
67
|
+
if getattr(self, "project", None) is not None
|
|
68
|
+
else None # it's only None in test cases
|
|
69
|
+
)
|
|
70
|
+
)
|
|
71
|
+
|
|
72
|
+
graph = graph if graph is not None else self.project.analyses.Clinic(func).graph
|
|
73
|
+
assert graph is not None
|
|
74
|
+
if not update_graph:
|
|
75
|
+
# copy the graph so updates don't affect the original graph
|
|
76
|
+
graph = copy_graph(graph) # type: ignore
|
|
77
|
+
|
|
78
|
+
self.region = None
|
|
79
|
+
self._start_node = None
|
|
80
|
+
self._loop_headers: list | None = None
|
|
81
|
+
self.regions_by_block_addrs = []
|
|
82
|
+
self._largest_successor_tree_outside_loop = largest_successor_tree_outside_loop
|
|
83
|
+
self._force_loop_single_exit = force_loop_single_exit
|
|
84
|
+
self._refine_loops_with_single_successor = refine_loops_with_single_successor
|
|
85
|
+
self._complete_successors = complete_successors
|
|
86
|
+
# we keep a dictionary of node and their traversal order in a quasi-topological traversal and update this
|
|
87
|
+
# dictionary as we update the graph
|
|
88
|
+
self._node_order: dict[Any, tuple[int, int]] = {}
|
|
89
|
+
|
|
90
|
+
self._graph = self._analyze(graph)
|
|
91
|
+
|
|
92
|
+
@staticmethod
|
|
93
|
+
def slice_graph(graph, node, frontier, include_frontier=False) -> TGraph:
|
|
94
|
+
"""
|
|
95
|
+
Generate a slice of the graph from the head node to the given frontier.
|
|
96
|
+
|
|
97
|
+
:param networkx.DiGraph graph: The graph to work on.
|
|
98
|
+
:param node: The starting node in the graph.
|
|
99
|
+
:param frontier: A list of frontier nodes.
|
|
100
|
+
:param bool include_frontier: Whether the frontier nodes are included in the slice or not.
|
|
101
|
+
:return: A subgraph.
|
|
102
|
+
:rtype: networkx.DiGraph
|
|
103
|
+
"""
|
|
104
|
+
|
|
105
|
+
subgraph = subgraph_between_nodes(graph, node, frontier, include_frontier=include_frontier)
|
|
106
|
+
# HACK: FIXME: for infinite loop nodes, this would return an empty set, so we include the loop body itself
|
|
107
|
+
# Make sure this makes sense (EDG thinks it does)
|
|
108
|
+
if not list(subgraph.nodes) and (node, node) in graph.edges:
|
|
109
|
+
subgraph.add_edge(node, node)
|
|
110
|
+
return subgraph
|
|
111
|
+
|
|
112
|
+
def _analyze(self, block_graph: networkx.DiGraph[Block]) -> TGraph:
|
|
113
|
+
graph = cast(TGraph, self._pick_one_connected_component(block_graph, as_copy=True))
|
|
114
|
+
|
|
115
|
+
# preprocess: make it a super graph
|
|
116
|
+
self._make_supergraph(graph)
|
|
117
|
+
|
|
118
|
+
self._start_node = self._get_start_node(graph)
|
|
119
|
+
self._node_order = self._compute_node_order(graph)
|
|
120
|
+
self.region = self._make_regions(graph)
|
|
121
|
+
|
|
122
|
+
# make regions into block address lists
|
|
123
|
+
self.regions_by_block_addrs = self._make_regions_by_block_addrs()
|
|
124
|
+
return graph
|
|
125
|
+
|
|
126
|
+
def _pick_one_connected_component(
|
|
127
|
+
self, digraph: networkx.DiGraph[Block], as_copy: bool = False
|
|
128
|
+
) -> networkx.DiGraph[Block]:
|
|
129
|
+
g = networkx.Graph(digraph)
|
|
130
|
+
components: list[list[Block]] = list(networkx.connected_components(g))
|
|
131
|
+
if len(components) <= 1:
|
|
132
|
+
return networkx.DiGraph(digraph) if as_copy else digraph
|
|
133
|
+
|
|
134
|
+
the_component = None
|
|
135
|
+
largest_component = None
|
|
136
|
+
for component in components:
|
|
137
|
+
if largest_component is None or len(component) > len(largest_component):
|
|
138
|
+
largest_component = component
|
|
139
|
+
if any((block.addr, block.idx) == self.entry_node_addr for block in component):
|
|
140
|
+
the_component = component
|
|
141
|
+
break
|
|
142
|
+
|
|
143
|
+
if the_component is None:
|
|
144
|
+
the_component = largest_component
|
|
145
|
+
|
|
146
|
+
assert the_component is not None
|
|
147
|
+
return digraph.subgraph(the_component).to_directed()
|
|
148
|
+
|
|
149
|
+
@staticmethod
|
|
150
|
+
def _compute_node_order(graph: TGraph) -> dict[TNode, tuple[int, int]]:
|
|
151
|
+
sorted_nodes = GraphUtils.quasi_topological_sort_nodes(graph)
|
|
152
|
+
node_order = {}
|
|
153
|
+
for i, n in enumerate(sorted_nodes):
|
|
154
|
+
node_order[n] = i, 0
|
|
155
|
+
return node_order
|
|
156
|
+
|
|
157
|
+
def _sort_nodes(self, nodes: Iterable[TNode]) -> list[TNode]:
|
|
158
|
+
"""
|
|
159
|
+
Sorts the nodes in the order specified in self._node_order.
|
|
160
|
+
|
|
161
|
+
:param nodes: A list or set of nodes to be sorted.
|
|
162
|
+
:return: A sorted list of nodes.
|
|
163
|
+
"""
|
|
164
|
+
return sorted(nodes, key=lambda n: self._node_order[n])
|
|
165
|
+
|
|
166
|
+
def _make_regions_by_block_addrs(self) -> list[list[tuple[int, int | None]]]:
|
|
167
|
+
"""
|
|
168
|
+
Creates a list of addr lists representing each region without recursion. A single region is defined
|
|
169
|
+
as a set of only blocks, no Graphs containing nested regions. The list contains the address of each
|
|
170
|
+
block in the region, including the heads of each recursive region.
|
|
171
|
+
|
|
172
|
+
:return: List of addr lists
|
|
173
|
+
"""
|
|
174
|
+
|
|
175
|
+
assert self.region is not None
|
|
176
|
+
work_list = [self.region]
|
|
177
|
+
block_only_regions = []
|
|
178
|
+
seen_regions = set()
|
|
179
|
+
while work_list:
|
|
180
|
+
children_regions: list[GraphRegion] = []
|
|
181
|
+
for region in work_list:
|
|
182
|
+
children_blocks = []
|
|
183
|
+
assert region.graph is not None
|
|
184
|
+
for node in region.graph.nodes:
|
|
185
|
+
if isinstance(node, Block):
|
|
186
|
+
children_blocks.append((node.addr, node.idx))
|
|
187
|
+
elif isinstance(node, MultiNode):
|
|
188
|
+
children_blocks += [(n.addr, node.idx) for n in node.nodes]
|
|
189
|
+
elif isinstance(node, GraphRegion):
|
|
190
|
+
if node not in seen_regions:
|
|
191
|
+
children_regions.append(node)
|
|
192
|
+
children_blocks.append(
|
|
193
|
+
(node.head.addr, node.head.idx if hasattr(node.head, "idx") else None)
|
|
194
|
+
)
|
|
195
|
+
seen_regions.add(node)
|
|
196
|
+
else:
|
|
197
|
+
continue
|
|
198
|
+
|
|
199
|
+
if children_blocks:
|
|
200
|
+
block_only_regions.append(children_blocks)
|
|
201
|
+
|
|
202
|
+
work_list = children_regions
|
|
203
|
+
|
|
204
|
+
return block_only_regions
|
|
205
|
+
|
|
206
|
+
def _get_start_node(self, graph: TGraph):
|
|
207
|
+
try:
|
|
208
|
+
return next(n for n in graph.nodes() if graph.in_degree(n) == 0)
|
|
209
|
+
except StopIteration:
|
|
210
|
+
pass
|
|
211
|
+
|
|
212
|
+
if self.entry_node_addr is not None:
|
|
213
|
+
try:
|
|
214
|
+
return next(
|
|
215
|
+
n
|
|
216
|
+
for n in graph.nodes()
|
|
217
|
+
if (
|
|
218
|
+
(n.addr, n.idx) == self.entry_node_addr
|
|
219
|
+
if isinstance(n, Block)
|
|
220
|
+
else n.addr == self.entry_node_addr[0]
|
|
221
|
+
)
|
|
222
|
+
)
|
|
223
|
+
except StopIteration as ex:
|
|
224
|
+
raise AngrRuntimeError("Cannot find the start node from the graph!") from ex
|
|
225
|
+
raise AngrRuntimeError("Cannot find the start node from the graph!")
|
|
226
|
+
|
|
227
|
+
def _get_entry_node(self, graph: TGraph):
|
|
228
|
+
if self.entry_node_addr is None:
|
|
229
|
+
return None
|
|
230
|
+
return next(
|
|
231
|
+
(
|
|
232
|
+
n
|
|
233
|
+
for n in graph.nodes()
|
|
234
|
+
if (
|
|
235
|
+
(n.addr, n.idx) == self.entry_node_addr
|
|
236
|
+
if isinstance(n, Block)
|
|
237
|
+
else n.addr == self.entry_node_addr[0]
|
|
238
|
+
)
|
|
239
|
+
),
|
|
240
|
+
None,
|
|
241
|
+
)
|
|
242
|
+
|
|
243
|
+
def _make_supergraph(self, graph: TGraph):
|
|
244
|
+
|
|
245
|
+
entry_node = None
|
|
246
|
+
if self.entry_node_addr is not None:
|
|
247
|
+
entry_node = next(iter(nn for nn in graph if nn.addr == self.entry_node_addr[0]), None)
|
|
248
|
+
|
|
249
|
+
while True:
|
|
250
|
+
for src, dst, data in graph.edges(data=True):
|
|
251
|
+
if entry_node is not None and dst is entry_node:
|
|
252
|
+
# the entry node must be kept instead of merged with its predecessor (which can happen in real
|
|
253
|
+
# binaries! e.g., 444a401b900eb825f216e95111dcb6ef94b01a81fc7b88a48599867db8c50365, function
|
|
254
|
+
# 0x1802BEA28, block 0x1802BEA05 and 0x1802BEA28)
|
|
255
|
+
continue
|
|
256
|
+
|
|
257
|
+
type_ = data.get("type", None)
|
|
258
|
+
if type_ == "fake_return":
|
|
259
|
+
if len(list(graph.successors(src))) == 1 and len(list(graph.predecessors(dst))) == 1:
|
|
260
|
+
merged_node = self._merge_nodes(graph, src, dst, force_multinode=True)
|
|
261
|
+
# update the entry_node if necessary
|
|
262
|
+
if entry_node is not None and entry_node is src:
|
|
263
|
+
entry_node = merged_node
|
|
264
|
+
break
|
|
265
|
+
elif type_ == "call":
|
|
266
|
+
graph.remove_node(dst)
|
|
267
|
+
break
|
|
268
|
+
else:
|
|
269
|
+
break
|
|
270
|
+
|
|
271
|
+
def _find_loop_headers(self, graph: TGraph) -> list[TNode]:
|
|
272
|
+
assert self._start_node is not None
|
|
273
|
+
heads = list({t for _, t in dfs_back_edges(graph, self._start_node)})
|
|
274
|
+
return self._sort_nodes(heads)
|
|
275
|
+
|
|
276
|
+
def _find_initial_loop_nodes(self, graph: TGraph, head: TNode) -> set[TNode]:
|
|
277
|
+
assert self._start_node is not None
|
|
278
|
+
# TODO optimize
|
|
279
|
+
latching_nodes = {s for s, t in dfs_back_edges(graph, self._start_node) if t == head}
|
|
280
|
+
loop_subgraph = self.slice_graph(graph, head, latching_nodes, include_frontier=True)
|
|
281
|
+
|
|
282
|
+
# special case: any node with more than two non-self successors are probably the head of a switch-case. we
|
|
283
|
+
# should include all successors into the loop subgraph.
|
|
284
|
+
# we must be extra careful here to not include nodes that are reachable from outside the loop subgraph. an
|
|
285
|
+
# example is in binary 064e1d62c8542d658d83f7e231cc3b935a1f18153b8aea809dcccfd446a91c93, loop 0x40d7b0 should
|
|
286
|
+
# not include block 0x40d9d5 because this node has a out-of-loop-body predecessor (block 0x40d795).
|
|
287
|
+
while True:
|
|
288
|
+
updated = False
|
|
289
|
+
for node in list(loop_subgraph):
|
|
290
|
+
nonself_successors = [succ for succ in graph.successors(node) if succ is not node]
|
|
291
|
+
if len(nonself_successors) > 2:
|
|
292
|
+
for succ in nonself_successors:
|
|
293
|
+
if not loop_subgraph.has_edge(node, succ) and all(
|
|
294
|
+
pred in loop_subgraph for pred in graph.predecessors(succ)
|
|
295
|
+
):
|
|
296
|
+
updated = True
|
|
297
|
+
loop_subgraph.add_edge(node, succ)
|
|
298
|
+
if not updated:
|
|
299
|
+
break
|
|
300
|
+
|
|
301
|
+
return set(loop_subgraph)
|
|
302
|
+
|
|
303
|
+
def _refine_loop(
|
|
304
|
+
self, graph: TGraph, head: TNode, initial_loop_nodes: set[TNode], initial_exit_nodes: set[TNode]
|
|
305
|
+
) -> tuple[set[TNode], set[TNode]]:
|
|
306
|
+
if (self._refine_loops_with_single_successor and len(initial_exit_nodes) == 0) or (
|
|
307
|
+
not self._refine_loops_with_single_successor and len(initial_exit_nodes) <= 1
|
|
308
|
+
):
|
|
309
|
+
return initial_loop_nodes, initial_exit_nodes
|
|
310
|
+
|
|
311
|
+
refined_loop_nodes = initial_loop_nodes.copy()
|
|
312
|
+
refined_exit_nodes = initial_exit_nodes.copy()
|
|
313
|
+
|
|
314
|
+
# simple optimization: include all single-in-degree successors of existing loop nodes
|
|
315
|
+
while True:
|
|
316
|
+
added = set()
|
|
317
|
+
for exit_node in list(refined_exit_nodes):
|
|
318
|
+
if graph.in_degree[exit_node] == 1 and graph.out_degree[exit_node] <= 1:
|
|
319
|
+
added.add(exit_node)
|
|
320
|
+
refined_loop_nodes.add(exit_node)
|
|
321
|
+
refined_exit_nodes |= {
|
|
322
|
+
succ for succ in graph.successors(exit_node) if succ not in refined_loop_nodes
|
|
323
|
+
}
|
|
324
|
+
refined_exit_nodes.remove(exit_node)
|
|
325
|
+
if not added:
|
|
326
|
+
break
|
|
327
|
+
|
|
328
|
+
if len(refined_exit_nodes) <= 1:
|
|
329
|
+
return refined_loop_nodes, refined_exit_nodes
|
|
330
|
+
|
|
331
|
+
idom = networkx.immediate_dominators(graph, head)
|
|
332
|
+
|
|
333
|
+
new_exit_nodes = refined_exit_nodes
|
|
334
|
+
# a graph with only initial exit nodes and new loop nodes that are reachable from at least one initial exit
|
|
335
|
+
# node.
|
|
336
|
+
subgraph = networkx.DiGraph()
|
|
337
|
+
|
|
338
|
+
sorted_refined_exit_nodes = self._sort_nodes(refined_exit_nodes)
|
|
339
|
+
while len(sorted_refined_exit_nodes) > 1 and new_exit_nodes:
|
|
340
|
+
# visit each node in refined_exit_nodes once and determine which nodes to consider as loop nodes
|
|
341
|
+
candidate_nodes = {}
|
|
342
|
+
for n in list(sorted_refined_exit_nodes):
|
|
343
|
+
if all((pred is n or pred in refined_loop_nodes) for pred in graph.predecessors(n)) and dominates(
|
|
344
|
+
idom, head, n
|
|
345
|
+
):
|
|
346
|
+
to_add = set(graph.successors(n)) - refined_loop_nodes
|
|
347
|
+
candidate_nodes[n] = to_add
|
|
348
|
+
|
|
349
|
+
# visit all candidate nodes and only consider candidates that will not be added as exit nodes
|
|
350
|
+
all_new_exit_candidates = set()
|
|
351
|
+
for new_exit_candidates in candidate_nodes.values():
|
|
352
|
+
all_new_exit_candidates |= new_exit_candidates
|
|
353
|
+
|
|
354
|
+
# to guarantee progressing, we must ensure all_new_exit_candidates cannot contain all candidate nodes
|
|
355
|
+
if all(n in all_new_exit_candidates for n in candidate_nodes):
|
|
356
|
+
all_new_exit_candidates = set()
|
|
357
|
+
|
|
358
|
+
# do the actual work
|
|
359
|
+
new_exit_nodes = set()
|
|
360
|
+
for n in candidate_nodes:
|
|
361
|
+
if n in all_new_exit_candidates:
|
|
362
|
+
continue
|
|
363
|
+
refined_loop_nodes.add(n)
|
|
364
|
+
sorted_refined_exit_nodes.remove(n)
|
|
365
|
+
to_add = set(graph.successors(n)) - refined_loop_nodes
|
|
366
|
+
new_exit_nodes |= to_add
|
|
367
|
+
for succ in to_add:
|
|
368
|
+
subgraph.add_edge(n, succ)
|
|
369
|
+
|
|
370
|
+
sorted_refined_exit_nodes += list(new_exit_nodes)
|
|
371
|
+
sorted_refined_exit_nodes = list(set(sorted_refined_exit_nodes))
|
|
372
|
+
sorted_refined_exit_nodes = self._sort_nodes(sorted_refined_exit_nodes)
|
|
373
|
+
|
|
374
|
+
refined_exit_nodes = set(sorted_refined_exit_nodes)
|
|
375
|
+
refined_loop_nodes = refined_loop_nodes - refined_exit_nodes
|
|
376
|
+
|
|
377
|
+
if self._largest_successor_tree_outside_loop and not refined_exit_nodes:
|
|
378
|
+
# figure out the new successor tree with the highest number of nodes
|
|
379
|
+
initial_exit_to_newnodes = defaultdict(set)
|
|
380
|
+
newnode_to_initial_exits = defaultdict(set)
|
|
381
|
+
for initial_exit in initial_exit_nodes:
|
|
382
|
+
if initial_exit in subgraph:
|
|
383
|
+
for _, succs in networkx.bfs_successors(subgraph, initial_exit):
|
|
384
|
+
initial_exit_to_newnodes[initial_exit] |= set(succs)
|
|
385
|
+
for succ in succs:
|
|
386
|
+
newnode_to_initial_exits[succ].add(initial_exit)
|
|
387
|
+
|
|
388
|
+
for newnode, exits in newnode_to_initial_exits.items():
|
|
389
|
+
for exit_ in exits:
|
|
390
|
+
initial_exit_to_newnodes[exit_].add(newnode)
|
|
391
|
+
|
|
392
|
+
# filter initial_exit_to_newnodes and remove the subtrees with nodes that are reachable from nodes that are
|
|
393
|
+
# outside the current subtree
|
|
394
|
+
for initial_exit, subtree in list(initial_exit_to_newnodes.items()):
|
|
395
|
+
subtree_preds = set()
|
|
396
|
+
for node in subtree:
|
|
397
|
+
preds = set(graph.predecessors(node))
|
|
398
|
+
subtree_preds |= {pred for pred in preds if pred not in subtree}
|
|
399
|
+
if len(subtree_preds) > 1:
|
|
400
|
+
# early break
|
|
401
|
+
break
|
|
402
|
+
|
|
403
|
+
if len(subtree_preds) > 1:
|
|
404
|
+
# there is more than one out-of-tree predecessor. remove this subtree
|
|
405
|
+
del initial_exit_to_newnodes[initial_exit]
|
|
406
|
+
|
|
407
|
+
if initial_exit_to_newnodes:
|
|
408
|
+
tree_sizes = {exit_: len(initial_exit_to_newnodes[exit_]) for exit_ in initial_exit_to_newnodes}
|
|
409
|
+
max_tree_size = max(tree_sizes.values())
|
|
410
|
+
if list(tree_sizes.values()).count(max_tree_size) == 1:
|
|
411
|
+
tree_size_to_exit = {v: k for k, v in tree_sizes.items()}
|
|
412
|
+
max_size_exit = tree_size_to_exit[max_tree_size]
|
|
413
|
+
if all(len(newnode_to_initial_exits[nn]) == 1 for nn in initial_exit_to_newnodes[max_size_exit]):
|
|
414
|
+
refined_loop_nodes = (
|
|
415
|
+
refined_loop_nodes - initial_exit_to_newnodes[max_size_exit] - {max_size_exit}
|
|
416
|
+
)
|
|
417
|
+
refined_exit_nodes.add(max_size_exit)
|
|
418
|
+
|
|
419
|
+
return refined_loop_nodes, refined_exit_nodes
|
|
420
|
+
|
|
421
|
+
def _make_regions(self, graph: TGraph) -> GraphRegion:
|
|
422
|
+
structured_loop_headers = set()
|
|
423
|
+
new_regions: list[GraphRegion] = []
|
|
424
|
+
|
|
425
|
+
# FIXME: _get_start_node() will fail if the graph is just a loop
|
|
426
|
+
|
|
427
|
+
# iteratively find and make loop regions
|
|
428
|
+
while True:
|
|
429
|
+
# find loop headers
|
|
430
|
+
self._loop_headers = self._find_loop_headers(graph)
|
|
431
|
+
if not self._loop_headers:
|
|
432
|
+
break
|
|
433
|
+
|
|
434
|
+
# Find all loops
|
|
435
|
+
while True:
|
|
436
|
+
restart = False
|
|
437
|
+
|
|
438
|
+
self._start_node = self._get_start_node(graph)
|
|
439
|
+
|
|
440
|
+
# re-find loop headers
|
|
441
|
+
self._loop_headers = self._find_loop_headers(graph)
|
|
442
|
+
if not self._loop_headers:
|
|
443
|
+
break
|
|
444
|
+
|
|
445
|
+
# Start from loops
|
|
446
|
+
for node in list(reversed(self._loop_headers)):
|
|
447
|
+
if node in structured_loop_headers:
|
|
448
|
+
continue
|
|
449
|
+
if node not in graph:
|
|
450
|
+
continue
|
|
451
|
+
region = self._make_cyclic_region(node, graph)
|
|
452
|
+
if region is None:
|
|
453
|
+
# failed to struct the loop region - remove the header node from loop headers
|
|
454
|
+
l.debug(
|
|
455
|
+
"Failed to structure a loop region starting at %#x. Remove it from loop headers.", node.addr
|
|
456
|
+
)
|
|
457
|
+
self._loop_headers.remove(node)
|
|
458
|
+
else:
|
|
459
|
+
l.debug("Structured a loop region %r.", region)
|
|
460
|
+
new_regions.append(region)
|
|
461
|
+
structured_loop_headers.add(node)
|
|
462
|
+
restart = True
|
|
463
|
+
break
|
|
464
|
+
|
|
465
|
+
if restart:
|
|
466
|
+
continue
|
|
467
|
+
|
|
468
|
+
break
|
|
469
|
+
|
|
470
|
+
new_regions.append(GraphRegion(self._get_start_node(graph), graph, None, None, False, None))
|
|
471
|
+
|
|
472
|
+
l.debug("Identified %d loop regions.", len(structured_loop_headers))
|
|
473
|
+
l.debug("No more loops left. Start structuring acyclic regions.")
|
|
474
|
+
# No more loops left. Structure acyclic regions.
|
|
475
|
+
while new_regions:
|
|
476
|
+
region = new_regions.pop(0)
|
|
477
|
+
assert region.graph is not None
|
|
478
|
+
head = region.head
|
|
479
|
+
subgraph = region.graph
|
|
480
|
+
|
|
481
|
+
failed_region_attempts = set()
|
|
482
|
+
while self._make_acyclic_region(
|
|
483
|
+
head, subgraph, region.graph_with_successors, failed_region_attempts, region.cyclic
|
|
484
|
+
):
|
|
485
|
+
if head not in subgraph:
|
|
486
|
+
# update head
|
|
487
|
+
head = next(iter(n for n in subgraph.nodes() if n.addr == head.addr))
|
|
488
|
+
|
|
489
|
+
head = next(iter(n for n in subgraph.nodes() if n.addr == head.addr))
|
|
490
|
+
region.head = head
|
|
491
|
+
|
|
492
|
+
if len(graph) == 1:
|
|
493
|
+
(res,) = graph.nodes
|
|
494
|
+
if isinstance(res, GraphRegion):
|
|
495
|
+
return res
|
|
496
|
+
# create a large graph region
|
|
497
|
+
new_head = self._get_start_node(graph)
|
|
498
|
+
return GraphRegion(new_head, graph, None, None, False, None)
|
|
499
|
+
|
|
500
|
+
#
|
|
501
|
+
# Cyclic regions
|
|
502
|
+
#
|
|
503
|
+
|
|
504
|
+
def _make_cyclic_region(self, head: TNode, graph: TGraph):
|
|
505
|
+
original_entry = self._get_entry_node(graph)
|
|
506
|
+
|
|
507
|
+
l.debug("Found cyclic region at %#08x", head.addr)
|
|
508
|
+
initial_loop_nodes = self._find_initial_loop_nodes(graph, head)
|
|
509
|
+
l.debug("Initial loop nodes %s", self._dbg_block_list(initial_loop_nodes))
|
|
510
|
+
|
|
511
|
+
# Make sure no other loops are contained in the current loop
|
|
512
|
+
assert self._loop_headers is not None
|
|
513
|
+
if {n for n in initial_loop_nodes if n.addr != head.addr}.intersection(self._loop_headers):
|
|
514
|
+
return None
|
|
515
|
+
|
|
516
|
+
normal_entries = {n for n in graph.predecessors(head) if n not in initial_loop_nodes}
|
|
517
|
+
abnormal_entries = set()
|
|
518
|
+
for n in initial_loop_nodes:
|
|
519
|
+
if n == head:
|
|
520
|
+
continue
|
|
521
|
+
preds = set(graph.predecessors(n))
|
|
522
|
+
abnormal_entries |= preds - initial_loop_nodes
|
|
523
|
+
l.debug("Normal entries %s", self._dbg_block_list(normal_entries))
|
|
524
|
+
l.debug("Abnormal entries %s", self._dbg_block_list(abnormal_entries))
|
|
525
|
+
|
|
526
|
+
initial_exit_nodes = set()
|
|
527
|
+
for n in initial_loop_nodes:
|
|
528
|
+
succs = set(graph.successors(n))
|
|
529
|
+
initial_exit_nodes |= succs - initial_loop_nodes
|
|
530
|
+
|
|
531
|
+
l.debug("Initial exit nodes %s", self._dbg_block_list(initial_exit_nodes))
|
|
532
|
+
|
|
533
|
+
refined_loop_nodes, refined_exit_nodes = self._refine_loop(graph, head, initial_loop_nodes, initial_exit_nodes)
|
|
534
|
+
l.debug("Refined loop nodes %s", self._dbg_block_list(refined_loop_nodes))
|
|
535
|
+
l.debug("Refined exit nodes %s", self._dbg_block_list(refined_exit_nodes))
|
|
536
|
+
|
|
537
|
+
# make sure there is a jump statement to the outside at the end of each node going to exit nodes.
|
|
538
|
+
# this jump statement will be rewritten to a break statement during structuring.
|
|
539
|
+
for exit_node in refined_exit_nodes:
|
|
540
|
+
for pred in graph.predecessors(exit_node):
|
|
541
|
+
if pred in refined_loop_nodes:
|
|
542
|
+
self._ensure_jump_at_loop_exit_ends(pred)
|
|
543
|
+
|
|
544
|
+
if len(refined_exit_nodes) > 1:
|
|
545
|
+
# self._get_start_node(graph)
|
|
546
|
+
node_post_order = list(networkx.dfs_postorder_nodes(graph, head))
|
|
547
|
+
sorted_exit_nodes = sorted(refined_exit_nodes, key=node_post_order.index)
|
|
548
|
+
normal_exit_node = sorted_exit_nodes[0]
|
|
549
|
+
abnormal_exit_nodes = set(sorted_exit_nodes[1:])
|
|
550
|
+
else:
|
|
551
|
+
normal_exit_node = next(iter(refined_exit_nodes)) if len(refined_exit_nodes) > 0 else None
|
|
552
|
+
abnormal_exit_nodes = set()
|
|
553
|
+
|
|
554
|
+
region = self._abstract_cyclic_region(
|
|
555
|
+
graph,
|
|
556
|
+
refined_loop_nodes,
|
|
557
|
+
head,
|
|
558
|
+
normal_entries,
|
|
559
|
+
abnormal_entries,
|
|
560
|
+
normal_exit_node,
|
|
561
|
+
abnormal_exit_nodes,
|
|
562
|
+
self._node_order,
|
|
563
|
+
)
|
|
564
|
+
assert region.graph is not None
|
|
565
|
+
if region.successors is not None and len(region.successors) > 1 and self._force_loop_single_exit:
|
|
566
|
+
# multi-successor region. refinement is required
|
|
567
|
+
self._refine_loop_successors_to_guarded_successors(region, graph)
|
|
568
|
+
|
|
569
|
+
# if the head node is in the graph and it's not the head of the graph, we will need to update the head node
|
|
570
|
+
# address.
|
|
571
|
+
if original_entry is not None and original_entry in region.graph and region.head is not original_entry:
|
|
572
|
+
assert head.addr is not None
|
|
573
|
+
self.entry_node_addr = (head.addr, None)
|
|
574
|
+
# FIXME: the identified region will probably be incorrect. we may need to add a jump block that jumps to
|
|
575
|
+
# original_entry.
|
|
576
|
+
|
|
577
|
+
return region
|
|
578
|
+
|
|
579
|
+
def _refine_loop_successors_to_guarded_successors(self, region: GraphRegion, graph: TGraph):
|
|
580
|
+
"""
|
|
581
|
+
If there are multiple successors of a loop, convert them into guarded successors. Eventually there should be
|
|
582
|
+
only one loop successor. This is used in the DREAM structuring algorithm.
|
|
583
|
+
|
|
584
|
+
:param GraphRegion region: The cyclic region to refine.
|
|
585
|
+
:param networkx.DiGraph graph: The current graph that is being structured.
|
|
586
|
+
:return: None
|
|
587
|
+
"""
|
|
588
|
+
assert region.graph is not None
|
|
589
|
+
assert region.successors is not None
|
|
590
|
+
assert region.graph_with_successors is not None
|
|
591
|
+
if len(region.successors) <= 1:
|
|
592
|
+
return
|
|
593
|
+
|
|
594
|
+
# recover reaching conditions
|
|
595
|
+
self.cond_proc.recover_reaching_conditions(region, with_successors=True)
|
|
596
|
+
|
|
597
|
+
successors = list(region.successors)
|
|
598
|
+
|
|
599
|
+
condnode_addr = next(CONDITIONNODE_ADDR)
|
|
600
|
+
# create a new successor
|
|
601
|
+
cond = ConditionNode(
|
|
602
|
+
condnode_addr,
|
|
603
|
+
None,
|
|
604
|
+
self.cond_proc.reaching_conditions[successors[1]],
|
|
605
|
+
successors[1],
|
|
606
|
+
false_node=successors[0],
|
|
607
|
+
)
|
|
608
|
+
for succ in successors[2:]:
|
|
609
|
+
cond: TNode = ConditionNode(
|
|
610
|
+
condnode_addr,
|
|
611
|
+
None,
|
|
612
|
+
self.cond_proc.reaching_conditions[succ],
|
|
613
|
+
succ,
|
|
614
|
+
false_node=cond,
|
|
615
|
+
)
|
|
616
|
+
|
|
617
|
+
g = region.graph_with_successors
|
|
618
|
+
|
|
619
|
+
# modify region in place
|
|
620
|
+
region.successors = {cast(TNode, cond)}
|
|
621
|
+
for succ in successors:
|
|
622
|
+
for src, _, data in list(g.in_edges(succ, data=True)):
|
|
623
|
+
removed_edges = []
|
|
624
|
+
for src2src, _, data_ in list(g.in_edges(src, data=True)):
|
|
625
|
+
removed_edges.append((src2src, src, data_))
|
|
626
|
+
g.remove_edge(src2src, src)
|
|
627
|
+
g.remove_edge(src, succ)
|
|
628
|
+
|
|
629
|
+
# TODO: rewrite the conditional jumps in src so that it goes to cond-node instead.
|
|
630
|
+
|
|
631
|
+
# modify the last statement of src so that it jumps to cond
|
|
632
|
+
replaced_any_stmt = False
|
|
633
|
+
last_stmts = self.cond_proc.get_last_statements(src)
|
|
634
|
+
for last_stmt in last_stmts:
|
|
635
|
+
if isinstance(last_stmt, ConditionalJump):
|
|
636
|
+
if (
|
|
637
|
+
isinstance(last_stmt.true_target, ailment.Expr.Const)
|
|
638
|
+
and last_stmt.true_target.value == succ.addr
|
|
639
|
+
):
|
|
640
|
+
new_last_stmt = ConditionalJump(
|
|
641
|
+
last_stmt.idx,
|
|
642
|
+
last_stmt.condition,
|
|
643
|
+
ailment.Expr.Const(None, None, condnode_addr, self.project.arch.bits),
|
|
644
|
+
last_stmt.false_target,
|
|
645
|
+
ins_addr=last_stmt.tags["ins_addr"],
|
|
646
|
+
)
|
|
647
|
+
elif (
|
|
648
|
+
isinstance(last_stmt.false_target, ailment.Expr.Const)
|
|
649
|
+
and last_stmt.false_target.value == succ.addr
|
|
650
|
+
):
|
|
651
|
+
new_last_stmt = ConditionalJump(
|
|
652
|
+
last_stmt.idx,
|
|
653
|
+
last_stmt.condition,
|
|
654
|
+
last_stmt.true_target,
|
|
655
|
+
ailment.Expr.Const(None, None, condnode_addr, self.project.arch.bits),
|
|
656
|
+
ins_addr=last_stmt.tags["ins_addr"],
|
|
657
|
+
)
|
|
658
|
+
else:
|
|
659
|
+
# none of the two branches is jumping out of the loop
|
|
660
|
+
continue
|
|
661
|
+
elif isinstance(last_stmt, Jump):
|
|
662
|
+
if isinstance(last_stmt.target, ailment.Expr.Const):
|
|
663
|
+
new_last_stmt = Jump(
|
|
664
|
+
last_stmt.idx,
|
|
665
|
+
ailment.Expr.Const(None, None, condnode_addr, self.project.arch.bits),
|
|
666
|
+
ins_addr=last_stmt.tags["ins_addr"],
|
|
667
|
+
)
|
|
668
|
+
else:
|
|
669
|
+
# an indirect jump - might be a jump table. ignore it
|
|
670
|
+
continue
|
|
671
|
+
else:
|
|
672
|
+
l.error("Unexpected last_stmt type %s. Ignore.", type(last_stmt))
|
|
673
|
+
continue
|
|
674
|
+
replace_last_statement(src, last_stmt, new_last_stmt)
|
|
675
|
+
replaced_any_stmt = True
|
|
676
|
+
if not replaced_any_stmt:
|
|
677
|
+
l.warning("No statement was replaced. Is there anything wrong?")
|
|
678
|
+
# raise Exception()
|
|
679
|
+
|
|
680
|
+
# add src back
|
|
681
|
+
for src2src, _, data_ in removed_edges:
|
|
682
|
+
g.add_edge(src2src, src, **data_)
|
|
683
|
+
|
|
684
|
+
g.add_edge(src, cond, **data)
|
|
685
|
+
|
|
686
|
+
# modify graph
|
|
687
|
+
graph.add_edge(region, cond)
|
|
688
|
+
for succ in successors:
|
|
689
|
+
edge_data = graph.get_edge_data(region, succ)
|
|
690
|
+
graph.remove_edge(region, succ)
|
|
691
|
+
graph.add_edge(cond, succ, **edge_data)
|
|
692
|
+
|
|
693
|
+
# compute the node order of newly created nodes
|
|
694
|
+
self._node_order[region] = region_node_order = min(self._node_order[node_] for node_ in region.graph)
|
|
695
|
+
self._node_order[cond] = region_node_order[0], region_node_order[1] + 1
|
|
696
|
+
|
|
697
|
+
#
|
|
698
|
+
# Acyclic regions
|
|
699
|
+
#
|
|
700
|
+
|
|
701
|
+
def _make_acyclic_region(
|
|
702
|
+
self,
|
|
703
|
+
head: TNode,
|
|
704
|
+
graph: TGraph,
|
|
705
|
+
secondary_graph: TGraph | None,
|
|
706
|
+
failed_region_attempts: set[tuple[TNode, TNode]],
|
|
707
|
+
cyclic: bool,
|
|
708
|
+
):
|
|
709
|
+
# pre-processing
|
|
710
|
+
|
|
711
|
+
# we need to create a copy of the original graph if
|
|
712
|
+
# - there are in edges to the head node, or
|
|
713
|
+
# - there are more than one end nodes
|
|
714
|
+
|
|
715
|
+
head_inedges = list(graph.in_edges(head))
|
|
716
|
+
if head_inedges:
|
|
717
|
+
# we need a copy of the graph to remove edges coming into the head
|
|
718
|
+
graph_copy = networkx.DiGraph(graph)
|
|
719
|
+
# remove any in-edge to the head node
|
|
720
|
+
for src, _ in head_inedges:
|
|
721
|
+
graph_copy.remove_edge(src, head)
|
|
722
|
+
else:
|
|
723
|
+
graph_copy = graph
|
|
724
|
+
|
|
725
|
+
endnodes = [node for node in graph_copy.nodes() if graph_copy.out_degree(node) == 0]
|
|
726
|
+
if len(endnodes) == 0:
|
|
727
|
+
# sanity check: there should be at least one end node
|
|
728
|
+
l.critical("No end node is found in a supposedly acyclic graph. Is it really acyclic?")
|
|
729
|
+
return False
|
|
730
|
+
|
|
731
|
+
add_dummy_endnode = False
|
|
732
|
+
if len(endnodes) > 1:
|
|
733
|
+
# if this graph has multiple end nodes: create a single end node
|
|
734
|
+
add_dummy_endnode = True
|
|
735
|
+
elif head_inedges and len(endnodes) == 1 and endnodes[0] not in list(graph.predecessors(head)):
|
|
736
|
+
# special case: there are in-edges to head, but the only end node is not a predecessor to head.
|
|
737
|
+
# in this case, we will want to put the end node and a predecessor of the head into the same region.
|
|
738
|
+
add_dummy_endnode = True
|
|
739
|
+
|
|
740
|
+
if add_dummy_endnode:
|
|
741
|
+
# we need a copy of the graph!
|
|
742
|
+
graph_copy = networkx.DiGraph(graph_copy)
|
|
743
|
+
dummy_endnode = Block(-1, -1)
|
|
744
|
+
for endnode in endnodes:
|
|
745
|
+
graph_copy.add_edge(endnode, dummy_endnode)
|
|
746
|
+
endnodes = [dummy_endnode]
|
|
747
|
+
else:
|
|
748
|
+
dummy_endnode = None
|
|
749
|
+
|
|
750
|
+
# dominators and post-dominators, computed incrementally
|
|
751
|
+
doms = IncrementalDominators(graph_copy, head)
|
|
752
|
+
postdoms = IncrementalDominators(graph_copy, endnodes[0], post=True)
|
|
753
|
+
|
|
754
|
+
# visit the nodes in post-order
|
|
755
|
+
region_created = False
|
|
756
|
+
for node in list(GraphUtils.dfs_postorder_nodes_deterministic(graph_copy, head)):
|
|
757
|
+
if node is dummy_endnode:
|
|
758
|
+
# skip the dummy endnode
|
|
759
|
+
continue
|
|
760
|
+
if cyclic and node is head:
|
|
761
|
+
continue
|
|
762
|
+
if node not in graph_copy:
|
|
763
|
+
continue
|
|
764
|
+
|
|
765
|
+
out_degree = graph_copy.out_degree[node]
|
|
766
|
+
if out_degree == 0:
|
|
767
|
+
# the root element of the region hierarchy should always be a GraphRegion,
|
|
768
|
+
# so we transform it into one, if necessary
|
|
769
|
+
if graph_copy.in_degree(node) == 0 and not isinstance(node, GraphRegion):
|
|
770
|
+
subgraph = networkx.DiGraph()
|
|
771
|
+
subgraph.add_node(node)
|
|
772
|
+
self._abstract_acyclic_region(
|
|
773
|
+
graph,
|
|
774
|
+
GraphRegion(node, subgraph, None, None, False, None, cyclic_ancestor=cyclic),
|
|
775
|
+
set(),
|
|
776
|
+
self._node_order,
|
|
777
|
+
secondary_graph=secondary_graph,
|
|
778
|
+
)
|
|
779
|
+
continue
|
|
780
|
+
|
|
781
|
+
# test if this node is an entry to a single-entry, single-successor region
|
|
782
|
+
levels = 0
|
|
783
|
+
postdom_node = postdoms.idom(node)
|
|
784
|
+
while postdom_node is not None:
|
|
785
|
+
if (node, postdom_node) not in failed_region_attempts and self._check_region(
|
|
786
|
+
graph_copy, node, postdom_node, doms
|
|
787
|
+
):
|
|
788
|
+
frontier = {postdom_node}
|
|
789
|
+
region = self._compute_region(
|
|
790
|
+
graph_copy, node, frontier, dummy_endnode=dummy_endnode, cyclic_ancestor=cyclic
|
|
791
|
+
)
|
|
792
|
+
if region is not None:
|
|
793
|
+
assert region.graph is not None
|
|
794
|
+
# update region.graph_with_successors
|
|
795
|
+
if secondary_graph is not None:
|
|
796
|
+
assert region.graph_with_successors is not None
|
|
797
|
+
assert region.successors is not None
|
|
798
|
+
if self._complete_successors:
|
|
799
|
+
for nn in list(region.graph_with_successors.nodes):
|
|
800
|
+
original_successors = secondary_graph.successors(nn)
|
|
801
|
+
for succ in original_successors:
|
|
802
|
+
if not region.graph_with_successors.has_edge(nn, succ):
|
|
803
|
+
region.graph_with_successors.add_edge(nn, succ)
|
|
804
|
+
region.successors.add(succ)
|
|
805
|
+
else:
|
|
806
|
+
for nn in list(region.graph_with_successors.nodes):
|
|
807
|
+
original_successors = secondary_graph.successors(nn)
|
|
808
|
+
for succ in original_successors:
|
|
809
|
+
if succ not in graph_copy:
|
|
810
|
+
# the successor wasn't added to the graph because it does not belong
|
|
811
|
+
# to the frontier. we backpatch the successor graph here.
|
|
812
|
+
region.graph_with_successors.add_edge(nn, succ)
|
|
813
|
+
region.successors.add(succ)
|
|
814
|
+
|
|
815
|
+
# add edges between successors
|
|
816
|
+
for succ_0 in region.successors:
|
|
817
|
+
for succ_1 in region.successors:
|
|
818
|
+
if succ_0 is not succ_1 and secondary_graph.has_edge(succ_0, succ_1):
|
|
819
|
+
region.graph_with_successors.add_edge(succ_0, succ_1)
|
|
820
|
+
|
|
821
|
+
# l.debug("Walked back %d levels in postdom tree.", levels)
|
|
822
|
+
l.debug("Node %r, frontier %r.", node, frontier)
|
|
823
|
+
# l.debug("Identified an acyclic region %s.", self._dbg_block_list(region.graph.nodes()))
|
|
824
|
+
self._abstract_acyclic_region(
|
|
825
|
+
graph,
|
|
826
|
+
region,
|
|
827
|
+
frontier,
|
|
828
|
+
self._node_order,
|
|
829
|
+
dummy_endnode=dummy_endnode,
|
|
830
|
+
secondary_graph=secondary_graph,
|
|
831
|
+
)
|
|
832
|
+
# assert dummy_endnode not in graph
|
|
833
|
+
region_created = True
|
|
834
|
+
# we created a new region to replace one or more nodes in the graph.
|
|
835
|
+
replaced_nodes = set(region.graph.nodes)
|
|
836
|
+
# update graph_copy; doms and postdoms are updated as well because they hold references to
|
|
837
|
+
# graph_copy internally.
|
|
838
|
+
if graph_copy is not graph:
|
|
839
|
+
self._update_graph(graph_copy, region, replaced_nodes)
|
|
840
|
+
doms.graph_updated(region, replaced_nodes, region.head)
|
|
841
|
+
postdoms.graph_updated(region, replaced_nodes, region.head)
|
|
842
|
+
# break out of the inner loop
|
|
843
|
+
break
|
|
844
|
+
|
|
845
|
+
failed_region_attempts.add((node, postdom_node))
|
|
846
|
+
if not doms.dominates(node, postdom_node):
|
|
847
|
+
break
|
|
848
|
+
if postdom_node is postdoms.idom(postdom_node):
|
|
849
|
+
break
|
|
850
|
+
postdom_node = postdoms.idom(postdom_node)
|
|
851
|
+
levels += 1
|
|
852
|
+
# l.debug("Walked back %d levels in postdom tree and did not find anything for %r. Next.", levels, node)
|
|
853
|
+
|
|
854
|
+
return region_created
|
|
855
|
+
|
|
856
|
+
@staticmethod
|
|
857
|
+
def _update_graph(graph: TGraph, new_region: GraphRegion, replaced_nodes: set[TNode]) -> None:
|
|
858
|
+
region_in_edges = RegionIdentifier._region_in_edges(graph, new_region, data=True)
|
|
859
|
+
region_out_edges = RegionIdentifier._region_out_edges(graph, new_region, data=True)
|
|
860
|
+
for node in replaced_nodes:
|
|
861
|
+
graph.remove_node(node)
|
|
862
|
+
graph.add_node(new_region)
|
|
863
|
+
for src, _, data in region_in_edges:
|
|
864
|
+
graph.add_edge(src, new_region, **data)
|
|
865
|
+
for _, dst, data in region_out_edges:
|
|
866
|
+
graph.add_edge(new_region, dst, **data)
|
|
867
|
+
|
|
868
|
+
@staticmethod
|
|
869
|
+
def _check_region(graph: TGraph, start_node: TNode, end_node: TNode, doms: IncrementalDominators) -> bool:
|
|
870
|
+
"""
|
|
871
|
+
Determine the graph slice between start_node and end_node forms a good region.
|
|
872
|
+
"""
|
|
873
|
+
|
|
874
|
+
# if the exit node is the header of a loop that contains the start node, the dominance frontier should only
|
|
875
|
+
# contain the exit node.
|
|
876
|
+
start_node_frontier = None
|
|
877
|
+
end_node_frontier = None
|
|
878
|
+
|
|
879
|
+
if not doms.dominates(start_node, end_node):
|
|
880
|
+
start_node_frontier = doms.df(start_node)
|
|
881
|
+
for node in start_node_frontier:
|
|
882
|
+
if node is not start_node and node is not end_node:
|
|
883
|
+
return False
|
|
884
|
+
|
|
885
|
+
# no edges should enter the region.
|
|
886
|
+
end_node_frontier = doms.df(end_node)
|
|
887
|
+
for node in end_node_frontier:
|
|
888
|
+
if doms.dominates(start_node, node) and node is not end_node:
|
|
889
|
+
return False
|
|
890
|
+
|
|
891
|
+
if start_node_frontier is None:
|
|
892
|
+
start_node_frontier = doms.df(start_node)
|
|
893
|
+
|
|
894
|
+
# no edges should leave the region.
|
|
895
|
+
for node in start_node_frontier:
|
|
896
|
+
if node is start_node or node is end_node:
|
|
897
|
+
continue
|
|
898
|
+
if node not in end_node_frontier:
|
|
899
|
+
return False
|
|
900
|
+
for pred in graph.predecessors(node):
|
|
901
|
+
if doms.dominates(start_node, pred) and not doms.dominates(end_node, pred):
|
|
902
|
+
return False
|
|
903
|
+
|
|
904
|
+
return True
|
|
905
|
+
|
|
906
|
+
@staticmethod
|
|
907
|
+
def _compute_region(
|
|
908
|
+
graph: TGraph,
|
|
909
|
+
node: TNode,
|
|
910
|
+
frontier: set[TNode],
|
|
911
|
+
include_frontier: bool = False,
|
|
912
|
+
dummy_endnode: TNode | None = None,
|
|
913
|
+
cyclic_ancestor: bool = False,
|
|
914
|
+
) -> GraphRegion | None:
|
|
915
|
+
subgraph = networkx.DiGraph()
|
|
916
|
+
frontier_edges = []
|
|
917
|
+
queue = [node]
|
|
918
|
+
traversed = set()
|
|
919
|
+
|
|
920
|
+
while queue:
|
|
921
|
+
node_ = queue.pop()
|
|
922
|
+
if node_ in frontier:
|
|
923
|
+
continue
|
|
924
|
+
traversed.add(node_)
|
|
925
|
+
subgraph.add_node(node_)
|
|
926
|
+
|
|
927
|
+
for succ in graph.successors(node_):
|
|
928
|
+
edge_data = graph.get_edge_data(node_, succ)
|
|
929
|
+
|
|
930
|
+
if node_ in frontier and succ in traversed:
|
|
931
|
+
if include_frontier:
|
|
932
|
+
# if frontier nodes are included, do not keep traversing their successors
|
|
933
|
+
# however, if it has an edge to an already traversed node, we should add that edge
|
|
934
|
+
subgraph.add_edge(node_, succ, **edge_data)
|
|
935
|
+
else:
|
|
936
|
+
frontier_edges.append((node_, succ, edge_data))
|
|
937
|
+
continue
|
|
938
|
+
|
|
939
|
+
if succ is dummy_endnode:
|
|
940
|
+
continue
|
|
941
|
+
|
|
942
|
+
if succ in frontier and not include_frontier:
|
|
943
|
+
# skip all frontier nodes
|
|
944
|
+
frontier_edges.append((node_, succ, edge_data))
|
|
945
|
+
continue
|
|
946
|
+
subgraph.add_edge(node_, succ, **edge_data)
|
|
947
|
+
if succ in traversed:
|
|
948
|
+
continue
|
|
949
|
+
queue.append(succ)
|
|
950
|
+
|
|
951
|
+
if dummy_endnode is not None:
|
|
952
|
+
frontier = {n for n in frontier if n is not dummy_endnode}
|
|
953
|
+
|
|
954
|
+
if subgraph.number_of_nodes() > 1:
|
|
955
|
+
subgraph_with_frontier = networkx.DiGraph(subgraph)
|
|
956
|
+
for src, dst, edge_data in frontier_edges:
|
|
957
|
+
if dst is not dummy_endnode:
|
|
958
|
+
subgraph_with_frontier.add_edge(src, dst, **edge_data)
|
|
959
|
+
# assert dummy_endnode not in frontier
|
|
960
|
+
# assert dummy_endnode not in subgraph_with_frontier
|
|
961
|
+
return GraphRegion(
|
|
962
|
+
node, subgraph, frontier, subgraph_with_frontier, False, None, cyclic_ancestor=cyclic_ancestor
|
|
963
|
+
)
|
|
964
|
+
return None
|
|
965
|
+
|
|
966
|
+
@staticmethod
|
|
967
|
+
def _abstract_acyclic_region(
|
|
968
|
+
graph: TGraph,
|
|
969
|
+
region: GraphRegion,
|
|
970
|
+
frontier: set[TNode],
|
|
971
|
+
node_order: dict[TNode, tuple[int, int]],
|
|
972
|
+
dummy_endnode: TNode | None = None,
|
|
973
|
+
secondary_graph: TGraph | None = None,
|
|
974
|
+
):
|
|
975
|
+
assert region.graph is not None
|
|
976
|
+
in_edges = RegionIdentifier._region_in_edges(graph, region, data=True)
|
|
977
|
+
out_edges = RegionIdentifier._region_out_edges(graph, region, data=True)
|
|
978
|
+
|
|
979
|
+
nodes_set = set()
|
|
980
|
+
for node_ in list(region.graph.nodes()):
|
|
981
|
+
nodes_set.add(node_)
|
|
982
|
+
if node_ is not dummy_endnode:
|
|
983
|
+
graph.remove_node(node_)
|
|
984
|
+
|
|
985
|
+
graph.add_node(region)
|
|
986
|
+
node_order[region] = min(node_order[node_] for node_ in nodes_set)
|
|
987
|
+
|
|
988
|
+
for src, _, data in in_edges:
|
|
989
|
+
if src not in nodes_set:
|
|
990
|
+
graph.add_edge(src, region, **data)
|
|
991
|
+
|
|
992
|
+
for _, dst, data in out_edges:
|
|
993
|
+
if dst not in nodes_set:
|
|
994
|
+
graph.add_edge(region, dst, **data)
|
|
995
|
+
|
|
996
|
+
for frontier_node in frontier:
|
|
997
|
+
if frontier_node is not dummy_endnode:
|
|
998
|
+
graph.add_edge(region, frontier_node)
|
|
999
|
+
|
|
1000
|
+
if secondary_graph is not None:
|
|
1001
|
+
RegionIdentifier._abstract_acyclic_region(secondary_graph, region, set(), node_order)
|
|
1002
|
+
|
|
1003
|
+
@staticmethod
|
|
1004
|
+
def _abstract_cyclic_region(
|
|
1005
|
+
graph: TGraph,
|
|
1006
|
+
loop_nodes: Iterable[TNode],
|
|
1007
|
+
head: TNode,
|
|
1008
|
+
normal_entries: set[TNode],
|
|
1009
|
+
abnormal_entries: set[TNode],
|
|
1010
|
+
normal_exit_node: TNode | None,
|
|
1011
|
+
abnormal_exit_nodes: set[TNode],
|
|
1012
|
+
node_order: dict[TNode, tuple[int, int]],
|
|
1013
|
+
) -> GraphRegion:
|
|
1014
|
+
region = GraphRegion(head, None, None, None, True, None)
|
|
1015
|
+
|
|
1016
|
+
subgraph = networkx.DiGraph()
|
|
1017
|
+
region_outedges = []
|
|
1018
|
+
|
|
1019
|
+
delayed_edges = []
|
|
1020
|
+
|
|
1021
|
+
full_graph = networkx.DiGraph()
|
|
1022
|
+
|
|
1023
|
+
for node in loop_nodes:
|
|
1024
|
+
subgraph.add_node(node)
|
|
1025
|
+
in_edges = list(graph.in_edges(node, data=True))
|
|
1026
|
+
out_edges = list(graph.out_edges(node, data=True))
|
|
1027
|
+
|
|
1028
|
+
for src, dst, data in in_edges:
|
|
1029
|
+
full_graph.add_edge(src, dst, **data)
|
|
1030
|
+
if src in loop_nodes:
|
|
1031
|
+
subgraph.add_edge(src, dst, **data)
|
|
1032
|
+
elif src == region:
|
|
1033
|
+
subgraph.add_edge(head, dst, **data)
|
|
1034
|
+
elif src in normal_entries:
|
|
1035
|
+
# graph.add_edge(src, region, **data)
|
|
1036
|
+
delayed_edges.append((src, region, data))
|
|
1037
|
+
elif src in abnormal_entries:
|
|
1038
|
+
data["region_dst_node"] = dst
|
|
1039
|
+
# graph.add_edge(src, region, **data)
|
|
1040
|
+
delayed_edges.append((src, region, data))
|
|
1041
|
+
else:
|
|
1042
|
+
assert 0
|
|
1043
|
+
|
|
1044
|
+
for src, dst, data in out_edges:
|
|
1045
|
+
full_graph.add_edge(src, dst, **data)
|
|
1046
|
+
if dst in loop_nodes:
|
|
1047
|
+
subgraph.add_edge(src, dst, **data)
|
|
1048
|
+
elif dst == region:
|
|
1049
|
+
subgraph.add_edge(src, head, **data)
|
|
1050
|
+
elif dst == normal_exit_node:
|
|
1051
|
+
region_outedges.append((node, dst))
|
|
1052
|
+
# graph.add_edge(region, dst, **data)
|
|
1053
|
+
delayed_edges.append((region, dst, data))
|
|
1054
|
+
elif dst in abnormal_exit_nodes:
|
|
1055
|
+
region_outedges.append((node, dst))
|
|
1056
|
+
# data['region_src_node'] = src
|
|
1057
|
+
# graph.add_edge(region, dst, **data)
|
|
1058
|
+
delayed_edges.append((region, dst, data))
|
|
1059
|
+
else:
|
|
1060
|
+
assert 0
|
|
1061
|
+
|
|
1062
|
+
subgraph_with_exits = networkx.DiGraph(subgraph)
|
|
1063
|
+
for src, dst in region_outedges:
|
|
1064
|
+
subgraph_with_exits.add_edge(src, dst)
|
|
1065
|
+
region.graph = subgraph
|
|
1066
|
+
region.graph_with_successors = subgraph_with_exits
|
|
1067
|
+
succs = [normal_exit_node] if normal_exit_node is not None else []
|
|
1068
|
+
succs += list(abnormal_exit_nodes)
|
|
1069
|
+
succs = sorted(set(succs), key=lambda x: x.addr if isinstance(x.addr, int) else -1)
|
|
1070
|
+
region.successors = set(succs)
|
|
1071
|
+
|
|
1072
|
+
for succ_0 in succs:
|
|
1073
|
+
for succ_1 in succs:
|
|
1074
|
+
if succ_0 is not succ_1 and graph.has_edge(succ_0, succ_1):
|
|
1075
|
+
region.graph_with_successors.add_edge(succ_0, succ_1)
|
|
1076
|
+
|
|
1077
|
+
for node in loop_nodes:
|
|
1078
|
+
graph.remove_node(node)
|
|
1079
|
+
|
|
1080
|
+
# add delayed edges
|
|
1081
|
+
graph.add_node(region)
|
|
1082
|
+
for src, dst, data in delayed_edges:
|
|
1083
|
+
graph.add_edge(src, dst, **data)
|
|
1084
|
+
# update node order
|
|
1085
|
+
node_order[region] = node_order[head]
|
|
1086
|
+
|
|
1087
|
+
region.full_graph = full_graph
|
|
1088
|
+
|
|
1089
|
+
return region
|
|
1090
|
+
|
|
1091
|
+
@overload
|
|
1092
|
+
@staticmethod
|
|
1093
|
+
def _region_in_edges(
|
|
1094
|
+
graph: TGraph, region: GraphRegion, data: Literal[True]
|
|
1095
|
+
) -> list[tuple[TNode, TNode, dict[str, Any]]]: ...
|
|
1096
|
+
|
|
1097
|
+
@overload
|
|
1098
|
+
@staticmethod
|
|
1099
|
+
def _region_in_edges(graph: TGraph, region: GraphRegion, data: Literal[False]) -> list[tuple[TNode, TNode]]: ...
|
|
1100
|
+
|
|
1101
|
+
@staticmethod
|
|
1102
|
+
def _region_in_edges(graph, region, data=False):
|
|
1103
|
+
return list(graph.in_edges(region.head, data=data))
|
|
1104
|
+
|
|
1105
|
+
@staticmethod
|
|
1106
|
+
def _region_out_edges(graph, region, data=False):
|
|
1107
|
+
out_edges = []
|
|
1108
|
+
for node in region.graph.nodes():
|
|
1109
|
+
out_ = graph.out_edges(node, data=data)
|
|
1110
|
+
for _, dst, data_ in out_:
|
|
1111
|
+
if dst in region.graph:
|
|
1112
|
+
continue
|
|
1113
|
+
out_edges.append((region, dst, data_))
|
|
1114
|
+
return out_edges
|
|
1115
|
+
|
|
1116
|
+
@staticmethod
|
|
1117
|
+
def _merge_nodes(graph: TGraph, node_a: TNode, node_b: TNode, force_multinode: bool = False) -> MultiNode | None:
|
|
1118
|
+
in_edges = list(graph.in_edges(node_a, data=True))
|
|
1119
|
+
out_edges = list(graph.out_edges(node_b, data=True))
|
|
1120
|
+
|
|
1121
|
+
if not force_multinode and len(in_edges) <= 1 and len(out_edges) <= 1:
|
|
1122
|
+
# it forms a region by itself :-)
|
|
1123
|
+
new_node = None
|
|
1124
|
+
|
|
1125
|
+
else:
|
|
1126
|
+
nodes = []
|
|
1127
|
+
match node_a:
|
|
1128
|
+
case MultiNode():
|
|
1129
|
+
nodes.extend(node_a.nodes)
|
|
1130
|
+
case Block():
|
|
1131
|
+
nodes.append(node_a)
|
|
1132
|
+
case _:
|
|
1133
|
+
raise TypeError(type(node_a))
|
|
1134
|
+
match node_b:
|
|
1135
|
+
case MultiNode():
|
|
1136
|
+
nodes.extend(node_b.nodes)
|
|
1137
|
+
case Block():
|
|
1138
|
+
nodes.append(node_b)
|
|
1139
|
+
case _:
|
|
1140
|
+
raise TypeError(type(node_b))
|
|
1141
|
+
new_node = MultiNode(nodes)
|
|
1142
|
+
|
|
1143
|
+
graph.remove_node(node_a)
|
|
1144
|
+
graph.remove_node(node_b)
|
|
1145
|
+
|
|
1146
|
+
if new_node is not None:
|
|
1147
|
+
graph.add_node(new_node)
|
|
1148
|
+
|
|
1149
|
+
for src, _, data in in_edges:
|
|
1150
|
+
if src is node_b:
|
|
1151
|
+
src = new_node
|
|
1152
|
+
graph.add_edge(src, new_node, **data)
|
|
1153
|
+
|
|
1154
|
+
for _, dst, data in out_edges:
|
|
1155
|
+
if dst is node_a:
|
|
1156
|
+
dst = new_node
|
|
1157
|
+
graph.add_edge(new_node, dst, **data)
|
|
1158
|
+
|
|
1159
|
+
assert node_a not in graph
|
|
1160
|
+
assert node_b not in graph
|
|
1161
|
+
|
|
1162
|
+
return new_node
|
|
1163
|
+
|
|
1164
|
+
def _ensure_jump_at_loop_exit_ends(self, node: TNode) -> None:
|
|
1165
|
+
if isinstance(node, Block):
|
|
1166
|
+
if not node.statements:
|
|
1167
|
+
node.statements.append(
|
|
1168
|
+
Jump(
|
|
1169
|
+
None,
|
|
1170
|
+
Const(None, None, node.addr + node.original_size, self.project.arch.bits),
|
|
1171
|
+
ins_addr=node.addr,
|
|
1172
|
+
)
|
|
1173
|
+
)
|
|
1174
|
+
else:
|
|
1175
|
+
if not isinstance(first_nonlabel_nonphi_statement(node), ConditionalJump) and not isinstance(
|
|
1176
|
+
node.statements[-1],
|
|
1177
|
+
(
|
|
1178
|
+
Jump,
|
|
1179
|
+
ConditionalJump,
|
|
1180
|
+
IncompleteSwitchCaseHeadStatement,
|
|
1181
|
+
),
|
|
1182
|
+
):
|
|
1183
|
+
node.statements.append(
|
|
1184
|
+
Jump(
|
|
1185
|
+
None,
|
|
1186
|
+
Const(None, None, node.addr + node.original_size, self.project.arch.bits),
|
|
1187
|
+
ins_addr=node.addr,
|
|
1188
|
+
)
|
|
1189
|
+
)
|
|
1190
|
+
elif isinstance(node, MultiNode) and node.nodes:
|
|
1191
|
+
self._ensure_jump_at_loop_exit_ends(node.nodes[-1])
|
|
1192
|
+
|
|
1193
|
+
@staticmethod
|
|
1194
|
+
def _dbg_block_list(blocks: Iterable[TNode]) -> list[str]:
|
|
1195
|
+
return [(hex(b.addr) if hasattr(b, "addr") and b.addr is not None else repr(b)) for b in blocks]
|
|
1196
|
+
|
|
1197
|
+
#
|
|
1198
|
+
# Reducibility
|
|
1199
|
+
#
|
|
1200
|
+
|
|
1201
|
+
def test_reducibility(self) -> bool:
|
|
1202
|
+
# make a copy of the graph
|
|
1203
|
+
graph = networkx.DiGraph(self._graph)
|
|
1204
|
+
|
|
1205
|
+
# preprocess: make it a super graph
|
|
1206
|
+
self._make_supergraph(graph)
|
|
1207
|
+
|
|
1208
|
+
while True:
|
|
1209
|
+
changed = False
|
|
1210
|
+
|
|
1211
|
+
# find a node with a back-edge, remove the edge (deleting the loop), and replace it with a MultiNode
|
|
1212
|
+
changed |= self._remove_self_loop(graph)
|
|
1213
|
+
|
|
1214
|
+
# find a node that has only one predecessor, and merge it with its predecessor (replace them with a
|
|
1215
|
+
# MultiNode)
|
|
1216
|
+
changed |= self._merge_single_entry_node(graph)
|
|
1217
|
+
|
|
1218
|
+
if not changed:
|
|
1219
|
+
# a fixed-point is reached
|
|
1220
|
+
break
|
|
1221
|
+
|
|
1222
|
+
# Flow graph reducibility, Hecht and Ullman
|
|
1223
|
+
return len(graph.nodes) == 1
|
|
1224
|
+
|
|
1225
|
+
def _remove_self_loop(self, graph: TGraph) -> bool:
|
|
1226
|
+
r = False
|
|
1227
|
+
|
|
1228
|
+
while True:
|
|
1229
|
+
for node in graph.nodes():
|
|
1230
|
+
if node in graph[node]:
|
|
1231
|
+
# found a self loop
|
|
1232
|
+
self._remove_node(graph, node)
|
|
1233
|
+
r = True
|
|
1234
|
+
break
|
|
1235
|
+
else:
|
|
1236
|
+
break
|
|
1237
|
+
|
|
1238
|
+
return r
|
|
1239
|
+
|
|
1240
|
+
def _merge_single_entry_node(self, graph: TGraph) -> bool:
|
|
1241
|
+
r = False
|
|
1242
|
+
|
|
1243
|
+
while True:
|
|
1244
|
+
for node in networkx.dfs_postorder_nodes(graph):
|
|
1245
|
+
preds = list(graph.predecessors(node))
|
|
1246
|
+
if len(preds) == 1:
|
|
1247
|
+
# merge the two nodes
|
|
1248
|
+
(pred,) = preds
|
|
1249
|
+
self._absorb_node(graph, pred, node)
|
|
1250
|
+
r = True
|
|
1251
|
+
break
|
|
1252
|
+
else:
|
|
1253
|
+
break
|
|
1254
|
+
|
|
1255
|
+
return r
|
|
1256
|
+
|
|
1257
|
+
def _remove_node(self, graph: TGraph, node: TNode): # pylint:disable=no-self-use
|
|
1258
|
+
in_edges = [(src, dst, data) for (src, dst, data) in graph.in_edges(node, data=True) if src is not node]
|
|
1259
|
+
out_edges = [(src, dst, data) for (src, dst, data) in graph.out_edges(node, data=True) if dst is not node]
|
|
1260
|
+
|
|
1261
|
+
if len(in_edges) <= 1 and len(out_edges) <= 1:
|
|
1262
|
+
new_node = None
|
|
1263
|
+
else:
|
|
1264
|
+
# true case: it forms a region by itself :-)
|
|
1265
|
+
assert isinstance(node, Block)
|
|
1266
|
+
new_node = MultiNode([node])
|
|
1267
|
+
|
|
1268
|
+
graph.remove_node(node)
|
|
1269
|
+
|
|
1270
|
+
if new_node is not None:
|
|
1271
|
+
for src, _, data in in_edges:
|
|
1272
|
+
graph.add_edge(src, new_node, **data)
|
|
1273
|
+
|
|
1274
|
+
for _, dst, data in out_edges:
|
|
1275
|
+
graph.add_edge(new_node, dst, **data)
|
|
1276
|
+
|
|
1277
|
+
@staticmethod
|
|
1278
|
+
def _absorb_node(graph: TGraph, node_mommy: TNode, node_kiddie: TNode, force_multinode: bool = False):
|
|
1279
|
+
in_edges_mommy = graph.in_edges(node_mommy, data=True)
|
|
1280
|
+
out_edges_mommy = graph.out_edges(node_mommy, data=True)
|
|
1281
|
+
out_edges_kiddie = graph.out_edges(node_kiddie, data=True)
|
|
1282
|
+
|
|
1283
|
+
if not force_multinode and len(in_edges_mommy) <= 1 and len(out_edges_kiddie) <= 1:
|
|
1284
|
+
# it forms a region by itself :-)
|
|
1285
|
+
new_node = None
|
|
1286
|
+
|
|
1287
|
+
else:
|
|
1288
|
+
assert isinstance(node_mommy, Block)
|
|
1289
|
+
assert isinstance(node_kiddie, Block)
|
|
1290
|
+
new_node = MultiNode([node_mommy, node_kiddie])
|
|
1291
|
+
|
|
1292
|
+
graph.remove_node(node_mommy)
|
|
1293
|
+
graph.remove_node(node_kiddie)
|
|
1294
|
+
|
|
1295
|
+
if new_node is not None:
|
|
1296
|
+
graph.add_node(new_node)
|
|
1297
|
+
|
|
1298
|
+
for src, _, data in in_edges_mommy:
|
|
1299
|
+
if src == node_kiddie:
|
|
1300
|
+
src = new_node
|
|
1301
|
+
graph.add_edge(src, new_node, **data)
|
|
1302
|
+
|
|
1303
|
+
for _, dst, data in out_edges_mommy:
|
|
1304
|
+
if dst == node_kiddie:
|
|
1305
|
+
continue
|
|
1306
|
+
if dst == node_mommy:
|
|
1307
|
+
dst = new_node
|
|
1308
|
+
graph.add_edge(new_node, dst, **data)
|
|
1309
|
+
|
|
1310
|
+
for _, dst, data in out_edges_kiddie:
|
|
1311
|
+
if dst == node_mommy:
|
|
1312
|
+
dst = new_node
|
|
1313
|
+
graph.add_edge(new_node, dst, **data)
|
|
1314
|
+
|
|
1315
|
+
assert node_mommy not in graph
|
|
1316
|
+
assert node_kiddie not in graph
|
|
1317
|
+
|
|
1318
|
+
|
|
1319
|
+
register_analysis(RegionIdentifier, "RegionIdentifier")
|