angr 9.2.103__py3-none-manylinux2014_aarch64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of angr might be problematic. Click here for more details.
- angr/__init__.py +153 -0
- angr/__main__.py +59 -0
- angr/analyses/__init__.py +46 -0
- angr/analyses/analysis.py +359 -0
- angr/analyses/backward_slice.py +691 -0
- angr/analyses/binary_optimizer.py +683 -0
- angr/analyses/bindiff.py +1251 -0
- angr/analyses/boyscout.py +77 -0
- angr/analyses/callee_cleanup_finder.py +75 -0
- angr/analyses/calling_convention.py +956 -0
- angr/analyses/cdg.py +197 -0
- angr/analyses/cfg/__init__.py +11 -0
- angr/analyses/cfg/cfb.py +436 -0
- angr/analyses/cfg/cfg.py +73 -0
- angr/analyses/cfg/cfg_arch_options.py +82 -0
- angr/analyses/cfg/cfg_base.py +2917 -0
- angr/analyses/cfg/cfg_emulated.py +3570 -0
- angr/analyses/cfg/cfg_fast.py +5053 -0
- angr/analyses/cfg/cfg_fast_soot.py +669 -0
- angr/analyses/cfg/cfg_job_base.py +204 -0
- angr/analyses/cfg/indirect_jump_resolvers/__init__.py +8 -0
- angr/analyses/cfg/indirect_jump_resolvers/amd64_elf_got.py +63 -0
- angr/analyses/cfg/indirect_jump_resolvers/amd64_pe_iat.py +52 -0
- angr/analyses/cfg/indirect_jump_resolvers/arm_elf_fast.py +151 -0
- angr/analyses/cfg/indirect_jump_resolvers/const_resolver.py +141 -0
- angr/analyses/cfg/indirect_jump_resolvers/default_resolvers.py +68 -0
- angr/analyses/cfg/indirect_jump_resolvers/jumptable.py +2368 -0
- angr/analyses/cfg/indirect_jump_resolvers/mips_elf_fast.py +517 -0
- angr/analyses/cfg/indirect_jump_resolvers/propagator_utils.py +26 -0
- angr/analyses/cfg/indirect_jump_resolvers/resolver.py +74 -0
- angr/analyses/cfg/indirect_jump_resolvers/x86_elf_pic_plt.py +93 -0
- angr/analyses/cfg/indirect_jump_resolvers/x86_pe_iat.py +51 -0
- angr/analyses/cfg_slice_to_sink/__init__.py +2 -0
- angr/analyses/cfg_slice_to_sink/cfg_slice_to_sink.py +117 -0
- angr/analyses/cfg_slice_to_sink/graph.py +84 -0
- angr/analyses/cfg_slice_to_sink/transitions.py +25 -0
- angr/analyses/class_identifier.py +62 -0
- angr/analyses/code_tagging.py +123 -0
- angr/analyses/complete_calling_conventions.py +424 -0
- angr/analyses/congruency_check.py +384 -0
- angr/analyses/data_dep/__init__.py +2 -0
- angr/analyses/data_dep/data_dependency_analysis.py +605 -0
- angr/analyses/data_dep/dep_nodes.py +170 -0
- angr/analyses/data_dep/sim_act_location.py +46 -0
- angr/analyses/datagraph_meta.py +105 -0
- angr/analyses/ddg.py +1695 -0
- angr/analyses/decompiler/__init__.py +13 -0
- angr/analyses/decompiler/ail_simplifier.py +1408 -0
- angr/analyses/decompiler/ailgraph_walker.py +48 -0
- angr/analyses/decompiler/block_io_finder.py +293 -0
- angr/analyses/decompiler/block_similarity.py +188 -0
- angr/analyses/decompiler/block_simplifier.py +434 -0
- angr/analyses/decompiler/call_counter.py +43 -0
- angr/analyses/decompiler/callsite_maker.py +403 -0
- angr/analyses/decompiler/ccall_rewriters/__init__.py +6 -0
- angr/analyses/decompiler/ccall_rewriters/amd64_ccalls.py +489 -0
- angr/analyses/decompiler/ccall_rewriters/rewriter_base.py +19 -0
- angr/analyses/decompiler/clinic.py +2166 -0
- angr/analyses/decompiler/condition_processor.py +1184 -0
- angr/analyses/decompiler/decompilation_cache.py +38 -0
- angr/analyses/decompiler/decompilation_options.py +274 -0
- angr/analyses/decompiler/decompiler.py +544 -0
- angr/analyses/decompiler/empty_node_remover.py +211 -0
- angr/analyses/decompiler/expression_counters.py +76 -0
- angr/analyses/decompiler/expression_narrower.py +92 -0
- angr/analyses/decompiler/goto_manager.py +73 -0
- angr/analyses/decompiler/graph_region.py +413 -0
- angr/analyses/decompiler/jump_target_collector.py +36 -0
- angr/analyses/decompiler/jumptable_entry_condition_rewriter.py +66 -0
- angr/analyses/decompiler/optimization_passes/__init__.py +108 -0
- angr/analyses/decompiler/optimization_passes/base_ptr_save_simplifier.py +144 -0
- angr/analyses/decompiler/optimization_passes/code_motion.py +360 -0
- angr/analyses/decompiler/optimization_passes/const_derefs.py +265 -0
- angr/analyses/decompiler/optimization_passes/cross_jump_reverter.py +108 -0
- angr/analyses/decompiler/optimization_passes/deadblock_remover.py +73 -0
- angr/analyses/decompiler/optimization_passes/div_simplifier.py +391 -0
- angr/analyses/decompiler/optimization_passes/engine_base.py +303 -0
- angr/analyses/decompiler/optimization_passes/expr_op_swapper.py +136 -0
- angr/analyses/decompiler/optimization_passes/flip_boolean_cmp.py +91 -0
- angr/analyses/decompiler/optimization_passes/inlined_string_transformation_simplifier.py +386 -0
- angr/analyses/decompiler/optimization_passes/ite_expr_converter.py +226 -0
- angr/analyses/decompiler/optimization_passes/ite_region_converter.py +189 -0
- angr/analyses/decompiler/optimization_passes/lowered_switch_simplifier.py +757 -0
- angr/analyses/decompiler/optimization_passes/mod_simplifier.py +86 -0
- angr/analyses/decompiler/optimization_passes/multi_simplifier.py +227 -0
- angr/analyses/decompiler/optimization_passes/optimization_pass.py +397 -0
- angr/analyses/decompiler/optimization_passes/register_save_area_simplifier.py +198 -0
- angr/analyses/decompiler/optimization_passes/ret_addr_save_simplifier.py +172 -0
- angr/analyses/decompiler/optimization_passes/ret_deduplicator.py +219 -0
- angr/analyses/decompiler/optimization_passes/return_duplicator_base.py +448 -0
- angr/analyses/decompiler/optimization_passes/return_duplicator_high.py +57 -0
- angr/analyses/decompiler/optimization_passes/return_duplicator_low.py +121 -0
- angr/analyses/decompiler/optimization_passes/spilled_register_finder.py +18 -0
- angr/analyses/decompiler/optimization_passes/stack_canary_simplifier.py +293 -0
- angr/analyses/decompiler/optimization_passes/switch_default_case_duplicator.py +110 -0
- angr/analyses/decompiler/optimization_passes/win_stack_canary_simplifier.py +281 -0
- angr/analyses/decompiler/optimization_passes/x86_gcc_getpc_simplifier.py +87 -0
- angr/analyses/decompiler/peephole_optimizations/__init__.py +69 -0
- angr/analyses/decompiler/peephole_optimizations/a_div_const_add_a_mul_n_div_const.py +38 -0
- angr/analyses/decompiler/peephole_optimizations/a_mul_const_div_shr_const.py +38 -0
- angr/analyses/decompiler/peephole_optimizations/a_shl_const_sub_a.py +31 -0
- angr/analyses/decompiler/peephole_optimizations/a_sub_a_div.py +25 -0
- angr/analyses/decompiler/peephole_optimizations/a_sub_a_div_const_mul_const.py +56 -0
- angr/analyses/decompiler/peephole_optimizations/a_sub_a_sub_n.py +19 -0
- angr/analyses/decompiler/peephole_optimizations/arm_cmpf.py +235 -0
- angr/analyses/decompiler/peephole_optimizations/base.py +120 -0
- angr/analyses/decompiler/peephole_optimizations/basepointeroffset_add_n.py +33 -0
- angr/analyses/decompiler/peephole_optimizations/basepointeroffset_and_mask.py +35 -0
- angr/analyses/decompiler/peephole_optimizations/bitwise_or_to_logical_or.py +34 -0
- angr/analyses/decompiler/peephole_optimizations/bool_expr_xor_1.py +27 -0
- angr/analyses/decompiler/peephole_optimizations/bswap.py +131 -0
- angr/analyses/decompiler/peephole_optimizations/cmpord_rewriter.py +72 -0
- angr/analyses/decompiler/peephole_optimizations/coalesce_same_cascading_ifs.py +27 -0
- angr/analyses/decompiler/peephole_optimizations/const_mull_a_shift.py +91 -0
- angr/analyses/decompiler/peephole_optimizations/constant_derefs.py +43 -0
- angr/analyses/decompiler/peephole_optimizations/conv_a_sub0_shr_and.py +70 -0
- angr/analyses/decompiler/peephole_optimizations/conv_shl_shr.py +51 -0
- angr/analyses/decompiler/peephole_optimizations/eager_eval.py +225 -0
- angr/analyses/decompiler/peephole_optimizations/extended_byte_and_mask.py +55 -0
- angr/analyses/decompiler/peephole_optimizations/inlined_strcpy.py +146 -0
- angr/analyses/decompiler/peephole_optimizations/inlined_strcpy_consolidation.py +102 -0
- angr/analyses/decompiler/peephole_optimizations/inlined_wstrcpy.py +159 -0
- angr/analyses/decompiler/peephole_optimizations/invert_negated_logical_conjuction_disjunction.py +50 -0
- angr/analyses/decompiler/peephole_optimizations/one_sub_bool.py +33 -0
- angr/analyses/decompiler/peephole_optimizations/remove_cascading_conversions.py +19 -0
- angr/analyses/decompiler/peephole_optimizations/remove_empty_if_body.py +45 -0
- angr/analyses/decompiler/peephole_optimizations/remove_noop_conversions.py +26 -0
- angr/analyses/decompiler/peephole_optimizations/remove_redundant_bitmasks.py +48 -0
- angr/analyses/decompiler/peephole_optimizations/remove_redundant_conversions.py +160 -0
- angr/analyses/decompiler/peephole_optimizations/remove_redundant_ite_branch.py +29 -0
- angr/analyses/decompiler/peephole_optimizations/remove_redundant_ite_comparisons.py +54 -0
- angr/analyses/decompiler/peephole_optimizations/remove_redundant_nots.py +17 -0
- angr/analyses/decompiler/peephole_optimizations/remove_redundant_reinterprets.py +43 -0
- angr/analyses/decompiler/peephole_optimizations/remove_redundant_shifts.py +44 -0
- angr/analyses/decompiler/peephole_optimizations/remove_redundant_shifts_around_comparators.py +40 -0
- angr/analyses/decompiler/peephole_optimizations/rewrite_bit_extractions.py +85 -0
- angr/analyses/decompiler/peephole_optimizations/rewrite_mips_gp_loads.py +47 -0
- angr/analyses/decompiler/peephole_optimizations/rol_ror.py +77 -0
- angr/analyses/decompiler/peephole_optimizations/sar_to_signed_div.py +105 -0
- angr/analyses/decompiler/peephole_optimizations/simplify_pc_relative_loads.py +37 -0
- angr/analyses/decompiler/peephole_optimizations/single_bit_cond_to_boolexpr.py +52 -0
- angr/analyses/decompiler/peephole_optimizations/single_bit_xor.py +26 -0
- angr/analyses/decompiler/peephole_optimizations/tidy_stack_addr.py +133 -0
- angr/analyses/decompiler/redundant_label_remover.py +116 -0
- angr/analyses/decompiler/region_identifier.py +1098 -0
- angr/analyses/decompiler/region_simplifiers/__init__.py +1 -0
- angr/analyses/decompiler/region_simplifiers/cascading_cond_transformer.py +93 -0
- angr/analyses/decompiler/region_simplifiers/cascading_ifs.py +81 -0
- angr/analyses/decompiler/region_simplifiers/expr_folding.py +606 -0
- angr/analyses/decompiler/region_simplifiers/goto.py +177 -0
- angr/analyses/decompiler/region_simplifiers/if_.py +142 -0
- angr/analyses/decompiler/region_simplifiers/ifelse.py +90 -0
- angr/analyses/decompiler/region_simplifiers/loop.py +135 -0
- angr/analyses/decompiler/region_simplifiers/node_address_finder.py +23 -0
- angr/analyses/decompiler/region_simplifiers/region_simplifier.py +211 -0
- angr/analyses/decompiler/region_simplifiers/switch_cluster_simplifier.py +644 -0
- angr/analyses/decompiler/region_simplifiers/switch_expr_simplifier.py +83 -0
- angr/analyses/decompiler/region_walker.py +23 -0
- angr/analyses/decompiler/return_maker.py +70 -0
- angr/analyses/decompiler/seq_to_blocks.py +19 -0
- angr/analyses/decompiler/sequence_walker.py +235 -0
- angr/analyses/decompiler/structured_codegen/__init__.py +10 -0
- angr/analyses/decompiler/structured_codegen/base.py +132 -0
- angr/analyses/decompiler/structured_codegen/c.py +3811 -0
- angr/analyses/decompiler/structured_codegen/dummy.py +14 -0
- angr/analyses/decompiler/structured_codegen/dwarf_import.py +186 -0
- angr/analyses/decompiler/structuring/__init__.py +15 -0
- angr/analyses/decompiler/structuring/dream.py +1225 -0
- angr/analyses/decompiler/structuring/phoenix.py +2546 -0
- angr/analyses/decompiler/structuring/recursive_structurer.py +186 -0
- angr/analyses/decompiler/structuring/structurer_base.py +954 -0
- angr/analyses/decompiler/structuring/structurer_nodes.py +414 -0
- angr/analyses/decompiler/utils.py +787 -0
- angr/analyses/disassembly.py +1302 -0
- angr/analyses/disassembly_utils.py +104 -0
- angr/analyses/dominance_frontier.py +39 -0
- angr/analyses/find_objects_static.py +203 -0
- angr/analyses/flirt.py +185 -0
- angr/analyses/forward_analysis/__init__.py +2 -0
- angr/analyses/forward_analysis/forward_analysis.py +527 -0
- angr/analyses/forward_analysis/job_info.py +64 -0
- angr/analyses/forward_analysis/visitors/__init__.py +4 -0
- angr/analyses/forward_analysis/visitors/call_graph.py +28 -0
- angr/analyses/forward_analysis/visitors/function_graph.py +85 -0
- angr/analyses/forward_analysis/visitors/graph.py +250 -0
- angr/analyses/forward_analysis/visitors/loop.py +28 -0
- angr/analyses/forward_analysis/visitors/single_node_graph.py +38 -0
- angr/analyses/identifier/__init__.py +1 -0
- angr/analyses/identifier/custom_callable.py +138 -0
- angr/analyses/identifier/errors.py +9 -0
- angr/analyses/identifier/func.py +57 -0
- angr/analyses/identifier/functions/__init__.py +36 -0
- angr/analyses/identifier/functions/atoi.py +75 -0
- angr/analyses/identifier/functions/based_atoi.py +128 -0
- angr/analyses/identifier/functions/fdprintf.py +122 -0
- angr/analyses/identifier/functions/free.py +64 -0
- angr/analyses/identifier/functions/int2str.py +302 -0
- angr/analyses/identifier/functions/malloc.py +113 -0
- angr/analyses/identifier/functions/memcmp.py +69 -0
- angr/analyses/identifier/functions/memcpy.py +89 -0
- angr/analyses/identifier/functions/memset.py +43 -0
- angr/analyses/identifier/functions/printf.py +122 -0
- angr/analyses/identifier/functions/recv_until.py +315 -0
- angr/analyses/identifier/functions/skip_calloc.py +72 -0
- angr/analyses/identifier/functions/skip_realloc.py +99 -0
- angr/analyses/identifier/functions/skip_recv_n.py +107 -0
- angr/analyses/identifier/functions/snprintf.py +114 -0
- angr/analyses/identifier/functions/sprintf.py +115 -0
- angr/analyses/identifier/functions/strcasecmp.py +32 -0
- angr/analyses/identifier/functions/strcmp.py +112 -0
- angr/analyses/identifier/functions/strcpy.py +43 -0
- angr/analyses/identifier/functions/strlen.py +26 -0
- angr/analyses/identifier/functions/strncmp.py +103 -0
- angr/analyses/identifier/functions/strncpy.py +65 -0
- angr/analyses/identifier/functions/strtol.py +91 -0
- angr/analyses/identifier/identify.py +848 -0
- angr/analyses/identifier/runner.py +359 -0
- angr/analyses/init_finder.py +264 -0
- angr/analyses/loop_analysis.py +353 -0
- angr/analyses/loopfinder.py +174 -0
- angr/analyses/propagator/__init__.py +1 -0
- angr/analyses/propagator/engine_ail.py +1560 -0
- angr/analyses/propagator/engine_base.py +53 -0
- angr/analyses/propagator/engine_vex.py +328 -0
- angr/analyses/propagator/outdated_definition_walker.py +158 -0
- angr/analyses/propagator/propagator.py +422 -0
- angr/analyses/propagator/tmpvar_finder.py +17 -0
- angr/analyses/propagator/top_checker_mixin.py +14 -0
- angr/analyses/propagator/values.py +116 -0
- angr/analyses/propagator/vex_vars.py +67 -0
- angr/analyses/proximity_graph.py +452 -0
- angr/analyses/reaching_definitions/__init__.py +65 -0
- angr/analyses/reaching_definitions/call_trace.py +72 -0
- angr/analyses/reaching_definitions/dep_graph.py +392 -0
- angr/analyses/reaching_definitions/engine_ail.py +1172 -0
- angr/analyses/reaching_definitions/engine_vex.py +1102 -0
- angr/analyses/reaching_definitions/external_codeloc.py +0 -0
- angr/analyses/reaching_definitions/function_handler.py +603 -0
- angr/analyses/reaching_definitions/heap_allocator.py +69 -0
- angr/analyses/reaching_definitions/rd_initializer.py +235 -0
- angr/analyses/reaching_definitions/rd_state.py +613 -0
- angr/analyses/reaching_definitions/reaching_definitions.py +594 -0
- angr/analyses/reaching_definitions/subject.py +64 -0
- angr/analyses/reassembler.py +2970 -0
- angr/analyses/soot_class_hierarchy.py +283 -0
- angr/analyses/stack_pointer_tracker.py +832 -0
- angr/analyses/static_hooker.py +51 -0
- angr/analyses/typehoon/__init__.py +1 -0
- angr/analyses/typehoon/dfa.py +108 -0
- angr/analyses/typehoon/lifter.py +91 -0
- angr/analyses/typehoon/simple_solver.py +1258 -0
- angr/analyses/typehoon/translator.py +242 -0
- angr/analyses/typehoon/typeconsts.py +294 -0
- angr/analyses/typehoon/typehoon.py +239 -0
- angr/analyses/typehoon/typevars.py +565 -0
- angr/analyses/typehoon/variance.py +10 -0
- angr/analyses/variable_recovery/__init__.py +2 -0
- angr/analyses/variable_recovery/annotations.py +57 -0
- angr/analyses/variable_recovery/engine_ail.py +746 -0
- angr/analyses/variable_recovery/engine_base.py +962 -0
- angr/analyses/variable_recovery/engine_vex.py +580 -0
- angr/analyses/variable_recovery/irsb_scanner.py +131 -0
- angr/analyses/variable_recovery/variable_recovery.py +552 -0
- angr/analyses/variable_recovery/variable_recovery_base.py +452 -0
- angr/analyses/variable_recovery/variable_recovery_fast.py +589 -0
- angr/analyses/veritesting.py +635 -0
- angr/analyses/vfg.py +1945 -0
- angr/analyses/vsa_ddg.py +423 -0
- angr/analyses/vtable.py +92 -0
- angr/analyses/xrefs.py +263 -0
- angr/angrdb/__init__.py +9 -0
- angr/angrdb/db.py +208 -0
- angr/angrdb/models.py +183 -0
- angr/angrdb/serializers/__init__.py +2 -0
- angr/angrdb/serializers/cfg_model.py +41 -0
- angr/angrdb/serializers/comments.py +59 -0
- angr/angrdb/serializers/funcs.py +60 -0
- angr/angrdb/serializers/kb.py +110 -0
- angr/angrdb/serializers/labels.py +58 -0
- angr/angrdb/serializers/loader.py +81 -0
- angr/angrdb/serializers/structured_code.py +128 -0
- angr/angrdb/serializers/variables.py +58 -0
- angr/angrdb/serializers/xrefs.py +48 -0
- angr/annocfg.py +320 -0
- angr/blade.py +430 -0
- angr/block.py +506 -0
- angr/callable.py +162 -0
- angr/calling_conventions.py +2383 -0
- angr/code_location.py +168 -0
- angr/codenode.py +140 -0
- angr/concretization_strategies/__init__.py +97 -0
- angr/concretization_strategies/any.py +15 -0
- angr/concretization_strategies/any_named.py +32 -0
- angr/concretization_strategies/controlled_data.py +54 -0
- angr/concretization_strategies/eval.py +18 -0
- angr/concretization_strategies/logging.py +32 -0
- angr/concretization_strategies/max.py +24 -0
- angr/concretization_strategies/nonzero.py +14 -0
- angr/concretization_strategies/nonzero_range.py +20 -0
- angr/concretization_strategies/norepeats.py +35 -0
- angr/concretization_strategies/norepeats_range.py +35 -0
- angr/concretization_strategies/range.py +17 -0
- angr/concretization_strategies/signed_add.py +24 -0
- angr/concretization_strategies/single.py +12 -0
- angr/concretization_strategies/solutions.py +18 -0
- angr/concretization_strategies/unlimited_range.py +15 -0
- angr/distributed/__init__.py +3 -0
- angr/distributed/server.py +198 -0
- angr/distributed/worker.py +183 -0
- angr/engines/__init__.py +41 -0
- angr/engines/concrete.py +178 -0
- angr/engines/engine.py +212 -0
- angr/engines/failure.py +27 -0
- angr/engines/hook.py +67 -0
- angr/engines/light/__init__.py +2 -0
- angr/engines/light/data.py +715 -0
- angr/engines/light/engine.py +1441 -0
- angr/engines/pcode/__init__.py +2 -0
- angr/engines/pcode/behavior.py +995 -0
- angr/engines/pcode/cc.py +123 -0
- angr/engines/pcode/emulate.py +446 -0
- angr/engines/pcode/engine.py +256 -0
- angr/engines/pcode/lifter.py +1423 -0
- angr/engines/procedure.py +71 -0
- angr/engines/soot/__init__.py +1 -0
- angr/engines/soot/engine.py +415 -0
- angr/engines/soot/exceptions.py +14 -0
- angr/engines/soot/expressions/__init__.py +56 -0
- angr/engines/soot/expressions/arrayref.py +21 -0
- angr/engines/soot/expressions/base.py +22 -0
- angr/engines/soot/expressions/binop.py +27 -0
- angr/engines/soot/expressions/cast.py +21 -0
- angr/engines/soot/expressions/condition.py +34 -0
- angr/engines/soot/expressions/constants.py +45 -0
- angr/engines/soot/expressions/instanceOf.py +11 -0
- angr/engines/soot/expressions/instancefieldref.py +7 -0
- angr/engines/soot/expressions/invoke.py +117 -0
- angr/engines/soot/expressions/length.py +7 -0
- angr/engines/soot/expressions/local.py +7 -0
- angr/engines/soot/expressions/new.py +15 -0
- angr/engines/soot/expressions/newArray.py +51 -0
- angr/engines/soot/expressions/newMultiArray.py +84 -0
- angr/engines/soot/expressions/paramref.py +7 -0
- angr/engines/soot/expressions/phi.py +29 -0
- angr/engines/soot/expressions/staticfieldref.py +7 -0
- angr/engines/soot/expressions/thisref.py +6 -0
- angr/engines/soot/expressions/unsupported.py +6 -0
- angr/engines/soot/field_dispatcher.py +49 -0
- angr/engines/soot/method_dispatcher.py +49 -0
- angr/engines/soot/statements/__init__.py +30 -0
- angr/engines/soot/statements/assign.py +29 -0
- angr/engines/soot/statements/base.py +80 -0
- angr/engines/soot/statements/goto.py +11 -0
- angr/engines/soot/statements/identity.py +14 -0
- angr/engines/soot/statements/if_.py +16 -0
- angr/engines/soot/statements/invoke.py +11 -0
- angr/engines/soot/statements/return_.py +19 -0
- angr/engines/soot/statements/switch.py +38 -0
- angr/engines/soot/statements/throw.py +12 -0
- angr/engines/soot/values/__init__.py +24 -0
- angr/engines/soot/values/arrayref.py +124 -0
- angr/engines/soot/values/base.py +4 -0
- angr/engines/soot/values/constants.py +17 -0
- angr/engines/soot/values/instancefieldref.py +42 -0
- angr/engines/soot/values/local.py +17 -0
- angr/engines/soot/values/paramref.py +17 -0
- angr/engines/soot/values/staticfieldref.py +37 -0
- angr/engines/soot/values/strref.py +37 -0
- angr/engines/soot/values/thisref.py +148 -0
- angr/engines/successors.py +540 -0
- angr/engines/syscall.py +53 -0
- angr/engines/unicorn.py +483 -0
- angr/engines/vex/__init__.py +4 -0
- angr/engines/vex/claripy/__init__.py +1 -0
- angr/engines/vex/claripy/ccall.py +2097 -0
- angr/engines/vex/claripy/datalayer.py +149 -0
- angr/engines/vex/claripy/irop.py +1279 -0
- angr/engines/vex/heavy/__init__.py +5 -0
- angr/engines/vex/heavy/actions.py +237 -0
- angr/engines/vex/heavy/concretizers.py +394 -0
- angr/engines/vex/heavy/dirty.py +467 -0
- angr/engines/vex/heavy/heavy.py +379 -0
- angr/engines/vex/heavy/inspect.py +51 -0
- angr/engines/vex/heavy/resilience.py +85 -0
- angr/engines/vex/heavy/super_fastpath.py +34 -0
- angr/engines/vex/lifter.py +424 -0
- angr/engines/vex/light/__init__.py +3 -0
- angr/engines/vex/light/light.py +555 -0
- angr/engines/vex/light/resilience.py +73 -0
- angr/engines/vex/light/slicing.py +51 -0
- angr/errors.py +604 -0
- angr/exploration_techniques/__init__.py +176 -0
- angr/exploration_techniques/bucketizer.py +96 -0
- angr/exploration_techniques/common.py +56 -0
- angr/exploration_techniques/dfs.py +34 -0
- angr/exploration_techniques/director.py +523 -0
- angr/exploration_techniques/driller_core.py +102 -0
- angr/exploration_techniques/explorer.py +146 -0
- angr/exploration_techniques/lengthlimiter.py +20 -0
- angr/exploration_techniques/local_loop_seer.py +64 -0
- angr/exploration_techniques/loop_seer.py +239 -0
- angr/exploration_techniques/manual_mergepoint.py +80 -0
- angr/exploration_techniques/memory_watcher.py +40 -0
- angr/exploration_techniques/oppologist.py +93 -0
- angr/exploration_techniques/slicecutor.py +115 -0
- angr/exploration_techniques/spiller.py +282 -0
- angr/exploration_techniques/spiller_db.py +27 -0
- angr/exploration_techniques/stochastic.py +57 -0
- angr/exploration_techniques/suggestions.py +156 -0
- angr/exploration_techniques/symbion.py +78 -0
- angr/exploration_techniques/tech_builder.py +47 -0
- angr/exploration_techniques/threading.py +77 -0
- angr/exploration_techniques/timeout.py +31 -0
- angr/exploration_techniques/tracer.py +1101 -0
- angr/exploration_techniques/unique.py +104 -0
- angr/exploration_techniques/veritesting.py +36 -0
- angr/factory.py +385 -0
- angr/flirt/__init__.py +126 -0
- angr/flirt/build_sig.py +316 -0
- angr/graph_utils.py +0 -0
- angr/keyed_region.py +532 -0
- angr/knowledge_base/__init__.py +1 -0
- angr/knowledge_base/knowledge_base.py +145 -0
- angr/knowledge_plugins/__init__.py +18 -0
- angr/knowledge_plugins/callsite_prototypes.py +52 -0
- angr/knowledge_plugins/cfg/__init__.py +16 -0
- angr/knowledge_plugins/cfg/cfg_manager.py +94 -0
- angr/knowledge_plugins/cfg/cfg_model.py +1057 -0
- angr/knowledge_plugins/cfg/cfg_node.py +541 -0
- angr/knowledge_plugins/cfg/indirect_jump.py +67 -0
- angr/knowledge_plugins/cfg/memory_data.py +156 -0
- angr/knowledge_plugins/comments.py +15 -0
- angr/knowledge_plugins/custom_strings.py +37 -0
- angr/knowledge_plugins/data.py +21 -0
- angr/knowledge_plugins/debug_variables.py +221 -0
- angr/knowledge_plugins/functions/__init__.py +2 -0
- angr/knowledge_plugins/functions/function.py +1694 -0
- angr/knowledge_plugins/functions/function_manager.py +501 -0
- angr/knowledge_plugins/functions/function_parser.py +295 -0
- angr/knowledge_plugins/functions/soot_function.py +131 -0
- angr/knowledge_plugins/indirect_jumps.py +34 -0
- angr/knowledge_plugins/key_definitions/__init__.py +16 -0
- angr/knowledge_plugins/key_definitions/atoms.py +314 -0
- angr/knowledge_plugins/key_definitions/constants.py +23 -0
- angr/knowledge_plugins/key_definitions/definition.py +217 -0
- angr/knowledge_plugins/key_definitions/environment.py +92 -0
- angr/knowledge_plugins/key_definitions/heap_address.py +32 -0
- angr/knowledge_plugins/key_definitions/key_definition_manager.py +81 -0
- angr/knowledge_plugins/key_definitions/live_definitions.py +1074 -0
- angr/knowledge_plugins/key_definitions/liveness.py +170 -0
- angr/knowledge_plugins/key_definitions/rd_model.py +176 -0
- angr/knowledge_plugins/key_definitions/tag.py +77 -0
- angr/knowledge_plugins/key_definitions/undefined.py +67 -0
- angr/knowledge_plugins/key_definitions/unknown_size.py +83 -0
- angr/knowledge_plugins/key_definitions/uses.py +180 -0
- angr/knowledge_plugins/labels.py +109 -0
- angr/knowledge_plugins/patches.py +125 -0
- angr/knowledge_plugins/plugin.py +23 -0
- angr/knowledge_plugins/propagations/__init__.py +2 -0
- angr/knowledge_plugins/propagations/prop_value.py +193 -0
- angr/knowledge_plugins/propagations/propagation_manager.py +60 -0
- angr/knowledge_plugins/propagations/propagation_model.py +74 -0
- angr/knowledge_plugins/propagations/states.py +1064 -0
- angr/knowledge_plugins/structured_code/__init__.py +1 -0
- angr/knowledge_plugins/structured_code/manager.py +59 -0
- angr/knowledge_plugins/sync/__init__.py +1 -0
- angr/knowledge_plugins/sync/sync_controller.py +329 -0
- angr/knowledge_plugins/types.py +87 -0
- angr/knowledge_plugins/variables/__init__.py +1 -0
- angr/knowledge_plugins/variables/variable_access.py +114 -0
- angr/knowledge_plugins/variables/variable_manager.py +1191 -0
- angr/knowledge_plugins/xrefs/__init__.py +3 -0
- angr/knowledge_plugins/xrefs/xref.py +157 -0
- angr/knowledge_plugins/xrefs/xref_manager.py +122 -0
- angr/knowledge_plugins/xrefs/xref_types.py +13 -0
- angr/lib/angr_native.so +0 -0
- angr/misc/__init__.py +8 -0
- angr/misc/ansi.py +46 -0
- angr/misc/autoimport.py +89 -0
- angr/misc/bug_report.py +125 -0
- angr/misc/hookset.py +106 -0
- angr/misc/import_hooks.py +63 -0
- angr/misc/loggers.py +130 -0
- angr/misc/picklable_lock.py +45 -0
- angr/misc/plugins.py +291 -0
- angr/misc/range.py +21 -0
- angr/misc/testing.py +23 -0
- angr/misc/ux.py +31 -0
- angr/misc/weakpatch.py +58 -0
- angr/procedures/__init__.py +2 -0
- angr/procedures/advapi32/__init__.py +0 -0
- angr/procedures/cgc/__init__.py +3 -0
- angr/procedures/cgc/_terminate.py +10 -0
- angr/procedures/cgc/allocate.py +76 -0
- angr/procedures/cgc/deallocate.py +59 -0
- angr/procedures/cgc/fdwait.py +62 -0
- angr/procedures/cgc/random.py +60 -0
- angr/procedures/cgc/receive.py +91 -0
- angr/procedures/cgc/transmit.py +63 -0
- angr/procedures/definitions/__init__.py +784 -0
- angr/procedures/definitions/cgc.py +19 -0
- angr/procedures/definitions/glibc.py +8384 -0
- angr/procedures/definitions/gnulib.py +35 -0
- angr/procedures/definitions/libstdcpp.py +20 -0
- angr/procedures/definitions/linux_kernel.py +6167 -0
- angr/procedures/definitions/linux_loader.py +6 -0
- angr/procedures/definitions/msvcr.py +15 -0
- angr/procedures/definitions/parse_syscalls_from_local_system.py +49 -0
- angr/procedures/definitions/parse_win32json.py +2556 -0
- angr/procedures/definitions/types_win32.py +34481 -0
- angr/procedures/definitions/wdk_api-ms-win-dx-d3dkmt-l1-1-4.py +44 -0
- angr/procedures/definitions/wdk_api-ms-win-dx-d3dkmt-l1-1-6.py +40 -0
- angr/procedures/definitions/wdk_clfs.py +154 -0
- angr/procedures/definitions/wdk_fltmgr.py +570 -0
- angr/procedures/definitions/wdk_fwpkclnt.py +44 -0
- angr/procedures/definitions/wdk_fwpuclnt.py +330 -0
- angr/procedures/definitions/wdk_gdi32.py +380 -0
- angr/procedures/definitions/wdk_hal.py +92 -0
- angr/procedures/definitions/wdk_ksecdd.py +76 -0
- angr/procedures/definitions/wdk_ndis.py +252 -0
- angr/procedures/definitions/wdk_ntoskrnl.py +3463 -0
- angr/procedures/definitions/wdk_offreg.py +86 -0
- angr/procedures/definitions/wdk_pshed.py +50 -0
- angr/procedures/definitions/wdk_secur32.py +54 -0
- angr/procedures/definitions/wdk_vhfum.py +48 -0
- angr/procedures/definitions/win32_aclui.py +44 -0
- angr/procedures/definitions/win32_activeds.py +82 -0
- angr/procedures/definitions/win32_advapi32.py +1698 -0
- angr/procedures/definitions/win32_advpack.py +138 -0
- angr/procedures/definitions/win32_amsi.py +52 -0
- angr/procedures/definitions/win32_api-ms-win-appmodel-runtime-l1-1-1.py +58 -0
- angr/procedures/definitions/win32_api-ms-win-appmodel-runtime-l1-1-3.py +48 -0
- angr/procedures/definitions/win32_api-ms-win-appmodel-runtime-l1-1-6.py +40 -0
- angr/procedures/definitions/win32_api-ms-win-core-apiquery-l2-1-0.py +40 -0
- angr/procedures/definitions/win32_api-ms-win-core-backgroundtask-l1-1-0.py +40 -0
- angr/procedures/definitions/win32_api-ms-win-core-comm-l1-1-1.py +40 -0
- angr/procedures/definitions/win32_api-ms-win-core-comm-l1-1-2.py +40 -0
- angr/procedures/definitions/win32_api-ms-win-core-enclave-l1-1-1.py +44 -0
- angr/procedures/definitions/win32_api-ms-win-core-errorhandling-l1-1-3.py +40 -0
- angr/procedures/definitions/win32_api-ms-win-core-featurestaging-l1-1-0.py +48 -0
- angr/procedures/definitions/win32_api-ms-win-core-featurestaging-l1-1-1.py +40 -0
- angr/procedures/definitions/win32_api-ms-win-core-file-fromapp-l1-1-0.py +60 -0
- angr/procedures/definitions/win32_api-ms-win-core-handle-l1-1-0.py +40 -0
- angr/procedures/definitions/win32_api-ms-win-core-ioring-l1-1-0.py +62 -0
- angr/procedures/definitions/win32_api-ms-win-core-marshal-l1-1-0.py +46 -0
- angr/procedures/definitions/win32_api-ms-win-core-memory-l1-1-3.py +46 -0
- angr/procedures/definitions/win32_api-ms-win-core-memory-l1-1-4.py +40 -0
- angr/procedures/definitions/win32_api-ms-win-core-memory-l1-1-5.py +44 -0
- angr/procedures/definitions/win32_api-ms-win-core-memory-l1-1-6.py +46 -0
- angr/procedures/definitions/win32_api-ms-win-core-memory-l1-1-7.py +42 -0
- angr/procedures/definitions/win32_api-ms-win-core-memory-l1-1-8.py +44 -0
- angr/procedures/definitions/win32_api-ms-win-core-path-l1-1-0.py +82 -0
- angr/procedures/definitions/win32_api-ms-win-core-psm-appnotify-l1-1-0.py +42 -0
- angr/procedures/definitions/win32_api-ms-win-core-psm-appnotify-l1-1-1.py +42 -0
- angr/procedures/definitions/win32_api-ms-win-core-realtime-l1-1-1.py +44 -0
- angr/procedures/definitions/win32_api-ms-win-core-realtime-l1-1-2.py +44 -0
- angr/procedures/definitions/win32_api-ms-win-core-slapi-l1-1-0.py +40 -0
- angr/procedures/definitions/win32_api-ms-win-core-state-helpers-l1-1-0.py +40 -0
- angr/procedures/definitions/win32_api-ms-win-core-synch-l1-2-0.py +44 -0
- angr/procedures/definitions/win32_api-ms-win-core-sysinfo-l1-2-0.py +40 -0
- angr/procedures/definitions/win32_api-ms-win-core-sysinfo-l1-2-3.py +42 -0
- angr/procedures/definitions/win32_api-ms-win-core-sysinfo-l1-2-4.py +42 -0
- angr/procedures/definitions/win32_api-ms-win-core-sysinfo-l1-2-6.py +40 -0
- angr/procedures/definitions/win32_api-ms-win-core-util-l1-1-1.py +42 -0
- angr/procedures/definitions/win32_api-ms-win-core-winrt-error-l1-1-0.py +43 -0
- angr/procedures/definitions/win32_api-ms-win-core-winrt-error-l1-1-1.py +37 -0
- angr/procedures/definitions/win32_api-ms-win-core-winrt-l1-1-0.py +39 -0
- angr/procedures/definitions/win32_api-ms-win-core-winrt-registration-l1-1-0.py +23 -0
- angr/procedures/definitions/win32_api-ms-win-core-winrt-robuffer-l1-1-0.py +23 -0
- angr/procedures/definitions/win32_api-ms-win-core-winrt-roparameterizediid-l1-1-0.py +27 -0
- angr/procedures/definitions/win32_api-ms-win-core-winrt-string-l1-1-0.py +75 -0
- angr/procedures/definitions/win32_api-ms-win-core-winrt-string-l1-1-1.py +23 -0
- angr/procedures/definitions/win32_api-ms-win-core-wow64-l1-1-1.py +44 -0
- angr/procedures/definitions/win32_api-ms-win-devices-query-l1-1-0.py +56 -0
- angr/procedures/definitions/win32_api-ms-win-devices-query-l1-1-1.py +48 -0
- angr/procedures/definitions/win32_api-ms-win-dx-d3dkmt-l1-1-0.py +40 -0
- angr/procedures/definitions/win32_api-ms-win-gaming-deviceinformation-l1-1-0.py +40 -0
- angr/procedures/definitions/win32_api-ms-win-gaming-expandedresources-l1-1-0.py +44 -0
- angr/procedures/definitions/win32_api-ms-win-gaming-tcui-l1-1-0.py +52 -0
- angr/procedures/definitions/win32_api-ms-win-gaming-tcui-l1-1-1.py +42 -0
- angr/procedures/definitions/win32_api-ms-win-gaming-tcui-l1-1-2.py +52 -0
- angr/procedures/definitions/win32_api-ms-win-gaming-tcui-l1-1-3.py +42 -0
- angr/procedures/definitions/win32_api-ms-win-gaming-tcui-l1-1-4.py +54 -0
- angr/procedures/definitions/win32_api-ms-win-mm-misc-l1-1-1.py +40 -0
- angr/procedures/definitions/win32_api-ms-win-net-isolation-l1-1-0.py +54 -0
- angr/procedures/definitions/win32_api-ms-win-security-base-l1-2-2.py +40 -0
- angr/procedures/definitions/win32_api-ms-win-security-isolatedcontainer-l1-1-0.py +40 -0
- angr/procedures/definitions/win32_api-ms-win-security-isolatedcontainer-l1-1-1.py +40 -0
- angr/procedures/definitions/win32_api-ms-win-service-core-l1-1-3.py +40 -0
- angr/procedures/definitions/win32_api-ms-win-service-core-l1-1-4.py +40 -0
- angr/procedures/definitions/win32_api-ms-win-service-core-l1-1-5.py +42 -0
- angr/procedures/definitions/win32_api-ms-win-shcore-scaling-l1-1-0.py +44 -0
- angr/procedures/definitions/win32_api-ms-win-shcore-scaling-l1-1-1.py +50 -0
- angr/procedures/definitions/win32_api-ms-win-shcore-scaling-l1-1-2.py +40 -0
- angr/procedures/definitions/win32_api-ms-win-shcore-stream-winrt-l1-1-0.py +27 -0
- angr/procedures/definitions/win32_api-ms-win-wsl-api-l1-1-0.py +52 -0
- angr/procedures/definitions/win32_apphelp.py +40 -0
- angr/procedures/definitions/win32_authz.py +104 -0
- angr/procedures/definitions/win32_avicap32.py +46 -0
- angr/procedures/definitions/win32_avifil32.py +158 -0
- angr/procedures/definitions/win32_avrt.py +66 -0
- angr/procedures/definitions/win32_bcp47mrm.py +42 -0
- angr/procedures/definitions/win32_bcrypt.py +144 -0
- angr/procedures/definitions/win32_bcryptprimitives.py +42 -0
- angr/procedures/definitions/win32_bluetoothapis.py +120 -0
- angr/procedures/definitions/win32_bthprops.py +33 -0
- angr/procedures/definitions/win32_bthprops_cpl.py +50 -0
- angr/procedures/definitions/win32_cabinet.py +82 -0
- angr/procedures/definitions/win32_certadm.py +74 -0
- angr/procedures/definitions/win32_certpoleng.py +54 -0
- angr/procedures/definitions/win32_cfgmgr32.py +516 -0
- angr/procedures/definitions/win32_chakra.py +212 -0
- angr/procedures/definitions/win32_cldapi.py +110 -0
- angr/procedures/definitions/win32_clfsw32.py +156 -0
- angr/procedures/definitions/win32_clusapi.py +598 -0
- angr/procedures/definitions/win32_comctl32.py +268 -0
- angr/procedures/definitions/win32_comdlg32.py +80 -0
- angr/procedures/definitions/win32_compstui.py +46 -0
- angr/procedures/definitions/win32_computecore.py +146 -0
- angr/procedures/definitions/win32_computenetwork.py +124 -0
- angr/procedures/definitions/win32_computestorage.py +62 -0
- angr/procedures/definitions/win32_comsvcs.py +52 -0
- angr/procedures/definitions/win32_coremessaging.py +23 -0
- angr/procedures/definitions/win32_credui.py +76 -0
- angr/procedures/definitions/win32_crypt32.py +496 -0
- angr/procedures/definitions/win32_cryptnet.py +48 -0
- angr/procedures/definitions/win32_cryptui.py +58 -0
- angr/procedures/definitions/win32_cryptxml.py +76 -0
- angr/procedures/definitions/win32_cscapi.py +46 -0
- angr/procedures/definitions/win32_d2d1.py +64 -0
- angr/procedures/definitions/win32_d3d10.py +92 -0
- angr/procedures/definitions/win32_d3d10_1.py +42 -0
- angr/procedures/definitions/win32_d3d11.py +44 -0
- angr/procedures/definitions/win32_d3d12.py +54 -0
- angr/procedures/definitions/win32_d3d9.py +60 -0
- angr/procedures/definitions/win32_d3dcompiler_47.py +90 -0
- angr/procedures/definitions/win32_d3dcsx.py +56 -0
- angr/procedures/definitions/win32_davclnt.py +74 -0
- angr/procedures/definitions/win32_dbgeng.py +46 -0
- angr/procedures/definitions/win32_dbghelp.py +476 -0
- angr/procedures/definitions/win32_dbgmodel.py +40 -0
- angr/procedures/definitions/win32_dciman32.py +78 -0
- angr/procedures/definitions/win32_dcomp.py +62 -0
- angr/procedures/definitions/win32_ddraw.py +52 -0
- angr/procedures/definitions/win32_deviceaccess.py +40 -0
- angr/procedures/definitions/win32_dflayout.py +40 -0
- angr/procedures/definitions/win32_dhcpcsvc.py +68 -0
- angr/procedures/definitions/win32_dhcpcsvc6.py +50 -0
- angr/procedures/definitions/win32_dhcpsapi.py +430 -0
- angr/procedures/definitions/win32_diagnosticdataquery.py +108 -0
- angr/procedures/definitions/win32_dinput8.py +40 -0
- angr/procedures/definitions/win32_directml.py +42 -0
- angr/procedures/definitions/win32_dmprocessxmlfiltered.py +40 -0
- angr/procedures/definitions/win32_dnsapi.py +166 -0
- angr/procedures/definitions/win32_drt.py +70 -0
- angr/procedures/definitions/win32_drtprov.py +56 -0
- angr/procedures/definitions/win32_drttransport.py +42 -0
- angr/procedures/definitions/win32_dsound.py +58 -0
- angr/procedures/definitions/win32_dsparse.py +76 -0
- angr/procedures/definitions/win32_dsprop.py +52 -0
- angr/procedures/definitions/win32_dssec.py +46 -0
- angr/procedures/definitions/win32_dsuiext.py +46 -0
- angr/procedures/definitions/win32_dwmapi.py +100 -0
- angr/procedures/definitions/win32_dwrite.py +40 -0
- angr/procedures/definitions/win32_dxcompiler.py +42 -0
- angr/procedures/definitions/win32_dxcore.py +40 -0
- angr/procedures/definitions/win32_dxgi.py +50 -0
- angr/procedures/definitions/win32_dxva2.py +114 -0
- angr/procedures/definitions/win32_eappcfg.py +66 -0
- angr/procedures/definitions/win32_eappprxy.py +74 -0
- angr/procedures/definitions/win32_efswrt.py +42 -0
- angr/procedures/definitions/win32_elscore.py +48 -0
- angr/procedures/definitions/win32_esent.py +496 -0
- angr/procedures/definitions/win32_evr.py +52 -0
- angr/procedures/definitions/win32_faultrep.py +46 -0
- angr/procedures/definitions/win32_fhsvcctl.py +52 -0
- angr/procedures/definitions/win32_firewallapi.py +44 -0
- angr/procedures/definitions/win32_fltlib.py +94 -0
- angr/procedures/definitions/win32_fontsub.py +42 -0
- angr/procedures/definitions/win32_forceinline.py +44 -0
- angr/procedures/definitions/win32_fwpuclnt.py +422 -0
- angr/procedures/definitions/win32_fxsutility.py +42 -0
- angr/procedures/definitions/win32_gdi32.py +900 -0
- angr/procedures/definitions/win32_gdiplus.py +1296 -0
- angr/procedures/definitions/win32_glu32.py +142 -0
- angr/procedures/definitions/win32_gpedit.py +50 -0
- angr/procedures/definitions/win32_hhctrl_ocx.py +42 -0
- angr/procedures/definitions/win32_hid.py +128 -0
- angr/procedures/definitions/win32_hlink.py +94 -0
- angr/procedures/definitions/win32_hrtfapo.py +40 -0
- angr/procedures/definitions/win32_httpapi.py +124 -0
- angr/procedures/definitions/win32_icm32.py +80 -0
- angr/procedures/definitions/win32_icmui.py +42 -0
- angr/procedures/definitions/win32_icu.py +2088 -0
- angr/procedures/definitions/win32_ieframe.py +96 -0
- angr/procedures/definitions/win32_imagehlp.py +90 -0
- angr/procedures/definitions/win32_imgutil.py +56 -0
- angr/procedures/definitions/win32_imm32.py +202 -0
- angr/procedures/definitions/win32_infocardapi.py +72 -0
- angr/procedures/definitions/win32_inkobjcore.py +92 -0
- angr/procedures/definitions/win32_iphlpapi.py +440 -0
- angr/procedures/definitions/win32_iscsidsc.py +196 -0
- angr/procedures/definitions/win32_isolatedwindowsenvironmentutils.py +42 -0
- angr/procedures/definitions/win32_kernel32.py +3199 -0
- angr/procedures/definitions/win32_kernelbase.py +50 -0
- angr/procedures/definitions/win32_keycredmgr.py +46 -0
- angr/procedures/definitions/win32_ksproxy_ax.py +50 -0
- angr/procedures/definitions/win32_ksuser.py +54 -0
- angr/procedures/definitions/win32_ktmw32.py +116 -0
- angr/procedures/definitions/win32_licenseprotection.py +42 -0
- angr/procedures/definitions/win32_loadperf.py +62 -0
- angr/procedures/definitions/win32_magnification.py +76 -0
- angr/procedures/definitions/win32_mapi32.py +170 -0
- angr/procedures/definitions/win32_mdmlocalmanagement.py +44 -0
- angr/procedures/definitions/win32_mdmregistration.py +68 -0
- angr/procedures/definitions/win32_mf.py +162 -0
- angr/procedures/definitions/win32_mfcore.py +42 -0
- angr/procedures/definitions/win32_mfplat.py +328 -0
- angr/procedures/definitions/win32_mfplay.py +40 -0
- angr/procedures/definitions/win32_mfreadwrite.py +48 -0
- angr/procedures/definitions/win32_mfsensorgroup.py +58 -0
- angr/procedures/definitions/win32_mfsrcsnk.py +42 -0
- angr/procedures/definitions/win32_mgmtapi.py +56 -0
- angr/procedures/definitions/win32_mi.py +40 -0
- angr/procedures/definitions/win32_mmdevapi.py +40 -0
- angr/procedures/definitions/win32_mpr.py +132 -0
- angr/procedures/definitions/win32_mprapi.py +262 -0
- angr/procedures/definitions/win32_mqrt.py +106 -0
- angr/procedures/definitions/win32_mrmsupport.py +92 -0
- angr/procedures/definitions/win32_msacm32.py +122 -0
- angr/procedures/definitions/win32_msajapi.py +1132 -0
- angr/procedures/definitions/win32_mscms.py +196 -0
- angr/procedures/definitions/win32_mscoree.py +92 -0
- angr/procedures/definitions/win32_msctfmonitor.py +44 -0
- angr/procedures/definitions/win32_msdelta.py +70 -0
- angr/procedures/definitions/win32_msdmo.py +60 -0
- angr/procedures/definitions/win32_msdrm.py +206 -0
- angr/procedures/definitions/win32_msi.py +566 -0
- angr/procedures/definitions/win32_msimg32.py +44 -0
- angr/procedures/definitions/win32_mspatcha.py +70 -0
- angr/procedures/definitions/win32_mspatchc.py +56 -0
- angr/procedures/definitions/win32_msports.py +52 -0
- angr/procedures/definitions/win32_msrating.py +76 -0
- angr/procedures/definitions/win32_mssign32.py +58 -0
- angr/procedures/definitions/win32_mstask.py +42 -0
- angr/procedures/definitions/win32_msvfw32.py +124 -0
- angr/procedures/definitions/win32_mswsock.py +70 -0
- angr/procedures/definitions/win32_mtxdm.py +40 -0
- angr/procedures/definitions/win32_ncrypt.py +116 -0
- angr/procedures/definitions/win32_ndfapi.py +70 -0
- angr/procedures/definitions/win32_netapi32.py +450 -0
- angr/procedures/definitions/win32_netsh.py +54 -0
- angr/procedures/definitions/win32_netshell.py +42 -0
- angr/procedures/definitions/win32_newdev.py +60 -0
- angr/procedures/definitions/win32_ninput.py +98 -0
- angr/procedures/definitions/win32_normaliz.py +42 -0
- angr/procedures/definitions/win32_ntdll.py +185 -0
- angr/procedures/definitions/win32_ntdllk.py +40 -0
- angr/procedures/definitions/win32_ntdsapi.py +200 -0
- angr/procedures/definitions/win32_ntlanman.py +58 -0
- angr/procedures/definitions/win32_odbc32.py +406 -0
- angr/procedures/definitions/win32_odbcbcp.py +92 -0
- angr/procedures/definitions/win32_ole32.py +672 -0
- angr/procedures/definitions/win32_oleacc.py +72 -0
- angr/procedures/definitions/win32_oleaut32.py +848 -0
- angr/procedures/definitions/win32_oledlg.py +84 -0
- angr/procedures/definitions/win32_ondemandconnroutehelper.py +48 -0
- angr/procedures/definitions/win32_opengl32.py +748 -0
- angr/procedures/definitions/win32_opmxbox.py +44 -0
- angr/procedures/definitions/win32_p2p.py +254 -0
- angr/procedures/definitions/win32_p2pgraph.py +112 -0
- angr/procedures/definitions/win32_pdh.py +234 -0
- angr/procedures/definitions/win32_peerdist.py +94 -0
- angr/procedures/definitions/win32_powrprof.py +206 -0
- angr/procedures/definitions/win32_prntvpt.py +60 -0
- angr/procedures/definitions/win32_projectedfslib.py +76 -0
- angr/procedures/definitions/win32_propsys.py +474 -0
- angr/procedures/definitions/win32_psapi.py +92 -0
- angr/procedures/definitions/win32_quartz.py +42 -0
- angr/procedures/definitions/win32_query.py +46 -0
- angr/procedures/definitions/win32_qwave.py +60 -0
- angr/procedures/definitions/win32_rasapi32.py +206 -0
- angr/procedures/definitions/win32_rasdlg.py +50 -0
- angr/procedures/definitions/win32_resutils.py +278 -0
- angr/procedures/definitions/win32_rometadata.py +23 -0
- angr/procedures/definitions/win32_rpcns4.py +160 -0
- angr/procedures/definitions/win32_rpcproxy.py +46 -0
- angr/procedures/definitions/win32_rpcrt4.py +932 -0
- angr/procedures/definitions/win32_rstrtmgr.py +60 -0
- angr/procedures/definitions/win32_rtm.py +190 -0
- angr/procedures/definitions/win32_rtutils.py +120 -0
- angr/procedures/definitions/win32_rtworkq.py +104 -0
- angr/procedures/definitions/win32_sas.py +40 -0
- angr/procedures/definitions/win32_scarddlg.py +48 -0
- angr/procedures/definitions/win32_schannel.py +56 -0
- angr/procedures/definitions/win32_sechost.py +42 -0
- angr/procedures/definitions/win32_secur32.py +216 -0
- angr/procedures/definitions/win32_sensapi.py +44 -0
- angr/procedures/definitions/win32_sensorsutilsv2.py +118 -0
- angr/procedures/definitions/win32_setupapi.py +706 -0
- angr/procedures/definitions/win32_sfc.py +50 -0
- angr/procedures/definitions/win32_shdocvw.py +44 -0
- angr/procedures/definitions/win32_shell32.py +526 -0
- angr/procedures/definitions/win32_shlwapi.py +758 -0
- angr/procedures/definitions/win32_slc.py +102 -0
- angr/procedures/definitions/win32_slcext.py +46 -0
- angr/procedures/definitions/win32_slwga.py +40 -0
- angr/procedures/definitions/win32_snmpapi.py +90 -0
- angr/procedures/definitions/win32_spoolss.py +90 -0
- angr/procedures/definitions/win32_srclient.py +40 -0
- angr/procedures/definitions/win32_srpapi.py +60 -0
- angr/procedures/definitions/win32_sspicli.py +52 -0
- angr/procedures/definitions/win32_sti.py +40 -0
- angr/procedures/definitions/win32_t2embed.py +66 -0
- angr/procedures/definitions/win32_tapi32.py +536 -0
- angr/procedures/definitions/win32_tbs.py +66 -0
- angr/procedures/definitions/win32_tdh.py +92 -0
- angr/procedures/definitions/win32_tokenbinding.py +58 -0
- angr/procedures/definitions/win32_traffic.py +78 -0
- angr/procedures/definitions/win32_txfw32.py +56 -0
- angr/procedures/definitions/win32_ualapi.py +46 -0
- angr/procedures/definitions/win32_uiautomationcore.py +234 -0
- angr/procedures/definitions/win32_urlmon.py +192 -0
- angr/procedures/definitions/win32_user32.py +1565 -0
- angr/procedures/definitions/win32_userenv.py +126 -0
- angr/procedures/definitions/win32_usp10.py +118 -0
- angr/procedures/definitions/win32_uxtheme.py +192 -0
- angr/procedures/definitions/win32_verifier.py +40 -0
- angr/procedures/definitions/win32_version.py +66 -0
- angr/procedures/definitions/win32_vertdll.py +52 -0
- angr/procedures/definitions/win32_virtdisk.py +96 -0
- angr/procedures/definitions/win32_vmdevicehost.py +64 -0
- angr/procedures/definitions/win32_vmsavedstatedumpprovider.py +124 -0
- angr/procedures/definitions/win32_vssapi.py +40 -0
- angr/procedures/definitions/win32_wcmapi.py +48 -0
- angr/procedures/definitions/win32_wdsbp.py +52 -0
- angr/procedures/definitions/win32_wdsclientapi.py +112 -0
- angr/procedures/definitions/win32_wdsmc.py +50 -0
- angr/procedures/definitions/win32_wdspxe.py +100 -0
- angr/procedures/definitions/win32_wdstptc.py +64 -0
- angr/procedures/definitions/win32_webauthn.py +64 -0
- angr/procedures/definitions/win32_webservices.py +424 -0
- angr/procedures/definitions/win32_websocket.py +64 -0
- angr/procedures/definitions/win32_wecapi.py +68 -0
- angr/procedures/definitions/win32_wer.py +80 -0
- angr/procedures/definitions/win32_wevtapi.py +108 -0
- angr/procedures/definitions/win32_winbio.py +146 -0
- angr/procedures/definitions/win32_windows_ai_machinelearning.py +40 -0
- angr/procedures/definitions/win32_windows_data_pdf.py +23 -0
- angr/procedures/definitions/win32_windows_media_mediacontrol.py +54 -0
- angr/procedures/definitions/win32_windows_networking.py +40 -0
- angr/procedures/definitions/win32_windows_ui_xaml.py +42 -0
- angr/procedures/definitions/win32_windowscodecs.py +56 -0
- angr/procedures/definitions/win32_winfax.py +150 -0
- angr/procedures/definitions/win32_winhttp.py +150 -0
- angr/procedures/definitions/win32_winhvemulation.py +46 -0
- angr/procedures/definitions/win32_winhvplatform.py +170 -0
- angr/procedures/definitions/win32_wininet.py +630 -0
- angr/procedures/definitions/win32_winml.py +40 -0
- angr/procedures/definitions/win32_winmm.py +390 -0
- angr/procedures/definitions/win32_winscard.py +178 -0
- angr/procedures/definitions/win32_winspool.py +363 -0
- angr/procedures/definitions/win32_winspool_drv.py +382 -0
- angr/procedures/definitions/win32_wintrust.py +158 -0
- angr/procedures/definitions/win32_winusb.py +106 -0
- angr/procedures/definitions/win32_wlanapi.py +158 -0
- angr/procedures/definitions/win32_wlanui.py +40 -0
- angr/procedures/definitions/win32_wldap32.py +524 -0
- angr/procedures/definitions/win32_wldp.py +56 -0
- angr/procedures/definitions/win32_wmvcore.py +60 -0
- angr/procedures/definitions/win32_wnvapi.py +42 -0
- angr/procedures/definitions/win32_wofutil.py +60 -0
- angr/procedures/definitions/win32_ws2_32.py +358 -0
- angr/procedures/definitions/win32_wscapi.py +50 -0
- angr/procedures/definitions/win32_wsclient.py +44 -0
- angr/procedures/definitions/win32_wsdapi.py +102 -0
- angr/procedures/definitions/win32_wsmsvc.py +104 -0
- angr/procedures/definitions/win32_wsnmp32.py +136 -0
- angr/procedures/definitions/win32_wtsapi32.py +164 -0
- angr/procedures/definitions/win32_xaudio2_8.py +46 -0
- angr/procedures/definitions/win32_xinput1_4.py +52 -0
- angr/procedures/definitions/win32_xinputuap.py +35 -0
- angr/procedures/definitions/win32_xmllite.py +50 -0
- angr/procedures/definitions/win32_xolehlp.py +46 -0
- angr/procedures/definitions/win32_xpsprint.py +42 -0
- angr/procedures/glibc/__ctype_b_loc.py +22 -0
- angr/procedures/glibc/__ctype_tolower_loc.py +22 -0
- angr/procedures/glibc/__ctype_toupper_loc.py +22 -0
- angr/procedures/glibc/__errno_location.py +6 -0
- angr/procedures/glibc/__init__.py +3 -0
- angr/procedures/glibc/__libc_init.py +36 -0
- angr/procedures/glibc/__libc_start_main.py +294 -0
- angr/procedures/glibc/dynamic_loading.py +19 -0
- angr/procedures/glibc/scanf.py +10 -0
- angr/procedures/glibc/sscanf.py +5 -0
- angr/procedures/gnulib/__init__.py +3 -0
- angr/procedures/gnulib/xalloc_die.py +13 -0
- angr/procedures/gnulib/xstrtol_fatal.py +13 -0
- angr/procedures/java/__init__.py +38 -0
- angr/procedures/java/unconstrained.py +64 -0
- angr/procedures/java_io/__init__.py +0 -0
- angr/procedures/java_io/read.py +11 -0
- angr/procedures/java_io/write.py +16 -0
- angr/procedures/java_jni/__init__.py +475 -0
- angr/procedures/java_jni/array_operations.py +309 -0
- angr/procedures/java_jni/class_and_interface_operations.py +31 -0
- angr/procedures/java_jni/field_access.py +176 -0
- angr/procedures/java_jni/global_and_local_refs.py +56 -0
- angr/procedures/java_jni/method_calls.py +364 -0
- angr/procedures/java_jni/not_implemented.py +25 -0
- angr/procedures/java_jni/object_operations.py +95 -0
- angr/procedures/java_jni/string_operations.py +86 -0
- angr/procedures/java_jni/version_information.py +11 -0
- angr/procedures/java_lang/__init__.py +0 -0
- angr/procedures/java_lang/character.py +31 -0
- angr/procedures/java_lang/double.py +24 -0
- angr/procedures/java_lang/exit.py +12 -0
- angr/procedures/java_lang/getsimplename.py +15 -0
- angr/procedures/java_lang/integer.py +42 -0
- angr/procedures/java_lang/load_library.py +8 -0
- angr/procedures/java_lang/math.py +14 -0
- angr/procedures/java_lang/string.py +78 -0
- angr/procedures/java_lang/stringbuilder.py +43 -0
- angr/procedures/java_lang/system.py +17 -0
- angr/procedures/java_util/__init__.py +0 -0
- angr/procedures/java_util/collection.py +34 -0
- angr/procedures/java_util/iterator.py +45 -0
- angr/procedures/java_util/list.py +98 -0
- angr/procedures/java_util/map.py +132 -0
- angr/procedures/java_util/random.py +11 -0
- angr/procedures/java_util/scanner_nextline.py +22 -0
- angr/procedures/libc/__init__.py +3 -0
- angr/procedures/libc/abort.py +8 -0
- angr/procedures/libc/access.py +10 -0
- angr/procedures/libc/atoi.py +14 -0
- angr/procedures/libc/atol.py +12 -0
- angr/procedures/libc/calloc.py +7 -0
- angr/procedures/libc/closelog.py +9 -0
- angr/procedures/libc/err.py +13 -0
- angr/procedures/libc/error.py +55 -0
- angr/procedures/libc/exit.py +10 -0
- angr/procedures/libc/fclose.py +20 -0
- angr/procedures/libc/feof.py +19 -0
- angr/procedures/libc/fflush.py +15 -0
- angr/procedures/libc/fgetc.py +24 -0
- angr/procedures/libc/fgets.py +68 -0
- angr/procedures/libc/fopen.py +64 -0
- angr/procedures/libc/fprintf.py +24 -0
- angr/procedures/libc/fputc.py +22 -0
- angr/procedures/libc/fputs.py +23 -0
- angr/procedures/libc/fread.py +22 -0
- angr/procedures/libc/free.py +8 -0
- angr/procedures/libc/fscanf.py +20 -0
- angr/procedures/libc/fseek.py +32 -0
- angr/procedures/libc/ftell.py +21 -0
- angr/procedures/libc/fwrite.py +18 -0
- angr/procedures/libc/getchar.py +13 -0
- angr/procedures/libc/getdelim.py +96 -0
- angr/procedures/libc/getegid.py +7 -0
- angr/procedures/libc/geteuid.py +7 -0
- angr/procedures/libc/getgid.py +7 -0
- angr/procedures/libc/gets.py +66 -0
- angr/procedures/libc/getuid.py +7 -0
- angr/procedures/libc/malloc.py +11 -0
- angr/procedures/libc/memcmp.py +69 -0
- angr/procedures/libc/memcpy.py +37 -0
- angr/procedures/libc/memset.py +69 -0
- angr/procedures/libc/openlog.py +9 -0
- angr/procedures/libc/perror.py +12 -0
- angr/procedures/libc/printf.py +33 -0
- angr/procedures/libc/putchar.py +12 -0
- angr/procedures/libc/puts.py +16 -0
- angr/procedures/libc/rand.py +7 -0
- angr/procedures/libc/realloc.py +7 -0
- angr/procedures/libc/rewind.py +11 -0
- angr/procedures/libc/scanf.py +20 -0
- angr/procedures/libc/setbuf.py +8 -0
- angr/procedures/libc/setvbuf.py +6 -0
- angr/procedures/libc/snprintf.py +33 -0
- angr/procedures/libc/sprintf.py +22 -0
- angr/procedures/libc/srand.py +6 -0
- angr/procedures/libc/sscanf.py +13 -0
- angr/procedures/libc/stpcpy.py +18 -0
- angr/procedures/libc/strcat.py +13 -0
- angr/procedures/libc/strchr.py +44 -0
- angr/procedures/libc/strcmp.py +28 -0
- angr/procedures/libc/strcpy.py +13 -0
- angr/procedures/libc/strlen.py +99 -0
- angr/procedures/libc/strncat.py +18 -0
- angr/procedures/libc/strncmp.py +180 -0
- angr/procedures/libc/strncpy.py +18 -0
- angr/procedures/libc/strnlen.py +13 -0
- angr/procedures/libc/strstr.py +94 -0
- angr/procedures/libc/strtol.py +263 -0
- angr/procedures/libc/strtoul.py +9 -0
- angr/procedures/libc/system.py +12 -0
- angr/procedures/libc/time.py +9 -0
- angr/procedures/libc/tmpnam.py +19 -0
- angr/procedures/libc/tolower.py +7 -0
- angr/procedures/libc/toupper.py +7 -0
- angr/procedures/libc/ungetc.py +19 -0
- angr/procedures/libc/vsnprintf.py +16 -0
- angr/procedures/libc/wchar.py +15 -0
- angr/procedures/libstdcpp/__init__.py +0 -0
- angr/procedures/libstdcpp/_unwind_resume.py +10 -0
- angr/procedures/libstdcpp/std____throw_bad_alloc.py +12 -0
- angr/procedures/libstdcpp/std____throw_bad_cast.py +12 -0
- angr/procedures/libstdcpp/std____throw_length_error.py +12 -0
- angr/procedures/libstdcpp/std____throw_logic_error.py +12 -0
- angr/procedures/libstdcpp/std__terminate.py +12 -0
- angr/procedures/linux_kernel/__init__.py +3 -0
- angr/procedures/linux_kernel/access.py +17 -0
- angr/procedures/linux_kernel/arch_prctl.py +33 -0
- angr/procedures/linux_kernel/arm_user_helpers.py +58 -0
- angr/procedures/linux_kernel/brk.py +17 -0
- angr/procedures/linux_kernel/cwd.py +27 -0
- angr/procedures/linux_kernel/fstat.py +137 -0
- angr/procedures/linux_kernel/fstat64.py +169 -0
- angr/procedures/linux_kernel/futex.py +17 -0
- angr/procedures/linux_kernel/getegid.py +16 -0
- angr/procedures/linux_kernel/geteuid.py +16 -0
- angr/procedures/linux_kernel/getgid.py +16 -0
- angr/procedures/linux_kernel/getpid.py +13 -0
- angr/procedures/linux_kernel/getrlimit.py +24 -0
- angr/procedures/linux_kernel/gettid.py +8 -0
- angr/procedures/linux_kernel/getuid.py +16 -0
- angr/procedures/linux_kernel/iovec.py +43 -0
- angr/procedures/linux_kernel/lseek.py +39 -0
- angr/procedures/linux_kernel/mmap.py +15 -0
- angr/procedures/linux_kernel/mprotect.py +41 -0
- angr/procedures/linux_kernel/munmap.py +7 -0
- angr/procedures/linux_kernel/openat.py +28 -0
- angr/procedures/linux_kernel/set_tid_address.py +7 -0
- angr/procedures/linux_kernel/sigaction.py +16 -0
- angr/procedures/linux_kernel/sigprocmask.py +20 -0
- angr/procedures/linux_kernel/stat.py +22 -0
- angr/procedures/linux_kernel/sysinfo.py +58 -0
- angr/procedures/linux_kernel/tgkill.py +7 -0
- angr/procedures/linux_kernel/time.py +30 -0
- angr/procedures/linux_kernel/uid.py +29 -0
- angr/procedures/linux_kernel/uname.py +28 -0
- angr/procedures/linux_kernel/unlink.py +22 -0
- angr/procedures/linux_kernel/vsyscall.py +15 -0
- angr/procedures/linux_loader/__init__.py +3 -0
- angr/procedures/linux_loader/_dl_initial_error_catch_tsd.py +6 -0
- angr/procedures/linux_loader/_dl_rtld_lock.py +14 -0
- angr/procedures/linux_loader/sim_loader.py +53 -0
- angr/procedures/linux_loader/tls.py +40 -0
- angr/procedures/msvcr/__getmainargs.py +15 -0
- angr/procedures/msvcr/__init__.py +4 -0
- angr/procedures/msvcr/_initterm.py +37 -0
- angr/procedures/msvcr/fmode.py +28 -0
- angr/procedures/ntdll/__init__.py +0 -0
- angr/procedures/ntdll/exceptions.py +57 -0
- angr/procedures/posix/__init__.py +3 -0
- angr/procedures/posix/accept.py +29 -0
- angr/procedures/posix/bind.py +12 -0
- angr/procedures/posix/bzero.py +6 -0
- angr/procedures/posix/chroot.py +26 -0
- angr/procedures/posix/close.py +9 -0
- angr/procedures/posix/closedir.py +6 -0
- angr/procedures/posix/dup.py +55 -0
- angr/procedures/posix/fcntl.py +9 -0
- angr/procedures/posix/fdopen.py +77 -0
- angr/procedures/posix/fileno.py +17 -0
- angr/procedures/posix/fork.py +10 -0
- angr/procedures/posix/getenv.py +34 -0
- angr/procedures/posix/gethostbyname.py +42 -0
- angr/procedures/posix/getpass.py +18 -0
- angr/procedures/posix/getsockopt.py +10 -0
- angr/procedures/posix/htonl.py +11 -0
- angr/procedures/posix/htons.py +11 -0
- angr/procedures/posix/inet_ntoa.py +61 -0
- angr/procedures/posix/listen.py +12 -0
- angr/procedures/posix/mmap.py +140 -0
- angr/procedures/posix/open.py +17 -0
- angr/procedures/posix/opendir.py +9 -0
- angr/procedures/posix/poll.py +54 -0
- angr/procedures/posix/pread64.py +45 -0
- angr/procedures/posix/pthread.py +87 -0
- angr/procedures/posix/pwrite64.py +45 -0
- angr/procedures/posix/read.py +12 -0
- angr/procedures/posix/readdir.py +59 -0
- angr/procedures/posix/recv.py +12 -0
- angr/procedures/posix/recvfrom.py +12 -0
- angr/procedures/posix/select.py +46 -0
- angr/procedures/posix/send.py +22 -0
- angr/procedures/posix/setsockopt.py +8 -0
- angr/procedures/posix/sigaction.py +20 -0
- angr/procedures/posix/sim_time.py +45 -0
- angr/procedures/posix/sleep.py +7 -0
- angr/procedures/posix/socket.py +18 -0
- angr/procedures/posix/strcasecmp.py +23 -0
- angr/procedures/posix/strdup.py +17 -0
- angr/procedures/posix/strtok_r.py +65 -0
- angr/procedures/posix/syslog.py +15 -0
- angr/procedures/posix/tz.py +8 -0
- angr/procedures/posix/unlink.py +10 -0
- angr/procedures/posix/usleep.py +7 -0
- angr/procedures/posix/write.py +12 -0
- angr/procedures/procedure_dict.py +48 -0
- angr/procedures/stubs/CallReturn.py +12 -0
- angr/procedures/stubs/NoReturnUnconstrained.py +12 -0
- angr/procedures/stubs/Nop.py +6 -0
- angr/procedures/stubs/PathTerminator.py +8 -0
- angr/procedures/stubs/Redirect.py +15 -0
- angr/procedures/stubs/ReturnChar.py +10 -0
- angr/procedures/stubs/ReturnUnconstrained.py +24 -0
- angr/procedures/stubs/UnresolvableCallTarget.py +8 -0
- angr/procedures/stubs/UnresolvableJumpTarget.py +8 -0
- angr/procedures/stubs/UserHook.py +15 -0
- angr/procedures/stubs/__init__.py +3 -0
- angr/procedures/stubs/b64_decode.py +12 -0
- angr/procedures/stubs/caller.py +13 -0
- angr/procedures/stubs/crazy_scanf.py +17 -0
- angr/procedures/stubs/format_parser.py +677 -0
- angr/procedures/stubs/syscall_stub.py +26 -0
- angr/procedures/testing/__init__.py +3 -0
- angr/procedures/testing/manyargs.py +8 -0
- angr/procedures/testing/retreg.py +8 -0
- angr/procedures/tracer/__init__.py +4 -0
- angr/procedures/tracer/random.py +8 -0
- angr/procedures/tracer/receive.py +21 -0
- angr/procedures/tracer/transmit.py +24 -0
- angr/procedures/uclibc/__init__.py +3 -0
- angr/procedures/uclibc/__uClibc_main.py +9 -0
- angr/procedures/win32/EncodePointer.py +6 -0
- angr/procedures/win32/ExitProcess.py +8 -0
- angr/procedures/win32/GetCommandLine.py +11 -0
- angr/procedures/win32/GetCurrentProcessId.py +6 -0
- angr/procedures/win32/GetCurrentThreadId.py +6 -0
- angr/procedures/win32/GetLastInputInfo.py +37 -0
- angr/procedures/win32/GetModuleHandle.py +30 -0
- angr/procedures/win32/GetProcessAffinityMask.py +34 -0
- angr/procedures/win32/InterlockedExchange.py +14 -0
- angr/procedures/win32/IsProcessorFeaturePresent.py +6 -0
- angr/procedures/win32/VirtualAlloc.py +113 -0
- angr/procedures/win32/VirtualProtect.py +59 -0
- angr/procedures/win32/__init__.py +3 -0
- angr/procedures/win32/critical_section.py +11 -0
- angr/procedures/win32/dynamic_loading.py +103 -0
- angr/procedures/win32/file_handles.py +47 -0
- angr/procedures/win32/gethostbyname.py +10 -0
- angr/procedures/win32/heap.py +42 -0
- angr/procedures/win32/is_bad_ptr.py +25 -0
- angr/procedures/win32/local_storage.py +85 -0
- angr/procedures/win32/mutex.py +10 -0
- angr/procedures/win32/sim_time.py +135 -0
- angr/procedures/win32/system_paths.py +34 -0
- angr/procedures/win32_kernel/ExAllocatePool.py +12 -0
- angr/procedures/win32_kernel/ExFreePoolWithTag.py +7 -0
- angr/procedures/win32_kernel/__init__.py +3 -0
- angr/procedures/win_user32/__init__.py +0 -0
- angr/procedures/win_user32/chars.py +12 -0
- angr/procedures/win_user32/keyboard.py +13 -0
- angr/procedures/win_user32/messagebox.py +49 -0
- angr/project.py +834 -0
- angr/protos/__init__.py +13 -0
- angr/protos/cfg_pb2.py +31 -0
- angr/protos/function_pb2.py +37 -0
- angr/protos/primitives_pb2.py +124 -0
- angr/protos/variables_pb2.py +126 -0
- angr/protos/xrefs_pb2.py +34 -0
- angr/py.typed +1 -0
- angr/serializable.py +63 -0
- angr/service.py +35 -0
- angr/sim_manager.py +971 -0
- angr/sim_options.py +444 -0
- angr/sim_procedure.py +606 -0
- angr/sim_state.py +1003 -0
- angr/sim_state_options.py +409 -0
- angr/sim_type.py +3372 -0
- angr/sim_variable.py +562 -0
- angr/simos/__init__.py +31 -0
- angr/simos/cgc.py +152 -0
- angr/simos/javavm.py +471 -0
- angr/simos/linux.py +519 -0
- angr/simos/simos.py +450 -0
- angr/simos/snimmuc_nxp.py +152 -0
- angr/simos/userland.py +163 -0
- angr/simos/windows.py +562 -0
- angr/slicer.py +353 -0
- angr/state_hierarchy.py +262 -0
- angr/state_plugins/__init__.py +29 -0
- angr/state_plugins/callstack.py +404 -0
- angr/state_plugins/cgc.py +153 -0
- angr/state_plugins/concrete.py +297 -0
- angr/state_plugins/debug_variables.py +194 -0
- angr/state_plugins/filesystem.py +469 -0
- angr/state_plugins/gdb.py +146 -0
- angr/state_plugins/globals.py +62 -0
- angr/state_plugins/heap/__init__.py +5 -0
- angr/state_plugins/heap/heap_base.py +126 -0
- angr/state_plugins/heap/heap_brk.py +134 -0
- angr/state_plugins/heap/heap_freelist.py +210 -0
- angr/state_plugins/heap/heap_libc.py +45 -0
- angr/state_plugins/heap/heap_ptmalloc.py +646 -0
- angr/state_plugins/heap/utils.py +21 -0
- angr/state_plugins/history.py +548 -0
- angr/state_plugins/inspect.py +376 -0
- angr/state_plugins/javavm_classloader.py +133 -0
- angr/state_plugins/jni_references.py +93 -0
- angr/state_plugins/libc.py +1263 -0
- angr/state_plugins/light_registers.py +170 -0
- angr/state_plugins/log.py +85 -0
- angr/state_plugins/loop_data.py +92 -0
- angr/state_plugins/plugin.py +155 -0
- angr/state_plugins/posix.py +709 -0
- angr/state_plugins/preconstrainer.py +195 -0
- angr/state_plugins/scratch.py +175 -0
- angr/state_plugins/sim_action.py +334 -0
- angr/state_plugins/sim_action_object.py +148 -0
- angr/state_plugins/sim_event.py +58 -0
- angr/state_plugins/solver.py +1129 -0
- angr/state_plugins/symbolizer.py +292 -0
- angr/state_plugins/trace_additions.py +752 -0
- angr/state_plugins/uc_manager.py +85 -0
- angr/state_plugins/unicorn_engine.py +1899 -0
- angr/state_plugins/view.py +341 -0
- angr/storage/__init__.py +9 -0
- angr/storage/file.py +1219 -0
- angr/storage/memory_mixins/__init__.py +393 -0
- angr/storage/memory_mixins/__init__.pyi +49 -0
- angr/storage/memory_mixins/actions_mixin.py +69 -0
- angr/storage/memory_mixins/address_concretization_mixin.py +388 -0
- angr/storage/memory_mixins/bvv_conversion_mixin.py +74 -0
- angr/storage/memory_mixins/clouseau_mixin.py +131 -0
- angr/storage/memory_mixins/conditional_store_mixin.py +24 -0
- angr/storage/memory_mixins/convenient_mappings_mixin.py +257 -0
- angr/storage/memory_mixins/default_filler_mixin.py +146 -0
- angr/storage/memory_mixins/dirty_addrs_mixin.py +9 -0
- angr/storage/memory_mixins/hex_dumper_mixin.py +85 -0
- angr/storage/memory_mixins/javavm_memory/__init__.py +1 -0
- angr/storage/memory_mixins/javavm_memory/javavm_memory_mixin.py +394 -0
- angr/storage/memory_mixins/keyvalue_memory/__init__.py +1 -0
- angr/storage/memory_mixins/keyvalue_memory/keyvalue_memory_mixin.py +36 -0
- angr/storage/memory_mixins/label_merger_mixin.py +31 -0
- angr/storage/memory_mixins/multi_value_merger_mixin.py +68 -0
- angr/storage/memory_mixins/name_resolution_mixin.py +70 -0
- angr/storage/memory_mixins/paged_memory/__init__.py +0 -0
- angr/storage/memory_mixins/paged_memory/page_backer_mixins.py +266 -0
- angr/storage/memory_mixins/paged_memory/paged_memory_mixin.py +750 -0
- angr/storage/memory_mixins/paged_memory/paged_memory_multivalue_mixin.py +63 -0
- angr/storage/memory_mixins/paged_memory/pages/__init__.py +33 -0
- angr/storage/memory_mixins/paged_memory/pages/cooperation.py +330 -0
- angr/storage/memory_mixins/paged_memory/pages/history_tracking_mixin.py +87 -0
- angr/storage/memory_mixins/paged_memory/pages/ispo_mixin.py +53 -0
- angr/storage/memory_mixins/paged_memory/pages/list_page.py +346 -0
- angr/storage/memory_mixins/paged_memory/pages/multi_values.py +290 -0
- angr/storage/memory_mixins/paged_memory/pages/mv_list_page.py +434 -0
- angr/storage/memory_mixins/paged_memory/pages/permissions_mixin.py +33 -0
- angr/storage/memory_mixins/paged_memory/pages/refcount_mixin.py +51 -0
- angr/storage/memory_mixins/paged_memory/pages/ultra_page.py +468 -0
- angr/storage/memory_mixins/paged_memory/privileged_mixin.py +36 -0
- angr/storage/memory_mixins/paged_memory/stack_allocation_mixin.py +73 -0
- angr/storage/memory_mixins/regioned_memory/__init__.py +6 -0
- angr/storage/memory_mixins/regioned_memory/abstract_address_descriptor.py +35 -0
- angr/storage/memory_mixins/regioned_memory/abstract_merger_mixin.py +43 -0
- angr/storage/memory_mixins/regioned_memory/region_category_mixin.py +7 -0
- angr/storage/memory_mixins/regioned_memory/region_data.py +245 -0
- angr/storage/memory_mixins/regioned_memory/region_meta_mixin.py +125 -0
- angr/storage/memory_mixins/regioned_memory/regioned_address_concretization_mixin.py +118 -0
- angr/storage/memory_mixins/regioned_memory/regioned_memory_mixin.py +462 -0
- angr/storage/memory_mixins/regioned_memory/static_find_mixin.py +70 -0
- angr/storage/memory_mixins/simple_interface_mixin.py +73 -0
- angr/storage/memory_mixins/simplification_mixin.py +13 -0
- angr/storage/memory_mixins/size_resolution_mixin.py +140 -0
- angr/storage/memory_mixins/slotted_memory.py +140 -0
- angr/storage/memory_mixins/smart_find_mixin.py +159 -0
- angr/storage/memory_mixins/symbolic_merger_mixin.py +12 -0
- angr/storage/memory_mixins/top_merger_mixin.py +24 -0
- angr/storage/memory_mixins/underconstrained_mixin.py +67 -0
- angr/storage/memory_mixins/unwrapper_mixin.py +26 -0
- angr/storage/memory_object.py +194 -0
- angr/storage/pcap.py +65 -0
- angr/tablespecs.py +90 -0
- angr/utils/__init__.py +33 -0
- angr/utils/algo.py +33 -0
- angr/utils/constants.py +7 -0
- angr/utils/cowdict.py +64 -0
- angr/utils/dynamic_dictlist.py +92 -0
- angr/utils/enums_conv.py +80 -0
- angr/utils/env.py +11 -0
- angr/utils/formatting.py +124 -0
- angr/utils/funcid.py +133 -0
- angr/utils/graph.py +822 -0
- angr/utils/lazy_import.py +12 -0
- angr/utils/library.py +214 -0
- angr/utils/loader.py +55 -0
- angr/utils/mp.py +64 -0
- angr/utils/segment_list.py +558 -0
- angr/utils/timing.py +45 -0
- angr/utils/typing.py +17 -0
- angr/vaults.py +370 -0
- angr-9.2.103.dist-info/LICENSE +24 -0
- angr-9.2.103.dist-info/METADATA +119 -0
- angr-9.2.103.dist-info/RECORD +1300 -0
- angr-9.2.103.dist-info/WHEEL +5 -0
- angr-9.2.103.dist-info/entry_points.txt +2 -0
- angr-9.2.103.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,1408 @@
|
|
|
1
|
+
# pylint:disable=too-many-boolean-expressions
|
|
2
|
+
from typing import Any, Optional, TYPE_CHECKING
|
|
3
|
+
from collections import defaultdict
|
|
4
|
+
import logging
|
|
5
|
+
|
|
6
|
+
from ailment import AILBlockWalker
|
|
7
|
+
from ailment.block import Block
|
|
8
|
+
from ailment.statement import Statement, Assignment, Store, Call, ConditionalJump, DirtyStatement
|
|
9
|
+
from ailment.expression import (
|
|
10
|
+
Register,
|
|
11
|
+
Convert,
|
|
12
|
+
Load,
|
|
13
|
+
StackBaseOffset,
|
|
14
|
+
Expression,
|
|
15
|
+
DirtyExpression,
|
|
16
|
+
VEXCCallExpression,
|
|
17
|
+
Tmp,
|
|
18
|
+
Const,
|
|
19
|
+
BinaryOp,
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
from ...engines.light import SpOffset
|
|
23
|
+
from ...code_location import CodeLocation, ExternalCodeLocation
|
|
24
|
+
from ...sim_variable import SimStackVariable, SimMemoryVariable
|
|
25
|
+
from ...knowledge_plugins.propagations.states import Equivalence
|
|
26
|
+
from ...knowledge_plugins.key_definitions import atoms
|
|
27
|
+
from ...knowledge_plugins.key_definitions.atoms import Register as RegisterAtom
|
|
28
|
+
from ...knowledge_plugins.key_definitions.definition import Definition
|
|
29
|
+
from ...knowledge_plugins.key_definitions.constants import OP_BEFORE
|
|
30
|
+
from .. import Analysis, AnalysesHub
|
|
31
|
+
from .ailgraph_walker import AILGraphWalker
|
|
32
|
+
from .expression_narrower import ExpressionNarrowingWalker
|
|
33
|
+
from .block_simplifier import BlockSimplifier
|
|
34
|
+
from .ccall_rewriters import CCALL_REWRITERS
|
|
35
|
+
from .expression_counters import SingleExpressionCounter
|
|
36
|
+
|
|
37
|
+
if TYPE_CHECKING:
|
|
38
|
+
from ailment.manager import Manager
|
|
39
|
+
from angr.analyses.reaching_definitions import ReachingDefinitionsModel
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
_l = logging.getLogger(__name__)
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
class HasCallNotification(Exception):
|
|
46
|
+
"""
|
|
47
|
+
Notifies the existence of a call statement.
|
|
48
|
+
"""
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
class AILBlockTempCollector(AILBlockWalker):
|
|
52
|
+
"""
|
|
53
|
+
Collects any temporaries used in a block.
|
|
54
|
+
"""
|
|
55
|
+
|
|
56
|
+
def __init__(self, **kwargs):
|
|
57
|
+
super().__init__(**kwargs)
|
|
58
|
+
self.temps = set()
|
|
59
|
+
self.expr_handlers[Tmp] = self._handle_Tmp
|
|
60
|
+
|
|
61
|
+
# pylint:disable=unused-argument
|
|
62
|
+
def _handle_Tmp(self, expr_idx: int, expr: Expression, stmt_idx: int, stmt: Statement, block) -> None:
|
|
63
|
+
if isinstance(expr, Tmp):
|
|
64
|
+
self.temps.add(expr)
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
class AILSimplifier(Analysis):
|
|
68
|
+
"""
|
|
69
|
+
Perform function-level simplifications.
|
|
70
|
+
"""
|
|
71
|
+
|
|
72
|
+
def __init__(
|
|
73
|
+
self,
|
|
74
|
+
func,
|
|
75
|
+
func_graph=None,
|
|
76
|
+
remove_dead_memdefs=False,
|
|
77
|
+
stack_arg_offsets: set[tuple[int, int]] | None = None,
|
|
78
|
+
unify_variables=False,
|
|
79
|
+
ail_manager: Optional["Manager"] = None,
|
|
80
|
+
gp: int | None = None,
|
|
81
|
+
narrow_expressions=False,
|
|
82
|
+
only_consts=False,
|
|
83
|
+
fold_callexprs_into_conditions=False,
|
|
84
|
+
use_callee_saved_regs_at_return=True,
|
|
85
|
+
rewrite_ccalls=True,
|
|
86
|
+
):
|
|
87
|
+
self.func = func
|
|
88
|
+
self.func_graph = func_graph if func_graph is not None else func.graph
|
|
89
|
+
self._reaching_definitions: Optional["ReachingDefinitionsModel"] = None
|
|
90
|
+
self._propagator = None
|
|
91
|
+
|
|
92
|
+
self._remove_dead_memdefs = remove_dead_memdefs
|
|
93
|
+
self._stack_arg_offsets = stack_arg_offsets
|
|
94
|
+
self._unify_vars = unify_variables
|
|
95
|
+
self._ail_manager = ail_manager
|
|
96
|
+
self._gp = gp
|
|
97
|
+
self._narrow_expressions = narrow_expressions
|
|
98
|
+
self._only_consts = only_consts
|
|
99
|
+
self._fold_callexprs_into_conditions = fold_callexprs_into_conditions
|
|
100
|
+
self._use_callee_saved_regs_at_return = use_callee_saved_regs_at_return
|
|
101
|
+
self._should_rewrite_ccalls = rewrite_ccalls
|
|
102
|
+
|
|
103
|
+
self._calls_to_remove: set[CodeLocation] = set()
|
|
104
|
+
self._assignments_to_remove: set[CodeLocation] = set()
|
|
105
|
+
self.blocks = {} # Mapping nodes to simplified blocks
|
|
106
|
+
|
|
107
|
+
self.simplified: bool = False
|
|
108
|
+
self._simplify()
|
|
109
|
+
|
|
110
|
+
def _simplify(self):
|
|
111
|
+
if self._narrow_expressions:
|
|
112
|
+
_l.debug("Narrowing expressions")
|
|
113
|
+
narrowed_exprs = self._narrow_exprs()
|
|
114
|
+
self.simplified |= narrowed_exprs
|
|
115
|
+
if narrowed_exprs:
|
|
116
|
+
_l.debug("... expressions narrowed")
|
|
117
|
+
self._rebuild_func_graph()
|
|
118
|
+
self._clear_cache()
|
|
119
|
+
|
|
120
|
+
_l.debug("Folding expressions")
|
|
121
|
+
folded_exprs = self._fold_exprs()
|
|
122
|
+
self.simplified |= folded_exprs
|
|
123
|
+
if folded_exprs:
|
|
124
|
+
_l.debug("... expressions folded")
|
|
125
|
+
self._rebuild_func_graph()
|
|
126
|
+
# reaching definition analysis results are no longer reliable
|
|
127
|
+
self._clear_cache()
|
|
128
|
+
|
|
129
|
+
if self._only_consts:
|
|
130
|
+
return
|
|
131
|
+
|
|
132
|
+
if self._should_rewrite_ccalls:
|
|
133
|
+
_l.debug("Rewriting ccalls")
|
|
134
|
+
ccalls_rewritten = self._rewrite_ccalls()
|
|
135
|
+
self.simplified |= ccalls_rewritten
|
|
136
|
+
if ccalls_rewritten:
|
|
137
|
+
_l.debug("... ccalls rewritten")
|
|
138
|
+
self._rebuild_func_graph()
|
|
139
|
+
self._clear_cache()
|
|
140
|
+
|
|
141
|
+
if self._unify_vars:
|
|
142
|
+
_l.debug("Removing dead assignments")
|
|
143
|
+
r = self._remove_dead_assignments()
|
|
144
|
+
if r:
|
|
145
|
+
_l.debug("... dead assignments removed")
|
|
146
|
+
self.simplified = True
|
|
147
|
+
self._rebuild_func_graph()
|
|
148
|
+
self._clear_cache()
|
|
149
|
+
|
|
150
|
+
_l.debug("Unifying local variables")
|
|
151
|
+
r = self._unify_local_variables()
|
|
152
|
+
if r:
|
|
153
|
+
_l.debug("... local variables unified")
|
|
154
|
+
self.simplified = True
|
|
155
|
+
self._rebuild_func_graph()
|
|
156
|
+
|
|
157
|
+
# _fold_call_exprs() may set self._calls_to_remove, which will be honored in _remove_dead_assignments()
|
|
158
|
+
_l.debug("Folding call expressions")
|
|
159
|
+
r = self._fold_call_exprs()
|
|
160
|
+
if r:
|
|
161
|
+
_l.debug("... call expressions folded")
|
|
162
|
+
self.simplified = True
|
|
163
|
+
self._rebuild_func_graph()
|
|
164
|
+
|
|
165
|
+
_l.debug("Removing dead assignments")
|
|
166
|
+
r = self._remove_dead_assignments()
|
|
167
|
+
if r:
|
|
168
|
+
_l.debug("... dead assignments removed")
|
|
169
|
+
self.simplified = True
|
|
170
|
+
self._rebuild_func_graph()
|
|
171
|
+
|
|
172
|
+
def _rebuild_func_graph(self):
|
|
173
|
+
def _handler(node):
|
|
174
|
+
return self.blocks.get(node, None)
|
|
175
|
+
|
|
176
|
+
AILGraphWalker(self.func_graph, _handler, replace_nodes=True).walk()
|
|
177
|
+
self.blocks = {}
|
|
178
|
+
|
|
179
|
+
def _compute_reaching_definitions(self) -> "ReachingDefinitionsModel":
|
|
180
|
+
# Computing reaching definitions or return the cached one
|
|
181
|
+
if self._reaching_definitions is not None:
|
|
182
|
+
return self._reaching_definitions
|
|
183
|
+
rd = self.project.analyses.ReachingDefinitions(
|
|
184
|
+
subject=self.func,
|
|
185
|
+
func_graph=self.func_graph,
|
|
186
|
+
# init_context=(), <-- in case of fire break glass
|
|
187
|
+
observe_all=False,
|
|
188
|
+
use_callee_saved_regs_at_return=self._use_callee_saved_regs_at_return,
|
|
189
|
+
track_tmps=True,
|
|
190
|
+
element_limit=1,
|
|
191
|
+
).model
|
|
192
|
+
self._reaching_definitions = rd
|
|
193
|
+
return rd
|
|
194
|
+
|
|
195
|
+
def _compute_propagation(self, immediate_stmt_removal: bool = False):
|
|
196
|
+
# Propagate expressions or return the existing result
|
|
197
|
+
if self._propagator is not None:
|
|
198
|
+
return self._propagator
|
|
199
|
+
prop = self.project.analyses.Propagator(
|
|
200
|
+
func=self.func,
|
|
201
|
+
func_graph=self.func_graph,
|
|
202
|
+
gp=self._gp,
|
|
203
|
+
only_consts=self._only_consts,
|
|
204
|
+
reaching_definitions=self._compute_reaching_definitions(),
|
|
205
|
+
immediate_stmt_removal=immediate_stmt_removal,
|
|
206
|
+
)
|
|
207
|
+
self._propagator = prop
|
|
208
|
+
return prop
|
|
209
|
+
|
|
210
|
+
def _clear_cache(self) -> None:
|
|
211
|
+
self._propagator = None
|
|
212
|
+
self._reaching_definitions = None
|
|
213
|
+
|
|
214
|
+
def _clear_propagator_cache(self) -> None:
|
|
215
|
+
self._propagator = None
|
|
216
|
+
|
|
217
|
+
def _clear_reaching_definitions_cache(self) -> None:
|
|
218
|
+
self._reaching_definitions = None
|
|
219
|
+
|
|
220
|
+
#
|
|
221
|
+
# Expression narrowing
|
|
222
|
+
#
|
|
223
|
+
|
|
224
|
+
def _narrow_exprs(self) -> bool:
|
|
225
|
+
"""
|
|
226
|
+
A register may be used with full width even when only the lower bytes are really needed. This results in the
|
|
227
|
+
incorrect determination of wider variables while the actual variable is narrower (e.g., int64 vs char). This
|
|
228
|
+
optimization narrows a register definition if all its uses are narrower than the definition itself.
|
|
229
|
+
"""
|
|
230
|
+
|
|
231
|
+
narrowed = False
|
|
232
|
+
|
|
233
|
+
addr_and_idx_to_block: dict[tuple[int, int], Block] = {}
|
|
234
|
+
for block in self.func_graph.nodes():
|
|
235
|
+
addr_and_idx_to_block[(block.addr, block.idx)] = block
|
|
236
|
+
|
|
237
|
+
rd = self._compute_reaching_definitions()
|
|
238
|
+
sorted_defs = sorted(rd.all_definitions, key=lambda d: d.codeloc, reverse=True)
|
|
239
|
+
for def_ in (d_ for d_ in sorted_defs if d_.codeloc.context is None):
|
|
240
|
+
if isinstance(def_.atom, atoms.Register):
|
|
241
|
+
# only do this for general purpose register
|
|
242
|
+
skip_def = False
|
|
243
|
+
for reg in self.project.arch.register_list:
|
|
244
|
+
if not reg.artificial and reg.vex_offset == def_.atom.reg_offset and not reg.general_purpose:
|
|
245
|
+
skip_def = True
|
|
246
|
+
break
|
|
247
|
+
|
|
248
|
+
if skip_def:
|
|
249
|
+
continue
|
|
250
|
+
|
|
251
|
+
needs_narrowing, to_size, use_exprs = self._narrowing_needed(def_, rd, addr_and_idx_to_block)
|
|
252
|
+
if needs_narrowing:
|
|
253
|
+
# replace the definition
|
|
254
|
+
if not isinstance(def_.codeloc, ExternalCodeLocation):
|
|
255
|
+
old_block = addr_and_idx_to_block.get((def_.codeloc.block_addr, def_.codeloc.block_idx))
|
|
256
|
+
if old_block is None:
|
|
257
|
+
# this definition might be inside a callee function, which is why the block does not exist
|
|
258
|
+
# ignore it
|
|
259
|
+
continue
|
|
260
|
+
|
|
261
|
+
the_block = self.blocks.get(old_block, old_block)
|
|
262
|
+
stmt = the_block.statements[def_.codeloc.stmt_idx]
|
|
263
|
+
r, new_block = False, None
|
|
264
|
+
if isinstance(stmt, Assignment) and isinstance(stmt.dst, Register):
|
|
265
|
+
tags = dict(stmt.dst.tags)
|
|
266
|
+
tags["reg_name"] = self.project.arch.translate_register_name(
|
|
267
|
+
def_.atom.reg_offset, size=to_size
|
|
268
|
+
)
|
|
269
|
+
tags["write_size"] = stmt.dst.size
|
|
270
|
+
new_assignment_dst = Register(
|
|
271
|
+
stmt.dst.idx,
|
|
272
|
+
None,
|
|
273
|
+
def_.atom.reg_offset,
|
|
274
|
+
to_size * self.project.arch.byte_width,
|
|
275
|
+
**tags,
|
|
276
|
+
)
|
|
277
|
+
new_assignment_src = Convert(
|
|
278
|
+
stmt.src.idx, # FIXME: This is a hack
|
|
279
|
+
stmt.src.bits,
|
|
280
|
+
to_size * self.project.arch.byte_width,
|
|
281
|
+
False,
|
|
282
|
+
stmt.src,
|
|
283
|
+
**stmt.src.tags,
|
|
284
|
+
)
|
|
285
|
+
r, new_block = BlockSimplifier._replace_and_build(
|
|
286
|
+
the_block,
|
|
287
|
+
{
|
|
288
|
+
def_.codeloc: {
|
|
289
|
+
stmt.dst: new_assignment_dst,
|
|
290
|
+
stmt.src: new_assignment_src,
|
|
291
|
+
}
|
|
292
|
+
},
|
|
293
|
+
replace_assignment_dsts=True,
|
|
294
|
+
replace_loads=True,
|
|
295
|
+
)
|
|
296
|
+
elif isinstance(stmt, Call):
|
|
297
|
+
if stmt.ret_expr is not None:
|
|
298
|
+
tags = dict(stmt.ret_expr.tags)
|
|
299
|
+
tags["reg_name"] = self.project.arch.translate_register_name(
|
|
300
|
+
def_.atom.reg_offset, size=to_size
|
|
301
|
+
)
|
|
302
|
+
new_retexpr = Register(
|
|
303
|
+
stmt.ret_expr.idx,
|
|
304
|
+
None,
|
|
305
|
+
def_.atom.reg_offset,
|
|
306
|
+
to_size * self.project.arch.byte_width,
|
|
307
|
+
**tags,
|
|
308
|
+
)
|
|
309
|
+
r, new_block = BlockSimplifier._replace_and_build(
|
|
310
|
+
the_block, {def_.codeloc: {stmt.ret_expr: new_retexpr}}
|
|
311
|
+
)
|
|
312
|
+
if not r:
|
|
313
|
+
# couldn't replace the definition...
|
|
314
|
+
continue
|
|
315
|
+
self.blocks[old_block] = new_block
|
|
316
|
+
|
|
317
|
+
# replace all uses if necessary
|
|
318
|
+
for use_loc, (use_type, use_expr_tpl) in use_exprs:
|
|
319
|
+
if isinstance(use_expr_tpl[0], Register) and to_size == use_expr_tpl[0].size:
|
|
320
|
+
# don't replace registers to the same registers
|
|
321
|
+
continue
|
|
322
|
+
|
|
323
|
+
old_block = addr_and_idx_to_block.get((use_loc.block_addr, use_loc.block_idx))
|
|
324
|
+
the_block = self.blocks.get(old_block, old_block)
|
|
325
|
+
|
|
326
|
+
if use_type in {"expr", "mask", "convert"}:
|
|
327
|
+
# the first used expr
|
|
328
|
+
use_expr_0 = use_expr_tpl[0]
|
|
329
|
+
tags = dict(use_expr_0.tags)
|
|
330
|
+
tags["reg_name"] = self.project.arch.translate_register_name(
|
|
331
|
+
def_.atom.reg_offset, size=to_size
|
|
332
|
+
)
|
|
333
|
+
new_use_expr_0 = Register(
|
|
334
|
+
use_expr_0.idx,
|
|
335
|
+
None,
|
|
336
|
+
def_.atom.reg_offset,
|
|
337
|
+
to_size * self.project.arch.byte_width,
|
|
338
|
+
**tags,
|
|
339
|
+
)
|
|
340
|
+
|
|
341
|
+
# the second used expr (if it exists)
|
|
342
|
+
if len(use_expr_tpl) == 2:
|
|
343
|
+
use_expr_1 = use_expr_tpl[1]
|
|
344
|
+
assert isinstance(use_expr_1, BinaryOp)
|
|
345
|
+
con = use_expr_1.operands[1]
|
|
346
|
+
assert isinstance(con, Const)
|
|
347
|
+
new_use_expr_1 = BinaryOp(
|
|
348
|
+
use_expr_1.idx,
|
|
349
|
+
use_expr_1.op,
|
|
350
|
+
[
|
|
351
|
+
new_use_expr_0,
|
|
352
|
+
Const(con.idx, con.variable, con.value, new_use_expr_0.bits, **con.tags),
|
|
353
|
+
],
|
|
354
|
+
use_expr_1.signed,
|
|
355
|
+
floating_point=use_expr_1.floating_point,
|
|
356
|
+
rounding_mode=use_expr_1.rounding_mode,
|
|
357
|
+
**use_expr_1.tags,
|
|
358
|
+
)
|
|
359
|
+
|
|
360
|
+
if use_expr_1.size > new_use_expr_1.size:
|
|
361
|
+
new_use_expr_1 = Convert(
|
|
362
|
+
None,
|
|
363
|
+
new_use_expr_1.bits,
|
|
364
|
+
use_expr_1.bits,
|
|
365
|
+
False,
|
|
366
|
+
new_use_expr_1,
|
|
367
|
+
**new_use_expr_1.tags,
|
|
368
|
+
)
|
|
369
|
+
|
|
370
|
+
r, new_block = BlockSimplifier._replace_and_build(
|
|
371
|
+
the_block, {use_loc: {use_expr_1: new_use_expr_1}}
|
|
372
|
+
)
|
|
373
|
+
elif len(use_expr_tpl) == 1:
|
|
374
|
+
if use_expr_0.size > new_use_expr_0.size:
|
|
375
|
+
new_use_expr_0 = Convert(
|
|
376
|
+
None,
|
|
377
|
+
new_use_expr_0.bits,
|
|
378
|
+
use_expr_0.bits,
|
|
379
|
+
False,
|
|
380
|
+
new_use_expr_0,
|
|
381
|
+
**new_use_expr_0.tags,
|
|
382
|
+
)
|
|
383
|
+
|
|
384
|
+
r, new_block = BlockSimplifier._replace_and_build(
|
|
385
|
+
the_block, {use_loc: {use_expr_0: new_use_expr_0}}
|
|
386
|
+
)
|
|
387
|
+
else:
|
|
388
|
+
_l.warning("Nothing to replace at %s.", use_loc)
|
|
389
|
+
r = False
|
|
390
|
+
new_block = None
|
|
391
|
+
elif use_type == "binop-convert":
|
|
392
|
+
use_expr_0 = use_expr_tpl[0]
|
|
393
|
+
tags = dict(use_expr_0.tags)
|
|
394
|
+
tags["reg_name"] = self.project.arch.translate_register_name(
|
|
395
|
+
def_.atom.reg_offset, size=to_size
|
|
396
|
+
)
|
|
397
|
+
new_use_expr_0 = Register(
|
|
398
|
+
use_expr_0.idx,
|
|
399
|
+
None,
|
|
400
|
+
def_.atom.reg_offset,
|
|
401
|
+
to_size * self.project.arch.byte_width,
|
|
402
|
+
**tags,
|
|
403
|
+
)
|
|
404
|
+
|
|
405
|
+
use_expr_1: BinaryOp = use_expr_tpl[1]
|
|
406
|
+
# build the new use_expr_1
|
|
407
|
+
new_use_expr_1_operands = {}
|
|
408
|
+
if use_expr_1.operands[0] is use_expr_0:
|
|
409
|
+
new_use_expr_1_operands[0] = new_use_expr_0
|
|
410
|
+
other_operand = use_expr_1.operands[1]
|
|
411
|
+
else:
|
|
412
|
+
new_use_expr_1_operands[1] = new_use_expr_0
|
|
413
|
+
other_operand = use_expr_1.operands[0]
|
|
414
|
+
use_expr_2: Convert = use_expr_tpl[2]
|
|
415
|
+
if other_operand.bits == use_expr_2.from_bits:
|
|
416
|
+
new_other_operand = Convert(
|
|
417
|
+
None, use_expr_2.from_bits, use_expr_2.to_bits, False, other_operand
|
|
418
|
+
)
|
|
419
|
+
else:
|
|
420
|
+
# Some operations, like Sar and Shl, have operands with different sizes
|
|
421
|
+
new_other_operand = other_operand
|
|
422
|
+
|
|
423
|
+
if 0 in new_use_expr_1_operands:
|
|
424
|
+
new_use_expr_1_operands[1] = new_other_operand
|
|
425
|
+
else:
|
|
426
|
+
new_use_expr_1_operands[0] = new_other_operand
|
|
427
|
+
|
|
428
|
+
# build new use_expr_1
|
|
429
|
+
new_use_expr_1 = BinaryOp(
|
|
430
|
+
use_expr_1.idx,
|
|
431
|
+
use_expr_1.op,
|
|
432
|
+
[new_use_expr_1_operands[0], new_use_expr_1_operands[1]],
|
|
433
|
+
use_expr_1.signed,
|
|
434
|
+
bits=to_size * 8,
|
|
435
|
+
floating_point=use_expr_1.floating_point,
|
|
436
|
+
rounding_mode=use_expr_1.rounding_mode,
|
|
437
|
+
**use_expr_1.tags,
|
|
438
|
+
)
|
|
439
|
+
|
|
440
|
+
# first remove the old conversion
|
|
441
|
+
r, new_block = BlockSimplifier._replace_and_build(
|
|
442
|
+
the_block, {use_loc: {use_expr_2: use_expr_2.operand}}
|
|
443
|
+
)
|
|
444
|
+
# then replace use_expr_1
|
|
445
|
+
if r:
|
|
446
|
+
r, new_block = BlockSimplifier._replace_and_build(
|
|
447
|
+
new_block, {use_loc: {use_expr_1: new_use_expr_1}}
|
|
448
|
+
)
|
|
449
|
+
else:
|
|
450
|
+
raise TypeError(f'Unsupported use_type value "{use_type}"')
|
|
451
|
+
|
|
452
|
+
if not r:
|
|
453
|
+
_l.warning("Failed to replace use-expr at %s.", use_loc)
|
|
454
|
+
else:
|
|
455
|
+
self.blocks[old_block] = new_block
|
|
456
|
+
|
|
457
|
+
narrowed = True
|
|
458
|
+
|
|
459
|
+
return narrowed
|
|
460
|
+
|
|
461
|
+
def _narrowing_needed(
|
|
462
|
+
self, def_, rd, addr_and_idx_to_block
|
|
463
|
+
) -> tuple[bool, int | None, list[tuple[CodeLocation, tuple[str, tuple[Expression, ...]]]] | None]:
|
|
464
|
+
def_size = def_.size
|
|
465
|
+
# find its uses
|
|
466
|
+
use_and_exprs = rd.all_uses.get_uses_with_expr(def_)
|
|
467
|
+
|
|
468
|
+
all_used_sizes = set()
|
|
469
|
+
used_by: list[tuple[CodeLocation, tuple[str, tuple[Expression, ...]]]] = []
|
|
470
|
+
|
|
471
|
+
for loc, expr in use_and_exprs:
|
|
472
|
+
old_block = addr_and_idx_to_block.get((loc.block_addr, loc.block_idx), None)
|
|
473
|
+
if old_block is None:
|
|
474
|
+
# missing a block for whatever reason
|
|
475
|
+
return False, None, None
|
|
476
|
+
|
|
477
|
+
block = self.blocks.get(old_block, old_block)
|
|
478
|
+
if loc.stmt_idx >= len(block.statements):
|
|
479
|
+
# missing a statement for whatever reason
|
|
480
|
+
return False, None, None
|
|
481
|
+
stmt = block.statements[loc.stmt_idx]
|
|
482
|
+
|
|
483
|
+
expr_size, used_by_exprs = self._extract_expression_effective_size(stmt, expr)
|
|
484
|
+
if expr_size is None:
|
|
485
|
+
# it's probably used in full width
|
|
486
|
+
return False, None, None
|
|
487
|
+
|
|
488
|
+
all_used_sizes.add(expr_size)
|
|
489
|
+
used_by.append((loc, used_by_exprs))
|
|
490
|
+
|
|
491
|
+
if len(all_used_sizes) == 1 and next(iter(all_used_sizes)) < def_size:
|
|
492
|
+
return True, next(iter(all_used_sizes)), used_by
|
|
493
|
+
|
|
494
|
+
return False, None, None
|
|
495
|
+
|
|
496
|
+
def _extract_expression_effective_size(
|
|
497
|
+
self, statement, expr
|
|
498
|
+
) -> tuple[int | None, tuple[str, tuple[Expression, ...]] | None]:
|
|
499
|
+
"""
|
|
500
|
+
Determine the effective size of an expression when it's used.
|
|
501
|
+
"""
|
|
502
|
+
|
|
503
|
+
walker = ExpressionNarrowingWalker(expr)
|
|
504
|
+
walker.walk_statement(statement)
|
|
505
|
+
if not walker.operations:
|
|
506
|
+
if expr is None:
|
|
507
|
+
return None, None
|
|
508
|
+
return expr.size, ("expr", (expr,))
|
|
509
|
+
|
|
510
|
+
first_op = walker.operations[0]
|
|
511
|
+
if isinstance(first_op, Convert):
|
|
512
|
+
if first_op.to_bits >= self.project.arch.byte_width:
|
|
513
|
+
# we need at least one byte!
|
|
514
|
+
return first_op.to_bits // self.project.arch.byte_width, ("convert", (first_op,))
|
|
515
|
+
if isinstance(first_op, BinaryOp):
|
|
516
|
+
second_op = None
|
|
517
|
+
if len(walker.operations) >= 2:
|
|
518
|
+
second_op = walker.operations[1]
|
|
519
|
+
if (
|
|
520
|
+
first_op.op == "And"
|
|
521
|
+
and isinstance(first_op.operands[1], Const)
|
|
522
|
+
and (second_op is None or isinstance(second_op, BinaryOp) and isinstance(second_op.operands[1], Const))
|
|
523
|
+
):
|
|
524
|
+
mask = first_op.operands[1].value
|
|
525
|
+
if mask == 0xFF:
|
|
526
|
+
return 1, ("mask", (first_op, second_op)) if second_op is not None else ("mask", (first_op,))
|
|
527
|
+
if mask == 0xFFFF:
|
|
528
|
+
return 2, ("mask", (first_op, second_op)) if second_op is not None else ("mask", (first_op,))
|
|
529
|
+
if mask == 0xFFFF_FFFF:
|
|
530
|
+
return 4, ("mask", (first_op, second_op)) if second_op is not None else ("mask", (first_op,))
|
|
531
|
+
if (
|
|
532
|
+
(first_op.operands[0] is expr or first_op.operands[1] is expr)
|
|
533
|
+
and first_op.op not in {"Shr", "Sar"}
|
|
534
|
+
and isinstance(second_op, Convert)
|
|
535
|
+
and second_op.from_bits == expr.bits
|
|
536
|
+
and second_op.to_bits >= self.project.arch.byte_width # we need at least one byte!
|
|
537
|
+
):
|
|
538
|
+
return min(expr.bits, second_op.to_bits) // self.project.arch.byte_width, (
|
|
539
|
+
"binop-convert",
|
|
540
|
+
(expr, first_op, second_op),
|
|
541
|
+
)
|
|
542
|
+
|
|
543
|
+
if expr is None:
|
|
544
|
+
return None, None
|
|
545
|
+
return expr.size, ("expr", (expr,))
|
|
546
|
+
|
|
547
|
+
#
|
|
548
|
+
# Expression folding
|
|
549
|
+
#
|
|
550
|
+
|
|
551
|
+
def _fold_exprs(self):
|
|
552
|
+
"""
|
|
553
|
+
Fold expressions: Fold assigned expressions that are only used once.
|
|
554
|
+
"""
|
|
555
|
+
|
|
556
|
+
# propagator
|
|
557
|
+
propagator = self._compute_propagation(immediate_stmt_removal=True)
|
|
558
|
+
replacements = propagator.replacements
|
|
559
|
+
|
|
560
|
+
# take replacements and rebuild the corresponding blocks
|
|
561
|
+
replacements_by_block_addrs_and_idx = defaultdict(dict)
|
|
562
|
+
for codeloc, reps in replacements.items():
|
|
563
|
+
if reps:
|
|
564
|
+
replacements_by_block_addrs_and_idx[(codeloc.block_addr, codeloc.block_idx)][codeloc] = reps
|
|
565
|
+
|
|
566
|
+
if not replacements_by_block_addrs_and_idx:
|
|
567
|
+
return False
|
|
568
|
+
|
|
569
|
+
blocks_by_addr_and_idx = {(node.addr, node.idx): node for node in self.func_graph.nodes()}
|
|
570
|
+
|
|
571
|
+
if self._stack_arg_offsets:
|
|
572
|
+
insn_addrs_using_stack_args = {ins_addr for ins_addr, _ in self._stack_arg_offsets}
|
|
573
|
+
else:
|
|
574
|
+
insn_addrs_using_stack_args = None
|
|
575
|
+
|
|
576
|
+
replaced = False
|
|
577
|
+
for (block_addr, block_idx), reps in replacements_by_block_addrs_and_idx.items():
|
|
578
|
+
block = blocks_by_addr_and_idx[(block_addr, block_idx)]
|
|
579
|
+
|
|
580
|
+
# only replace loads if there are stack arguments in this block
|
|
581
|
+
replace_loads = insn_addrs_using_stack_args is not None and {
|
|
582
|
+
stmt.ins_addr for stmt in block.statements
|
|
583
|
+
}.intersection(insn_addrs_using_stack_args)
|
|
584
|
+
|
|
585
|
+
r, new_block = BlockSimplifier._replace_and_build(block, reps, gp=self._gp, replace_loads=replace_loads)
|
|
586
|
+
replaced |= r
|
|
587
|
+
self.blocks[block] = new_block
|
|
588
|
+
|
|
589
|
+
if replaced:
|
|
590
|
+
# blocks have been rebuilt - expression propagation results are no longer reliable
|
|
591
|
+
self._clear_cache()
|
|
592
|
+
return replaced
|
|
593
|
+
|
|
594
|
+
#
|
|
595
|
+
# Unifying local variables
|
|
596
|
+
#
|
|
597
|
+
|
|
598
|
+
def _unify_local_variables(self) -> bool:
|
|
599
|
+
"""
|
|
600
|
+
Find variables that are definitely equivalent and then eliminate unnecessary copies.
|
|
601
|
+
"""
|
|
602
|
+
|
|
603
|
+
simplified = False
|
|
604
|
+
|
|
605
|
+
prop = self._compute_propagation()
|
|
606
|
+
if not prop.model.equivalence:
|
|
607
|
+
return simplified
|
|
608
|
+
|
|
609
|
+
addr_and_idx_to_block: dict[tuple[int, int], Block] = {}
|
|
610
|
+
for block in self.func_graph.nodes():
|
|
611
|
+
addr_and_idx_to_block[(block.addr, block.idx)] = block
|
|
612
|
+
|
|
613
|
+
equivalences: dict[Any, set[Equivalence]] = defaultdict(set)
|
|
614
|
+
atom_by_loc = set()
|
|
615
|
+
for eq in prop.model.equivalence:
|
|
616
|
+
equivalences[eq.atom1].add(eq)
|
|
617
|
+
atom_by_loc.add((eq.codeloc, eq.atom1))
|
|
618
|
+
|
|
619
|
+
# sort keys to ensure a reproducible result
|
|
620
|
+
sorted_loc_and_atoms = sorted(atom_by_loc, key=lambda x: x[0])
|
|
621
|
+
|
|
622
|
+
for _, atom in sorted_loc_and_atoms:
|
|
623
|
+
eqs = equivalences[atom]
|
|
624
|
+
if len(eqs) > 1:
|
|
625
|
+
continue
|
|
626
|
+
|
|
627
|
+
eq = next(iter(eqs))
|
|
628
|
+
|
|
629
|
+
# Acceptable equivalence classes:
|
|
630
|
+
#
|
|
631
|
+
# stack variable == register
|
|
632
|
+
# register variable == register
|
|
633
|
+
# stack variable == Conv(register, M->N)
|
|
634
|
+
# global variable == register
|
|
635
|
+
#
|
|
636
|
+
# Equivalence is generally created at assignment sites. Therefore, eq.atom0 is the definition and
|
|
637
|
+
# eq.atom1 is the use.
|
|
638
|
+
the_def = None
|
|
639
|
+
if isinstance(eq.atom0, SimMemoryVariable): # covers both Stack and Global variables
|
|
640
|
+
if isinstance(eq.atom1, Register):
|
|
641
|
+
# stack_var == register or global_var == register
|
|
642
|
+
to_replace = eq.atom1
|
|
643
|
+
to_replace_is_def = False
|
|
644
|
+
elif isinstance(eq.atom1, Convert) and isinstance(eq.atom1.operand, Register):
|
|
645
|
+
# stack_var == Conv(register, M->N)
|
|
646
|
+
to_replace = eq.atom1.operand
|
|
647
|
+
to_replace_is_def = False
|
|
648
|
+
else:
|
|
649
|
+
continue
|
|
650
|
+
|
|
651
|
+
elif isinstance(eq.atom0, Register):
|
|
652
|
+
if isinstance(eq.atom1, Register):
|
|
653
|
+
# register == register
|
|
654
|
+
if self.project.arch.is_artificial_register(eq.atom0.reg_offset, eq.atom0.size):
|
|
655
|
+
to_replace = eq.atom0
|
|
656
|
+
to_replace_is_def = True
|
|
657
|
+
else:
|
|
658
|
+
to_replace = eq.atom1
|
|
659
|
+
to_replace_is_def = False
|
|
660
|
+
else:
|
|
661
|
+
continue
|
|
662
|
+
|
|
663
|
+
else:
|
|
664
|
+
continue
|
|
665
|
+
|
|
666
|
+
# find the definition of this register
|
|
667
|
+
rd = self._compute_reaching_definitions()
|
|
668
|
+
if to_replace_is_def:
|
|
669
|
+
# find defs
|
|
670
|
+
defs = []
|
|
671
|
+
for def_ in rd.all_definitions:
|
|
672
|
+
if def_.codeloc == eq.codeloc:
|
|
673
|
+
if isinstance(to_replace, SimStackVariable):
|
|
674
|
+
if isinstance(def_.atom, atoms.MemoryLocation) and isinstance(
|
|
675
|
+
def_.atom.addr, atoms.SpOffset
|
|
676
|
+
):
|
|
677
|
+
if to_replace.offset == def_.atom.addr.offset:
|
|
678
|
+
defs.append(def_)
|
|
679
|
+
elif isinstance(to_replace, Register):
|
|
680
|
+
if isinstance(def_.atom, atoms.Register) and to_replace.reg_offset == def_.atom.reg_offset:
|
|
681
|
+
defs.append(def_)
|
|
682
|
+
if len(defs) != 1:
|
|
683
|
+
continue
|
|
684
|
+
the_def = defs[0]
|
|
685
|
+
else:
|
|
686
|
+
# find uses
|
|
687
|
+
defs = rd.all_uses.get_uses_by_location(eq.codeloc)
|
|
688
|
+
if len(defs) != 1:
|
|
689
|
+
# there are multiple defs for this register - we do not support replacing all of them
|
|
690
|
+
continue
|
|
691
|
+
for def_ in defs:
|
|
692
|
+
def_: Definition
|
|
693
|
+
if isinstance(def_.atom, atoms.Register) and def_.atom.reg_offset == to_replace.reg_offset:
|
|
694
|
+
# found it!
|
|
695
|
+
the_def = def_
|
|
696
|
+
break
|
|
697
|
+
if the_def is None:
|
|
698
|
+
continue
|
|
699
|
+
if the_def.codeloc.context:
|
|
700
|
+
# the definition is in a callee function
|
|
701
|
+
continue
|
|
702
|
+
|
|
703
|
+
if isinstance(the_def.codeloc, ExternalCodeLocation):
|
|
704
|
+
# this is a function argument. we enter a slightly different logic and try to eliminate copies of this
|
|
705
|
+
# argument if
|
|
706
|
+
# (a) the on-stack or in-register copy of it has never been modified in this function
|
|
707
|
+
# (b) the function argument register has never been updated.
|
|
708
|
+
# TODO: we may loosen requirement (b) once we have real register versioning in AIL.
|
|
709
|
+
defs = [def_ for def_ in rd.all_definitions if def_.codeloc == eq.codeloc]
|
|
710
|
+
all_uses_with_def = None
|
|
711
|
+
replace_with = None
|
|
712
|
+
remove_initial_assignment = None
|
|
713
|
+
|
|
714
|
+
if defs and len(defs) == 1:
|
|
715
|
+
arg_copy_def = defs[0]
|
|
716
|
+
if (
|
|
717
|
+
isinstance(arg_copy_def.atom, atoms.MemoryLocation)
|
|
718
|
+
and isinstance(arg_copy_def.atom.addr, SpOffset)
|
|
719
|
+
or isinstance(arg_copy_def.atom, atoms.Register)
|
|
720
|
+
):
|
|
721
|
+
# found the copied definition (either a stack variable or a register variable)
|
|
722
|
+
|
|
723
|
+
# Make sure there is no other write to this stack location if the copy is a stack variable
|
|
724
|
+
if isinstance(arg_copy_def.atom, atoms.MemoryLocation):
|
|
725
|
+
if any(
|
|
726
|
+
(def_ != arg_copy_def and def_.atom == arg_copy_def.atom)
|
|
727
|
+
for def_ in rd.all_definitions
|
|
728
|
+
if isinstance(def_.atom, atoms.MemoryLocation)
|
|
729
|
+
):
|
|
730
|
+
continue
|
|
731
|
+
|
|
732
|
+
# Make sure the register is never updated across this function
|
|
733
|
+
if any(
|
|
734
|
+
(def_ != the_def and def_.atom == the_def.atom)
|
|
735
|
+
for def_ in rd.all_definitions
|
|
736
|
+
if isinstance(def_.atom, atoms.Register) and rd.all_uses.get_uses(def_)
|
|
737
|
+
):
|
|
738
|
+
continue
|
|
739
|
+
|
|
740
|
+
# find all its uses
|
|
741
|
+
all_arg_copy_var_uses: set[tuple[CodeLocation, Any]] = set(
|
|
742
|
+
rd.all_uses.get_uses_with_expr(arg_copy_def)
|
|
743
|
+
)
|
|
744
|
+
all_uses_with_def = set()
|
|
745
|
+
|
|
746
|
+
should_abort = False
|
|
747
|
+
for use in all_arg_copy_var_uses:
|
|
748
|
+
used_expr = use[1]
|
|
749
|
+
if used_expr is not None and used_expr.size != arg_copy_def.size:
|
|
750
|
+
should_abort = True
|
|
751
|
+
break
|
|
752
|
+
all_uses_with_def.add((arg_copy_def, use))
|
|
753
|
+
if should_abort:
|
|
754
|
+
continue
|
|
755
|
+
|
|
756
|
+
# to_replace = Load(None, StackBaseOffset(None, self.project.arch.bits, eq.atom0.offset),
|
|
757
|
+
# eq.atom0.size, endness=self.project.arch.memory_endness)
|
|
758
|
+
replace_with = eq.atom1
|
|
759
|
+
remove_initial_assignment = True
|
|
760
|
+
|
|
761
|
+
if all_uses_with_def is None:
|
|
762
|
+
continue
|
|
763
|
+
|
|
764
|
+
else:
|
|
765
|
+
if (
|
|
766
|
+
eq.codeloc.block_addr == the_def.codeloc.block_addr
|
|
767
|
+
and eq.codeloc.block_idx == the_def.codeloc.block_idx
|
|
768
|
+
):
|
|
769
|
+
# the definition and the eq location are within the same block, and the definition is before
|
|
770
|
+
# the eq location.
|
|
771
|
+
if eq.codeloc.stmt_idx < the_def.codeloc.stmt_idx:
|
|
772
|
+
continue
|
|
773
|
+
else:
|
|
774
|
+
# the definition is in the predecessor block of the eq
|
|
775
|
+
eq_block = next(
|
|
776
|
+
iter(
|
|
777
|
+
bb
|
|
778
|
+
for bb in self.func_graph
|
|
779
|
+
if bb.addr == eq.codeloc.block_addr and bb.idx == eq.codeloc.block_idx
|
|
780
|
+
)
|
|
781
|
+
)
|
|
782
|
+
eq_block_preds = set(self.func_graph.predecessors(eq_block))
|
|
783
|
+
if not any(
|
|
784
|
+
pred.addr == the_def.codeloc.block_addr and pred.idx == the_def.codeloc.block_idx
|
|
785
|
+
for pred in eq_block_preds
|
|
786
|
+
):
|
|
787
|
+
continue
|
|
788
|
+
|
|
789
|
+
if isinstance(eq.atom0, SimStackVariable):
|
|
790
|
+
# create the memory loading expression
|
|
791
|
+
new_idx = None if self._ail_manager is None else next(self._ail_manager.atom_ctr)
|
|
792
|
+
replace_with = Load(
|
|
793
|
+
new_idx,
|
|
794
|
+
StackBaseOffset(None, self.project.arch.bits, eq.atom0.offset),
|
|
795
|
+
eq.atom0.size,
|
|
796
|
+
endness=self.project.arch.memory_endness,
|
|
797
|
+
)
|
|
798
|
+
elif isinstance(eq.atom0, SimMemoryVariable) and isinstance(eq.atom0.addr, int):
|
|
799
|
+
# create the memory loading expression
|
|
800
|
+
new_idx = None if self._ail_manager is None else next(self._ail_manager.atom_ctr)
|
|
801
|
+
replace_with = Load(
|
|
802
|
+
new_idx,
|
|
803
|
+
Const(None, None, eq.atom0.addr, self.project.arch.bits),
|
|
804
|
+
eq.atom0.size,
|
|
805
|
+
endness=self.project.arch.memory_endness,
|
|
806
|
+
)
|
|
807
|
+
elif isinstance(eq.atom0, Register):
|
|
808
|
+
if isinstance(eq.atom1, Register):
|
|
809
|
+
if self.project.arch.is_artificial_register(eq.atom0.reg_offset, eq.atom0.size):
|
|
810
|
+
replace_with = eq.atom1
|
|
811
|
+
else:
|
|
812
|
+
replace_with = eq.atom0
|
|
813
|
+
else:
|
|
814
|
+
raise RuntimeError("Unsupported atom1 type %s." % type(eq.atom1))
|
|
815
|
+
else:
|
|
816
|
+
raise RuntimeError("Unsupported atom0 type %s." % type(eq.atom0))
|
|
817
|
+
|
|
818
|
+
to_replace_def = the_def
|
|
819
|
+
|
|
820
|
+
# find all uses of this definition
|
|
821
|
+
# we make a copy of the set since we may touch the set (uses) when replacing expressions
|
|
822
|
+
all_uses: set[tuple[CodeLocation, Any]] = set(rd.all_uses.get_uses_with_expr(to_replace_def))
|
|
823
|
+
# make sure none of these uses are phi nodes (depends on more than one def)
|
|
824
|
+
all_uses_with_unique_def = set()
|
|
825
|
+
for use_and_expr in all_uses:
|
|
826
|
+
use_loc, used_expr = use_and_expr
|
|
827
|
+
defs_and_exprs = rd.all_uses.get_uses_by_location(use_loc, exprs=True)
|
|
828
|
+
filtered_defs = {def_ for def_, expr_ in defs_and_exprs if expr_ == used_expr}
|
|
829
|
+
if len(filtered_defs) == 1:
|
|
830
|
+
all_uses_with_unique_def.add(use_and_expr)
|
|
831
|
+
else:
|
|
832
|
+
# optimization: break early
|
|
833
|
+
break
|
|
834
|
+
|
|
835
|
+
if len(all_uses) != len(all_uses_with_unique_def):
|
|
836
|
+
# only when all uses are determined by the same definition will we continue with the simplification
|
|
837
|
+
continue
|
|
838
|
+
|
|
839
|
+
# one more check: there can be at most one assignment in all these use locations
|
|
840
|
+
assignment_ctr = 0
|
|
841
|
+
for use_loc, used_expr in all_uses:
|
|
842
|
+
block = addr_and_idx_to_block[(use_loc.block_addr, use_loc.block_idx)]
|
|
843
|
+
stmt = block.statements[use_loc.stmt_idx]
|
|
844
|
+
if isinstance(stmt, Assignment):
|
|
845
|
+
assignment_ctr += 1
|
|
846
|
+
if assignment_ctr > 1:
|
|
847
|
+
continue
|
|
848
|
+
|
|
849
|
+
all_uses_with_def = {(to_replace_def, use_and_expr) for use_and_expr in all_uses}
|
|
850
|
+
|
|
851
|
+
remove_initial_assignment = False # expression folding will take care of it
|
|
852
|
+
|
|
853
|
+
# ensure the uses we consider are all after the eq location
|
|
854
|
+
filtered_all_uses_with_def = []
|
|
855
|
+
for def_, use_and_expr in all_uses_with_def:
|
|
856
|
+
u = use_and_expr[0]
|
|
857
|
+
if (
|
|
858
|
+
u.block_addr == eq.codeloc.block_addr
|
|
859
|
+
and u.block_idx == eq.codeloc.block_idx
|
|
860
|
+
and u.stmt_idx < eq.codeloc.stmt_idx
|
|
861
|
+
):
|
|
862
|
+
# this use happens before the assignment - ignore it
|
|
863
|
+
continue
|
|
864
|
+
filtered_all_uses_with_def.append((def_, use_and_expr))
|
|
865
|
+
all_uses_with_def = filtered_all_uses_with_def
|
|
866
|
+
|
|
867
|
+
if not all_uses_with_def:
|
|
868
|
+
# definitions without uses may simply be our data-flow analysis being incorrect. do not remove them.
|
|
869
|
+
continue
|
|
870
|
+
|
|
871
|
+
# TODO: We can only replace all these uses with the stack variable if the stack variable isn't
|
|
872
|
+
# TODO: re-assigned of a new value. Perform this check.
|
|
873
|
+
|
|
874
|
+
# replace all uses
|
|
875
|
+
all_uses_replaced = True
|
|
876
|
+
for def_, use_and_expr in all_uses_with_def:
|
|
877
|
+
u, used_expr = use_and_expr
|
|
878
|
+
|
|
879
|
+
use_expr_defns = []
|
|
880
|
+
for d in rd.all_uses.get_uses_by_location(u):
|
|
881
|
+
if (
|
|
882
|
+
isinstance(d.atom, RegisterAtom)
|
|
883
|
+
and isinstance(def_.atom, RegisterAtom)
|
|
884
|
+
and d.atom.reg_offset == def_.atom.reg_offset
|
|
885
|
+
):
|
|
886
|
+
use_expr_defns.append(d)
|
|
887
|
+
elif d.atom == def_.atom:
|
|
888
|
+
use_expr_defns.append(d)
|
|
889
|
+
# you can never replace a use with dependencies from outside the checked defn
|
|
890
|
+
if len(use_expr_defns) != 1 or list(use_expr_defns)[0] != def_:
|
|
891
|
+
if not use_expr_defns:
|
|
892
|
+
_l.warning("There was no use_expr_defns for %s, this is likely a bug", u)
|
|
893
|
+
# TODO: can you have multiple definitions which can all be eliminated?
|
|
894
|
+
all_uses_replaced = False
|
|
895
|
+
continue
|
|
896
|
+
|
|
897
|
+
if u == eq.codeloc:
|
|
898
|
+
# skip the very initial assignment location
|
|
899
|
+
continue
|
|
900
|
+
old_block = addr_and_idx_to_block.get((u.block_addr, u.block_idx), None)
|
|
901
|
+
if old_block is None:
|
|
902
|
+
continue
|
|
903
|
+
if used_expr is None:
|
|
904
|
+
all_uses_replaced = False
|
|
905
|
+
continue
|
|
906
|
+
|
|
907
|
+
# ensure the expression that we want to replace with is still up-to-date
|
|
908
|
+
replace_with_original_def = self._find_atom_def_at(replace_with, rd, def_.codeloc)
|
|
909
|
+
if replace_with_original_def is not None and not self._check_atom_last_def(
|
|
910
|
+
replace_with, u, rd, replace_with_original_def
|
|
911
|
+
):
|
|
912
|
+
all_uses_replaced = False
|
|
913
|
+
continue
|
|
914
|
+
|
|
915
|
+
# if there is an updated block, use it
|
|
916
|
+
the_block = self.blocks.get(old_block, old_block)
|
|
917
|
+
stmt: Statement = the_block.statements[u.stmt_idx]
|
|
918
|
+
|
|
919
|
+
replace_with_copy = replace_with.copy()
|
|
920
|
+
if used_expr.size != replace_with_copy.size:
|
|
921
|
+
new_idx = None if self._ail_manager is None else next(self._ail_manager.atom_ctr)
|
|
922
|
+
replace_with_copy = Convert(
|
|
923
|
+
new_idx,
|
|
924
|
+
replace_with_copy.bits,
|
|
925
|
+
used_expr.bits,
|
|
926
|
+
False,
|
|
927
|
+
replace_with_copy,
|
|
928
|
+
)
|
|
929
|
+
|
|
930
|
+
r, new_block = self._replace_expr_and_update_block(
|
|
931
|
+
the_block, u.stmt_idx, stmt, def_, u, used_expr, replace_with_copy
|
|
932
|
+
)
|
|
933
|
+
if r:
|
|
934
|
+
self.blocks[old_block] = new_block
|
|
935
|
+
else:
|
|
936
|
+
# failed to replace a use - we need to keep the initial assignment!
|
|
937
|
+
all_uses_replaced = False
|
|
938
|
+
simplified |= r
|
|
939
|
+
|
|
940
|
+
if all_uses_replaced and remove_initial_assignment:
|
|
941
|
+
# the initial statement can be removed
|
|
942
|
+
self._assignments_to_remove.add(eq.codeloc)
|
|
943
|
+
|
|
944
|
+
if simplified:
|
|
945
|
+
self._clear_cache()
|
|
946
|
+
return simplified
|
|
947
|
+
|
|
948
|
+
@staticmethod
|
|
949
|
+
def _find_atom_def_at(atom, rd, codeloc: CodeLocation) -> Definition | None:
|
|
950
|
+
if isinstance(atom, Register):
|
|
951
|
+
defs = rd.get_defs(atom, codeloc, OP_BEFORE)
|
|
952
|
+
return next(iter(defs)) if len(defs) == 1 else None
|
|
953
|
+
|
|
954
|
+
return None
|
|
955
|
+
|
|
956
|
+
@staticmethod
|
|
957
|
+
def _check_atom_last_def(atom, codeloc, rd, the_def) -> bool:
|
|
958
|
+
if isinstance(atom, Register):
|
|
959
|
+
defs = rd.get_defs(atom, codeloc, OP_BEFORE)
|
|
960
|
+
for d in defs:
|
|
961
|
+
if d.codeloc != the_def.codeloc:
|
|
962
|
+
return False
|
|
963
|
+
|
|
964
|
+
return True
|
|
965
|
+
|
|
966
|
+
#
|
|
967
|
+
# Folding call expressions
|
|
968
|
+
#
|
|
969
|
+
|
|
970
|
+
@staticmethod
|
|
971
|
+
def _is_expr_using_temporaries(expr: Expression) -> bool:
|
|
972
|
+
walker = AILBlockTempCollector()
|
|
973
|
+
walker.walk_expression(expr)
|
|
974
|
+
return len(walker.temps) > 0
|
|
975
|
+
|
|
976
|
+
@staticmethod
|
|
977
|
+
def _is_stmt_using_temporaries(stmt: Statement) -> bool:
|
|
978
|
+
walker = AILBlockTempCollector()
|
|
979
|
+
walker.walk_statement(stmt)
|
|
980
|
+
return len(walker.temps) > 0
|
|
981
|
+
|
|
982
|
+
def _fold_call_exprs(self) -> bool:
|
|
983
|
+
"""
|
|
984
|
+
Fold a call expression (statement) into other statements if the return value of the call expression (statement)
|
|
985
|
+
is only used once, and the use site and the call site belongs to the same supernode.
|
|
986
|
+
|
|
987
|
+
Example::
|
|
988
|
+
|
|
989
|
+
s1 = func();
|
|
990
|
+
s0 = s1;
|
|
991
|
+
if (s0) ...
|
|
992
|
+
|
|
993
|
+
after folding, it will be transformed to::
|
|
994
|
+
|
|
995
|
+
s0 = func();
|
|
996
|
+
if (s0) ...
|
|
997
|
+
|
|
998
|
+
s0 can be folded into the condition, which means this example can further be transformed to::
|
|
999
|
+
|
|
1000
|
+
if (func()) ...
|
|
1001
|
+
|
|
1002
|
+
this behavior is controlled by fold_callexprs_into_conditions. This to avoid cases where func() is called more
|
|
1003
|
+
than once after simplification and graph structuring where conditions might be duplicated (e.g., in Dream).
|
|
1004
|
+
In such cases, the one-use expression folder in RegionSimplifier will perform this transformation.
|
|
1005
|
+
"""
|
|
1006
|
+
|
|
1007
|
+
simplified = False
|
|
1008
|
+
|
|
1009
|
+
prop = self._compute_propagation()
|
|
1010
|
+
if not prop.model.equivalence:
|
|
1011
|
+
return simplified
|
|
1012
|
+
|
|
1013
|
+
addr_and_idx_to_block: dict[tuple[int, int], Block] = {}
|
|
1014
|
+
for block in self.func_graph.nodes():
|
|
1015
|
+
addr_and_idx_to_block[(block.addr, block.idx)] = block
|
|
1016
|
+
|
|
1017
|
+
def_locations_to_remove: set[CodeLocation] = set()
|
|
1018
|
+
updated_use_locations: set[CodeLocation] = set()
|
|
1019
|
+
|
|
1020
|
+
eq: Equivalence
|
|
1021
|
+
for eq in prop.model.equivalence:
|
|
1022
|
+
# register variable == Call
|
|
1023
|
+
if isinstance(eq.atom0, Register):
|
|
1024
|
+
call_addr: int | None
|
|
1025
|
+
if isinstance(eq.atom1, Call):
|
|
1026
|
+
# register variable = Call
|
|
1027
|
+
call: Expression = eq.atom1
|
|
1028
|
+
call_addr = call.target.value if isinstance(call.target, Const) else None
|
|
1029
|
+
elif isinstance(eq.atom1, Convert) and isinstance(eq.atom1.operand, Call):
|
|
1030
|
+
# register variable = Convert(Call)
|
|
1031
|
+
call = eq.atom1
|
|
1032
|
+
call_addr = call.operand.target.value if isinstance(call.operand.target, Const) else None
|
|
1033
|
+
else:
|
|
1034
|
+
continue
|
|
1035
|
+
|
|
1036
|
+
if self._is_expr_using_temporaries(call):
|
|
1037
|
+
continue
|
|
1038
|
+
|
|
1039
|
+
if eq.codeloc in updated_use_locations:
|
|
1040
|
+
# this def is now created by an updated use. the corresponding statement will be updated in the end.
|
|
1041
|
+
# we must rerun Propagator to get an updated definition (and Equivalence)
|
|
1042
|
+
continue
|
|
1043
|
+
|
|
1044
|
+
# find the definition of this register
|
|
1045
|
+
rd = self._compute_reaching_definitions()
|
|
1046
|
+
defs = [
|
|
1047
|
+
d
|
|
1048
|
+
for d in rd.all_definitions
|
|
1049
|
+
if d.codeloc == eq.codeloc
|
|
1050
|
+
and isinstance(d.atom, atoms.Register)
|
|
1051
|
+
and d.atom.reg_offset == eq.atom0.reg_offset
|
|
1052
|
+
]
|
|
1053
|
+
if not defs or len(defs) > 1:
|
|
1054
|
+
continue
|
|
1055
|
+
the_def: Definition = defs[0]
|
|
1056
|
+
|
|
1057
|
+
# find all uses of this definition
|
|
1058
|
+
all_uses: set[tuple[CodeLocation, Any]] = set(rd.all_uses.get_uses_with_expr(the_def))
|
|
1059
|
+
|
|
1060
|
+
if len(all_uses) != 1:
|
|
1061
|
+
continue
|
|
1062
|
+
u, used_expr = next(iter(all_uses))
|
|
1063
|
+
if used_expr is None:
|
|
1064
|
+
continue
|
|
1065
|
+
|
|
1066
|
+
if u in def_locations_to_remove:
|
|
1067
|
+
# this use site has been altered by previous folding attempts. the corresponding statement will be
|
|
1068
|
+
# removed in the end. in this case, this Equivalence is probably useless, and we must rerun
|
|
1069
|
+
# Propagator to get an updated Equivalence.
|
|
1070
|
+
continue
|
|
1071
|
+
|
|
1072
|
+
if not self._fold_callexprs_into_conditions:
|
|
1073
|
+
# check the statement and make sure it's not a conditional jump
|
|
1074
|
+
the_block = addr_and_idx_to_block[(u.block_addr, u.block_idx)]
|
|
1075
|
+
if isinstance(the_block.statements[u.stmt_idx], ConditionalJump):
|
|
1076
|
+
continue
|
|
1077
|
+
|
|
1078
|
+
# check if the use and the definition is within the same supernode
|
|
1079
|
+
super_node_blocks = self._get_super_node_blocks(
|
|
1080
|
+
addr_and_idx_to_block[(the_def.codeloc.block_addr, the_def.codeloc.block_idx)]
|
|
1081
|
+
)
|
|
1082
|
+
if u.block_addr not in {b.addr for b in super_node_blocks}:
|
|
1083
|
+
continue
|
|
1084
|
+
|
|
1085
|
+
# check if the register has been overwritten by statements in between the def site and the use site
|
|
1086
|
+
usesite_atom_defs = set(rd.get_defs(the_def.atom, u, OP_BEFORE))
|
|
1087
|
+
if len(usesite_atom_defs) != 1:
|
|
1088
|
+
continue
|
|
1089
|
+
usesite_atom_def = next(iter(usesite_atom_defs))
|
|
1090
|
+
if usesite_atom_def != the_def:
|
|
1091
|
+
continue
|
|
1092
|
+
|
|
1093
|
+
# check if any atoms that the call relies on has been overwritten by statements in between the def site
|
|
1094
|
+
# and the use site.
|
|
1095
|
+
defsite_all_expr_uses = set(rd.all_uses.get_uses_by_location(the_def.codeloc))
|
|
1096
|
+
defsite_used_atoms = set()
|
|
1097
|
+
for dd in defsite_all_expr_uses:
|
|
1098
|
+
defsite_used_atoms.add(dd.atom)
|
|
1099
|
+
usesite_expr_def_outdated = False
|
|
1100
|
+
for defsite_expr_atom in defsite_used_atoms:
|
|
1101
|
+
usesite_expr_uses = set(rd.get_defs(defsite_expr_atom, u, OP_BEFORE))
|
|
1102
|
+
if not usesite_expr_uses:
|
|
1103
|
+
# the atom is not defined at the use site - it's fine
|
|
1104
|
+
continue
|
|
1105
|
+
defsite_expr_uses = set(rd.get_defs(defsite_expr_atom, the_def.codeloc, OP_BEFORE))
|
|
1106
|
+
if usesite_expr_uses != defsite_expr_uses:
|
|
1107
|
+
# special case: ok if this atom is assigned to at the def site and has not been overwritten
|
|
1108
|
+
if len(usesite_expr_uses) == 1:
|
|
1109
|
+
usesite_expr_use = next(iter(usesite_expr_uses))
|
|
1110
|
+
if usesite_expr_use.atom == defsite_expr_atom and (
|
|
1111
|
+
usesite_expr_use.codeloc == the_def.codeloc
|
|
1112
|
+
or usesite_expr_use.codeloc.block_addr == call_addr
|
|
1113
|
+
):
|
|
1114
|
+
continue
|
|
1115
|
+
usesite_expr_def_outdated = True
|
|
1116
|
+
break
|
|
1117
|
+
if usesite_expr_def_outdated:
|
|
1118
|
+
continue
|
|
1119
|
+
|
|
1120
|
+
# check if there are any calls in between the def site and the use site
|
|
1121
|
+
if self._count_calls_in_supernodeblocks(super_node_blocks, the_def.codeloc, u) > 0:
|
|
1122
|
+
continue
|
|
1123
|
+
|
|
1124
|
+
# replace all uses
|
|
1125
|
+
old_block = addr_and_idx_to_block.get((u.block_addr, u.block_idx), None)
|
|
1126
|
+
if old_block is None:
|
|
1127
|
+
continue
|
|
1128
|
+
|
|
1129
|
+
# if there is an updated block, use that
|
|
1130
|
+
the_block = self.blocks.get(old_block, old_block)
|
|
1131
|
+
stmt: Statement = the_block.statements[u.stmt_idx]
|
|
1132
|
+
|
|
1133
|
+
if isinstance(eq.atom0, Register):
|
|
1134
|
+
src = used_expr
|
|
1135
|
+
dst: Expression = call
|
|
1136
|
+
|
|
1137
|
+
if src.bits != dst.bits:
|
|
1138
|
+
dst = Convert(None, dst.bits, src.bits, False, dst)
|
|
1139
|
+
else:
|
|
1140
|
+
continue
|
|
1141
|
+
|
|
1142
|
+
# ensure what we are going to replace only appears once
|
|
1143
|
+
expr_ctr = SingleExpressionCounter(stmt, src)
|
|
1144
|
+
if expr_ctr.count > 1:
|
|
1145
|
+
continue
|
|
1146
|
+
|
|
1147
|
+
replaced, new_block = self._replace_expr_and_update_block(
|
|
1148
|
+
the_block, u.stmt_idx, stmt, the_def, u, src, dst
|
|
1149
|
+
)
|
|
1150
|
+
|
|
1151
|
+
if replaced:
|
|
1152
|
+
self.blocks[old_block] = new_block
|
|
1153
|
+
# this call has been folded to the use site. we can remove this call.
|
|
1154
|
+
self._calls_to_remove.add(eq.codeloc)
|
|
1155
|
+
simplified = True
|
|
1156
|
+
def_locations_to_remove.add(eq.codeloc)
|
|
1157
|
+
updated_use_locations.add(u)
|
|
1158
|
+
|
|
1159
|
+
# no need to clear the cache at the end of this method
|
|
1160
|
+
return simplified
|
|
1161
|
+
|
|
1162
|
+
def _get_super_node_blocks(self, start_node: Block) -> list[Block]:
|
|
1163
|
+
lst: list[Block] = [start_node]
|
|
1164
|
+
while True:
|
|
1165
|
+
b = lst[-1]
|
|
1166
|
+
successors = list(self.func_graph.successors(b))
|
|
1167
|
+
if len(successors) == 0:
|
|
1168
|
+
break
|
|
1169
|
+
if len(successors) == 1:
|
|
1170
|
+
succ = successors[0]
|
|
1171
|
+
# check its predecessors
|
|
1172
|
+
succ_predecessors = list(self.func_graph.predecessors(succ))
|
|
1173
|
+
if len(succ_predecessors) == 1:
|
|
1174
|
+
lst.append(succ)
|
|
1175
|
+
else:
|
|
1176
|
+
break
|
|
1177
|
+
else:
|
|
1178
|
+
# too many successors
|
|
1179
|
+
break
|
|
1180
|
+
return lst
|
|
1181
|
+
|
|
1182
|
+
def _replace_expr_and_update_block(
|
|
1183
|
+
self, block, stmt_idx, stmt, the_def, codeloc, src_expr, dst_expr
|
|
1184
|
+
) -> tuple[bool, Block | None]:
|
|
1185
|
+
replaced, new_stmt = stmt.replace(src_expr, dst_expr)
|
|
1186
|
+
if replaced:
|
|
1187
|
+
new_block = block.copy()
|
|
1188
|
+
new_block.statements = block.statements[::]
|
|
1189
|
+
new_block.statements[stmt_idx] = new_stmt
|
|
1190
|
+
|
|
1191
|
+
# update the uses
|
|
1192
|
+
rd = self._compute_reaching_definitions()
|
|
1193
|
+
rd.all_uses.remove_use(the_def, codeloc, expr=src_expr)
|
|
1194
|
+
return True, new_block
|
|
1195
|
+
|
|
1196
|
+
return False, None
|
|
1197
|
+
|
|
1198
|
+
def _remove_dead_assignments(self) -> bool:
|
|
1199
|
+
stmts_to_remove_per_block: dict[tuple[int, int], set[int]] = defaultdict(set)
|
|
1200
|
+
|
|
1201
|
+
# Find all statements that should be removed
|
|
1202
|
+
mask = (1 << self.project.arch.bits) - 1
|
|
1203
|
+
|
|
1204
|
+
rd = self._compute_reaching_definitions()
|
|
1205
|
+
stackarg_offsets = (
|
|
1206
|
+
{(tpl[1] & mask) for tpl in self._stack_arg_offsets} if self._stack_arg_offsets is not None else None
|
|
1207
|
+
)
|
|
1208
|
+
def_: Definition
|
|
1209
|
+
for def_ in rd.all_definitions:
|
|
1210
|
+
if def_.dummy:
|
|
1211
|
+
continue
|
|
1212
|
+
# we do not remove references to global memory regions no matter what
|
|
1213
|
+
if isinstance(def_.atom, atoms.MemoryLocation) and isinstance(def_.atom.addr, int):
|
|
1214
|
+
continue
|
|
1215
|
+
if isinstance(def_.atom, atoms.MemoryLocation):
|
|
1216
|
+
if not self._remove_dead_memdefs:
|
|
1217
|
+
# we always remove definitions for stack arguments
|
|
1218
|
+
if stackarg_offsets is not None and isinstance(def_.atom.addr, atoms.SpOffset):
|
|
1219
|
+
if (def_.atom.addr.offset & mask) not in stackarg_offsets:
|
|
1220
|
+
continue
|
|
1221
|
+
else:
|
|
1222
|
+
continue
|
|
1223
|
+
|
|
1224
|
+
uses = rd.all_uses.get_uses(def_)
|
|
1225
|
+
if (
|
|
1226
|
+
isinstance(def_.atom, atoms.Register)
|
|
1227
|
+
and def_.atom.reg_offset in self.project.arch.artificial_registers_offsets
|
|
1228
|
+
):
|
|
1229
|
+
if len(uses) == 1 and next(iter(uses)) == def_.codeloc:
|
|
1230
|
+
# cc_ndep = amd64g_calculate_condition(..., cc_ndep)
|
|
1231
|
+
uses = set()
|
|
1232
|
+
|
|
1233
|
+
if not uses:
|
|
1234
|
+
if not isinstance(def_.codeloc, ExternalCodeLocation):
|
|
1235
|
+
stmts_to_remove_per_block[(def_.codeloc.block_addr, def_.codeloc.block_idx)].add(
|
|
1236
|
+
def_.codeloc.stmt_idx
|
|
1237
|
+
)
|
|
1238
|
+
|
|
1239
|
+
for codeloc in self._calls_to_remove | self._assignments_to_remove:
|
|
1240
|
+
# this call can be removed. make sure it exists in stmts_to_remove_per_block
|
|
1241
|
+
stmts_to_remove_per_block[codeloc.block_addr, codeloc.block_idx].add(codeloc.stmt_idx)
|
|
1242
|
+
|
|
1243
|
+
simplified = False
|
|
1244
|
+
|
|
1245
|
+
# Remove the statements
|
|
1246
|
+
for old_block in self.func_graph.nodes():
|
|
1247
|
+
# if there is an updated block, use it
|
|
1248
|
+
block = self.blocks.get(old_block, old_block)
|
|
1249
|
+
|
|
1250
|
+
if not isinstance(block, Block):
|
|
1251
|
+
continue
|
|
1252
|
+
|
|
1253
|
+
if (block.addr, block.idx) not in stmts_to_remove_per_block:
|
|
1254
|
+
continue
|
|
1255
|
+
|
|
1256
|
+
new_statements = []
|
|
1257
|
+
stmts_to_remove = stmts_to_remove_per_block[(block.addr, block.idx)]
|
|
1258
|
+
|
|
1259
|
+
if not stmts_to_remove:
|
|
1260
|
+
continue
|
|
1261
|
+
|
|
1262
|
+
for idx, stmt in enumerate(block.statements):
|
|
1263
|
+
if idx in stmts_to_remove and not isinstance(stmt, DirtyStatement):
|
|
1264
|
+
if isinstance(stmt, (Assignment, Store)):
|
|
1265
|
+
# Skip Assignment and Store statements
|
|
1266
|
+
# if this statement triggers a call, it should only be removed if it's in self._calls_to_remove
|
|
1267
|
+
codeloc = CodeLocation(block.addr, idx, ins_addr=stmt.ins_addr, block_idx=block.idx)
|
|
1268
|
+
if codeloc in self._assignments_to_remove:
|
|
1269
|
+
# it should be removed
|
|
1270
|
+
simplified = True
|
|
1271
|
+
continue
|
|
1272
|
+
|
|
1273
|
+
if self._statement_has_call_exprs(stmt):
|
|
1274
|
+
if codeloc in self._calls_to_remove:
|
|
1275
|
+
# it has a call and must be removed
|
|
1276
|
+
simplified = True
|
|
1277
|
+
continue
|
|
1278
|
+
else:
|
|
1279
|
+
# no calls. remove it
|
|
1280
|
+
simplified = True
|
|
1281
|
+
continue
|
|
1282
|
+
elif isinstance(stmt, Call):
|
|
1283
|
+
codeloc = CodeLocation(block.addr, idx, ins_addr=stmt.ins_addr, block_idx=block.idx)
|
|
1284
|
+
if codeloc in self._calls_to_remove:
|
|
1285
|
+
# this call can be removed
|
|
1286
|
+
simplified = True
|
|
1287
|
+
continue
|
|
1288
|
+
|
|
1289
|
+
if stmt.ret_expr is not None:
|
|
1290
|
+
# the return expr is not used. it should not have return expr
|
|
1291
|
+
if stmt.fp_ret_expr is not None:
|
|
1292
|
+
# maybe its fp_ret_expr is used?
|
|
1293
|
+
stmt = stmt.copy()
|
|
1294
|
+
stmt.ret_expr = stmt.fp_ret_expr
|
|
1295
|
+
stmt.fp_ret_expr = None
|
|
1296
|
+
else:
|
|
1297
|
+
# clear ret_expr
|
|
1298
|
+
stmt = stmt.copy()
|
|
1299
|
+
stmt.ret_expr = None
|
|
1300
|
+
simplified = True
|
|
1301
|
+
else:
|
|
1302
|
+
# Should not happen!
|
|
1303
|
+
raise NotImplementedError()
|
|
1304
|
+
|
|
1305
|
+
new_statements.append(stmt)
|
|
1306
|
+
|
|
1307
|
+
new_block = block.copy()
|
|
1308
|
+
new_block.statements = new_statements
|
|
1309
|
+
self.blocks[old_block] = new_block
|
|
1310
|
+
|
|
1311
|
+
return simplified
|
|
1312
|
+
|
|
1313
|
+
#
|
|
1314
|
+
# Rewriting ccalls
|
|
1315
|
+
#
|
|
1316
|
+
|
|
1317
|
+
def _rewrite_ccalls(self):
|
|
1318
|
+
rewriter_cls = CCALL_REWRITERS.get(self.project.arch.name, None)
|
|
1319
|
+
if rewriter_cls is None:
|
|
1320
|
+
return False
|
|
1321
|
+
|
|
1322
|
+
walker = None
|
|
1323
|
+
|
|
1324
|
+
class _any_update:
|
|
1325
|
+
"""
|
|
1326
|
+
Dummy class for storing if any result has been updated.
|
|
1327
|
+
"""
|
|
1328
|
+
|
|
1329
|
+
v = False
|
|
1330
|
+
|
|
1331
|
+
def _handle_expr(expr_idx: int, expr: Expression, stmt_idx: int, stmt: Statement, block) -> Expression | None:
|
|
1332
|
+
if isinstance(expr, DirtyExpression) and isinstance(expr.dirty_expr, VEXCCallExpression):
|
|
1333
|
+
rewriter = rewriter_cls(expr.dirty_expr, self.project.arch)
|
|
1334
|
+
if rewriter.result is not None:
|
|
1335
|
+
_any_update.v = True
|
|
1336
|
+
return rewriter.result
|
|
1337
|
+
else:
|
|
1338
|
+
return None
|
|
1339
|
+
|
|
1340
|
+
return AILBlockWalker._handle_expr(walker, expr_idx, expr, stmt_idx, stmt, block)
|
|
1341
|
+
|
|
1342
|
+
blocks_by_addr_and_idx = {(node.addr, node.idx): node for node in self.func_graph.nodes()}
|
|
1343
|
+
|
|
1344
|
+
walker = AILBlockWalker()
|
|
1345
|
+
walker._handle_expr = _handle_expr
|
|
1346
|
+
|
|
1347
|
+
updated = False
|
|
1348
|
+
for block in blocks_by_addr_and_idx.values():
|
|
1349
|
+
_any_update.v = False
|
|
1350
|
+
old_block = block.copy()
|
|
1351
|
+
walker.walk(block)
|
|
1352
|
+
if _any_update.v:
|
|
1353
|
+
self.blocks[old_block] = block
|
|
1354
|
+
updated = True
|
|
1355
|
+
|
|
1356
|
+
return updated
|
|
1357
|
+
|
|
1358
|
+
@staticmethod
|
|
1359
|
+
def _statement_has_call_exprs(stmt: Statement) -> bool:
|
|
1360
|
+
def _handle_callexpr(expr_idx, expr, stmt_idx, stmt, block): # pylint:disable=unused-argument
|
|
1361
|
+
raise HasCallNotification()
|
|
1362
|
+
|
|
1363
|
+
walker = AILBlockWalker()
|
|
1364
|
+
walker.expr_handlers[Call] = _handle_callexpr
|
|
1365
|
+
try:
|
|
1366
|
+
walker.walk_statement(stmt)
|
|
1367
|
+
except HasCallNotification:
|
|
1368
|
+
return True
|
|
1369
|
+
|
|
1370
|
+
return False
|
|
1371
|
+
|
|
1372
|
+
@staticmethod
|
|
1373
|
+
def _expression_has_call_exprs(expr: Expression) -> bool:
|
|
1374
|
+
def _handle_callexpr(expr_idx, expr, stmt_idx, stmt, block): # pylint:disable=unused-argument
|
|
1375
|
+
raise HasCallNotification()
|
|
1376
|
+
|
|
1377
|
+
walker = AILBlockWalker()
|
|
1378
|
+
walker.expr_handlers[Call] = _handle_callexpr
|
|
1379
|
+
try:
|
|
1380
|
+
walker.walk_expression(expr)
|
|
1381
|
+
except HasCallNotification:
|
|
1382
|
+
return True
|
|
1383
|
+
|
|
1384
|
+
return False
|
|
1385
|
+
|
|
1386
|
+
@staticmethod
|
|
1387
|
+
def _count_calls_in_supernodeblocks(blocks: list[Block], start: CodeLocation, end: CodeLocation) -> int:
|
|
1388
|
+
"""
|
|
1389
|
+
Count the number of call statements in a list of blocks for a single super block between two given code
|
|
1390
|
+
locations (exclusive).
|
|
1391
|
+
"""
|
|
1392
|
+
calls = 0
|
|
1393
|
+
started = False
|
|
1394
|
+
for b in blocks:
|
|
1395
|
+
if b.addr == start.block_addr:
|
|
1396
|
+
started = True
|
|
1397
|
+
continue
|
|
1398
|
+
if b.addr == end.block_addr:
|
|
1399
|
+
started = False
|
|
1400
|
+
continue
|
|
1401
|
+
|
|
1402
|
+
if started:
|
|
1403
|
+
if b.statements and isinstance(b.statements[-1], Call):
|
|
1404
|
+
calls += 1
|
|
1405
|
+
return calls
|
|
1406
|
+
|
|
1407
|
+
|
|
1408
|
+
AnalysesHub.register_default("AILSimplifier", AILSimplifier)
|