angr 9.2.117__py3-none-win_amd64.whl → 9.2.119__py3-none-win_amd64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of angr might be problematic. Click here for more details.
- angr/__init__.py +2 -1
- angr/__main__.py +21 -1
- angr/analyses/__init__.py +4 -0
- angr/analyses/analysis.py +88 -46
- angr/analyses/backward_slice.py +15 -18
- angr/analyses/binary_optimizer.py +29 -34
- angr/analyses/bindiff.py +35 -44
- angr/analyses/boyscout.py +1 -0
- angr/analyses/callee_cleanup_finder.py +3 -4
- angr/analyses/calling_convention.py +98 -98
- angr/analyses/cdg.py +5 -12
- angr/analyses/cfg/__init__.py +1 -0
- angr/analyses/cfg/cfb.py +14 -20
- angr/analyses/cfg/cfg.py +2 -1
- angr/analyses/cfg/cfg_arch_options.py +4 -1
- angr/analyses/cfg/cfg_base.py +122 -165
- angr/analyses/cfg/cfg_emulated.py +60 -92
- angr/analyses/cfg/cfg_fast.py +406 -335
- angr/analyses/cfg/cfg_fast_soot.py +10 -17
- angr/analyses/cfg/cfg_job_base.py +6 -7
- angr/analyses/cfg/indirect_jump_resolvers/__init__.py +1 -0
- angr/analyses/cfg/indirect_jump_resolvers/amd64_elf_got.py +2 -3
- angr/analyses/cfg/indirect_jump_resolvers/amd64_pe_iat.py +2 -3
- angr/analyses/cfg/indirect_jump_resolvers/arm_elf_fast.py +6 -8
- angr/analyses/cfg/indirect_jump_resolvers/const_resolver.py +3 -5
- angr/analyses/cfg/indirect_jump_resolvers/default_resolvers.py +1 -0
- angr/analyses/cfg/indirect_jump_resolvers/jumptable.py +97 -112
- angr/analyses/cfg/indirect_jump_resolvers/mips_elf_fast.py +26 -32
- angr/analyses/cfg/indirect_jump_resolvers/propagator_utils.py +1 -0
- angr/analyses/cfg/indirect_jump_resolvers/resolver.py +7 -7
- angr/analyses/cfg/indirect_jump_resolvers/x86_elf_pic_plt.py +3 -8
- angr/analyses/cfg/indirect_jump_resolvers/x86_pe_iat.py +2 -3
- angr/analyses/cfg_slice_to_sink/__init__.py +1 -0
- angr/analyses/cfg_slice_to_sink/cfg_slice_to_sink.py +4 -4
- angr/analyses/cfg_slice_to_sink/graph.py +4 -1
- angr/analyses/cfg_slice_to_sink/transitions.py +4 -2
- angr/analyses/class_identifier.py +1 -0
- angr/analyses/code_tagging.py +9 -9
- angr/analyses/complete_calling_conventions.py +28 -36
- angr/analyses/congruency_check.py +6 -11
- angr/analyses/data_dep/__init__.py +1 -0
- angr/analyses/data_dep/data_dependency_analysis.py +38 -48
- angr/analyses/data_dep/dep_nodes.py +13 -12
- angr/analyses/data_dep/sim_act_location.py +3 -0
- angr/analyses/datagraph_meta.py +7 -7
- angr/analyses/ddg.py +48 -69
- angr/analyses/decompiler/__init__.py +3 -0
- angr/analyses/decompiler/ail_simplifier.py +929 -400
- angr/analyses/decompiler/ailgraph_walker.py +1 -0
- angr/analyses/decompiler/block_io_finder.py +13 -4
- angr/analyses/decompiler/block_similarity.py +28 -18
- angr/analyses/decompiler/block_simplifier.py +40 -104
- angr/analyses/decompiler/callsite_maker.py +124 -82
- angr/analyses/decompiler/ccall_rewriters/__init__.py +1 -0
- angr/analyses/decompiler/ccall_rewriters/amd64_ccalls.py +115 -105
- angr/analyses/decompiler/ccall_rewriters/rewriter_base.py +2 -1
- angr/analyses/decompiler/clinic.py +371 -184
- angr/analyses/decompiler/condition_processor.py +127 -116
- angr/analyses/decompiler/counters/__init__.py +5 -0
- angr/analyses/decompiler/counters/boolean_counter.py +27 -0
- angr/analyses/decompiler/{call_counter.py → counters/call_counter.py} +5 -4
- angr/analyses/decompiler/{expression_counters.py → counters/expression_counters.py} +5 -4
- angr/analyses/decompiler/counters/seq_cf_structure_counter.py +63 -0
- angr/analyses/decompiler/decompilation_cache.py +2 -1
- angr/analyses/decompiler/decompilation_options.py +1 -0
- angr/analyses/decompiler/decompiler.py +50 -27
- angr/analyses/decompiler/dephication/__init__.py +6 -0
- angr/analyses/decompiler/dephication/dephication_base.py +87 -0
- angr/analyses/decompiler/dephication/graph_dephication.py +63 -0
- angr/analyses/decompiler/dephication/graph_rewriting.py +116 -0
- angr/analyses/decompiler/dephication/graph_vvar_mapping.py +313 -0
- angr/analyses/decompiler/dephication/rewriting_engine.py +247 -0
- angr/analyses/decompiler/dephication/seqnode_dephication.py +106 -0
- angr/analyses/decompiler/empty_node_remover.py +1 -0
- angr/analyses/decompiler/expression_narrower.py +12 -17
- angr/analyses/decompiler/goto_manager.py +43 -4
- angr/analyses/decompiler/graph_region.py +19 -31
- angr/analyses/decompiler/jump_target_collector.py +1 -0
- angr/analyses/decompiler/jumptable_entry_condition_rewriter.py +2 -1
- angr/analyses/decompiler/optimization_passes/__init__.py +7 -3
- angr/analyses/decompiler/optimization_passes/base_ptr_save_simplifier.py +23 -18
- angr/analyses/decompiler/optimization_passes/call_stmt_rewriter.py +46 -0
- angr/analyses/decompiler/optimization_passes/code_motion.py +4 -2
- angr/analyses/decompiler/optimization_passes/const_derefs.py +36 -36
- angr/analyses/decompiler/optimization_passes/const_prop_reverter.py +6 -9
- angr/analyses/decompiler/optimization_passes/cross_jump_reverter.py +4 -3
- angr/analyses/decompiler/optimization_passes/deadblock_remover.py +1 -0
- angr/analyses/decompiler/optimization_passes/div_simplifier.py +78 -72
- angr/analyses/decompiler/optimization_passes/duplication_reverter/__init__.py +2 -0
- angr/analyses/decompiler/optimization_passes/duplication_reverter/ail_merge_graph.py +503 -0
- angr/analyses/decompiler/optimization_passes/duplication_reverter/duplication_reverter.py +1215 -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 +169 -0
- angr/analyses/decompiler/optimization_passes/engine_base.py +60 -63
- angr/analyses/decompiler/optimization_passes/expr_op_swapper.py +6 -7
- angr/analyses/decompiler/optimization_passes/flip_boolean_cmp.py +1 -0
- angr/analyses/decompiler/optimization_passes/inlined_string_transformation_simplifier.py +102 -37
- angr/analyses/decompiler/optimization_passes/ite_expr_converter.py +8 -10
- angr/analyses/decompiler/optimization_passes/ite_region_converter.py +128 -18
- angr/analyses/decompiler/optimization_passes/lowered_switch_simplifier.py +142 -145
- angr/analyses/decompiler/optimization_passes/mod_simplifier.py +27 -23
- angr/analyses/decompiler/optimization_passes/multi_simplifier.py +30 -34
- angr/analyses/decompiler/optimization_passes/optimization_pass.py +108 -47
- angr/analyses/decompiler/optimization_passes/register_save_area_simplifier.py +10 -3
- angr/analyses/decompiler/optimization_passes/ret_addr_save_simplifier.py +5 -6
- angr/analyses/decompiler/optimization_passes/ret_deduplicator.py +3 -2
- angr/analyses/decompiler/optimization_passes/return_duplicator_base.py +125 -13
- angr/analyses/decompiler/optimization_passes/return_duplicator_high.py +1 -0
- angr/analyses/decompiler/optimization_passes/return_duplicator_low.py +3 -2
- angr/analyses/decompiler/optimization_passes/stack_canary_simplifier.py +52 -21
- angr/analyses/decompiler/optimization_passes/switch_default_case_duplicator.py +3 -2
- angr/analyses/decompiler/optimization_passes/win_stack_canary_simplifier.py +47 -36
- angr/analyses/decompiler/optimization_passes/x86_gcc_getpc_simplifier.py +2 -1
- angr/analyses/decompiler/peephole_optimizations/__init__.py +2 -0
- angr/analyses/decompiler/peephole_optimizations/a_div_const_add_a_mul_n_div_const.py +26 -22
- angr/analyses/decompiler/peephole_optimizations/a_mul_const_div_shr_const.py +2 -2
- angr/analyses/decompiler/peephole_optimizations/a_shl_const_sub_a.py +1 -0
- angr/analyses/decompiler/peephole_optimizations/a_sub_a_div.py +2 -2
- angr/analyses/decompiler/peephole_optimizations/a_sub_a_div_const_mul_const.py +1 -0
- angr/analyses/decompiler/peephole_optimizations/a_sub_a_sub_n.py +8 -4
- angr/analyses/decompiler/peephole_optimizations/arm_cmpf.py +28 -27
- angr/analyses/decompiler/peephole_optimizations/base.py +17 -20
- angr/analyses/decompiler/peephole_optimizations/basepointeroffset_add_n.py +1 -0
- angr/analyses/decompiler/peephole_optimizations/basepointeroffset_and_mask.py +1 -0
- angr/analyses/decompiler/peephole_optimizations/bitwise_or_to_logical_or.py +2 -2
- angr/analyses/decompiler/peephole_optimizations/bool_expr_xor_1.py +2 -2
- angr/analyses/decompiler/peephole_optimizations/bswap.py +29 -22
- angr/analyses/decompiler/peephole_optimizations/cmpord_rewriter.py +3 -4
- angr/analyses/decompiler/peephole_optimizations/coalesce_adjacent_shrs.py +39 -0
- angr/analyses/decompiler/peephole_optimizations/coalesce_same_cascading_ifs.py +2 -1
- angr/analyses/decompiler/peephole_optimizations/const_mull_a_shift.py +94 -29
- angr/analyses/decompiler/peephole_optimizations/constant_derefs.py +1 -0
- angr/analyses/decompiler/peephole_optimizations/conv_a_sub0_shr_and.py +48 -49
- angr/analyses/decompiler/peephole_optimizations/conv_shl_shr.py +1 -0
- angr/analyses/decompiler/peephole_optimizations/eager_eval.py +41 -34
- angr/analyses/decompiler/peephole_optimizations/extended_byte_and_mask.py +2 -1
- angr/analyses/decompiler/peephole_optimizations/inlined_strcpy.py +28 -18
- angr/analyses/decompiler/peephole_optimizations/inlined_strcpy_consolidation.py +8 -4
- angr/analyses/decompiler/peephole_optimizations/inlined_wstrcpy.py +28 -18
- angr/analyses/decompiler/peephole_optimizations/invert_negated_logical_conjuction_disjunction.py +32 -32
- angr/analyses/decompiler/peephole_optimizations/one_sub_bool.py +2 -2
- angr/analyses/decompiler/peephole_optimizations/remove_cascading_conversions.py +23 -3
- angr/analyses/decompiler/peephole_optimizations/remove_empty_if_body.py +2 -1
- angr/analyses/decompiler/peephole_optimizations/remove_noop_conversions.py +4 -0
- angr/analyses/decompiler/peephole_optimizations/remove_redundant_bitmasks.py +1 -0
- angr/analyses/decompiler/peephole_optimizations/remove_redundant_conversions.py +4 -6
- angr/analyses/decompiler/peephole_optimizations/remove_redundant_ite_branch.py +14 -13
- angr/analyses/decompiler/peephole_optimizations/remove_redundant_ite_comparisons.py +2 -2
- angr/analyses/decompiler/peephole_optimizations/remove_redundant_nots.py +1 -0
- angr/analyses/decompiler/peephole_optimizations/remove_redundant_reinterprets.py +3 -2
- angr/analyses/decompiler/peephole_optimizations/remove_redundant_shifts.py +2 -2
- angr/analyses/decompiler/peephole_optimizations/remove_redundant_shifts_around_comparators.py +20 -16
- angr/analyses/decompiler/peephole_optimizations/rewrite_bit_extractions.py +3 -3
- angr/analyses/decompiler/peephole_optimizations/rewrite_mips_gp_loads.py +4 -2
- angr/analyses/decompiler/peephole_optimizations/rol_ror.py +66 -40
- angr/analyses/decompiler/peephole_optimizations/sar_to_signed_div.py +64 -57
- angr/analyses/decompiler/peephole_optimizations/simplify_pc_relative_loads.py +14 -14
- angr/analyses/decompiler/peephole_optimizations/single_bit_cond_to_boolexpr.py +1 -0
- angr/analyses/decompiler/peephole_optimizations/single_bit_xor.py +8 -5
- angr/analyses/decompiler/peephole_optimizations/tidy_stack_addr.py +4 -6
- angr/analyses/decompiler/redundant_label_remover.py +20 -19
- angr/analyses/decompiler/region_identifier.py +64 -77
- angr/analyses/decompiler/region_simplifiers/__init__.py +1 -0
- angr/analyses/decompiler/region_simplifiers/cascading_cond_transformer.py +2 -1
- angr/analyses/decompiler/region_simplifiers/cascading_ifs.py +1 -0
- angr/analyses/decompiler/region_simplifiers/expr_folding.py +43 -29
- angr/analyses/decompiler/region_simplifiers/goto.py +1 -0
- angr/analyses/decompiler/region_simplifiers/if_.py +29 -36
- angr/analyses/decompiler/region_simplifiers/ifelse.py +1 -0
- angr/analyses/decompiler/region_simplifiers/loop.py +27 -13
- angr/analyses/decompiler/region_simplifiers/node_address_finder.py +1 -0
- angr/analyses/decompiler/region_simplifiers/region_simplifier.py +1 -0
- angr/analyses/decompiler/region_simplifiers/switch_cluster_simplifier.py +12 -16
- angr/analyses/decompiler/region_simplifiers/switch_expr_simplifier.py +36 -32
- angr/analyses/decompiler/region_walker.py +1 -0
- angr/analyses/decompiler/return_maker.py +1 -0
- angr/analyses/decompiler/seq_to_blocks.py +1 -0
- angr/analyses/decompiler/sequence_walker.py +5 -10
- angr/analyses/decompiler/ssailification/__init__.py +4 -0
- angr/analyses/decompiler/ssailification/rewriting.py +325 -0
- angr/analyses/decompiler/ssailification/rewriting_engine.py +601 -0
- angr/analyses/decompiler/ssailification/rewriting_state.py +60 -0
- angr/analyses/decompiler/ssailification/ssailification.py +213 -0
- angr/analyses/decompiler/ssailification/traversal.py +97 -0
- angr/analyses/decompiler/ssailification/traversal_engine.py +131 -0
- angr/analyses/decompiler/ssailification/traversal_state.py +42 -0
- angr/analyses/decompiler/structured_codegen/__init__.py +1 -0
- angr/analyses/decompiler/structured_codegen/base.py +2 -2
- angr/analyses/decompiler/structured_codegen/c.py +172 -160
- angr/analyses/decompiler/structured_codegen/dummy.py +1 -0
- angr/analyses/decompiler/structured_codegen/dwarf_import.py +1 -0
- angr/analyses/decompiler/structuring/__init__.py +1 -0
- angr/analyses/decompiler/structuring/dream.py +27 -43
- angr/analyses/decompiler/structuring/phoenix.py +201 -201
- angr/analyses/decompiler/structuring/recursive_structurer.py +4 -3
- angr/analyses/decompiler/structuring/sailr.py +5 -4
- angr/analyses/decompiler/structuring/structurer_base.py +26 -23
- angr/analyses/decompiler/structuring/structurer_nodes.py +14 -24
- angr/analyses/decompiler/utils.py +112 -52
- angr/analyses/disassembly.py +75 -77
- angr/analyses/disassembly_utils.py +10 -13
- angr/analyses/dominance_frontier.py +25 -7
- angr/analyses/find_objects_static.py +3 -2
- angr/analyses/flirt.py +7 -10
- angr/analyses/forward_analysis/__init__.py +1 -0
- angr/analyses/forward_analysis/forward_analysis.py +9 -6
- angr/analyses/forward_analysis/job_info.py +3 -3
- angr/analyses/forward_analysis/visitors/__init__.py +1 -0
- angr/analyses/forward_analysis/visitors/call_graph.py +1 -0
- angr/analyses/forward_analysis/visitors/function_graph.py +3 -2
- angr/analyses/forward_analysis/visitors/graph.py +9 -9
- angr/analyses/forward_analysis/visitors/loop.py +1 -0
- angr/analyses/forward_analysis/visitors/single_node_graph.py +2 -2
- angr/analyses/identifier/__init__.py +1 -0
- angr/analyses/identifier/custom_callable.py +2 -2
- angr/analyses/identifier/errors.py +1 -0
- angr/analyses/identifier/func.py +6 -3
- angr/analyses/identifier/functions/__init__.py +2 -1
- angr/analyses/identifier/functions/atoi.py +2 -4
- angr/analyses/identifier/functions/based_atoi.py +3 -6
- angr/analyses/identifier/functions/fdprintf.py +1 -0
- angr/analyses/identifier/functions/free.py +3 -5
- angr/analyses/identifier/functions/int2str.py +11 -26
- angr/analyses/identifier/functions/malloc.py +4 -6
- angr/analyses/identifier/functions/memcmp.py +2 -4
- angr/analyses/identifier/functions/memcpy.py +2 -2
- angr/analyses/identifier/functions/memset.py +2 -2
- angr/analyses/identifier/functions/printf.py +1 -0
- angr/analyses/identifier/functions/recv_until.py +3 -6
- angr/analyses/identifier/functions/skip_calloc.py +2 -1
- angr/analyses/identifier/functions/skip_realloc.py +4 -6
- angr/analyses/identifier/functions/skip_recv_n.py +4 -6
- angr/analyses/identifier/functions/snprintf.py +2 -4
- angr/analyses/identifier/functions/sprintf.py +1 -0
- angr/analyses/identifier/functions/strcasecmp.py +1 -0
- angr/analyses/identifier/functions/strcmp.py +2 -1
- angr/analyses/identifier/functions/strcpy.py +2 -2
- angr/analyses/identifier/functions/strlen.py +1 -0
- angr/analyses/identifier/functions/strncmp.py +2 -1
- angr/analyses/identifier/functions/strncpy.py +2 -2
- angr/analyses/identifier/functions/strtol.py +2 -4
- angr/analyses/identifier/identify.py +35 -54
- angr/analyses/identifier/runner.py +6 -5
- angr/analyses/init_finder.py +17 -17
- angr/analyses/loop_analysis.py +10 -14
- angr/analyses/loopfinder.py +9 -13
- angr/analyses/propagator/__init__.py +1 -0
- angr/analyses/propagator/engine_ail.py +161 -166
- angr/analyses/propagator/engine_base.py +3 -2
- angr/analyses/propagator/engine_vex.py +47 -48
- angr/analyses/propagator/outdated_definition_walker.py +18 -23
- angr/analyses/propagator/propagator.py +8 -12
- angr/analyses/propagator/tmpvar_finder.py +1 -0
- angr/analyses/propagator/top_checker_mixin.py +2 -4
- angr/analyses/propagator/values.py +1 -0
- angr/analyses/propagator/vex_vars.py +3 -2
- angr/analyses/proximity_graph.py +12 -20
- angr/analyses/reaching_definitions/__init__.py +5 -4
- angr/analyses/reaching_definitions/call_trace.py +7 -6
- angr/analyses/reaching_definitions/dep_graph.py +18 -23
- angr/analyses/reaching_definitions/engine_ail.py +89 -121
- angr/analyses/reaching_definitions/engine_vex.py +20 -32
- angr/analyses/reaching_definitions/function_handler.py +38 -35
- angr/analyses/reaching_definitions/function_handler_library/__init__.py +1 -0
- angr/analyses/reaching_definitions/function_handler_library/stdio.py +4 -6
- angr/analyses/reaching_definitions/function_handler_library/stdlib.py +1 -2
- angr/analyses/reaching_definitions/function_handler_library/string.py +2 -4
- angr/analyses/reaching_definitions/function_handler_library/unistd.py +1 -0
- angr/analyses/reaching_definitions/heap_allocator.py +7 -6
- angr/analyses/reaching_definitions/rd_initializer.py +27 -25
- angr/analyses/reaching_definitions/rd_state.py +14 -16
- angr/analyses/reaching_definitions/reaching_definitions.py +27 -36
- angr/analyses/reaching_definitions/subject.py +3 -2
- angr/analyses/reassembler.py +189 -253
- angr/analyses/s_liveness/__init__.py +2 -0
- angr/analyses/s_liveness/s_liveness.py +153 -0
- angr/analyses/s_propagator/__init__.py +2 -0
- angr/analyses/s_propagator/s_propagator.py +250 -0
- angr/analyses/s_reaching_definitions/__init__.py +2 -0
- angr/analyses/s_reaching_definitions/s_rda.py +479 -0
- angr/analyses/soot_class_hierarchy.py +15 -24
- angr/analyses/stack_pointer_tracker.py +106 -98
- angr/analyses/static_hooker.py +3 -2
- angr/analyses/typehoon/__init__.py +1 -0
- angr/analyses/typehoon/dfa.py +5 -5
- angr/analyses/typehoon/lifter.py +5 -4
- angr/analyses/typehoon/simple_solver.py +80 -64
- angr/analyses/typehoon/translator.py +26 -16
- angr/analyses/typehoon/typeconsts.py +22 -12
- angr/analyses/typehoon/typehoon.py +8 -10
- angr/analyses/typehoon/typevars.py +37 -49
- angr/analyses/typehoon/variance.py +1 -0
- angr/analyses/variable_recovery/__init__.py +1 -0
- angr/analyses/variable_recovery/annotations.py +1 -0
- angr/analyses/variable_recovery/engine_ail.py +78 -32
- angr/analyses/variable_recovery/engine_base.py +233 -59
- angr/analyses/variable_recovery/engine_vex.py +17 -21
- angr/analyses/variable_recovery/irsb_scanner.py +1 -0
- angr/analyses/variable_recovery/variable_recovery.py +14 -16
- angr/analyses/variable_recovery/variable_recovery_base.py +12 -14
- angr/analyses/variable_recovery/variable_recovery_fast.py +67 -47
- angr/analyses/veritesting.py +10 -16
- angr/analyses/vfg.py +102 -148
- angr/analyses/vsa_ddg.py +3 -5
- angr/analyses/vtable.py +6 -6
- angr/analyses/xrefs.py +9 -13
- angr/angrdb/__init__.py +4 -2
- angr/angrdb/db.py +51 -53
- angr/angrdb/models.py +1 -0
- angr/angrdb/serializers/__init__.py +1 -0
- angr/angrdb/serializers/cfg_model.py +2 -2
- angr/angrdb/serializers/comments.py +1 -0
- angr/angrdb/serializers/funcs.py +4 -3
- angr/angrdb/serializers/kb.py +3 -2
- angr/angrdb/serializers/labels.py +1 -0
- angr/angrdb/serializers/structured_code.py +5 -10
- angr/angrdb/serializers/variables.py +6 -6
- angr/angrdb/serializers/xrefs.py +2 -2
- angr/annocfg.py +17 -25
- angr/blade.py +19 -23
- angr/block.py +11 -13
- angr/callable.py +4 -3
- angr/calling_conventions.py +147 -147
- angr/code_location.py +12 -13
- angr/codenode.py +2 -1
- angr/concretization_strategies/__init__.py +6 -6
- angr/concretization_strategies/any.py +5 -4
- angr/concretization_strategies/any_named.py +1 -0
- angr/concretization_strategies/controlled_data.py +1 -0
- angr/concretization_strategies/eval.py +2 -2
- angr/concretization_strategies/logging.py +1 -0
- angr/concretization_strategies/max.py +6 -6
- angr/concretization_strategies/nonzero.py +1 -0
- angr/concretization_strategies/nonzero_range.py +4 -3
- angr/concretization_strategies/norepeats.py +5 -4
- angr/concretization_strategies/norepeats_range.py +1 -0
- angr/concretization_strategies/range.py +1 -0
- angr/concretization_strategies/signed_add.py +13 -9
- angr/concretization_strategies/single.py +2 -0
- angr/concretization_strategies/solutions.py +1 -0
- angr/concretization_strategies/unlimited_range.py +1 -0
- angr/distributed/__init__.py +1 -0
- angr/distributed/server.py +2 -2
- angr/distributed/worker.py +3 -3
- angr/engines/__init__.py +1 -0
- angr/engines/concrete.py +2 -1
- angr/engines/engine.py +4 -6
- angr/engines/failure.py +2 -1
- angr/engines/hook.py +1 -0
- angr/engines/light/__init__.py +1 -0
- angr/engines/light/data.py +221 -255
- angr/engines/light/engine.py +72 -85
- angr/engines/pcode/__init__.py +1 -0
- angr/engines/pcode/behavior.py +3 -3
- angr/engines/pcode/cc.py +1 -0
- angr/engines/pcode/emulate.py +13 -16
- angr/engines/pcode/engine.py +7 -5
- angr/engines/pcode/lifter.py +62 -79
- angr/engines/procedure.py +1 -0
- angr/engines/soot/__init__.py +1 -0
- angr/engines/soot/engine.py +46 -52
- angr/engines/soot/exceptions.py +3 -0
- angr/engines/soot/expressions/__init__.py +1 -0
- angr/engines/soot/expressions/arrayref.py +1 -0
- angr/engines/soot/expressions/base.py +4 -5
- angr/engines/soot/expressions/binop.py +1 -0
- angr/engines/soot/expressions/cast.py +1 -0
- angr/engines/soot/expressions/condition.py +2 -1
- angr/engines/soot/expressions/constants.py +1 -0
- angr/engines/soot/expressions/instanceOf.py +1 -0
- angr/engines/soot/expressions/instancefieldref.py +1 -0
- angr/engines/soot/expressions/invoke.py +7 -9
- angr/engines/soot/expressions/length.py +1 -0
- angr/engines/soot/expressions/local.py +1 -0
- angr/engines/soot/expressions/new.py +1 -0
- angr/engines/soot/expressions/newArray.py +1 -0
- angr/engines/soot/expressions/newMultiArray.py +3 -3
- angr/engines/soot/expressions/paramref.py +1 -0
- angr/engines/soot/expressions/phi.py +1 -0
- angr/engines/soot/expressions/staticfieldref.py +1 -0
- angr/engines/soot/expressions/thisref.py +1 -0
- angr/engines/soot/expressions/unsupported.py +1 -0
- angr/engines/soot/field_dispatcher.py +5 -8
- angr/engines/soot/method_dispatcher.py +4 -7
- angr/engines/soot/statements/__init__.py +4 -4
- angr/engines/soot/statements/assign.py +1 -0
- angr/engines/soot/statements/base.py +6 -7
- angr/engines/soot/statements/goto.py +2 -1
- angr/engines/soot/statements/identity.py +1 -0
- angr/engines/soot/statements/if_.py +2 -1
- angr/engines/soot/statements/invoke.py +1 -0
- angr/engines/soot/statements/return_.py +1 -0
- angr/engines/soot/statements/switch.py +1 -0
- angr/engines/soot/statements/throw.py +2 -1
- angr/engines/soot/values/__init__.py +4 -2
- angr/engines/soot/values/arrayref.py +8 -10
- angr/engines/soot/values/base.py +4 -1
- angr/engines/soot/values/constants.py +1 -0
- angr/engines/soot/values/instancefieldref.py +1 -0
- angr/engines/soot/values/local.py +1 -0
- angr/engines/soot/values/paramref.py +1 -0
- angr/engines/soot/values/staticfieldref.py +1 -0
- angr/engines/soot/values/strref.py +3 -2
- angr/engines/soot/values/thisref.py +1 -0
- angr/engines/successors.py +21 -24
- angr/engines/syscall.py +9 -9
- angr/engines/unicorn.py +14 -9
- angr/engines/vex/__init__.py +1 -0
- angr/engines/vex/claripy/__init__.py +1 -0
- angr/engines/vex/claripy/ccall.py +86 -112
- angr/engines/vex/claripy/datalayer.py +12 -16
- angr/engines/vex/claripy/irop.py +85 -104
- angr/engines/vex/heavy/__init__.py +1 -0
- angr/engines/vex/heavy/actions.py +1 -0
- angr/engines/vex/heavy/concretizers.py +8 -9
- angr/engines/vex/heavy/dirty.py +6 -5
- angr/engines/vex/heavy/heavy.py +15 -14
- angr/engines/vex/heavy/inspect.py +1 -0
- angr/engines/vex/heavy/resilience.py +2 -2
- angr/engines/vex/heavy/super_fastpath.py +2 -2
- angr/engines/vex/lifter.py +28 -35
- angr/engines/vex/light/__init__.py +1 -0
- angr/engines/vex/light/light.py +2 -4
- angr/engines/vex/light/resilience.py +1 -0
- angr/engines/vex/light/slicing.py +1 -0
- angr/errors.py +6 -1
- angr/exploration_techniques/__init__.py +3 -2
- angr/exploration_techniques/bucketizer.py +2 -3
- angr/exploration_techniques/common.py +3 -3
- angr/exploration_techniques/dfs.py +1 -0
- angr/exploration_techniques/director.py +17 -19
- angr/exploration_techniques/driller_core.py +3 -7
- angr/exploration_techniques/explorer.py +7 -3
- angr/exploration_techniques/lengthlimiter.py +1 -0
- angr/exploration_techniques/local_loop_seer.py +2 -2
- angr/exploration_techniques/loop_seer.py +11 -14
- angr/exploration_techniques/manual_mergepoint.py +3 -2
- angr/exploration_techniques/memory_watcher.py +1 -0
- angr/exploration_techniques/oppologist.py +4 -4
- angr/exploration_techniques/slicecutor.py +1 -0
- angr/exploration_techniques/spiller.py +8 -8
- angr/exploration_techniques/spiller_db.py +1 -0
- angr/exploration_techniques/stochastic.py +3 -4
- angr/exploration_techniques/stub_stasher.py +1 -0
- angr/exploration_techniques/suggestions.py +5 -4
- angr/exploration_techniques/symbion.py +1 -0
- angr/exploration_techniques/tech_builder.py +1 -0
- angr/exploration_techniques/threading.py +1 -0
- angr/exploration_techniques/timeout.py +1 -0
- angr/exploration_techniques/tracer.py +34 -39
- angr/exploration_techniques/unique.py +1 -0
- angr/exploration_techniques/veritesting.py +1 -0
- angr/factory.py +9 -9
- angr/flirt/__init__.py +1 -0
- angr/flirt/build_sig.py +8 -12
- angr/keyed_region.py +10 -17
- angr/knowledge_base/__init__.py +1 -0
- angr/knowledge_base/knowledge_base.py +17 -17
- angr/knowledge_plugins/__init__.py +1 -0
- angr/knowledge_plugins/callsite_prototypes.py +1 -0
- angr/knowledge_plugins/cfg/__init__.py +2 -0
- angr/knowledge_plugins/cfg/cfg_manager.py +2 -1
- angr/knowledge_plugins/cfg/cfg_model.py +27 -43
- angr/knowledge_plugins/cfg/cfg_node.py +8 -19
- angr/knowledge_plugins/cfg/indirect_jump.py +3 -5
- angr/knowledge_plugins/cfg/memory_data.py +4 -3
- angr/knowledge_plugins/comments.py +1 -0
- angr/knowledge_plugins/custom_strings.py +1 -0
- angr/knowledge_plugins/data.py +1 -0
- angr/knowledge_plugins/debug_variables.py +18 -23
- angr/knowledge_plugins/functions/__init__.py +1 -0
- angr/knowledge_plugins/functions/function.py +49 -53
- angr/knowledge_plugins/functions/function_manager.py +14 -14
- angr/knowledge_plugins/functions/function_parser.py +38 -42
- angr/knowledge_plugins/functions/soot_function.py +5 -6
- angr/knowledge_plugins/indirect_jumps.py +1 -0
- angr/knowledge_plugins/key_definitions/__init__.py +1 -0
- angr/knowledge_plugins/key_definitions/atoms.py +65 -17
- angr/knowledge_plugins/key_definitions/constants.py +6 -0
- angr/knowledge_plugins/key_definitions/definition.py +22 -25
- angr/knowledge_plugins/key_definitions/environment.py +18 -14
- angr/knowledge_plugins/key_definitions/heap_address.py +4 -3
- angr/knowledge_plugins/key_definitions/key_definition_manager.py +5 -4
- angr/knowledge_plugins/key_definitions/live_definitions.py +36 -45
- angr/knowledge_plugins/key_definitions/liveness.py +18 -23
- angr/knowledge_plugins/key_definitions/rd_model.py +29 -34
- angr/knowledge_plugins/key_definitions/tag.py +7 -6
- angr/knowledge_plugins/key_definitions/undefined.py +3 -0
- angr/knowledge_plugins/key_definitions/unknown_size.py +3 -0
- angr/knowledge_plugins/key_definitions/uses.py +21 -23
- angr/knowledge_plugins/labels.py +3 -2
- angr/knowledge_plugins/patches.py +2 -1
- angr/knowledge_plugins/plugin.py +2 -1
- angr/knowledge_plugins/propagations/__init__.py +1 -0
- angr/knowledge_plugins/propagations/prop_value.py +25 -27
- angr/knowledge_plugins/propagations/propagation_manager.py +2 -2
- angr/knowledge_plugins/propagations/propagation_model.py +5 -4
- angr/knowledge_plugins/propagations/states.py +71 -81
- angr/knowledge_plugins/structured_code/__init__.py +1 -0
- angr/knowledge_plugins/structured_code/manager.py +5 -4
- angr/knowledge_plugins/sync/__init__.py +1 -0
- angr/knowledge_plugins/sync/sync_controller.py +10 -15
- angr/knowledge_plugins/types.py +1 -0
- angr/knowledge_plugins/variables/__init__.py +1 -0
- angr/knowledge_plugins/variables/variable_access.py +9 -10
- angr/knowledge_plugins/variables/variable_manager.py +84 -55
- angr/knowledge_plugins/xrefs/__init__.py +1 -0
- angr/knowledge_plugins/xrefs/xref.py +7 -11
- angr/knowledge_plugins/xrefs/xref_manager.py +1 -0
- angr/knowledge_plugins/xrefs/xref_types.py +3 -0
- angr/lib/angr_native.dll +0 -0
- angr/misc/__init__.py +1 -0
- angr/misc/ansi.py +1 -0
- angr/misc/autoimport.py +3 -2
- angr/misc/bug_report.py +6 -5
- angr/misc/hookset.py +3 -2
- angr/misc/loggers.py +2 -2
- angr/misc/picklable_lock.py +1 -0
- angr/misc/plugins.py +11 -13
- angr/misc/range.py +3 -0
- angr/misc/telemetry.py +54 -0
- angr/misc/testing.py +2 -1
- angr/misc/ux.py +5 -5
- angr/misc/weakpatch.py +1 -0
- angr/procedures/__init__.py +1 -0
- angr/procedures/cgc/_terminate.py +1 -0
- angr/procedures/cgc/allocate.py +1 -0
- angr/procedures/cgc/deallocate.py +1 -0
- angr/procedures/cgc/fdwait.py +1 -0
- angr/procedures/cgc/random.py +1 -0
- angr/procedures/cgc/receive.py +26 -26
- angr/procedures/cgc/transmit.py +1 -0
- angr/procedures/definitions/__init__.py +9 -10
- angr/procedures/definitions/cgc.py +1 -0
- angr/procedures/definitions/glibc.py +1 -0
- angr/procedures/definitions/gnulib.py +1 -0
- angr/procedures/definitions/libstdcpp.py +1 -0
- angr/procedures/definitions/linux_kernel.py +1 -0
- angr/procedures/definitions/linux_loader.py +1 -0
- angr/procedures/definitions/msvcr.py +1 -0
- angr/procedures/definitions/parse_syscalls_from_local_system.py +2 -1
- angr/procedures/definitions/parse_win32json.py +27 -30
- angr/procedures/definitions/types_win32.py +1 -0
- angr/procedures/definitions/wdk_api-ms-win-dx-d3dkmt-l1-1-4.py +1 -0
- angr/procedures/definitions/wdk_api-ms-win-dx-d3dkmt-l1-1-6.py +1 -0
- angr/procedures/definitions/wdk_clfs.py +1 -0
- angr/procedures/definitions/wdk_fltmgr.py +1 -0
- angr/procedures/definitions/wdk_fwpkclnt.py +1 -0
- angr/procedures/definitions/wdk_fwpuclnt.py +1 -0
- angr/procedures/definitions/wdk_gdi32.py +1 -0
- angr/procedures/definitions/wdk_hal.py +1 -0
- angr/procedures/definitions/wdk_ksecdd.py +1 -0
- angr/procedures/definitions/wdk_ndis.py +1 -0
- angr/procedures/definitions/wdk_ntoskrnl.py +1 -0
- angr/procedures/definitions/wdk_offreg.py +1 -0
- angr/procedures/definitions/wdk_pshed.py +1 -0
- angr/procedures/definitions/wdk_secur32.py +1 -0
- angr/procedures/definitions/wdk_vhfum.py +1 -0
- angr/procedures/definitions/win32_aclui.py +1 -0
- angr/procedures/definitions/win32_activeds.py +1 -0
- angr/procedures/definitions/win32_advapi32.py +1 -0
- angr/procedures/definitions/win32_advpack.py +1 -0
- angr/procedures/definitions/win32_amsi.py +1 -0
- angr/procedures/definitions/win32_api-ms-win-appmodel-runtime-l1-1-1.py +1 -0
- angr/procedures/definitions/win32_api-ms-win-appmodel-runtime-l1-1-3.py +1 -0
- angr/procedures/definitions/win32_api-ms-win-appmodel-runtime-l1-1-6.py +1 -0
- angr/procedures/definitions/win32_api-ms-win-core-apiquery-l2-1-0.py +1 -0
- angr/procedures/definitions/win32_api-ms-win-core-backgroundtask-l1-1-0.py +1 -0
- angr/procedures/definitions/win32_api-ms-win-core-comm-l1-1-1.py +1 -0
- angr/procedures/definitions/win32_api-ms-win-core-comm-l1-1-2.py +1 -0
- angr/procedures/definitions/win32_api-ms-win-core-enclave-l1-1-1.py +1 -0
- angr/procedures/definitions/win32_api-ms-win-core-errorhandling-l1-1-3.py +1 -0
- angr/procedures/definitions/win32_api-ms-win-core-featurestaging-l1-1-0.py +1 -0
- angr/procedures/definitions/win32_api-ms-win-core-featurestaging-l1-1-1.py +1 -0
- angr/procedures/definitions/win32_api-ms-win-core-file-fromapp-l1-1-0.py +1 -0
- angr/procedures/definitions/win32_api-ms-win-core-handle-l1-1-0.py +1 -0
- angr/procedures/definitions/win32_api-ms-win-core-ioring-l1-1-0.py +1 -0
- angr/procedures/definitions/win32_api-ms-win-core-marshal-l1-1-0.py +1 -0
- angr/procedures/definitions/win32_api-ms-win-core-memory-l1-1-3.py +1 -0
- angr/procedures/definitions/win32_api-ms-win-core-memory-l1-1-4.py +1 -0
- angr/procedures/definitions/win32_api-ms-win-core-memory-l1-1-5.py +1 -0
- angr/procedures/definitions/win32_api-ms-win-core-memory-l1-1-6.py +1 -0
- angr/procedures/definitions/win32_api-ms-win-core-memory-l1-1-7.py +1 -0
- angr/procedures/definitions/win32_api-ms-win-core-memory-l1-1-8.py +1 -0
- angr/procedures/definitions/win32_api-ms-win-core-path-l1-1-0.py +1 -0
- angr/procedures/definitions/win32_api-ms-win-core-psm-appnotify-l1-1-0.py +1 -0
- angr/procedures/definitions/win32_api-ms-win-core-psm-appnotify-l1-1-1.py +1 -0
- angr/procedures/definitions/win32_api-ms-win-core-realtime-l1-1-1.py +1 -0
- angr/procedures/definitions/win32_api-ms-win-core-realtime-l1-1-2.py +1 -0
- angr/procedures/definitions/win32_api-ms-win-core-slapi-l1-1-0.py +1 -0
- angr/procedures/definitions/win32_api-ms-win-core-state-helpers-l1-1-0.py +1 -0
- angr/procedures/definitions/win32_api-ms-win-core-synch-l1-2-0.py +1 -0
- angr/procedures/definitions/win32_api-ms-win-core-sysinfo-l1-2-0.py +1 -0
- angr/procedures/definitions/win32_api-ms-win-core-sysinfo-l1-2-3.py +1 -0
- angr/procedures/definitions/win32_api-ms-win-core-sysinfo-l1-2-4.py +1 -0
- angr/procedures/definitions/win32_api-ms-win-core-sysinfo-l1-2-6.py +1 -0
- angr/procedures/definitions/win32_api-ms-win-core-util-l1-1-1.py +1 -0
- angr/procedures/definitions/win32_api-ms-win-core-winrt-error-l1-1-0.py +1 -0
- angr/procedures/definitions/win32_api-ms-win-core-winrt-error-l1-1-1.py +1 -0
- angr/procedures/definitions/win32_api-ms-win-core-winrt-l1-1-0.py +1 -0
- angr/procedures/definitions/win32_api-ms-win-core-winrt-registration-l1-1-0.py +1 -0
- angr/procedures/definitions/win32_api-ms-win-core-winrt-robuffer-l1-1-0.py +1 -0
- angr/procedures/definitions/win32_api-ms-win-core-winrt-roparameterizediid-l1-1-0.py +1 -0
- angr/procedures/definitions/win32_api-ms-win-core-winrt-string-l1-1-0.py +1 -0
- angr/procedures/definitions/win32_api-ms-win-core-winrt-string-l1-1-1.py +1 -0
- angr/procedures/definitions/win32_api-ms-win-core-wow64-l1-1-1.py +1 -0
- angr/procedures/definitions/win32_api-ms-win-devices-query-l1-1-0.py +1 -0
- angr/procedures/definitions/win32_api-ms-win-devices-query-l1-1-1.py +1 -0
- angr/procedures/definitions/win32_api-ms-win-dx-d3dkmt-l1-1-0.py +1 -0
- angr/procedures/definitions/win32_api-ms-win-gaming-deviceinformation-l1-1-0.py +1 -0
- angr/procedures/definitions/win32_api-ms-win-gaming-expandedresources-l1-1-0.py +1 -0
- angr/procedures/definitions/win32_api-ms-win-gaming-tcui-l1-1-0.py +1 -0
- angr/procedures/definitions/win32_api-ms-win-gaming-tcui-l1-1-1.py +1 -0
- angr/procedures/definitions/win32_api-ms-win-gaming-tcui-l1-1-2.py +1 -0
- angr/procedures/definitions/win32_api-ms-win-gaming-tcui-l1-1-3.py +1 -0
- angr/procedures/definitions/win32_api-ms-win-gaming-tcui-l1-1-4.py +1 -0
- angr/procedures/definitions/win32_api-ms-win-mm-misc-l1-1-1.py +1 -0
- angr/procedures/definitions/win32_api-ms-win-net-isolation-l1-1-0.py +1 -0
- angr/procedures/definitions/win32_api-ms-win-security-base-l1-2-2.py +1 -0
- angr/procedures/definitions/win32_api-ms-win-security-isolatedcontainer-l1-1-0.py +1 -0
- angr/procedures/definitions/win32_api-ms-win-security-isolatedcontainer-l1-1-1.py +1 -0
- angr/procedures/definitions/win32_api-ms-win-service-core-l1-1-3.py +1 -0
- angr/procedures/definitions/win32_api-ms-win-service-core-l1-1-4.py +1 -0
- angr/procedures/definitions/win32_api-ms-win-service-core-l1-1-5.py +1 -0
- angr/procedures/definitions/win32_api-ms-win-shcore-scaling-l1-1-0.py +1 -0
- angr/procedures/definitions/win32_api-ms-win-shcore-scaling-l1-1-1.py +1 -0
- angr/procedures/definitions/win32_api-ms-win-shcore-scaling-l1-1-2.py +1 -0
- angr/procedures/definitions/win32_api-ms-win-shcore-stream-winrt-l1-1-0.py +1 -0
- angr/procedures/definitions/win32_api-ms-win-wsl-api-l1-1-0.py +1 -0
- angr/procedures/definitions/win32_apphelp.py +1 -0
- angr/procedures/definitions/win32_authz.py +1 -0
- angr/procedures/definitions/win32_avicap32.py +1 -0
- angr/procedures/definitions/win32_avifil32.py +1 -0
- angr/procedures/definitions/win32_avrt.py +1 -0
- angr/procedures/definitions/win32_bcp47mrm.py +1 -0
- angr/procedures/definitions/win32_bcrypt.py +1 -0
- angr/procedures/definitions/win32_bcryptprimitives.py +1 -0
- angr/procedures/definitions/win32_bluetoothapis.py +1 -0
- angr/procedures/definitions/win32_bthprops.py +1 -0
- angr/procedures/definitions/win32_bthprops_cpl.py +1 -0
- angr/procedures/definitions/win32_cabinet.py +1 -0
- angr/procedures/definitions/win32_certadm.py +1 -0
- angr/procedures/definitions/win32_certpoleng.py +1 -0
- angr/procedures/definitions/win32_cfgmgr32.py +1 -0
- angr/procedures/definitions/win32_chakra.py +1 -0
- angr/procedures/definitions/win32_cldapi.py +1 -0
- angr/procedures/definitions/win32_clfsw32.py +1 -0
- angr/procedures/definitions/win32_clusapi.py +1 -0
- angr/procedures/definitions/win32_comctl32.py +1 -0
- angr/procedures/definitions/win32_comdlg32.py +1 -0
- angr/procedures/definitions/win32_compstui.py +1 -0
- angr/procedures/definitions/win32_computecore.py +1 -0
- angr/procedures/definitions/win32_computenetwork.py +1 -0
- angr/procedures/definitions/win32_computestorage.py +1 -0
- angr/procedures/definitions/win32_comsvcs.py +1 -0
- angr/procedures/definitions/win32_coremessaging.py +1 -0
- angr/procedures/definitions/win32_credui.py +1 -0
- angr/procedures/definitions/win32_crypt32.py +1 -0
- angr/procedures/definitions/win32_cryptnet.py +1 -0
- angr/procedures/definitions/win32_cryptui.py +1 -0
- angr/procedures/definitions/win32_cryptxml.py +1 -0
- angr/procedures/definitions/win32_cscapi.py +1 -0
- angr/procedures/definitions/win32_d2d1.py +1 -0
- angr/procedures/definitions/win32_d3d10.py +1 -0
- angr/procedures/definitions/win32_d3d10_1.py +1 -0
- angr/procedures/definitions/win32_d3d11.py +1 -0
- angr/procedures/definitions/win32_d3d12.py +1 -0
- angr/procedures/definitions/win32_d3d9.py +1 -0
- angr/procedures/definitions/win32_d3dcompiler_47.py +1 -0
- angr/procedures/definitions/win32_d3dcsx.py +1 -0
- angr/procedures/definitions/win32_davclnt.py +1 -0
- angr/procedures/definitions/win32_dbgeng.py +1 -0
- angr/procedures/definitions/win32_dbghelp.py +1 -0
- angr/procedures/definitions/win32_dbgmodel.py +1 -0
- angr/procedures/definitions/win32_dciman32.py +1 -0
- angr/procedures/definitions/win32_dcomp.py +1 -0
- angr/procedures/definitions/win32_ddraw.py +1 -0
- angr/procedures/definitions/win32_deviceaccess.py +1 -0
- angr/procedures/definitions/win32_dflayout.py +1 -0
- angr/procedures/definitions/win32_dhcpcsvc.py +1 -0
- angr/procedures/definitions/win32_dhcpcsvc6.py +1 -0
- angr/procedures/definitions/win32_dhcpsapi.py +1 -0
- angr/procedures/definitions/win32_diagnosticdataquery.py +1 -0
- angr/procedures/definitions/win32_dinput8.py +1 -0
- angr/procedures/definitions/win32_directml.py +1 -0
- angr/procedures/definitions/win32_dmprocessxmlfiltered.py +1 -0
- angr/procedures/definitions/win32_dnsapi.py +1 -0
- angr/procedures/definitions/win32_drt.py +1 -0
- angr/procedures/definitions/win32_drtprov.py +1 -0
- angr/procedures/definitions/win32_drttransport.py +1 -0
- angr/procedures/definitions/win32_dsound.py +1 -0
- angr/procedures/definitions/win32_dsparse.py +1 -0
- angr/procedures/definitions/win32_dsprop.py +1 -0
- angr/procedures/definitions/win32_dssec.py +1 -0
- angr/procedures/definitions/win32_dsuiext.py +1 -0
- angr/procedures/definitions/win32_dwmapi.py +1 -0
- angr/procedures/definitions/win32_dwrite.py +1 -0
- angr/procedures/definitions/win32_dxcompiler.py +1 -0
- angr/procedures/definitions/win32_dxcore.py +1 -0
- angr/procedures/definitions/win32_dxgi.py +1 -0
- angr/procedures/definitions/win32_dxva2.py +1 -0
- angr/procedures/definitions/win32_eappcfg.py +1 -0
- angr/procedures/definitions/win32_eappprxy.py +1 -0
- angr/procedures/definitions/win32_efswrt.py +1 -0
- angr/procedures/definitions/win32_elscore.py +1 -0
- angr/procedures/definitions/win32_esent.py +1 -0
- angr/procedures/definitions/win32_evr.py +1 -0
- angr/procedures/definitions/win32_faultrep.py +1 -0
- angr/procedures/definitions/win32_fhsvcctl.py +1 -0
- angr/procedures/definitions/win32_firewallapi.py +1 -0
- angr/procedures/definitions/win32_fltlib.py +1 -0
- angr/procedures/definitions/win32_fontsub.py +1 -0
- angr/procedures/definitions/win32_forceinline.py +1 -0
- angr/procedures/definitions/win32_fwpuclnt.py +1 -0
- angr/procedures/definitions/win32_fxsutility.py +1 -0
- angr/procedures/definitions/win32_gdi32.py +1 -0
- angr/procedures/definitions/win32_gdiplus.py +1 -0
- angr/procedures/definitions/win32_glu32.py +1 -0
- angr/procedures/definitions/win32_gpedit.py +1 -0
- angr/procedures/definitions/win32_hhctrl_ocx.py +1 -0
- angr/procedures/definitions/win32_hid.py +1 -0
- angr/procedures/definitions/win32_hlink.py +1 -0
- angr/procedures/definitions/win32_hrtfapo.py +1 -0
- angr/procedures/definitions/win32_httpapi.py +1 -0
- angr/procedures/definitions/win32_icm32.py +1 -0
- angr/procedures/definitions/win32_icmui.py +1 -0
- angr/procedures/definitions/win32_icu.py +1 -0
- angr/procedures/definitions/win32_ieframe.py +1 -0
- angr/procedures/definitions/win32_imagehlp.py +1 -0
- angr/procedures/definitions/win32_imgutil.py +1 -0
- angr/procedures/definitions/win32_imm32.py +1 -0
- angr/procedures/definitions/win32_infocardapi.py +1 -0
- angr/procedures/definitions/win32_inkobjcore.py +1 -0
- angr/procedures/definitions/win32_iphlpapi.py +1 -0
- angr/procedures/definitions/win32_iscsidsc.py +1 -0
- angr/procedures/definitions/win32_isolatedwindowsenvironmentutils.py +1 -0
- angr/procedures/definitions/win32_kernel32.py +1 -0
- angr/procedures/definitions/win32_kernelbase.py +1 -0
- angr/procedures/definitions/win32_keycredmgr.py +1 -0
- angr/procedures/definitions/win32_ksproxy_ax.py +1 -0
- angr/procedures/definitions/win32_ksuser.py +1 -0
- angr/procedures/definitions/win32_ktmw32.py +1 -0
- angr/procedures/definitions/win32_licenseprotection.py +1 -0
- angr/procedures/definitions/win32_loadperf.py +1 -0
- angr/procedures/definitions/win32_magnification.py +1 -0
- angr/procedures/definitions/win32_mapi32.py +1 -0
- angr/procedures/definitions/win32_mdmlocalmanagement.py +1 -0
- angr/procedures/definitions/win32_mdmregistration.py +1 -0
- angr/procedures/definitions/win32_mf.py +1 -0
- angr/procedures/definitions/win32_mfcore.py +1 -0
- angr/procedures/definitions/win32_mfplat.py +1 -0
- angr/procedures/definitions/win32_mfplay.py +1 -0
- angr/procedures/definitions/win32_mfreadwrite.py +1 -0
- angr/procedures/definitions/win32_mfsensorgroup.py +1 -0
- angr/procedures/definitions/win32_mfsrcsnk.py +1 -0
- angr/procedures/definitions/win32_mgmtapi.py +1 -0
- angr/procedures/definitions/win32_mi.py +1 -0
- angr/procedures/definitions/win32_mmdevapi.py +1 -0
- angr/procedures/definitions/win32_mpr.py +1 -0
- angr/procedures/definitions/win32_mprapi.py +1 -0
- angr/procedures/definitions/win32_mqrt.py +1 -0
- angr/procedures/definitions/win32_mrmsupport.py +1 -0
- angr/procedures/definitions/win32_msacm32.py +1 -0
- angr/procedures/definitions/win32_msajapi.py +1 -0
- angr/procedures/definitions/win32_mscms.py +1 -0
- angr/procedures/definitions/win32_mscoree.py +1 -0
- angr/procedures/definitions/win32_msctfmonitor.py +1 -0
- angr/procedures/definitions/win32_msdelta.py +1 -0
- angr/procedures/definitions/win32_msdmo.py +1 -0
- angr/procedures/definitions/win32_msdrm.py +1 -0
- angr/procedures/definitions/win32_msi.py +1 -0
- angr/procedures/definitions/win32_msimg32.py +1 -0
- angr/procedures/definitions/win32_mspatcha.py +1 -0
- angr/procedures/definitions/win32_mspatchc.py +1 -0
- angr/procedures/definitions/win32_msports.py +1 -0
- angr/procedures/definitions/win32_msrating.py +1 -0
- angr/procedures/definitions/win32_mssign32.py +1 -0
- angr/procedures/definitions/win32_mstask.py +1 -0
- angr/procedures/definitions/win32_msvfw32.py +1 -0
- angr/procedures/definitions/win32_mswsock.py +1 -0
- angr/procedures/definitions/win32_mtxdm.py +1 -0
- angr/procedures/definitions/win32_ncrypt.py +1 -0
- angr/procedures/definitions/win32_ndfapi.py +1 -0
- angr/procedures/definitions/win32_netapi32.py +1 -0
- angr/procedures/definitions/win32_netsh.py +1 -0
- angr/procedures/definitions/win32_netshell.py +1 -0
- angr/procedures/definitions/win32_newdev.py +1 -0
- angr/procedures/definitions/win32_ninput.py +1 -0
- angr/procedures/definitions/win32_normaliz.py +1 -0
- angr/procedures/definitions/win32_ntdll.py +1 -0
- angr/procedures/definitions/win32_ntdllk.py +1 -0
- angr/procedures/definitions/win32_ntdsapi.py +1 -0
- angr/procedures/definitions/win32_ntlanman.py +1 -0
- angr/procedures/definitions/win32_odbc32.py +1 -0
- angr/procedures/definitions/win32_odbcbcp.py +1 -0
- angr/procedures/definitions/win32_ole32.py +1 -0
- angr/procedures/definitions/win32_oleacc.py +1 -0
- angr/procedures/definitions/win32_oleaut32.py +1 -0
- angr/procedures/definitions/win32_oledlg.py +1 -0
- angr/procedures/definitions/win32_ondemandconnroutehelper.py +1 -0
- angr/procedures/definitions/win32_opengl32.py +1 -0
- angr/procedures/definitions/win32_opmxbox.py +1 -0
- angr/procedures/definitions/win32_p2p.py +1 -0
- angr/procedures/definitions/win32_p2pgraph.py +1 -0
- angr/procedures/definitions/win32_pdh.py +1 -0
- angr/procedures/definitions/win32_peerdist.py +1 -0
- angr/procedures/definitions/win32_powrprof.py +1 -0
- angr/procedures/definitions/win32_prntvpt.py +1 -0
- angr/procedures/definitions/win32_projectedfslib.py +1 -0
- angr/procedures/definitions/win32_propsys.py +1 -0
- angr/procedures/definitions/win32_psapi.py +1 -0
- angr/procedures/definitions/win32_quartz.py +1 -0
- angr/procedures/definitions/win32_query.py +1 -0
- angr/procedures/definitions/win32_qwave.py +1 -0
- angr/procedures/definitions/win32_rasapi32.py +1 -0
- angr/procedures/definitions/win32_rasdlg.py +1 -0
- angr/procedures/definitions/win32_resutils.py +1 -0
- angr/procedures/definitions/win32_rometadata.py +1 -0
- angr/procedures/definitions/win32_rpcns4.py +1 -0
- angr/procedures/definitions/win32_rpcproxy.py +1 -0
- angr/procedures/definitions/win32_rpcrt4.py +1 -0
- angr/procedures/definitions/win32_rstrtmgr.py +1 -0
- angr/procedures/definitions/win32_rtm.py +1 -0
- angr/procedures/definitions/win32_rtutils.py +1 -0
- angr/procedures/definitions/win32_rtworkq.py +1 -0
- angr/procedures/definitions/win32_sas.py +1 -0
- angr/procedures/definitions/win32_scarddlg.py +1 -0
- angr/procedures/definitions/win32_schannel.py +1 -0
- angr/procedures/definitions/win32_sechost.py +1 -0
- angr/procedures/definitions/win32_secur32.py +1 -0
- angr/procedures/definitions/win32_sensapi.py +1 -0
- angr/procedures/definitions/win32_sensorsutilsv2.py +1 -0
- angr/procedures/definitions/win32_setupapi.py +1 -0
- angr/procedures/definitions/win32_sfc.py +1 -0
- angr/procedures/definitions/win32_shdocvw.py +1 -0
- angr/procedures/definitions/win32_shell32.py +1 -0
- angr/procedures/definitions/win32_shlwapi.py +1 -0
- angr/procedures/definitions/win32_slc.py +1 -0
- angr/procedures/definitions/win32_slcext.py +1 -0
- angr/procedures/definitions/win32_slwga.py +1 -0
- angr/procedures/definitions/win32_snmpapi.py +1 -0
- angr/procedures/definitions/win32_spoolss.py +1 -0
- angr/procedures/definitions/win32_srclient.py +1 -0
- angr/procedures/definitions/win32_srpapi.py +1 -0
- angr/procedures/definitions/win32_sspicli.py +1 -0
- angr/procedures/definitions/win32_sti.py +1 -0
- angr/procedures/definitions/win32_t2embed.py +1 -0
- angr/procedures/definitions/win32_tapi32.py +1 -0
- angr/procedures/definitions/win32_tbs.py +1 -0
- angr/procedures/definitions/win32_tdh.py +1 -0
- angr/procedures/definitions/win32_tokenbinding.py +1 -0
- angr/procedures/definitions/win32_traffic.py +1 -0
- angr/procedures/definitions/win32_txfw32.py +1 -0
- angr/procedures/definitions/win32_ualapi.py +1 -0
- angr/procedures/definitions/win32_uiautomationcore.py +1 -0
- angr/procedures/definitions/win32_urlmon.py +1 -0
- angr/procedures/definitions/win32_user32.py +1 -0
- angr/procedures/definitions/win32_userenv.py +1 -0
- angr/procedures/definitions/win32_usp10.py +1 -0
- angr/procedures/definitions/win32_uxtheme.py +1 -0
- angr/procedures/definitions/win32_verifier.py +1 -0
- angr/procedures/definitions/win32_version.py +1 -0
- angr/procedures/definitions/win32_vertdll.py +1 -0
- angr/procedures/definitions/win32_virtdisk.py +1 -0
- angr/procedures/definitions/win32_vmdevicehost.py +1 -0
- angr/procedures/definitions/win32_vmsavedstatedumpprovider.py +1 -0
- angr/procedures/definitions/win32_vssapi.py +1 -0
- angr/procedures/definitions/win32_wcmapi.py +1 -0
- angr/procedures/definitions/win32_wdsbp.py +1 -0
- angr/procedures/definitions/win32_wdsclientapi.py +1 -0
- angr/procedures/definitions/win32_wdsmc.py +1 -0
- angr/procedures/definitions/win32_wdspxe.py +1 -0
- angr/procedures/definitions/win32_wdstptc.py +1 -0
- angr/procedures/definitions/win32_webauthn.py +1 -0
- angr/procedures/definitions/win32_webservices.py +1 -0
- angr/procedures/definitions/win32_websocket.py +1 -0
- angr/procedures/definitions/win32_wecapi.py +1 -0
- angr/procedures/definitions/win32_wer.py +1 -0
- angr/procedures/definitions/win32_wevtapi.py +1 -0
- angr/procedures/definitions/win32_winbio.py +1 -0
- angr/procedures/definitions/win32_windows_ai_machinelearning.py +1 -0
- angr/procedures/definitions/win32_windows_data_pdf.py +1 -0
- angr/procedures/definitions/win32_windows_media_mediacontrol.py +1 -0
- angr/procedures/definitions/win32_windows_networking.py +1 -0
- angr/procedures/definitions/win32_windows_ui_xaml.py +1 -0
- angr/procedures/definitions/win32_windowscodecs.py +1 -0
- angr/procedures/definitions/win32_winfax.py +1 -0
- angr/procedures/definitions/win32_winhttp.py +1 -0
- angr/procedures/definitions/win32_winhvemulation.py +1 -0
- angr/procedures/definitions/win32_winhvplatform.py +1 -0
- angr/procedures/definitions/win32_wininet.py +1 -0
- angr/procedures/definitions/win32_winml.py +1 -0
- angr/procedures/definitions/win32_winmm.py +1 -0
- angr/procedures/definitions/win32_winscard.py +1 -0
- angr/procedures/definitions/win32_winspool.py +1 -0
- angr/procedures/definitions/win32_winspool_drv.py +1 -0
- angr/procedures/definitions/win32_wintrust.py +1 -0
- angr/procedures/definitions/win32_winusb.py +1 -0
- angr/procedures/definitions/win32_wlanapi.py +1 -0
- angr/procedures/definitions/win32_wlanui.py +1 -0
- angr/procedures/definitions/win32_wldap32.py +1 -0
- angr/procedures/definitions/win32_wldp.py +1 -0
- angr/procedures/definitions/win32_wmvcore.py +1 -0
- angr/procedures/definitions/win32_wnvapi.py +1 -0
- angr/procedures/definitions/win32_wofutil.py +1 -0
- angr/procedures/definitions/win32_ws2_32.py +1 -0
- angr/procedures/definitions/win32_wscapi.py +1 -0
- angr/procedures/definitions/win32_wsclient.py +1 -0
- angr/procedures/definitions/win32_wsdapi.py +1 -0
- angr/procedures/definitions/win32_wsmsvc.py +1 -0
- angr/procedures/definitions/win32_wsnmp32.py +1 -0
- angr/procedures/definitions/win32_wtsapi32.py +1 -0
- angr/procedures/definitions/win32_xaudio2_8.py +1 -0
- angr/procedures/definitions/win32_xinput1_4.py +1 -0
- angr/procedures/definitions/win32_xinputuap.py +1 -0
- angr/procedures/definitions/win32_xmllite.py +1 -0
- angr/procedures/definitions/win32_xolehlp.py +1 -0
- angr/procedures/definitions/win32_xpsprint.py +1 -0
- angr/procedures/glibc/__ctype_b_loc.py +2 -3
- angr/procedures/glibc/__ctype_tolower_loc.py +2 -3
- angr/procedures/glibc/__ctype_toupper_loc.py +2 -3
- angr/procedures/glibc/__errno_location.py +1 -0
- angr/procedures/glibc/__libc_init.py +1 -0
- angr/procedures/glibc/__libc_start_main.py +2 -3
- angr/procedures/glibc/dynamic_loading.py +1 -0
- angr/procedures/glibc/scanf.py +1 -0
- angr/procedures/glibc/sscanf.py +1 -0
- angr/procedures/gnulib/xalloc_die.py +1 -0
- angr/procedures/gnulib/xstrtol_fatal.py +1 -0
- angr/procedures/java/__init__.py +1 -0
- angr/procedures/java/unconstrained.py +4 -3
- angr/procedures/java_io/read.py +1 -0
- angr/procedures/java_io/write.py +1 -0
- angr/procedures/java_jni/__init__.py +25 -18
- angr/procedures/java_jni/array_operations.py +1 -0
- angr/procedures/java_jni/class_and_interface_operations.py +3 -3
- angr/procedures/java_jni/field_access.py +3 -6
- angr/procedures/java_jni/global_and_local_refs.py +1 -0
- angr/procedures/java_jni/method_calls.py +3 -2
- angr/procedures/java_jni/not_implemented.py +2 -1
- angr/procedures/java_jni/object_operations.py +3 -4
- angr/procedures/java_jni/string_operations.py +2 -1
- angr/procedures/java_jni/version_information.py +1 -0
- angr/procedures/java_lang/character.py +2 -3
- angr/procedures/java_lang/double.py +2 -2
- angr/procedures/java_lang/exit.py +1 -0
- angr/procedures/java_lang/getsimplename.py +2 -2
- angr/procedures/java_lang/integer.py +1 -0
- angr/procedures/java_lang/load_library.py +1 -0
- angr/procedures/java_lang/math.py +1 -0
- angr/procedures/java_lang/string.py +3 -3
- angr/procedures/java_lang/stringbuilder.py +1 -0
- angr/procedures/java_lang/system.py +1 -0
- angr/procedures/java_util/collection.py +1 -0
- angr/procedures/java_util/iterator.py +1 -0
- angr/procedures/java_util/list.py +1 -0
- angr/procedures/java_util/map.py +3 -4
- angr/procedures/java_util/random.py +1 -0
- angr/procedures/java_util/scanner_nextline.py +2 -1
- angr/procedures/libc/abort.py +1 -0
- angr/procedures/libc/access.py +1 -0
- angr/procedures/libc/atoi.py +2 -2
- angr/procedures/libc/atol.py +1 -0
- angr/procedures/libc/calloc.py +1 -0
- angr/procedures/libc/closelog.py +1 -0
- angr/procedures/libc/err.py +1 -0
- angr/procedures/libc/error.py +2 -3
- angr/procedures/libc/exit.py +1 -0
- angr/procedures/libc/fclose.py +2 -3
- angr/procedures/libc/feof.py +1 -0
- angr/procedures/libc/fflush.py +1 -0
- angr/procedures/libc/fgetc.py +1 -0
- angr/procedures/libc/fgets.py +19 -19
- angr/procedures/libc/fopen.py +6 -8
- angr/procedures/libc/fprintf.py +1 -0
- angr/procedures/libc/fputc.py +1 -0
- angr/procedures/libc/fputs.py +1 -0
- angr/procedures/libc/fread.py +1 -0
- angr/procedures/libc/free.py +1 -0
- angr/procedures/libc/fscanf.py +2 -2
- angr/procedures/libc/fseek.py +3 -2
- angr/procedures/libc/ftell.py +1 -0
- angr/procedures/libc/fwrite.py +1 -0
- angr/procedures/libc/getchar.py +2 -2
- angr/procedures/libc/getdelim.py +25 -25
- angr/procedures/libc/getegid.py +1 -0
- angr/procedures/libc/geteuid.py +1 -0
- angr/procedures/libc/getgid.py +1 -0
- angr/procedures/libc/gets.py +18 -18
- angr/procedures/libc/getuid.py +1 -0
- angr/procedures/libc/malloc.py +1 -0
- angr/procedures/libc/memcmp.py +3 -6
- angr/procedures/libc/memcpy.py +1 -0
- angr/procedures/libc/memset.py +1 -0
- angr/procedures/libc/openlog.py +1 -0
- angr/procedures/libc/perror.py +1 -0
- angr/procedures/libc/printf.py +1 -0
- angr/procedures/libc/putchar.py +1 -0
- angr/procedures/libc/puts.py +1 -0
- angr/procedures/libc/rand.py +1 -0
- angr/procedures/libc/realloc.py +1 -0
- angr/procedures/libc/rewind.py +2 -1
- angr/procedures/libc/scanf.py +2 -2
- angr/procedures/libc/setbuf.py +1 -0
- angr/procedures/libc/setvbuf.py +1 -0
- angr/procedures/libc/snprintf.py +1 -0
- angr/procedures/libc/sprintf.py +1 -0
- angr/procedures/libc/srand.py +1 -0
- angr/procedures/libc/sscanf.py +2 -2
- angr/procedures/libc/stpcpy.py +2 -2
- angr/procedures/libc/strcat.py +1 -0
- angr/procedures/libc/strchr.py +1 -0
- angr/procedures/libc/strcmp.py +1 -0
- angr/procedures/libc/strcpy.py +2 -2
- angr/procedures/libc/strlen.py +35 -31
- angr/procedures/libc/strncat.py +1 -0
- angr/procedures/libc/strncmp.py +9 -11
- angr/procedures/libc/strncpy.py +1 -0
- angr/procedures/libc/strnlen.py +2 -2
- angr/procedures/libc/strstr.py +8 -4
- angr/procedures/libc/strtol.py +9 -9
- angr/procedures/libc/strtoul.py +2 -2
- angr/procedures/libc/system.py +1 -0
- angr/procedures/libc/time.py +2 -2
- angr/procedures/libc/tmpnam.py +1 -0
- angr/procedures/libc/tolower.py +1 -0
- angr/procedures/libc/toupper.py +1 -0
- angr/procedures/libc/ungetc.py +1 -0
- angr/procedures/libc/vsnprintf.py +1 -0
- angr/procedures/libc/wchar.py +1 -0
- angr/procedures/libstdcpp/_unwind_resume.py +1 -0
- angr/procedures/libstdcpp/std____throw_bad_alloc.py +1 -0
- angr/procedures/libstdcpp/std____throw_bad_cast.py +1 -0
- angr/procedures/libstdcpp/std____throw_length_error.py +1 -0
- angr/procedures/libstdcpp/std____throw_logic_error.py +1 -0
- angr/procedures/libstdcpp/std__terminate.py +1 -0
- angr/procedures/linux_kernel/access.py +1 -0
- angr/procedures/linux_kernel/arch_prctl.py +1 -0
- angr/procedures/linux_kernel/arm_user_helpers.py +1 -0
- angr/procedures/linux_kernel/brk.py +1 -0
- angr/procedures/linux_kernel/cwd.py +1 -0
- angr/procedures/linux_kernel/fstat.py +2 -1
- angr/procedures/linux_kernel/fstat64.py +2 -1
- angr/procedures/linux_kernel/futex.py +3 -3
- angr/procedures/linux_kernel/getegid.py +1 -0
- angr/procedures/linux_kernel/geteuid.py +1 -0
- angr/procedures/linux_kernel/getgid.py +1 -0
- angr/procedures/linux_kernel/getpid.py +1 -0
- angr/procedures/linux_kernel/getrlimit.py +3 -3
- angr/procedures/linux_kernel/gettid.py +1 -0
- angr/procedures/linux_kernel/getuid.py +1 -0
- angr/procedures/linux_kernel/iovec.py +1 -0
- angr/procedures/linux_kernel/lseek.py +1 -0
- angr/procedures/linux_kernel/mmap.py +1 -0
- angr/procedures/linux_kernel/mprotect.py +7 -6
- angr/procedures/linux_kernel/munmap.py +1 -0
- angr/procedures/linux_kernel/openat.py +3 -5
- angr/procedures/linux_kernel/set_tid_address.py +1 -0
- angr/procedures/linux_kernel/sigaction.py +1 -0
- angr/procedures/linux_kernel/sigprocmask.py +1 -0
- angr/procedures/linux_kernel/stat.py +3 -2
- angr/procedures/linux_kernel/sysinfo.py +1 -0
- angr/procedures/linux_kernel/tgkill.py +1 -0
- angr/procedures/linux_kernel/time.py +2 -1
- angr/procedures/linux_kernel/uid.py +1 -0
- angr/procedures/linux_kernel/uname.py +1 -0
- angr/procedures/linux_kernel/unlink.py +2 -2
- angr/procedures/linux_kernel/vsyscall.py +2 -1
- angr/procedures/linux_loader/_dl_initial_error_catch_tsd.py +1 -0
- angr/procedures/linux_loader/_dl_rtld_lock.py +1 -0
- angr/procedures/linux_loader/sim_loader.py +1 -0
- angr/procedures/linux_loader/tls.py +2 -2
- angr/procedures/msvcr/__getmainargs.py +1 -0
- angr/procedures/msvcr/_initterm.py +1 -0
- angr/procedures/msvcr/fmode.py +1 -0
- angr/procedures/ntdll/exceptions.py +4 -3
- angr/procedures/posix/accept.py +2 -2
- angr/procedures/posix/bind.py +1 -0
- angr/procedures/posix/bzero.py +1 -0
- angr/procedures/posix/chroot.py +1 -0
- angr/procedures/posix/close.py +2 -2
- angr/procedures/posix/closedir.py +1 -0
- angr/procedures/posix/dup.py +4 -3
- angr/procedures/posix/fcntl.py +1 -0
- angr/procedures/posix/fdopen.py +16 -19
- angr/procedures/posix/fileno.py +1 -0
- angr/procedures/posix/fork.py +1 -0
- angr/procedures/posix/getenv.py +1 -0
- angr/procedures/posix/gethostbyname.py +1 -0
- angr/procedures/posix/getpass.py +1 -0
- angr/procedures/posix/getsockopt.py +1 -0
- angr/procedures/posix/htonl.py +2 -2
- angr/procedures/posix/htons.py +2 -2
- angr/procedures/posix/inet_ntoa.py +3 -5
- angr/procedures/posix/listen.py +1 -0
- angr/procedures/posix/mmap.py +2 -1
- angr/procedures/posix/open.py +1 -0
- angr/procedures/posix/opendir.py +1 -0
- angr/procedures/posix/poll.py +3 -3
- angr/procedures/posix/pread64.py +1 -0
- angr/procedures/posix/pthread.py +3 -3
- angr/procedures/posix/pwrite64.py +1 -0
- angr/procedures/posix/read.py +1 -0
- angr/procedures/posix/readdir.py +1 -1
- angr/procedures/posix/recv.py +1 -0
- angr/procedures/posix/recvfrom.py +1 -0
- angr/procedures/posix/select.py +7 -7
- angr/procedures/posix/send.py +2 -2
- angr/procedures/posix/setsockopt.py +1 -0
- angr/procedures/posix/sigaction.py +1 -0
- angr/procedures/posix/sim_time.py +1 -0
- angr/procedures/posix/sleep.py +1 -0
- angr/procedures/posix/socket.py +2 -2
- angr/procedures/posix/strcasecmp.py +1 -0
- angr/procedures/posix/strdup.py +1 -0
- angr/procedures/posix/strtok_r.py +32 -36
- angr/procedures/posix/syslog.py +1 -0
- angr/procedures/posix/tz.py +1 -0
- angr/procedures/posix/unlink.py +1 -0
- angr/procedures/posix/usleep.py +1 -0
- angr/procedures/posix/write.py +1 -0
- angr/procedures/procedure_dict.py +1 -0
- angr/procedures/stubs/CallReturn.py +1 -0
- angr/procedures/stubs/NoReturnUnconstrained.py +1 -0
- angr/procedures/stubs/Nop.py +1 -0
- angr/procedures/stubs/PathTerminator.py +1 -0
- angr/procedures/stubs/Redirect.py +3 -2
- angr/procedures/stubs/ReturnChar.py +1 -0
- angr/procedures/stubs/ReturnUnconstrained.py +2 -1
- angr/procedures/stubs/UnresolvableCallTarget.py +1 -0
- angr/procedures/stubs/UnresolvableJumpTarget.py +1 -0
- angr/procedures/stubs/UserHook.py +2 -1
- angr/procedures/stubs/b64_decode.py +1 -0
- angr/procedures/stubs/caller.py +1 -0
- angr/procedures/stubs/crazy_scanf.py +1 -0
- angr/procedures/stubs/format_parser.py +12 -16
- angr/procedures/stubs/syscall_stub.py +6 -7
- angr/procedures/testing/manyargs.py +1 -0
- angr/procedures/testing/retreg.py +2 -2
- angr/procedures/tracer/random.py +1 -0
- angr/procedures/tracer/receive.py +4 -4
- angr/procedures/tracer/transmit.py +4 -4
- angr/procedures/uclibc/__uClibc_main.py +1 -0
- angr/procedures/win32/EncodePointer.py +1 -0
- angr/procedures/win32/ExitProcess.py +1 -0
- angr/procedures/win32/GetCommandLine.py +1 -0
- angr/procedures/win32/GetCurrentProcessId.py +1 -0
- angr/procedures/win32/GetCurrentThreadId.py +1 -0
- angr/procedures/win32/GetLastInputInfo.py +1 -0
- angr/procedures/win32/GetModuleHandle.py +3 -4
- angr/procedures/win32/GetProcessAffinityMask.py +1 -0
- angr/procedures/win32/InterlockedExchange.py +2 -1
- angr/procedures/win32/IsProcessorFeaturePresent.py +1 -0
- angr/procedures/win32/VirtualAlloc.py +2 -1
- angr/procedures/win32/VirtualProtect.py +1 -0
- angr/procedures/win32/critical_section.py +1 -0
- angr/procedures/win32/dynamic_loading.py +2 -1
- angr/procedures/win32/file_handles.py +4 -4
- angr/procedures/win32/gethostbyname.py +2 -2
- angr/procedures/win32/heap.py +1 -0
- angr/procedures/win32/is_bad_ptr.py +1 -0
- angr/procedures/win32/local_storage.py +7 -6
- angr/procedures/win32/mutex.py +1 -0
- angr/procedures/win32/sim_time.py +7 -10
- angr/procedures/win32/system_paths.py +5 -4
- angr/procedures/win32_kernel/ExAllocatePool.py +1 -0
- angr/procedures/win32_kernel/ExFreePoolWithTag.py +1 -0
- angr/procedures/win_user32/chars.py +1 -0
- angr/procedures/win_user32/keyboard.py +1 -0
- angr/procedures/win_user32/messagebox.py +2 -4
- angr/project.py +15 -22
- angr/protos/__init__.py +1 -0
- angr/serializable.py +6 -3
- angr/sim_manager.py +18 -18
- angr/sim_options.py +5 -7
- angr/sim_procedure.py +16 -15
- angr/sim_state.py +61 -88
- angr/sim_state_options.py +9 -15
- angr/sim_type.py +135 -123
- angr/sim_variable.py +23 -38
- angr/simos/__init__.py +3 -1
- angr/simos/cgc.py +2 -1
- angr/simos/javavm.py +84 -95
- angr/simos/linux.py +54 -64
- angr/simos/simos.py +14 -23
- angr/simos/snimmuc_nxp.py +3 -6
- angr/simos/userland.py +6 -6
- angr/simos/windows.py +14 -11
- angr/slicer.py +13 -11
- angr/state_hierarchy.py +4 -4
- angr/state_plugins/__init__.py +1 -0
- angr/state_plugins/callstack.py +19 -18
- angr/state_plugins/cgc.py +5 -4
- angr/state_plugins/concrete.py +7 -8
- angr/state_plugins/debug_variables.py +15 -17
- angr/state_plugins/filesystem.py +13 -19
- angr/state_plugins/gdb.py +3 -2
- angr/state_plugins/globals.py +5 -1
- angr/state_plugins/heap/__init__.py +1 -0
- angr/state_plugins/heap/heap_base.py +1 -0
- angr/state_plugins/heap/heap_brk.py +9 -6
- angr/state_plugins/heap/heap_freelist.py +12 -9
- angr/state_plugins/heap/heap_libc.py +1 -0
- angr/state_plugins/heap/heap_ptmalloc.py +27 -36
- angr/state_plugins/heap/utils.py +1 -0
- angr/state_plugins/history.py +7 -10
- angr/state_plugins/inspect.py +1 -0
- angr/state_plugins/javavm_classloader.py +3 -2
- angr/state_plugins/jni_references.py +2 -1
- angr/state_plugins/libc.py +4 -4
- angr/state_plugins/light_registers.py +6 -8
- angr/state_plugins/log.py +1 -0
- angr/state_plugins/loop_data.py +1 -0
- angr/state_plugins/plugin.py +7 -8
- angr/state_plugins/posix.py +14 -22
- angr/state_plugins/preconstrainer.py +4 -3
- angr/state_plugins/scratch.py +6 -5
- angr/state_plugins/sim_action.py +15 -20
- angr/state_plugins/sim_action_object.py +205 -82
- angr/state_plugins/sim_event.py +1 -0
- angr/state_plugins/solver.py +65 -93
- angr/state_plugins/symbolizer.py +5 -6
- angr/state_plugins/trace_additions.py +32 -42
- angr/state_plugins/uc_manager.py +16 -9
- angr/state_plugins/unicorn_engine.py +21 -37
- angr/state_plugins/view.py +20 -19
- angr/storage/__init__.py +1 -0
- angr/storage/file.py +31 -33
- angr/storage/memory_mixins/__init__.py +12 -15
- angr/storage/memory_mixins/__init__.pyi +13 -14
- angr/storage/memory_mixins/actions_mixin.py +2 -1
- angr/storage/memory_mixins/address_concretization_mixin.py +11 -15
- angr/storage/memory_mixins/bvv_conversion_mixin.py +10 -11
- angr/storage/memory_mixins/clouseau_mixin.py +1 -0
- angr/storage/memory_mixins/conditional_store_mixin.py +1 -0
- angr/storage/memory_mixins/convenient_mappings_mixin.py +7 -8
- angr/storage/memory_mixins/default_filler_mixin.py +12 -14
- angr/storage/memory_mixins/dirty_addrs_mixin.py +1 -0
- angr/storage/memory_mixins/hex_dumper_mixin.py +6 -9
- angr/storage/memory_mixins/javavm_memory/__init__.py +1 -0
- angr/storage/memory_mixins/javavm_memory/javavm_memory_mixin.py +16 -23
- angr/storage/memory_mixins/keyvalue_memory/__init__.py +1 -0
- angr/storage/memory_mixins/keyvalue_memory/keyvalue_memory_mixin.py +2 -1
- angr/storage/memory_mixins/label_merger_mixin.py +2 -2
- angr/storage/memory_mixins/multi_value_merger_mixin.py +6 -5
- angr/storage/memory_mixins/name_resolution_mixin.py +12 -15
- angr/storage/memory_mixins/paged_memory/page_backer_mixins.py +6 -6
- angr/storage/memory_mixins/paged_memory/paged_memory_mixin.py +22 -36
- angr/storage/memory_mixins/paged_memory/paged_memory_multivalue_mixin.py +1 -0
- angr/storage/memory_mixins/paged_memory/pages/__init__.py +1 -2
- angr/storage/memory_mixins/paged_memory/pages/cooperation.py +4 -3
- angr/storage/memory_mixins/paged_memory/pages/history_tracking_mixin.py +4 -4
- angr/storage/memory_mixins/paged_memory/pages/ispo_mixin.py +1 -0
- angr/storage/memory_mixins/paged_memory/pages/list_page.py +12 -20
- angr/storage/memory_mixins/paged_memory/pages/multi_values.py +14 -19
- angr/storage/memory_mixins/paged_memory/pages/mv_list_page.py +26 -32
- angr/storage/memory_mixins/paged_memory/pages/permissions_mixin.py +1 -0
- angr/storage/memory_mixins/paged_memory/pages/refcount_mixin.py +2 -2
- angr/storage/memory_mixins/paged_memory/pages/ultra_page.py +38 -42
- angr/storage/memory_mixins/paged_memory/privileged_mixin.py +1 -0
- angr/storage/memory_mixins/paged_memory/stack_allocation_mixin.py +1 -0
- angr/storage/memory_mixins/regioned_memory/__init__.py +1 -0
- angr/storage/memory_mixins/regioned_memory/abstract_address_descriptor.py +5 -4
- angr/storage/memory_mixins/regioned_memory/abstract_merger_mixin.py +6 -21
- angr/storage/memory_mixins/regioned_memory/region_category_mixin.py +1 -0
- angr/storage/memory_mixins/regioned_memory/region_data.py +4 -5
- angr/storage/memory_mixins/regioned_memory/region_meta_mixin.py +129 -13
- angr/storage/memory_mixins/regioned_memory/regioned_address_concretization_mixin.py +2 -1
- angr/storage/memory_mixins/regioned_memory/regioned_memory_mixin.py +34 -44
- angr/storage/memory_mixins/regioned_memory/static_find_mixin.py +7 -9
- angr/storage/memory_mixins/simple_interface_mixin.py +8 -11
- angr/storage/memory_mixins/simplification_mixin.py +1 -0
- angr/storage/memory_mixins/size_resolution_mixin.py +5 -4
- angr/storage/memory_mixins/slotted_memory.py +3 -3
- angr/storage/memory_mixins/smart_find_mixin.py +3 -2
- angr/storage/memory_mixins/symbolic_merger_mixin.py +1 -0
- angr/storage/memory_mixins/top_merger_mixin.py +2 -2
- angr/storage/memory_mixins/underconstrained_mixin.py +12 -14
- angr/storage/memory_mixins/unwrapper_mixin.py +1 -0
- angr/storage/memory_object.py +35 -35
- angr/storage/pcap.py +3 -3
- angr/tablespecs.py +1 -0
- angr/utils/__init__.py +1 -0
- angr/utils/ail.py +30 -0
- angr/utils/algo.py +1 -0
- angr/utils/bits.py +12 -0
- angr/utils/constants.py +2 -0
- angr/utils/cowdict.py +3 -4
- angr/utils/dynamic_dictlist.py +4 -7
- angr/utils/endness.py +1 -0
- angr/utils/enums_conv.py +1 -0
- angr/utils/env.py +1 -0
- angr/utils/formatting.py +1 -0
- angr/utils/funcid.py +15 -14
- angr/utils/graph.py +52 -19
- angr/utils/lazy_import.py +1 -0
- angr/utils/library.py +10 -13
- angr/utils/loader.py +6 -6
- angr/utils/mp.py +4 -3
- angr/utils/orderedset.py +1 -0
- angr/utils/segment_list.py +7 -9
- angr/utils/ssa/__init__.py +198 -0
- angr/utils/ssa/tmp_uses_collector.py +23 -0
- angr/utils/ssa/vvar_uses_collector.py +37 -0
- angr/utils/timing.py +32 -20
- angr/utils/typing.py +1 -0
- angr/vaults.py +7 -8
- {angr-9.2.117.dist-info → angr-9.2.119.dist-info}/METADATA +9 -8
- angr-9.2.119.dist-info/RECORD +1345 -0
- {angr-9.2.117.dist-info → angr-9.2.119.dist-info}/WHEEL +1 -1
- angr/analyses/decompiler/optimization_passes/spilled_register_finder.py +0 -18
- angr/analyses/decompiler/seq_cf_structure_counter.py +0 -37
- angr/service.py +0 -35
- angr-9.2.117.dist-info/RECORD +0 -1310
- {angr-9.2.117.dist-info → angr-9.2.119.dist-info}/LICENSE +0 -0
- {angr-9.2.117.dist-info → angr-9.2.119.dist-info}/entry_points.txt +0 -0
- {angr-9.2.117.dist-info → angr-9.2.119.dist-info}/top_level.txt +0 -0
|
@@ -1,8 +1,12 @@
|
|
|
1
|
-
# pylint:disable=too-many-boolean-expressions
|
|
2
|
-
from
|
|
1
|
+
# pylint:disable=too-many-boolean-expressions,consider-using-enumerate
|
|
2
|
+
from __future__ import annotations
|
|
3
|
+
from typing import Any, TYPE_CHECKING
|
|
4
|
+
from collections.abc import Iterable
|
|
3
5
|
from collections import defaultdict
|
|
4
6
|
import logging
|
|
5
7
|
|
|
8
|
+
import networkx
|
|
9
|
+
|
|
6
10
|
from ailment import AILBlockWalker
|
|
7
11
|
from ailment.block import Block
|
|
8
12
|
from ailment.statement import Statement, Assignment, Store, Call, ConditionalJump, DirtyStatement
|
|
@@ -17,14 +21,16 @@ from ailment.expression import (
|
|
|
17
21
|
Tmp,
|
|
18
22
|
Const,
|
|
19
23
|
BinaryOp,
|
|
24
|
+
VirtualVariable,
|
|
25
|
+
Phi,
|
|
20
26
|
)
|
|
21
27
|
|
|
22
|
-
from
|
|
28
|
+
from angr.analyses.s_reaching_definitions import SRDAModel
|
|
29
|
+
from angr.utils.ail import is_phi_assignment, HasExprWalker
|
|
23
30
|
from ...code_location import CodeLocation, ExternalCodeLocation
|
|
24
|
-
from ...sim_variable import SimStackVariable, SimMemoryVariable
|
|
31
|
+
from ...sim_variable import SimStackVariable, SimMemoryVariable, SimVariable
|
|
25
32
|
from ...knowledge_plugins.propagations.states import Equivalence
|
|
26
33
|
from ...knowledge_plugins.key_definitions import atoms
|
|
27
|
-
from ...knowledge_plugins.key_definitions.atoms import Register as RegisterAtom
|
|
28
34
|
from ...knowledge_plugins.key_definitions.definition import Definition
|
|
29
35
|
from ...knowledge_plugins.key_definitions.constants import OP_BEFORE
|
|
30
36
|
from ...errors import AngrRuntimeError
|
|
@@ -33,11 +39,10 @@ from .ailgraph_walker import AILGraphWalker
|
|
|
33
39
|
from .expression_narrower import ExpressionNarrowingWalker
|
|
34
40
|
from .block_simplifier import BlockSimplifier
|
|
35
41
|
from .ccall_rewriters import CCALL_REWRITERS
|
|
36
|
-
from .expression_counters import SingleExpressionCounter
|
|
42
|
+
from .counters.expression_counters import SingleExpressionCounter
|
|
37
43
|
|
|
38
44
|
if TYPE_CHECKING:
|
|
39
45
|
from ailment.manager import Manager
|
|
40
|
-
from angr.analyses.reaching_definitions import ReachingDefinitionsModel
|
|
41
46
|
|
|
42
47
|
|
|
43
48
|
_l = logging.getLogger(__name__)
|
|
@@ -49,6 +54,12 @@ class HasCallNotification(Exception):
|
|
|
49
54
|
"""
|
|
50
55
|
|
|
51
56
|
|
|
57
|
+
class HasVVarNotification(Exception):
|
|
58
|
+
"""
|
|
59
|
+
Notifies the existence of a VirtualVariable.
|
|
60
|
+
"""
|
|
61
|
+
|
|
62
|
+
|
|
52
63
|
class AILBlockTempCollector(AILBlockWalker):
|
|
53
64
|
"""
|
|
54
65
|
Collects any temporaries used in a block.
|
|
@@ -65,6 +76,26 @@ class AILBlockTempCollector(AILBlockWalker):
|
|
|
65
76
|
self.temps.add(expr)
|
|
66
77
|
|
|
67
78
|
|
|
79
|
+
class ExprNarrowingInfo:
|
|
80
|
+
"""
|
|
81
|
+
Stores the analysis result of _narrowing_needed().
|
|
82
|
+
"""
|
|
83
|
+
|
|
84
|
+
__slots__ = ("narrowable", "to_size", "use_exprs", "phi_vars")
|
|
85
|
+
|
|
86
|
+
def __init__(
|
|
87
|
+
self,
|
|
88
|
+
narrowable: bool,
|
|
89
|
+
to_size: int | None = None,
|
|
90
|
+
use_exprs: list[tuple[atoms.VirtualVariable, CodeLocation, tuple[str, tuple[Expression, ...]]]] | None = None,
|
|
91
|
+
phi_vars: set[atoms.VirtualVariable] | None = None,
|
|
92
|
+
):
|
|
93
|
+
self.narrowable = narrowable
|
|
94
|
+
self.to_size = to_size
|
|
95
|
+
self.use_exprs = use_exprs
|
|
96
|
+
self.phi_vars = phi_vars
|
|
97
|
+
|
|
98
|
+
|
|
68
99
|
class AILSimplifier(Analysis):
|
|
69
100
|
"""
|
|
70
101
|
Perform function-level simplifications.
|
|
@@ -77,29 +108,33 @@ class AILSimplifier(Analysis):
|
|
|
77
108
|
remove_dead_memdefs=False,
|
|
78
109
|
stack_arg_offsets: set[tuple[int, int]] | None = None,
|
|
79
110
|
unify_variables=False,
|
|
80
|
-
ail_manager:
|
|
111
|
+
ail_manager: Manager | None = None,
|
|
81
112
|
gp: int | None = None,
|
|
82
113
|
narrow_expressions=False,
|
|
83
114
|
only_consts=False,
|
|
84
115
|
fold_callexprs_into_conditions=False,
|
|
85
116
|
use_callee_saved_regs_at_return=True,
|
|
86
117
|
rewrite_ccalls=True,
|
|
118
|
+
removed_vvar_ids: set[int] | None = None,
|
|
119
|
+
arg_vvars: dict[int, tuple[VirtualVariable, SimVariable]] | None = None,
|
|
87
120
|
):
|
|
88
121
|
self.func = func
|
|
89
122
|
self.func_graph = func_graph if func_graph is not None else func.graph
|
|
90
|
-
self._reaching_definitions:
|
|
123
|
+
self._reaching_definitions: SRDAModel | None = None
|
|
91
124
|
self._propagator = None
|
|
92
125
|
|
|
93
126
|
self._remove_dead_memdefs = remove_dead_memdefs
|
|
94
127
|
self._stack_arg_offsets = stack_arg_offsets
|
|
95
128
|
self._unify_vars = unify_variables
|
|
96
|
-
self._ail_manager = ail_manager
|
|
129
|
+
self._ail_manager: Manager | None = ail_manager
|
|
97
130
|
self._gp = gp
|
|
98
131
|
self._narrow_expressions = narrow_expressions
|
|
99
132
|
self._only_consts = only_consts
|
|
100
133
|
self._fold_callexprs_into_conditions = fold_callexprs_into_conditions
|
|
101
134
|
self._use_callee_saved_regs_at_return = use_callee_saved_regs_at_return
|
|
102
135
|
self._should_rewrite_ccalls = rewrite_ccalls
|
|
136
|
+
self._removed_vvar_ids = removed_vvar_ids if removed_vvar_ids is not None else set()
|
|
137
|
+
self._arg_vvars = arg_vvars
|
|
103
138
|
|
|
104
139
|
self._calls_to_remove: set[CodeLocation] = set()
|
|
105
140
|
self._assignments_to_remove: set[CodeLocation] = set()
|
|
@@ -110,6 +145,14 @@ class AILSimplifier(Analysis):
|
|
|
110
145
|
|
|
111
146
|
def _simplify(self):
|
|
112
147
|
if self._narrow_expressions:
|
|
148
|
+
_l.debug("Removing dead assignments before narrowing expressions")
|
|
149
|
+
r = self._remove_dead_assignments()
|
|
150
|
+
if r:
|
|
151
|
+
_l.debug("... dead assignments removed")
|
|
152
|
+
self.simplified = True
|
|
153
|
+
self._rebuild_func_graph()
|
|
154
|
+
self._clear_cache()
|
|
155
|
+
|
|
113
156
|
_l.debug("Narrowing expressions")
|
|
114
157
|
narrowed_exprs = self._narrow_exprs()
|
|
115
158
|
self.simplified |= narrowed_exprs
|
|
@@ -162,6 +205,7 @@ class AILSimplifier(Analysis):
|
|
|
162
205
|
_l.debug("... call expressions folded")
|
|
163
206
|
self.simplified = True
|
|
164
207
|
self._rebuild_func_graph()
|
|
208
|
+
self._clear_cache()
|
|
165
209
|
|
|
166
210
|
_l.debug("Removing dead assignments")
|
|
167
211
|
r = self._remove_dead_assignments()
|
|
@@ -177,18 +221,15 @@ class AILSimplifier(Analysis):
|
|
|
177
221
|
AILGraphWalker(self.func_graph, _handler, replace_nodes=True).walk()
|
|
178
222
|
self.blocks = {}
|
|
179
223
|
|
|
180
|
-
def _compute_reaching_definitions(self) ->
|
|
224
|
+
def _compute_reaching_definitions(self) -> SRDAModel:
|
|
181
225
|
# Computing reaching definitions or return the cached one
|
|
182
226
|
if self._reaching_definitions is not None:
|
|
183
227
|
return self._reaching_definitions
|
|
184
|
-
rd = self.project.analyses.
|
|
228
|
+
rd = self.project.analyses.SReachingDefinitions(
|
|
185
229
|
subject=self.func,
|
|
186
230
|
func_graph=self.func_graph,
|
|
187
|
-
#
|
|
188
|
-
|
|
189
|
-
use_callee_saved_regs_at_return=self._use_callee_saved_regs_at_return,
|
|
190
|
-
track_tmps=True,
|
|
191
|
-
element_limit=1,
|
|
231
|
+
# use_callee_saved_regs_at_return=self._use_callee_saved_regs_at_return,
|
|
232
|
+
# track_tmps=True,
|
|
192
233
|
).model
|
|
193
234
|
self._reaching_definitions = rd
|
|
194
235
|
return rd
|
|
@@ -197,17 +238,47 @@ class AILSimplifier(Analysis):
|
|
|
197
238
|
# Propagate expressions or return the existing result
|
|
198
239
|
if self._propagator is not None:
|
|
199
240
|
return self._propagator
|
|
200
|
-
prop = self.project.analyses.
|
|
201
|
-
|
|
241
|
+
prop = self.project.analyses.SPropagator(
|
|
242
|
+
subject=self.func,
|
|
202
243
|
func_graph=self.func_graph,
|
|
203
|
-
gp=self._gp,
|
|
244
|
+
# gp=self._gp,
|
|
204
245
|
only_consts=self._only_consts,
|
|
205
|
-
reaching_definitions=self._compute_reaching_definitions(),
|
|
206
246
|
immediate_stmt_removal=immediate_stmt_removal,
|
|
207
247
|
)
|
|
208
248
|
self._propagator = prop
|
|
209
249
|
return prop
|
|
210
250
|
|
|
251
|
+
def _compute_equivalence(self) -> set[Equivalence]:
|
|
252
|
+
equivalence = set()
|
|
253
|
+
for block in self.func_graph:
|
|
254
|
+
for stmt_idx, stmt in enumerate(block.statements):
|
|
255
|
+
if isinstance(stmt, Assignment):
|
|
256
|
+
if isinstance(stmt.dst, VirtualVariable) and isinstance(
|
|
257
|
+
stmt.src, (VirtualVariable, Tmp, Call, Convert)
|
|
258
|
+
):
|
|
259
|
+
codeloc = CodeLocation(block.addr, stmt_idx, block_idx=block.idx, ins_addr=stmt.ins_addr)
|
|
260
|
+
equivalence.add(Equivalence(codeloc, stmt.dst, stmt.src))
|
|
261
|
+
elif isinstance(stmt, Call):
|
|
262
|
+
if isinstance(stmt.ret_expr, (VirtualVariable, Load)):
|
|
263
|
+
codeloc = CodeLocation(block.addr, stmt_idx, block_idx=block.idx, ins_addr=stmt.ins_addr)
|
|
264
|
+
equivalence.add(Equivalence(codeloc, stmt.ret_expr, stmt))
|
|
265
|
+
elif (
|
|
266
|
+
isinstance(stmt, Store)
|
|
267
|
+
and isinstance(stmt.size, int)
|
|
268
|
+
and isinstance(stmt.data, (VirtualVariable, Tmp, Call, Convert))
|
|
269
|
+
):
|
|
270
|
+
if isinstance(stmt.addr, StackBaseOffset) and isinstance(stmt.addr.offset, int):
|
|
271
|
+
# stack variable
|
|
272
|
+
atom = SimStackVariable(stmt.addr.offset, stmt.size)
|
|
273
|
+
codeloc = CodeLocation(block.addr, stmt_idx, block_idx=block.idx, ins_addr=stmt.ins_addr)
|
|
274
|
+
equivalence.add(Equivalence(codeloc, atom, stmt.data))
|
|
275
|
+
elif isinstance(stmt.addr, Const):
|
|
276
|
+
# global variable
|
|
277
|
+
atom = SimMemoryVariable(stmt.addr.value, stmt.size)
|
|
278
|
+
codeloc = CodeLocation(block.addr, stmt_idx, block_idx=block.idx, ins_addr=stmt.ins_addr)
|
|
279
|
+
equivalence.add(Equivalence(codeloc, atom, stmt.data))
|
|
280
|
+
return equivalence
|
|
281
|
+
|
|
211
282
|
def _clear_cache(self) -> None:
|
|
212
283
|
self._propagator = None
|
|
213
284
|
self._reaching_definitions = None
|
|
@@ -237,8 +308,9 @@ class AILSimplifier(Analysis):
|
|
|
237
308
|
|
|
238
309
|
rd = self._compute_reaching_definitions()
|
|
239
310
|
sorted_defs = sorted(rd.all_definitions, key=lambda d: d.codeloc, reverse=True)
|
|
311
|
+
narrowing_candidates: dict[int, tuple[Definition, ExprNarrowingInfo]] = {}
|
|
240
312
|
for def_ in (d_ for d_ in sorted_defs if d_.codeloc.context is None):
|
|
241
|
-
if isinstance(def_.atom, atoms.
|
|
313
|
+
if isinstance(def_.atom, atoms.VirtualVariable) and (def_.atom.was_reg or def_.atom.was_parameter):
|
|
242
314
|
# only do this for general purpose register
|
|
243
315
|
skip_def = False
|
|
244
316
|
for reg in self.project.arch.register_list:
|
|
@@ -249,250 +321,511 @@ class AILSimplifier(Analysis):
|
|
|
249
321
|
if skip_def:
|
|
250
322
|
continue
|
|
251
323
|
|
|
252
|
-
|
|
253
|
-
if
|
|
254
|
-
#
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
324
|
+
narrow = self._narrowing_needed(def_, rd, addr_and_idx_to_block)
|
|
325
|
+
if narrow.narrowable:
|
|
326
|
+
# we cannot narrow it immediately because any definition that is used by phi variables must be
|
|
327
|
+
# narrowed together with all other definitions that can reach the phi variables.
|
|
328
|
+
# so we record the information and decide if we are going to narrow these expressions or not at the
|
|
329
|
+
# end of the loop.
|
|
330
|
+
narrowing_candidates[def_.atom.varid] = def_, narrow
|
|
331
|
+
|
|
332
|
+
# first, determine which phi vars need to be narrowed and can be narrowed.
|
|
333
|
+
# a phi var can only be narrowed if all its source vvars are narrowable
|
|
334
|
+
vvar_to_narrowing_size = {}
|
|
335
|
+
for def_varid, (_, narrow_info) in narrowing_candidates.items():
|
|
336
|
+
vvar_to_narrowing_size[def_varid] = narrow_info.to_size
|
|
337
|
+
|
|
338
|
+
blacklist_varids = set()
|
|
339
|
+
while True:
|
|
340
|
+
repeat, narrowables = self._compute_narrowables_once(
|
|
341
|
+
rd, narrowing_candidates, vvar_to_narrowing_size, blacklist_varids
|
|
342
|
+
)
|
|
343
|
+
if not repeat:
|
|
344
|
+
break
|
|
261
345
|
|
|
262
|
-
|
|
263
|
-
stmt = the_block.statements[def_.codeloc.stmt_idx]
|
|
264
|
-
r, new_block = False, None
|
|
265
|
-
if isinstance(stmt, Assignment) and isinstance(stmt.dst, Register):
|
|
266
|
-
tags = dict(stmt.dst.tags)
|
|
267
|
-
tags["reg_name"] = self.project.arch.translate_register_name(
|
|
268
|
-
def_.atom.reg_offset, size=to_size
|
|
269
|
-
)
|
|
270
|
-
tags["write_size"] = stmt.dst.size
|
|
271
|
-
new_assignment_dst = Register(
|
|
272
|
-
stmt.dst.idx,
|
|
273
|
-
None,
|
|
274
|
-
def_.atom.reg_offset,
|
|
275
|
-
to_size * self.project.arch.byte_width,
|
|
276
|
-
**tags,
|
|
277
|
-
)
|
|
278
|
-
new_assignment_src = Convert(
|
|
279
|
-
stmt.src.idx, # FIXME: This is a hack
|
|
280
|
-
stmt.src.bits,
|
|
281
|
-
to_size * self.project.arch.byte_width,
|
|
282
|
-
False,
|
|
283
|
-
stmt.src,
|
|
284
|
-
**stmt.src.tags,
|
|
285
|
-
)
|
|
286
|
-
r, new_block = BlockSimplifier._replace_and_build(
|
|
287
|
-
the_block,
|
|
288
|
-
{
|
|
289
|
-
def_.codeloc: {
|
|
290
|
-
stmt.dst: new_assignment_dst,
|
|
291
|
-
stmt.src: new_assignment_src,
|
|
292
|
-
}
|
|
293
|
-
},
|
|
294
|
-
replace_assignment_dsts=True,
|
|
295
|
-
replace_loads=True,
|
|
296
|
-
)
|
|
297
|
-
elif isinstance(stmt, Call):
|
|
298
|
-
if stmt.ret_expr is not None:
|
|
299
|
-
tags = dict(stmt.ret_expr.tags)
|
|
300
|
-
tags["reg_name"] = self.project.arch.translate_register_name(
|
|
301
|
-
def_.atom.reg_offset, size=to_size
|
|
302
|
-
)
|
|
303
|
-
new_retexpr = Register(
|
|
304
|
-
stmt.ret_expr.idx,
|
|
305
|
-
None,
|
|
306
|
-
def_.atom.reg_offset,
|
|
307
|
-
to_size * self.project.arch.byte_width,
|
|
308
|
-
**tags,
|
|
309
|
-
)
|
|
310
|
-
r, new_block = BlockSimplifier._replace_and_build(
|
|
311
|
-
the_block, {def_.codeloc: {stmt.ret_expr: new_retexpr}}
|
|
312
|
-
)
|
|
313
|
-
if not r:
|
|
314
|
-
# couldn't replace the definition...
|
|
315
|
-
continue
|
|
316
|
-
self.blocks[old_block] = new_block
|
|
346
|
+
replaced_vvar_ids = set()
|
|
317
347
|
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
if isinstance(use_expr_tpl[0], Register) and to_size == use_expr_tpl[0].size:
|
|
321
|
-
# don't replace registers to the same registers
|
|
322
|
-
continue
|
|
348
|
+
# let's narrow them (finally)
|
|
349
|
+
for def_, narrow_info in narrowables:
|
|
323
350
|
|
|
324
|
-
|
|
325
|
-
|
|
351
|
+
# does any uses involve a previously replaced expressions? if so, we have to skip this one because the use
|
|
352
|
+
# expression may no longer exist.
|
|
353
|
+
should_skip = False
|
|
354
|
+
for _, _, (use_type, use_expr_tpl) in narrow_info.use_exprs:
|
|
355
|
+
if use_type == "binop-convert" and self._exprs_contain_vvar(use_expr_tpl, replaced_vvar_ids):
|
|
356
|
+
should_skip = True
|
|
357
|
+
break
|
|
358
|
+
if should_skip:
|
|
359
|
+
continue
|
|
326
360
|
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
361
|
+
# replace the definition
|
|
362
|
+
if not isinstance(def_.codeloc, ExternalCodeLocation):
|
|
363
|
+
old_block = addr_and_idx_to_block.get((def_.codeloc.block_addr, def_.codeloc.block_idx))
|
|
364
|
+
if old_block is None:
|
|
365
|
+
# this definition might be inside a callee function, which is why the block does not exist
|
|
366
|
+
# ignore it
|
|
367
|
+
continue
|
|
368
|
+
|
|
369
|
+
the_block = self.blocks.get(old_block, old_block)
|
|
370
|
+
stmt = the_block.statements[def_.codeloc.stmt_idx]
|
|
371
|
+
r, new_block = False, None
|
|
372
|
+
replaced_vvar: VirtualVariable | None = None
|
|
373
|
+
if is_phi_assignment(stmt):
|
|
374
|
+
new_assignment_dst = VirtualVariable(
|
|
375
|
+
stmt.dst.idx,
|
|
376
|
+
stmt.dst.varid,
|
|
377
|
+
narrow_info.to_size * self.project.arch.byte_width,
|
|
378
|
+
category=def_.atom.category,
|
|
379
|
+
oident=def_.atom.oident,
|
|
380
|
+
**stmt.dst.tags,
|
|
381
|
+
)
|
|
382
|
+
new_src_and_vvars = []
|
|
383
|
+
for src, vvar in stmt.src.src_and_vvars:
|
|
384
|
+
if vvar is not None and vvar.varid == stmt.dst.varid:
|
|
385
|
+
new_vvar = VirtualVariable(
|
|
386
|
+
vvar.idx,
|
|
387
|
+
vvar.varid,
|
|
388
|
+
narrow_info.to_size * self.project.arch.byte_width,
|
|
389
|
+
category=vvar.category,
|
|
390
|
+
oident=vvar.oident,
|
|
391
|
+
**vvar.tags,
|
|
333
392
|
)
|
|
334
|
-
|
|
335
|
-
|
|
393
|
+
else:
|
|
394
|
+
new_vvar = vvar
|
|
395
|
+
new_src_and_vvars.append((src, new_vvar))
|
|
396
|
+
new_assignment_src = Phi(
|
|
397
|
+
stmt.src.idx,
|
|
398
|
+
narrow_info.to_size * self.project.arch.byte_width,
|
|
399
|
+
new_src_and_vvars,
|
|
400
|
+
**stmt.src.tags,
|
|
401
|
+
)
|
|
402
|
+
replaced_vvar = stmt.dst
|
|
403
|
+
r, new_block = BlockSimplifier._replace_and_build(
|
|
404
|
+
the_block,
|
|
405
|
+
{
|
|
406
|
+
def_.codeloc: {
|
|
407
|
+
stmt.dst: new_assignment_dst,
|
|
408
|
+
stmt.src: new_assignment_src,
|
|
409
|
+
}
|
|
410
|
+
},
|
|
411
|
+
replace_assignment_dsts=True,
|
|
412
|
+
replace_loads=True,
|
|
413
|
+
)
|
|
414
|
+
elif isinstance(stmt, Assignment) and isinstance(stmt.dst, VirtualVariable) and stmt.dst.was_reg:
|
|
415
|
+
new_assignment_dst = VirtualVariable(
|
|
416
|
+
stmt.dst.idx,
|
|
417
|
+
stmt.dst.varid,
|
|
418
|
+
narrow_info.to_size * self.project.arch.byte_width,
|
|
419
|
+
category=def_.atom.category,
|
|
420
|
+
oident=def_.atom.oident,
|
|
421
|
+
**stmt.dst.tags,
|
|
422
|
+
)
|
|
423
|
+
new_assignment_src = Convert(
|
|
424
|
+
stmt.src.idx, # FIXME: This is a hack
|
|
425
|
+
stmt.src.bits,
|
|
426
|
+
narrow_info.to_size * self.project.arch.byte_width,
|
|
427
|
+
False,
|
|
428
|
+
stmt.src,
|
|
429
|
+
**stmt.src.tags,
|
|
430
|
+
)
|
|
431
|
+
replaced_vvar = stmt.dst
|
|
432
|
+
r, new_block = BlockSimplifier._replace_and_build(
|
|
433
|
+
the_block,
|
|
434
|
+
{
|
|
435
|
+
def_.codeloc: {
|
|
436
|
+
stmt.dst: new_assignment_dst,
|
|
437
|
+
stmt.src: new_assignment_src,
|
|
438
|
+
}
|
|
439
|
+
},
|
|
440
|
+
replace_assignment_dsts=True,
|
|
441
|
+
replace_loads=True,
|
|
442
|
+
)
|
|
443
|
+
elif isinstance(stmt, Call):
|
|
444
|
+
if stmt.ret_expr is not None:
|
|
445
|
+
tags = dict(stmt.ret_expr.tags)
|
|
446
|
+
tags["reg_name"] = self.project.arch.translate_register_name(
|
|
447
|
+
def_.atom.reg_offset, size=narrow_info.to_size
|
|
448
|
+
)
|
|
449
|
+
replaced_vvar = stmt.ret_expr
|
|
450
|
+
new_retexpr = VirtualVariable(
|
|
451
|
+
stmt.ret_expr.idx,
|
|
452
|
+
stmt.ret_expr.varid,
|
|
453
|
+
narrow_info.to_size * self.project.arch.byte_width,
|
|
454
|
+
category=def_.atom.category,
|
|
455
|
+
oident=def_.atom.oident,
|
|
456
|
+
**stmt.ret_expr.tags,
|
|
457
|
+
)
|
|
458
|
+
r, new_block = BlockSimplifier._replace_and_build(
|
|
459
|
+
the_block, {def_.codeloc: {stmt.ret_expr: new_retexpr}}
|
|
460
|
+
)
|
|
461
|
+
if not r:
|
|
462
|
+
# couldn't replace the definition...
|
|
463
|
+
continue
|
|
464
|
+
self.blocks[old_block] = new_block
|
|
465
|
+
if replaced_vvar is not None:
|
|
466
|
+
replaced_vvar_ids.add(replaced_vvar.varid)
|
|
467
|
+
|
|
468
|
+
use_exprs = list(narrow_info.use_exprs)
|
|
469
|
+
if narrow_info.phi_vars:
|
|
470
|
+
for phi_var in narrow_info.phi_vars:
|
|
471
|
+
loc = rd.all_vvar_definitions[phi_var]
|
|
472
|
+
old_block = addr_and_idx_to_block.get((loc.block_addr, loc.block_idx))
|
|
473
|
+
the_block = self.blocks.get(old_block, old_block)
|
|
474
|
+
stmt = the_block.statements[loc.stmt_idx]
|
|
475
|
+
assert is_phi_assignment(stmt)
|
|
476
|
+
|
|
477
|
+
for _, vvar in stmt.src.src_and_vvars:
|
|
478
|
+
if vvar is not None and vvar.varid == def_.atom.varid:
|
|
479
|
+
use_exprs.append((vvar, loc, ("phi-src-expr", (vvar,))))
|
|
480
|
+
|
|
481
|
+
# replace all uses if necessary
|
|
482
|
+
for use_atom, use_loc, (use_type, use_expr_tpl) in use_exprs:
|
|
483
|
+
if (
|
|
484
|
+
isinstance(use_expr_tpl[0], VirtualVariable)
|
|
485
|
+
and use_expr_tpl[0].was_reg
|
|
486
|
+
and narrow_info.to_size == use_expr_tpl[0].size
|
|
487
|
+
):
|
|
488
|
+
# don't replace registers to the same registers
|
|
489
|
+
continue
|
|
490
|
+
if use_atom.varid != def_.atom.varid:
|
|
491
|
+
# don't replace this use - it will be replaced later
|
|
492
|
+
continue
|
|
493
|
+
|
|
494
|
+
old_block = addr_and_idx_to_block.get((use_loc.block_addr, use_loc.block_idx))
|
|
495
|
+
the_block = self.blocks.get(old_block, old_block)
|
|
496
|
+
|
|
497
|
+
if use_type in {"expr", "mask", "convert"}:
|
|
498
|
+
# the first used expr
|
|
499
|
+
use_expr_0 = use_expr_tpl[0]
|
|
500
|
+
new_use_expr_0 = VirtualVariable(
|
|
501
|
+
use_expr_0.idx,
|
|
502
|
+
def_.atom.varid,
|
|
503
|
+
narrow_info.to_size * self.project.arch.byte_width,
|
|
504
|
+
category=def_.atom.category,
|
|
505
|
+
oident=def_.atom.oident,
|
|
506
|
+
**use_expr_0.tags,
|
|
507
|
+
)
|
|
508
|
+
new_use_expr = new_use_expr_0
|
|
509
|
+
|
|
510
|
+
# the second used expr (if it exists)
|
|
511
|
+
if len(use_expr_tpl) == 2:
|
|
512
|
+
use_expr_1 = use_expr_tpl[1]
|
|
513
|
+
assert isinstance(use_expr_1, BinaryOp)
|
|
514
|
+
con = use_expr_1.operands[1]
|
|
515
|
+
assert isinstance(con, Const)
|
|
516
|
+
new_use_expr_1 = BinaryOp(
|
|
517
|
+
use_expr_1.idx,
|
|
518
|
+
use_expr_1.op,
|
|
519
|
+
[
|
|
520
|
+
new_use_expr_0,
|
|
521
|
+
Const(con.idx, con.variable, con.value, new_use_expr_0.bits, **con.tags),
|
|
522
|
+
],
|
|
523
|
+
use_expr_1.signed,
|
|
524
|
+
floating_point=use_expr_1.floating_point,
|
|
525
|
+
rounding_mode=use_expr_1.rounding_mode,
|
|
526
|
+
**use_expr_1.tags,
|
|
527
|
+
)
|
|
528
|
+
|
|
529
|
+
if use_expr_1.size > new_use_expr_1.size:
|
|
530
|
+
new_use_expr_1 = Convert(
|
|
336
531
|
None,
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
532
|
+
new_use_expr_1.bits,
|
|
533
|
+
use_expr_1.bits,
|
|
534
|
+
False,
|
|
535
|
+
new_use_expr_1,
|
|
536
|
+
**new_use_expr_1.tags,
|
|
340
537
|
)
|
|
341
538
|
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
new_use_expr_1 = BinaryOp(
|
|
349
|
-
use_expr_1.idx,
|
|
350
|
-
use_expr_1.op,
|
|
351
|
-
[
|
|
352
|
-
new_use_expr_0,
|
|
353
|
-
Const(con.idx, con.variable, con.value, new_use_expr_0.bits, **con.tags),
|
|
354
|
-
],
|
|
355
|
-
use_expr_1.signed,
|
|
356
|
-
floating_point=use_expr_1.floating_point,
|
|
357
|
-
rounding_mode=use_expr_1.rounding_mode,
|
|
358
|
-
**use_expr_1.tags,
|
|
359
|
-
)
|
|
360
|
-
|
|
361
|
-
if use_expr_1.size > new_use_expr_1.size:
|
|
362
|
-
new_use_expr_1 = Convert(
|
|
363
|
-
None,
|
|
364
|
-
new_use_expr_1.bits,
|
|
365
|
-
use_expr_1.bits,
|
|
366
|
-
False,
|
|
367
|
-
new_use_expr_1,
|
|
368
|
-
**new_use_expr_1.tags,
|
|
369
|
-
)
|
|
370
|
-
|
|
371
|
-
r, new_block = BlockSimplifier._replace_and_build(
|
|
372
|
-
the_block, {use_loc: {use_expr_1: new_use_expr_1}}
|
|
373
|
-
)
|
|
374
|
-
elif len(use_expr_tpl) == 1:
|
|
375
|
-
if use_expr_0.size > new_use_expr_0.size:
|
|
376
|
-
new_use_expr_0 = Convert(
|
|
377
|
-
None,
|
|
378
|
-
new_use_expr_0.bits,
|
|
379
|
-
use_expr_0.bits,
|
|
380
|
-
False,
|
|
381
|
-
new_use_expr_0,
|
|
382
|
-
**new_use_expr_0.tags,
|
|
383
|
-
)
|
|
384
|
-
|
|
385
|
-
r, new_block = BlockSimplifier._replace_and_build(
|
|
386
|
-
the_block, {use_loc: {use_expr_0: new_use_expr_0}}
|
|
387
|
-
)
|
|
388
|
-
else:
|
|
389
|
-
_l.warning("Nothing to replace at %s.", use_loc)
|
|
390
|
-
r = False
|
|
391
|
-
new_block = None
|
|
392
|
-
elif use_type == "binop-convert":
|
|
393
|
-
use_expr_0 = use_expr_tpl[0]
|
|
394
|
-
tags = dict(use_expr_0.tags)
|
|
395
|
-
tags["reg_name"] = self.project.arch.translate_register_name(
|
|
396
|
-
def_.atom.reg_offset, size=to_size
|
|
397
|
-
)
|
|
398
|
-
new_use_expr_0 = Register(
|
|
399
|
-
use_expr_0.idx,
|
|
539
|
+
r, new_block = BlockSimplifier._replace_and_build(
|
|
540
|
+
the_block, {use_loc: {use_expr_1: new_use_expr_1}}
|
|
541
|
+
)
|
|
542
|
+
elif len(use_expr_tpl) == 1:
|
|
543
|
+
if use_expr_0.size > new_use_expr_0.size:
|
|
544
|
+
new_use_expr_0 = Convert(
|
|
400
545
|
None,
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
546
|
+
new_use_expr_0.bits,
|
|
547
|
+
use_expr_0.bits,
|
|
548
|
+
False,
|
|
549
|
+
new_use_expr_0,
|
|
550
|
+
**new_use_expr_0.tags,
|
|
404
551
|
)
|
|
405
552
|
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
553
|
+
r, new_block = BlockSimplifier._replace_and_build(
|
|
554
|
+
the_block, {use_loc: {use_expr_0: new_use_expr_0}}
|
|
555
|
+
)
|
|
556
|
+
else:
|
|
557
|
+
_l.warning("Nothing to replace at %s.", use_loc)
|
|
558
|
+
r = False
|
|
559
|
+
new_block = None
|
|
560
|
+
|
|
561
|
+
elif use_type == "phi-src-expr":
|
|
562
|
+
# the size of the replaced variable will be different from its original size, and it's expected
|
|
563
|
+
use_expr = use_expr_tpl[0]
|
|
564
|
+
new_use_expr = VirtualVariable(
|
|
565
|
+
use_expr.idx,
|
|
566
|
+
def_.atom.varid,
|
|
567
|
+
narrow_info.to_size * self.project.arch.byte_width,
|
|
568
|
+
category=def_.atom.category,
|
|
569
|
+
oident=def_.atom.oident,
|
|
570
|
+
**use_expr.tags,
|
|
571
|
+
)
|
|
572
|
+
r, new_block = BlockSimplifier._replace_and_build(the_block, {use_loc: {use_expr: new_use_expr}})
|
|
573
|
+
|
|
574
|
+
elif use_type == "binop-convert":
|
|
575
|
+
use_expr_0 = use_expr_tpl[0]
|
|
576
|
+
new_use_expr_0 = VirtualVariable(
|
|
577
|
+
use_expr_0.idx,
|
|
578
|
+
def_.atom.varid,
|
|
579
|
+
narrow_info.to_size * self.project.arch.byte_width,
|
|
580
|
+
category=def_.atom.category,
|
|
581
|
+
oident=def_.atom.oident,
|
|
582
|
+
**use_expr_0.tags,
|
|
583
|
+
)
|
|
584
|
+
new_use_expr = new_use_expr_0
|
|
585
|
+
|
|
586
|
+
use_expr_1: BinaryOp = use_expr_tpl[1]
|
|
587
|
+
# build the new use_expr_1
|
|
588
|
+
new_use_expr_1_operands = {}
|
|
589
|
+
if use_expr_1.operands[0] is use_expr_0:
|
|
590
|
+
new_use_expr_1_operands[0] = new_use_expr_0
|
|
591
|
+
other_operand = use_expr_1.operands[1]
|
|
592
|
+
else:
|
|
593
|
+
new_use_expr_1_operands[1] = new_use_expr_0
|
|
594
|
+
other_operand = use_expr_1.operands[0]
|
|
595
|
+
use_expr_2: Convert = use_expr_tpl[2]
|
|
596
|
+
if other_operand.bits == use_expr_2.from_bits:
|
|
597
|
+
new_other_operand = Convert(
|
|
598
|
+
None, use_expr_2.from_bits, use_expr_2.to_bits, False, other_operand
|
|
599
|
+
)
|
|
600
|
+
else:
|
|
601
|
+
# Some operations, like Sar and Shl, have operands with different sizes
|
|
602
|
+
new_other_operand = other_operand
|
|
440
603
|
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
604
|
+
if 0 in new_use_expr_1_operands:
|
|
605
|
+
new_use_expr_1_operands[1] = new_other_operand
|
|
606
|
+
else:
|
|
607
|
+
new_use_expr_1_operands[0] = new_other_operand
|
|
608
|
+
|
|
609
|
+
# build new use_expr_1
|
|
610
|
+
new_use_expr_1 = BinaryOp(
|
|
611
|
+
use_expr_1.idx,
|
|
612
|
+
use_expr_1.op,
|
|
613
|
+
[new_use_expr_1_operands[0], new_use_expr_1_operands[1]],
|
|
614
|
+
use_expr_1.signed,
|
|
615
|
+
bits=narrow_info.to_size * 8,
|
|
616
|
+
floating_point=use_expr_1.floating_point,
|
|
617
|
+
rounding_mode=use_expr_1.rounding_mode,
|
|
618
|
+
**use_expr_1.tags,
|
|
619
|
+
)
|
|
452
620
|
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
621
|
+
# first remove the old conversion
|
|
622
|
+
r, new_block = BlockSimplifier._replace_and_build(
|
|
623
|
+
the_block, {use_loc: {use_expr_2: use_expr_2.operand}}
|
|
624
|
+
)
|
|
625
|
+
# then replace use_expr_1
|
|
626
|
+
if r:
|
|
627
|
+
r, new_block = BlockSimplifier._replace_and_build(
|
|
628
|
+
new_block, {use_loc: {use_expr_1: new_use_expr_1}}
|
|
629
|
+
)
|
|
630
|
+
else:
|
|
631
|
+
raise TypeError(f'Unsupported use_type value "{use_type}"')
|
|
457
632
|
|
|
458
|
-
|
|
633
|
+
if not r:
|
|
634
|
+
_l.warning("Failed to replace use-expr at %s.", use_loc)
|
|
635
|
+
else:
|
|
636
|
+
# update self._arg_vvars if necessary
|
|
637
|
+
if new_use_expr is not None and new_use_expr.was_parameter and self._arg_vvars:
|
|
638
|
+
for func_arg_idx in list(self._arg_vvars):
|
|
639
|
+
vvar, simvar = self._arg_vvars[func_arg_idx]
|
|
640
|
+
if vvar.varid == new_use_expr.varid:
|
|
641
|
+
simvar_new = simvar.copy()
|
|
642
|
+
simvar_new._hash = None
|
|
643
|
+
simvar_new.size = new_use_expr.size
|
|
644
|
+
self._arg_vvars[func_arg_idx] = new_use_expr, simvar_new
|
|
645
|
+
|
|
646
|
+
self.blocks[old_block] = new_block
|
|
647
|
+
|
|
648
|
+
narrowed = True
|
|
459
649
|
|
|
460
650
|
return narrowed
|
|
461
651
|
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
652
|
+
@staticmethod
|
|
653
|
+
def _compute_narrowables_once(
|
|
654
|
+
rd, narrowing_candidates: dict, vvar_to_narrowing_size: dict[int, int], blacklist_varids: set
|
|
655
|
+
):
|
|
656
|
+
repeat = False
|
|
657
|
+
narrowable_phivarids = set()
|
|
658
|
+
for def_vvarid, (_, narrow_info) in narrowing_candidates.items():
|
|
659
|
+
if def_vvarid in blacklist_varids:
|
|
660
|
+
continue
|
|
661
|
+
if def_vvarid in rd.phi_vvar_ids:
|
|
662
|
+
narrowing_sizes = set()
|
|
663
|
+
src_vvarids = rd.phivarid_to_varids[def_vvarid]
|
|
664
|
+
for vvarid in src_vvarids:
|
|
665
|
+
if vvarid in blacklist_varids:
|
|
666
|
+
narrowing_sizes.add(None)
|
|
667
|
+
else:
|
|
668
|
+
narrowing_sizes.add(vvar_to_narrowing_size.get(vvarid))
|
|
669
|
+
if len(narrowing_sizes) == 1 and None not in narrowing_sizes:
|
|
670
|
+
# we can narrow this phi vvar!
|
|
671
|
+
narrowable_phivarids.add(def_vvarid)
|
|
672
|
+
|
|
673
|
+
# now determine what to narrow!
|
|
674
|
+
narrowables = []
|
|
675
|
+
|
|
676
|
+
for def_, narrow_info in narrowing_candidates.values():
|
|
677
|
+
if def_.atom.varid in blacklist_varids:
|
|
678
|
+
continue
|
|
679
|
+
if not narrow_info.phi_vars:
|
|
680
|
+
# not used by any other phi variables. good!
|
|
681
|
+
narrowables.append((def_, narrow_info))
|
|
682
|
+
else:
|
|
683
|
+
if {phivar.varid for phivar in narrow_info.phi_vars}.issubset(narrowable_phivarids):
|
|
684
|
+
# all phi vvars that use this definition can be narrowed
|
|
685
|
+
narrowables.append((def_, narrow_info))
|
|
686
|
+
else:
|
|
687
|
+
# this vvar cannot be narrowed
|
|
688
|
+
# note that all phi variables that relies on this vvar also cannot be narrowed! we must analyze
|
|
689
|
+
# again
|
|
690
|
+
repeat = True
|
|
691
|
+
blacklist_varids.add(def_.atom.varid)
|
|
692
|
+
blacklist_varids |= {phivar.varid for phivar in narrow_info.phi_vars}
|
|
693
|
+
|
|
694
|
+
return repeat, narrowables
|
|
695
|
+
|
|
696
|
+
def _narrowing_needed(self, def_, rd: SRDAModel, addr_and_idx_to_block) -> ExprNarrowingInfo:
|
|
697
|
+
|
|
465
698
|
def_size = def_.size
|
|
466
699
|
# find its uses
|
|
467
|
-
|
|
700
|
+
# some use locations are phi assignments. we keep tracking the uses of phi variables and update the dictionary
|
|
701
|
+
result = self._get_vvar_use_and_exprs_recursive(def_.atom, rd, addr_and_idx_to_block)
|
|
702
|
+
if result is None:
|
|
703
|
+
return ExprNarrowingInfo(False)
|
|
704
|
+
use_and_exprs, phi_vars = result
|
|
468
705
|
|
|
469
706
|
all_used_sizes = set()
|
|
470
|
-
used_by: list[tuple[CodeLocation, tuple[str, tuple[Expression, ...]]]] = []
|
|
707
|
+
used_by: list[tuple[atoms.VirtualVariable, CodeLocation, tuple[str, tuple[Expression, ...]]]] = []
|
|
708
|
+
used_by_loc = defaultdict(list)
|
|
471
709
|
|
|
472
|
-
for loc, expr in use_and_exprs:
|
|
710
|
+
for atom, loc, expr in use_and_exprs:
|
|
473
711
|
old_block = addr_and_idx_to_block.get((loc.block_addr, loc.block_idx), None)
|
|
474
712
|
if old_block is None:
|
|
475
713
|
# missing a block for whatever reason
|
|
476
|
-
return False
|
|
714
|
+
return ExprNarrowingInfo(False)
|
|
477
715
|
|
|
478
716
|
block = self.blocks.get(old_block, old_block)
|
|
479
717
|
if loc.stmt_idx >= len(block.statements):
|
|
480
718
|
# missing a statement for whatever reason
|
|
481
|
-
return False
|
|
719
|
+
return ExprNarrowingInfo(False)
|
|
482
720
|
stmt = block.statements[loc.stmt_idx]
|
|
483
721
|
|
|
722
|
+
# special case: if the statement is a Call statement and expr is None, it means we have not been able to
|
|
723
|
+
# determine if the expression is really used by the call or not. skip it in this case
|
|
724
|
+
if isinstance(stmt, Call) and expr is None:
|
|
725
|
+
continue
|
|
726
|
+
# special case: if the statement is a phi statement, we ignore it
|
|
727
|
+
if is_phi_assignment(stmt):
|
|
728
|
+
continue
|
|
729
|
+
|
|
484
730
|
expr_size, used_by_exprs = self._extract_expression_effective_size(stmt, expr)
|
|
485
731
|
if expr_size is None:
|
|
486
732
|
# it's probably used in full width
|
|
487
|
-
return False
|
|
733
|
+
return ExprNarrowingInfo(False)
|
|
488
734
|
|
|
489
735
|
all_used_sizes.add(expr_size)
|
|
490
|
-
|
|
736
|
+
used_by_loc[loc].append((atom, used_by_exprs))
|
|
491
737
|
|
|
492
738
|
if len(all_used_sizes) == 1 and next(iter(all_used_sizes)) < def_size:
|
|
493
|
-
|
|
739
|
+
for loc, atom_expr_pairs in used_by_loc.items():
|
|
740
|
+
if len(atom_expr_pairs) == 1:
|
|
741
|
+
atom, used_by_exprs = atom_expr_pairs[0]
|
|
742
|
+
used_by.append((atom, loc, used_by_exprs))
|
|
743
|
+
else:
|
|
744
|
+
# the order matters - we must replace the outer expressions first, then replace the inner
|
|
745
|
+
# expressions. replacing in the wrong order will lead to expressions that are not replaced in the
|
|
746
|
+
# end.
|
|
747
|
+
ordered = []
|
|
748
|
+
for atom, used_by_exprs in atom_expr_pairs:
|
|
749
|
+
last_inclusion = len(ordered) - 1 # by default we append at the end of the list
|
|
750
|
+
for idx in range(len(ordered)):
|
|
751
|
+
if self._is_expr0_included_in_expr1(ordered[idx][1], used_by_exprs):
|
|
752
|
+
# this element must be inserted before idx
|
|
753
|
+
ordered.insert(idx, (atom, used_by_exprs))
|
|
754
|
+
break
|
|
755
|
+
if self._is_expr0_included_in_expr1(used_by_exprs, ordered[idx][1]):
|
|
756
|
+
# this element can be inserted after this element. record the index
|
|
757
|
+
last_inclusion = idx
|
|
758
|
+
else:
|
|
759
|
+
ordered.insert(last_inclusion + 1, (atom, used_by_exprs))
|
|
494
760
|
|
|
495
|
-
|
|
761
|
+
for atom, used_by_exprs in ordered:
|
|
762
|
+
used_by.append((atom, loc, used_by_exprs))
|
|
763
|
+
|
|
764
|
+
return ExprNarrowingInfo(True, to_size=next(iter(all_used_sizes)), use_exprs=used_by, phi_vars=phi_vars)
|
|
765
|
+
|
|
766
|
+
return ExprNarrowingInfo(False)
|
|
767
|
+
|
|
768
|
+
@staticmethod
|
|
769
|
+
def _exprs_from_used_by_exprs(used_by_exprs) -> set[Expression]:
|
|
770
|
+
use_type, expr_tuple = used_by_exprs
|
|
771
|
+
match use_type:
|
|
772
|
+
case "expr" | "mask" | "convert":
|
|
773
|
+
return {expr_tuple[1]} if len(expr_tuple) == 2 else {expr_tuple[0]}
|
|
774
|
+
case "phi-src-expr":
|
|
775
|
+
return {expr_tuple[0]}
|
|
776
|
+
case "binop-convert":
|
|
777
|
+
return {expr_tuple[0], expr_tuple[1]}
|
|
778
|
+
case _:
|
|
779
|
+
return set()
|
|
780
|
+
|
|
781
|
+
def _is_expr0_included_in_expr1(self, used_by_exprs0, used_by_exprs1) -> bool:
|
|
782
|
+
# extract expressions
|
|
783
|
+
exprs0 = self._exprs_from_used_by_exprs(used_by_exprs0)
|
|
784
|
+
exprs1 = self._exprs_from_used_by_exprs(used_by_exprs1)
|
|
785
|
+
|
|
786
|
+
# test for inclusion
|
|
787
|
+
for expr1 in exprs1:
|
|
788
|
+
walker = HasExprWalker(exprs0)
|
|
789
|
+
walker.walk_expression(expr1)
|
|
790
|
+
if walker.contains_exprs:
|
|
791
|
+
return True
|
|
792
|
+
return False
|
|
793
|
+
|
|
794
|
+
def _get_vvar_use_and_exprs_recursive(
|
|
795
|
+
self, initial_atom: atoms.VirtualVariable, rd, block_dict: dict[tuple[int, int | None], Block]
|
|
796
|
+
) -> tuple[list[tuple[atoms.VirtualVariable, CodeLocation, Expression]], set[VirtualVariable]] | None:
|
|
797
|
+
result = []
|
|
798
|
+
atom_queue = [initial_atom]
|
|
799
|
+
phi_vars = set()
|
|
800
|
+
seen = set()
|
|
801
|
+
while atom_queue:
|
|
802
|
+
atom = atom_queue.pop(0)
|
|
803
|
+
seen.add(atom)
|
|
804
|
+
|
|
805
|
+
use_and_exprs = rd.get_vvar_uses_with_expr(atom)
|
|
806
|
+
|
|
807
|
+
for loc, expr in use_and_exprs:
|
|
808
|
+
old_block = block_dict.get((loc.block_addr, loc.block_idx), None)
|
|
809
|
+
if old_block is None:
|
|
810
|
+
# missing a block for whatever reason
|
|
811
|
+
return None
|
|
812
|
+
|
|
813
|
+
block: Block = self.blocks.get(old_block, old_block)
|
|
814
|
+
if loc.stmt_idx >= len(block.statements):
|
|
815
|
+
# missing a statement for whatever reason
|
|
816
|
+
return None
|
|
817
|
+
stmt = block.statements[loc.stmt_idx]
|
|
818
|
+
|
|
819
|
+
if is_phi_assignment(stmt):
|
|
820
|
+
phi_vars.add(stmt.dst)
|
|
821
|
+
new_atom = atoms.VirtualVariable(
|
|
822
|
+
stmt.dst.varid, stmt.dst.size, stmt.dst.category, oident=stmt.dst.oident
|
|
823
|
+
)
|
|
824
|
+
if new_atom not in seen:
|
|
825
|
+
atom_queue.append(new_atom)
|
|
826
|
+
else:
|
|
827
|
+
result.append((atom, loc, expr))
|
|
828
|
+
return result, phi_vars
|
|
496
829
|
|
|
497
830
|
def _extract_expression_effective_size(
|
|
498
831
|
self, statement, expr
|
|
@@ -509,10 +842,9 @@ class AILSimplifier(Analysis):
|
|
|
509
842
|
return expr.size, ("expr", (expr,))
|
|
510
843
|
|
|
511
844
|
first_op = walker.operations[0]
|
|
512
|
-
if isinstance(first_op, Convert):
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
return first_op.to_bits // self.project.arch.byte_width, ("convert", (first_op,))
|
|
845
|
+
if isinstance(first_op, Convert) and first_op.to_bits >= self.project.arch.byte_width:
|
|
846
|
+
# we need at least one byte!
|
|
847
|
+
return first_op.to_bits // self.project.arch.byte_width, ("convert", (first_op,))
|
|
516
848
|
if isinstance(first_op, BinaryOp):
|
|
517
849
|
second_op = None
|
|
518
850
|
if len(walker.operations) >= 2:
|
|
@@ -551,7 +883,7 @@ class AILSimplifier(Analysis):
|
|
|
551
883
|
|
|
552
884
|
def _fold_exprs(self):
|
|
553
885
|
"""
|
|
554
|
-
Fold expressions: Fold assigned expressions that are only used once.
|
|
886
|
+
Fold expressions: Fold assigned expressions that are constant or only used once.
|
|
555
887
|
"""
|
|
556
888
|
|
|
557
889
|
# propagator
|
|
@@ -603,8 +935,8 @@ class AILSimplifier(Analysis):
|
|
|
603
935
|
|
|
604
936
|
simplified = False
|
|
605
937
|
|
|
606
|
-
|
|
607
|
-
if not
|
|
938
|
+
equivalence = self._compute_equivalence()
|
|
939
|
+
if not equivalence:
|
|
608
940
|
return simplified
|
|
609
941
|
|
|
610
942
|
addr_and_idx_to_block: dict[tuple[int, int], Block] = {}
|
|
@@ -613,7 +945,7 @@ class AILSimplifier(Analysis):
|
|
|
613
945
|
|
|
614
946
|
equivalences: dict[Any, set[Equivalence]] = defaultdict(set)
|
|
615
947
|
atom_by_loc = set()
|
|
616
|
-
for eq in
|
|
948
|
+
for eq in equivalence:
|
|
617
949
|
equivalences[eq.atom1].add(eq)
|
|
618
950
|
atom_by_loc.add((eq.codeloc, eq.atom1))
|
|
619
951
|
|
|
@@ -637,20 +969,37 @@ class AILSimplifier(Analysis):
|
|
|
637
969
|
# Equivalence is generally created at assignment sites. Therefore, eq.atom0 is the definition and
|
|
638
970
|
# eq.atom1 is the use.
|
|
639
971
|
the_def = None
|
|
640
|
-
if isinstance(eq.atom0,
|
|
641
|
-
|
|
972
|
+
if (isinstance(eq.atom0, VirtualVariable) and eq.atom0.was_stack) or (
|
|
973
|
+
isinstance(eq.atom0, SimMemoryVariable)
|
|
974
|
+
and not isinstance(eq.atom0, SimStackVariable)
|
|
975
|
+
and isinstance(eq.atom0.addr, int)
|
|
976
|
+
):
|
|
977
|
+
if isinstance(eq.atom1, VirtualVariable) and eq.atom1.was_reg:
|
|
642
978
|
# stack_var == register or global_var == register
|
|
643
979
|
to_replace = eq.atom1
|
|
644
980
|
to_replace_is_def = False
|
|
645
|
-
elif
|
|
981
|
+
elif (
|
|
982
|
+
isinstance(eq.atom0, VirtualVariable)
|
|
983
|
+
and eq.atom0.was_stack
|
|
984
|
+
and isinstance(eq.atom1, VirtualVariable)
|
|
985
|
+
and eq.atom1.was_parameter
|
|
986
|
+
):
|
|
987
|
+
# stack_var == parameter
|
|
988
|
+
to_replace = eq.atom0
|
|
989
|
+
to_replace_is_def = True
|
|
990
|
+
elif (
|
|
991
|
+
isinstance(eq.atom1, Convert)
|
|
992
|
+
and isinstance(eq.atom1.operand, VirtualVariable)
|
|
993
|
+
and eq.atom1.operand.was_reg
|
|
994
|
+
):
|
|
646
995
|
# stack_var == Conv(register, M->N)
|
|
647
996
|
to_replace = eq.atom1.operand
|
|
648
997
|
to_replace_is_def = False
|
|
649
998
|
else:
|
|
650
999
|
continue
|
|
651
1000
|
|
|
652
|
-
elif isinstance(eq.atom0,
|
|
653
|
-
if isinstance(eq.atom1,
|
|
1001
|
+
elif isinstance(eq.atom0, VirtualVariable) and eq.atom0.was_reg:
|
|
1002
|
+
if isinstance(eq.atom1, VirtualVariable) and (eq.atom1.was_reg or eq.atom1.was_parameter):
|
|
654
1003
|
# register == register
|
|
655
1004
|
if self.project.arch.is_artificial_register(eq.atom0.reg_offset, eq.atom0.size):
|
|
656
1005
|
to_replace = eq.atom0
|
|
@@ -664,44 +1013,46 @@ class AILSimplifier(Analysis):
|
|
|
664
1013
|
else:
|
|
665
1014
|
continue
|
|
666
1015
|
|
|
667
|
-
|
|
1016
|
+
assert isinstance(to_replace, VirtualVariable)
|
|
1017
|
+
|
|
1018
|
+
# find the definition of this virtual register
|
|
668
1019
|
rd = self._compute_reaching_definitions()
|
|
669
1020
|
if to_replace_is_def:
|
|
670
1021
|
# find defs
|
|
671
1022
|
defs = []
|
|
672
1023
|
for def_ in rd.all_definitions:
|
|
673
|
-
if def_.
|
|
674
|
-
|
|
675
|
-
if isinstance(def_.atom, atoms.MemoryLocation) and isinstance(
|
|
676
|
-
def_.atom.addr, atoms.SpOffset
|
|
677
|
-
):
|
|
678
|
-
if to_replace.offset == def_.atom.addr.offset:
|
|
679
|
-
defs.append(def_)
|
|
680
|
-
elif isinstance(to_replace, Register):
|
|
681
|
-
if isinstance(def_.atom, atoms.Register) and to_replace.reg_offset == def_.atom.reg_offset:
|
|
682
|
-
defs.append(def_)
|
|
1024
|
+
if def_.atom.varid == to_replace.varid:
|
|
1025
|
+
defs.append(def_)
|
|
683
1026
|
if len(defs) != 1:
|
|
684
1027
|
continue
|
|
685
1028
|
the_def = defs[0]
|
|
686
1029
|
else:
|
|
687
1030
|
# find uses
|
|
688
|
-
defs = rd.
|
|
1031
|
+
defs = rd.get_uses_by_location(eq.codeloc)
|
|
689
1032
|
if len(defs) != 1:
|
|
690
1033
|
# there are multiple defs for this register - we do not support replacing all of them
|
|
691
1034
|
continue
|
|
692
1035
|
for def_ in defs:
|
|
693
1036
|
def_: Definition
|
|
694
|
-
if
|
|
1037
|
+
if (
|
|
1038
|
+
isinstance(def_.atom, atoms.VirtualVariable)
|
|
1039
|
+
and def_.atom.category == to_replace.category
|
|
1040
|
+
and def_.atom.oident == to_replace.oident
|
|
1041
|
+
):
|
|
695
1042
|
# found it!
|
|
696
1043
|
the_def = def_
|
|
697
1044
|
break
|
|
698
1045
|
if the_def is None:
|
|
699
1046
|
continue
|
|
700
|
-
if the_def.codeloc.context:
|
|
1047
|
+
if the_def.codeloc.context: # FIXME: now the_def.codeloc.context is never filled in
|
|
701
1048
|
# the definition is in a callee function
|
|
702
1049
|
continue
|
|
703
1050
|
|
|
704
|
-
if
|
|
1051
|
+
if (
|
|
1052
|
+
isinstance(the_def.codeloc, ExternalCodeLocation)
|
|
1053
|
+
or isinstance(eq.atom1, VirtualVariable)
|
|
1054
|
+
and eq.atom1.was_parameter
|
|
1055
|
+
):
|
|
705
1056
|
# this is a function argument. we enter a slightly different logic and try to eliminate copies of this
|
|
706
1057
|
# argument if
|
|
707
1058
|
# (a) the on-stack or in-register copy of it has never been modified in this function
|
|
@@ -715,32 +1066,37 @@ class AILSimplifier(Analysis):
|
|
|
715
1066
|
if defs and len(defs) == 1:
|
|
716
1067
|
arg_copy_def = defs[0]
|
|
717
1068
|
if (
|
|
718
|
-
isinstance(arg_copy_def.atom, atoms.
|
|
719
|
-
and
|
|
720
|
-
or isinstance(arg_copy_def.atom, atoms.
|
|
1069
|
+
isinstance(arg_copy_def.atom, atoms.VirtualVariable)
|
|
1070
|
+
and arg_copy_def.atom.was_stack
|
|
1071
|
+
or (isinstance(arg_copy_def.atom, atoms.VirtualVariable) and arg_copy_def.atom.was_reg)
|
|
721
1072
|
):
|
|
722
1073
|
# found the copied definition (either a stack variable or a register variable)
|
|
723
1074
|
|
|
724
1075
|
# Make sure there is no other write to this stack location if the copy is a stack variable
|
|
725
|
-
if
|
|
726
|
-
|
|
727
|
-
|
|
1076
|
+
if (
|
|
1077
|
+
isinstance(arg_copy_def.atom, atoms.VirtualVariable)
|
|
1078
|
+
and arg_copy_def.atom.was_stack
|
|
1079
|
+
and any(
|
|
1080
|
+
(def_ != arg_copy_def and def_.atom.stack_offset == arg_copy_def.atom.stack_offset)
|
|
728
1081
|
for def_ in rd.all_definitions
|
|
729
|
-
if isinstance(def_.atom, atoms.
|
|
730
|
-
)
|
|
731
|
-
|
|
1082
|
+
if isinstance(def_.atom, atoms.VirtualVariable) and def_.atom.was_stack
|
|
1083
|
+
)
|
|
1084
|
+
):
|
|
1085
|
+
continue
|
|
732
1086
|
|
|
733
1087
|
# Make sure the register is never updated across this function
|
|
734
1088
|
if any(
|
|
735
1089
|
(def_ != the_def and def_.atom == the_def.atom)
|
|
736
1090
|
for def_ in rd.all_definitions
|
|
737
|
-
if isinstance(def_.atom, atoms.
|
|
1091
|
+
if isinstance(def_.atom, atoms.VirtualVariable)
|
|
1092
|
+
and def_.atom.was_reg
|
|
1093
|
+
and rd.get_vvar_uses(def_.atom)
|
|
738
1094
|
):
|
|
739
1095
|
continue
|
|
740
1096
|
|
|
741
1097
|
# find all its uses
|
|
742
1098
|
all_arg_copy_var_uses: set[tuple[CodeLocation, Any]] = set(
|
|
743
|
-
rd.
|
|
1099
|
+
rd.get_vvar_uses_with_expr(arg_copy_def.atom)
|
|
744
1100
|
)
|
|
745
1101
|
all_uses_with_def = set()
|
|
746
1102
|
|
|
@@ -754,8 +1110,6 @@ class AILSimplifier(Analysis):
|
|
|
754
1110
|
if should_abort:
|
|
755
1111
|
continue
|
|
756
1112
|
|
|
757
|
-
# to_replace = Load(None, StackBaseOffset(None, self.project.arch.bits, eq.atom0.offset),
|
|
758
|
-
# eq.atom0.size, endness=self.project.arch.memory_endness)
|
|
759
1113
|
replace_with = eq.atom1
|
|
760
1114
|
remove_initial_assignment = True
|
|
761
1115
|
|
|
@@ -787,15 +1141,30 @@ class AILSimplifier(Analysis):
|
|
|
787
1141
|
):
|
|
788
1142
|
continue
|
|
789
1143
|
|
|
790
|
-
if isinstance(eq.atom0,
|
|
791
|
-
# create the
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
new_idx
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
1144
|
+
if isinstance(eq.atom0, VirtualVariable) and eq.atom0.was_stack:
|
|
1145
|
+
# create the replacement expression
|
|
1146
|
+
if isinstance(eq.atom1, VirtualVariable) and eq.atom1.was_parameter:
|
|
1147
|
+
# replacing atom0
|
|
1148
|
+
new_idx = None if self._ail_manager is None else next(self._ail_manager.atom_ctr)
|
|
1149
|
+
replace_with = VirtualVariable(
|
|
1150
|
+
new_idx,
|
|
1151
|
+
eq.atom1.varid,
|
|
1152
|
+
eq.atom1.bits,
|
|
1153
|
+
category=eq.atom1.category,
|
|
1154
|
+
oident=eq.atom1.oident,
|
|
1155
|
+
**eq.atom1.tags,
|
|
1156
|
+
)
|
|
1157
|
+
else:
|
|
1158
|
+
# replacing atom1
|
|
1159
|
+
new_idx = None if self._ail_manager is None else next(self._ail_manager.atom_ctr)
|
|
1160
|
+
replace_with = VirtualVariable(
|
|
1161
|
+
new_idx,
|
|
1162
|
+
eq.atom0.varid,
|
|
1163
|
+
eq.atom0.bits,
|
|
1164
|
+
category=eq.atom0.category,
|
|
1165
|
+
oident=eq.atom0.oident,
|
|
1166
|
+
**eq.atom0.tags,
|
|
1167
|
+
)
|
|
799
1168
|
elif isinstance(eq.atom0, SimMemoryVariable) and isinstance(eq.atom0.addr, int):
|
|
800
1169
|
# create the memory loading expression
|
|
801
1170
|
new_idx = None if self._ail_manager is None else next(self._ail_manager.atom_ctr)
|
|
@@ -805,27 +1174,27 @@ class AILSimplifier(Analysis):
|
|
|
805
1174
|
eq.atom0.size,
|
|
806
1175
|
endness=self.project.arch.memory_endness,
|
|
807
1176
|
)
|
|
808
|
-
elif isinstance(eq.atom0,
|
|
809
|
-
if isinstance(eq.atom1,
|
|
1177
|
+
elif isinstance(eq.atom0, VirtualVariable) and eq.atom0.was_reg:
|
|
1178
|
+
if isinstance(eq.atom1, VirtualVariable) and eq.atom1.was_reg:
|
|
810
1179
|
if self.project.arch.is_artificial_register(eq.atom0.reg_offset, eq.atom0.size):
|
|
811
1180
|
replace_with = eq.atom1
|
|
812
1181
|
else:
|
|
813
1182
|
replace_with = eq.atom0
|
|
814
1183
|
else:
|
|
815
|
-
raise AngrRuntimeError("Unsupported atom1 type
|
|
1184
|
+
raise AngrRuntimeError(f"Unsupported atom1 type {type(eq.atom1)}.")
|
|
816
1185
|
else:
|
|
817
|
-
raise AngrRuntimeError("Unsupported atom0 type
|
|
1186
|
+
raise AngrRuntimeError(f"Unsupported atom0 type {type(eq.atom0)}.")
|
|
818
1187
|
|
|
819
1188
|
to_replace_def = the_def
|
|
820
1189
|
|
|
821
1190
|
# find all uses of this definition
|
|
822
1191
|
# we make a copy of the set since we may touch the set (uses) when replacing expressions
|
|
823
|
-
all_uses: set[tuple[CodeLocation, Any]] = set(rd.
|
|
1192
|
+
all_uses: set[tuple[CodeLocation, Any]] = set(rd.get_vvar_uses_with_expr(to_replace_def.atom))
|
|
824
1193
|
# make sure none of these uses are phi nodes (depends on more than one def)
|
|
825
1194
|
all_uses_with_unique_def = set()
|
|
826
1195
|
for use_and_expr in all_uses:
|
|
827
1196
|
use_loc, used_expr = use_and_expr
|
|
828
|
-
defs_and_exprs = rd.
|
|
1197
|
+
defs_and_exprs = rd.get_uses_by_location(use_loc, exprs=True)
|
|
829
1198
|
filtered_defs = {def_ for def_, expr_ in defs_and_exprs if expr_ == used_expr}
|
|
830
1199
|
if len(filtered_defs) == 1:
|
|
831
1200
|
all_uses_with_unique_def.add(use_and_expr)
|
|
@@ -837,20 +1206,40 @@ class AILSimplifier(Analysis):
|
|
|
837
1206
|
# only when all uses are determined by the same definition will we continue with the simplification
|
|
838
1207
|
continue
|
|
839
1208
|
|
|
840
|
-
# one more check: there can be at most one assignment in all these use locations
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
1209
|
+
# one more check: there can be at most one assignment in all these use locations if the expression is
|
|
1210
|
+
# not going to be replaced with a parameter. the assignment can be an Assignment statement, but may also
|
|
1211
|
+
# be a Store if it's a global variable (via Load) that we are replacing with
|
|
1212
|
+
|
|
1213
|
+
if not (isinstance(replace_with, VirtualVariable) and replace_with.was_parameter):
|
|
1214
|
+
assignment_ctr = 0
|
|
1215
|
+
all_use_locs = {use_loc for use_loc, _ in all_uses}
|
|
1216
|
+
for use_loc in all_use_locs:
|
|
1217
|
+
if use_loc == eq.codeloc:
|
|
1218
|
+
continue
|
|
1219
|
+
block = addr_and_idx_to_block[(use_loc.block_addr, use_loc.block_idx)]
|
|
1220
|
+
stmt = block.statements[use_loc.stmt_idx]
|
|
1221
|
+
if isinstance(stmt, Assignment) or isinstance(replace_with, Load) and isinstance(stmt, Store):
|
|
1222
|
+
assignment_ctr += 1
|
|
1223
|
+
if assignment_ctr > 1:
|
|
1224
|
+
continue
|
|
849
1225
|
|
|
850
1226
|
all_uses_with_def = {(to_replace_def, use_and_expr) for use_and_expr in all_uses}
|
|
851
1227
|
|
|
852
1228
|
remove_initial_assignment = False # expression folding will take care of it
|
|
853
1229
|
|
|
1230
|
+
if any(not isinstance(use_and_expr[1], VirtualVariable) for _, use_and_expr in all_uses_with_def):
|
|
1231
|
+
# if any of the uses are phi assignments, we skip
|
|
1232
|
+
used_in_phi_assignment = False
|
|
1233
|
+
for _, use_and_expr in all_uses_with_def:
|
|
1234
|
+
u = use_and_expr[0]
|
|
1235
|
+
block = addr_and_idx_to_block[(u.block_addr, u.block_idx)]
|
|
1236
|
+
stmt = block.statements[u.stmt_idx]
|
|
1237
|
+
if is_phi_assignment(stmt):
|
|
1238
|
+
used_in_phi_assignment = True
|
|
1239
|
+
break
|
|
1240
|
+
if used_in_phi_assignment:
|
|
1241
|
+
continue
|
|
1242
|
+
|
|
854
1243
|
# ensure the uses we consider are all after the eq location
|
|
855
1244
|
filtered_all_uses_with_def = []
|
|
856
1245
|
for def_, use_and_expr in all_uses_with_def:
|
|
@@ -878,17 +1267,17 @@ class AILSimplifier(Analysis):
|
|
|
878
1267
|
u, used_expr = use_and_expr
|
|
879
1268
|
|
|
880
1269
|
use_expr_defns = []
|
|
881
|
-
for d in rd.
|
|
1270
|
+
for d in rd.get_uses_by_location(u):
|
|
882
1271
|
if (
|
|
883
|
-
isinstance(d.atom,
|
|
884
|
-
and
|
|
1272
|
+
isinstance(d.atom, atoms.VirtualVariable)
|
|
1273
|
+
and d.atom.was_reg
|
|
1274
|
+
and isinstance(def_.atom, atoms.VirtualVariable)
|
|
1275
|
+
and def_.atom.was_reg
|
|
885
1276
|
and d.atom.reg_offset == def_.atom.reg_offset
|
|
886
|
-
):
|
|
887
|
-
use_expr_defns.append(d)
|
|
888
|
-
elif d.atom == def_.atom:
|
|
1277
|
+
) or d.atom == def_.atom:
|
|
889
1278
|
use_expr_defns.append(d)
|
|
890
1279
|
# you can never replace a use with dependencies from outside the checked defn
|
|
891
|
-
if len(use_expr_defns) != 1 or
|
|
1280
|
+
if len(use_expr_defns) != 1 or next(iter(use_expr_defns)) != def_:
|
|
892
1281
|
if not use_expr_defns:
|
|
893
1282
|
_l.warning("There was no use_expr_defns for %s, this is likely a bug", u)
|
|
894
1283
|
# TODO: can you have multiple definitions which can all be eliminated?
|
|
@@ -929,7 +1318,7 @@ class AILSimplifier(Analysis):
|
|
|
929
1318
|
)
|
|
930
1319
|
|
|
931
1320
|
r, new_block = self._replace_expr_and_update_block(
|
|
932
|
-
the_block, u.stmt_idx, stmt,
|
|
1321
|
+
the_block, u.stmt_idx, stmt, used_expr, replace_with_copy
|
|
933
1322
|
)
|
|
934
1323
|
if r:
|
|
935
1324
|
self.blocks[old_block] = new_block
|
|
@@ -1007,8 +1396,8 @@ class AILSimplifier(Analysis):
|
|
|
1007
1396
|
|
|
1008
1397
|
simplified = False
|
|
1009
1398
|
|
|
1010
|
-
|
|
1011
|
-
if not
|
|
1399
|
+
equivalence = self._compute_equivalence()
|
|
1400
|
+
if not equivalence:
|
|
1012
1401
|
return simplified
|
|
1013
1402
|
|
|
1014
1403
|
addr_and_idx_to_block: dict[tuple[int, int], Block] = {}
|
|
@@ -1018,19 +1407,17 @@ class AILSimplifier(Analysis):
|
|
|
1018
1407
|
def_locations_to_remove: set[CodeLocation] = set()
|
|
1019
1408
|
updated_use_locations: set[CodeLocation] = set()
|
|
1020
1409
|
|
|
1021
|
-
eq:
|
|
1022
|
-
for eq in prop.model.equivalence:
|
|
1410
|
+
for eq in equivalence:
|
|
1023
1411
|
# register variable == Call
|
|
1024
|
-
if isinstance(eq.atom0,
|
|
1025
|
-
call_addr: int | None
|
|
1412
|
+
if isinstance(eq.atom0, VirtualVariable) and eq.atom0.was_reg:
|
|
1026
1413
|
if isinstance(eq.atom1, Call):
|
|
1027
1414
|
# register variable = Call
|
|
1028
1415
|
call: Expression = eq.atom1
|
|
1029
|
-
call_addr = call.target.value if isinstance(call.target, Const) else None
|
|
1416
|
+
# call_addr = call.target.value if isinstance(call.target, Const) else None
|
|
1030
1417
|
elif isinstance(eq.atom1, Convert) and isinstance(eq.atom1.operand, Call):
|
|
1031
1418
|
# register variable = Convert(Call)
|
|
1032
1419
|
call = eq.atom1
|
|
1033
|
-
call_addr = call.operand.target.value if isinstance(call.operand.target, Const) else None
|
|
1420
|
+
# call_addr = call.operand.target.value if isinstance(call.operand.target, Const) else None
|
|
1034
1421
|
else:
|
|
1035
1422
|
continue
|
|
1036
1423
|
|
|
@@ -1042,21 +1429,17 @@ class AILSimplifier(Analysis):
|
|
|
1042
1429
|
# we must rerun Propagator to get an updated definition (and Equivalence)
|
|
1043
1430
|
continue
|
|
1044
1431
|
|
|
1045
|
-
# find
|
|
1432
|
+
# find all uses of this virtual register
|
|
1046
1433
|
rd = self._compute_reaching_definitions()
|
|
1047
|
-
defs = [
|
|
1048
|
-
d
|
|
1049
|
-
for d in rd.all_definitions
|
|
1050
|
-
if d.codeloc == eq.codeloc
|
|
1051
|
-
and isinstance(d.atom, atoms.Register)
|
|
1052
|
-
and d.atom.reg_offset == eq.atom0.reg_offset
|
|
1053
|
-
]
|
|
1054
|
-
if not defs or len(defs) > 1:
|
|
1055
|
-
continue
|
|
1056
|
-
the_def: Definition = defs[0]
|
|
1057
1434
|
|
|
1058
|
-
|
|
1059
|
-
|
|
1435
|
+
the_def: Definition = Definition(
|
|
1436
|
+
atoms.VirtualVariable(
|
|
1437
|
+
eq.atom0.varid, eq.atom0.size, category=eq.atom0.category, oident=eq.atom0.oident
|
|
1438
|
+
),
|
|
1439
|
+
eq.codeloc,
|
|
1440
|
+
)
|
|
1441
|
+
|
|
1442
|
+
all_uses: set[tuple[CodeLocation, Any]] = set(rd.get_vvar_uses_with_expr(the_def.atom))
|
|
1060
1443
|
|
|
1061
1444
|
if len(all_uses) != 1:
|
|
1062
1445
|
continue
|
|
@@ -1084,39 +1467,40 @@ class AILSimplifier(Analysis):
|
|
|
1084
1467
|
continue
|
|
1085
1468
|
|
|
1086
1469
|
# check if the register has been overwritten by statements in between the def site and the use site
|
|
1087
|
-
usesite_atom_defs = set(rd.get_defs(the_def.atom, u, OP_BEFORE))
|
|
1088
|
-
if len(usesite_atom_defs) != 1:
|
|
1089
|
-
|
|
1090
|
-
usesite_atom_def = next(iter(usesite_atom_defs))
|
|
1091
|
-
if usesite_atom_def != the_def:
|
|
1092
|
-
|
|
1470
|
+
# usesite_atom_defs = set(rd.get_defs(the_def.atom, u, OP_BEFORE))
|
|
1471
|
+
# if len(usesite_atom_defs) != 1:
|
|
1472
|
+
# continue
|
|
1473
|
+
# usesite_atom_def = next(iter(usesite_atom_defs))
|
|
1474
|
+
# if usesite_atom_def != the_def:
|
|
1475
|
+
# continue
|
|
1093
1476
|
|
|
1094
1477
|
# check if any atoms that the call relies on has been overwritten by statements in between the def site
|
|
1095
1478
|
# and the use site.
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1479
|
+
# TODO: Prove non-interference
|
|
1480
|
+
# defsite_all_expr_uses = set(rd.all_uses.get_uses_by_location(the_def.codeloc))
|
|
1481
|
+
# defsite_used_atoms = set()
|
|
1482
|
+
# for dd in defsite_all_expr_uses:
|
|
1483
|
+
# defsite_used_atoms.add(dd.atom)
|
|
1484
|
+
# usesite_expr_def_outdated = False
|
|
1485
|
+
# for defsite_expr_atom in defsite_used_atoms:
|
|
1486
|
+
# usesite_expr_uses = set(rd.get_defs(defsite_expr_atom, u, OP_BEFORE))
|
|
1487
|
+
# if not usesite_expr_uses:
|
|
1488
|
+
# # the atom is not defined at the use site - it's fine
|
|
1489
|
+
# continue
|
|
1490
|
+
# defsite_expr_uses = set(rd.get_defs(defsite_expr_atom, the_def.codeloc, OP_BEFORE))
|
|
1491
|
+
# if usesite_expr_uses != defsite_expr_uses:
|
|
1492
|
+
# # special case: ok if this atom is assigned to at the def site and has not been overwritten
|
|
1493
|
+
# if len(usesite_expr_uses) == 1:
|
|
1494
|
+
# usesite_expr_use = next(iter(usesite_expr_uses))
|
|
1495
|
+
# if usesite_expr_use.atom == defsite_expr_atom and (
|
|
1496
|
+
# usesite_expr_use.codeloc == the_def.codeloc
|
|
1497
|
+
# or usesite_expr_use.codeloc.block_addr == call_addr
|
|
1498
|
+
# ):
|
|
1499
|
+
# continue
|
|
1500
|
+
# usesite_expr_def_outdated = True
|
|
1501
|
+
# break
|
|
1502
|
+
# if usesite_expr_def_outdated:
|
|
1503
|
+
# continue
|
|
1120
1504
|
|
|
1121
1505
|
# check if there are any calls in between the def site and the use site
|
|
1122
1506
|
if self._count_calls_in_supernodeblocks(super_node_blocks, the_def.codeloc, u) > 0:
|
|
@@ -1131,9 +1515,17 @@ class AILSimplifier(Analysis):
|
|
|
1131
1515
|
the_block = self.blocks.get(old_block, old_block)
|
|
1132
1516
|
stmt: Statement = the_block.statements[u.stmt_idx]
|
|
1133
1517
|
|
|
1134
|
-
if isinstance(eq.atom0,
|
|
1518
|
+
if isinstance(eq.atom0, VirtualVariable):
|
|
1135
1519
|
src = used_expr
|
|
1136
|
-
dst:
|
|
1520
|
+
dst: Call | Convert = call.copy()
|
|
1521
|
+
|
|
1522
|
+
if isinstance(dst, Call) and dst.ret_expr is not None:
|
|
1523
|
+
dst_bits = dst.ret_expr.bits
|
|
1524
|
+
# clear the ret_expr and fp_ret_expr of dst, then set bits so that it can be used as an
|
|
1525
|
+
# expression
|
|
1526
|
+
dst.ret_expr = None
|
|
1527
|
+
dst.fp_ret_expr = None
|
|
1528
|
+
dst.bits = dst_bits
|
|
1137
1529
|
|
|
1138
1530
|
if src.bits != dst.bits:
|
|
1139
1531
|
dst = Convert(None, dst.bits, src.bits, False, dst)
|
|
@@ -1145,9 +1537,7 @@ class AILSimplifier(Analysis):
|
|
|
1145
1537
|
if expr_ctr.count > 1:
|
|
1146
1538
|
continue
|
|
1147
1539
|
|
|
1148
|
-
replaced, new_block = self._replace_expr_and_update_block(
|
|
1149
|
-
the_block, u.stmt_idx, stmt, the_def, u, src, dst
|
|
1150
|
-
)
|
|
1540
|
+
replaced, new_block = self._replace_expr_and_update_block(the_block, u.stmt_idx, stmt, src, dst)
|
|
1151
1541
|
|
|
1152
1542
|
if replaced:
|
|
1153
1543
|
self.blocks[old_block] = new_block
|
|
@@ -1180,24 +1570,25 @@ class AILSimplifier(Analysis):
|
|
|
1180
1570
|
break
|
|
1181
1571
|
return lst
|
|
1182
1572
|
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
) -> tuple[bool, Block | None]:
|
|
1573
|
+
@staticmethod
|
|
1574
|
+
def _replace_expr_and_update_block(block, stmt_idx, stmt, src_expr, dst_expr) -> tuple[bool, Block | None]:
|
|
1186
1575
|
replaced, new_stmt = stmt.replace(src_expr, dst_expr)
|
|
1187
1576
|
if replaced:
|
|
1188
1577
|
new_block = block.copy()
|
|
1189
1578
|
new_block.statements = block.statements[::]
|
|
1190
1579
|
new_block.statements[stmt_idx] = new_stmt
|
|
1191
|
-
|
|
1192
|
-
# update the uses
|
|
1193
|
-
rd = self._compute_reaching_definitions()
|
|
1194
|
-
rd.all_uses.remove_use(the_def, codeloc, expr=src_expr)
|
|
1195
1580
|
return True, new_block
|
|
1196
1581
|
|
|
1197
1582
|
return False, None
|
|
1198
1583
|
|
|
1199
1584
|
def _remove_dead_assignments(self) -> bool:
|
|
1585
|
+
|
|
1586
|
+
# keeping tracking of statements to remove and statements (as well as dead vvars) to keep allows us to handle
|
|
1587
|
+
# cases where a statement defines more than one atoms, e.g., a call statement that defines both the return
|
|
1588
|
+
# value and the floating-point return value.
|
|
1200
1589
|
stmts_to_remove_per_block: dict[tuple[int, int], set[int]] = defaultdict(set)
|
|
1590
|
+
stmts_to_keep_per_block: dict[tuple[int, int], set[int]] = defaultdict(set)
|
|
1591
|
+
dead_vvar_ids: set[int] = set()
|
|
1201
1592
|
|
|
1202
1593
|
# Find all statements that should be removed
|
|
1203
1594
|
mask = (1 << self.project.arch.bits) - 1
|
|
@@ -1206,36 +1597,80 @@ class AILSimplifier(Analysis):
|
|
|
1206
1597
|
stackarg_offsets = (
|
|
1207
1598
|
{(tpl[1] & mask) for tpl in self._stack_arg_offsets} if self._stack_arg_offsets is not None else None
|
|
1208
1599
|
)
|
|
1209
|
-
def_: Definition
|
|
1210
1600
|
for def_ in rd.all_definitions:
|
|
1211
1601
|
if def_.dummy:
|
|
1212
1602
|
continue
|
|
1213
1603
|
# we do not remove references to global memory regions no matter what
|
|
1214
1604
|
if isinstance(def_.atom, atoms.MemoryLocation) and isinstance(def_.atom.addr, int):
|
|
1215
1605
|
continue
|
|
1216
|
-
if isinstance(def_.atom, atoms.
|
|
1217
|
-
if
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1606
|
+
if isinstance(def_.atom, atoms.VirtualVariable):
|
|
1607
|
+
if def_.atom.was_stack:
|
|
1608
|
+
if not self._remove_dead_memdefs:
|
|
1609
|
+
if rd.is_phi_vvar_id(def_.atom.varid):
|
|
1610
|
+
# we always remove unused phi variables
|
|
1611
|
+
pass
|
|
1612
|
+
elif stackarg_offsets is not None:
|
|
1613
|
+
# we always remove definitions for stack arguments
|
|
1614
|
+
if (def_.atom.stack_offset & mask) not in stackarg_offsets:
|
|
1615
|
+
continue
|
|
1616
|
+
else:
|
|
1221
1617
|
continue
|
|
1222
|
-
|
|
1223
|
-
continue
|
|
1618
|
+
uses = rd.get_vvar_uses(def_.atom)
|
|
1224
1619
|
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
|
|
1620
|
+
elif def_.atom.was_reg:
|
|
1621
|
+
uses = rd.get_vvar_uses(def_.atom)
|
|
1622
|
+
if (
|
|
1623
|
+
def_.atom.reg_offset in self.project.arch.artificial_registers_offsets
|
|
1624
|
+
and len(uses) == 1
|
|
1625
|
+
and next(iter(uses)) == def_.codeloc
|
|
1626
|
+
):
|
|
1627
|
+
# TODO: Verify if we still need this hack after moving to SSA
|
|
1628
|
+
# cc_ndep = amd64g_calculate_condition(..., cc_ndep)
|
|
1629
|
+
uses = set()
|
|
1630
|
+
|
|
1631
|
+
elif def_.atom.was_parameter:
|
|
1632
|
+
uses = rd.get_vvar_uses(def_.atom)
|
|
1633
|
+
|
|
1634
|
+
else:
|
|
1232
1635
|
uses = set()
|
|
1233
1636
|
|
|
1637
|
+
else:
|
|
1638
|
+
continue
|
|
1639
|
+
|
|
1234
1640
|
if not uses:
|
|
1641
|
+
if isinstance(def_.atom, atoms.VirtualVariable):
|
|
1642
|
+
dead_vvar_ids.add(def_.atom.varid)
|
|
1643
|
+
|
|
1235
1644
|
if not isinstance(def_.codeloc, ExternalCodeLocation):
|
|
1236
1645
|
stmts_to_remove_per_block[(def_.codeloc.block_addr, def_.codeloc.block_idx)].add(
|
|
1237
1646
|
def_.codeloc.stmt_idx
|
|
1238
1647
|
)
|
|
1648
|
+
else:
|
|
1649
|
+
stmts_to_keep_per_block[(def_.codeloc.block_addr, def_.codeloc.block_idx)].add(def_.codeloc.stmt_idx)
|
|
1650
|
+
|
|
1651
|
+
# find all phi variables that rely on variables that no longer exist
|
|
1652
|
+
all_removed_var_ids = self._removed_vvar_ids.copy()
|
|
1653
|
+
removed_vvar_ids = self._removed_vvar_ids
|
|
1654
|
+
while True:
|
|
1655
|
+
new_removed_vvar_ids = set()
|
|
1656
|
+
for phi_varid, phi_use_varids in rd.phivarid_to_varids.items():
|
|
1657
|
+
if phi_varid not in all_removed_var_ids and any(
|
|
1658
|
+
vvarid in removed_vvar_ids for vvarid in phi_use_varids
|
|
1659
|
+
):
|
|
1660
|
+
loc = rd.all_vvar_definitions[rd.varid_to_vvar[phi_varid]]
|
|
1661
|
+
stmts_to_remove_per_block[(loc.block_addr, loc.block_idx)].add(loc.stmt_idx)
|
|
1662
|
+
new_removed_vvar_ids.add(phi_varid)
|
|
1663
|
+
all_removed_var_ids.add(phi_varid)
|
|
1664
|
+
if not new_removed_vvar_ids:
|
|
1665
|
+
break
|
|
1666
|
+
removed_vvar_ids = new_removed_vvar_ids
|
|
1667
|
+
|
|
1668
|
+
# find all phi variables that are only ever used by other phi variables
|
|
1669
|
+
redundant_phi_and_dirty_varids = self._find_cyclic_dependent_phis_and_dirty_vvars(rd)
|
|
1670
|
+
for varid in redundant_phi_and_dirty_varids:
|
|
1671
|
+
loc = rd.all_vvar_definitions[rd.varid_to_vvar[varid]]
|
|
1672
|
+
stmts_to_remove_per_block[(loc.block_addr, loc.block_idx)].add(loc.stmt_idx)
|
|
1673
|
+
stmts_to_keep_per_block[(loc.block_addr, loc.block_idx)].discard(loc.stmt_idx)
|
|
1239
1674
|
|
|
1240
1675
|
for codeloc in self._calls_to_remove | self._assignments_to_remove:
|
|
1241
1676
|
# this call can be removed. make sure it exists in stmts_to_remove_per_block
|
|
@@ -1256,14 +1691,28 @@ class AILSimplifier(Analysis):
|
|
|
1256
1691
|
|
|
1257
1692
|
new_statements = []
|
|
1258
1693
|
stmts_to_remove = stmts_to_remove_per_block[(block.addr, block.idx)]
|
|
1694
|
+
stmts_to_keep = stmts_to_keep_per_block[(block.addr, block.idx)]
|
|
1259
1695
|
|
|
1260
1696
|
if not stmts_to_remove:
|
|
1261
1697
|
continue
|
|
1262
1698
|
|
|
1263
1699
|
for idx, stmt in enumerate(block.statements):
|
|
1264
|
-
if idx in stmts_to_remove and
|
|
1700
|
+
if idx in stmts_to_remove and idx in stmts_to_keep and isinstance(stmt, Call):
|
|
1701
|
+
# this statement declares more than one variable. we should handle it surgically
|
|
1702
|
+
# case 1: stmt.ret_expr and stmt.fp_ret_expr are both set, but one of them is not used
|
|
1703
|
+
if isinstance(stmt.ret_expr, VirtualVariable) and stmt.ret_expr.varid in dead_vvar_ids:
|
|
1704
|
+
stmt = stmt.copy()
|
|
1705
|
+
stmt.ret_expr = None
|
|
1706
|
+
simplified = True
|
|
1707
|
+
if isinstance(stmt.fp_ret_expr, VirtualVariable) and stmt.fp_ret_expr.varid in dead_vvar_ids:
|
|
1708
|
+
stmt = stmt.copy()
|
|
1709
|
+
stmt.fp_ret_expr = None
|
|
1710
|
+
simplified = True
|
|
1711
|
+
|
|
1712
|
+
if idx in stmts_to_remove and idx not in stmts_to_keep and not isinstance(stmt, DirtyStatement):
|
|
1265
1713
|
if isinstance(stmt, (Assignment, Store)):
|
|
1266
|
-
#
|
|
1714
|
+
# Special logic for Assignment and Store statements
|
|
1715
|
+
|
|
1267
1716
|
# if this statement triggers a call, it should only be removed if it's in self._calls_to_remove
|
|
1268
1717
|
codeloc = CodeLocation(block.addr, idx, ins_addr=stmt.ins_addr, block_idx=block.idx)
|
|
1269
1718
|
if codeloc in self._assignments_to_remove:
|
|
@@ -1276,6 +1725,10 @@ class AILSimplifier(Analysis):
|
|
|
1276
1725
|
# it has a call and must be removed
|
|
1277
1726
|
simplified = True
|
|
1278
1727
|
continue
|
|
1728
|
+
if isinstance(stmt, Assignment) and isinstance(stmt.dst, VirtualVariable):
|
|
1729
|
+
# no one is using the returned virtual variable. replace this assignment statement with
|
|
1730
|
+
# a call statement
|
|
1731
|
+
stmt = stmt.src
|
|
1279
1732
|
else:
|
|
1280
1733
|
# no calls. remove it
|
|
1281
1734
|
simplified = True
|
|
@@ -1287,21 +1740,15 @@ class AILSimplifier(Analysis):
|
|
|
1287
1740
|
simplified = True
|
|
1288
1741
|
continue
|
|
1289
1742
|
|
|
1290
|
-
if stmt.ret_expr is not None:
|
|
1291
|
-
# the return expr
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
stmt.fp_ret_expr = None
|
|
1297
|
-
else:
|
|
1298
|
-
# clear ret_expr
|
|
1299
|
-
stmt = stmt.copy()
|
|
1300
|
-
stmt.ret_expr = None
|
|
1301
|
-
simplified = True
|
|
1743
|
+
if stmt.ret_expr is not None or stmt.fp_ret_expr is not None:
|
|
1744
|
+
# both the return expr and the fp_ret_expr are not used
|
|
1745
|
+
stmt = stmt.copy()
|
|
1746
|
+
stmt.ret_expr = None
|
|
1747
|
+
stmt.fp_ret_expr = None
|
|
1748
|
+
simplified = True
|
|
1302
1749
|
else:
|
|
1303
1750
|
# Should not happen!
|
|
1304
|
-
raise NotImplementedError
|
|
1751
|
+
raise NotImplementedError
|
|
1305
1752
|
|
|
1306
1753
|
new_statements.append(stmt)
|
|
1307
1754
|
|
|
@@ -1311,6 +1758,74 @@ class AILSimplifier(Analysis):
|
|
|
1311
1758
|
|
|
1312
1759
|
return simplified
|
|
1313
1760
|
|
|
1761
|
+
def _find_cyclic_dependent_phis_and_dirty_vvars(self, rd: SRDAModel) -> set[int]:
|
|
1762
|
+
blocks_dict = {(bb.addr, bb.idx): bb for bb in self.func_graph}
|
|
1763
|
+
|
|
1764
|
+
# find dirty vvars
|
|
1765
|
+
dirty_vvar_ids = set()
|
|
1766
|
+
for bb in self.func_graph:
|
|
1767
|
+
for stmt in bb.statements:
|
|
1768
|
+
if (
|
|
1769
|
+
isinstance(stmt, Assignment)
|
|
1770
|
+
and isinstance(stmt.dst, VirtualVariable)
|
|
1771
|
+
and stmt.dst.was_reg
|
|
1772
|
+
and isinstance(stmt.src, DirtyExpression)
|
|
1773
|
+
):
|
|
1774
|
+
dirty_vvar_ids.add(stmt.dst.varid)
|
|
1775
|
+
|
|
1776
|
+
phi_and_dirty_vvar_ids = rd.phi_vvar_ids | dirty_vvar_ids
|
|
1777
|
+
|
|
1778
|
+
vvar_used_by: dict[int, set[int]] = defaultdict(set)
|
|
1779
|
+
for var_id in phi_and_dirty_vvar_ids:
|
|
1780
|
+
if var_id in rd.phivarid_to_varids:
|
|
1781
|
+
for used_by_varid in rd.phivarid_to_varids[var_id]:
|
|
1782
|
+
vvar_used_by[used_by_varid].add(var_id)
|
|
1783
|
+
|
|
1784
|
+
vvar = rd.varid_to_vvar[var_id]
|
|
1785
|
+
used_by = set()
|
|
1786
|
+
for used_vvar, loc in rd.all_vvar_uses[vvar]:
|
|
1787
|
+
if used_vvar is None:
|
|
1788
|
+
# no explicit reference
|
|
1789
|
+
used_by.add(None)
|
|
1790
|
+
else:
|
|
1791
|
+
stmt = blocks_dict[loc.block_addr, loc.block_idx].statements[loc.stmt_idx]
|
|
1792
|
+
if isinstance(stmt, Assignment) and isinstance(stmt.dst, VirtualVariable):
|
|
1793
|
+
used_by.add(stmt.dst.varid)
|
|
1794
|
+
else:
|
|
1795
|
+
used_by.add(None)
|
|
1796
|
+
vvar_used_by[var_id] |= used_by
|
|
1797
|
+
|
|
1798
|
+
g = networkx.DiGraph()
|
|
1799
|
+
dummy_vvar_id = -1
|
|
1800
|
+
for var_id, used_by_initial in vvar_used_by.items():
|
|
1801
|
+
for u in used_by_initial:
|
|
1802
|
+
if u is None:
|
|
1803
|
+
# we can't have None in networkx.DiGraph
|
|
1804
|
+
g.add_edge(var_id, dummy_vvar_id)
|
|
1805
|
+
else:
|
|
1806
|
+
g.add_edge(var_id, u)
|
|
1807
|
+
|
|
1808
|
+
cyclic_dependent_phi_varids = set()
|
|
1809
|
+
for scc in networkx.strongly_connected_components(g):
|
|
1810
|
+
if len(scc) == 1:
|
|
1811
|
+
continue
|
|
1812
|
+
|
|
1813
|
+
bail = False
|
|
1814
|
+
for varid in scc:
|
|
1815
|
+
# if this vvar is a phi var, ensure this vvar is not used by anything else outside the scc
|
|
1816
|
+
if varid in rd.phi_vvar_ids:
|
|
1817
|
+
succs = list(g.successors(varid))
|
|
1818
|
+
if any(succ_varid not in scc for succ_varid in succs):
|
|
1819
|
+
bail = True
|
|
1820
|
+
break
|
|
1821
|
+
if bail:
|
|
1822
|
+
continue
|
|
1823
|
+
|
|
1824
|
+
if all(varid in phi_and_dirty_vvar_ids for varid in scc):
|
|
1825
|
+
cyclic_dependent_phi_varids |= set(scc)
|
|
1826
|
+
|
|
1827
|
+
return cyclic_dependent_phi_varids
|
|
1828
|
+
|
|
1314
1829
|
#
|
|
1315
1830
|
# Rewriting ccalls
|
|
1316
1831
|
#
|
|
@@ -1335,8 +1850,7 @@ class AILSimplifier(Analysis):
|
|
|
1335
1850
|
if rewriter.result is not None:
|
|
1336
1851
|
_any_update.v = True
|
|
1337
1852
|
return rewriter.result
|
|
1338
|
-
|
|
1339
|
-
return None
|
|
1853
|
+
return None
|
|
1340
1854
|
|
|
1341
1855
|
return AILBlockWalker._handle_expr(walker, expr_idx, expr, stmt_idx, stmt, block)
|
|
1342
1856
|
|
|
@@ -1359,7 +1873,7 @@ class AILSimplifier(Analysis):
|
|
|
1359
1873
|
@staticmethod
|
|
1360
1874
|
def _statement_has_call_exprs(stmt: Statement) -> bool:
|
|
1361
1875
|
def _handle_callexpr(expr_idx, expr, stmt_idx, stmt, block): # pylint:disable=unused-argument
|
|
1362
|
-
raise HasCallNotification
|
|
1876
|
+
raise HasCallNotification
|
|
1363
1877
|
|
|
1364
1878
|
walker = AILBlockWalker()
|
|
1365
1879
|
walker.expr_handlers[Call] = _handle_callexpr
|
|
@@ -1373,7 +1887,7 @@ class AILSimplifier(Analysis):
|
|
|
1373
1887
|
@staticmethod
|
|
1374
1888
|
def _expression_has_call_exprs(expr: Expression) -> bool:
|
|
1375
1889
|
def _handle_callexpr(expr_idx, expr, stmt_idx, stmt, block): # pylint:disable=unused-argument
|
|
1376
|
-
raise HasCallNotification
|
|
1890
|
+
raise HasCallNotification
|
|
1377
1891
|
|
|
1378
1892
|
walker = AILBlockWalker()
|
|
1379
1893
|
walker.expr_handlers[Call] = _handle_callexpr
|
|
@@ -1400,10 +1914,25 @@ class AILSimplifier(Analysis):
|
|
|
1400
1914
|
started = False
|
|
1401
1915
|
continue
|
|
1402
1916
|
|
|
1403
|
-
if started:
|
|
1404
|
-
|
|
1405
|
-
calls += 1
|
|
1917
|
+
if started and b.statements and isinstance(b.statements[-1], Call):
|
|
1918
|
+
calls += 1
|
|
1406
1919
|
return calls
|
|
1407
1920
|
|
|
1921
|
+
@staticmethod
|
|
1922
|
+
def _exprs_contain_vvar(exprs: Iterable[Expression], vvar_ids: set[int]) -> bool:
|
|
1923
|
+
def _handle_VirtualVariable(expr_idx, expr, stmt_idx, stmt, block): # pylint:disable=unused-argument
|
|
1924
|
+
if expr.varid in vvar_ids:
|
|
1925
|
+
raise HasVVarNotification
|
|
1926
|
+
|
|
1927
|
+
walker = AILBlockWalker()
|
|
1928
|
+
walker.expr_handlers[VirtualVariable] = _handle_VirtualVariable
|
|
1929
|
+
|
|
1930
|
+
for expr in exprs:
|
|
1931
|
+
try:
|
|
1932
|
+
walker.walk_expression(expr)
|
|
1933
|
+
except HasVVarNotification:
|
|
1934
|
+
return True
|
|
1935
|
+
return False
|
|
1936
|
+
|
|
1408
1937
|
|
|
1409
1938
|
AnalysesHub.register_default("AILSimplifier", AILSimplifier)
|