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,1221 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
from collections import defaultdict
|
|
3
|
+
import logging
|
|
4
|
+
from itertools import combinations
|
|
5
|
+
import itertools
|
|
6
|
+
|
|
7
|
+
import networkx as nx
|
|
8
|
+
|
|
9
|
+
import angr.ailment as ailment
|
|
10
|
+
from angr.ailment.block import Block
|
|
11
|
+
from angr.ailment.statement import ConditionalJump, Jump, Assignment, Return, Label
|
|
12
|
+
from angr.ailment.expression import Const, Register, Convert, Expression, VirtualVariable
|
|
13
|
+
|
|
14
|
+
from .ail_merge_graph import AILMergeGraph, AILBlockSplit
|
|
15
|
+
from .errors import SAILRSemanticError
|
|
16
|
+
from .similarity import longest_ail_graph_subseq
|
|
17
|
+
|
|
18
|
+
from .utils import (
|
|
19
|
+
replace_node_in_graph,
|
|
20
|
+
find_block_in_successors_by_addr,
|
|
21
|
+
copy_graph_and_nodes,
|
|
22
|
+
correct_jump_targets,
|
|
23
|
+
deepcopy_ail_anyjump,
|
|
24
|
+
)
|
|
25
|
+
from angr.analyses.decompiler.optimization_passes.optimization_pass import StructuringOptimizationPass
|
|
26
|
+
from angr.analyses.decompiler.block_io_finder import BlockIOFinder
|
|
27
|
+
from angr.analyses.decompiler.block_similarity import is_similar, index_of_similar_stmts, longest_ail_subseq
|
|
28
|
+
from angr.analyses.decompiler.utils import to_ail_supergraph, remove_labels
|
|
29
|
+
from angr.analyses.decompiler.counters.boolean_counter import BooleanCounter
|
|
30
|
+
from angr.knowledge_plugins.key_definitions.atoms import MemoryLocation
|
|
31
|
+
from angr.utils.graph import dominates
|
|
32
|
+
|
|
33
|
+
_l = logging.getLogger(name=__name__)
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
class DuplicationReverter(StructuringOptimizationPass):
|
|
37
|
+
"""
|
|
38
|
+
This (de)optimization reverts the effects of many compiler optimizations that cause code duplication in
|
|
39
|
+
the decompilation. This deoptimization is the implementation of the USENIX 2024 paper SAILR's ISD
|
|
40
|
+
doptimization. As such, the main goal of this optimization is to remove code duplication by merging
|
|
41
|
+
semantically similar blocks in the AIL graph.
|
|
42
|
+
"""
|
|
43
|
+
|
|
44
|
+
NAME = "Revert Statement Duplication Optimizations"
|
|
45
|
+
DESCRIPTION = __doc__.strip()
|
|
46
|
+
|
|
47
|
+
def __init__(self, func, max_guarding_conditions=4, **kwargs):
|
|
48
|
+
super().__init__(
|
|
49
|
+
func,
|
|
50
|
+
prevent_new_gotos=True,
|
|
51
|
+
strictly_less_gotos=False,
|
|
52
|
+
recover_structure_fails=True,
|
|
53
|
+
must_improve_rel_quality=True,
|
|
54
|
+
max_opt_iters=5,
|
|
55
|
+
simplify_ail=True,
|
|
56
|
+
require_gotos=True,
|
|
57
|
+
readd_labels=True,
|
|
58
|
+
**kwargs,
|
|
59
|
+
)
|
|
60
|
+
|
|
61
|
+
self.max_guarding_conditions = max_guarding_conditions
|
|
62
|
+
self.write_graph: nx.DiGraph | None = None
|
|
63
|
+
self.read_graph: nx.DiGraph | None = None
|
|
64
|
+
self.candidate_blacklist = set()
|
|
65
|
+
|
|
66
|
+
# cache items
|
|
67
|
+
self._idom_cache = {}
|
|
68
|
+
self._entry_node_cache = {}
|
|
69
|
+
|
|
70
|
+
self.analyze()
|
|
71
|
+
|
|
72
|
+
#
|
|
73
|
+
# Superclass methods
|
|
74
|
+
#
|
|
75
|
+
|
|
76
|
+
def _check(self):
|
|
77
|
+
return True, {}
|
|
78
|
+
|
|
79
|
+
def _get_new_gotos(self):
|
|
80
|
+
future_irreducible_gotos = self._find_future_irreducible_gotos()
|
|
81
|
+
return [goto for goto in self._goto_manager.gotos if goto not in future_irreducible_gotos]
|
|
82
|
+
|
|
83
|
+
#
|
|
84
|
+
# Main Analysis
|
|
85
|
+
#
|
|
86
|
+
|
|
87
|
+
def _analyze(self, cache=None) -> bool:
|
|
88
|
+
"""
|
|
89
|
+
This function is the main analysis function for this deoptimization which implements SAILR's ISD deoptimization.
|
|
90
|
+
There are generally three steps to this deoptimization:
|
|
91
|
+
1. Search for candidates to merge based on the ISD-schema
|
|
92
|
+
2. Construct the middle graph/node that is merged from the duplicate candidate
|
|
93
|
+
3. Reinsert the merged candidate into the original graph
|
|
94
|
+
|
|
95
|
+
Of these stages, the later two are the most complex. In stage 2, we create a new AILMergeGraph that represents
|
|
96
|
+
the merging of two subgraphs that are duplicates. This stage will also record how blocks map to the split forms
|
|
97
|
+
(see AILMergeGraph class string for more information). During this stage, semantic failures can happen, which
|
|
98
|
+
mean that while creating the merged graph we encounter a scenario that is non-verifiable to not harm the graph.
|
|
99
|
+
In these cases, we bail. In stage 3, we reinsert the merged candidate into the original graph. This stage is
|
|
100
|
+
also a little messy because need to correct every jump address.
|
|
101
|
+
|
|
102
|
+
Finally, the _analyze function returns True if the analysis was successful and a change was made to the graph.
|
|
103
|
+
In this case, we return True if this optimization requires another iteration, and False if it does not.
|
|
104
|
+
It can be True even if no changes were made to the graph.
|
|
105
|
+
"""
|
|
106
|
+
# construct graphs for writing and reading so we can corrupt the write graph
|
|
107
|
+
# but still have a clean copy to read from
|
|
108
|
+
graph = self.out_graph or self._graph
|
|
109
|
+
self.write_graph = remove_labels(to_ail_supergraph(copy_graph_and_nodes(graph), allow_fake=True))
|
|
110
|
+
self.read_graph: nx.DiGraph = self.write_graph.copy()
|
|
111
|
+
|
|
112
|
+
# phase 1: search for candidates to merge based on the ISD-schema
|
|
113
|
+
candidate = self._search_for_deduplication_candidate()
|
|
114
|
+
if candidate is None:
|
|
115
|
+
return False
|
|
116
|
+
|
|
117
|
+
# phase 2: construct the middle graph/node that is merged from the duplicate candidate
|
|
118
|
+
try:
|
|
119
|
+
ail_merge_graph, candidate = self._construct_merged_candidate(candidate)
|
|
120
|
+
except SAILRSemanticError as e:
|
|
121
|
+
_l.debug("Skipping this candidate because of %s...", e)
|
|
122
|
+
self.candidate_blacklist.add(tuple(candidate))
|
|
123
|
+
return True
|
|
124
|
+
|
|
125
|
+
# phase 3: reinsert the merged candidate into the original graph
|
|
126
|
+
success = self._reinsert_merged_candidate(ail_merge_graph, candidate)
|
|
127
|
+
if not success:
|
|
128
|
+
self.candidate_blacklist.add(tuple(candidate))
|
|
129
|
+
return True
|
|
130
|
+
|
|
131
|
+
self.out_graph = to_ail_supergraph(self.write_graph)
|
|
132
|
+
return True
|
|
133
|
+
|
|
134
|
+
def _search_for_deduplication_candidate(self) -> tuple[Block, Block] | None:
|
|
135
|
+
candidates = self._find_initial_candidates()
|
|
136
|
+
if not candidates:
|
|
137
|
+
_l.debug("There are no duplicate statements in this function, stopping analysis")
|
|
138
|
+
return None
|
|
139
|
+
|
|
140
|
+
# with merge_candidates=False, max size for a candidate is 2
|
|
141
|
+
candidates = self._filter_candidates(candidates, merge_candidates=False)
|
|
142
|
+
if not candidates:
|
|
143
|
+
_l.debug("There are no duplicate blocks in this function, stopping analysis")
|
|
144
|
+
return None
|
|
145
|
+
|
|
146
|
+
candidates = sorted(candidates, key=len)
|
|
147
|
+
_l.debug("Located %d candidates for merging: %s", len(candidates), candidates)
|
|
148
|
+
|
|
149
|
+
candidate = sorted(candidates[0])
|
|
150
|
+
_l.debug("Selecting the candidate: %s", candidate)
|
|
151
|
+
return candidate[0], candidate[1]
|
|
152
|
+
|
|
153
|
+
def _construct_merged_candidate(
|
|
154
|
+
self, candidate: tuple[Block, Block]
|
|
155
|
+
) -> tuple[AILMergeGraph, tuple[Block, Block]] | None:
|
|
156
|
+
ail_merge_graph = self.create_merged_subgraph(candidate, self.write_graph)
|
|
157
|
+
new_candidate = ail_merge_graph.starts
|
|
158
|
+
for block in ail_merge_graph.original_ends:
|
|
159
|
+
if self._block_has_goto_edge(
|
|
160
|
+
block, [b for b in ail_merge_graph.original_ends if b is not block], graph=self.write_graph
|
|
161
|
+
):
|
|
162
|
+
break
|
|
163
|
+
else:
|
|
164
|
+
raise SAILRSemanticError("An initial candidate was incorrectly reported to have gotos at it's ends!")
|
|
165
|
+
|
|
166
|
+
return ail_merge_graph, new_candidate
|
|
167
|
+
|
|
168
|
+
def _reinsert_merged_candidate(self, ail_merge_graph: AILMergeGraph, candidate: tuple[Block, Block]) -> bool:
|
|
169
|
+
og_succs, og_preds = {}, {}
|
|
170
|
+
for original_blocks in ail_merge_graph.original_blocks.values():
|
|
171
|
+
# collect all the old edges
|
|
172
|
+
for og_block in original_blocks:
|
|
173
|
+
og_succs[og_block] = list(self.write_graph.successors(og_block))
|
|
174
|
+
og_preds[og_block] = list(self.write_graph.predecessors(og_block))
|
|
175
|
+
|
|
176
|
+
# delete all the blocks that will be merged into the merge_graph
|
|
177
|
+
self.write_graph.remove_nodes_from(original_blocks)
|
|
178
|
+
|
|
179
|
+
# add the new graph in to the original graph
|
|
180
|
+
self.write_graph = nx.compose(self.write_graph, ail_merge_graph.graph)
|
|
181
|
+
|
|
182
|
+
# connect all the out-edges that may have been altered
|
|
183
|
+
for merged_node, originals in ail_merge_graph.merge_blocks_to_originals.items():
|
|
184
|
+
last_stmt = merged_node.statements[-1]
|
|
185
|
+
curr_succs = list(self.write_graph.successors(merged_node))
|
|
186
|
+
|
|
187
|
+
# skip any nodes that already have enough successors
|
|
188
|
+
broken_conditional_jump = not isinstance(last_stmt, (ConditionalJump, Jump)) and len(curr_succs) == 1
|
|
189
|
+
if (
|
|
190
|
+
broken_conditional_jump
|
|
191
|
+
or (isinstance(last_stmt, Jump) and len(curr_succs) == 1)
|
|
192
|
+
or (isinstance(last_stmt, ConditionalJump) and len(curr_succs) == 2)
|
|
193
|
+
):
|
|
194
|
+
continue
|
|
195
|
+
|
|
196
|
+
all_og_succs = set()
|
|
197
|
+
for orig in originals:
|
|
198
|
+
orig_block = orig.original if isinstance(orig, AILBlockSplit) else orig
|
|
199
|
+
if orig_block not in og_succs:
|
|
200
|
+
continue
|
|
201
|
+
|
|
202
|
+
for og_suc in og_succs[orig_block]:
|
|
203
|
+
if og_suc not in self.write_graph:
|
|
204
|
+
continue
|
|
205
|
+
|
|
206
|
+
all_og_succs.add(og_suc)
|
|
207
|
+
|
|
208
|
+
# no if-stmt updating is needed here!
|
|
209
|
+
for og_succ in all_og_succs:
|
|
210
|
+
self.write_graph.add_edge(merged_node, og_succ)
|
|
211
|
+
|
|
212
|
+
# correct all the in-edges that may have been altered
|
|
213
|
+
all_preds = set()
|
|
214
|
+
for block in candidate:
|
|
215
|
+
for original in ail_merge_graph.original_blocks[block]:
|
|
216
|
+
if original not in og_preds:
|
|
217
|
+
continue
|
|
218
|
+
|
|
219
|
+
orig_preds = og_preds[original]
|
|
220
|
+
for orig_pred in orig_preds:
|
|
221
|
+
if orig_pred not in self.write_graph:
|
|
222
|
+
continue
|
|
223
|
+
|
|
224
|
+
all_preds.add(orig_pred)
|
|
225
|
+
|
|
226
|
+
for orig_pred in all_preds:
|
|
227
|
+
last_stmt = orig_pred.statements[-1]
|
|
228
|
+
if isinstance(last_stmt, (Jump, ConditionalJump)):
|
|
229
|
+
target_addrs = []
|
|
230
|
+
if isinstance(last_stmt, Jump):
|
|
231
|
+
if not isinstance(last_stmt.target, Const):
|
|
232
|
+
_l.debug("Candidate %s is a child of an indirect-jump, which is not supported", candidate)
|
|
233
|
+
self.write_graph = self.read_graph.copy()
|
|
234
|
+
return False
|
|
235
|
+
|
|
236
|
+
target_addrs = [last_stmt.target.value] if isinstance(last_stmt.target, Const) else []
|
|
237
|
+
elif isinstance(last_stmt, ConditionalJump):
|
|
238
|
+
target_addrs = [last_stmt.true_target.value, last_stmt.false_target.value]
|
|
239
|
+
|
|
240
|
+
replacement_map = {}
|
|
241
|
+
for target_addr in target_addrs:
|
|
242
|
+
target_candidates = []
|
|
243
|
+
for mblock, oblocks in ail_merge_graph.merge_blocks_to_originals.items():
|
|
244
|
+
for oblock in oblocks:
|
|
245
|
+
if (isinstance(oblock, AILBlockSplit) and oblock.original.addr == target_addr) or (
|
|
246
|
+
isinstance(oblock, Block) and oblock.addr == target_addr
|
|
247
|
+
):
|
|
248
|
+
target_candidates.append(mblock)
|
|
249
|
+
|
|
250
|
+
if not target_candidates:
|
|
251
|
+
continue
|
|
252
|
+
|
|
253
|
+
new_target = None
|
|
254
|
+
curr_succs = list(self.write_graph.successors(orig_pred))
|
|
255
|
+
target_candidates = [t for t in target_candidates if t not in curr_succs]
|
|
256
|
+
for target_can in target_candidates:
|
|
257
|
+
if target_can.addr == target_addr:
|
|
258
|
+
new_target = target_can
|
|
259
|
+
break
|
|
260
|
+
|
|
261
|
+
if new_target is None:
|
|
262
|
+
for target_can in target_candidates:
|
|
263
|
+
found = False
|
|
264
|
+
for orig in ail_merge_graph.merge_blocks_to_originals[target_can]:
|
|
265
|
+
if isinstance(orig, Block):
|
|
266
|
+
new_target = target_can
|
|
267
|
+
found = True
|
|
268
|
+
break
|
|
269
|
+
|
|
270
|
+
if found:
|
|
271
|
+
break
|
|
272
|
+
|
|
273
|
+
if new_target is None:
|
|
274
|
+
for split_type in ["up_split", "match_split", "down_split"]:
|
|
275
|
+
found = False
|
|
276
|
+
|
|
277
|
+
for target_can in target_candidates:
|
|
278
|
+
if ail_merge_graph.merged_is_split_type(target_can, split_type):
|
|
279
|
+
new_target = target_can
|
|
280
|
+
found = True
|
|
281
|
+
break
|
|
282
|
+
|
|
283
|
+
if found:
|
|
284
|
+
break
|
|
285
|
+
|
|
286
|
+
if new_target is None:
|
|
287
|
+
_l.debug("Unable to correct a predecessor, this is a bug!")
|
|
288
|
+
self.write_graph = self.read_graph.copy()
|
|
289
|
+
return False
|
|
290
|
+
|
|
291
|
+
replacement_map[target_addr] = new_target.addr
|
|
292
|
+
self.write_graph.add_edge(orig_pred, new_target)
|
|
293
|
+
|
|
294
|
+
new_pred = orig_pred.copy()
|
|
295
|
+
new_pred.statements[-1] = correct_jump_targets(new_pred.statements[-1], replacement_map, new_stmt=True)
|
|
296
|
+
if new_pred != orig_pred:
|
|
297
|
+
replace_node_in_graph(self.write_graph, orig_pred, new_pred)
|
|
298
|
+
else:
|
|
299
|
+
# we are at a block that has no ending, if this block does not end in one successor, then
|
|
300
|
+
# it is just an incorrect graph
|
|
301
|
+
orig_pred_succs = list(self.read_graph.successors(orig_pred))
|
|
302
|
+
assert len(orig_pred_succs) == 1
|
|
303
|
+
|
|
304
|
+
orig_pred_succ = orig_pred_succs[0]
|
|
305
|
+
new_succ = None
|
|
306
|
+
for merge, originals in ail_merge_graph.merge_blocks_to_originals.items():
|
|
307
|
+
found = False
|
|
308
|
+
for og in originals:
|
|
309
|
+
if (og == orig_pred_succ) or (isinstance(og, AILBlockSplit) and og.original == orig_pred_succ):
|
|
310
|
+
new_succ = merge
|
|
311
|
+
found = True
|
|
312
|
+
break
|
|
313
|
+
|
|
314
|
+
if found:
|
|
315
|
+
break
|
|
316
|
+
|
|
317
|
+
if new_succ is None:
|
|
318
|
+
_l.debug("Unable to find the successor for block with no jump or condition!")
|
|
319
|
+
self.write_graph = self.read_graph.copy()
|
|
320
|
+
return False
|
|
321
|
+
|
|
322
|
+
self.write_graph.add_edge(orig_pred, new_succ)
|
|
323
|
+
|
|
324
|
+
self.write_graph = self._correct_all_broken_jumps(self.write_graph)
|
|
325
|
+
self.write_graph = self._uniquify_addrs(self.write_graph)
|
|
326
|
+
_l.info("Candidate merge successful on blocks: %s", candidate)
|
|
327
|
+
return True
|
|
328
|
+
|
|
329
|
+
#
|
|
330
|
+
# Helpers
|
|
331
|
+
#
|
|
332
|
+
|
|
333
|
+
def _uniquify_addrs(self, graph):
|
|
334
|
+
new_graph = nx.DiGraph()
|
|
335
|
+
new_nodes = {}
|
|
336
|
+
nodes_by_addr = defaultdict(list)
|
|
337
|
+
for node in graph.nodes:
|
|
338
|
+
nodes_by_addr[node.addr].append(node)
|
|
339
|
+
|
|
340
|
+
for _, nodes in nodes_by_addr.items():
|
|
341
|
+
if len(nodes) == 1:
|
|
342
|
+
continue
|
|
343
|
+
|
|
344
|
+
# we have multiple nodes with the same address
|
|
345
|
+
duplicate_addr_nodes = sorted(nodes, reverse=True)
|
|
346
|
+
for duplicate_node in duplicate_addr_nodes:
|
|
347
|
+
new_node = duplicate_node.copy()
|
|
348
|
+
new_node.idx = None
|
|
349
|
+
new_addr = self.new_block_addr()
|
|
350
|
+
new_node.addr = new_addr
|
|
351
|
+
for i, stmt in enumerate(new_node.statements):
|
|
352
|
+
if stmt.tags and "ins_addr" in stmt.tags:
|
|
353
|
+
if "orig_ins_addr" not in stmt.tags:
|
|
354
|
+
stmt.tags["orig_ins_addr"] = stmt.tags["ins_addr"]
|
|
355
|
+
stmt.tags["ins_addr"] = new_addr + i + 1
|
|
356
|
+
|
|
357
|
+
new_nodes[duplicate_node] = new_node
|
|
358
|
+
|
|
359
|
+
# reset the idx for all of them since they are unique now, also fix the jump targets idx
|
|
360
|
+
for node in graph.nodes:
|
|
361
|
+
new_node = new_nodes[node] if node in new_nodes else node.copy()
|
|
362
|
+
new_node.idx = None
|
|
363
|
+
if new_node.statements and isinstance(new_node.statements[-1], Jump):
|
|
364
|
+
new_node.statements[-1].target_idx = None
|
|
365
|
+
|
|
366
|
+
new_nodes[node] = new_node
|
|
367
|
+
|
|
368
|
+
# fixup every single jump target (before adding them to the graph)
|
|
369
|
+
for src, dst in graph.edges():
|
|
370
|
+
new_src = new_nodes[src]
|
|
371
|
+
new_dst = new_nodes[dst]
|
|
372
|
+
if new_dst is not dst:
|
|
373
|
+
new_new_src = new_src.copy()
|
|
374
|
+
new_new_src.statements[-1] = correct_jump_targets(new_new_src.statements[-1], {dst.addr: new_dst.addr})
|
|
375
|
+
new_nodes[src] = new_new_src
|
|
376
|
+
|
|
377
|
+
# add all the nodes in the same order back to the graph
|
|
378
|
+
for node in graph.nodes:
|
|
379
|
+
new_graph.add_node(new_nodes[node])
|
|
380
|
+
for src, dst, data in graph.edges(data=True):
|
|
381
|
+
new_graph.add_edge(new_nodes[src], new_nodes[dst], **data)
|
|
382
|
+
|
|
383
|
+
return new_graph
|
|
384
|
+
|
|
385
|
+
def _correct_all_broken_jumps(self, graph):
|
|
386
|
+
new_graph = nx.DiGraph()
|
|
387
|
+
new_nodes = {}
|
|
388
|
+
for node in graph.nodes:
|
|
389
|
+
# correct the last statement of the node for single-successor nodes
|
|
390
|
+
new_node = node
|
|
391
|
+
if graph.out_degree(node) == 1:
|
|
392
|
+
last_stmt = node.statements[-1]
|
|
393
|
+
successor = next(iter(graph.successors(node)))
|
|
394
|
+
if isinstance(last_stmt, Jump):
|
|
395
|
+
if last_stmt.target.value != successor.addr:
|
|
396
|
+
new_last_stmt = deepcopy_ail_anyjump(last_stmt, idx=last_stmt.idx)
|
|
397
|
+
last_stmt.target_idx = successor.idx
|
|
398
|
+
new_last_stmt.target = Const(None, None, successor.addr, self.project.arch.bits)
|
|
399
|
+
new_node = node.copy()
|
|
400
|
+
new_node.statements[-1] = new_last_stmt
|
|
401
|
+
# the last statement is not a jump, but this node should have one, so add it
|
|
402
|
+
else:
|
|
403
|
+
new_node = node.copy()
|
|
404
|
+
new_last_stmt = Jump(
|
|
405
|
+
None, Const(None, None, successor.addr, self.project.arch.bits), target_idx=successor.idx
|
|
406
|
+
)
|
|
407
|
+
# TODO: improve addressing here
|
|
408
|
+
new_last_stmt.tags["ins_addr"] = new_node.addr + 1
|
|
409
|
+
new_node.statements.append(new_last_stmt)
|
|
410
|
+
|
|
411
|
+
elif graph.out_degree(node) == 2:
|
|
412
|
+
last_stmt = node.statements[-1]
|
|
413
|
+
if isinstance(last_stmt, ConditionalJump):
|
|
414
|
+
real_successor_addrs = [_n.addr for _n in graph.successors(node)]
|
|
415
|
+
addr_map = {}
|
|
416
|
+
unmapped_addrs = []
|
|
417
|
+
for target in (last_stmt.true_target, last_stmt.false_target):
|
|
418
|
+
if target.value in real_successor_addrs:
|
|
419
|
+
addr_map[target.value] = target.value
|
|
420
|
+
real_successor_addrs.remove(target.value)
|
|
421
|
+
else:
|
|
422
|
+
unmapped_addrs.append(target.value)
|
|
423
|
+
|
|
424
|
+
# right now we can only correct cases where one edge is incorrect
|
|
425
|
+
if len(real_successor_addrs) == 1 and len(unmapped_addrs) == 1:
|
|
426
|
+
addr_map[unmapped_addrs[0]] = real_successor_addrs[0]
|
|
427
|
+
new_last_stmt = correct_jump_targets(last_stmt, addr_map, new_stmt=True)
|
|
428
|
+
new_node = node.copy()
|
|
429
|
+
new_node.statements[-1] = new_last_stmt
|
|
430
|
+
|
|
431
|
+
new_nodes[node] = new_node
|
|
432
|
+
new_graph.add_node(new_node)
|
|
433
|
+
|
|
434
|
+
for src, dst, data in graph.edges(data=True):
|
|
435
|
+
new_graph.add_edge(new_nodes[src], new_nodes[dst], **data)
|
|
436
|
+
|
|
437
|
+
return new_graph
|
|
438
|
+
|
|
439
|
+
def _construct_best_condition_block_for_merge(self, blocks, graph) -> tuple[Block, Block]:
|
|
440
|
+
# find the conditions that block both of these blocks
|
|
441
|
+
common_cond = self.shared_common_conditional_dom(blocks, graph)
|
|
442
|
+
conditions_by_start = self.collect_conditions_between_nodes(graph, common_cond, blocks)
|
|
443
|
+
|
|
444
|
+
best_condition_pair = None
|
|
445
|
+
for start, condition in conditions_by_start.items():
|
|
446
|
+
if best_condition_pair is None:
|
|
447
|
+
best_condition_pair = (start, condition)
|
|
448
|
+
continue
|
|
449
|
+
|
|
450
|
+
if isinstance(condition, Const):
|
|
451
|
+
continue
|
|
452
|
+
|
|
453
|
+
_, best_cond = best_condition_pair
|
|
454
|
+
if self.boolean_operators_in_condition(condition) < self.boolean_operators_in_condition(best_cond):
|
|
455
|
+
best_condition_pair = start, condition
|
|
456
|
+
|
|
457
|
+
true_block, best_condition = best_condition_pair
|
|
458
|
+
boolean_cnt = self.boolean_operators_in_condition(best_condition)
|
|
459
|
+
if boolean_cnt >= self.max_guarding_conditions:
|
|
460
|
+
self.candidate_blacklist.add(tuple(blocks))
|
|
461
|
+
raise SAILRSemanticError("A condition would be too long for a fixup, this analysis must skip it")
|
|
462
|
+
|
|
463
|
+
cond_block = Block(common_cond.addr, 1, idx=common_cond.idx + 1 if isinstance(common_cond.idx, int) else 1)
|
|
464
|
+
old_stmt_tags = common_cond.statements[0].tags
|
|
465
|
+
cond_jump = ConditionalJump(
|
|
466
|
+
1,
|
|
467
|
+
best_condition.copy() if best_condition is not None else None,
|
|
468
|
+
Const(None, None, 0, self.project.arch.bits),
|
|
469
|
+
Const(None, None, 0, self.project.arch.bits),
|
|
470
|
+
**old_stmt_tags,
|
|
471
|
+
)
|
|
472
|
+
cond_block.statements = [cond_jump]
|
|
473
|
+
|
|
474
|
+
return cond_block, true_block
|
|
475
|
+
|
|
476
|
+
@staticmethod
|
|
477
|
+
def boolean_operators_in_condition(condition: Expression):
|
|
478
|
+
"""
|
|
479
|
+
TODO: this entire boolean checking semantic we use needs to be removed, see how it is used for other dels needed
|
|
480
|
+
we need to replace it with a boolean variable insertion on both branches that lead to the new block
|
|
481
|
+
say we have:
|
|
482
|
+
if (A()) {
|
|
483
|
+
do_thing();
|
|
484
|
+
}
|
|
485
|
+
if (B()) {
|
|
486
|
+
do_thing():
|
|
487
|
+
}
|
|
488
|
+
|
|
489
|
+
We want to translate it to:
|
|
490
|
+
int should_do_thing = 0;
|
|
491
|
+
if (A())
|
|
492
|
+
should_do_thing = 1;
|
|
493
|
+
if (B())
|
|
494
|
+
should_do_thing = 1;
|
|
495
|
+
|
|
496
|
+
if (should_do_thing):
|
|
497
|
+
do_thing();
|
|
498
|
+
|
|
499
|
+
Although longer, this code can be optimized to look like:
|
|
500
|
+
int should_do_thing = A() || B();
|
|
501
|
+
if (should_do_thing)
|
|
502
|
+
do_thing();
|
|
503
|
+
"""
|
|
504
|
+
walker = BooleanCounter()
|
|
505
|
+
walker.walk_expression(condition)
|
|
506
|
+
return walker.boolean_cnt
|
|
507
|
+
|
|
508
|
+
@staticmethod
|
|
509
|
+
def _input_defined_by_other_stmt(target_idx, other_idx, io_finder):
|
|
510
|
+
target_inputs = io_finder.inputs_by_stmt[target_idx]
|
|
511
|
+
# any memory location, not on stack, is not movable
|
|
512
|
+
if any(isinstance(i, MemoryLocation) and not i.is_on_stack for i in target_inputs):
|
|
513
|
+
return True
|
|
514
|
+
|
|
515
|
+
other_outputs = io_finder.outputs_by_stmt[other_idx]
|
|
516
|
+
return target_inputs.intersection(other_outputs)
|
|
517
|
+
|
|
518
|
+
@staticmethod
|
|
519
|
+
def _output_used_by_other_stmt(target_idx, other_idx, io_finder):
|
|
520
|
+
target_output = io_finder.outputs_by_stmt[target_idx]
|
|
521
|
+
# any memory location, not on stack, is not movable
|
|
522
|
+
if any(isinstance(o, MemoryLocation) and not o.is_on_stack for o in target_output):
|
|
523
|
+
return True
|
|
524
|
+
|
|
525
|
+
other_input = io_finder.inputs_by_stmt[other_idx]
|
|
526
|
+
return target_output.intersection(other_input)
|
|
527
|
+
|
|
528
|
+
def stmt_can_move_to(self, stmt, block, new_idx, io_finder=None):
|
|
529
|
+
if stmt not in block.statements:
|
|
530
|
+
raise NotImplementedError("Statement not in block, and we can't compute moving a stmt to a new block!")
|
|
531
|
+
|
|
532
|
+
# jumps of any kind are not moveable
|
|
533
|
+
if (
|
|
534
|
+
new_idx == len(block.statements) - 1 and isinstance(block.statements[new_idx], (ConditionalJump, Jump))
|
|
535
|
+
) or isinstance(stmt, (ConditionalJump, Jump)):
|
|
536
|
+
return False
|
|
537
|
+
|
|
538
|
+
io_finder = io_finder or BlockIOFinder(block, self.project)
|
|
539
|
+
curr_idx = block.statements.index(stmt)
|
|
540
|
+
move_up = new_idx < curr_idx
|
|
541
|
+
|
|
542
|
+
# moving a statement up in the statements:
|
|
543
|
+
# we must check if it's defined by anything above it (lower in index)
|
|
544
|
+
can_move = True
|
|
545
|
+
if move_up:
|
|
546
|
+
# exclude curr_idx in range
|
|
547
|
+
for mid_idx in range(new_idx, curr_idx):
|
|
548
|
+
if self._input_defined_by_other_stmt(curr_idx, mid_idx, io_finder):
|
|
549
|
+
can_move = False
|
|
550
|
+
break
|
|
551
|
+
|
|
552
|
+
# moving a statement down in the statements:
|
|
553
|
+
# we much check if it's used by anything below it (greater in index)
|
|
554
|
+
else:
|
|
555
|
+
for mid_idx in range(curr_idx + 1, new_idx + 1):
|
|
556
|
+
if self._output_used_by_other_stmt(curr_idx, mid_idx, io_finder):
|
|
557
|
+
can_move = False
|
|
558
|
+
break
|
|
559
|
+
|
|
560
|
+
return can_move
|
|
561
|
+
|
|
562
|
+
def maximize_similarity_of_blocks(self, block1, block2, graph) -> tuple[Block, Block]:
|
|
563
|
+
"""
|
|
564
|
+
This attempts to rearrange the order of statements in block1 and block2 to maximize the similarity between them.
|
|
565
|
+
This implementation is a little outdated since CodeMotion optimization was implemented, but it should
|
|
566
|
+
be disabled until we have a good SSA implementation.
|
|
567
|
+
|
|
568
|
+
TODO: reimplement me when we have better SSA
|
|
569
|
+
"""
|
|
570
|
+
new_block1, new_block2 = block1.copy(), block2.copy()
|
|
571
|
+
|
|
572
|
+
updates = True
|
|
573
|
+
prev_moved = set()
|
|
574
|
+
while updates:
|
|
575
|
+
updates = False
|
|
576
|
+
_, lcs_idxs = longest_ail_subseq([new_block1.statements, new_block2.statements])
|
|
577
|
+
lcs_idx_by_block = {new_block1: lcs_idxs[0], new_block2: lcs_idxs[1]}
|
|
578
|
+
if any(v is None for v in lcs_idx_by_block.values()):
|
|
579
|
+
break
|
|
580
|
+
|
|
581
|
+
io_finder_by_block = {
|
|
582
|
+
new_block1: BlockIOFinder(new_block1, self.project),
|
|
583
|
+
new_block2: BlockIOFinder(new_block2, self.project),
|
|
584
|
+
}
|
|
585
|
+
|
|
586
|
+
for search_offset in (-1, 1):
|
|
587
|
+
for b1, b2 in itertools.permutations([new_block1, new_block2], 2):
|
|
588
|
+
if lcs_idx_by_block[b1] + search_offset < 0 or lcs_idx_by_block[b1] + search_offset >= len(
|
|
589
|
+
b1.statements
|
|
590
|
+
):
|
|
591
|
+
continue
|
|
592
|
+
|
|
593
|
+
b1_unmatched = b1.statements[lcs_idx_by_block[b1] + search_offset]
|
|
594
|
+
if b1_unmatched in prev_moved:
|
|
595
|
+
continue
|
|
596
|
+
|
|
597
|
+
unmatched_b2_positions = index_of_similar_stmts([b1_unmatched], b2.statements, all_positions=True)
|
|
598
|
+
if unmatched_b2_positions is None:
|
|
599
|
+
continue
|
|
600
|
+
|
|
601
|
+
# b1_unmatched must be in b2
|
|
602
|
+
for b2_pos in unmatched_b2_positions:
|
|
603
|
+
b2_stmt = b2.statements[b2_pos]
|
|
604
|
+
if b2_stmt in prev_moved:
|
|
605
|
+
continue
|
|
606
|
+
|
|
607
|
+
if b2_pos + search_offset < 0 or b2_pos + search_offset >= len(b2.statements):
|
|
608
|
+
continue
|
|
609
|
+
|
|
610
|
+
# a stmt must be independent to be moveable
|
|
611
|
+
if self.stmt_can_move_to(
|
|
612
|
+
b2_stmt, b2, lcs_idx_by_block[b2] + search_offset, io_finder=io_finder_by_block[b2]
|
|
613
|
+
):
|
|
614
|
+
# prev_stmts = b2.statements.copy()
|
|
615
|
+
b2.statements.remove(b2_stmt)
|
|
616
|
+
b2.statements.insert(lcs_idx_by_block[b2] + search_offset, b2_stmt)
|
|
617
|
+
prev_moved.add(b2_stmt)
|
|
618
|
+
prev_moved.add(b1_unmatched)
|
|
619
|
+
|
|
620
|
+
# new_lcs, _ = longest_ail_subseq([b1.statements, b2.statements])
|
|
621
|
+
## if changes make don't make the lcs longer, revert changes
|
|
622
|
+
# if len(lcs) >= len(new_lcs):
|
|
623
|
+
# b2.statements = prev_stmts
|
|
624
|
+
updates = True
|
|
625
|
+
break
|
|
626
|
+
|
|
627
|
+
if updates:
|
|
628
|
+
break
|
|
629
|
+
if updates:
|
|
630
|
+
break
|
|
631
|
+
else:
|
|
632
|
+
# no updates happen, we are ready to kill this search
|
|
633
|
+
break
|
|
634
|
+
|
|
635
|
+
graph_changed = False
|
|
636
|
+
if new_block1.statements != block1.statements:
|
|
637
|
+
replace_node_in_graph(graph, block1, new_block1)
|
|
638
|
+
graph_changed = True
|
|
639
|
+
|
|
640
|
+
if new_block2.statements != block2.statements:
|
|
641
|
+
replace_node_in_graph(graph, block2, new_block2)
|
|
642
|
+
graph_changed = True
|
|
643
|
+
|
|
644
|
+
if graph_changed:
|
|
645
|
+
return new_block1, new_block2
|
|
646
|
+
|
|
647
|
+
return block1, block2
|
|
648
|
+
|
|
649
|
+
def create_merged_subgraph(self, blocks, graph: nx.DiGraph, maximize_similarity=False) -> AILMergeGraph:
|
|
650
|
+
# Before creating a full graph LCS, optimize the common seq between the starting blocks
|
|
651
|
+
if maximize_similarity:
|
|
652
|
+
# TODO: this is disabled by default right now because it's both slow and incorrect. It should
|
|
653
|
+
# be fixed one day when we have a good SSA implementation. To test this, use the following:
|
|
654
|
+
# https://github.com/mahaloz/sailr-eval/blob/d9f99b3521b60b9a1fd862d106b77e5664a9d175
|
|
655
|
+
# /tests/test_deoptimization.py#L130
|
|
656
|
+
blocks = list(self.maximize_similarity_of_blocks(blocks[0], blocks[1], graph))
|
|
657
|
+
else:
|
|
658
|
+
blocks = list(blocks)
|
|
659
|
+
|
|
660
|
+
# Eliminate all cases that may only have returns (we should do that in a later pass)
|
|
661
|
+
all_only_returns = True
|
|
662
|
+
for block in blocks:
|
|
663
|
+
for stmt in block.statements:
|
|
664
|
+
if not isinstance(stmt, (Return, Label)):
|
|
665
|
+
all_only_returns = False
|
|
666
|
+
break
|
|
667
|
+
if not all_only_returns:
|
|
668
|
+
break
|
|
669
|
+
if all_only_returns:
|
|
670
|
+
self.candidate_blacklist.add(tuple(blocks))
|
|
671
|
+
raise SAILRSemanticError("Both blocks only contain returns, this analysis must skip it")
|
|
672
|
+
|
|
673
|
+
# Traverse both blocks subgraphs within the original graph and find the longest common AIL sequence.
|
|
674
|
+
# Use one of the blocks subraphs to construct the top-half of the new merged graph that contains no inserted
|
|
675
|
+
# conditions yet. This means the graph is still missing the divergence of the two graphs.
|
|
676
|
+
try:
|
|
677
|
+
graph_lcs = longest_ail_graph_subseq(blocks, graph)
|
|
678
|
+
except SAILRSemanticError as e:
|
|
679
|
+
self.candidate_blacklist.add(tuple(blocks))
|
|
680
|
+
raise e
|
|
681
|
+
|
|
682
|
+
ail_merge_graph = AILMergeGraph(original_graph=graph)
|
|
683
|
+
# some blocks in originals may update during this time (if-statements can change)
|
|
684
|
+
update_blocks = ail_merge_graph.create_conditionless_graph(blocks, graph_lcs)
|
|
685
|
+
if update_blocks is None:
|
|
686
|
+
# failed to create the condition-less graph
|
|
687
|
+
self.candidate_blacklist.add(tuple(blocks))
|
|
688
|
+
raise SAILRSemanticError("Failed to create a condition-less graph, this analysis must skip it")
|
|
689
|
+
|
|
690
|
+
#
|
|
691
|
+
# SPECIAL CASE: the merged graph contains only 1 node and no splits
|
|
692
|
+
# allows for an early return without expensive computations
|
|
693
|
+
#
|
|
694
|
+
if len(ail_merge_graph.graph.nodes) == 1 and all(
|
|
695
|
+
not splits for splits in ail_merge_graph.original_split_blocks.values()
|
|
696
|
+
):
|
|
697
|
+
new_node = next(iter(ail_merge_graph.graph.nodes))
|
|
698
|
+
base_successor = next(iter(graph.successors(blocks[0])))
|
|
699
|
+
other_successor = next(iter(graph.successors(blocks[1])))
|
|
700
|
+
conditional_block, true_target = self._construct_best_condition_block_for_merge(blocks, graph)
|
|
701
|
+
if true_target == blocks[0]:
|
|
702
|
+
conditional_block.statements[-1].true_target.value = base_successor.addr
|
|
703
|
+
conditional_block.statements[-1].false_target.value = other_successor.addr
|
|
704
|
+
else:
|
|
705
|
+
conditional_block.statements[-1].true_target.value = other_successor.addr
|
|
706
|
+
conditional_block.statements[-1].false_target.value = base_successor.addr
|
|
707
|
+
|
|
708
|
+
ail_merge_graph.graph.add_edge(new_node, conditional_block)
|
|
709
|
+
return ail_merge_graph
|
|
710
|
+
|
|
711
|
+
# we have now generated the top half of the merge graph. We now need to create a mapping for all the
|
|
712
|
+
# merge_graph blocks to the original blocks from the two targets we are merging. This map will store
|
|
713
|
+
# the AILBlockSplit if it is a split, so we can track preds and succss later.
|
|
714
|
+
merge_end_pairs = ail_merge_graph.create_mapping_to_merge_graph(update_blocks, blocks)
|
|
715
|
+
|
|
716
|
+
# collect the conditions
|
|
717
|
+
# make a new conditional block
|
|
718
|
+
conditional_block, true_target = self._construct_best_condition_block_for_merge(blocks, graph)
|
|
719
|
+
true_target = ail_merge_graph.starts[0] if true_target is blocks[0] else ail_merge_graph.starts[1]
|
|
720
|
+
ail_merge_graph.add_edges_to_condition(conditional_block, true_target, merge_end_pairs)
|
|
721
|
+
|
|
722
|
+
return ail_merge_graph
|
|
723
|
+
|
|
724
|
+
def similar_conditional_when_single_corrected(self, block1: Block, block2: Block, graph: nx.DiGraph):
|
|
725
|
+
cond1, cond2 = block1.statements[-1], block2.statements[-1]
|
|
726
|
+
if not isinstance(cond1, ConditionalJump) or not isinstance(cond2, ConditionalJump):
|
|
727
|
+
return False
|
|
728
|
+
|
|
729
|
+
# conditions must match
|
|
730
|
+
if not cond1.condition.likes(cond2.condition):
|
|
731
|
+
return False
|
|
732
|
+
|
|
733
|
+
# collect the true and false targets for the condition
|
|
734
|
+
block_to_target_map = defaultdict(dict)
|
|
735
|
+
for block, cond in ((block1, cond1), (block2, cond2)):
|
|
736
|
+
for succ in graph.successors(block):
|
|
737
|
+
if succ.addr == cond.true_target.value:
|
|
738
|
+
block_to_target_map[block]["true_target"] = succ
|
|
739
|
+
elif succ.addr == cond.false_target.value:
|
|
740
|
+
block_to_target_map[block]["false_target"] = succ
|
|
741
|
+
else:
|
|
742
|
+
# exit early if you ever can't find a supposed target
|
|
743
|
+
return False
|
|
744
|
+
|
|
745
|
+
# check if at least one block in successors match
|
|
746
|
+
mismatched_blocks = {}
|
|
747
|
+
for target_type in block_to_target_map[block1]:
|
|
748
|
+
t1_blk, t2_blk = block_to_target_map[block1][target_type], block_to_target_map[block2][target_type]
|
|
749
|
+
if not is_similar(t1_blk, t2_blk, partial=True):
|
|
750
|
+
mismatched_blocks[target_type] = {block1: t1_blk, block2: t2_blk}
|
|
751
|
+
|
|
752
|
+
if len(mismatched_blocks) != 1:
|
|
753
|
+
return False
|
|
754
|
+
|
|
755
|
+
# We now know that at least one block matches
|
|
756
|
+
# at this moment we have something that looks like this:
|
|
757
|
+
# A ---> C <--- B
|
|
758
|
+
# | |
|
|
759
|
+
# V V
|
|
760
|
+
# D E
|
|
761
|
+
#
|
|
762
|
+
# A and B both share the same condition, point to a block that is either similar to each
|
|
763
|
+
# other or the same block, AND they have a mismatch block D & E. We want to make a new NOP
|
|
764
|
+
# block that is between A->D and B->E to make a balanced merged graph:
|
|
765
|
+
#
|
|
766
|
+
# A ---> C <--- B
|
|
767
|
+
# | |
|
|
768
|
+
# V V
|
|
769
|
+
# N -> D E <- N'
|
|
770
|
+
#
|
|
771
|
+
# We now will have a balanced merge graph
|
|
772
|
+
for target_type, block_map in mismatched_blocks.items():
|
|
773
|
+
for src, dst in block_map.items():
|
|
774
|
+
# create a new nop block
|
|
775
|
+
nop_blk = Block(
|
|
776
|
+
self.new_block_addr(),
|
|
777
|
+
0,
|
|
778
|
+
statements=[Jump(0, Const(0, 0, 0, self.project.arch.bits), 0, ins_addr=self.new_block_addr())],
|
|
779
|
+
)
|
|
780
|
+
# point src -> nop -> dst
|
|
781
|
+
graph.add_edge(src, nop_blk)
|
|
782
|
+
graph.add_edge(nop_blk, dst)
|
|
783
|
+
# unlink src -X-> dst
|
|
784
|
+
graph.remove_edge(src, dst)
|
|
785
|
+
# correct the targets of the src
|
|
786
|
+
target = getattr(src.statements[-1], target_type)
|
|
787
|
+
target.value = nop_blk.addr
|
|
788
|
+
|
|
789
|
+
return True
|
|
790
|
+
|
|
791
|
+
@staticmethod
|
|
792
|
+
def _has_single_successor_path(source, target, graph):
|
|
793
|
+
if source not in graph or target not in graph:
|
|
794
|
+
return []
|
|
795
|
+
|
|
796
|
+
if not nx.has_path(graph, source, target):
|
|
797
|
+
return []
|
|
798
|
+
|
|
799
|
+
for simple_path in nx.all_simple_paths(graph, source, target, cutoff=10):
|
|
800
|
+
for node in simple_path:
|
|
801
|
+
if node is target or node is source:
|
|
802
|
+
continue
|
|
803
|
+
if graph.out_degree(node) != 1:
|
|
804
|
+
break
|
|
805
|
+
else:
|
|
806
|
+
if simple_path[-1] is target:
|
|
807
|
+
return simple_path
|
|
808
|
+
|
|
809
|
+
return []
|
|
810
|
+
|
|
811
|
+
def _block_has_goto_edge(self, block: ailment.Block, other_ends, graph=None):
|
|
812
|
+
# case1:
|
|
813
|
+
# A -> (goto) -> B.
|
|
814
|
+
# if goto edge coming from end block, from any instruction in the block
|
|
815
|
+
# since instructions can shift...
|
|
816
|
+
last_stmt = block.statements[-1]
|
|
817
|
+
|
|
818
|
+
gotos = self._goto_manager.gotos_in_block(block)
|
|
819
|
+
for goto in gotos:
|
|
820
|
+
target_block = find_block_in_successors_by_addr(goto.dst_addr, block, graph)
|
|
821
|
+
if any(self._has_single_successor_path(end, target_block, graph) for end in other_ends):
|
|
822
|
+
return True
|
|
823
|
+
|
|
824
|
+
# case2:
|
|
825
|
+
# A.last (conditional) -> (goto) -> B -> C
|
|
826
|
+
#
|
|
827
|
+
# Some condition ends in a goto to one of the ends of the merge graph. In this case,
|
|
828
|
+
# we consider it a modified version of case2
|
|
829
|
+
if graph:
|
|
830
|
+
for pred in graph.predecessors(block):
|
|
831
|
+
last_stmt = pred.statements[-1]
|
|
832
|
+
if isinstance(last_stmt, ConditionalJump):
|
|
833
|
+
gotos = self._goto_manager.gotos_in_block(pred)
|
|
834
|
+
# TODO: this is only valid for duplication reverter, but it should be better
|
|
835
|
+
if gotos and block.idx is not None:
|
|
836
|
+
return True
|
|
837
|
+
|
|
838
|
+
for goto in gotos:
|
|
839
|
+
if goto.dst_addr in (block.addr, block.statements[0].tags["ins_addr"]):
|
|
840
|
+
return True
|
|
841
|
+
|
|
842
|
+
for succ in graph.successors(block):
|
|
843
|
+
last_stmt = succ.statements[-1]
|
|
844
|
+
if isinstance(last_stmt, ConditionalJump):
|
|
845
|
+
gotos = self._goto_manager.gotos_in_block(succ)
|
|
846
|
+
# TODO: this is only valid for duplication reverter, but it should be better
|
|
847
|
+
if gotos and block.idx is not None:
|
|
848
|
+
return True
|
|
849
|
+
|
|
850
|
+
for goto in gotos:
|
|
851
|
+
for other_end in other_ends:
|
|
852
|
+
found = False
|
|
853
|
+
for other_succ in graph.successors(other_end):
|
|
854
|
+
if other_succ.addr == goto.dst_addr:
|
|
855
|
+
found = True
|
|
856
|
+
|
|
857
|
+
if not found:
|
|
858
|
+
break
|
|
859
|
+
|
|
860
|
+
return False
|
|
861
|
+
|
|
862
|
+
def _find_future_irreducible_gotos(self, max_endpoint_distance=5):
|
|
863
|
+
"""
|
|
864
|
+
Checks if these gotos could be fixed by eager returns
|
|
865
|
+
"""
|
|
866
|
+
endnodes = [node for node in self.out_graph.nodes() if self.out_graph.out_degree[node] == 0]
|
|
867
|
+
blocks_by_addr = {blk.addr: blk for blk in self.out_graph.nodes()}
|
|
868
|
+
|
|
869
|
+
bad_gotos = set()
|
|
870
|
+
for goto in self._goto_manager.gotos:
|
|
871
|
+
goto_end_block = blocks_by_addr.get(goto.dst_addr, None)
|
|
872
|
+
# skip gotos that don't exist
|
|
873
|
+
if not goto_end_block:
|
|
874
|
+
continue
|
|
875
|
+
|
|
876
|
+
# if a goto end is an endnode, then this is good! Skip it!
|
|
877
|
+
if goto_end_block in endnodes:
|
|
878
|
+
continue
|
|
879
|
+
|
|
880
|
+
connects_endnode = False
|
|
881
|
+
for endnode in endnodes:
|
|
882
|
+
if (
|
|
883
|
+
goto_end_block in self.out_graph
|
|
884
|
+
and endnode in self.out_graph
|
|
885
|
+
and nx.has_path(self.out_graph, goto_end_block, endnode)
|
|
886
|
+
):
|
|
887
|
+
try:
|
|
888
|
+
next(nx.all_simple_paths(self.out_graph, goto_end_block, endnode, cutoff=max_endpoint_distance))
|
|
889
|
+
except StopIteration:
|
|
890
|
+
continue
|
|
891
|
+
|
|
892
|
+
# if we are here, a path exists
|
|
893
|
+
connects_endnode = True
|
|
894
|
+
break
|
|
895
|
+
|
|
896
|
+
# if goto is connected, great, skip it!
|
|
897
|
+
if connects_endnode:
|
|
898
|
+
continue
|
|
899
|
+
|
|
900
|
+
# if we are here, this goto is non_reducible
|
|
901
|
+
bad_gotos.add(goto)
|
|
902
|
+
|
|
903
|
+
return bad_gotos
|
|
904
|
+
|
|
905
|
+
def collect_conditions_between_nodes(self, graph, source: Block, sinks: list[Block], max_depth=15):
|
|
906
|
+
graph_nodes = set(sinks)
|
|
907
|
+
for sink in set(sinks):
|
|
908
|
+
# we need to cutoff the maximum number of nodes that can be included in this search
|
|
909
|
+
paths_between = nx.all_simple_paths(graph, source=source, target=sink, cutoff=max_depth)
|
|
910
|
+
graph_nodes.update({node for path in paths_between for node in path})
|
|
911
|
+
|
|
912
|
+
full_condition_graph: nx.DiGraph = nx.DiGraph(nx.subgraph(graph, graph_nodes))
|
|
913
|
+
|
|
914
|
+
# destroy any edges which go to what is supposed to be the start node of the graph
|
|
915
|
+
# which in effect removes loops (hopefully)
|
|
916
|
+
while True:
|
|
917
|
+
try:
|
|
918
|
+
cycles = nx.find_cycle(full_condition_graph)
|
|
919
|
+
except nx.NetworkXNoCycle:
|
|
920
|
+
break
|
|
921
|
+
|
|
922
|
+
full_condition_graph.remove_edge(*cycles[0])
|
|
923
|
+
|
|
924
|
+
# now that we have a full target graph, we want to know the condensed conditions that allow
|
|
925
|
+
# control flow to get to that target end. We get the reaching conditions to construct a guarding
|
|
926
|
+
# node later
|
|
927
|
+
self._ri.cond_proc.recover_reaching_conditions(None, graph=full_condition_graph)
|
|
928
|
+
conditions_by_start = {}
|
|
929
|
+
for sink in sinks:
|
|
930
|
+
if sink in self._ri.cond_proc.guarding_conditions:
|
|
931
|
+
condition = self._ri.cond_proc.guarding_conditions[sink]
|
|
932
|
+
elif sink in self._ri.cond_proc.reaching_conditions:
|
|
933
|
+
condition = self._ri.cond_proc.reaching_conditions[sink]
|
|
934
|
+
else:
|
|
935
|
+
# TODO: this should be better fixed
|
|
936
|
+
self.candidate_blacklist.add(tuple(sinks))
|
|
937
|
+
raise SAILRSemanticError(
|
|
938
|
+
f"Unable to find the conditions for target: {sink}. "
|
|
939
|
+
f"This is likely caused by unsupported statements, like Switches, being in the graph."
|
|
940
|
+
)
|
|
941
|
+
|
|
942
|
+
condition = self._ri.cond_proc.simplify_condition(condition)
|
|
943
|
+
if condition.is_true() or condition.is_false():
|
|
944
|
+
condition = self._ri.cond_proc.simplify_condition(self._ri.cond_proc.reaching_conditions[sink])
|
|
945
|
+
|
|
946
|
+
conditions_by_start[sink] = self._ri.cond_proc.convert_claripy_bool_ast(condition)
|
|
947
|
+
|
|
948
|
+
return conditions_by_start
|
|
949
|
+
|
|
950
|
+
#
|
|
951
|
+
# Search Stages
|
|
952
|
+
#
|
|
953
|
+
|
|
954
|
+
def _share_subregion(self, blocks: list[Block]) -> bool:
|
|
955
|
+
return any(
|
|
956
|
+
all((block.addr, block.idx) in region for block in blocks) for region in self._ri.regions_by_block_addrs
|
|
957
|
+
)
|
|
958
|
+
|
|
959
|
+
def _is_valid_candidate(self, b0, b1):
|
|
960
|
+
# blocks must have statements
|
|
961
|
+
if not b0.statements or not b1.statements:
|
|
962
|
+
return False
|
|
963
|
+
|
|
964
|
+
# blocks must share a region
|
|
965
|
+
if not self._share_subregion([b0, b1]):
|
|
966
|
+
return False
|
|
967
|
+
|
|
968
|
+
# if not self.shared_common_conditional_dom([b0, b1], self.read_graph):
|
|
969
|
+
# return False
|
|
970
|
+
|
|
971
|
+
stmt_in_common = False
|
|
972
|
+
# special case: when we only have a single stmt
|
|
973
|
+
if len(b0.statements) == len(b1.statements) == 1:
|
|
974
|
+
# Case 1:
|
|
975
|
+
# [if(a)] == [if(b)]
|
|
976
|
+
#
|
|
977
|
+
# we must use the more expensive `similar` function to tell on the graph if they are
|
|
978
|
+
# stmts that result in the same successors
|
|
979
|
+
stmt_is_similar = is_similar(b0, b1, graph=self.read_graph)
|
|
980
|
+
|
|
981
|
+
# Case 2:
|
|
982
|
+
# [if(a)] == [if(a)]
|
|
983
|
+
# and at least one child for the correct target type matches
|
|
984
|
+
# TODO: this not not yet supported
|
|
985
|
+
|
|
986
|
+
# update ether we resolved in the above cases
|
|
987
|
+
if stmt_is_similar:
|
|
988
|
+
stmt_in_common = True
|
|
989
|
+
else:
|
|
990
|
+
# check if these nodes share any stmt in common
|
|
991
|
+
for stmt0 in b0.statements:
|
|
992
|
+
# jumps don't count
|
|
993
|
+
if isinstance(stmt0, Jump):
|
|
994
|
+
continue
|
|
995
|
+
|
|
996
|
+
# Most Assignments don't count just by themselves:
|
|
997
|
+
# register = register
|
|
998
|
+
# TOP = const | register
|
|
999
|
+
if isinstance(stmt0, Assignment):
|
|
1000
|
+
src = stmt0.src.operand if isinstance(stmt0.dst, Convert) else stmt0.src
|
|
1001
|
+
if (
|
|
1002
|
+
isinstance(src, Register)
|
|
1003
|
+
or (isinstance(src, VirtualVariable) and src.was_reg)
|
|
1004
|
+
or (isinstance(src, Const) and src.bits > 2)
|
|
1005
|
+
):
|
|
1006
|
+
continue
|
|
1007
|
+
|
|
1008
|
+
for stmt1 in b1.statements:
|
|
1009
|
+
if is_similar(stmt0, stmt1, graph=self.write_graph):
|
|
1010
|
+
stmt_in_common = True
|
|
1011
|
+
break
|
|
1012
|
+
|
|
1013
|
+
if stmt_in_common:
|
|
1014
|
+
break
|
|
1015
|
+
|
|
1016
|
+
# must share a common dominator
|
|
1017
|
+
return stmt_in_common and self.shared_common_conditional_dom((b0, b1), self.write_graph) is not None
|
|
1018
|
+
|
|
1019
|
+
@staticmethod
|
|
1020
|
+
def _construct_goto_related_subgraph(base: Block, graph: nx.DiGraph, max_ancestors=5):
|
|
1021
|
+
"""
|
|
1022
|
+
Creates a subgraph of the large graph starting from the base block and working upwards (predecessors)
|
|
1023
|
+
for max_ancestors amount of nodes
|
|
1024
|
+
"""
|
|
1025
|
+
blocks = [base]
|
|
1026
|
+
level_blocks = [base]
|
|
1027
|
+
block_lvls = {base: 0}
|
|
1028
|
+
new_level_blocks = []
|
|
1029
|
+
for lvl in range(max_ancestors):
|
|
1030
|
+
new_level_blocks = []
|
|
1031
|
+
for lblock in level_blocks:
|
|
1032
|
+
block_lvls[lblock] = lvl + 1
|
|
1033
|
+
new_level_blocks += sorted(graph.predecessors(lblock))
|
|
1034
|
+
|
|
1035
|
+
blocks += new_level_blocks
|
|
1036
|
+
level_blocks = new_level_blocks
|
|
1037
|
+
|
|
1038
|
+
# collect last level blocks
|
|
1039
|
+
if new_level_blocks:
|
|
1040
|
+
for new_block in new_level_blocks:
|
|
1041
|
+
if new_block in block_lvls:
|
|
1042
|
+
continue
|
|
1043
|
+
|
|
1044
|
+
block_lvls[new_block] = max_ancestors + 1
|
|
1045
|
+
|
|
1046
|
+
# construct the final subgraph
|
|
1047
|
+
g = nx.subgraph(graph, blocks)
|
|
1048
|
+
return g, block_lvls
|
|
1049
|
+
|
|
1050
|
+
def _find_initial_candidates(self) -> list[tuple[Block, Block]]:
|
|
1051
|
+
"""
|
|
1052
|
+
Here is how
|
|
1053
|
+
"""
|
|
1054
|
+
# first, find all the goto edges, since these locations will always be the base of the merge
|
|
1055
|
+
# graph we create; therefore, we only need search around gotos
|
|
1056
|
+
goto_edges = sorted(self._goto_manager.find_goto_edges(self.read_graph))
|
|
1057
|
+
|
|
1058
|
+
candidates = []
|
|
1059
|
+
for goto_src, goto_dst in goto_edges:
|
|
1060
|
+
candidate_subgraph, dist_by_block = self._construct_goto_related_subgraph(goto_dst, self.read_graph)
|
|
1061
|
+
goto_candidates = []
|
|
1062
|
+
for b0, b1 in combinations(candidate_subgraph, 2):
|
|
1063
|
+
if self._is_valid_candidate(b0, b1):
|
|
1064
|
+
pair = tuple(sorted([b0, b1]))
|
|
1065
|
+
goto_candidates.append(pair)
|
|
1066
|
+
|
|
1067
|
+
# eliminate any that are already blacklisted
|
|
1068
|
+
goto_candidates = [c for c in goto_candidates if c not in self.candidate_blacklist]
|
|
1069
|
+
# re-sort candidates by address (for tiebreakers)
|
|
1070
|
+
goto_candidates = sorted(goto_candidates, reverse=True)
|
|
1071
|
+
|
|
1072
|
+
# choose only a single candidate for this goto, make it the one nearest to the head
|
|
1073
|
+
best = None
|
|
1074
|
+
best_dist = None
|
|
1075
|
+
for b0, b1 in goto_candidates:
|
|
1076
|
+
if best is None:
|
|
1077
|
+
best = (b0, b1)
|
|
1078
|
+
best_dist = dist_by_block[b0] + dist_by_block[b1]
|
|
1079
|
+
continue
|
|
1080
|
+
|
|
1081
|
+
total_dist = dist_by_block[b0] + dist_by_block[b1]
|
|
1082
|
+
if total_dist > best_dist:
|
|
1083
|
+
best = (b0, b1)
|
|
1084
|
+
|
|
1085
|
+
if best is not None:
|
|
1086
|
+
if best == (goto_src, goto_dst)[::-1]:
|
|
1087
|
+
# just flip it to normalize
|
|
1088
|
+
best = best[::-1]
|
|
1089
|
+
|
|
1090
|
+
candidates.append(best)
|
|
1091
|
+
|
|
1092
|
+
return sorted(set(candidates))
|
|
1093
|
+
|
|
1094
|
+
def _filter_candidates(self, candidates, merge_candidates=True):
|
|
1095
|
+
"""
|
|
1096
|
+
Preform a series of filters on the candidates to reduce the fast set to an assured set of
|
|
1097
|
+
the duplication case we are searching for.
|
|
1098
|
+
"""
|
|
1099
|
+
|
|
1100
|
+
#
|
|
1101
|
+
# filter out bad candidates from the blacklist
|
|
1102
|
+
#
|
|
1103
|
+
|
|
1104
|
+
filted_candidates = []
|
|
1105
|
+
id_blacklist = {((b0.addr, b0.idx), (b1.addr, b1.idx)) for b1, b0 in self.candidate_blacklist}
|
|
1106
|
+
for candidate in candidates:
|
|
1107
|
+
blk_id = ((candidate[0].addr, candidate[0].idx), (candidate[1].addr, candidate[1].idx))
|
|
1108
|
+
rev_blk_id = blk_id[::-1]
|
|
1109
|
+
if blk_id not in id_blacklist and rev_blk_id not in id_blacklist:
|
|
1110
|
+
filted_candidates.append(candidate)
|
|
1111
|
+
candidates = filted_candidates
|
|
1112
|
+
|
|
1113
|
+
# when enabled, attempts to merge candidates
|
|
1114
|
+
if merge_candidates:
|
|
1115
|
+
#
|
|
1116
|
+
# Now, merge pairs that may actually be n-pairs. This will look like multiple pairs having a single
|
|
1117
|
+
# block in common, and have one or more statements in common.
|
|
1118
|
+
#
|
|
1119
|
+
|
|
1120
|
+
not_fixed = True
|
|
1121
|
+
while not_fixed:
|
|
1122
|
+
not_fixed = False
|
|
1123
|
+
queued = set()
|
|
1124
|
+
merged_candidates = []
|
|
1125
|
+
|
|
1126
|
+
# no merging needs to be done, there is only one candidate left
|
|
1127
|
+
if len(candidates) == 1:
|
|
1128
|
+
break
|
|
1129
|
+
|
|
1130
|
+
for can0 in candidates:
|
|
1131
|
+
# skip candidates being merged
|
|
1132
|
+
if can0 in queued:
|
|
1133
|
+
continue
|
|
1134
|
+
|
|
1135
|
+
for can1 in candidates:
|
|
1136
|
+
if can0 == can1 or can1 in queued:
|
|
1137
|
+
continue
|
|
1138
|
+
|
|
1139
|
+
# only try a merge if candidates share a node in common
|
|
1140
|
+
if not set(can0).intersection(set(can1)):
|
|
1141
|
+
continue
|
|
1142
|
+
|
|
1143
|
+
lcs, _ = longest_ail_subseq([b.statements for b in set(can0 + can1)])
|
|
1144
|
+
if not lcs:
|
|
1145
|
+
continue
|
|
1146
|
+
|
|
1147
|
+
merged_candidates.append(tuple(set(can0 + can1)))
|
|
1148
|
+
queued.add(can0)
|
|
1149
|
+
queued.add(can1)
|
|
1150
|
+
not_fixed |= True
|
|
1151
|
+
break
|
|
1152
|
+
|
|
1153
|
+
remaining_candidates = []
|
|
1154
|
+
for can in candidates:
|
|
1155
|
+
for m_can in merged_candidates:
|
|
1156
|
+
if not all(blk not in m_can for blk in can):
|
|
1157
|
+
break
|
|
1158
|
+
else:
|
|
1159
|
+
remaining_candidates.append(can)
|
|
1160
|
+
|
|
1161
|
+
candidates = merged_candidates + remaining_candidates
|
|
1162
|
+
|
|
1163
|
+
candidates = list(set(candidates))
|
|
1164
|
+
candidates = [tuple(sorted(candidate)) for candidate in candidates]
|
|
1165
|
+
candidates = sorted(candidates)
|
|
1166
|
+
|
|
1167
|
+
return candidates
|
|
1168
|
+
|
|
1169
|
+
def shared_common_conditional_dom(self, nodes, graph: nx.DiGraph):
|
|
1170
|
+
"""
|
|
1171
|
+
Takes n nodes and returns True only if all the nodes are dominated by the same node, which must be
|
|
1172
|
+
a ConditionalJump
|
|
1173
|
+
|
|
1174
|
+
@param nodes:
|
|
1175
|
+
@param graph:
|
|
1176
|
+
@return:
|
|
1177
|
+
"""
|
|
1178
|
+
|
|
1179
|
+
if graph not in self._entry_node_cache:
|
|
1180
|
+
entry_blocks = [node for node in graph.nodes if graph.in_degree(node) == 0]
|
|
1181
|
+
entry_block = None if len(entry_blocks) != 1 else entry_blocks[0]
|
|
1182
|
+
|
|
1183
|
+
if entry_block is None:
|
|
1184
|
+
return None
|
|
1185
|
+
self._entry_node_cache[graph] = entry_block
|
|
1186
|
+
|
|
1187
|
+
entry_blk = self._entry_node_cache[graph]
|
|
1188
|
+
|
|
1189
|
+
if graph not in self._idom_cache:
|
|
1190
|
+
self._idom_cache[graph] = nx.algorithms.immediate_dominators(graph, entry_blk)
|
|
1191
|
+
|
|
1192
|
+
idoms = self._idom_cache[graph]
|
|
1193
|
+
|
|
1194
|
+
# first check if any of the node pairs could be a dominating loop
|
|
1195
|
+
b0, b1 = nodes[:]
|
|
1196
|
+
if dominates(idoms, b0, b1) or dominates(idoms, b1, b0):
|
|
1197
|
+
return None
|
|
1198
|
+
|
|
1199
|
+
node = nodes[0]
|
|
1200
|
+
node_level = [node]
|
|
1201
|
+
seen_nodes = set()
|
|
1202
|
+
while node_level:
|
|
1203
|
+
# check if any of the nodes on the current level are dominators to all nodes
|
|
1204
|
+
for cnode in node_level:
|
|
1205
|
+
if not cnode.statements:
|
|
1206
|
+
continue
|
|
1207
|
+
|
|
1208
|
+
if (
|
|
1209
|
+
isinstance(cnode.statements[-1], ConditionalJump)
|
|
1210
|
+
and all(dominates(idoms, cnode, node) for node in nodes)
|
|
1211
|
+
and cnode not in nodes
|
|
1212
|
+
):
|
|
1213
|
+
return cnode
|
|
1214
|
+
|
|
1215
|
+
# if no dominators found, move up a level
|
|
1216
|
+
seen_nodes.update(set(node_level))
|
|
1217
|
+
next_level = itertools.chain.from_iterable([sorted(graph.predecessors(cnode)) for cnode in node_level])
|
|
1218
|
+
# only add nodes we have never seen
|
|
1219
|
+
node_level = set(next_level).difference(seen_nodes)
|
|
1220
|
+
|
|
1221
|
+
return None
|