angr 9.2.192__cp311-cp311-macosx_10_12_x86_64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- angr/__init__.py +366 -0
- angr/__main__.py +182 -0
- angr/ail_callable.py +79 -0
- angr/ailment/__init__.py +83 -0
- angr/ailment/block.py +88 -0
- angr/ailment/block_walker.py +856 -0
- angr/ailment/constant.py +3 -0
- angr/ailment/converter_common.py +11 -0
- angr/ailment/converter_pcode.py +648 -0
- angr/ailment/converter_vex.py +829 -0
- angr/ailment/expression.py +1655 -0
- angr/ailment/manager.py +34 -0
- angr/ailment/statement.py +973 -0
- angr/ailment/tagged_object.py +58 -0
- angr/ailment/utils.py +114 -0
- angr/analyses/__init__.py +117 -0
- angr/analyses/analysis.py +429 -0
- angr/analyses/backward_slice.py +686 -0
- angr/analyses/binary_optimizer.py +670 -0
- angr/analyses/bindiff.py +1512 -0
- angr/analyses/boyscout.py +76 -0
- angr/analyses/callee_cleanup_finder.py +74 -0
- angr/analyses/calling_convention/__init__.py +6 -0
- angr/analyses/calling_convention/calling_convention.py +1113 -0
- angr/analyses/calling_convention/fact_collector.py +647 -0
- angr/analyses/calling_convention/utils.py +60 -0
- angr/analyses/cdg.py +189 -0
- angr/analyses/cfg/__init__.py +23 -0
- angr/analyses/cfg/cfb.py +451 -0
- angr/analyses/cfg/cfg.py +74 -0
- angr/analyses/cfg/cfg_arch_options.py +95 -0
- angr/analyses/cfg/cfg_base.py +2954 -0
- angr/analyses/cfg/cfg_emulated.py +3451 -0
- angr/analyses/cfg/cfg_fast.py +5431 -0
- angr/analyses/cfg/cfg_fast_soot.py +662 -0
- angr/analyses/cfg/cfg_job_base.py +203 -0
- angr/analyses/cfg/indirect_jump_resolvers/__init__.py +30 -0
- angr/analyses/cfg/indirect_jump_resolvers/aarch64_macho_got.py +77 -0
- angr/analyses/cfg/indirect_jump_resolvers/amd64_elf_got.py +62 -0
- angr/analyses/cfg/indirect_jump_resolvers/amd64_pe_iat.py +51 -0
- angr/analyses/cfg/indirect_jump_resolvers/arm_elf_fast.py +159 -0
- angr/analyses/cfg/indirect_jump_resolvers/const_resolver.py +339 -0
- angr/analyses/cfg/indirect_jump_resolvers/constant_value_manager.py +107 -0
- angr/analyses/cfg/indirect_jump_resolvers/default_resolvers.py +82 -0
- angr/analyses/cfg/indirect_jump_resolvers/jumptable.py +2490 -0
- angr/analyses/cfg/indirect_jump_resolvers/memload_resolver.py +81 -0
- angr/analyses/cfg/indirect_jump_resolvers/mips_elf_fast.py +286 -0
- angr/analyses/cfg/indirect_jump_resolvers/mips_elf_got.py +148 -0
- angr/analyses/cfg/indirect_jump_resolvers/propagator_utils.py +46 -0
- angr/analyses/cfg/indirect_jump_resolvers/resolver.py +74 -0
- angr/analyses/cfg/indirect_jump_resolvers/syscall_resolver.py +92 -0
- angr/analyses/cfg/indirect_jump_resolvers/x86_elf_pic_plt.py +88 -0
- angr/analyses/cfg/indirect_jump_resolvers/x86_pe_iat.py +47 -0
- angr/analyses/cfg_slice_to_sink/__init__.py +11 -0
- angr/analyses/cfg_slice_to_sink/cfg_slice_to_sink.py +117 -0
- angr/analyses/cfg_slice_to_sink/graph.py +87 -0
- angr/analyses/cfg_slice_to_sink/transitions.py +27 -0
- angr/analyses/class_identifier.py +63 -0
- angr/analyses/code_tagging.py +123 -0
- angr/analyses/codecave.py +77 -0
- angr/analyses/complete_calling_conventions.py +475 -0
- angr/analyses/congruency_check.py +377 -0
- angr/analyses/data_dep/__init__.py +16 -0
- angr/analyses/data_dep/data_dependency_analysis.py +595 -0
- angr/analyses/data_dep/dep_nodes.py +171 -0
- angr/analyses/data_dep/sim_act_location.py +49 -0
- angr/analyses/datagraph_meta.py +105 -0
- angr/analyses/ddg.py +1670 -0
- angr/analyses/decompiler/__init__.py +41 -0
- angr/analyses/decompiler/ail_simplifier.py +2246 -0
- angr/analyses/decompiler/ailgraph_walker.py +49 -0
- angr/analyses/decompiler/block_io_finder.py +302 -0
- angr/analyses/decompiler/block_similarity.py +199 -0
- angr/analyses/decompiler/block_simplifier.py +397 -0
- angr/analyses/decompiler/callsite_maker.py +579 -0
- angr/analyses/decompiler/ccall_rewriters/__init__.py +9 -0
- angr/analyses/decompiler/ccall_rewriters/amd64_ccalls.py +618 -0
- angr/analyses/decompiler/ccall_rewriters/rewriter_base.py +24 -0
- angr/analyses/decompiler/ccall_rewriters/x86_ccalls.py +354 -0
- angr/analyses/decompiler/clinic.py +3662 -0
- angr/analyses/decompiler/condition_processor.py +1323 -0
- angr/analyses/decompiler/counters/__init__.py +16 -0
- angr/analyses/decompiler/counters/boolean_counter.py +27 -0
- angr/analyses/decompiler/counters/call_counter.py +77 -0
- angr/analyses/decompiler/counters/expression_counters.py +77 -0
- angr/analyses/decompiler/counters/seq_cf_structure_counter.py +63 -0
- angr/analyses/decompiler/decompilation_cache.py +54 -0
- angr/analyses/decompiler/decompilation_options.py +317 -0
- angr/analyses/decompiler/decompiler.py +796 -0
- angr/analyses/decompiler/dephication/__init__.py +6 -0
- angr/analyses/decompiler/dephication/dephication_base.py +100 -0
- angr/analyses/decompiler/dephication/graph_dephication.py +70 -0
- angr/analyses/decompiler/dephication/graph_rewriting.py +112 -0
- angr/analyses/decompiler/dephication/graph_vvar_mapping.py +357 -0
- angr/analyses/decompiler/dephication/rewriting_engine.py +528 -0
- angr/analyses/decompiler/dephication/seqnode_dephication.py +156 -0
- angr/analyses/decompiler/dirty_rewriters/__init__.py +7 -0
- angr/analyses/decompiler/dirty_rewriters/amd64_dirty.py +74 -0
- angr/analyses/decompiler/dirty_rewriters/rewriter_base.py +27 -0
- angr/analyses/decompiler/empty_node_remover.py +212 -0
- angr/analyses/decompiler/expression_narrower.py +290 -0
- angr/analyses/decompiler/goto_manager.py +112 -0
- angr/analyses/decompiler/graph_region.py +441 -0
- angr/analyses/decompiler/jump_target_collector.py +37 -0
- angr/analyses/decompiler/jumptable_entry_condition_rewriter.py +67 -0
- angr/analyses/decompiler/label_collector.py +32 -0
- angr/analyses/decompiler/node_replacer.py +42 -0
- angr/analyses/decompiler/notes/__init__.py +9 -0
- angr/analyses/decompiler/notes/decompilation_note.py +48 -0
- angr/analyses/decompiler/notes/deobfuscated_strings.py +56 -0
- angr/analyses/decompiler/optimization_passes/__init__.py +164 -0
- angr/analyses/decompiler/optimization_passes/base_ptr_save_simplifier.py +157 -0
- angr/analyses/decompiler/optimization_passes/call_stmt_rewriter.py +46 -0
- angr/analyses/decompiler/optimization_passes/code_motion.py +362 -0
- angr/analyses/decompiler/optimization_passes/condition_constprop.py +211 -0
- angr/analyses/decompiler/optimization_passes/const_derefs.py +127 -0
- angr/analyses/decompiler/optimization_passes/const_prop_reverter.py +365 -0
- angr/analyses/decompiler/optimization_passes/cross_jump_reverter.py +106 -0
- angr/analyses/decompiler/optimization_passes/deadblock_remover.py +82 -0
- angr/analyses/decompiler/optimization_passes/determine_load_sizes.py +64 -0
- angr/analyses/decompiler/optimization_passes/div_simplifier.py +425 -0
- angr/analyses/decompiler/optimization_passes/duplication_reverter/__init__.py +5 -0
- angr/analyses/decompiler/optimization_passes/duplication_reverter/ail_merge_graph.py +503 -0
- angr/analyses/decompiler/optimization_passes/duplication_reverter/duplication_reverter.py +1221 -0
- angr/analyses/decompiler/optimization_passes/duplication_reverter/errors.py +16 -0
- angr/analyses/decompiler/optimization_passes/duplication_reverter/similarity.py +126 -0
- angr/analyses/decompiler/optimization_passes/duplication_reverter/utils.py +167 -0
- angr/analyses/decompiler/optimization_passes/eager_std_string_concatenation.py +236 -0
- angr/analyses/decompiler/optimization_passes/eager_std_string_eval.py +186 -0
- angr/analyses/decompiler/optimization_passes/engine_base.py +502 -0
- angr/analyses/decompiler/optimization_passes/expr_op_swapper.py +138 -0
- angr/analyses/decompiler/optimization_passes/flip_boolean_cmp.py +113 -0
- angr/analyses/decompiler/optimization_passes/inlined_string_transformation_simplifier.py +618 -0
- angr/analyses/decompiler/optimization_passes/inlined_strlen_simplifier.py +274 -0
- angr/analyses/decompiler/optimization_passes/ite_expr_converter.py +224 -0
- angr/analyses/decompiler/optimization_passes/ite_region_converter.py +337 -0
- angr/analyses/decompiler/optimization_passes/lowered_switch_simplifier.py +939 -0
- angr/analyses/decompiler/optimization_passes/mod_simplifier.py +99 -0
- angr/analyses/decompiler/optimization_passes/optimization_pass.py +710 -0
- angr/analyses/decompiler/optimization_passes/peephole_simplifier.py +75 -0
- angr/analyses/decompiler/optimization_passes/register_save_area_simplifier.py +263 -0
- angr/analyses/decompiler/optimization_passes/register_save_area_simplifier_adv.py +198 -0
- angr/analyses/decompiler/optimization_passes/ret_addr_save_simplifier.py +171 -0
- angr/analyses/decompiler/optimization_passes/ret_deduplicator.py +222 -0
- angr/analyses/decompiler/optimization_passes/return_duplicator_base.py +632 -0
- angr/analyses/decompiler/optimization_passes/return_duplicator_high.py +61 -0
- angr/analyses/decompiler/optimization_passes/return_duplicator_low.py +166 -0
- angr/analyses/decompiler/optimization_passes/stack_canary_simplifier.py +333 -0
- angr/analyses/decompiler/optimization_passes/static_vvar_rewriter.py +336 -0
- angr/analyses/decompiler/optimization_passes/switch_default_case_duplicator.py +166 -0
- angr/analyses/decompiler/optimization_passes/switch_reused_entry_rewriter.py +102 -0
- angr/analyses/decompiler/optimization_passes/tag_slicer.py +41 -0
- angr/analyses/decompiler/optimization_passes/win_stack_canary_simplifier.py +477 -0
- angr/analyses/decompiler/optimization_passes/x86_gcc_getpc_simplifier.py +88 -0
- angr/analyses/decompiler/peephole_optimizations/__init__.py +136 -0
- angr/analyses/decompiler/peephole_optimizations/a_div_const_add_a_mul_n_div_const.py +42 -0
- angr/analyses/decompiler/peephole_optimizations/a_mul_const_div_shr_const.py +38 -0
- angr/analyses/decompiler/peephole_optimizations/a_mul_const_sub_a.py +34 -0
- angr/analyses/decompiler/peephole_optimizations/a_shl_const_sub_a.py +34 -0
- angr/analyses/decompiler/peephole_optimizations/a_sub_a_div.py +25 -0
- angr/analyses/decompiler/peephole_optimizations/a_sub_a_shr_const_shr_const.py +37 -0
- angr/analyses/decompiler/peephole_optimizations/a_sub_a_sub_n.py +23 -0
- angr/analyses/decompiler/peephole_optimizations/arm_cmpf.py +236 -0
- angr/analyses/decompiler/peephole_optimizations/base.py +157 -0
- angr/analyses/decompiler/peephole_optimizations/basepointeroffset_add_n.py +34 -0
- angr/analyses/decompiler/peephole_optimizations/basepointeroffset_and_mask.py +36 -0
- angr/analyses/decompiler/peephole_optimizations/bitwise_or_to_logical_or.py +34 -0
- angr/analyses/decompiler/peephole_optimizations/bool_expr_xor_1.py +27 -0
- angr/analyses/decompiler/peephole_optimizations/bswap.py +142 -0
- angr/analyses/decompiler/peephole_optimizations/cas_intrinsics.py +182 -0
- angr/analyses/decompiler/peephole_optimizations/cmpord_rewriter.py +71 -0
- angr/analyses/decompiler/peephole_optimizations/coalesce_adjacent_shrs.py +39 -0
- angr/analyses/decompiler/peephole_optimizations/coalesce_same_cascading_ifs.py +28 -0
- angr/analyses/decompiler/peephole_optimizations/constant_derefs.py +44 -0
- angr/analyses/decompiler/peephole_optimizations/conv_a_sub0_shr_and.py +69 -0
- angr/analyses/decompiler/peephole_optimizations/conv_shl_shr.py +52 -0
- angr/analyses/decompiler/peephole_optimizations/eager_eval.py +436 -0
- angr/analyses/decompiler/peephole_optimizations/extended_byte_and_mask.py +56 -0
- angr/analyses/decompiler/peephole_optimizations/inlined_memcpy.py +78 -0
- angr/analyses/decompiler/peephole_optimizations/inlined_memset.py +262 -0
- angr/analyses/decompiler/peephole_optimizations/inlined_strcpy.py +217 -0
- angr/analyses/decompiler/peephole_optimizations/inlined_strcpy_consolidation.py +106 -0
- angr/analyses/decompiler/peephole_optimizations/inlined_wcscpy.py +256 -0
- angr/analyses/decompiler/peephole_optimizations/inlined_wcscpy_consolidation.py +296 -0
- angr/analyses/decompiler/peephole_optimizations/invert_negated_logical_conjuction_disjunction.py +50 -0
- angr/analyses/decompiler/peephole_optimizations/modulo_simplifier.py +89 -0
- angr/analyses/decompiler/peephole_optimizations/one_sub_bool.py +33 -0
- angr/analyses/decompiler/peephole_optimizations/optimized_div_simplifier.py +356 -0
- angr/analyses/decompiler/peephole_optimizations/remove_cascading_conversions.py +45 -0
- angr/analyses/decompiler/peephole_optimizations/remove_cxx_destructor_calls.py +32 -0
- angr/analyses/decompiler/peephole_optimizations/remove_empty_if_body.py +46 -0
- angr/analyses/decompiler/peephole_optimizations/remove_noop_conversions.py +47 -0
- angr/analyses/decompiler/peephole_optimizations/remove_redundant_bitmasks.py +125 -0
- angr/analyses/decompiler/peephole_optimizations/remove_redundant_conversions.py +273 -0
- angr/analyses/decompiler/peephole_optimizations/remove_redundant_derefs.py +21 -0
- angr/analyses/decompiler/peephole_optimizations/remove_redundant_ite_branch.py +30 -0
- angr/analyses/decompiler/peephole_optimizations/remove_redundant_ite_comparisons.py +54 -0
- angr/analyses/decompiler/peephole_optimizations/remove_redundant_nots.py +36 -0
- angr/analyses/decompiler/peephole_optimizations/remove_redundant_reinterprets.py +44 -0
- angr/analyses/decompiler/peephole_optimizations/remove_redundant_shifts.py +95 -0
- angr/analyses/decompiler/peephole_optimizations/remove_redundant_shifts_around_comparators.py +115 -0
- angr/analyses/decompiler/peephole_optimizations/rewrite_bit_extractions.py +85 -0
- angr/analyses/decompiler/peephole_optimizations/rewrite_conv_mul.py +40 -0
- angr/analyses/decompiler/peephole_optimizations/rewrite_cxx_operator_calls.py +90 -0
- angr/analyses/decompiler/peephole_optimizations/rewrite_mips_gp_loads.py +49 -0
- angr/analyses/decompiler/peephole_optimizations/rol_ror.py +130 -0
- angr/analyses/decompiler/peephole_optimizations/sar_to_signed_div.py +143 -0
- angr/analyses/decompiler/peephole_optimizations/shl_to_mul.py +25 -0
- angr/analyses/decompiler/peephole_optimizations/simplify_pc_relative_loads.py +51 -0
- angr/analyses/decompiler/peephole_optimizations/single_bit_cond_to_boolexpr.py +28 -0
- angr/analyses/decompiler/peephole_optimizations/single_bit_xor.py +29 -0
- angr/analyses/decompiler/peephole_optimizations/tidy_stack_addr.py +131 -0
- angr/analyses/decompiler/peephole_optimizations/utils.py +18 -0
- angr/analyses/decompiler/presets/__init__.py +22 -0
- angr/analyses/decompiler/presets/basic.py +36 -0
- angr/analyses/decompiler/presets/fast.py +66 -0
- angr/analyses/decompiler/presets/full.py +76 -0
- angr/analyses/decompiler/presets/malware.py +70 -0
- angr/analyses/decompiler/presets/preset.py +37 -0
- angr/analyses/decompiler/redundant_label_remover.py +141 -0
- angr/analyses/decompiler/region_identifier.py +1319 -0
- angr/analyses/decompiler/region_simplifiers/__init__.py +5 -0
- angr/analyses/decompiler/region_simplifiers/cascading_cond_transformer.py +95 -0
- angr/analyses/decompiler/region_simplifiers/cascading_ifs.py +82 -0
- angr/analyses/decompiler/region_simplifiers/expr_folding.py +838 -0
- angr/analyses/decompiler/region_simplifiers/goto.py +178 -0
- angr/analyses/decompiler/region_simplifiers/if_.py +135 -0
- angr/analyses/decompiler/region_simplifiers/ifelse.py +91 -0
- angr/analyses/decompiler/region_simplifiers/loop.py +143 -0
- angr/analyses/decompiler/region_simplifiers/node_address_finder.py +24 -0
- angr/analyses/decompiler/region_simplifiers/region_simplifier.py +270 -0
- angr/analyses/decompiler/region_simplifiers/switch_cluster_simplifier.py +654 -0
- angr/analyses/decompiler/region_simplifiers/switch_expr_simplifier.py +87 -0
- angr/analyses/decompiler/region_walker.py +24 -0
- angr/analyses/decompiler/return_maker.py +72 -0
- angr/analyses/decompiler/semantic_naming/__init__.py +37 -0
- angr/analyses/decompiler/semantic_naming/array_index_naming.py +196 -0
- angr/analyses/decompiler/semantic_naming/boolean_naming.py +264 -0
- angr/analyses/decompiler/semantic_naming/call_result_naming.py +220 -0
- angr/analyses/decompiler/semantic_naming/naming_base.py +166 -0
- angr/analyses/decompiler/semantic_naming/orchestrator.py +107 -0
- angr/analyses/decompiler/semantic_naming/pointer_naming.py +334 -0
- angr/analyses/decompiler/semantic_naming/region_loop_counter_naming.py +246 -0
- angr/analyses/decompiler/semantic_naming/size_naming.py +137 -0
- angr/analyses/decompiler/seq_to_blocks.py +20 -0
- angr/analyses/decompiler/sequence_walker.py +261 -0
- angr/analyses/decompiler/ssailification/__init__.py +4 -0
- angr/analyses/decompiler/ssailification/rewriting.py +451 -0
- angr/analyses/decompiler/ssailification/rewriting_engine.py +1091 -0
- angr/analyses/decompiler/ssailification/rewriting_state.py +61 -0
- angr/analyses/decompiler/ssailification/ssailification.py +283 -0
- angr/analyses/decompiler/ssailification/traversal.py +127 -0
- angr/analyses/decompiler/ssailification/traversal_engine.py +323 -0
- angr/analyses/decompiler/ssailification/traversal_state.py +48 -0
- angr/analyses/decompiler/stack_item.py +36 -0
- angr/analyses/decompiler/structured_codegen/__init__.py +25 -0
- angr/analyses/decompiler/structured_codegen/base.py +193 -0
- angr/analyses/decompiler/structured_codegen/c.py +4257 -0
- angr/analyses/decompiler/structured_codegen/dummy.py +15 -0
- angr/analyses/decompiler/structured_codegen/dwarf_import.py +190 -0
- angr/analyses/decompiler/structuring/__init__.py +30 -0
- angr/analyses/decompiler/structuring/dream.py +1217 -0
- angr/analyses/decompiler/structuring/phoenix.py +3636 -0
- angr/analyses/decompiler/structuring/recursive_structurer.py +187 -0
- angr/analyses/decompiler/structuring/sailr.py +120 -0
- angr/analyses/decompiler/structuring/structurer_base.py +1140 -0
- angr/analyses/decompiler/structuring/structurer_nodes.py +442 -0
- angr/analyses/decompiler/utils.py +1224 -0
- angr/analyses/deobfuscator/__init__.py +23 -0
- angr/analyses/deobfuscator/api_obf_finder.py +333 -0
- angr/analyses/deobfuscator/api_obf_peephole_optimizer.py +80 -0
- angr/analyses/deobfuscator/api_obf_type2_finder.py +166 -0
- angr/analyses/deobfuscator/data_transformation_embedder.py +633 -0
- angr/analyses/deobfuscator/hash_lookup_api_deobfuscator.py +156 -0
- angr/analyses/deobfuscator/irsb_reg_collector.py +54 -0
- angr/analyses/deobfuscator/scope_ops_analyzer.py +68 -0
- angr/analyses/deobfuscator/string_obf_finder.py +983 -0
- angr/analyses/deobfuscator/string_obf_opt_passes.py +136 -0
- angr/analyses/deobfuscator/string_obf_peephole_optimizer.py +47 -0
- angr/analyses/disassembly.py +1351 -0
- angr/analyses/disassembly_utils.py +101 -0
- angr/analyses/dominance_frontier.py +57 -0
- angr/analyses/fcp/__init__.py +4 -0
- angr/analyses/fcp/fcp.py +427 -0
- angr/analyses/find_objects_static.py +205 -0
- angr/analyses/flirt/__init__.py +47 -0
- angr/analyses/flirt/consts.py +160 -0
- angr/analyses/flirt/flirt.py +249 -0
- angr/analyses/flirt/flirt_function.py +20 -0
- angr/analyses/flirt/flirt_matcher.py +352 -0
- angr/analyses/flirt/flirt_module.py +32 -0
- angr/analyses/flirt/flirt_node.py +23 -0
- angr/analyses/flirt/flirt_sig.py +359 -0
- angr/analyses/flirt/flirt_utils.py +31 -0
- angr/analyses/forward_analysis/__init__.py +12 -0
- angr/analyses/forward_analysis/forward_analysis.py +619 -0
- angr/analyses/forward_analysis/job_info.py +64 -0
- angr/analyses/forward_analysis/visitors/__init__.py +14 -0
- angr/analyses/forward_analysis/visitors/call_graph.py +29 -0
- angr/analyses/forward_analysis/visitors/function_graph.py +86 -0
- angr/analyses/forward_analysis/visitors/graph.py +242 -0
- angr/analyses/forward_analysis/visitors/loop.py +29 -0
- angr/analyses/forward_analysis/visitors/single_node_graph.py +38 -0
- angr/analyses/identifier/__init__.py +5 -0
- angr/analyses/identifier/custom_callable.py +137 -0
- angr/analyses/identifier/errors.py +10 -0
- angr/analyses/identifier/func.py +60 -0
- angr/analyses/identifier/functions/__init__.py +37 -0
- angr/analyses/identifier/functions/atoi.py +73 -0
- angr/analyses/identifier/functions/based_atoi.py +125 -0
- angr/analyses/identifier/functions/fdprintf.py +123 -0
- angr/analyses/identifier/functions/free.py +64 -0
- angr/analyses/identifier/functions/int2str.py +287 -0
- angr/analyses/identifier/functions/malloc.py +111 -0
- angr/analyses/identifier/functions/memcmp.py +67 -0
- angr/analyses/identifier/functions/memcpy.py +89 -0
- angr/analyses/identifier/functions/memset.py +43 -0
- angr/analyses/identifier/functions/printf.py +123 -0
- angr/analyses/identifier/functions/recv_until.py +312 -0
- angr/analyses/identifier/functions/skip_calloc.py +73 -0
- angr/analyses/identifier/functions/skip_realloc.py +97 -0
- angr/analyses/identifier/functions/skip_recv_n.py +105 -0
- angr/analyses/identifier/functions/snprintf.py +112 -0
- angr/analyses/identifier/functions/sprintf.py +116 -0
- angr/analyses/identifier/functions/strcasecmp.py +33 -0
- angr/analyses/identifier/functions/strcmp.py +113 -0
- angr/analyses/identifier/functions/strcpy.py +43 -0
- angr/analyses/identifier/functions/strlen.py +27 -0
- angr/analyses/identifier/functions/strncmp.py +104 -0
- angr/analyses/identifier/functions/strncpy.py +65 -0
- angr/analyses/identifier/functions/strtol.py +89 -0
- angr/analyses/identifier/identify.py +825 -0
- angr/analyses/identifier/runner.py +360 -0
- angr/analyses/init_finder.py +289 -0
- angr/analyses/loop_analysis/__init__.py +4 -0
- angr/analyses/loop_analysis/loop_analysis.py +464 -0
- angr/analyses/loop_analysis.py +349 -0
- angr/analyses/loop_unroller/__init__.py +4 -0
- angr/analyses/loop_unroller/loop_unroller.py +222 -0
- angr/analyses/loopfinder.py +171 -0
- angr/analyses/outliner/__init__.py +7 -0
- angr/analyses/outliner/outliner.py +402 -0
- angr/analyses/patchfinder.py +137 -0
- angr/analyses/pathfinder.py +282 -0
- angr/analyses/propagator/__init__.py +5 -0
- angr/analyses/propagator/engine_base.py +62 -0
- angr/analyses/propagator/engine_vex.py +297 -0
- angr/analyses/propagator/propagator.py +361 -0
- angr/analyses/propagator/top_checker_mixin.py +218 -0
- angr/analyses/propagator/values.py +117 -0
- angr/analyses/propagator/vex_vars.py +68 -0
- angr/analyses/proximity_graph.py +444 -0
- angr/analyses/purity/__init__.py +15 -0
- angr/analyses/purity/analysis.py +78 -0
- angr/analyses/purity/engine.py +593 -0
- angr/analyses/reaching_definitions/__init__.py +67 -0
- angr/analyses/reaching_definitions/call_trace.py +73 -0
- angr/analyses/reaching_definitions/dep_graph.py +433 -0
- angr/analyses/reaching_definitions/engine_ail.py +1128 -0
- angr/analyses/reaching_definitions/engine_vex.py +1128 -0
- angr/analyses/reaching_definitions/external_codeloc.py +0 -0
- angr/analyses/reaching_definitions/function_handler.py +639 -0
- angr/analyses/reaching_definitions/function_handler_library/__init__.py +12 -0
- angr/analyses/reaching_definitions/function_handler_library/stdio.py +269 -0
- angr/analyses/reaching_definitions/function_handler_library/stdlib.py +195 -0
- angr/analyses/reaching_definitions/function_handler_library/string.py +158 -0
- angr/analyses/reaching_definitions/function_handler_library/unistd.py +51 -0
- angr/analyses/reaching_definitions/heap_allocator.py +70 -0
- angr/analyses/reaching_definitions/rd_initializer.py +237 -0
- angr/analyses/reaching_definitions/rd_state.py +579 -0
- angr/analyses/reaching_definitions/reaching_definitions.py +581 -0
- angr/analyses/reaching_definitions/subject.py +65 -0
- angr/analyses/reassembler.py +2900 -0
- angr/analyses/s_liveness.py +254 -0
- angr/analyses/s_propagator.py +575 -0
- angr/analyses/s_reaching_definitions/__init__.py +12 -0
- angr/analyses/s_reaching_definitions/s_rda_model.py +145 -0
- angr/analyses/s_reaching_definitions/s_rda_view.py +344 -0
- angr/analyses/s_reaching_definitions/s_reaching_definitions.py +230 -0
- angr/analyses/smc.py +160 -0
- angr/analyses/soot_class_hierarchy.py +273 -0
- angr/analyses/stack_pointer_tracker.py +954 -0
- angr/analyses/static_hooker.py +53 -0
- angr/analyses/typehoon/__init__.py +5 -0
- angr/analyses/typehoon/dfa.py +118 -0
- angr/analyses/typehoon/lifter.py +133 -0
- angr/analyses/typehoon/simple_solver.py +2009 -0
- angr/analyses/typehoon/translator.py +283 -0
- angr/analyses/typehoon/typeconsts.py +439 -0
- angr/analyses/typehoon/typehoon.py +338 -0
- angr/analyses/typehoon/typevars.py +633 -0
- angr/analyses/typehoon/variance.py +11 -0
- angr/analyses/unpacker/__init__.py +6 -0
- angr/analyses/unpacker/obfuscation_detector.py +103 -0
- angr/analyses/unpacker/packing_detector.py +138 -0
- angr/analyses/variable_recovery/__init__.py +9 -0
- angr/analyses/variable_recovery/annotations.py +58 -0
- angr/analyses/variable_recovery/engine_ail.py +978 -0
- angr/analyses/variable_recovery/engine_base.py +1256 -0
- angr/analyses/variable_recovery/engine_vex.py +594 -0
- angr/analyses/variable_recovery/irsb_scanner.py +143 -0
- angr/analyses/variable_recovery/variable_recovery.py +574 -0
- angr/analyses/variable_recovery/variable_recovery_base.py +489 -0
- angr/analyses/variable_recovery/variable_recovery_fast.py +669 -0
- angr/analyses/veritesting.py +626 -0
- angr/analyses/vfg.py +1898 -0
- angr/analyses/vsa_ddg.py +420 -0
- angr/analyses/vtable.py +92 -0
- angr/analyses/xrefs.py +286 -0
- angr/angrdb/__init__.py +14 -0
- angr/angrdb/db.py +215 -0
- angr/angrdb/models.py +184 -0
- angr/angrdb/serializers/__init__.py +10 -0
- angr/angrdb/serializers/cfg_model.py +41 -0
- angr/angrdb/serializers/comments.py +60 -0
- angr/angrdb/serializers/funcs.py +61 -0
- angr/angrdb/serializers/kb.py +111 -0
- angr/angrdb/serializers/labels.py +59 -0
- angr/angrdb/serializers/loader.py +165 -0
- angr/angrdb/serializers/structured_code.py +167 -0
- angr/angrdb/serializers/variables.py +58 -0
- angr/angrdb/serializers/xrefs.py +48 -0
- angr/annocfg.py +317 -0
- angr/blade.py +431 -0
- angr/block.py +509 -0
- angr/callable.py +176 -0
- angr/calling_conventions.py +2613 -0
- angr/code_location.py +249 -0
- angr/codenode.py +145 -0
- angr/concretization_strategies/__init__.py +32 -0
- angr/concretization_strategies/any.py +17 -0
- angr/concretization_strategies/any_named.py +35 -0
- angr/concretization_strategies/base.py +81 -0
- angr/concretization_strategies/controlled_data.py +58 -0
- angr/concretization_strategies/eval.py +19 -0
- angr/concretization_strategies/logging.py +35 -0
- angr/concretization_strategies/max.py +25 -0
- angr/concretization_strategies/nonzero.py +16 -0
- angr/concretization_strategies/nonzero_range.py +22 -0
- angr/concretization_strategies/norepeats.py +37 -0
- angr/concretization_strategies/norepeats_range.py +37 -0
- angr/concretization_strategies/range.py +19 -0
- angr/concretization_strategies/signed_add.py +31 -0
- angr/concretization_strategies/single.py +15 -0
- angr/concretization_strategies/solutions.py +20 -0
- angr/concretization_strategies/unlimited_range.py +17 -0
- angr/distributed/__init__.py +9 -0
- angr/distributed/server.py +197 -0
- angr/distributed/worker.py +185 -0
- angr/emulator.py +144 -0
- angr/engines/__init__.py +69 -0
- angr/engines/ail/__init__.py +16 -0
- angr/engines/ail/callstack.py +58 -0
- angr/engines/ail/engine_light.py +903 -0
- angr/engines/ail/engine_successors.py +24 -0
- angr/engines/ail/setup.py +57 -0
- angr/engines/concrete.py +66 -0
- angr/engines/engine.py +29 -0
- angr/engines/failure.py +27 -0
- angr/engines/hook.py +93 -0
- angr/engines/icicle.py +294 -0
- angr/engines/light/__init__.py +23 -0
- angr/engines/light/data.py +681 -0
- angr/engines/light/engine.py +1297 -0
- angr/engines/pcode/__init__.py +9 -0
- angr/engines/pcode/behavior.py +998 -0
- angr/engines/pcode/cc.py +148 -0
- angr/engines/pcode/emulate.py +440 -0
- angr/engines/pcode/engine.py +242 -0
- angr/engines/pcode/lifter.py +1428 -0
- angr/engines/procedure.py +70 -0
- angr/engines/soot/__init__.py +5 -0
- angr/engines/soot/engine.py +410 -0
- angr/engines/soot/exceptions.py +17 -0
- angr/engines/soot/expressions/__init__.py +87 -0
- angr/engines/soot/expressions/arrayref.py +22 -0
- angr/engines/soot/expressions/base.py +21 -0
- angr/engines/soot/expressions/binop.py +28 -0
- angr/engines/soot/expressions/cast.py +22 -0
- angr/engines/soot/expressions/condition.py +35 -0
- angr/engines/soot/expressions/constants.py +47 -0
- angr/engines/soot/expressions/instanceOf.py +15 -0
- angr/engines/soot/expressions/instancefieldref.py +8 -0
- angr/engines/soot/expressions/invoke.py +114 -0
- angr/engines/soot/expressions/length.py +8 -0
- angr/engines/soot/expressions/local.py +8 -0
- angr/engines/soot/expressions/new.py +16 -0
- angr/engines/soot/expressions/newArray.py +54 -0
- angr/engines/soot/expressions/newMultiArray.py +86 -0
- angr/engines/soot/expressions/paramref.py +8 -0
- angr/engines/soot/expressions/phi.py +30 -0
- angr/engines/soot/expressions/staticfieldref.py +8 -0
- angr/engines/soot/expressions/thisref.py +7 -0
- angr/engines/soot/expressions/unsupported.py +7 -0
- angr/engines/soot/field_dispatcher.py +46 -0
- angr/engines/soot/method_dispatcher.py +46 -0
- angr/engines/soot/statements/__init__.py +44 -0
- angr/engines/soot/statements/assign.py +30 -0
- angr/engines/soot/statements/base.py +79 -0
- angr/engines/soot/statements/goto.py +14 -0
- angr/engines/soot/statements/identity.py +15 -0
- angr/engines/soot/statements/if_.py +19 -0
- angr/engines/soot/statements/invoke.py +12 -0
- angr/engines/soot/statements/return_.py +20 -0
- angr/engines/soot/statements/switch.py +41 -0
- angr/engines/soot/statements/throw.py +15 -0
- angr/engines/soot/values/__init__.py +38 -0
- angr/engines/soot/values/arrayref.py +122 -0
- angr/engines/soot/values/base.py +7 -0
- angr/engines/soot/values/constants.py +18 -0
- angr/engines/soot/values/instancefieldref.py +44 -0
- angr/engines/soot/values/local.py +18 -0
- angr/engines/soot/values/paramref.py +18 -0
- angr/engines/soot/values/staticfieldref.py +38 -0
- angr/engines/soot/values/strref.py +38 -0
- angr/engines/soot/values/thisref.py +149 -0
- angr/engines/successors.py +608 -0
- angr/engines/syscall.py +51 -0
- angr/engines/unicorn.py +490 -0
- angr/engines/vex/__init__.py +20 -0
- angr/engines/vex/claripy/__init__.py +5 -0
- angr/engines/vex/claripy/ccall.py +2097 -0
- angr/engines/vex/claripy/datalayer.py +141 -0
- angr/engines/vex/claripy/irop.py +1276 -0
- angr/engines/vex/heavy/__init__.py +16 -0
- angr/engines/vex/heavy/actions.py +231 -0
- angr/engines/vex/heavy/concretizers.py +403 -0
- angr/engines/vex/heavy/dirty.py +466 -0
- angr/engines/vex/heavy/heavy.py +370 -0
- angr/engines/vex/heavy/inspect.py +52 -0
- angr/engines/vex/heavy/resilience.py +85 -0
- angr/engines/vex/heavy/super_fastpath.py +34 -0
- angr/engines/vex/lifter.py +420 -0
- angr/engines/vex/light/__init__.py +11 -0
- angr/engines/vex/light/light.py +551 -0
- angr/engines/vex/light/resilience.py +74 -0
- angr/engines/vex/light/slicing.py +52 -0
- angr/errors.py +611 -0
- angr/exploration_techniques/__init__.py +53 -0
- angr/exploration_techniques/base.py +126 -0
- angr/exploration_techniques/bucketizer.py +94 -0
- angr/exploration_techniques/common.py +56 -0
- angr/exploration_techniques/dfs.py +37 -0
- angr/exploration_techniques/director.py +520 -0
- angr/exploration_techniques/driller_core.py +100 -0
- angr/exploration_techniques/explorer.py +152 -0
- angr/exploration_techniques/lengthlimiter.py +22 -0
- angr/exploration_techniques/local_loop_seer.py +65 -0
- angr/exploration_techniques/loop_seer.py +236 -0
- angr/exploration_techniques/manual_mergepoint.py +82 -0
- angr/exploration_techniques/memory_watcher.py +43 -0
- angr/exploration_techniques/oppologist.py +92 -0
- angr/exploration_techniques/slicecutor.py +118 -0
- angr/exploration_techniques/spiller.py +280 -0
- angr/exploration_techniques/spiller_db.py +27 -0
- angr/exploration_techniques/stochastic.py +56 -0
- angr/exploration_techniques/stub_stasher.py +19 -0
- angr/exploration_techniques/suggestions.py +159 -0
- angr/exploration_techniques/tech_builder.py +49 -0
- angr/exploration_techniques/threading.py +69 -0
- angr/exploration_techniques/timeout.py +34 -0
- angr/exploration_techniques/tracer.py +1098 -0
- angr/exploration_techniques/unique.py +106 -0
- angr/exploration_techniques/veritesting.py +37 -0
- angr/factory.py +413 -0
- angr/flirt/__init__.py +124 -0
- angr/flirt/build_sig.py +305 -0
- angr/graph_utils.py +0 -0
- angr/keyed_region.py +525 -0
- angr/knowledge_base.py +146 -0
- angr/knowledge_plugins/__init__.py +43 -0
- angr/knowledge_plugins/callsite_prototypes.py +95 -0
- angr/knowledge_plugins/cfg/__init__.py +18 -0
- angr/knowledge_plugins/cfg/cfg_manager.py +95 -0
- angr/knowledge_plugins/cfg/cfg_model.py +1043 -0
- angr/knowledge_plugins/cfg/cfg_node.py +536 -0
- angr/knowledge_plugins/cfg/indirect_jump.py +131 -0
- angr/knowledge_plugins/cfg/memory_data.py +156 -0
- angr/knowledge_plugins/comments.py +16 -0
- angr/knowledge_plugins/custom_strings.py +38 -0
- angr/knowledge_plugins/data.py +22 -0
- angr/knowledge_plugins/debug_variables.py +216 -0
- angr/knowledge_plugins/functions/__init__.py +9 -0
- angr/knowledge_plugins/functions/function.py +1830 -0
- angr/knowledge_plugins/functions/function_manager.py +621 -0
- angr/knowledge_plugins/functions/function_parser.py +360 -0
- angr/knowledge_plugins/functions/soot_function.py +128 -0
- angr/knowledge_plugins/indirect_jumps.py +35 -0
- angr/knowledge_plugins/key_definitions/__init__.py +17 -0
- angr/knowledge_plugins/key_definitions/atoms.py +374 -0
- angr/knowledge_plugins/key_definitions/constants.py +29 -0
- angr/knowledge_plugins/key_definitions/definition.py +216 -0
- angr/knowledge_plugins/key_definitions/environment.py +96 -0
- angr/knowledge_plugins/key_definitions/heap_address.py +33 -0
- angr/knowledge_plugins/key_definitions/key_definition_manager.py +82 -0
- angr/knowledge_plugins/key_definitions/live_definitions.py +1020 -0
- angr/knowledge_plugins/key_definitions/liveness.py +165 -0
- angr/knowledge_plugins/key_definitions/rd_model.py +171 -0
- angr/knowledge_plugins/key_definitions/tag.py +78 -0
- angr/knowledge_plugins/key_definitions/undefined.py +70 -0
- angr/knowledge_plugins/key_definitions/unknown_size.py +86 -0
- angr/knowledge_plugins/key_definitions/uses.py +178 -0
- angr/knowledge_plugins/labels.py +110 -0
- angr/knowledge_plugins/obfuscations.py +40 -0
- angr/knowledge_plugins/patches.py +126 -0
- angr/knowledge_plugins/plugin.py +24 -0
- angr/knowledge_plugins/propagations/__init__.py +10 -0
- angr/knowledge_plugins/propagations/prop_value.py +191 -0
- angr/knowledge_plugins/propagations/propagation_manager.py +60 -0
- angr/knowledge_plugins/propagations/propagation_model.py +80 -0
- angr/knowledge_plugins/propagations/states.py +552 -0
- angr/knowledge_plugins/structured_code.py +63 -0
- angr/knowledge_plugins/types.py +95 -0
- angr/knowledge_plugins/variables/__init__.py +8 -0
- angr/knowledge_plugins/variables/variable_access.py +113 -0
- angr/knowledge_plugins/variables/variable_manager.py +1375 -0
- angr/knowledge_plugins/xrefs/__init__.py +12 -0
- angr/knowledge_plugins/xrefs/xref.py +150 -0
- angr/knowledge_plugins/xrefs/xref_manager.py +127 -0
- angr/knowledge_plugins/xrefs/xref_types.py +16 -0
- angr/misc/__init__.py +19 -0
- angr/misc/ansi.py +47 -0
- angr/misc/autoimport.py +90 -0
- angr/misc/bug_report.py +126 -0
- angr/misc/hookset.py +106 -0
- angr/misc/loggers.py +130 -0
- angr/misc/picklable_lock.py +46 -0
- angr/misc/plugins.py +289 -0
- angr/misc/telemetry.py +54 -0
- angr/misc/testing.py +24 -0
- angr/misc/ux.py +31 -0
- angr/procedures/__init__.py +12 -0
- angr/procedures/advapi32/__init__.py +0 -0
- angr/procedures/cgc/__init__.py +3 -0
- angr/procedures/cgc/_terminate.py +11 -0
- angr/procedures/cgc/allocate.py +75 -0
- angr/procedures/cgc/deallocate.py +67 -0
- angr/procedures/cgc/fdwait.py +65 -0
- angr/procedures/cgc/random.py +67 -0
- angr/procedures/cgc/receive.py +93 -0
- angr/procedures/cgc/transmit.py +65 -0
- angr/procedures/definitions/__init__.py +1043 -0
- angr/procedures/definitions/cgc.py +23 -0
- angr/procedures/definitions/common/glibc.json +3516 -0
- angr/procedures/definitions/gnulib.py +41 -0
- angr/procedures/definitions/libstdcpp.py +25 -0
- angr/procedures/definitions/linux_kernel.py +8382 -0
- angr/procedures/definitions/linux_loader.py +7 -0
- angr/procedures/definitions/macho_libsystem.py +18 -0
- angr/procedures/definitions/msvcr.py +25 -0
- angr/procedures/definitions/parse_glibc.py +77 -0
- angr/procedures/definitions/parse_syscalls_from_local_system.py +54 -0
- angr/procedures/definitions/parse_win32json.py +2540 -0
- angr/procedures/definitions/types_stl.py +22 -0
- angr/procedures/definitions/wdk/api-ms-win-dx-d3dkmt-l1-1-4.json +24 -0
- angr/procedures/definitions/wdk/api-ms-win-dx-d3dkmt-l1-1-6.json +18 -0
- angr/procedures/definitions/wdk/clfs.json +189 -0
- angr/procedures/definitions/wdk/fltmgr.json +813 -0
- angr/procedures/definitions/wdk/fwpkclnt.json +24 -0
- angr/procedures/definitions/wdk/fwpuclnt.json +453 -0
- angr/procedures/definitions/wdk/gdi32.json +528 -0
- angr/procedures/definitions/wdk/hal.json +96 -0
- angr/procedures/definitions/wdk/ksecdd.json +72 -0
- angr/procedures/definitions/wdk/ndis.json +336 -0
- angr/procedures/definitions/wdk/ntoskrnl.json +5158 -0
- angr/procedures/definitions/wdk/offreg.json +87 -0
- angr/procedures/definitions/wdk/pshed.json +33 -0
- angr/procedures/definitions/wdk/secur32.json +39 -0
- angr/procedures/definitions/wdk/vhfum.json +30 -0
- angr/procedures/definitions/win32/_types_win32.json +34480 -0
- angr/procedures/definitions/win32/aclui.json +24 -0
- angr/procedures/definitions/win32/activeds.json +81 -0
- angr/procedures/definitions/win32/advapi32.json +2505 -0
- angr/procedures/definitions/win32/advpack.json +165 -0
- angr/procedures/definitions/win32/amsi.json +36 -0
- angr/procedures/definitions/win32/api-ms-win-appmodel-runtime-l1-1-1.json +45 -0
- angr/procedures/definitions/win32/api-ms-win-appmodel-runtime-l1-1-3.json +30 -0
- angr/procedures/definitions/win32/api-ms-win-appmodel-runtime-l1-1-6.json +18 -0
- angr/procedures/definitions/win32/api-ms-win-core-apiquery-l2-1-0.json +18 -0
- angr/procedures/definitions/win32/api-ms-win-core-backgroundtask-l1-1-0.json +18 -0
- angr/procedures/definitions/win32/api-ms-win-core-comm-l1-1-1.json +18 -0
- angr/procedures/definitions/win32/api-ms-win-core-comm-l1-1-2.json +18 -0
- angr/procedures/definitions/win32/api-ms-win-core-enclave-l1-1-1.json +24 -0
- angr/procedures/definitions/win32/api-ms-win-core-errorhandling-l1-1-3.json +18 -0
- angr/procedures/definitions/win32/api-ms-win-core-featurestaging-l1-1-0.json +30 -0
- angr/procedures/definitions/win32/api-ms-win-core-featurestaging-l1-1-1.json +18 -0
- angr/procedures/definitions/win32/api-ms-win-core-file-fromapp-l1-1-0.json +48 -0
- angr/procedures/definitions/win32/api-ms-win-core-handle-l1-1-0.json +18 -0
- angr/procedures/definitions/win32/api-ms-win-core-ioring-l1-1-0.json +51 -0
- angr/procedures/definitions/win32/api-ms-win-core-marshal-l1-1-0.json +27 -0
- angr/procedures/definitions/win32/api-ms-win-core-memory-l1-1-3.json +27 -0
- angr/procedures/definitions/win32/api-ms-win-core-memory-l1-1-4.json +18 -0
- angr/procedures/definitions/win32/api-ms-win-core-memory-l1-1-5.json +24 -0
- angr/procedures/definitions/win32/api-ms-win-core-memory-l1-1-6.json +27 -0
- angr/procedures/definitions/win32/api-ms-win-core-memory-l1-1-7.json +21 -0
- angr/procedures/definitions/win32/api-ms-win-core-memory-l1-1-8.json +24 -0
- angr/procedures/definitions/win32/api-ms-win-core-path-l1-1-0.json +81 -0
- angr/procedures/definitions/win32/api-ms-win-core-psm-appnotify-l1-1-0.json +21 -0
- angr/procedures/definitions/win32/api-ms-win-core-psm-appnotify-l1-1-1.json +21 -0
- angr/procedures/definitions/win32/api-ms-win-core-realtime-l1-1-1.json +24 -0
- angr/procedures/definitions/win32/api-ms-win-core-realtime-l1-1-2.json +24 -0
- angr/procedures/definitions/win32/api-ms-win-core-slapi-l1-1-0.json +18 -0
- angr/procedures/definitions/win32/api-ms-win-core-state-helpers-l1-1-0.json +18 -0
- angr/procedures/definitions/win32/api-ms-win-core-synch-l1-2-0.json +24 -0
- angr/procedures/definitions/win32/api-ms-win-core-sysinfo-l1-2-0.json +18 -0
- angr/procedures/definitions/win32/api-ms-win-core-sysinfo-l1-2-3.json +21 -0
- angr/procedures/definitions/win32/api-ms-win-core-sysinfo-l1-2-4.json +21 -0
- angr/procedures/definitions/win32/api-ms-win-core-sysinfo-l1-2-6.json +18 -0
- angr/procedures/definitions/win32/api-ms-win-core-util-l1-1-1.json +21 -0
- angr/procedures/definitions/win32/api-ms-win-core-wow64-l1-1-1.json +24 -0
- angr/procedures/definitions/win32/api-ms-win-devices-query-l1-1-0.json +42 -0
- angr/procedures/definitions/win32/api-ms-win-devices-query-l1-1-1.json +30 -0
- angr/procedures/definitions/win32/api-ms-win-dx-d3dkmt-l1-1-0.json +18 -0
- angr/procedures/definitions/win32/api-ms-win-gaming-deviceinformation-l1-1-0.json +18 -0
- angr/procedures/definitions/win32/api-ms-win-gaming-expandedresources-l1-1-0.json +24 -0
- angr/procedures/definitions/win32/api-ms-win-gaming-tcui-l1-1-0.json +36 -0
- angr/procedures/definitions/win32/api-ms-win-gaming-tcui-l1-1-1.json +21 -0
- angr/procedures/definitions/win32/api-ms-win-gaming-tcui-l1-1-2.json +36 -0
- angr/procedures/definitions/win32/api-ms-win-gaming-tcui-l1-1-3.json +21 -0
- angr/procedures/definitions/win32/api-ms-win-gaming-tcui-l1-1-4.json +39 -0
- angr/procedures/definitions/win32/api-ms-win-mm-misc-l1-1-1.json +18 -0
- angr/procedures/definitions/win32/api-ms-win-net-isolation-l1-1-0.json +39 -0
- angr/procedures/definitions/win32/api-ms-win-security-base-l1-2-2.json +18 -0
- angr/procedures/definitions/win32/api-ms-win-security-isolatedcontainer-l1-1-0.json +18 -0
- angr/procedures/definitions/win32/api-ms-win-security-isolatedcontainer-l1-1-1.json +18 -0
- angr/procedures/definitions/win32/api-ms-win-service-core-l1-1-3.json +18 -0
- angr/procedures/definitions/win32/api-ms-win-service-core-l1-1-4.json +18 -0
- angr/procedures/definitions/win32/api-ms-win-service-core-l1-1-5.json +21 -0
- angr/procedures/definitions/win32/api-ms-win-shcore-scaling-l1-1-0.json +24 -0
- angr/procedures/definitions/win32/api-ms-win-shcore-scaling-l1-1-1.json +33 -0
- angr/procedures/definitions/win32/api-ms-win-shcore-scaling-l1-1-2.json +18 -0
- angr/procedures/definitions/win32/api-ms-win-wsl-api-l1-1-0.json +36 -0
- angr/procedures/definitions/win32/apphelp.json +18 -0
- angr/procedures/definitions/win32/authz.json +114 -0
- angr/procedures/definitions/win32/avicap32.json +27 -0
- angr/procedures/definitions/win32/avifil32.json +195 -0
- angr/procedures/definitions/win32/avrt.json +57 -0
- angr/procedures/definitions/win32/bcp47mrm.json +21 -0
- angr/procedures/definitions/win32/bcrypt.json +174 -0
- angr/procedures/definitions/win32/bcryptprimitives.json +21 -0
- angr/procedures/definitions/win32/bluetoothapis.json +138 -0
- angr/procedures/definitions/win32/bthprops_cpl.json +33 -0
- angr/procedures/definitions/win32/cabinet.json +81 -0
- angr/procedures/definitions/win32/certadm.json +69 -0
- angr/procedures/definitions/win32/certpoleng.json +39 -0
- angr/procedures/definitions/win32/cfgmgr32.json +732 -0
- angr/procedures/definitions/win32/chakra.json +270 -0
- angr/procedures/definitions/win32/cldapi.json +123 -0
- angr/procedures/definitions/win32/clfsw32.json +192 -0
- angr/procedures/definitions/win32/clusapi.json +855 -0
- angr/procedures/definitions/win32/comctl32.json +360 -0
- angr/procedures/definitions/win32/comdlg32.json +78 -0
- angr/procedures/definitions/win32/compstui.json +27 -0
- angr/procedures/definitions/win32/computecore.json +177 -0
- angr/procedures/definitions/win32/computenetwork.json +144 -0
- angr/procedures/definitions/win32/computestorage.json +51 -0
- angr/procedures/definitions/win32/comsvcs.json +36 -0
- angr/procedures/definitions/win32/credui.json +72 -0
- angr/procedures/definitions/win32/crypt32.json +702 -0
- angr/procedures/definitions/win32/cryptnet.json +30 -0
- angr/procedures/definitions/win32/cryptui.json +45 -0
- angr/procedures/definitions/win32/cryptxml.json +72 -0
- angr/procedures/definitions/win32/cscapi.json +27 -0
- angr/procedures/definitions/win32/d2d1.json +54 -0
- angr/procedures/definitions/win32/d3d10.json +96 -0
- angr/procedures/definitions/win32/d3d10_1.json +21 -0
- angr/procedures/definitions/win32/d3d11.json +24 -0
- angr/procedures/definitions/win32/d3d12.json +39 -0
- angr/procedures/definitions/win32/d3d9.json +48 -0
- angr/procedures/definitions/win32/d3dcompiler_47.json +93 -0
- angr/procedures/definitions/win32/d3dcsx.json +42 -0
- angr/procedures/definitions/win32/davclnt.json +69 -0
- angr/procedures/definitions/win32/dbgeng.json +27 -0
- angr/procedures/definitions/win32/dbghelp.json +663 -0
- angr/procedures/definitions/win32/dbgmodel.json +18 -0
- angr/procedures/definitions/win32/dciman32.json +75 -0
- angr/procedures/definitions/win32/dcomp.json +51 -0
- angr/procedures/definitions/win32/ddraw.json +36 -0
- angr/procedures/definitions/win32/deviceaccess.json +18 -0
- angr/procedures/definitions/win32/dflayout.json +18 -0
- angr/procedures/definitions/win32/dhcpcsvc.json +60 -0
- angr/procedures/definitions/win32/dhcpcsvc6.json +33 -0
- angr/procedures/definitions/win32/dhcpsapi.json +603 -0
- angr/procedures/definitions/win32/diagnosticdataquery.json +120 -0
- angr/procedures/definitions/win32/dinput8.json +18 -0
- angr/procedures/definitions/win32/directml.json +21 -0
- angr/procedures/definitions/win32/dmprocessxmlfiltered.json +18 -0
- angr/procedures/definitions/win32/dnsapi.json +207 -0
- angr/procedures/definitions/win32/drt.json +63 -0
- angr/procedures/definitions/win32/drtprov.json +42 -0
- angr/procedures/definitions/win32/drttransport.json +21 -0
- angr/procedures/definitions/win32/dsound.json +45 -0
- angr/procedures/definitions/win32/dsparse.json +72 -0
- angr/procedures/definitions/win32/dsprop.json +36 -0
- angr/procedures/definitions/win32/dssec.json +27 -0
- angr/procedures/definitions/win32/dsuiext.json +27 -0
- angr/procedures/definitions/win32/dwmapi.json +108 -0
- angr/procedures/definitions/win32/dwrite.json +18 -0
- angr/procedures/definitions/win32/dxcompiler.json +21 -0
- angr/procedures/definitions/win32/dxcore.json +18 -0
- angr/procedures/definitions/win32/dxgi.json +33 -0
- angr/procedures/definitions/win32/dxva2.json +129 -0
- angr/procedures/definitions/win32/eappcfg.json +57 -0
- angr/procedures/definitions/win32/eappprxy.json +69 -0
- angr/procedures/definitions/win32/efswrt.json +21 -0
- angr/procedures/definitions/win32/elscore.json +30 -0
- angr/procedures/definitions/win32/esent.json +702 -0
- angr/procedures/definitions/win32/evr.json +36 -0
- angr/procedures/definitions/win32/faultrep.json +27 -0
- angr/procedures/definitions/win32/fhsvcctl.json +36 -0
- angr/procedures/definitions/win32/firewallapi.json +24 -0
- angr/procedures/definitions/win32/fltlib.json +99 -0
- angr/procedures/definitions/win32/fontsub.json +21 -0
- angr/procedures/definitions/win32/forceinline.json +24 -0
- angr/procedures/definitions/win32/fwpuclnt.json +591 -0
- angr/procedures/definitions/win32/fxsutility.json +21 -0
- angr/procedures/definitions/win32/gdi32.json +1308 -0
- angr/procedures/definitions/win32/gdiplus.json +1902 -0
- angr/procedures/definitions/win32/glu32.json +171 -0
- angr/procedures/definitions/win32/gpedit.json +33 -0
- angr/procedures/definitions/win32/hhctrl_ocx.json +21 -0
- angr/procedures/definitions/win32/hid.json +150 -0
- angr/procedures/definitions/win32/hlink.json +99 -0
- angr/procedures/definitions/win32/hrtfapo.json +18 -0
- angr/procedures/definitions/win32/httpapi.json +144 -0
- angr/procedures/definitions/win32/icm32.json +78 -0
- angr/procedures/definitions/win32/icmui.json +21 -0
- angr/procedures/definitions/win32/icu.json +3090 -0
- angr/procedures/definitions/win32/ieframe.json +102 -0
- angr/procedures/definitions/win32/imagehlp.json +84 -0
- angr/procedures/definitions/win32/imgutil.json +42 -0
- angr/procedures/definitions/win32/imm32.json +261 -0
- angr/procedures/definitions/win32/infocardapi.json +66 -0
- angr/procedures/definitions/win32/inkobjcore.json +96 -0
- angr/procedures/definitions/win32/iphlpapi.json +618 -0
- angr/procedures/definitions/win32/iscsidsc.json +252 -0
- angr/procedures/definitions/win32/isolatedwindowsenvironmentutils.json +21 -0
- angr/procedures/definitions/win32/kernel32.json +4566 -0
- angr/procedures/definitions/win32/kernelbase.json +33 -0
- angr/procedures/definitions/win32/keycredmgr.json +27 -0
- angr/procedures/definitions/win32/ksproxy_ax.json +33 -0
- angr/procedures/definitions/win32/ksuser.json +39 -0
- angr/procedures/definitions/win32/ktmw32.json +132 -0
- angr/procedures/definitions/win32/licenseprotection.json +21 -0
- angr/procedures/definitions/win32/loadperf.json +51 -0
- angr/procedures/definitions/win32/magnification.json +72 -0
- angr/procedures/definitions/win32/mapi32.json +213 -0
- angr/procedures/definitions/win32/mdmlocalmanagement.json +24 -0
- angr/procedures/definitions/win32/mdmregistration.json +60 -0
- angr/procedures/definitions/win32/mf.json +201 -0
- angr/procedures/definitions/win32/mfcore.json +21 -0
- angr/procedures/definitions/win32/mfplat.json +450 -0
- angr/procedures/definitions/win32/mfplay.json +18 -0
- angr/procedures/definitions/win32/mfreadwrite.json +30 -0
- angr/procedures/definitions/win32/mfsensorgroup.json +45 -0
- angr/procedures/definitions/win32/mfsrcsnk.json +21 -0
- angr/procedures/definitions/win32/mgmtapi.json +42 -0
- angr/procedures/definitions/win32/mi.json +18 -0
- angr/procedures/definitions/win32/mmdevapi.json +18 -0
- angr/procedures/definitions/win32/mpr.json +156 -0
- angr/procedures/definitions/win32/mprapi.json +351 -0
- angr/procedures/definitions/win32/mqrt.json +117 -0
- angr/procedures/definitions/win32/mrmsupport.json +96 -0
- angr/procedures/definitions/win32/msacm32.json +141 -0
- angr/procedures/definitions/win32/msajapi.json +1656 -0
- angr/procedures/definitions/win32/mscms.json +252 -0
- angr/procedures/definitions/win32/mscoree.json +96 -0
- angr/procedures/definitions/win32/msctfmonitor.json +24 -0
- angr/procedures/definitions/win32/msdelta.json +63 -0
- angr/procedures/definitions/win32/msdmo.json +48 -0
- angr/procedures/definitions/win32/msdrm.json +267 -0
- angr/procedures/definitions/win32/msi.json +807 -0
- angr/procedures/definitions/win32/msimg32.json +24 -0
- angr/procedures/definitions/win32/mspatcha.json +63 -0
- angr/procedures/definitions/win32/mspatchc.json +42 -0
- angr/procedures/definitions/win32/msports.json +36 -0
- angr/procedures/definitions/win32/msrating.json +72 -0
- angr/procedures/definitions/win32/mssign32.json +45 -0
- angr/procedures/definitions/win32/mstask.json +21 -0
- angr/procedures/definitions/win32/msvfw32.json +144 -0
- angr/procedures/definitions/win32/mswsock.json +63 -0
- angr/procedures/definitions/win32/mtxdm.json +18 -0
- angr/procedures/definitions/win32/ncrypt.json +132 -0
- angr/procedures/definitions/win32/ndfapi.json +63 -0
- angr/procedures/definitions/win32/netapi32.json +633 -0
- angr/procedures/definitions/win32/netsh.json +39 -0
- angr/procedures/definitions/win32/netshell.json +21 -0
- angr/procedures/definitions/win32/newdev.json +48 -0
- angr/procedures/definitions/win32/ninput.json +105 -0
- angr/procedures/definitions/win32/normaliz.json +21 -0
- angr/procedures/definitions/win32/ntdll.json +234 -0
- angr/procedures/definitions/win32/ntdllk.json +18 -0
- angr/procedures/definitions/win32/ntdsapi.json +258 -0
- angr/procedures/definitions/win32/ntlanman.json +45 -0
- angr/procedures/definitions/win32/odbc32.json +477 -0
- angr/procedures/definitions/win32/odbcbcp.json +96 -0
- angr/procedures/definitions/win32/ole32.json +966 -0
- angr/procedures/definitions/win32/oleacc.json +66 -0
- angr/procedures/definitions/win32/oleaut32.json +1230 -0
- angr/procedures/definitions/win32/oledlg.json +84 -0
- angr/procedures/definitions/win32/ondemandconnroutehelper.json +30 -0
- angr/procedures/definitions/win32/opengl32.json +1080 -0
- angr/procedures/definitions/win32/opmxbox.json +24 -0
- angr/procedures/definitions/win32/p2p.json +339 -0
- angr/procedures/definitions/win32/p2pgraph.json +126 -0
- angr/procedures/definitions/win32/pdh.json +309 -0
- angr/procedures/definitions/win32/peerdist.json +99 -0
- angr/procedures/definitions/win32/powrprof.json +267 -0
- angr/procedures/definitions/win32/prntvpt.json +48 -0
- angr/procedures/definitions/win32/projectedfslib.json +72 -0
- angr/procedures/definitions/win32/propsys.json +669 -0
- angr/procedures/definitions/win32/psapi.json +96 -0
- angr/procedures/definitions/win32/quartz.json +21 -0
- angr/procedures/definitions/win32/query.json +27 -0
- angr/procedures/definitions/win32/qwave.json +48 -0
- angr/procedures/definitions/win32/rasapi32.json +267 -0
- angr/procedures/definitions/win32/rasdlg.json +33 -0
- angr/procedures/definitions/win32/resutils.json +375 -0
- angr/procedures/definitions/win32/rpcns4.json +198 -0
- angr/procedures/definitions/win32/rpcproxy.json +27 -0
- angr/procedures/definitions/win32/rpcrt4.json +1356 -0
- angr/procedures/definitions/win32/rstrtmgr.json +48 -0
- angr/procedures/definitions/win32/rtm.json +243 -0
- angr/procedures/definitions/win32/rtutils.json +138 -0
- angr/procedures/definitions/win32/rtworkq.json +114 -0
- angr/procedures/definitions/win32/sas.json +18 -0
- angr/procedures/definitions/win32/scarddlg.json +30 -0
- angr/procedures/definitions/win32/schannel.json +42 -0
- angr/procedures/definitions/win32/sechost.json +21 -0
- angr/procedures/definitions/win32/secur32.json +282 -0
- angr/procedures/definitions/win32/sensapi.json +24 -0
- angr/procedures/definitions/win32/sensorsutilsv2.json +135 -0
- angr/procedures/definitions/win32/setupapi.json +1017 -0
- angr/procedures/definitions/win32/sfc.json +33 -0
- angr/procedures/definitions/win32/shdocvw.json +24 -0
- angr/procedures/definitions/win32/shell32.json +747 -0
- angr/procedures/definitions/win32/shlwapi.json +1095 -0
- angr/procedures/definitions/win32/slc.json +111 -0
- angr/procedures/definitions/win32/slcext.json +27 -0
- angr/procedures/definitions/win32/slwga.json +18 -0
- angr/procedures/definitions/win32/snmpapi.json +93 -0
- angr/procedures/definitions/win32/spoolss.json +93 -0
- angr/procedures/definitions/win32/srclient.json +18 -0
- angr/procedures/definitions/win32/srpapi.json +48 -0
- angr/procedures/definitions/win32/sspicli.json +36 -0
- angr/procedures/definitions/win32/sti.json +18 -0
- angr/procedures/definitions/win32/t2embed.json +57 -0
- angr/procedures/definitions/win32/tapi32.json +762 -0
- angr/procedures/definitions/win32/tbs.json +57 -0
- angr/procedures/definitions/win32/tdh.json +96 -0
- angr/procedures/definitions/win32/tokenbinding.json +45 -0
- angr/procedures/definitions/win32/traffic.json +75 -0
- angr/procedures/definitions/win32/txfw32.json +42 -0
- angr/procedures/definitions/win32/ualapi.json +27 -0
- angr/procedures/definitions/win32/uiautomationcore.json +309 -0
- angr/procedures/definitions/win32/urlmon.json +246 -0
- angr/procedures/definitions/win32/user32.json +2298 -0
- angr/procedures/definitions/win32/userenv.json +147 -0
- angr/procedures/definitions/win32/usp10.json +135 -0
- angr/procedures/definitions/win32/uxtheme.json +246 -0
- angr/procedures/definitions/win32/verifier.json +18 -0
- angr/procedures/definitions/win32/version.json +57 -0
- angr/procedures/definitions/win32/vertdll.json +36 -0
- angr/procedures/definitions/win32/virtdisk.json +102 -0
- angr/procedures/definitions/win32/vmdevicehost.json +54 -0
- angr/procedures/definitions/win32/vmsavedstatedumpprovider.json +144 -0
- angr/procedures/definitions/win32/vssapi.json +18 -0
- angr/procedures/definitions/win32/wcmapi.json +30 -0
- angr/procedures/definitions/win32/wdsbp.json +36 -0
- angr/procedures/definitions/win32/wdsclientapi.json +126 -0
- angr/procedures/definitions/win32/wdsmc.json +33 -0
- angr/procedures/definitions/win32/wdspxe.json +108 -0
- angr/procedures/definitions/win32/wdstptc.json +54 -0
- angr/procedures/definitions/win32/webauthn.json +54 -0
- angr/procedures/definitions/win32/webservices.json +594 -0
- angr/procedures/definitions/win32/websocket.json +54 -0
- angr/procedures/definitions/win32/wecapi.json +60 -0
- angr/procedures/definitions/win32/wer.json +78 -0
- angr/procedures/definitions/win32/wevtapi.json +120 -0
- angr/procedures/definitions/win32/winbio.json +177 -0
- angr/procedures/definitions/win32/windows_ai_machinelearning.json +18 -0
- angr/procedures/definitions/win32/windows_media_mediacontrol.json +39 -0
- angr/procedures/definitions/win32/windows_networking.json +18 -0
- angr/procedures/definitions/win32/windows_ui_xaml.json +21 -0
- angr/procedures/definitions/win32/windowscodecs.json +42 -0
- angr/procedures/definitions/win32/winfax.json +183 -0
- angr/procedures/definitions/win32/winhttp.json +183 -0
- angr/procedures/definitions/win32/winhvemulation.json +27 -0
- angr/procedures/definitions/win32/winhvplatform.json +213 -0
- angr/procedures/definitions/win32/wininet.json +903 -0
- angr/procedures/definitions/win32/winml.json +18 -0
- angr/procedures/definitions/win32/winmm.json +543 -0
- angr/procedures/definitions/win32/winscard.json +225 -0
- angr/procedures/definitions/win32/winspool_drv.json +531 -0
- angr/procedures/definitions/win32/wintrust.json +195 -0
- angr/procedures/definitions/win32/winusb.json +117 -0
- angr/procedures/definitions/win32/wlanapi.json +195 -0
- angr/procedures/definitions/win32/wlanui.json +18 -0
- angr/procedures/definitions/win32/wldap32.json +744 -0
- angr/procedures/definitions/win32/wldp.json +42 -0
- angr/procedures/definitions/win32/wmvcore.json +48 -0
- angr/procedures/definitions/win32/wnvapi.json +21 -0
- angr/procedures/definitions/win32/wofutil.json +48 -0
- angr/procedures/definitions/win32/ws2_32.json +495 -0
- angr/procedures/definitions/win32/wscapi.json +33 -0
- angr/procedures/definitions/win32/wsclient.json +24 -0
- angr/procedures/definitions/win32/wsdapi.json +111 -0
- angr/procedures/definitions/win32/wsmsvc.json +114 -0
- angr/procedures/definitions/win32/wsnmp32.json +162 -0
- angr/procedures/definitions/win32/wtsapi32.json +204 -0
- angr/procedures/definitions/win32/xaudio2_8.json +27 -0
- angr/procedures/definitions/win32/xinput1_4.json +36 -0
- angr/procedures/definitions/win32/xmllite.json +33 -0
- angr/procedures/definitions/win32/xolehlp.json +27 -0
- angr/procedures/definitions/win32/xpsprint.json +21 -0
- angr/procedures/glibc/__ctype_b_loc.py +21 -0
- angr/procedures/glibc/__ctype_tolower_loc.py +21 -0
- angr/procedures/glibc/__ctype_toupper_loc.py +21 -0
- angr/procedures/glibc/__errno_location.py +7 -0
- angr/procedures/glibc/__init__.py +3 -0
- angr/procedures/glibc/__libc_init.py +37 -0
- angr/procedures/glibc/__libc_start_main.py +301 -0
- angr/procedures/glibc/dynamic_loading.py +20 -0
- angr/procedures/glibc/scanf.py +19 -0
- angr/procedures/glibc/sscanf.py +10 -0
- angr/procedures/gnulib/__init__.py +3 -0
- angr/procedures/gnulib/xalloc_die.py +14 -0
- angr/procedures/gnulib/xstrtol_fatal.py +14 -0
- angr/procedures/java/__init__.py +42 -0
- angr/procedures/java/unconstrained.py +65 -0
- angr/procedures/java_io/__init__.py +0 -0
- angr/procedures/java_io/read.py +12 -0
- angr/procedures/java_io/write.py +17 -0
- angr/procedures/java_jni/__init__.py +482 -0
- angr/procedures/java_jni/array_operations.py +312 -0
- angr/procedures/java_jni/class_and_interface_operations.py +31 -0
- angr/procedures/java_jni/field_access.py +173 -0
- angr/procedures/java_jni/global_and_local_refs.py +57 -0
- angr/procedures/java_jni/method_calls.py +365 -0
- angr/procedures/java_jni/not_implemented.py +26 -0
- angr/procedures/java_jni/object_operations.py +94 -0
- angr/procedures/java_jni/string_operations.py +87 -0
- angr/procedures/java_jni/version_information.py +12 -0
- angr/procedures/java_lang/__init__.py +0 -0
- angr/procedures/java_lang/character.py +30 -0
- angr/procedures/java_lang/double.py +24 -0
- angr/procedures/java_lang/exit.py +13 -0
- angr/procedures/java_lang/getsimplename.py +18 -0
- angr/procedures/java_lang/integer.py +43 -0
- angr/procedures/java_lang/load_library.py +9 -0
- angr/procedures/java_lang/math.py +15 -0
- angr/procedures/java_lang/string.py +78 -0
- angr/procedures/java_lang/stringbuilder.py +44 -0
- angr/procedures/java_lang/system.py +18 -0
- angr/procedures/java_util/__init__.py +0 -0
- angr/procedures/java_util/collection.py +35 -0
- angr/procedures/java_util/iterator.py +46 -0
- angr/procedures/java_util/list.py +99 -0
- angr/procedures/java_util/map.py +131 -0
- angr/procedures/java_util/random.py +14 -0
- angr/procedures/java_util/scanner_nextline.py +23 -0
- angr/procedures/libc/__init__.py +3 -0
- angr/procedures/libc/abort.py +9 -0
- angr/procedures/libc/access.py +13 -0
- angr/procedures/libc/atoi.py +14 -0
- angr/procedures/libc/atol.py +13 -0
- angr/procedures/libc/calloc.py +8 -0
- angr/procedures/libc/closelog.py +10 -0
- angr/procedures/libc/err.py +14 -0
- angr/procedures/libc/error.py +54 -0
- angr/procedures/libc/exit.py +11 -0
- angr/procedures/libc/fclose.py +19 -0
- angr/procedures/libc/feof.py +21 -0
- angr/procedures/libc/fflush.py +16 -0
- angr/procedures/libc/fgetc.py +27 -0
- angr/procedures/libc/fgets.py +69 -0
- angr/procedures/libc/fopen.py +63 -0
- angr/procedures/libc/fprintf.py +25 -0
- angr/procedures/libc/fputc.py +23 -0
- angr/procedures/libc/fputs.py +24 -0
- angr/procedures/libc/fread.py +24 -0
- angr/procedures/libc/free.py +9 -0
- angr/procedures/libc/fscanf.py +20 -0
- angr/procedures/libc/fseek.py +34 -0
- angr/procedures/libc/ftell.py +22 -0
- angr/procedures/libc/fwrite.py +19 -0
- angr/procedures/libc/getchar.py +13 -0
- angr/procedures/libc/getdelim.py +99 -0
- angr/procedures/libc/getegid.py +8 -0
- angr/procedures/libc/geteuid.py +8 -0
- angr/procedures/libc/getgid.py +8 -0
- angr/procedures/libc/gets.py +68 -0
- angr/procedures/libc/getuid.py +8 -0
- angr/procedures/libc/malloc.py +12 -0
- angr/procedures/libc/memcmp.py +69 -0
- angr/procedures/libc/memcpy.py +45 -0
- angr/procedures/libc/memset.py +72 -0
- angr/procedures/libc/openlog.py +10 -0
- angr/procedures/libc/perror.py +13 -0
- angr/procedures/libc/printf.py +34 -0
- angr/procedures/libc/putchar.py +13 -0
- angr/procedures/libc/puts.py +19 -0
- angr/procedures/libc/rand.py +8 -0
- angr/procedures/libc/realloc.py +8 -0
- angr/procedures/libc/rewind.py +12 -0
- angr/procedures/libc/scanf.py +20 -0
- angr/procedures/libc/setbuf.py +9 -0
- angr/procedures/libc/setvbuf.py +7 -0
- angr/procedures/libc/snprintf.py +36 -0
- angr/procedures/libc/sprintf.py +25 -0
- angr/procedures/libc/srand.py +7 -0
- angr/procedures/libc/sscanf.py +13 -0
- angr/procedures/libc/stpcpy.py +18 -0
- angr/procedures/libc/strcat.py +14 -0
- angr/procedures/libc/strchr.py +48 -0
- angr/procedures/libc/strcmp.py +31 -0
- angr/procedures/libc/strcpy.py +13 -0
- angr/procedures/libc/strlen.py +114 -0
- angr/procedures/libc/strncat.py +19 -0
- angr/procedures/libc/strncmp.py +183 -0
- angr/procedures/libc/strncpy.py +22 -0
- angr/procedures/libc/strnlen.py +13 -0
- angr/procedures/libc/strstr.py +101 -0
- angr/procedures/libc/strtol.py +261 -0
- angr/procedures/libc/strtoul.py +9 -0
- angr/procedures/libc/system.py +13 -0
- angr/procedures/libc/time.py +9 -0
- angr/procedures/libc/tmpnam.py +20 -0
- angr/procedures/libc/tolower.py +10 -0
- angr/procedures/libc/toupper.py +10 -0
- angr/procedures/libc/ungetc.py +20 -0
- angr/procedures/libc/vsnprintf.py +17 -0
- angr/procedures/libc/wchar.py +16 -0
- angr/procedures/libstdcpp/__init__.py +0 -0
- angr/procedures/libstdcpp/_unwind_resume.py +11 -0
- angr/procedures/libstdcpp/std____throw_bad_alloc.py +13 -0
- angr/procedures/libstdcpp/std____throw_bad_cast.py +13 -0
- angr/procedures/libstdcpp/std____throw_length_error.py +13 -0
- angr/procedures/libstdcpp/std____throw_logic_error.py +13 -0
- angr/procedures/libstdcpp/std__terminate.py +13 -0
- angr/procedures/linux_kernel/__init__.py +3 -0
- angr/procedures/linux_kernel/access.py +18 -0
- angr/procedures/linux_kernel/arch_prctl.py +34 -0
- angr/procedures/linux_kernel/arm_user_helpers.py +59 -0
- angr/procedures/linux_kernel/brk.py +18 -0
- angr/procedures/linux_kernel/cwd.py +28 -0
- angr/procedures/linux_kernel/fstat.py +138 -0
- angr/procedures/linux_kernel/fstat64.py +170 -0
- angr/procedures/linux_kernel/futex.py +17 -0
- angr/procedures/linux_kernel/getegid.py +17 -0
- angr/procedures/linux_kernel/geteuid.py +17 -0
- angr/procedures/linux_kernel/getgid.py +17 -0
- angr/procedures/linux_kernel/getpid.py +14 -0
- angr/procedures/linux_kernel/getrlimit.py +24 -0
- angr/procedures/linux_kernel/gettid.py +9 -0
- angr/procedures/linux_kernel/getuid.py +17 -0
- angr/procedures/linux_kernel/iovec.py +47 -0
- angr/procedures/linux_kernel/lseek.py +42 -0
- angr/procedures/linux_kernel/mmap.py +16 -0
- angr/procedures/linux_kernel/mprotect.py +42 -0
- angr/procedures/linux_kernel/munmap.py +8 -0
- angr/procedures/linux_kernel/openat.py +26 -0
- angr/procedures/linux_kernel/set_tid_address.py +8 -0
- angr/procedures/linux_kernel/sigaction.py +19 -0
- angr/procedures/linux_kernel/sigprocmask.py +23 -0
- angr/procedures/linux_kernel/stat.py +23 -0
- angr/procedures/linux_kernel/sysinfo.py +59 -0
- angr/procedures/linux_kernel/tgkill.py +10 -0
- angr/procedures/linux_kernel/time.py +34 -0
- angr/procedures/linux_kernel/uid.py +30 -0
- angr/procedures/linux_kernel/uname.py +29 -0
- angr/procedures/linux_kernel/unlink.py +22 -0
- angr/procedures/linux_kernel/vsyscall.py +16 -0
- angr/procedures/linux_loader/__init__.py +3 -0
- angr/procedures/linux_loader/_dl_initial_error_catch_tsd.py +7 -0
- angr/procedures/linux_loader/_dl_rtld_lock.py +15 -0
- angr/procedures/linux_loader/sim_loader.py +54 -0
- angr/procedures/linux_loader/tls.py +40 -0
- angr/procedures/msvcr/__getmainargs.py +16 -0
- angr/procedures/msvcr/__init__.py +4 -0
- angr/procedures/msvcr/_initterm.py +38 -0
- angr/procedures/msvcr/fmode.py +31 -0
- angr/procedures/ntdll/__init__.py +0 -0
- angr/procedures/ntdll/exceptions.py +60 -0
- angr/procedures/posix/__init__.py +3 -0
- angr/procedures/posix/accept.py +29 -0
- angr/procedures/posix/bind.py +13 -0
- angr/procedures/posix/bzero.py +9 -0
- angr/procedures/posix/chroot.py +27 -0
- angr/procedures/posix/close.py +9 -0
- angr/procedures/posix/closedir.py +7 -0
- angr/procedures/posix/dup.py +56 -0
- angr/procedures/posix/fcntl.py +10 -0
- angr/procedures/posix/fdopen.py +76 -0
- angr/procedures/posix/fileno.py +18 -0
- angr/procedures/posix/fork.py +13 -0
- angr/procedures/posix/getenv.py +35 -0
- angr/procedures/posix/gethostbyname.py +43 -0
- angr/procedures/posix/getpass.py +19 -0
- angr/procedures/posix/getsockopt.py +11 -0
- angr/procedures/posix/htonl.py +11 -0
- angr/procedures/posix/htons.py +11 -0
- angr/procedures/posix/inet_ntoa.py +59 -0
- angr/procedures/posix/listen.py +13 -0
- angr/procedures/posix/mmap.py +144 -0
- angr/procedures/posix/open.py +18 -0
- angr/procedures/posix/opendir.py +10 -0
- angr/procedures/posix/poll.py +55 -0
- angr/procedures/posix/pread64.py +46 -0
- angr/procedures/posix/pthread.py +87 -0
- angr/procedures/posix/pwrite64.py +46 -0
- angr/procedures/posix/read.py +13 -0
- angr/procedures/posix/readdir.py +62 -0
- angr/procedures/posix/recv.py +13 -0
- angr/procedures/posix/recvfrom.py +13 -0
- angr/procedures/posix/select.py +48 -0
- angr/procedures/posix/send.py +23 -0
- angr/procedures/posix/setsockopt.py +9 -0
- angr/procedures/posix/sigaction.py +23 -0
- angr/procedures/posix/sim_time.py +48 -0
- angr/procedures/posix/sleep.py +8 -0
- angr/procedures/posix/socket.py +18 -0
- angr/procedures/posix/strcasecmp.py +26 -0
- angr/procedures/posix/strdup.py +18 -0
- angr/procedures/posix/strtok_r.py +64 -0
- angr/procedures/posix/syslog.py +15 -0
- angr/procedures/posix/tz.py +9 -0
- angr/procedures/posix/unlink.py +11 -0
- angr/procedures/posix/usleep.py +8 -0
- angr/procedures/posix/write.py +13 -0
- angr/procedures/procedure_dict.py +50 -0
- angr/procedures/stubs/CallReturn.py +13 -0
- angr/procedures/stubs/NoReturnUnconstrained.py +13 -0
- angr/procedures/stubs/Nop.py +7 -0
- angr/procedures/stubs/PathTerminator.py +9 -0
- angr/procedures/stubs/Redirect.py +18 -0
- angr/procedures/stubs/ReturnChar.py +11 -0
- angr/procedures/stubs/ReturnUnconstrained.py +24 -0
- angr/procedures/stubs/UnresolvableCallTarget.py +9 -0
- angr/procedures/stubs/UnresolvableJumpTarget.py +9 -0
- angr/procedures/stubs/UserHook.py +18 -0
- angr/procedures/stubs/__init__.py +3 -0
- angr/procedures/stubs/b64_decode.py +15 -0
- angr/procedures/stubs/caller.py +14 -0
- angr/procedures/stubs/crazy_scanf.py +20 -0
- angr/procedures/stubs/format_parser.py +669 -0
- angr/procedures/stubs/syscall_stub.py +24 -0
- angr/procedures/testing/__init__.py +3 -0
- angr/procedures/testing/manyargs.py +9 -0
- angr/procedures/testing/retreg.py +8 -0
- angr/procedures/tracer/__init__.py +4 -0
- angr/procedures/tracer/random.py +9 -0
- angr/procedures/tracer/receive.py +23 -0
- angr/procedures/tracer/transmit.py +26 -0
- angr/procedures/uclibc/__init__.py +3 -0
- angr/procedures/uclibc/__uClibc_main.py +10 -0
- angr/procedures/win32/EncodePointer.py +7 -0
- angr/procedures/win32/ExitProcess.py +9 -0
- angr/procedures/win32/GetCommandLine.py +12 -0
- angr/procedures/win32/GetCurrentProcessId.py +7 -0
- angr/procedures/win32/GetCurrentThreadId.py +7 -0
- angr/procedures/win32/GetLastInputInfo.py +40 -0
- angr/procedures/win32/GetModuleHandle.py +29 -0
- angr/procedures/win32/GetProcessAffinityMask.py +37 -0
- angr/procedures/win32/InterlockedExchange.py +15 -0
- angr/procedures/win32/IsProcessorFeaturePresent.py +7 -0
- angr/procedures/win32/VirtualAlloc.py +114 -0
- angr/procedures/win32/VirtualProtect.py +60 -0
- angr/procedures/win32/__init__.py +3 -0
- angr/procedures/win32/critical_section.py +12 -0
- angr/procedures/win32/dynamic_loading.py +104 -0
- angr/procedures/win32/file_handles.py +47 -0
- angr/procedures/win32/gethostbyname.py +12 -0
- angr/procedures/win32/heap.py +45 -0
- angr/procedures/win32/is_bad_ptr.py +26 -0
- angr/procedures/win32/local_storage.py +88 -0
- angr/procedures/win32/mutex.py +11 -0
- angr/procedures/win32/sim_time.py +135 -0
- angr/procedures/win32/system_paths.py +35 -0
- angr/procedures/win32_kernel/ExAllocatePool.py +13 -0
- angr/procedures/win32_kernel/ExFreePoolWithTag.py +8 -0
- angr/procedures/win32_kernel/__fastfail.py +15 -0
- angr/procedures/win32_kernel/__init__.py +3 -0
- angr/procedures/win_user32/__init__.py +0 -0
- angr/procedures/win_user32/chars.py +15 -0
- angr/procedures/win_user32/keyboard.py +14 -0
- angr/procedures/win_user32/messagebox.py +49 -0
- angr/project.py +860 -0
- angr/protos/__init__.py +19 -0
- angr/protos/cfg_pb2.py +42 -0
- angr/protos/function_pb2.py +38 -0
- angr/protos/primitives_pb2.py +59 -0
- angr/protos/variables_pb2.py +55 -0
- angr/protos/xrefs_pb2.py +36 -0
- angr/py.typed +1 -0
- angr/rustylib.cpython-311-darwin.so +0 -0
- angr/serializable.py +66 -0
- angr/sim_manager.py +971 -0
- angr/sim_options.py +436 -0
- angr/sim_procedure.py +626 -0
- angr/sim_state.py +926 -0
- angr/sim_state_options.py +403 -0
- angr/sim_type.py +4026 -0
- angr/sim_variable.py +470 -0
- angr/simos/__init__.py +47 -0
- angr/simos/cgc.py +153 -0
- angr/simos/javavm.py +458 -0
- angr/simos/linux.py +509 -0
- angr/simos/simos.py +444 -0
- angr/simos/snimmuc_nxp.py +149 -0
- angr/simos/userland.py +163 -0
- angr/simos/windows.py +615 -0
- angr/simos/xbox.py +32 -0
- angr/slicer.py +352 -0
- angr/state_hierarchy.py +262 -0
- angr/state_plugins/__init__.py +84 -0
- angr/state_plugins/callstack.py +478 -0
- angr/state_plugins/cgc.py +155 -0
- angr/state_plugins/debug_variables.py +192 -0
- angr/state_plugins/filesystem.py +463 -0
- angr/state_plugins/gdb.py +148 -0
- angr/state_plugins/globals.py +65 -0
- angr/state_plugins/heap/__init__.py +15 -0
- angr/state_plugins/heap/heap_base.py +128 -0
- angr/state_plugins/heap/heap_brk.py +136 -0
- angr/state_plugins/heap/heap_freelist.py +213 -0
- angr/state_plugins/heap/heap_libc.py +46 -0
- angr/state_plugins/heap/heap_ptmalloc.py +620 -0
- angr/state_plugins/heap/utils.py +22 -0
- angr/state_plugins/history.py +564 -0
- angr/state_plugins/inspect.py +375 -0
- angr/state_plugins/javavm_classloader.py +134 -0
- angr/state_plugins/jni_references.py +95 -0
- angr/state_plugins/libc.py +1263 -0
- angr/state_plugins/light_registers.py +168 -0
- angr/state_plugins/log.py +84 -0
- angr/state_plugins/loop_data.py +92 -0
- angr/state_plugins/plugin.py +176 -0
- angr/state_plugins/posix.py +703 -0
- angr/state_plugins/preconstrainer.py +196 -0
- angr/state_plugins/scratch.py +173 -0
- angr/state_plugins/sim_action.py +326 -0
- angr/state_plugins/sim_action_object.py +271 -0
- angr/state_plugins/sim_event.py +59 -0
- angr/state_plugins/solver.py +1128 -0
- angr/state_plugins/symbolizer.py +291 -0
- angr/state_plugins/trace_additions.py +738 -0
- angr/state_plugins/uc_manager.py +94 -0
- angr/state_plugins/unicorn_engine.py +1920 -0
- angr/state_plugins/view.py +340 -0
- angr/storage/__init__.py +15 -0
- angr/storage/file.py +1210 -0
- angr/storage/memory_mixins/__init__.py +317 -0
- angr/storage/memory_mixins/actions_mixin.py +72 -0
- angr/storage/memory_mixins/address_concretization_mixin.py +384 -0
- angr/storage/memory_mixins/bvv_conversion_mixin.py +73 -0
- angr/storage/memory_mixins/clouseau_mixin.py +137 -0
- angr/storage/memory_mixins/conditional_store_mixin.py +25 -0
- angr/storage/memory_mixins/convenient_mappings_mixin.py +256 -0
- angr/storage/memory_mixins/default_filler_mixin.py +144 -0
- angr/storage/memory_mixins/dirty_addrs_mixin.py +11 -0
- angr/storage/memory_mixins/hex_dumper_mixin.py +82 -0
- angr/storage/memory_mixins/javavm_memory_mixin.py +392 -0
- angr/storage/memory_mixins/keyvalue_memory_mixin.py +43 -0
- angr/storage/memory_mixins/label_merger_mixin.py +31 -0
- angr/storage/memory_mixins/memory_mixin.py +175 -0
- angr/storage/memory_mixins/multi_value_merger_mixin.py +79 -0
- angr/storage/memory_mixins/name_resolution_mixin.py +67 -0
- angr/storage/memory_mixins/paged_memory/__init__.py +0 -0
- angr/storage/memory_mixins/paged_memory/page_backer_mixins.py +266 -0
- angr/storage/memory_mixins/paged_memory/paged_memory_mixin.py +743 -0
- angr/storage/memory_mixins/paged_memory/paged_memory_multivalue_mixin.py +65 -0
- angr/storage/memory_mixins/paged_memory/pages/__init__.py +26 -0
- angr/storage/memory_mixins/paged_memory/pages/base.py +31 -0
- angr/storage/memory_mixins/paged_memory/pages/cooperation.py +341 -0
- angr/storage/memory_mixins/paged_memory/pages/history_tracking_mixin.py +92 -0
- angr/storage/memory_mixins/paged_memory/pages/ispo_mixin.py +55 -0
- angr/storage/memory_mixins/paged_memory/pages/list_page.py +338 -0
- angr/storage/memory_mixins/paged_memory/pages/multi_values.py +324 -0
- angr/storage/memory_mixins/paged_memory/pages/mv_list_page.py +419 -0
- angr/storage/memory_mixins/paged_memory/pages/permissions_mixin.py +36 -0
- angr/storage/memory_mixins/paged_memory/pages/refcount_mixin.py +52 -0
- angr/storage/memory_mixins/paged_memory/pages/ultra_page.py +529 -0
- angr/storage/memory_mixins/paged_memory/privileged_mixin.py +36 -0
- angr/storage/memory_mixins/paged_memory/stack_allocation_mixin.py +74 -0
- angr/storage/memory_mixins/regioned_memory/__init__.py +17 -0
- angr/storage/memory_mixins/regioned_memory/abstract_address_descriptor.py +36 -0
- angr/storage/memory_mixins/regioned_memory/abstract_merger_mixin.py +31 -0
- angr/storage/memory_mixins/regioned_memory/region_category_mixin.py +9 -0
- angr/storage/memory_mixins/regioned_memory/region_data.py +246 -0
- angr/storage/memory_mixins/regioned_memory/region_meta_mixin.py +241 -0
- angr/storage/memory_mixins/regioned_memory/regioned_address_concretization_mixin.py +119 -0
- angr/storage/memory_mixins/regioned_memory/regioned_memory_mixin.py +442 -0
- angr/storage/memory_mixins/regioned_memory/static_find_mixin.py +69 -0
- angr/storage/memory_mixins/simple_interface_mixin.py +71 -0
- angr/storage/memory_mixins/simplification_mixin.py +15 -0
- angr/storage/memory_mixins/size_resolution_mixin.py +143 -0
- angr/storage/memory_mixins/slotted_memory.py +140 -0
- angr/storage/memory_mixins/smart_find_mixin.py +161 -0
- angr/storage/memory_mixins/symbolic_merger_mixin.py +16 -0
- angr/storage/memory_mixins/top_merger_mixin.py +25 -0
- angr/storage/memory_mixins/underconstrained_mixin.py +67 -0
- angr/storage/memory_mixins/unwrapper_mixin.py +26 -0
- angr/storage/memory_object.py +195 -0
- angr/tablespecs.py +91 -0
- angr/unicornlib.dylib +0 -0
- angr/utils/__init__.py +46 -0
- angr/utils/ail.py +176 -0
- angr/utils/algo.py +34 -0
- angr/utils/balancer.py +776 -0
- angr/utils/bits.py +46 -0
- angr/utils/constants.py +9 -0
- angr/utils/cowdict.py +63 -0
- angr/utils/cpp.py +17 -0
- angr/utils/doms.py +150 -0
- angr/utils/dynamic_dictlist.py +89 -0
- angr/utils/endness.py +18 -0
- angr/utils/enums_conv.py +97 -0
- angr/utils/env.py +12 -0
- angr/utils/formatting.py +128 -0
- angr/utils/funcid.py +244 -0
- angr/utils/graph.py +981 -0
- angr/utils/lazy_import.py +13 -0
- angr/utils/library.py +236 -0
- angr/utils/loader.py +55 -0
- angr/utils/mp.py +66 -0
- angr/utils/orderedset.py +74 -0
- angr/utils/ssa/__init__.py +455 -0
- angr/utils/ssa/tmp_uses_collector.py +23 -0
- angr/utils/ssa/vvar_uses_collector.py +36 -0
- angr/utils/strings.py +20 -0
- angr/utils/tagged_interval_map.py +112 -0
- angr/utils/timing.py +74 -0
- angr/utils/types.py +193 -0
- angr/utils/vex.py +11 -0
- angr/vaults.py +367 -0
- angr-9.2.192.dist-info/METADATA +112 -0
- angr-9.2.192.dist-info/RECORD +1442 -0
- angr-9.2.192.dist-info/WHEEL +6 -0
- angr-9.2.192.dist-info/entry_points.txt +2 -0
- angr-9.2.192.dist-info/licenses/LICENSE +27 -0
- angr-9.2.192.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,2613 @@
|
|
|
1
|
+
# pylint:disable=line-too-long,missing-class-docstring,no-self-use
|
|
2
|
+
from __future__ import annotations
|
|
3
|
+
import logging
|
|
4
|
+
from typing import Generic, cast, TypeVar
|
|
5
|
+
|
|
6
|
+
from collections.abc import Iterable
|
|
7
|
+
from collections import defaultdict
|
|
8
|
+
import contextlib
|
|
9
|
+
|
|
10
|
+
import claripy
|
|
11
|
+
import archinfo
|
|
12
|
+
from archinfo import RegisterName
|
|
13
|
+
from unique_log_filter import UniqueLogFilter
|
|
14
|
+
|
|
15
|
+
import angr
|
|
16
|
+
from .errors import AngrTypeError
|
|
17
|
+
from .sim_type import (
|
|
18
|
+
NamedTypeMixin,
|
|
19
|
+
SimCppClass,
|
|
20
|
+
SimType,
|
|
21
|
+
SimTypeChar,
|
|
22
|
+
SimTypePointer,
|
|
23
|
+
SimTypeFixedSizeArray,
|
|
24
|
+
SimTypeArray,
|
|
25
|
+
SimTypeString,
|
|
26
|
+
SimTypeFunction,
|
|
27
|
+
SimTypeFloat,
|
|
28
|
+
SimTypeDouble,
|
|
29
|
+
SimTypeReg,
|
|
30
|
+
SimStruct,
|
|
31
|
+
SimStructValue,
|
|
32
|
+
SimTypeInt,
|
|
33
|
+
SimTypeNum,
|
|
34
|
+
SimUnion,
|
|
35
|
+
SimTypeBottom,
|
|
36
|
+
parse_signature,
|
|
37
|
+
SimTypeReference,
|
|
38
|
+
SimTypeRef,
|
|
39
|
+
SimTypeBool,
|
|
40
|
+
)
|
|
41
|
+
from .state_plugins.sim_action_object import SimActionObject
|
|
42
|
+
|
|
43
|
+
l = logging.getLogger(name=__name__)
|
|
44
|
+
l.addFilter(UniqueLogFilter())
|
|
45
|
+
|
|
46
|
+
T = TypeVar("T", bound="SimFunctionArgument")
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
class PointerWrapper:
|
|
50
|
+
def __init__(self, value, buffer=False):
|
|
51
|
+
self.value = value
|
|
52
|
+
self.buffer = buffer
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
class AllocHelper:
|
|
56
|
+
def __init__(self, ptrsize):
|
|
57
|
+
self.base = claripy.BVS("alloc_base", ptrsize)
|
|
58
|
+
self.ptr = self.base
|
|
59
|
+
self.stores = {}
|
|
60
|
+
self.store_asts = {}
|
|
61
|
+
|
|
62
|
+
def alloc(self, size):
|
|
63
|
+
out = self.ptr
|
|
64
|
+
self.ptr += size
|
|
65
|
+
return out
|
|
66
|
+
|
|
67
|
+
def dump(self, val, state, loc=None):
|
|
68
|
+
if loc is None:
|
|
69
|
+
loc = self.stack_loc(val, state.arch)
|
|
70
|
+
self.stores[self.ptr] = (val, loc)
|
|
71
|
+
return self.alloc(self.calc_size(val, state.arch))
|
|
72
|
+
|
|
73
|
+
def translate(self, val, base):
|
|
74
|
+
if type(val) is SimStructValue:
|
|
75
|
+
return SimStructValue(
|
|
76
|
+
val.struct, {field: self.translate(subval, base) for field, subval in val._values.items()}
|
|
77
|
+
)
|
|
78
|
+
if isinstance(val, claripy.ast.Bits):
|
|
79
|
+
return claripy.replace(val, self.base, base)
|
|
80
|
+
if type(val) is list:
|
|
81
|
+
return [self.translate(subval, base) for subval in val]
|
|
82
|
+
raise TypeError(type(val))
|
|
83
|
+
|
|
84
|
+
def apply(self, state, base):
|
|
85
|
+
for ptr, (val, loc) in self.stores.items():
|
|
86
|
+
translated_val = self.translate(val, base)
|
|
87
|
+
translated_ptr = self.translate(ptr, base)
|
|
88
|
+
loc.set_value(state, translated_val, stack_base=translated_ptr)
|
|
89
|
+
|
|
90
|
+
def size(self):
|
|
91
|
+
val = self.translate(self.ptr, claripy.BVV(0, len(self.ptr)))
|
|
92
|
+
assert isinstance(val, claripy.ast.Base) and val.op == "BVV"
|
|
93
|
+
assert isinstance(val.args[0], int)
|
|
94
|
+
return abs(val.args[0])
|
|
95
|
+
|
|
96
|
+
@classmethod
|
|
97
|
+
def calc_size(cls, val, arch):
|
|
98
|
+
if type(val) is SimStructValue:
|
|
99
|
+
return val.struct.size // arch.byte_width
|
|
100
|
+
if isinstance(val, claripy.ast.Bits):
|
|
101
|
+
return len(val) // arch.byte_width
|
|
102
|
+
if type(val) is list:
|
|
103
|
+
# TODO real strides
|
|
104
|
+
if len(val) == 0:
|
|
105
|
+
return 0
|
|
106
|
+
return cls.calc_size(val[0], arch) * len(val)
|
|
107
|
+
raise TypeError(type(val))
|
|
108
|
+
|
|
109
|
+
@classmethod
|
|
110
|
+
def stack_loc(cls, val, arch, offset=0):
|
|
111
|
+
if isinstance(val, claripy.ast.Bits):
|
|
112
|
+
return SimStackArg(offset, len(val) // arch.byte_width)
|
|
113
|
+
if type(val) is list:
|
|
114
|
+
# TODO real strides
|
|
115
|
+
if len(val) == 0:
|
|
116
|
+
return SimArrayArg([])
|
|
117
|
+
stride = cls.calc_size(val[0], arch)
|
|
118
|
+
return SimArrayArg([cls.stack_loc(subval, arch, offset + i * stride) for i, subval in enumerate(val)])
|
|
119
|
+
if type(val) is SimStructValue:
|
|
120
|
+
return SimStructArg(
|
|
121
|
+
val.struct,
|
|
122
|
+
{
|
|
123
|
+
field: cls.stack_loc(subval, arch, offset + val.struct.offsets[field])
|
|
124
|
+
for field, subval in val._values.items()
|
|
125
|
+
},
|
|
126
|
+
)
|
|
127
|
+
raise TypeError(type(val))
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
def refine_locs_with_struct_type(
|
|
131
|
+
arch: archinfo.Arch,
|
|
132
|
+
locs: list,
|
|
133
|
+
arg_type: SimType,
|
|
134
|
+
offset: int = 0,
|
|
135
|
+
treat_bot_as_int=True,
|
|
136
|
+
treat_unsupported_as_int=True,
|
|
137
|
+
):
|
|
138
|
+
# CONTRACT FOR USING THIS METHOD: locs must be a list of locs which are all wordsize
|
|
139
|
+
# ADDITIONAL NUANCE: this will not respect the need for big-endian integers to be stored at the end of words.
|
|
140
|
+
# that's why this is named with_struct_type, because it will blindly trust the offsets given to it.
|
|
141
|
+
|
|
142
|
+
if treat_bot_as_int and isinstance(arg_type, SimTypeBottom):
|
|
143
|
+
arg_type = SimTypeInt(label=arg_type.label).with_arch(arch)
|
|
144
|
+
|
|
145
|
+
if isinstance(arg_type, (SimTypeReg, SimTypeNum, SimTypeFloat)):
|
|
146
|
+
assert arg_type.size is not None
|
|
147
|
+
seen_bytes = 0
|
|
148
|
+
pieces = []
|
|
149
|
+
while seen_bytes < arg_type.size // arch.byte_width:
|
|
150
|
+
start_offset = offset + seen_bytes
|
|
151
|
+
chunk = start_offset // arch.bytes
|
|
152
|
+
chunk_offset = start_offset % arch.bytes
|
|
153
|
+
chunk_remaining = arch.bytes - chunk_offset
|
|
154
|
+
type_remaining = arg_type.size // arch.byte_width - seen_bytes
|
|
155
|
+
use_bytes = min(chunk_remaining, type_remaining)
|
|
156
|
+
pieces.append(locs[chunk].refine(size=use_bytes, offset=chunk_offset))
|
|
157
|
+
seen_bytes += use_bytes
|
|
158
|
+
|
|
159
|
+
piece = pieces[0] if len(pieces) == 1 else SimComboArg(pieces)
|
|
160
|
+
if isinstance(arg_type, SimTypeFloat):
|
|
161
|
+
piece.is_fp = True
|
|
162
|
+
return piece
|
|
163
|
+
if isinstance(arg_type, SimTypeFixedSizeArray):
|
|
164
|
+
assert arg_type.elem_type.size is not None and arg_type.length is not None
|
|
165
|
+
# TODO explicit stride
|
|
166
|
+
locs_list = [
|
|
167
|
+
refine_locs_with_struct_type(
|
|
168
|
+
arch, locs, arg_type.elem_type, offset=offset + i * arg_type.elem_type.size // arch.byte_width
|
|
169
|
+
)
|
|
170
|
+
for i in range(arg_type.length)
|
|
171
|
+
]
|
|
172
|
+
return SimArrayArg(locs_list)
|
|
173
|
+
if isinstance(arg_type, SimStruct):
|
|
174
|
+
locs_dict = {
|
|
175
|
+
field: refine_locs_with_struct_type(arch, locs, field_ty, offset=offset + arg_type.offsets[field])
|
|
176
|
+
for field, field_ty in arg_type.fields.items()
|
|
177
|
+
}
|
|
178
|
+
return SimStructArg(arg_type, locs_dict)
|
|
179
|
+
if isinstance(arg_type, SimUnion):
|
|
180
|
+
# Treat a SimUnion as functionality equivalent to its longest member
|
|
181
|
+
for member in arg_type.members.values():
|
|
182
|
+
if member.size == arg_type.size:
|
|
183
|
+
return refine_locs_with_struct_type(arch, locs, member, offset)
|
|
184
|
+
|
|
185
|
+
# for all other types, we basically treat them as integers until someone implements proper layouting logic
|
|
186
|
+
if treat_unsupported_as_int:
|
|
187
|
+
arg_type = SimTypeInt().with_arch(arch)
|
|
188
|
+
return refine_locs_with_struct_type(
|
|
189
|
+
arch,
|
|
190
|
+
locs,
|
|
191
|
+
arg_type,
|
|
192
|
+
offset=offset,
|
|
193
|
+
treat_bot_as_int=treat_bot_as_int,
|
|
194
|
+
treat_unsupported_as_int=treat_unsupported_as_int,
|
|
195
|
+
)
|
|
196
|
+
|
|
197
|
+
raise TypeError(f"I don't know how to lay out a {arg_type}")
|
|
198
|
+
|
|
199
|
+
|
|
200
|
+
class SerializableIterator:
|
|
201
|
+
def __iter__(self):
|
|
202
|
+
return self
|
|
203
|
+
|
|
204
|
+
def __next__(self):
|
|
205
|
+
raise NotImplementedError
|
|
206
|
+
|
|
207
|
+
def getstate(self):
|
|
208
|
+
raise NotImplementedError
|
|
209
|
+
|
|
210
|
+
def setstate(self, state):
|
|
211
|
+
raise NotImplementedError
|
|
212
|
+
|
|
213
|
+
|
|
214
|
+
class SerializableListIterator(SerializableIterator):
|
|
215
|
+
def __init__(self, lst):
|
|
216
|
+
self._lst = lst
|
|
217
|
+
self._index = 0
|
|
218
|
+
|
|
219
|
+
def __next__(self):
|
|
220
|
+
if self._index >= len(self._lst):
|
|
221
|
+
raise StopIteration
|
|
222
|
+
result = self._lst[self._index]
|
|
223
|
+
self._index += 1
|
|
224
|
+
return result
|
|
225
|
+
|
|
226
|
+
def getstate(self):
|
|
227
|
+
return self._index
|
|
228
|
+
|
|
229
|
+
def setstate(self, state):
|
|
230
|
+
self._index = state
|
|
231
|
+
|
|
232
|
+
|
|
233
|
+
class SerializableCounter(SerializableIterator):
|
|
234
|
+
def __init__(self, start, stride, mapping=lambda x: x):
|
|
235
|
+
self._next = start
|
|
236
|
+
self._stride = stride
|
|
237
|
+
self._mapping = mapping
|
|
238
|
+
|
|
239
|
+
def __next__(self):
|
|
240
|
+
result = self._mapping(self._next)
|
|
241
|
+
self._next += self._stride
|
|
242
|
+
return result
|
|
243
|
+
|
|
244
|
+
def getstate(self):
|
|
245
|
+
return self._next
|
|
246
|
+
|
|
247
|
+
def setstate(self, state):
|
|
248
|
+
self._next = state
|
|
249
|
+
|
|
250
|
+
|
|
251
|
+
class SimFunctionArgument:
|
|
252
|
+
"""
|
|
253
|
+
Represent a generic function argument.
|
|
254
|
+
|
|
255
|
+
:ivar int size: The size of the argument, in number of bytes.
|
|
256
|
+
:ivar bool is_fp: Whether loads from this location should return a floating point bitvector
|
|
257
|
+
"""
|
|
258
|
+
|
|
259
|
+
def __init__(self, size: int, is_fp: bool = False):
|
|
260
|
+
self.size = size
|
|
261
|
+
self.is_fp = is_fp
|
|
262
|
+
|
|
263
|
+
def __ne__(self, other):
|
|
264
|
+
return not self == other
|
|
265
|
+
|
|
266
|
+
def __hash__(self):
|
|
267
|
+
return hash(("function_argument", self.size))
|
|
268
|
+
|
|
269
|
+
def check_value_set(self, value, arch):
|
|
270
|
+
if not isinstance(value, claripy.ast.Base) and self.size is None:
|
|
271
|
+
raise TypeError("Only claripy objects may be stored through SimFunctionArgument when size is not provided")
|
|
272
|
+
if self.size is not None and isinstance(value, claripy.ast.Base) and self.size * arch.byte_width < value.length:
|
|
273
|
+
raise TypeError(f"{value} doesn't fit in an argument of size {self.size}")
|
|
274
|
+
if isinstance(value, int):
|
|
275
|
+
value = claripy.BVV(value, self.size * arch.byte_width)
|
|
276
|
+
if isinstance(value, float):
|
|
277
|
+
if self.size not in (4, 8):
|
|
278
|
+
raise ValueError(f"What do I do with a float {self.size} bytes long")
|
|
279
|
+
value = claripy.FPV(value, claripy.FSORT_FLOAT if self.size == 4 else claripy.FSORT_DOUBLE)
|
|
280
|
+
return value.raw_to_bv() # type:ignore
|
|
281
|
+
|
|
282
|
+
def check_value_get(self, value):
|
|
283
|
+
if self.is_fp:
|
|
284
|
+
return value.raw_to_fp()
|
|
285
|
+
return value
|
|
286
|
+
|
|
287
|
+
def set_value(self, state, value, **kwargs):
|
|
288
|
+
raise NotImplementedError
|
|
289
|
+
|
|
290
|
+
def get_value(self, state, **kwargs):
|
|
291
|
+
raise NotImplementedError
|
|
292
|
+
|
|
293
|
+
def refine(self, size, arch=None, offset=None, is_fp=None):
|
|
294
|
+
raise NotImplementedError
|
|
295
|
+
|
|
296
|
+
def get_footprint(self) -> Iterable[SimRegArg | SimStackArg]:
|
|
297
|
+
"""
|
|
298
|
+
Return a list of SimRegArg and SimStackArgs that are the base components used for this location
|
|
299
|
+
"""
|
|
300
|
+
raise NotImplementedError
|
|
301
|
+
|
|
302
|
+
|
|
303
|
+
class SimRegArg(SimFunctionArgument):
|
|
304
|
+
"""
|
|
305
|
+
Represents a function argument that has been passed in a register.
|
|
306
|
+
|
|
307
|
+
:ivar string reg_name: The name of the represented register.
|
|
308
|
+
:ivar int size: The size of the data to store, in number of bytes.
|
|
309
|
+
:ivar reg_offset: The offset into the register to start storing data.
|
|
310
|
+
:ivar clear_entire_reg: Whether a store to this register should zero the unused parts of the register.
|
|
311
|
+
:ivar bool is_fp: Whether loads from this location should return a floating point bitvector
|
|
312
|
+
"""
|
|
313
|
+
|
|
314
|
+
def __init__(self, reg_name: RegisterName, size: int, reg_offset=0, is_fp=False, clear_entire_reg=False):
|
|
315
|
+
super().__init__(size, is_fp)
|
|
316
|
+
self.reg_name = reg_name
|
|
317
|
+
self.reg_offset = reg_offset
|
|
318
|
+
self.clear_entire_reg = clear_entire_reg
|
|
319
|
+
|
|
320
|
+
def get_footprint(self):
|
|
321
|
+
return {self}
|
|
322
|
+
|
|
323
|
+
def __repr__(self):
|
|
324
|
+
return f"<{self.reg_name}>"
|
|
325
|
+
|
|
326
|
+
def __eq__(self, other):
|
|
327
|
+
return (
|
|
328
|
+
type(other) is SimRegArg
|
|
329
|
+
and self.reg_name == other.reg_name
|
|
330
|
+
and self.reg_offset == other.reg_offset
|
|
331
|
+
and self.size == other.size
|
|
332
|
+
)
|
|
333
|
+
|
|
334
|
+
def __hash__(self):
|
|
335
|
+
return hash((self.size, self.reg_name, self.reg_offset))
|
|
336
|
+
|
|
337
|
+
def check_offset(self, arch) -> int:
|
|
338
|
+
return arch.registers[self.reg_name][0] + self.reg_offset
|
|
339
|
+
|
|
340
|
+
def set_value(self, state, value, **kwargs): # pylint: disable=unused-argument,arguments-differ
|
|
341
|
+
value = self.check_value_set(value, state.arch)
|
|
342
|
+
offset = self.check_offset(state.arch)
|
|
343
|
+
if self.clear_entire_reg:
|
|
344
|
+
state.registers.store(self.reg_name, 0)
|
|
345
|
+
state.registers.store(offset, value, size=self.size)
|
|
346
|
+
|
|
347
|
+
def get_value(self, state, **kwargs): # pylint: disable=unused-argument,arguments-differ
|
|
348
|
+
offset = self.check_offset(state.arch)
|
|
349
|
+
return self.check_value_get(state.registers.load(offset, size=self.size))
|
|
350
|
+
|
|
351
|
+
def refine(self, size, arch=None, offset=None, is_fp=None):
|
|
352
|
+
passed_offset_none = offset is None
|
|
353
|
+
if offset is None:
|
|
354
|
+
if arch is None:
|
|
355
|
+
raise ValueError("Need to specify either offset or arch in order to refine a register argument")
|
|
356
|
+
offset = 0 if arch.register_endness == "Iend_LE" else self.size - size
|
|
357
|
+
if is_fp is None:
|
|
358
|
+
is_fp = self.is_fp
|
|
359
|
+
return SimRegArg(self.reg_name, size, self.reg_offset + offset, is_fp, clear_entire_reg=passed_offset_none)
|
|
360
|
+
|
|
361
|
+
def sse_extend(self):
|
|
362
|
+
return SimRegArg(self.reg_name, self.size, self.reg_offset + self.size, is_fp=self.is_fp)
|
|
363
|
+
|
|
364
|
+
|
|
365
|
+
class SimStackArg(SimFunctionArgument):
|
|
366
|
+
"""
|
|
367
|
+
Represents a function argument that has been passed on the stack.
|
|
368
|
+
|
|
369
|
+
:var int stack_offset: The position of the argument relative to the stack pointer after the function prelude.
|
|
370
|
+
:ivar int size: The size of the argument, in number of bytes.
|
|
371
|
+
:ivar bool is_fp: Whether loads from this location should return a floating point bitvector
|
|
372
|
+
"""
|
|
373
|
+
|
|
374
|
+
def __init__(self, stack_offset: int, size: int, is_fp: bool = False):
|
|
375
|
+
SimFunctionArgument.__init__(self, size, is_fp)
|
|
376
|
+
self.stack_offset: int = stack_offset
|
|
377
|
+
|
|
378
|
+
def get_footprint(self):
|
|
379
|
+
return {self}
|
|
380
|
+
|
|
381
|
+
def __repr__(self):
|
|
382
|
+
return f"[{self.stack_offset:#x}]"
|
|
383
|
+
|
|
384
|
+
def __eq__(self, other):
|
|
385
|
+
return type(other) is SimStackArg and self.stack_offset == other.stack_offset
|
|
386
|
+
|
|
387
|
+
def __hash__(self):
|
|
388
|
+
return hash((self.size, self.stack_offset))
|
|
389
|
+
|
|
390
|
+
def set_value(self, state, value, stack_base=None, **kwargs): # pylint: disable=arguments-differ
|
|
391
|
+
value = self.check_value_set(value, state.arch)
|
|
392
|
+
if stack_base is None:
|
|
393
|
+
stack_base = state.regs.sp
|
|
394
|
+
state.memory.store(stack_base + self.stack_offset, value, endness=state.arch.memory_endness)
|
|
395
|
+
|
|
396
|
+
def get_value(self, state, stack_base=None, **kwargs): # pylint: disable=arguments-differ
|
|
397
|
+
if stack_base is None:
|
|
398
|
+
stack_base = state.regs.sp
|
|
399
|
+
value = state.memory.load(stack_base + self.stack_offset, endness=state.arch.memory_endness, size=self.size)
|
|
400
|
+
return self.check_value_get(value)
|
|
401
|
+
|
|
402
|
+
def refine(self, size, arch=None, offset=None, is_fp=None):
|
|
403
|
+
if offset is None:
|
|
404
|
+
if arch is None:
|
|
405
|
+
raise ValueError("Need to specify either offset or arch in order to refine a stack argument")
|
|
406
|
+
offset = 0 if arch.register_endness == "Iend_LE" else self.size - size
|
|
407
|
+
if is_fp is None:
|
|
408
|
+
is_fp = self.is_fp
|
|
409
|
+
return SimStackArg(self.stack_offset + offset, size, is_fp)
|
|
410
|
+
|
|
411
|
+
|
|
412
|
+
class SimComboArg(SimFunctionArgument, Generic[T]):
|
|
413
|
+
"""
|
|
414
|
+
An argument which spans multiple storage locations. Locations should be given least-significant first.
|
|
415
|
+
"""
|
|
416
|
+
|
|
417
|
+
def __init__(self, locations: list[T], is_fp=False):
|
|
418
|
+
super().__init__(sum(x.size for x in locations), is_fp=is_fp)
|
|
419
|
+
self.locations = locations
|
|
420
|
+
|
|
421
|
+
def get_footprint(self):
|
|
422
|
+
return {y for x in self.locations for y in x.get_footprint()}
|
|
423
|
+
|
|
424
|
+
def __repr__(self):
|
|
425
|
+
return f"SimComboArg({self.locations!r})"
|
|
426
|
+
|
|
427
|
+
def __eq__(self, other):
|
|
428
|
+
return type(other) is SimComboArg and all(a == b for a, b in zip(self.locations, other.locations))
|
|
429
|
+
|
|
430
|
+
def set_value(self, state, value, **kwargs): # pylint:disable=arguments-differ
|
|
431
|
+
value = self.check_value_set(value, state.arch)
|
|
432
|
+
cur = 0
|
|
433
|
+
for loc in self.locations:
|
|
434
|
+
size_bits = loc.size * state.arch.byte_width
|
|
435
|
+
loc.set_value(state, value[cur + size_bits - 1 : cur], **kwargs)
|
|
436
|
+
cur += size_bits
|
|
437
|
+
|
|
438
|
+
def get_value(self, state, **kwargs): # pylint:disable=arguments-differ
|
|
439
|
+
vals = []
|
|
440
|
+
for loc in reversed(self.locations):
|
|
441
|
+
vals.append(loc.get_value(state, **kwargs))
|
|
442
|
+
return self.check_value_get(claripy.Concat(*vals))
|
|
443
|
+
|
|
444
|
+
|
|
445
|
+
class SimStructArg(SimFunctionArgument):
|
|
446
|
+
"""
|
|
447
|
+
An argument which de/serializes a struct from a list of storage locations
|
|
448
|
+
|
|
449
|
+
:ivar struct: The simtype describing the structure
|
|
450
|
+
:ivar locs: The storage locations to use
|
|
451
|
+
"""
|
|
452
|
+
|
|
453
|
+
def __init__(self, struct: SimStruct, locs: dict[str, SimFunctionArgument]):
|
|
454
|
+
super().__init__(sum(loc.size for loc in locs.values()))
|
|
455
|
+
self.struct = struct
|
|
456
|
+
self.locs = locs
|
|
457
|
+
|
|
458
|
+
def get_footprint(self):
|
|
459
|
+
regs: defaultdict[str, set[SimRegArg]] = defaultdict(set)
|
|
460
|
+
others: set[SimRegArg | SimStackArg] = set()
|
|
461
|
+
for loc in self.locs.values():
|
|
462
|
+
for footloc in loc.get_footprint():
|
|
463
|
+
if isinstance(footloc, SimRegArg):
|
|
464
|
+
regs[footloc.reg_name].add(footloc)
|
|
465
|
+
else:
|
|
466
|
+
others.add(footloc)
|
|
467
|
+
|
|
468
|
+
for reg, locset in regs.items():
|
|
469
|
+
min_offset = min(loc.reg_offset for loc in locset)
|
|
470
|
+
max_offset = max(loc.reg_offset + loc.size for loc in locset)
|
|
471
|
+
others.add(SimRegArg(reg, max_offset - min_offset, min_offset))
|
|
472
|
+
|
|
473
|
+
return others
|
|
474
|
+
|
|
475
|
+
def get_single_footprint(self) -> SimStackArg | SimRegArg | SimComboArg:
|
|
476
|
+
if self.struct._arch is None:
|
|
477
|
+
raise TypeError("Can't tell the size of a struct without an arch")
|
|
478
|
+
stack_min = None
|
|
479
|
+
stack_max = None
|
|
480
|
+
regs = []
|
|
481
|
+
for field in self.struct.fields:
|
|
482
|
+
loc = self.locs[field]
|
|
483
|
+
if isinstance(loc, SimStackArg):
|
|
484
|
+
if stack_min is None or stack_max is None:
|
|
485
|
+
stack_min = loc.stack_offset
|
|
486
|
+
stack_max = loc.stack_offset
|
|
487
|
+
else:
|
|
488
|
+
# sanity check that arguments are laid out in order...
|
|
489
|
+
assert loc.stack_offset >= stack_max
|
|
490
|
+
stack_max = loc.stack_offset + loc.size
|
|
491
|
+
elif isinstance(loc, SimRegArg):
|
|
492
|
+
regs.append(loc)
|
|
493
|
+
else:
|
|
494
|
+
assert False, "Why would a struct have layout elements other than stack and reg?"
|
|
495
|
+
|
|
496
|
+
# things to consider...
|
|
497
|
+
# what happens if we return the concat of two registers but there's slack space missing?
|
|
498
|
+
# an example of this would be big-endian struct { long a; int b; }
|
|
499
|
+
# do any CCs do this??
|
|
500
|
+
# for now assume no
|
|
501
|
+
|
|
502
|
+
if stack_min is not None:
|
|
503
|
+
if regs:
|
|
504
|
+
assert (
|
|
505
|
+
False
|
|
506
|
+
), "Unknown CC argument passing structure - why are we passing both regs and stack at the same time?"
|
|
507
|
+
return SimStackArg(stack_min, self.struct.size // self.struct._arch.byte_width)
|
|
508
|
+
if not regs:
|
|
509
|
+
assert False, "huh??????"
|
|
510
|
+
if len(regs) == 1:
|
|
511
|
+
return regs[0]
|
|
512
|
+
return SimComboArg(regs)
|
|
513
|
+
|
|
514
|
+
def get_value(self, state, **kwargs):
|
|
515
|
+
return SimStructValue(
|
|
516
|
+
self.struct, {field: getter.get_value(state, **kwargs) for field, getter in self.locs.items()}
|
|
517
|
+
)
|
|
518
|
+
|
|
519
|
+
def set_value(self, state, value, **kwargs):
|
|
520
|
+
for field, setter in self.locs.items():
|
|
521
|
+
setter.set_value(state, value[field], **kwargs)
|
|
522
|
+
|
|
523
|
+
|
|
524
|
+
class SimArrayArg(SimFunctionArgument):
|
|
525
|
+
def __init__(self, locs):
|
|
526
|
+
super().__init__(sum(loc.size for loc in locs))
|
|
527
|
+
self.locs = locs
|
|
528
|
+
|
|
529
|
+
def get_footprint(self):
|
|
530
|
+
return {y for x in self.locs for y in x.get_footprint()}
|
|
531
|
+
|
|
532
|
+
def get_value(self, state, **kwargs):
|
|
533
|
+
return [getter.get_value(state, **kwargs) for getter in self.locs]
|
|
534
|
+
|
|
535
|
+
def set_value(self, state, value, **kwargs):
|
|
536
|
+
if len(value) != len(self.locs):
|
|
537
|
+
raise TypeError(f"Expected {len(self.locs)} elements, got {len(value)}")
|
|
538
|
+
for subvalue, setter in zip(value, self.locs):
|
|
539
|
+
setter.set_value(state, subvalue, **kwargs)
|
|
540
|
+
|
|
541
|
+
|
|
542
|
+
class SimReferenceArgument(SimFunctionArgument):
|
|
543
|
+
"""
|
|
544
|
+
A function argument which is passed by reference.
|
|
545
|
+
|
|
546
|
+
:ivar ptr_loc: The location the reference's pointer is stored
|
|
547
|
+
:ivar main_loc: A SimStackArgument describing how to load the argument's value as if it were stored at offset
|
|
548
|
+
zero on the stack. It will be passed ``stack_base=ptr_loc.get_value(state)``
|
|
549
|
+
"""
|
|
550
|
+
|
|
551
|
+
def __init__(self, ptr_loc: SimFunctionArgument, main_loc: SimFunctionArgument):
|
|
552
|
+
super().__init__(ptr_loc.size) # ???
|
|
553
|
+
self.ptr_loc = ptr_loc
|
|
554
|
+
self.main_loc = main_loc
|
|
555
|
+
|
|
556
|
+
def get_footprint(self):
|
|
557
|
+
return self.main_loc.get_footprint()
|
|
558
|
+
|
|
559
|
+
def get_value(self, state, **kwargs):
|
|
560
|
+
ptr_val = self.ptr_loc.get_value(state, **kwargs)
|
|
561
|
+
return self.main_loc.get_value(state, stack_base=ptr_val, **kwargs)
|
|
562
|
+
|
|
563
|
+
def set_value(self, state, value, **kwargs):
|
|
564
|
+
ptr_val = self.ptr_loc.get_value(state, **kwargs)
|
|
565
|
+
self.main_loc.set_value(state, value, stack_base=ptr_val, **kwargs)
|
|
566
|
+
|
|
567
|
+
|
|
568
|
+
class ArgSession:
|
|
569
|
+
"""
|
|
570
|
+
A class to keep track of the state accumulated in laying parameters out into memory
|
|
571
|
+
"""
|
|
572
|
+
|
|
573
|
+
__slots__ = (
|
|
574
|
+
"both_iter",
|
|
575
|
+
"cc",
|
|
576
|
+
"fp_iter",
|
|
577
|
+
"int_iter",
|
|
578
|
+
)
|
|
579
|
+
|
|
580
|
+
def __init__(self, cc):
|
|
581
|
+
self.cc = cc
|
|
582
|
+
self.fp_iter = cc.fp_args
|
|
583
|
+
self.int_iter = cc.int_args
|
|
584
|
+
self.both_iter = cc.memory_args
|
|
585
|
+
|
|
586
|
+
def getstate(self):
|
|
587
|
+
return (self.fp_iter.getstate(), self.int_iter.getstate(), self.both_iter.getstate())
|
|
588
|
+
|
|
589
|
+
def setstate(self, state):
|
|
590
|
+
fp, int_, both = state
|
|
591
|
+
self.fp_iter.setstate(fp)
|
|
592
|
+
self.int_iter.setstate(int_)
|
|
593
|
+
self.both_iter.setstate(both)
|
|
594
|
+
|
|
595
|
+
|
|
596
|
+
class UsercallArgSession:
|
|
597
|
+
"""
|
|
598
|
+
An argsession for use with SimCCUsercall
|
|
599
|
+
"""
|
|
600
|
+
|
|
601
|
+
__slots__ = (
|
|
602
|
+
"cc",
|
|
603
|
+
"real_args",
|
|
604
|
+
)
|
|
605
|
+
|
|
606
|
+
def __init__(self, cc):
|
|
607
|
+
self.cc = cc
|
|
608
|
+
self.real_args = SerializableListIterator(self.cc.args)
|
|
609
|
+
|
|
610
|
+
def getstate(self):
|
|
611
|
+
return self.real_args.getstate()
|
|
612
|
+
|
|
613
|
+
def setstate(self, state):
|
|
614
|
+
self.real_args.setstate(state)
|
|
615
|
+
|
|
616
|
+
|
|
617
|
+
class SimCC:
|
|
618
|
+
"""
|
|
619
|
+
A calling convention allows you to extract from a state the data passed from function to
|
|
620
|
+
function by calls and returns. Most of the methods provided by SimCC that operate on a state
|
|
621
|
+
assume that the program is just after a call but just before stack frame allocation, though
|
|
622
|
+
this may be overridden with the `stack_base` parameter to each individual method.
|
|
623
|
+
|
|
624
|
+
This is the base class for all calling conventions.
|
|
625
|
+
"""
|
|
626
|
+
|
|
627
|
+
def __init__(self, arch: archinfo.Arch):
|
|
628
|
+
"""
|
|
629
|
+
:param arch: The Archinfo arch for this CC
|
|
630
|
+
"""
|
|
631
|
+
self.arch = arch
|
|
632
|
+
|
|
633
|
+
#
|
|
634
|
+
# Here are all the things a subclass needs to specify!
|
|
635
|
+
#
|
|
636
|
+
|
|
637
|
+
ARG_REGS: list[str] = [] # A list of all the registers used for integral args, in order (names or offsets)
|
|
638
|
+
FP_ARG_REGS: list[str] = [] # A list of all the registers used for floating point args, in order
|
|
639
|
+
STACKARG_SP_BUFF = 0 # The amount of stack space reserved between the saved return address
|
|
640
|
+
# (if applicable) and the arguments. Probably zero.
|
|
641
|
+
STACKARG_SP_DIFF = 0 # The amount of stack space reserved for the return address
|
|
642
|
+
CALLER_SAVED_REGS: list[str] = [] # Caller-saved registers
|
|
643
|
+
RETURN_ADDR: SimFunctionArgument | None = (
|
|
644
|
+
None # The location where the return address is stored, as a SimFunctionArgument
|
|
645
|
+
)
|
|
646
|
+
RETURN_VAL: SimFunctionArgument | None = (
|
|
647
|
+
None # The location where the return value is stored, as a SimFunctionArgument
|
|
648
|
+
)
|
|
649
|
+
OVERFLOW_RETURN_VAL: SimFunctionArgument | None = (
|
|
650
|
+
None # The second half of the location where a double-length return value is stored
|
|
651
|
+
)
|
|
652
|
+
FP_RETURN_VAL: SimFunctionArgument | None = (
|
|
653
|
+
None # The location where floating-point argument return values are stored
|
|
654
|
+
)
|
|
655
|
+
ARCH: type[archinfo.Arch] | None = (
|
|
656
|
+
None # The archinfo.Arch class for which this CC is most likely relevant, if related
|
|
657
|
+
)
|
|
658
|
+
# archinfo.Arch classes for which this CC is relevant, in addition to self.ARCH.
|
|
659
|
+
# you should access cls.arches() to get a list of all arches for which this CC is relevant
|
|
660
|
+
EXTRA_ARCHES: tuple[type[archinfo.Arch], ...] = ()
|
|
661
|
+
CALLEE_CLEANUP = False # Whether the callee has to deallocate the stack space for the arguments
|
|
662
|
+
|
|
663
|
+
STACK_ALIGNMENT = 1 # the alignment requirement of the stack pointer at function start BEFORE call
|
|
664
|
+
|
|
665
|
+
#
|
|
666
|
+
# Here are several things you MAY want to override to change your cc's convention
|
|
667
|
+
#
|
|
668
|
+
|
|
669
|
+
@property
|
|
670
|
+
def int_args(self):
|
|
671
|
+
"""
|
|
672
|
+
Iterate through all the possible arg positions that can only be used to store integer or pointer values.
|
|
673
|
+
|
|
674
|
+
Returns an iterator of SimFunctionArguments
|
|
675
|
+
"""
|
|
676
|
+
if self.ARG_REGS is None:
|
|
677
|
+
raise NotImplementedError
|
|
678
|
+
return SerializableListIterator([SimRegArg(reg, self.arch.bytes) for reg in self.ARG_REGS])
|
|
679
|
+
|
|
680
|
+
@property
|
|
681
|
+
def memory_args(self):
|
|
682
|
+
"""
|
|
683
|
+
Iterate through all the possible arg positions that can be used to store any kind of argument.
|
|
684
|
+
|
|
685
|
+
Returns an iterator of SimFunctionArguments
|
|
686
|
+
"""
|
|
687
|
+
start = self.STACKARG_SP_BUFF + self.STACKARG_SP_DIFF
|
|
688
|
+
return SerializableCounter(start, self.arch.bytes, lambda offset: SimStackArg(offset, self.arch.bytes))
|
|
689
|
+
|
|
690
|
+
@property
|
|
691
|
+
def fp_args(self):
|
|
692
|
+
"""
|
|
693
|
+
Iterate through all the possible arg positions that can only be used to store floating point values.
|
|
694
|
+
|
|
695
|
+
Returns an iterator of SimFunctionArguments
|
|
696
|
+
"""
|
|
697
|
+
if self.FP_ARG_REGS is None:
|
|
698
|
+
raise NotImplementedError
|
|
699
|
+
return SerializableListIterator([SimRegArg(reg, self.arch.bytes) for reg in self.FP_ARG_REGS])
|
|
700
|
+
|
|
701
|
+
def is_fp_arg(self, arg):
|
|
702
|
+
"""
|
|
703
|
+
This should take a SimFunctionArgument instance and return whether or not that argument is a floating-point
|
|
704
|
+
argument.
|
|
705
|
+
|
|
706
|
+
Returns True for MUST be a floating point arg,
|
|
707
|
+
False for MUST NOT be a floating point arg,
|
|
708
|
+
None for when it can be either.
|
|
709
|
+
"""
|
|
710
|
+
if arg in self.int_args:
|
|
711
|
+
return False
|
|
712
|
+
if arg in self.fp_args or arg == self.FP_RETURN_VAL:
|
|
713
|
+
return True
|
|
714
|
+
return None
|
|
715
|
+
|
|
716
|
+
ArgSession = ArgSession # import this from global scope so SimCC subclasses can subclass it if they like
|
|
717
|
+
|
|
718
|
+
def arg_session(self, ret_ty: SimType | None) -> ArgSession:
|
|
719
|
+
"""
|
|
720
|
+
Return an arg session.
|
|
721
|
+
|
|
722
|
+
A session provides the control interface necessary to describe how integral and floating-point arguments are
|
|
723
|
+
laid out into memory. The default behavior is that there are a finite list of int-only and fp-only argument
|
|
724
|
+
slots, and an infinite number of generic slots, and when an argument of a given type is requested, the most
|
|
725
|
+
slot available is used. If you need different behavior, subclass ArgSession.
|
|
726
|
+
|
|
727
|
+
You need to provide the return type of the function in order to kick off an arg layout session.
|
|
728
|
+
"""
|
|
729
|
+
session = self.ArgSession(self)
|
|
730
|
+
if self.return_in_implicit_outparam(ret_ty):
|
|
731
|
+
self.next_arg(session, SimTypePointer(SimTypeBottom()).with_arch(self.arch))
|
|
732
|
+
return session
|
|
733
|
+
|
|
734
|
+
def return_in_implicit_outparam(self, ty) -> bool: # pylint:disable=unused-argument
|
|
735
|
+
return False
|
|
736
|
+
|
|
737
|
+
def stack_space(self, args):
|
|
738
|
+
"""
|
|
739
|
+
:param args: A list of SimFunctionArguments
|
|
740
|
+
|
|
741
|
+
:returns: The number of bytes that should be allocated on the stack to store all these args,
|
|
742
|
+
NOT INCLUDING the return address.
|
|
743
|
+
"""
|
|
744
|
+
out = self.STACKARG_SP_DIFF
|
|
745
|
+
for arg in args:
|
|
746
|
+
if isinstance(arg, SimStackArg):
|
|
747
|
+
out = max(out, arg.stack_offset + self.arch.bytes)
|
|
748
|
+
|
|
749
|
+
out += self.STACKARG_SP_BUFF
|
|
750
|
+
return out
|
|
751
|
+
|
|
752
|
+
def return_val(self, ty, perspective_returned=False):
|
|
753
|
+
"""
|
|
754
|
+
The location the return value is stored, based on its type.
|
|
755
|
+
"""
|
|
756
|
+
if ty._arch is None:
|
|
757
|
+
ty = ty.with_arch(self.arch)
|
|
758
|
+
if isinstance(ty, (SimStruct, SimUnion, SimTypeFixedSizeArray)):
|
|
759
|
+
raise AngrTypeError(
|
|
760
|
+
f"{self} doesn't know how to return aggregate types ({type(ty)}). Consider overriding return_val to "
|
|
761
|
+
"implement its ABI logic"
|
|
762
|
+
)
|
|
763
|
+
if self.return_in_implicit_outparam(ty):
|
|
764
|
+
if perspective_returned:
|
|
765
|
+
assert self.RETURN_VAL is not None
|
|
766
|
+
ptr_loc = self.RETURN_VAL
|
|
767
|
+
else:
|
|
768
|
+
ptr_loc = self.next_arg(self.ArgSession(self), SimTypePointer(SimTypeBottom()).with_arch(self.arch))
|
|
769
|
+
return SimReferenceArgument(
|
|
770
|
+
ptr_loc, SimStackArg(0, ty.size // self.arch.byte_width, is_fp=isinstance(ty, SimTypeFloat))
|
|
771
|
+
)
|
|
772
|
+
|
|
773
|
+
if isinstance(ty, SimTypeFloat) and self.FP_RETURN_VAL is not None:
|
|
774
|
+
return self.FP_RETURN_VAL.refine(size=ty.size // self.arch.byte_width, arch=self.arch, is_fp=True)
|
|
775
|
+
|
|
776
|
+
if self.RETURN_VAL is None or isinstance(ty, SimTypeBottom):
|
|
777
|
+
return None
|
|
778
|
+
if ty.size > self.RETURN_VAL.size * self.arch.byte_width:
|
|
779
|
+
assert self.OVERFLOW_RETURN_VAL is not None
|
|
780
|
+
return SimComboArg([self.RETURN_VAL, self.OVERFLOW_RETURN_VAL])
|
|
781
|
+
return self.RETURN_VAL.refine(size=ty.size // self.arch.byte_width, arch=self.arch, is_fp=False)
|
|
782
|
+
|
|
783
|
+
@property
|
|
784
|
+
def return_addr(self):
|
|
785
|
+
"""
|
|
786
|
+
The location the return address is stored.
|
|
787
|
+
"""
|
|
788
|
+
return self.RETURN_ADDR
|
|
789
|
+
|
|
790
|
+
def next_arg(self, session: ArgSession, arg_type: SimType) -> SimFunctionArgument:
|
|
791
|
+
if isinstance(arg_type, (SimTypeArray, SimTypeFixedSizeArray)): # hack
|
|
792
|
+
arg_type = SimTypePointer(arg_type.elem_type).with_arch(self.arch)
|
|
793
|
+
if isinstance(arg_type, (SimStruct, SimUnion, SimTypeFixedSizeArray)):
|
|
794
|
+
raise TypeError(
|
|
795
|
+
f"{self} doesn't know how to store aggregate type {type(arg_type)}. Consider overriding next_arg to "
|
|
796
|
+
"implement its ABI logic"
|
|
797
|
+
)
|
|
798
|
+
if isinstance(arg_type, SimTypeBottom):
|
|
799
|
+
# This is usually caused by failures or mistakes during type inference
|
|
800
|
+
l.warning("Function argument type cannot be BOT. Treating it as a 32-bit int.")
|
|
801
|
+
arg_type = SimTypeInt().with_arch(self.arch)
|
|
802
|
+
is_fp = isinstance(arg_type, SimTypeFloat)
|
|
803
|
+
assert arg_type.size is not None
|
|
804
|
+
size = arg_type.size // self.arch.byte_width
|
|
805
|
+
try:
|
|
806
|
+
arg = next(session.fp_iter) if is_fp else next(session.int_iter)
|
|
807
|
+
except StopIteration:
|
|
808
|
+
try:
|
|
809
|
+
arg = next(session.both_iter)
|
|
810
|
+
except StopIteration as err:
|
|
811
|
+
raise TypeError("Accessed too many arguments - exhausted all positions?") from err
|
|
812
|
+
|
|
813
|
+
if size > arg.size:
|
|
814
|
+
if isinstance(arg, SimStackArg):
|
|
815
|
+
arg_size = arg.size
|
|
816
|
+
locations = [arg]
|
|
817
|
+
while arg_size < size:
|
|
818
|
+
next_arg = next(session.both_iter)
|
|
819
|
+
arg_size += next_arg.size
|
|
820
|
+
locations.append(next_arg)
|
|
821
|
+
return SimComboArg(locations, is_fp=is_fp)
|
|
822
|
+
raise ValueError(
|
|
823
|
+
f"{self} doesn't know how to store large types. Consider overriding"
|
|
824
|
+
" next_arg to implement its ABI logic"
|
|
825
|
+
)
|
|
826
|
+
return arg.refine(size, is_fp=is_fp, arch=self.arch)
|
|
827
|
+
|
|
828
|
+
#
|
|
829
|
+
# Useful functions!
|
|
830
|
+
#
|
|
831
|
+
|
|
832
|
+
@staticmethod
|
|
833
|
+
def is_fp_value(val):
|
|
834
|
+
return (
|
|
835
|
+
isinstance(val, (float, claripy.ast.FP))
|
|
836
|
+
or (isinstance(val, claripy.ast.Base) and val.op.startswith("fp")) # type: ignore
|
|
837
|
+
or (
|
|
838
|
+
isinstance(val, claripy.ast.Base)
|
|
839
|
+
and val.op == "Reverse" # type:ignore
|
|
840
|
+
and val.args[0].op.startswith("fp") # type:ignore
|
|
841
|
+
)
|
|
842
|
+
)
|
|
843
|
+
|
|
844
|
+
@staticmethod
|
|
845
|
+
def guess_prototype(args, prototype=None):
|
|
846
|
+
"""
|
|
847
|
+
Come up with a plausible SimTypeFunction for the given args (as would be passed to e.g. setup_callsite).
|
|
848
|
+
|
|
849
|
+
You can pass a variadic function prototype in the `base_type` parameter and all its arguments will be used,
|
|
850
|
+
only guessing types for the variadic arguments.
|
|
851
|
+
"""
|
|
852
|
+
if type(prototype) is str:
|
|
853
|
+
prototype = parse_signature(prototype)
|
|
854
|
+
elif prototype is None:
|
|
855
|
+
l.warning("Guessing call prototype. Please specify prototype.")
|
|
856
|
+
|
|
857
|
+
charp = SimTypePointer(SimTypeChar())
|
|
858
|
+
result = prototype if prototype is not None else SimTypeFunction([], charp)
|
|
859
|
+
for arg in args[len(result.args) :]:
|
|
860
|
+
if type(arg) in (int, bytes, PointerWrapper):
|
|
861
|
+
result.args += (charp,)
|
|
862
|
+
elif type(arg) is float:
|
|
863
|
+
result.args += (SimTypeDouble(),)
|
|
864
|
+
elif isinstance(arg, claripy.ast.BV):
|
|
865
|
+
result.args += (SimTypeNum(len(arg), False),)
|
|
866
|
+
elif isinstance(arg, claripy.ast.FP):
|
|
867
|
+
if arg.sort == claripy.FSORT_FLOAT:
|
|
868
|
+
result.args += (SimTypeFloat(),)
|
|
869
|
+
elif arg.sort == claripy.FSORT_DOUBLE:
|
|
870
|
+
result.args += (SimTypeDouble(),)
|
|
871
|
+
else:
|
|
872
|
+
raise TypeError("WHAT kind of floating point is this")
|
|
873
|
+
else:
|
|
874
|
+
raise TypeError(f"Cannot guess FFI type for {type(arg)}")
|
|
875
|
+
|
|
876
|
+
return result
|
|
877
|
+
|
|
878
|
+
def arg_locs(self, prototype) -> list[SimFunctionArgument]:
|
|
879
|
+
if prototype._arch is None:
|
|
880
|
+
prototype = prototype.with_arch(self.arch)
|
|
881
|
+
session = self.arg_session(prototype.returnty)
|
|
882
|
+
return [self.next_arg(session, arg_ty) for arg_ty in prototype.args]
|
|
883
|
+
|
|
884
|
+
def get_args(self, state, prototype, stack_base=None):
|
|
885
|
+
arg_locs = self.arg_locs(prototype)
|
|
886
|
+
return [loc.get_value(state, stack_base=stack_base) for loc in arg_locs]
|
|
887
|
+
|
|
888
|
+
def set_return_val(self, state, val, ty, stack_base=None, perspective_returned=False):
|
|
889
|
+
loc = self.return_val(ty, perspective_returned=perspective_returned)
|
|
890
|
+
if loc is None:
|
|
891
|
+
raise ValueError("Cannot set return value - there is no return value location")
|
|
892
|
+
loc.set_value(state, val, stack_base=stack_base)
|
|
893
|
+
|
|
894
|
+
def setup_callsite(self, state, ret_addr, args, prototype, stack_base=None, alloc_base=None, grow_like_stack=True):
|
|
895
|
+
"""
|
|
896
|
+
This function performs the actions of the caller getting ready to jump into a function.
|
|
897
|
+
|
|
898
|
+
:param state: The SimState to operate on
|
|
899
|
+
:param ret_addr: The address to return to when the called function finishes
|
|
900
|
+
:param args: The list of arguments that that the called function will see
|
|
901
|
+
:param prototype: The signature of the call you're making. Should include variadic args concretely.
|
|
902
|
+
:param stack_base: An optional pointer to use as the top of the stack, circa the function entry point
|
|
903
|
+
:param alloc_base: An optional pointer to use as the place to put excess argument data
|
|
904
|
+
:param grow_like_stack: When allocating data at alloc_base, whether to allocate at decreasing addresses
|
|
905
|
+
|
|
906
|
+
The idea here is that you can provide almost any kind of python type in `args` and it'll be translated to a
|
|
907
|
+
binary format to be placed into simulated memory. Lists (representing arrays) must be entirely elements of the
|
|
908
|
+
same type and size, while tuples (representing structs) can be elements of any type and size.
|
|
909
|
+
If you'd like there to be a pointer to a given value, wrap the value in a `PointerWrapper`.
|
|
910
|
+
|
|
911
|
+
If stack_base is not provided, the current stack pointer will be used, and it will be updated.
|
|
912
|
+
If alloc_base is not provided, the stack base will be used and grow_like_stack will implicitly be True.
|
|
913
|
+
|
|
914
|
+
grow_like_stack controls the behavior of allocating data at alloc_base. When data from args needs to be wrapped
|
|
915
|
+
in a pointer, the pointer needs to point somewhere, so that data is dumped into memory at alloc_base. If you
|
|
916
|
+
set alloc_base to point to somewhere other than the stack, set grow_like_stack to False so that sequential
|
|
917
|
+
allocations happen at increasing addresses.
|
|
918
|
+
"""
|
|
919
|
+
|
|
920
|
+
# STEP 0: clerical work
|
|
921
|
+
|
|
922
|
+
allocator = AllocHelper(self.arch.bits)
|
|
923
|
+
if type(prototype) is str:
|
|
924
|
+
prototype = parse_signature(prototype, arch=self.arch)
|
|
925
|
+
elif prototype._arch is None:
|
|
926
|
+
prototype = prototype.with_arch(self.arch)
|
|
927
|
+
|
|
928
|
+
#
|
|
929
|
+
# STEP 1: convert all values into serialized form
|
|
930
|
+
# this entails creating the vals list of simple values to store and also populating the allocator's
|
|
931
|
+
# understanding of what aux data needs to be stored
|
|
932
|
+
# This is also where we compute arg locations (arg_locs)
|
|
933
|
+
#
|
|
934
|
+
|
|
935
|
+
vals = [self._standardize_value(arg, ty, state, allocator.dump) for arg, ty in zip(args, prototype.args)]
|
|
936
|
+
arg_locs = self.arg_locs(prototype)
|
|
937
|
+
|
|
938
|
+
# step 1.5, gotta handle the SimReferenceArguments correctly
|
|
939
|
+
for i, (loc, val) in enumerate(zip(arg_locs, vals)):
|
|
940
|
+
if not isinstance(loc, SimReferenceArgument):
|
|
941
|
+
continue
|
|
942
|
+
dumped = allocator.dump(val, state, loc=val.main_loc)
|
|
943
|
+
vals[i] = dumped
|
|
944
|
+
arg_locs[i] = val.ptr_loc
|
|
945
|
+
|
|
946
|
+
# step 1.75 allocate implicit outparam stuff
|
|
947
|
+
if self.return_in_implicit_outparam(prototype.returnty):
|
|
948
|
+
loc = self.return_val(prototype.returnty)
|
|
949
|
+
assert isinstance(loc, SimReferenceArgument)
|
|
950
|
+
# hack: because the allocator gives us a pointer that needs to be translated, we need to shove it into
|
|
951
|
+
# the args list so it'll be translated and stored once everything is laid out
|
|
952
|
+
vals.append(allocator.alloc(loc.main_loc.size))
|
|
953
|
+
arg_locs.append(loc.ptr_loc)
|
|
954
|
+
|
|
955
|
+
#
|
|
956
|
+
# STEP 2: decide on memory storage locations
|
|
957
|
+
# implement the contract for stack_base/alloc_base/grow_like_stack
|
|
958
|
+
# after this, stack_base should be the final stack pointer, alloc_base should be the final aux storage location,
|
|
959
|
+
# and the stack pointer should be updated
|
|
960
|
+
#
|
|
961
|
+
|
|
962
|
+
if stack_base is None:
|
|
963
|
+
if alloc_base is None:
|
|
964
|
+
alloc_size = allocator.size()
|
|
965
|
+
state.regs.sp -= alloc_size
|
|
966
|
+
alloc_base = state.regs.sp
|
|
967
|
+
grow_like_stack = False
|
|
968
|
+
|
|
969
|
+
state.regs.sp -= self.stack_space(arg_locs)
|
|
970
|
+
|
|
971
|
+
# handle alignment
|
|
972
|
+
alignment = (state.regs.sp + self.STACKARG_SP_DIFF) % self.STACK_ALIGNMENT
|
|
973
|
+
state.regs.sp -= alignment
|
|
974
|
+
|
|
975
|
+
else:
|
|
976
|
+
state.regs.sp = stack_base
|
|
977
|
+
|
|
978
|
+
if alloc_base is None:
|
|
979
|
+
alloc_base = stack_base + self.stack_space(arg_locs)
|
|
980
|
+
grow_like_stack = False
|
|
981
|
+
|
|
982
|
+
if grow_like_stack:
|
|
983
|
+
alloc_base -= allocator.size()
|
|
984
|
+
if type(alloc_base) is int:
|
|
985
|
+
alloc_base = claripy.BVV(alloc_base, state.arch.bits)
|
|
986
|
+
|
|
987
|
+
for i, val in enumerate(vals):
|
|
988
|
+
vals[i] = allocator.translate(val, alloc_base)
|
|
989
|
+
|
|
990
|
+
#
|
|
991
|
+
# STEP 3: store everything!
|
|
992
|
+
#
|
|
993
|
+
|
|
994
|
+
allocator.apply(state, alloc_base)
|
|
995
|
+
|
|
996
|
+
for loc, val in zip(arg_locs, vals):
|
|
997
|
+
assert loc is not None
|
|
998
|
+
loc.set_value(state, val, stack_base=stack_base)
|
|
999
|
+
if self.return_addr is not None:
|
|
1000
|
+
self.return_addr.set_value(state, ret_addr, stack_base=stack_base)
|
|
1001
|
+
|
|
1002
|
+
def teardown_callsite(self, state, return_val=None, prototype=None, force_callee_cleanup=False):
|
|
1003
|
+
"""
|
|
1004
|
+
This function performs the actions of the callee as it's getting ready to return.
|
|
1005
|
+
It returns the address to return to.
|
|
1006
|
+
|
|
1007
|
+
:param state: The state to mutate
|
|
1008
|
+
:param return_val: The value to return
|
|
1009
|
+
:param prototype: The prototype of the given function
|
|
1010
|
+
:param force_callee_cleanup: If we should clean up the stack allocation for the arguments even if it's not
|
|
1011
|
+
the callee's job to do so
|
|
1012
|
+
|
|
1013
|
+
TODO: support the stack_base parameter from setup_callsite...? Does that make sense in this context?
|
|
1014
|
+
Maybe it could make sense by saying that you pass it in as something like the "saved base pointer" value?
|
|
1015
|
+
"""
|
|
1016
|
+
if return_val is not None and prototype is not None and not isinstance(prototype.returnty, SimTypeBottom):
|
|
1017
|
+
self.set_return_val(state, return_val, prototype.returnty)
|
|
1018
|
+
# ummmmmmmm hack
|
|
1019
|
+
loc = self.return_val(prototype.returnty)
|
|
1020
|
+
if self.RETURN_VAL is not None and isinstance(loc, SimReferenceArgument):
|
|
1021
|
+
self.RETURN_VAL.set_value(state, loc.ptr_loc.get_value(state))
|
|
1022
|
+
|
|
1023
|
+
ret_addr = self.return_addr.get_value(state) if self.return_addr is not None else None
|
|
1024
|
+
|
|
1025
|
+
if state.arch.sp_offset is not None and prototype is not None:
|
|
1026
|
+
if force_callee_cleanup or self.CALLEE_CLEANUP:
|
|
1027
|
+
session = self.arg_session(prototype.returnty)
|
|
1028
|
+
if self.return_in_implicit_outparam(prototype.returnty):
|
|
1029
|
+
extra = [cast(SimReferenceArgument, self.return_val(prototype.returnty)).ptr_loc]
|
|
1030
|
+
else:
|
|
1031
|
+
extra = []
|
|
1032
|
+
state.regs.sp += self.stack_space(extra + [self.next_arg(session, x) for x in prototype.args])
|
|
1033
|
+
else:
|
|
1034
|
+
state.regs.sp += self.STACKARG_SP_DIFF
|
|
1035
|
+
|
|
1036
|
+
return ret_addr
|
|
1037
|
+
|
|
1038
|
+
#
|
|
1039
|
+
# Helper functions
|
|
1040
|
+
#
|
|
1041
|
+
|
|
1042
|
+
@staticmethod
|
|
1043
|
+
def _standardize_value(arg, ty, state, alloc):
|
|
1044
|
+
if isinstance(arg, SimActionObject):
|
|
1045
|
+
return SimCC._standardize_value(arg.ast, ty, state, alloc)
|
|
1046
|
+
if isinstance(arg, PointerWrapper):
|
|
1047
|
+
if not isinstance(ty, (SimTypePointer, SimTypeReference)):
|
|
1048
|
+
raise TypeError(f"Type mismatch: expected {ty}, got pointer-wrapper")
|
|
1049
|
+
|
|
1050
|
+
if arg.buffer:
|
|
1051
|
+
if isinstance(arg.value, claripy.ast.Bits):
|
|
1052
|
+
real_value = arg.value.chop(state.arch.byte_width) # type:ignore
|
|
1053
|
+
elif type(arg.value) in (bytes, str):
|
|
1054
|
+
real_value = claripy.BVV(arg.value).chop(8)
|
|
1055
|
+
else:
|
|
1056
|
+
raise TypeError("PointerWrapper(buffer=True) can only be used with a bitvector or a bytestring")
|
|
1057
|
+
else:
|
|
1058
|
+
sub = ty.pts_to if isinstance(ty, SimTypePointer) else ty.refs
|
|
1059
|
+
child_type = SimTypeArray(sub) if isinstance(arg.value, (str, bytes, list)) else sub
|
|
1060
|
+
try:
|
|
1061
|
+
real_value = SimCC._standardize_value(arg.value, child_type, state, alloc)
|
|
1062
|
+
except TypeError as e: # this is a dangerous catch...
|
|
1063
|
+
raise TypeError(
|
|
1064
|
+
f"Failed to store pointer-wrapped data ({e.args[0]}). "
|
|
1065
|
+
"Do you want a PointerWrapper(buffer=True)?"
|
|
1066
|
+
) from None
|
|
1067
|
+
return alloc(real_value, state)
|
|
1068
|
+
|
|
1069
|
+
if isinstance(arg, (str, bytes)):
|
|
1070
|
+
# sanitize the argument and request standardization again with SimTypeArray
|
|
1071
|
+
if isinstance(arg, str):
|
|
1072
|
+
arg = arg.encode()
|
|
1073
|
+
arg += b"\0"
|
|
1074
|
+
if isinstance(ty, SimTypePointer) and isinstance(ty.pts_to, SimTypeChar):
|
|
1075
|
+
pass
|
|
1076
|
+
elif (isinstance(ty, SimTypeFixedSizeArray) and isinstance(ty.elem_type, SimTypeChar)) or (
|
|
1077
|
+
isinstance(ty, SimTypeArray) and isinstance(ty.elem_type, SimTypeChar)
|
|
1078
|
+
):
|
|
1079
|
+
if ty.length is not None:
|
|
1080
|
+
if len(arg) > ty.length:
|
|
1081
|
+
raise TypeError(f"String {arg!r} is too long for {ty}")
|
|
1082
|
+
arg = arg.ljust(ty.length, b"\0")
|
|
1083
|
+
elif isinstance(ty, SimTypeString):
|
|
1084
|
+
if ty.length is not None:
|
|
1085
|
+
if len(arg) > ty.length + 1:
|
|
1086
|
+
raise TypeError(f"String {arg!r} is too long for {ty}")
|
|
1087
|
+
arg = arg.ljust(ty.length + 1, b"\0")
|
|
1088
|
+
else:
|
|
1089
|
+
raise TypeError(f"Type mismatch: Expected {ty}, got char*")
|
|
1090
|
+
return SimCC._standardize_value(list(arg), SimTypeArray(SimTypeChar(), len(arg)), state, alloc)
|
|
1091
|
+
|
|
1092
|
+
if isinstance(arg, list):
|
|
1093
|
+
if isinstance(ty, SimTypePointer):
|
|
1094
|
+
ref = True
|
|
1095
|
+
subty = ty.pts_to
|
|
1096
|
+
elif isinstance(ty, SimTypeReference):
|
|
1097
|
+
ref = True
|
|
1098
|
+
subty = ty.refs
|
|
1099
|
+
elif isinstance(ty, SimTypeArray):
|
|
1100
|
+
ref = True
|
|
1101
|
+
subty = ty.elem_type
|
|
1102
|
+
if ty.length is not None and len(arg) != ty.length:
|
|
1103
|
+
raise TypeError(f"Array {arg!r} is the wrong length for {ty}")
|
|
1104
|
+
else:
|
|
1105
|
+
raise TypeError(f"Type mismatch: Expected {ty}, got char*")
|
|
1106
|
+
|
|
1107
|
+
val = [SimCC._standardize_value(sarg, subty, state, alloc) for sarg in arg]
|
|
1108
|
+
if ref:
|
|
1109
|
+
val = alloc(val, state)
|
|
1110
|
+
return val
|
|
1111
|
+
|
|
1112
|
+
if isinstance(arg, (tuple, dict, SimStructValue)):
|
|
1113
|
+
if not isinstance(ty, SimStruct):
|
|
1114
|
+
raise TypeError(f"Type mismatch: Expected {ty}, got {type(arg)} (i.e. struct)")
|
|
1115
|
+
if not isinstance(arg, SimStructValue):
|
|
1116
|
+
if len(arg) != len(ty.fields):
|
|
1117
|
+
raise TypeError(f"Wrong number of fields in struct, expected {len(ty.fields)} got {len(arg)}")
|
|
1118
|
+
arg = SimStructValue(ty, arg)
|
|
1119
|
+
return SimStructValue(
|
|
1120
|
+
ty, [SimCC._standardize_value(arg[field], ty.fields[field], state, alloc) for field in ty.fields]
|
|
1121
|
+
)
|
|
1122
|
+
|
|
1123
|
+
if isinstance(arg, int):
|
|
1124
|
+
if isinstance(ty, SimTypeFloat):
|
|
1125
|
+
return SimCC._standardize_value(float(arg), ty, state, alloc)
|
|
1126
|
+
|
|
1127
|
+
return claripy.BVV(arg, ty.size)
|
|
1128
|
+
|
|
1129
|
+
if isinstance(arg, float):
|
|
1130
|
+
if isinstance(ty, SimTypeDouble):
|
|
1131
|
+
sort = claripy.FSORT_DOUBLE
|
|
1132
|
+
elif isinstance(ty, SimTypeFloat):
|
|
1133
|
+
sort = claripy.FSORT_FLOAT
|
|
1134
|
+
else:
|
|
1135
|
+
raise TypeError(f"Type mismatch: expected {ty}, got float")
|
|
1136
|
+
|
|
1137
|
+
return claripy.FPV(arg, sort)
|
|
1138
|
+
|
|
1139
|
+
if isinstance(arg, claripy.ast.FP):
|
|
1140
|
+
if isinstance(ty, SimTypeFloat):
|
|
1141
|
+
if len(arg) != ty.size:
|
|
1142
|
+
raise TypeError(f"Type mismatch: expected {ty}, got {arg.sort}")
|
|
1143
|
+
return arg
|
|
1144
|
+
if isinstance(ty, (SimTypeReg, SimTypeNum)):
|
|
1145
|
+
return arg.val_to_bv(ty.size, ty.signed if isinstance(ty, SimTypeNum) else False)
|
|
1146
|
+
raise TypeError(f"Type mismatch: expected {ty}, got {arg.sort}")
|
|
1147
|
+
|
|
1148
|
+
if isinstance(arg, claripy.ast.BV):
|
|
1149
|
+
if isinstance(ty, (SimTypeReg, SimTypeNum)):
|
|
1150
|
+
if len(arg) != ty.size:
|
|
1151
|
+
if arg.concrete:
|
|
1152
|
+
size = ty.size
|
|
1153
|
+
assert size is not None
|
|
1154
|
+
return claripy.BVV(arg.concrete_value, size)
|
|
1155
|
+
raise TypeError(f"Type mismatch of symbolic data: expected {ty}, got {len(arg)} bits")
|
|
1156
|
+
return arg
|
|
1157
|
+
if isinstance(ty, (SimTypeFloat)):
|
|
1158
|
+
raise TypeError(
|
|
1159
|
+
"It's unclear how to coerce a bitvector to %s. "
|
|
1160
|
+
"Do you want .raw_to_fp or .val_to_fp, and signed or unsigned?"
|
|
1161
|
+
)
|
|
1162
|
+
raise TypeError(f"Type mismatch: expected {ty}, got bitvector")
|
|
1163
|
+
|
|
1164
|
+
raise TypeError(f"I don't know how to serialize {arg!r}.")
|
|
1165
|
+
|
|
1166
|
+
def __repr__(self):
|
|
1167
|
+
return f"<{self.__class__.__name__}>"
|
|
1168
|
+
|
|
1169
|
+
def __eq__(self, other):
|
|
1170
|
+
return isinstance(other, self.__class__)
|
|
1171
|
+
|
|
1172
|
+
@classmethod
|
|
1173
|
+
def _match(cls, arch, args: list[SimRegArg | SimStackArg], sp_delta):
|
|
1174
|
+
if (
|
|
1175
|
+
cls.arches() is not None and ":" not in arch.name and not isinstance(arch, cls.arches())
|
|
1176
|
+
): # pylint:disable=isinstance-second-argument-not-valid-type
|
|
1177
|
+
return False
|
|
1178
|
+
if sp_delta != cls.STACKARG_SP_DIFF:
|
|
1179
|
+
return False
|
|
1180
|
+
|
|
1181
|
+
def _arg_ident(a: SimRegArg | SimStackArg) -> int | str:
|
|
1182
|
+
if isinstance(a, SimRegArg):
|
|
1183
|
+
return a.reg_name
|
|
1184
|
+
return a.stack_offset
|
|
1185
|
+
|
|
1186
|
+
sample_inst = cls(arch)
|
|
1187
|
+
all_fp_args: set[int | str] = {_arg_ident(a) for a in sample_inst.fp_args}
|
|
1188
|
+
all_int_args: set[int | str] = {_arg_ident(a) for a in sample_inst.int_args}
|
|
1189
|
+
both_iter = sample_inst.memory_args
|
|
1190
|
+
max_args = cls._guess_arg_count(args)
|
|
1191
|
+
some_both_args: set[int | str] = {_arg_ident(next(both_iter)) for _ in range(max_args)}
|
|
1192
|
+
|
|
1193
|
+
new_args = []
|
|
1194
|
+
for arg in args:
|
|
1195
|
+
arg_ident = _arg_ident(arg)
|
|
1196
|
+
if arg_ident not in all_fp_args and arg_ident not in all_int_args and arg_ident not in some_both_args:
|
|
1197
|
+
if isinstance(arg, SimRegArg) and arg.reg_name in sample_inst.CALLER_SAVED_REGS:
|
|
1198
|
+
continue
|
|
1199
|
+
return False
|
|
1200
|
+
new_args.append(arg)
|
|
1201
|
+
|
|
1202
|
+
# update args (e.g., drop caller-saved register arguments)
|
|
1203
|
+
args.clear()
|
|
1204
|
+
args.extend(new_args)
|
|
1205
|
+
|
|
1206
|
+
return True
|
|
1207
|
+
|
|
1208
|
+
@classmethod
|
|
1209
|
+
def _guess_arg_count(cls, args, limit: int = 64) -> int:
|
|
1210
|
+
# pylint:disable=not-callable
|
|
1211
|
+
assert cls.ARCH is not None
|
|
1212
|
+
if hasattr(cls, "LANGUAGE"): # noqa: SIM108
|
|
1213
|
+
# this is a PCode SimCC where cls.ARCH is directly callable
|
|
1214
|
+
stack_arg_size = cls.ARCH().bytes # type:ignore
|
|
1215
|
+
else:
|
|
1216
|
+
stack_arg_size = cls.ARCH(archinfo.Endness.LE).bytes
|
|
1217
|
+
stack_args = [a for a in args if isinstance(a, SimStackArg)]
|
|
1218
|
+
stack_arg_count = (max(a.stack_offset for a in stack_args) // stack_arg_size + 1) if stack_args else 0
|
|
1219
|
+
return min(limit, max(len(args), stack_arg_count))
|
|
1220
|
+
|
|
1221
|
+
@staticmethod
|
|
1222
|
+
def find_cc(
|
|
1223
|
+
arch: archinfo.Arch, args: list[SimRegArg | SimStackArg], sp_delta: int, platform: str | None = "Linux"
|
|
1224
|
+
) -> SimCC | None:
|
|
1225
|
+
"""
|
|
1226
|
+
Pinpoint the best-fit calling convention and return the corresponding SimCC instance, or None if no fit is
|
|
1227
|
+
found.
|
|
1228
|
+
|
|
1229
|
+
:param arch: An ArchX instance. Can be obtained from archinfo.
|
|
1230
|
+
:param args: A list of arguments. It may be updated by the first matched calling convention to
|
|
1231
|
+
remove non-argument arguments.
|
|
1232
|
+
:param sp_delta: The change of stack pointer before and after the call is made.
|
|
1233
|
+
:return: A calling convention instance, or None if none of the SimCC subclasses seems to fit the
|
|
1234
|
+
arguments provided.
|
|
1235
|
+
"""
|
|
1236
|
+
if arch.name not in CC:
|
|
1237
|
+
return None
|
|
1238
|
+
if platform not in CC[arch.name]:
|
|
1239
|
+
# fallback to default
|
|
1240
|
+
platform = "default"
|
|
1241
|
+
possible_cc_classes = CC[arch.name][platform]
|
|
1242
|
+
for cc_cls in possible_cc_classes:
|
|
1243
|
+
if cc_cls._match(arch, args, sp_delta):
|
|
1244
|
+
return cc_cls(arch)
|
|
1245
|
+
return None
|
|
1246
|
+
|
|
1247
|
+
@classmethod
|
|
1248
|
+
def arches(cls) -> tuple[type[archinfo.Arch], ...]:
|
|
1249
|
+
if cls.ARCH is not None:
|
|
1250
|
+
return (cls.ARCH, *cls.EXTRA_ARCHES)
|
|
1251
|
+
return cls.EXTRA_ARCHES
|
|
1252
|
+
|
|
1253
|
+
def get_arg_info(self, state, prototype):
|
|
1254
|
+
"""
|
|
1255
|
+
This is just a simple wrapper that collects the information from various locations
|
|
1256
|
+
prototype is as passed to self.arg_locs and self.get_args
|
|
1257
|
+
:param angr.SimState state: The state to evaluate and extract the values from
|
|
1258
|
+
:return: A list of tuples, where the nth tuple is (type, name, location, value) of the nth argument
|
|
1259
|
+
"""
|
|
1260
|
+
|
|
1261
|
+
argument_locations = self.arg_locs(prototype)
|
|
1262
|
+
argument_values = self.get_args(state, prototype)
|
|
1263
|
+
|
|
1264
|
+
argument_types = prototype.args
|
|
1265
|
+
argument_names = prototype.arg_names if prototype.arg_names else ["unknown"] * len(prototype.args)
|
|
1266
|
+
return list(zip(argument_types, argument_names, argument_locations, argument_values))
|
|
1267
|
+
|
|
1268
|
+
|
|
1269
|
+
class SimLyingRegArg(SimRegArg):
|
|
1270
|
+
"""
|
|
1271
|
+
A register that LIES about the types it holds
|
|
1272
|
+
"""
|
|
1273
|
+
|
|
1274
|
+
def __init__(self, name, size=8):
|
|
1275
|
+
super().__init__(name, 8)
|
|
1276
|
+
self._real_size = size
|
|
1277
|
+
|
|
1278
|
+
def get_value(self, state, **kwargs): # pylint:disable=arguments-differ
|
|
1279
|
+
# val = super(SimLyingRegArg, self).get_value(state, **kwargs)
|
|
1280
|
+
val = state.registers.load(self.reg_name).raw_to_fp()
|
|
1281
|
+
if self._real_size == 4:
|
|
1282
|
+
val = claripy.fpToFP(claripy.fp.RM.RM_NearestTiesEven, val.raw_to_fp(), claripy.FSORT_FLOAT) # type:ignore
|
|
1283
|
+
return val
|
|
1284
|
+
|
|
1285
|
+
def set_value(self, state, value, **kwargs): # pylint:disable=arguments-differ,unused-argument
|
|
1286
|
+
value = self.check_value_set(value, state.arch)
|
|
1287
|
+
if self._real_size == 4:
|
|
1288
|
+
value = claripy.fpToFP(
|
|
1289
|
+
claripy.fp.RM.RM_NearestTiesEven, value.raw_to_fp(), claripy.FSORT_DOUBLE # type:ignore
|
|
1290
|
+
)
|
|
1291
|
+
state.registers.store(self.reg_name, value)
|
|
1292
|
+
# super(SimLyingRegArg, self).set_value(state, value, endness=endness, **kwargs)
|
|
1293
|
+
|
|
1294
|
+
def refine(self, size, arch=None, offset=None, is_fp=None):
|
|
1295
|
+
return SimLyingRegArg(self.reg_name, size)
|
|
1296
|
+
|
|
1297
|
+
|
|
1298
|
+
class SimCCUsercall(SimCC):
|
|
1299
|
+
def __init__(self, arch, args, ret_loc):
|
|
1300
|
+
super().__init__(arch)
|
|
1301
|
+
self.args = args
|
|
1302
|
+
self.ret_loc = ret_loc
|
|
1303
|
+
|
|
1304
|
+
ArgSession = UsercallArgSession
|
|
1305
|
+
|
|
1306
|
+
def next_arg(self, session: UsercallArgSession, arg_type): # type:ignore[reportIncompatibleMethodOverride]
|
|
1307
|
+
return next(session.real_args)
|
|
1308
|
+
|
|
1309
|
+
def return_val(self, ty, **kwargs): # type:ignore # pylint: disable=unused-argument
|
|
1310
|
+
return self.ret_loc
|
|
1311
|
+
|
|
1312
|
+
|
|
1313
|
+
class SimCCCdecl(SimCC):
|
|
1314
|
+
ARG_REGS = [] # All arguments are passed in stack
|
|
1315
|
+
FP_ARG_REGS = []
|
|
1316
|
+
STACKARG_SP_DIFF = 4 # Return address is pushed on to stack by call
|
|
1317
|
+
CALLER_SAVED_REGS = ["eax", "ecx", "edx"]
|
|
1318
|
+
RETURN_VAL = SimRegArg("eax", 4)
|
|
1319
|
+
OVERFLOW_RETURN_VAL = SimRegArg("edx", 4)
|
|
1320
|
+
FP_RETURN_VAL = SimLyingRegArg("st0")
|
|
1321
|
+
RETURN_ADDR = SimStackArg(0, 4)
|
|
1322
|
+
ARCH = archinfo.ArchX86
|
|
1323
|
+
|
|
1324
|
+
def next_arg(self, session, arg_type):
|
|
1325
|
+
if isinstance(arg_type, (SimTypeArray, SimTypeFixedSizeArray)): # hack
|
|
1326
|
+
arg_type = SimTypePointer(arg_type.elem_type).with_arch(self.arch)
|
|
1327
|
+
locs_size = 0
|
|
1328
|
+
byte_size = arg_type.size // self.arch.byte_width if arg_type.size is not None else self.arch.bytes
|
|
1329
|
+
locs = []
|
|
1330
|
+
while locs_size < byte_size:
|
|
1331
|
+
locs.append(next(session.both_iter))
|
|
1332
|
+
locs_size += locs[-1].size
|
|
1333
|
+
|
|
1334
|
+
return refine_locs_with_struct_type(self.arch, locs, arg_type)
|
|
1335
|
+
|
|
1336
|
+
STRUCT_RETURN_THRESHOLD = 32
|
|
1337
|
+
|
|
1338
|
+
def return_val(self, ty, perspective_returned=False):
|
|
1339
|
+
if ty._arch is None:
|
|
1340
|
+
ty = ty.with_arch(self.arch)
|
|
1341
|
+
if not isinstance(ty, SimStruct):
|
|
1342
|
+
return super().return_val(ty, perspective_returned)
|
|
1343
|
+
|
|
1344
|
+
if ty.size > self.STRUCT_RETURN_THRESHOLD:
|
|
1345
|
+
# TODO this code is duplicated a ton of places. how should it be a function?
|
|
1346
|
+
byte_size = ty.size // self.arch.byte_width
|
|
1347
|
+
referenced_locs = [SimStackArg(offset, self.arch.bytes) for offset in range(0, byte_size, self.arch.bytes)]
|
|
1348
|
+
referenced_loc = refine_locs_with_struct_type(self.arch, referenced_locs, ty)
|
|
1349
|
+
ptr_loc = self.RETURN_VAL if perspective_returned else SimStackArg(0, 4)
|
|
1350
|
+
assert ptr_loc is not None
|
|
1351
|
+
return SimReferenceArgument(ptr_loc, referenced_loc)
|
|
1352
|
+
|
|
1353
|
+
return refine_locs_with_struct_type(self.arch, [self.RETURN_VAL, self.OVERFLOW_RETURN_VAL], ty)
|
|
1354
|
+
|
|
1355
|
+
def return_in_implicit_outparam(self, ty):
|
|
1356
|
+
if isinstance(ty, SimTypeBottom):
|
|
1357
|
+
return False
|
|
1358
|
+
return isinstance(ty, SimStruct) and ty.size > self.STRUCT_RETURN_THRESHOLD
|
|
1359
|
+
|
|
1360
|
+
|
|
1361
|
+
class SimCCMicrosoftCdecl(SimCCCdecl):
|
|
1362
|
+
STRUCT_RETURN_THRESHOLD = 64
|
|
1363
|
+
|
|
1364
|
+
|
|
1365
|
+
class SimCCMicrosoftThiscall(SimCCCdecl):
|
|
1366
|
+
CALLEE_CLEANUP = True
|
|
1367
|
+
ARG_REGS = ["ecx"]
|
|
1368
|
+
CALLER_SAVED_REGS = ["eax", "ecx", "edx"]
|
|
1369
|
+
STRUCT_RETURN_THRESHOLD = 64
|
|
1370
|
+
|
|
1371
|
+
def arg_locs(self, prototype) -> list[SimFunctionArgument]:
|
|
1372
|
+
if prototype._arch is None:
|
|
1373
|
+
prototype = prototype.with_arch(self.arch)
|
|
1374
|
+
session = self.arg_session(prototype.returnty)
|
|
1375
|
+
if not prototype.args:
|
|
1376
|
+
return []
|
|
1377
|
+
return [SimRegArg("ecx", self.arch.bytes)] + [
|
|
1378
|
+
self.next_arg(session, arg_ty) for arg_ty in prototype.args[1:]
|
|
1379
|
+
] # type:ignore
|
|
1380
|
+
|
|
1381
|
+
|
|
1382
|
+
class SimCCStdcall(SimCCMicrosoftCdecl):
|
|
1383
|
+
CALLEE_CLEANUP = True
|
|
1384
|
+
|
|
1385
|
+
|
|
1386
|
+
class SimCCMicrosoftFastcall(SimCC):
|
|
1387
|
+
ARG_REGS = ["ecx", "edx"] # Remaining arguments are passed in stack
|
|
1388
|
+
STACKARG_SP_DIFF = 4 # Return address is pushed on to stack by call
|
|
1389
|
+
RETURN_VAL = SimRegArg("eax", 4)
|
|
1390
|
+
RETURN_ADDR = SimStackArg(0, 4)
|
|
1391
|
+
ARCH = archinfo.ArchX86
|
|
1392
|
+
|
|
1393
|
+
|
|
1394
|
+
class MicrosoftAMD64ArgSession(ArgSession):
|
|
1395
|
+
pass
|
|
1396
|
+
|
|
1397
|
+
|
|
1398
|
+
class SimCCMicrosoftAMD64(SimCC):
|
|
1399
|
+
ARG_REGS = ["rcx", "rdx", "r8", "r9"]
|
|
1400
|
+
FP_ARG_REGS = ["xmm0", "xmm1", "xmm2", "xmm3"]
|
|
1401
|
+
STACKARG_SP_DIFF = 8 # Return address is pushed on to stack by call
|
|
1402
|
+
STACKARG_SP_BUFF = 32 # 32 bytes of shadow stack space
|
|
1403
|
+
RETURN_VAL = SimRegArg("rax", 8)
|
|
1404
|
+
OVERFLOW_RETURN_VAL = SimRegArg("rdx", 8)
|
|
1405
|
+
FP_RETURN_VAL = SimRegArg("xmm0", 32)
|
|
1406
|
+
RETURN_ADDR = SimStackArg(0, 8)
|
|
1407
|
+
ARCH = archinfo.ArchAMD64
|
|
1408
|
+
STACK_ALIGNMENT = 16
|
|
1409
|
+
|
|
1410
|
+
ArgSession = MicrosoftAMD64ArgSession
|
|
1411
|
+
|
|
1412
|
+
STRUCT_RETURN_THRESHOLD = 64
|
|
1413
|
+
|
|
1414
|
+
def next_arg(self, session, arg_type):
|
|
1415
|
+
if isinstance(arg_type, (SimTypeArray, SimTypeFixedSizeArray)): # hack
|
|
1416
|
+
arg_type = SimTypePointer(arg_type.elem_type).with_arch(self.arch)
|
|
1417
|
+
try:
|
|
1418
|
+
int_loc = next(session.int_iter)
|
|
1419
|
+
fp_loc = next(session.fp_iter)
|
|
1420
|
+
except StopIteration:
|
|
1421
|
+
int_loc = fp_loc = next(session.both_iter)
|
|
1422
|
+
|
|
1423
|
+
byte_size = arg_type.size // self.arch.byte_width if arg_type.size is not None else self.arch.bytes
|
|
1424
|
+
|
|
1425
|
+
if isinstance(arg_type, SimTypeFloat):
|
|
1426
|
+
return fp_loc.refine(size=byte_size, is_fp=True, arch=self.arch)
|
|
1427
|
+
|
|
1428
|
+
if byte_size <= int_loc.size:
|
|
1429
|
+
return int_loc.refine(size=byte_size, is_fp=False, arch=self.arch)
|
|
1430
|
+
|
|
1431
|
+
referenced_locs = [SimStackArg(offset, self.arch.bytes) for offset in range(0, byte_size, self.arch.bytes)]
|
|
1432
|
+
referenced_loc = refine_locs_with_struct_type(self.arch, referenced_locs, arg_type)
|
|
1433
|
+
return SimReferenceArgument(int_loc, referenced_loc)
|
|
1434
|
+
|
|
1435
|
+
def return_in_implicit_outparam(self, ty):
|
|
1436
|
+
if isinstance(ty, (SimTypeBottom, SimTypeRef)):
|
|
1437
|
+
return False
|
|
1438
|
+
return not isinstance(ty, SimTypeFloat) and ty.size > self.STRUCT_RETURN_THRESHOLD
|
|
1439
|
+
|
|
1440
|
+
def return_val(self, ty, perspective_returned=False):
|
|
1441
|
+
if ty._arch is None:
|
|
1442
|
+
ty = ty.with_arch(self.arch)
|
|
1443
|
+
|
|
1444
|
+
# Unions are allocated according to the layout of the largest member
|
|
1445
|
+
if isinstance(ty, SimUnion):
|
|
1446
|
+
chosen = None
|
|
1447
|
+
size = None
|
|
1448
|
+
for subty in ty.members.values():
|
|
1449
|
+
if subty.size is not None and (size is None or size < subty.size):
|
|
1450
|
+
chosen = subty
|
|
1451
|
+
size = subty.size
|
|
1452
|
+
if chosen is None:
|
|
1453
|
+
# fallback to void*
|
|
1454
|
+
chosen = SimTypePointer(SimTypeBottom()).with_arch(self.arch)
|
|
1455
|
+
return self.return_val(chosen, perspective_returned=perspective_returned)
|
|
1456
|
+
|
|
1457
|
+
if not isinstance(ty, SimStruct):
|
|
1458
|
+
return super().return_val(ty, perspective_returned)
|
|
1459
|
+
|
|
1460
|
+
if ty.size > self.STRUCT_RETURN_THRESHOLD:
|
|
1461
|
+
# TODO this code is duplicated a ton of places. how should it be a function?
|
|
1462
|
+
byte_size = ty.size // self.arch.byte_width
|
|
1463
|
+
referenced_locs = [SimStackArg(offset, self.arch.bytes) for offset in range(0, byte_size, self.arch.bytes)]
|
|
1464
|
+
referenced_loc = refine_locs_with_struct_type(self.arch, referenced_locs, ty)
|
|
1465
|
+
if perspective_returned:
|
|
1466
|
+
ptr_loc = self.RETURN_VAL
|
|
1467
|
+
else:
|
|
1468
|
+
ptr_loc = self.next_arg(self.ArgSession(self), SimTypePointer(SimTypeBottom()).with_arch(self.arch))
|
|
1469
|
+
assert ptr_loc is not None
|
|
1470
|
+
return SimReferenceArgument(ptr_loc, referenced_loc)
|
|
1471
|
+
|
|
1472
|
+
return refine_locs_with_struct_type(self.arch, [self.RETURN_VAL], ty)
|
|
1473
|
+
|
|
1474
|
+
|
|
1475
|
+
class SimCCSyscall(SimCC):
|
|
1476
|
+
"""
|
|
1477
|
+
The base class of all syscall CCs.
|
|
1478
|
+
"""
|
|
1479
|
+
|
|
1480
|
+
ERROR_REG: SimRegArg = None # type:ignore
|
|
1481
|
+
SYSCALL_ERRNO_START = None
|
|
1482
|
+
|
|
1483
|
+
@staticmethod
|
|
1484
|
+
def syscall_num(state) -> int:
|
|
1485
|
+
raise NotImplementedError
|
|
1486
|
+
|
|
1487
|
+
def linux_syscall_update_error_reg(self, state, expr):
|
|
1488
|
+
# special handling for Linux syscalls: on some architectures (mips/a3, powerpc/cr0_0) a bool indicating success
|
|
1489
|
+
# or failure of a system call is used as an error flag (0 for success, 1 for error). we have to set this
|
|
1490
|
+
if state.project is None or state.project.simos is None or state.project.simos.name != "Linux":
|
|
1491
|
+
return expr
|
|
1492
|
+
if type(expr) is int:
|
|
1493
|
+
expr = claripy.BVV(expr, state.arch.bits)
|
|
1494
|
+
with contextlib.suppress(AttributeError):
|
|
1495
|
+
expr = expr.ast
|
|
1496
|
+
nbits = self.ERROR_REG.size * state.arch.byte_width
|
|
1497
|
+
error_cond = claripy.UGE(expr, self.SYSCALL_ERRNO_START)
|
|
1498
|
+
if state.solver.is_false(error_cond):
|
|
1499
|
+
# guaranteed no error
|
|
1500
|
+
error_reg_val = claripy.BVV(0, nbits)
|
|
1501
|
+
elif state.solver.is_true(error_cond):
|
|
1502
|
+
# guaranteed error
|
|
1503
|
+
error_reg_val = claripy.BVV(-1, nbits)
|
|
1504
|
+
expr = -expr
|
|
1505
|
+
else:
|
|
1506
|
+
# both are satisfied, handle gracefully
|
|
1507
|
+
error_reg_val = claripy.If(error_cond, claripy.BVV(-1, nbits), 0)
|
|
1508
|
+
expr = claripy.If(error_cond, -expr, expr)
|
|
1509
|
+
|
|
1510
|
+
self.ERROR_REG.set_value(state, error_reg_val)
|
|
1511
|
+
return expr
|
|
1512
|
+
|
|
1513
|
+
def set_return_val(self, state, val, ty, **kwargs): # type:ignore # pylint:disable=arguments-differ
|
|
1514
|
+
if self.ERROR_REG is not None:
|
|
1515
|
+
val = self.linux_syscall_update_error_reg(state, val)
|
|
1516
|
+
super().set_return_val(state, val, ty, **kwargs)
|
|
1517
|
+
|
|
1518
|
+
|
|
1519
|
+
class SimCCX86LinuxSyscall(SimCCSyscall):
|
|
1520
|
+
ARG_REGS = ["ebx", "ecx", "edx", "esi", "edi", "ebp"]
|
|
1521
|
+
FP_ARG_REGS = []
|
|
1522
|
+
RETURN_VAL = SimRegArg("eax", 4)
|
|
1523
|
+
RETURN_ADDR = SimRegArg("ip_at_syscall", 4)
|
|
1524
|
+
ARCH = archinfo.ArchX86
|
|
1525
|
+
|
|
1526
|
+
@classmethod
|
|
1527
|
+
def _match(cls, arch, args, sp_delta): # pylint: disable=unused-argument
|
|
1528
|
+
# never appears anywhere except syscalls
|
|
1529
|
+
return False
|
|
1530
|
+
|
|
1531
|
+
@staticmethod
|
|
1532
|
+
def syscall_num(state):
|
|
1533
|
+
return state.regs.eax
|
|
1534
|
+
|
|
1535
|
+
|
|
1536
|
+
class SimCCX86WindowsSyscall(SimCCSyscall):
|
|
1537
|
+
# TODO: Make sure the information is correct
|
|
1538
|
+
ARG_REGS = ["ecx"]
|
|
1539
|
+
FP_ARG_REGS = []
|
|
1540
|
+
RETURN_VAL = SimRegArg("eax", 4)
|
|
1541
|
+
RETURN_ADDR = SimRegArg("ip_at_syscall", 4)
|
|
1542
|
+
ARCH = archinfo.ArchX86
|
|
1543
|
+
|
|
1544
|
+
@classmethod
|
|
1545
|
+
def _match(cls, arch, args, sp_delta): # pylint: disable=unused-argument
|
|
1546
|
+
# never appears anywhere except syscalls
|
|
1547
|
+
return False
|
|
1548
|
+
|
|
1549
|
+
@staticmethod
|
|
1550
|
+
def syscall_num(state):
|
|
1551
|
+
return state.regs.eax
|
|
1552
|
+
|
|
1553
|
+
|
|
1554
|
+
class SimCCSystemVAMD64(SimCC):
|
|
1555
|
+
ARG_REGS = ["rdi", "rsi", "rdx", "rcx", "r8", "r9"]
|
|
1556
|
+
FP_ARG_REGS = ["xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7"]
|
|
1557
|
+
STACKARG_SP_DIFF = 8 # Return address is pushed on to stack by call
|
|
1558
|
+
CALLER_SAVED_REGS = [
|
|
1559
|
+
"rdi",
|
|
1560
|
+
"rsi",
|
|
1561
|
+
"rdx",
|
|
1562
|
+
"rcx",
|
|
1563
|
+
"r8",
|
|
1564
|
+
"r9",
|
|
1565
|
+
"r10",
|
|
1566
|
+
"r11",
|
|
1567
|
+
"rax",
|
|
1568
|
+
]
|
|
1569
|
+
RETURN_ADDR = SimStackArg(0, 8)
|
|
1570
|
+
RETURN_VAL = SimRegArg("rax", 8)
|
|
1571
|
+
OVERFLOW_RETURN_VAL = SimRegArg("rdx", 8)
|
|
1572
|
+
FP_RETURN_VAL = SimRegArg("xmm0", 128)
|
|
1573
|
+
OVERFLOW_FP_RETURN_VAL = SimRegArg("xmm1", 128)
|
|
1574
|
+
ARCH = archinfo.ArchAMD64
|
|
1575
|
+
STACK_ALIGNMENT = 16
|
|
1576
|
+
|
|
1577
|
+
@classmethod
|
|
1578
|
+
def _match(cls, arch, args, sp_delta):
|
|
1579
|
+
if cls.ARCH is not None and ":" not in arch.name and not isinstance(arch, cls.ARCH):
|
|
1580
|
+
return False
|
|
1581
|
+
# if sp_delta != cls.STACKARG_SP_DIFF:
|
|
1582
|
+
# return False
|
|
1583
|
+
|
|
1584
|
+
sample_inst = cls(arch)
|
|
1585
|
+
all_fp_args = list(sample_inst.fp_args)
|
|
1586
|
+
all_int_args = list(sample_inst.int_args)
|
|
1587
|
+
both_iter = sample_inst.memory_args
|
|
1588
|
+
some_both_args = [next(both_iter) for _ in range(len(args))]
|
|
1589
|
+
|
|
1590
|
+
for arg in args:
|
|
1591
|
+
ex_arg = arg
|
|
1592
|
+
# attempt to coerce the argument into a form that might show up in these lists
|
|
1593
|
+
if type(ex_arg) is SimRegArg:
|
|
1594
|
+
if ex_arg.reg_name not in arch.registers:
|
|
1595
|
+
# danger!
|
|
1596
|
+
# if the register name is a digit-only string, we use it as an offset
|
|
1597
|
+
try:
|
|
1598
|
+
regfile_offset = int(ex_arg.reg_name)
|
|
1599
|
+
except ValueError:
|
|
1600
|
+
return False
|
|
1601
|
+
else:
|
|
1602
|
+
regfile_offset = arch.registers[ex_arg.reg_name][0]
|
|
1603
|
+
while regfile_offset not in arch.register_names:
|
|
1604
|
+
regfile_offset -= 1
|
|
1605
|
+
ex_arg.reg_name = arch.register_names[regfile_offset]
|
|
1606
|
+
ex_arg.reg_offset = 0
|
|
1607
|
+
|
|
1608
|
+
if ex_arg not in all_fp_args and ex_arg not in all_int_args and ex_arg not in some_both_args:
|
|
1609
|
+
if isinstance(arg, SimStackArg) and arg.stack_offset == 0:
|
|
1610
|
+
continue # ignore return address?
|
|
1611
|
+
return False
|
|
1612
|
+
|
|
1613
|
+
return True
|
|
1614
|
+
|
|
1615
|
+
# https://raw.githubusercontent.com/wiki/hjl-tools/x86-psABI/x86-64-psABI-1.0.pdf
|
|
1616
|
+
# section 3.2.3
|
|
1617
|
+
def next_arg(self, session, arg_type):
|
|
1618
|
+
if isinstance(arg_type, (SimTypeArray, SimTypeFixedSizeArray)): # hack
|
|
1619
|
+
arg_type = SimTypePointer(arg_type.elem_type).with_arch(self.arch)
|
|
1620
|
+
state = session.getstate()
|
|
1621
|
+
classification = self._classify(arg_type)
|
|
1622
|
+
try:
|
|
1623
|
+
mapped_classes = []
|
|
1624
|
+
for cls in classification:
|
|
1625
|
+
if cls == "SSEUP":
|
|
1626
|
+
mapped_classes.append(mapped_classes[-1].sse_extend(self.arch.bytes))
|
|
1627
|
+
elif cls == "NO_CLASS":
|
|
1628
|
+
raise NotImplementedError("Bug. Report to @rhelmot")
|
|
1629
|
+
elif cls == "MEMORY":
|
|
1630
|
+
mapped_classes.append(next(session.both_iter))
|
|
1631
|
+
elif cls == "INTEGER":
|
|
1632
|
+
mapped_classes.append(next(session.int_iter))
|
|
1633
|
+
elif cls == "SSE":
|
|
1634
|
+
mapped_classes.append(next(session.fp_iter))
|
|
1635
|
+
else:
|
|
1636
|
+
raise NotImplementedError("Bug. Report to @rhelmot")
|
|
1637
|
+
except StopIteration:
|
|
1638
|
+
session.setstate(state)
|
|
1639
|
+
mapped_classes = [next(session.both_iter) for _ in classification]
|
|
1640
|
+
|
|
1641
|
+
return refine_locs_with_struct_type(self.arch, mapped_classes, arg_type)
|
|
1642
|
+
|
|
1643
|
+
def return_val(self, ty: SimType | None, perspective_returned=False):
|
|
1644
|
+
if ty is None:
|
|
1645
|
+
return None
|
|
1646
|
+
if ty._arch is None:
|
|
1647
|
+
ty = ty.with_arch(self.arch)
|
|
1648
|
+
classification = self._classify(ty)
|
|
1649
|
+
if any(cls == "MEMORY" for cls in classification):
|
|
1650
|
+
assert all(cls == "MEMORY" for cls in classification)
|
|
1651
|
+
assert ty.size is not None
|
|
1652
|
+
byte_size = ty.size // self.arch.byte_width
|
|
1653
|
+
referenced_locs = [SimStackArg(offset, self.arch.bytes) for offset in range(0, byte_size, self.arch.bytes)]
|
|
1654
|
+
referenced_loc = refine_locs_with_struct_type(self.arch, referenced_locs, ty)
|
|
1655
|
+
ptr_loc = self.RETURN_VAL if perspective_returned else SimRegArg("rdi", 8)
|
|
1656
|
+
assert ptr_loc is not None
|
|
1657
|
+
return SimReferenceArgument(ptr_loc, referenced_loc)
|
|
1658
|
+
mapped_classes = []
|
|
1659
|
+
int_iter = iter([self.RETURN_VAL, self.OVERFLOW_RETURN_VAL])
|
|
1660
|
+
fp_iter = iter([self.FP_RETURN_VAL, self.OVERFLOW_FP_RETURN_VAL])
|
|
1661
|
+
for cls in classification:
|
|
1662
|
+
if cls == "SSEUP":
|
|
1663
|
+
mapped_classes.append(mapped_classes[-1].sse_extend(self.arch.bytes))
|
|
1664
|
+
elif cls == "NO_CLASS":
|
|
1665
|
+
raise NotImplementedError("Bug. Report to @rhelmot")
|
|
1666
|
+
elif cls == "INTEGER":
|
|
1667
|
+
mapped_classes.append(next(int_iter))
|
|
1668
|
+
elif cls == "SSE":
|
|
1669
|
+
mapped_classes.append(next(fp_iter))
|
|
1670
|
+
else:
|
|
1671
|
+
raise NotImplementedError("Bug. Report to @rhelmot")
|
|
1672
|
+
|
|
1673
|
+
return refine_locs_with_struct_type(self.arch, mapped_classes, ty)
|
|
1674
|
+
|
|
1675
|
+
def return_in_implicit_outparam(self, ty):
|
|
1676
|
+
if isinstance(ty, SimTypeBottom):
|
|
1677
|
+
return False
|
|
1678
|
+
# :P
|
|
1679
|
+
return isinstance(self.return_val(ty), SimReferenceArgument)
|
|
1680
|
+
|
|
1681
|
+
def _classify(self, ty: SimType, chunksize=None) -> list[str]:
|
|
1682
|
+
if chunksize is None:
|
|
1683
|
+
chunksize = self.arch.bytes
|
|
1684
|
+
# treat BOT as INTEGER
|
|
1685
|
+
nchunks = 1 if ty.size is None else (ty.size // self.arch.byte_width + chunksize - 1) // chunksize
|
|
1686
|
+
if isinstance(ty, (SimTypeFloat,)):
|
|
1687
|
+
return ["SSE"] + ["SSEUP"] * (nchunks - 1)
|
|
1688
|
+
if isinstance(ty, (SimTypeReg, SimTypeNum, SimTypeBottom)):
|
|
1689
|
+
return ["INTEGER"] * nchunks
|
|
1690
|
+
if isinstance(ty, SimCppClass) and not ty.fields and ty.size:
|
|
1691
|
+
raise TypeError("Cannot lay out an opaque class")
|
|
1692
|
+
if isinstance(ty, SimTypeArray) or (isinstance(ty, SimType) and isinstance(ty, NamedTypeMixin)):
|
|
1693
|
+
# NamedTypeMixin covers SimUnion, SimStruct, SimCppClass, and other struct-like classes
|
|
1694
|
+
assert ty.size is not None
|
|
1695
|
+
if ty.size > 512:
|
|
1696
|
+
return ["MEMORY"] * nchunks
|
|
1697
|
+
flattened = self._flatten(ty)
|
|
1698
|
+
if flattened is None:
|
|
1699
|
+
return ["MEMORY"] * nchunks
|
|
1700
|
+
result = ["NO_CLASS"] * nchunks
|
|
1701
|
+
for offset, subty_list in flattened.items():
|
|
1702
|
+
for subty in subty_list:
|
|
1703
|
+
assert subty.size
|
|
1704
|
+
# is the smaller chunk size necessary? Genuinely unsure
|
|
1705
|
+
subresult = self._classify(subty, chunksize=1)
|
|
1706
|
+
idx_start = offset // chunksize
|
|
1707
|
+
idx_end = (offset + (subty.size // self.arch.byte_width) - 1) // chunksize
|
|
1708
|
+
for i, idx in enumerate(range(idx_start, idx_end + 1)):
|
|
1709
|
+
subclass = subresult[i * chunksize]
|
|
1710
|
+
result[idx] = self._combine_classes(result[idx], subclass)
|
|
1711
|
+
if any(subresult == "MEMORY" for subresult in result):
|
|
1712
|
+
return ["MEMORY"] * nchunks
|
|
1713
|
+
if nchunks > 2 and (result[0] != "SSE" or any(subresult != "SSEUP" for subresult in result[1:])):
|
|
1714
|
+
return ["MEMORY"] * nchunks
|
|
1715
|
+
for i in range(1, nchunks):
|
|
1716
|
+
if result[i] == "SSEUP" and result[i - 1] not in ("SSE", "SSEUP"):
|
|
1717
|
+
result[i] = "SSE"
|
|
1718
|
+
return result
|
|
1719
|
+
raise NotImplementedError("Ummmmm... not sure what goes here. report bug to @rhelmot")
|
|
1720
|
+
|
|
1721
|
+
def _flatten(self, ty) -> dict[int, list[SimType]] | None:
|
|
1722
|
+
result: dict[int, list[SimType]] = defaultdict(list)
|
|
1723
|
+
if isinstance(ty, SimStruct):
|
|
1724
|
+
if ty.packed:
|
|
1725
|
+
return None
|
|
1726
|
+
for field, subty in ty.fields.items():
|
|
1727
|
+
offset = ty.offsets[field]
|
|
1728
|
+
subresult = self._flatten(subty)
|
|
1729
|
+
if subresult is None:
|
|
1730
|
+
return None
|
|
1731
|
+
for suboffset, subsubty_list in subresult.items():
|
|
1732
|
+
result[offset + suboffset] += subsubty_list
|
|
1733
|
+
elif isinstance(ty, SimTypeFixedSizeArray):
|
|
1734
|
+
assert ty.length is not None and ty.elem_type.size is not None
|
|
1735
|
+
subresult = self._flatten(ty.elem_type)
|
|
1736
|
+
if subresult is None:
|
|
1737
|
+
return None
|
|
1738
|
+
for suboffset, subsubty_list in subresult.items():
|
|
1739
|
+
for idx in range(ty.length):
|
|
1740
|
+
# TODO I think we need an explicit stride field on array types
|
|
1741
|
+
result[idx * ty.elem_type.size // self.arch.byte_width + suboffset] += subsubty_list
|
|
1742
|
+
elif isinstance(ty, SimUnion):
|
|
1743
|
+
for subty in ty.members.values():
|
|
1744
|
+
subresult = self._flatten(subty)
|
|
1745
|
+
if subresult is None:
|
|
1746
|
+
return None
|
|
1747
|
+
for suboffset, subsubty_list in subresult.items():
|
|
1748
|
+
result[suboffset] += subsubty_list
|
|
1749
|
+
else:
|
|
1750
|
+
result[0].append(ty)
|
|
1751
|
+
return result
|
|
1752
|
+
|
|
1753
|
+
def _combine_classes(self, cls1, cls2):
|
|
1754
|
+
if cls1 == cls2:
|
|
1755
|
+
return cls1
|
|
1756
|
+
if cls1 == "NO_CLASS":
|
|
1757
|
+
return cls2
|
|
1758
|
+
if cls2 == "NO_CLASS":
|
|
1759
|
+
return cls1
|
|
1760
|
+
if cls1 == "MEMORY" or cls2 == "MEMORY":
|
|
1761
|
+
return "MEMORY"
|
|
1762
|
+
if cls1 == "INTEGER" or cls2 == "INTEGER":
|
|
1763
|
+
return "INTEGER"
|
|
1764
|
+
return "SSE"
|
|
1765
|
+
|
|
1766
|
+
|
|
1767
|
+
class SimCCAMD64LinuxSyscall(SimCCSyscall):
|
|
1768
|
+
ARG_REGS = ["rdi", "rsi", "rdx", "r10", "r8", "r9"]
|
|
1769
|
+
RETURN_VAL = SimRegArg("rax", 8)
|
|
1770
|
+
RETURN_ADDR = SimRegArg("ip_at_syscall", 8)
|
|
1771
|
+
ARCH = archinfo.ArchAMD64
|
|
1772
|
+
CALLER_SAVED_REGS = ["rax", "rcx", "r11"]
|
|
1773
|
+
|
|
1774
|
+
@staticmethod
|
|
1775
|
+
def _match(arch, args, sp_delta): # type:ignore # pylint: disable=unused-argument
|
|
1776
|
+
# doesn't appear anywhere but syscalls
|
|
1777
|
+
return False
|
|
1778
|
+
|
|
1779
|
+
@staticmethod
|
|
1780
|
+
def syscall_num(state):
|
|
1781
|
+
return state.regs.rax
|
|
1782
|
+
|
|
1783
|
+
|
|
1784
|
+
class SimCCAMD64WindowsSyscall(SimCCSyscall):
|
|
1785
|
+
# TODO: Make sure the information is correct
|
|
1786
|
+
ARG_REGS = ["rcx"]
|
|
1787
|
+
FP_ARG_REGS = []
|
|
1788
|
+
RETURN_VAL = SimRegArg("rax", 8)
|
|
1789
|
+
RETURN_ADDR = SimRegArg("ip_at_syscall", 8)
|
|
1790
|
+
ARCH = archinfo.ArchAMD64
|
|
1791
|
+
|
|
1792
|
+
@classmethod
|
|
1793
|
+
def _match(cls, arch, args, sp_delta): # pylint: disable=unused-argument
|
|
1794
|
+
# never appears anywhere except syscalls
|
|
1795
|
+
return False
|
|
1796
|
+
|
|
1797
|
+
@staticmethod
|
|
1798
|
+
def syscall_num(state):
|
|
1799
|
+
return state.regs.rax
|
|
1800
|
+
|
|
1801
|
+
|
|
1802
|
+
class SimCCARM(SimCC):
|
|
1803
|
+
ARG_REGS = ["r0", "r1", "r2", "r3"]
|
|
1804
|
+
FP_ARG_REGS = [] # regular arg regs are used as fp arg regs
|
|
1805
|
+
CALLER_SAVED_REGS = ["r0", "r1", "r2", "r3"]
|
|
1806
|
+
RETURN_ADDR = SimRegArg("lr", 4)
|
|
1807
|
+
RETURN_VAL = SimRegArg("r0", 4)
|
|
1808
|
+
OVERFLOW_RETURN_VAL = SimRegArg("r1", 4)
|
|
1809
|
+
ARCH = archinfo.ArchARM
|
|
1810
|
+
|
|
1811
|
+
# https://github.com/ARM-software/abi-aa/blob/60a8eb8c55e999d74dac5e368fc9d7e36e38dda4/aapcs32/aapcs32.rst#parameter-passing
|
|
1812
|
+
def next_arg(self, session, arg_type):
|
|
1813
|
+
if isinstance(arg_type, (SimTypeArray, SimTypeFixedSizeArray)): # hack
|
|
1814
|
+
arg_type = SimTypePointer(arg_type.elem_type).with_arch(self.arch)
|
|
1815
|
+
state = session.getstate()
|
|
1816
|
+
classification = self._classify(arg_type)
|
|
1817
|
+
try:
|
|
1818
|
+
mapped_classes = []
|
|
1819
|
+
for cls in classification:
|
|
1820
|
+
if cls == "DOUBLEP":
|
|
1821
|
+
if session.getstate()[1] % 2 == 1: # doubles must start on an even register
|
|
1822
|
+
next(session.int_iter)
|
|
1823
|
+
|
|
1824
|
+
if session.getstate()[1] == len(self.ARG_REGS) - 2:
|
|
1825
|
+
mapped_classes.append(next(session.int_iter))
|
|
1826
|
+
mapped_classes.append(next(session.both_iter))
|
|
1827
|
+
else:
|
|
1828
|
+
try:
|
|
1829
|
+
mapped_classes.append(next(session.int_iter))
|
|
1830
|
+
mapped_classes.append(next(session.int_iter))
|
|
1831
|
+
except StopIteration:
|
|
1832
|
+
mapped_classes.append(next(session.both_iter))
|
|
1833
|
+
mapped_classes.append(next(session.both_iter))
|
|
1834
|
+
elif cls == "NO_CLASS":
|
|
1835
|
+
raise NotImplementedError("Bug. Report to @rhelmot")
|
|
1836
|
+
elif cls == "MEMORY":
|
|
1837
|
+
mapped_classes.append(next(session.both_iter))
|
|
1838
|
+
elif cls in {"INTEGER", "SINGLEP"}:
|
|
1839
|
+
try:
|
|
1840
|
+
mapped_classes.append(next(session.int_iter))
|
|
1841
|
+
except StopIteration:
|
|
1842
|
+
mapped_classes.append(next(session.both_iter))
|
|
1843
|
+
else:
|
|
1844
|
+
raise NotImplementedError("Bug. Report to @rhelmot")
|
|
1845
|
+
except StopIteration:
|
|
1846
|
+
session.setstate(state)
|
|
1847
|
+
mapped_classes = [next(session.both_iter) for _ in classification]
|
|
1848
|
+
|
|
1849
|
+
return refine_locs_with_struct_type(self.arch, mapped_classes, arg_type)
|
|
1850
|
+
|
|
1851
|
+
def _classify(self, ty, chunksize=None):
|
|
1852
|
+
if chunksize is None:
|
|
1853
|
+
chunksize = self.arch.bytes
|
|
1854
|
+
# treat BOT as INTEGER
|
|
1855
|
+
nchunks = 1 if isinstance(ty, SimTypeBottom) else (ty.size // self.arch.byte_width + chunksize - 1) // chunksize
|
|
1856
|
+
if isinstance(
|
|
1857
|
+
ty, (SimTypeInt, SimTypeChar, SimTypeBool, SimTypePointer, SimTypeNum, SimTypeBottom, SimTypeReference)
|
|
1858
|
+
):
|
|
1859
|
+
return ["INTEGER"] * nchunks
|
|
1860
|
+
if isinstance(ty, (SimTypeFloat,)):
|
|
1861
|
+
if ty.size == 64:
|
|
1862
|
+
return ["DOUBLEP"]
|
|
1863
|
+
if ty.size == 32:
|
|
1864
|
+
return ["SINGLEP"]
|
|
1865
|
+
return ["NO_CLASS"]
|
|
1866
|
+
if isinstance(ty, (SimStruct, SimTypeFixedSizeArray, SimUnion)):
|
|
1867
|
+
flattened = self._flatten(ty)
|
|
1868
|
+
if flattened is None:
|
|
1869
|
+
return ["MEMORY"] * nchunks
|
|
1870
|
+
result = ["NO_CLASS"] * nchunks
|
|
1871
|
+
for offset, subty_list in flattened.items():
|
|
1872
|
+
for subty in subty_list:
|
|
1873
|
+
assert subty.size is not None
|
|
1874
|
+
# is the smaller chunk size necessary? Genuinely unsure
|
|
1875
|
+
subresult = self._classify(subty, chunksize=1)
|
|
1876
|
+
idx_start = offset // chunksize
|
|
1877
|
+
idx_end = (offset + (subty.size // self.arch.byte_width) - 1) // chunksize
|
|
1878
|
+
for i, idx in enumerate(range(idx_start, idx_end + 1)):
|
|
1879
|
+
subclass = subresult[i * chunksize]
|
|
1880
|
+
result[idx] = self._combine_classes(result[idx], subclass)
|
|
1881
|
+
return result
|
|
1882
|
+
raise NotImplementedError("Ummmmm... not sure what goes here. report bug to @rhelmot")
|
|
1883
|
+
|
|
1884
|
+
def _combine_classes(self, cls1, cls2):
|
|
1885
|
+
if cls1 == cls2:
|
|
1886
|
+
return cls1
|
|
1887
|
+
if cls1 == "NO_CLASS":
|
|
1888
|
+
return cls2
|
|
1889
|
+
if cls2 == "NO_CLASS":
|
|
1890
|
+
return cls1
|
|
1891
|
+
if cls1 == "MEMORY" or cls2 == "MEMORY":
|
|
1892
|
+
return "MEMORY"
|
|
1893
|
+
if cls1 == "INTEGER" or cls2 == "INTEGER":
|
|
1894
|
+
return "INTEGER"
|
|
1895
|
+
return "SSE"
|
|
1896
|
+
|
|
1897
|
+
def _flatten(self, ty) -> dict[int, list[SimType]] | None:
|
|
1898
|
+
result: dict[int, list[SimType]] = defaultdict(list)
|
|
1899
|
+
if isinstance(ty, SimStruct):
|
|
1900
|
+
if ty.packed:
|
|
1901
|
+
return None
|
|
1902
|
+
for field, subty in ty.fields.items():
|
|
1903
|
+
offset = ty.offsets[field]
|
|
1904
|
+
subresult = self._flatten(subty)
|
|
1905
|
+
if subresult is None:
|
|
1906
|
+
return None
|
|
1907
|
+
for suboffset, subsubty_list in subresult.items():
|
|
1908
|
+
result[offset + suboffset] += subsubty_list
|
|
1909
|
+
if not result:
|
|
1910
|
+
# the struct is empty (because somehow we do not know its members), so we treat it as a single INTEGER
|
|
1911
|
+
# at offset 0
|
|
1912
|
+
result[0].append(SimTypeInt().with_arch(self.arch))
|
|
1913
|
+
elif isinstance(ty, SimTypeFixedSizeArray):
|
|
1914
|
+
assert ty.length is not None and ty.elem_type.size is not None
|
|
1915
|
+
subresult = self._flatten(ty.elem_type)
|
|
1916
|
+
if subresult is None:
|
|
1917
|
+
return None
|
|
1918
|
+
for suboffset, subsubty_list in subresult.items():
|
|
1919
|
+
for idx in range(ty.length):
|
|
1920
|
+
# TODO I think we need an explicit stride field on array types
|
|
1921
|
+
result[idx * ty.elem_type.size // self.arch.byte_width + suboffset] += subsubty_list
|
|
1922
|
+
elif isinstance(ty, SimUnion):
|
|
1923
|
+
for subty in ty.members.values():
|
|
1924
|
+
subresult = self._flatten(subty)
|
|
1925
|
+
if subresult is None:
|
|
1926
|
+
return None
|
|
1927
|
+
for suboffset, subsubty_list in subresult.items():
|
|
1928
|
+
result[suboffset] += subsubty_list
|
|
1929
|
+
else:
|
|
1930
|
+
result[0].append(ty)
|
|
1931
|
+
return result
|
|
1932
|
+
|
|
1933
|
+
|
|
1934
|
+
class SimCCARMHF(SimCCARM):
|
|
1935
|
+
ARG_REGS = ["r0", "r1", "r2", "r3"]
|
|
1936
|
+
FP_ARG_REGS = [f"s{i}" for i in range(16)] # regular arg regs are used as fp arg regs
|
|
1937
|
+
FP_RETURN_VAL = SimRegArg("s0", 32)
|
|
1938
|
+
CALLER_SAVED_REGS = []
|
|
1939
|
+
RETURN_ADDR = SimRegArg("lr", 4)
|
|
1940
|
+
RETURN_VAL = SimRegArg("r0", 4)
|
|
1941
|
+
OVERFLOW_RETURN_VAL = SimRegArg("r1", 4)
|
|
1942
|
+
ARCH = archinfo.ArchARMHF
|
|
1943
|
+
EXTRA_ARCHES = (archinfo.ArchARMCortexM,)
|
|
1944
|
+
|
|
1945
|
+
def next_arg(self, session, arg_type):
|
|
1946
|
+
if isinstance(arg_type, (SimTypeArray, SimTypeFixedSizeArray)): # hack
|
|
1947
|
+
arg_type = SimTypePointer(arg_type.elem_type).with_arch(self.arch)
|
|
1948
|
+
state = session.getstate()
|
|
1949
|
+
classification = self._classify(arg_type)
|
|
1950
|
+
try:
|
|
1951
|
+
mapped_classes = []
|
|
1952
|
+
for cls in classification:
|
|
1953
|
+
if cls == "DOUBLEP":
|
|
1954
|
+
if session.getstate()[1] % 2 == 1: # doubles must start on an even register
|
|
1955
|
+
next(session.int_iter)
|
|
1956
|
+
|
|
1957
|
+
if session.getstate()[1] == len(self.ARG_REGS) - 2:
|
|
1958
|
+
mapped_classes.append(next(session.int_iter))
|
|
1959
|
+
mapped_classes.append(next(session.both_iter))
|
|
1960
|
+
else:
|
|
1961
|
+
try:
|
|
1962
|
+
mapped_classes.append(next(session.int_iter))
|
|
1963
|
+
mapped_classes.append(next(session.int_iter))
|
|
1964
|
+
except StopIteration:
|
|
1965
|
+
mapped_classes.append(next(session.both_iter))
|
|
1966
|
+
mapped_classes.append(next(session.both_iter))
|
|
1967
|
+
elif cls == "NO_CLASS":
|
|
1968
|
+
raise NotImplementedError("Bug. Report to @rhelmot")
|
|
1969
|
+
elif cls == "MEMORY":
|
|
1970
|
+
mapped_classes.append(next(session.both_iter))
|
|
1971
|
+
elif cls == "INTEGER":
|
|
1972
|
+
try:
|
|
1973
|
+
mapped_classes.append(next(session.int_iter))
|
|
1974
|
+
except StopIteration:
|
|
1975
|
+
mapped_classes.append(next(session.both_iter))
|
|
1976
|
+
elif cls == "SINGLEP":
|
|
1977
|
+
try:
|
|
1978
|
+
mapped_classes.append(next(session.fp_iter))
|
|
1979
|
+
except StopIteration:
|
|
1980
|
+
mapped_classes.append(next(session.both_iter))
|
|
1981
|
+
else:
|
|
1982
|
+
raise NotImplementedError("Bug. Report to @rhelmot")
|
|
1983
|
+
except StopIteration:
|
|
1984
|
+
session.setstate(state)
|
|
1985
|
+
mapped_classes = [next(session.both_iter) for _ in classification]
|
|
1986
|
+
|
|
1987
|
+
return refine_locs_with_struct_type(self.arch, mapped_classes, arg_type)
|
|
1988
|
+
|
|
1989
|
+
|
|
1990
|
+
class SimCCARMLinuxSyscall(SimCCSyscall):
|
|
1991
|
+
# TODO: Make sure all the information is correct
|
|
1992
|
+
ARG_REGS = ["r0", "r1", "r2", "r3"]
|
|
1993
|
+
FP_ARG_REGS = [] # TODO: ???
|
|
1994
|
+
RETURN_ADDR = SimRegArg("ip_at_syscall", 4)
|
|
1995
|
+
RETURN_VAL = SimRegArg("r0", 4)
|
|
1996
|
+
ARCH = archinfo.ArchARM
|
|
1997
|
+
|
|
1998
|
+
@classmethod
|
|
1999
|
+
def _match(cls, arch, args, sp_delta): # pylint: disable=unused-argument
|
|
2000
|
+
# never appears anywhere except syscalls
|
|
2001
|
+
return False
|
|
2002
|
+
|
|
2003
|
+
@staticmethod
|
|
2004
|
+
def syscall_num(state):
|
|
2005
|
+
if ((state.regs.ip_at_syscall & 1) == 1).is_true():
|
|
2006
|
+
insn = state.mem[state.regs.ip_at_syscall - 3].short.resolved
|
|
2007
|
+
is_svc = ((insn & 0xFF00) == 0xDF00).is_true()
|
|
2008
|
+
svc_num = insn & 0xFF
|
|
2009
|
+
else:
|
|
2010
|
+
insn = state.mem[state.regs.ip_at_syscall - 4].dword.resolved
|
|
2011
|
+
is_svc = ((insn & 0x0F000000) == 0x0F000000).is_true()
|
|
2012
|
+
svc_num = insn & 0xFFFFFF
|
|
2013
|
+
if not is_svc:
|
|
2014
|
+
l.error("ARM syscall number being queried at an address which is not an SVC")
|
|
2015
|
+
return claripy.BVV(0, 32)
|
|
2016
|
+
|
|
2017
|
+
if len(svc_num) == 32 and (svc_num > 0x900000).is_true() and (svc_num < 0x90FFFF).is_true():
|
|
2018
|
+
return svc_num - 0x900000
|
|
2019
|
+
return state.regs.r7
|
|
2020
|
+
|
|
2021
|
+
|
|
2022
|
+
class SimCCAArch64(SimCC):
|
|
2023
|
+
ARG_REGS = ["x0", "x1", "x2", "x3", "x4", "x5", "x6", "x7"]
|
|
2024
|
+
FP_ARG_REGS = [] # TODO: ???
|
|
2025
|
+
RETURN_ADDR = SimRegArg("lr", 8)
|
|
2026
|
+
RETURN_VAL = SimRegArg("x0", 8)
|
|
2027
|
+
ARCH = archinfo.ArchAArch64
|
|
2028
|
+
|
|
2029
|
+
|
|
2030
|
+
class SimCCAArch64LinuxSyscall(SimCCSyscall):
|
|
2031
|
+
# TODO: Make sure all the information is correct
|
|
2032
|
+
ARG_REGS = ["x0", "x1", "x2", "x3", "x4", "x5", "x6", "x7"]
|
|
2033
|
+
FP_ARG_REGS = [] # TODO: ???
|
|
2034
|
+
RETURN_VAL = SimRegArg("x0", 8)
|
|
2035
|
+
RETURN_ADDR = SimRegArg("ip_at_syscall", 8)
|
|
2036
|
+
ARCH = archinfo.ArchAArch64
|
|
2037
|
+
|
|
2038
|
+
@classmethod
|
|
2039
|
+
def _match(cls, arch, args, sp_delta): # pylint: disable=unused-argument
|
|
2040
|
+
# never appears anywhere except syscalls
|
|
2041
|
+
return False
|
|
2042
|
+
|
|
2043
|
+
@staticmethod
|
|
2044
|
+
def syscall_num(state):
|
|
2045
|
+
return state.regs.x8
|
|
2046
|
+
|
|
2047
|
+
|
|
2048
|
+
class SimCCRISCV64LinuxSyscall(SimCCSyscall):
|
|
2049
|
+
# TODO: Make sure all the information is correct
|
|
2050
|
+
ARG_REGS = ["a0", "a1", "a2", "a3", "a4", "a5", "a6", "a7"]
|
|
2051
|
+
FP_ARG_REGS = [] # TODO: ???
|
|
2052
|
+
RETURN_VAL = SimRegArg("a0", 8)
|
|
2053
|
+
RETURN_ADDR = SimRegArg("ip_at_syscall", 4)
|
|
2054
|
+
ARCH = archinfo.ArchRISCV64
|
|
2055
|
+
|
|
2056
|
+
@classmethod
|
|
2057
|
+
def _match(cls, arch, args, sp_delta): # pylint: disable=unused-argument
|
|
2058
|
+
# never appears anywhere except syscalls
|
|
2059
|
+
return False
|
|
2060
|
+
|
|
2061
|
+
@staticmethod
|
|
2062
|
+
def syscall_num(state):
|
|
2063
|
+
return state.regs.a0
|
|
2064
|
+
|
|
2065
|
+
|
|
2066
|
+
class SimCCO32(SimCC):
|
|
2067
|
+
ARG_REGS = ["a0", "a1", "a2", "a3"]
|
|
2068
|
+
FP_ARG_REGS = [
|
|
2069
|
+
"f12",
|
|
2070
|
+
"f13",
|
|
2071
|
+
"f14",
|
|
2072
|
+
"f15",
|
|
2073
|
+
] # Note double precision args are split between f12-f13, f14-f15 and single precision only use f12 and f14
|
|
2074
|
+
STACKARG_SP_BUFF = 16
|
|
2075
|
+
CALLER_SAVED_REGS = ["t9", "gp"]
|
|
2076
|
+
RETURN_ADDR = SimRegArg("ra", 4)
|
|
2077
|
+
RETURN_VAL = SimRegArg("v0", 4)
|
|
2078
|
+
OVERFLOW_RETURN_VAL = SimRegArg("v1", 4)
|
|
2079
|
+
ARCH = archinfo.ArchMIPS32
|
|
2080
|
+
|
|
2081
|
+
# http://math-atlas.sourceforge.net/devel/assembly/mipsabi32.pdf Section 3-17
|
|
2082
|
+
def next_arg(self, session, arg_type):
|
|
2083
|
+
if isinstance(arg_type, (SimTypeArray, SimTypeFixedSizeArray)): # hack
|
|
2084
|
+
arg_type = SimTypePointer(arg_type.elem_type).with_arch(self.arch)
|
|
2085
|
+
state = session.getstate()
|
|
2086
|
+
classification = self._classify(arg_type)
|
|
2087
|
+
try:
|
|
2088
|
+
mapped_classes = []
|
|
2089
|
+
can_use_fp = True
|
|
2090
|
+
for idx, cls in enumerate(classification):
|
|
2091
|
+
if cls == "DOUBLEP":
|
|
2092
|
+
mapped_classes.append(next(session.fp_iter))
|
|
2093
|
+
mapped_classes.append(next(session.fp_iter))
|
|
2094
|
+
if isinstance(arg_type, SimStruct) and idx < 2 and can_use_fp:
|
|
2095
|
+
next(session.fp_iter) # consume next two fp regs since it's double precision
|
|
2096
|
+
next(session.fp_iter)
|
|
2097
|
+
elif cls == "NO_CLASS":
|
|
2098
|
+
raise NotImplementedError("Bug. Report to @rhelmot")
|
|
2099
|
+
elif cls == "MEMORY":
|
|
2100
|
+
mapped_classes.append(next(session.both_iter))
|
|
2101
|
+
can_use_fp = False
|
|
2102
|
+
elif cls == "INTEGER":
|
|
2103
|
+
mapped_classes.append(next(session.int_iter))
|
|
2104
|
+
can_use_fp = False
|
|
2105
|
+
elif cls == "SINGLEP":
|
|
2106
|
+
if isinstance(arg_type, SimStruct):
|
|
2107
|
+
if idx < 2 and can_use_fp:
|
|
2108
|
+
mapped_classes.append(next(session.fp_iter))
|
|
2109
|
+
next(session.int_iter) # Need to take up the arg slot
|
|
2110
|
+
else:
|
|
2111
|
+
mapped_classes.append(next(session.both_iter))
|
|
2112
|
+
else:
|
|
2113
|
+
mapped_classes.append(next(session.fp_iter))
|
|
2114
|
+
next(session.fp_iter) # consume f13 or f15 since it's single precision
|
|
2115
|
+
|
|
2116
|
+
else:
|
|
2117
|
+
raise NotImplementedError("Bug. Report to @rhelmot")
|
|
2118
|
+
except StopIteration:
|
|
2119
|
+
session.setstate(state)
|
|
2120
|
+
mapped_classes = [next(session.both_iter) for _ in classification]
|
|
2121
|
+
|
|
2122
|
+
return refine_locs_with_struct_type(self.arch, mapped_classes, arg_type)
|
|
2123
|
+
|
|
2124
|
+
def _classify(self, ty, chunksize=None):
|
|
2125
|
+
if chunksize is None:
|
|
2126
|
+
chunksize = self.arch.bytes
|
|
2127
|
+
# treat BOT as INTEGER
|
|
2128
|
+
nchunks = 1 if isinstance(ty, SimTypeBottom) else (ty.size // self.arch.byte_width + chunksize - 1) // chunksize
|
|
2129
|
+
if isinstance(ty, (SimTypeInt, SimTypeChar, SimTypePointer, SimTypeNum, SimTypeBottom, SimTypeReference)):
|
|
2130
|
+
return ["INTEGER"] * nchunks
|
|
2131
|
+
if isinstance(ty, (SimTypeFloat,)):
|
|
2132
|
+
if ty.size == 64:
|
|
2133
|
+
return ["DOUBLEP"]
|
|
2134
|
+
if ty.size == 32:
|
|
2135
|
+
return ["SINGLEP"]
|
|
2136
|
+
return ["NO_CLASS"]
|
|
2137
|
+
if isinstance(ty, (SimStruct, SimTypeFixedSizeArray, SimUnion)):
|
|
2138
|
+
flattened = self._flatten(ty)
|
|
2139
|
+
if flattened is None:
|
|
2140
|
+
return ["MEMORY"] * nchunks
|
|
2141
|
+
result = ["NO_CLASS"] * nchunks
|
|
2142
|
+
for offset, subty_list in flattened.items():
|
|
2143
|
+
for subty in subty_list:
|
|
2144
|
+
assert subty.size is not None
|
|
2145
|
+
# is the smaller chunk size necessary? Genuinely unsure
|
|
2146
|
+
subresult = self._classify(subty, chunksize=1)
|
|
2147
|
+
idx_start = offset // chunksize
|
|
2148
|
+
idx_end = (offset + (subty.size // self.arch.byte_width) - 1) // chunksize
|
|
2149
|
+
for i, idx in enumerate(range(idx_start, idx_end + 1)):
|
|
2150
|
+
subclass = subresult[i * chunksize]
|
|
2151
|
+
result[idx] = self._combine_classes(result[idx], subclass)
|
|
2152
|
+
return result
|
|
2153
|
+
raise NotImplementedError("Ummmmm... not sure what goes here. report bug to @rhelmot")
|
|
2154
|
+
|
|
2155
|
+
def _combine_classes(self, cls1, cls2):
|
|
2156
|
+
if cls1 == cls2:
|
|
2157
|
+
return cls1
|
|
2158
|
+
if cls1 == "NO_CLASS":
|
|
2159
|
+
return cls2
|
|
2160
|
+
if cls2 == "NO_CLASS":
|
|
2161
|
+
return cls1
|
|
2162
|
+
if cls1 == "MEMORY" or cls2 == "MEMORY":
|
|
2163
|
+
return "MEMORY"
|
|
2164
|
+
if cls1 == "INTEGER" or cls2 == "INTEGER":
|
|
2165
|
+
return "INTEGER"
|
|
2166
|
+
return "SSE"
|
|
2167
|
+
|
|
2168
|
+
def _flatten(self, ty) -> dict[int, list[SimType]] | None:
|
|
2169
|
+
result: dict[int, list[SimType]] = defaultdict(list)
|
|
2170
|
+
if isinstance(ty, SimStruct):
|
|
2171
|
+
if ty.packed:
|
|
2172
|
+
return None
|
|
2173
|
+
for field, subty in ty.fields.items():
|
|
2174
|
+
offset = ty.offsets[field]
|
|
2175
|
+
subresult = self._flatten(subty)
|
|
2176
|
+
if subresult is None:
|
|
2177
|
+
return None
|
|
2178
|
+
for suboffset, subsubty_list in subresult.items():
|
|
2179
|
+
result[offset + suboffset] += subsubty_list
|
|
2180
|
+
elif isinstance(ty, SimTypeFixedSizeArray):
|
|
2181
|
+
assert ty.length is not None and ty.elem_type.size is not None
|
|
2182
|
+
subresult = self._flatten(ty.elem_type)
|
|
2183
|
+
if subresult is None:
|
|
2184
|
+
return None
|
|
2185
|
+
for suboffset, subsubty_list in subresult.items():
|
|
2186
|
+
for idx in range(ty.length):
|
|
2187
|
+
# TODO I think we need an explicit stride field on array types
|
|
2188
|
+
result[idx * ty.elem_type.size // self.arch.byte_width + suboffset] += subsubty_list
|
|
2189
|
+
elif isinstance(ty, SimUnion):
|
|
2190
|
+
for subty in ty.members.values():
|
|
2191
|
+
subresult = self._flatten(subty)
|
|
2192
|
+
if subresult is None:
|
|
2193
|
+
return None
|
|
2194
|
+
for suboffset, subsubty_list in subresult.items():
|
|
2195
|
+
result[suboffset] += subsubty_list
|
|
2196
|
+
else:
|
|
2197
|
+
result[0].append(ty)
|
|
2198
|
+
return result
|
|
2199
|
+
|
|
2200
|
+
|
|
2201
|
+
class SimCCO32LinuxSyscall(SimCCSyscall):
|
|
2202
|
+
# TODO: Make sure all the information is correct
|
|
2203
|
+
ARG_REGS = ["a0", "a1", "a2", "a3"]
|
|
2204
|
+
FP_ARG_REGS = [] # TODO: ???
|
|
2205
|
+
RETURN_VAL = SimRegArg("v0", 4)
|
|
2206
|
+
RETURN_ADDR = SimRegArg("ip_at_syscall", 4)
|
|
2207
|
+
ARCH = archinfo.ArchMIPS32
|
|
2208
|
+
|
|
2209
|
+
ERROR_REG = SimRegArg("a3", 4)
|
|
2210
|
+
SYSCALL_ERRNO_START = -1133
|
|
2211
|
+
|
|
2212
|
+
@classmethod
|
|
2213
|
+
def _match(cls, arch, args, sp_delta): # pylint: disable=unused-argument
|
|
2214
|
+
# never appears anywhere except syscalls
|
|
2215
|
+
return False
|
|
2216
|
+
|
|
2217
|
+
@staticmethod
|
|
2218
|
+
def syscall_num(state):
|
|
2219
|
+
return state.regs.v0
|
|
2220
|
+
|
|
2221
|
+
|
|
2222
|
+
class SimCCN64(SimCC): # TODO: add n32
|
|
2223
|
+
ARG_REGS = ["a0", "a1", "a2", "a3", "a4", "a5", "a6", "a7"]
|
|
2224
|
+
CALLER_SAVED_REGS = ["t9", "gp"]
|
|
2225
|
+
FP_ARG_REGS = [] # TODO: ???
|
|
2226
|
+
STACKARG_SP_BUFF = 32
|
|
2227
|
+
RETURN_ADDR = SimRegArg("ra", 8)
|
|
2228
|
+
RETURN_VAL = SimRegArg("v0", 8)
|
|
2229
|
+
ARCH = archinfo.ArchMIPS64
|
|
2230
|
+
|
|
2231
|
+
|
|
2232
|
+
SimCCO64 = SimCCN64 # compatibility
|
|
2233
|
+
|
|
2234
|
+
|
|
2235
|
+
class SimCCN64LinuxSyscall(SimCCSyscall):
|
|
2236
|
+
ARG_REGS = ["a0", "a1", "a2", "a3", "a4", "a5", "a6", "a7"]
|
|
2237
|
+
FP_ARG_REGS = [] # TODO: ???
|
|
2238
|
+
RETURN_VAL = SimRegArg("v0", 8)
|
|
2239
|
+
RETURN_ADDR = SimRegArg("ip_at_syscall", 8)
|
|
2240
|
+
ARCH = archinfo.ArchMIPS64
|
|
2241
|
+
|
|
2242
|
+
ERROR_REG = SimRegArg("a3", 8)
|
|
2243
|
+
SYSCALL_ERRNO_START = -1133
|
|
2244
|
+
|
|
2245
|
+
@classmethod
|
|
2246
|
+
def _match(cls, arch, args, sp_delta): # pylint: disable=unused-argument
|
|
2247
|
+
# never appears anywhere except syscalls
|
|
2248
|
+
return False
|
|
2249
|
+
|
|
2250
|
+
@staticmethod
|
|
2251
|
+
def syscall_num(state):
|
|
2252
|
+
return state.regs.v0
|
|
2253
|
+
|
|
2254
|
+
|
|
2255
|
+
class SimCCPowerPC(SimCC):
|
|
2256
|
+
ARG_REGS = ["r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10"]
|
|
2257
|
+
FP_ARG_REGS = [] # TODO: ???
|
|
2258
|
+
STACKARG_SP_BUFF = 8
|
|
2259
|
+
RETURN_ADDR = SimRegArg("lr", 4)
|
|
2260
|
+
RETURN_VAL = SimRegArg("r3", 4)
|
|
2261
|
+
OVERFLOW_RETURN_VAL = SimRegArg("r4", 4)
|
|
2262
|
+
ARCH = archinfo.ArchPPC32
|
|
2263
|
+
|
|
2264
|
+
|
|
2265
|
+
class SimCCPowerPCLinuxSyscall(SimCCSyscall):
|
|
2266
|
+
# TODO: Make sure all the information is correct
|
|
2267
|
+
ARG_REGS = ["r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10"]
|
|
2268
|
+
FP_ARG_REGS = []
|
|
2269
|
+
RETURN_VAL = SimRegArg("r3", 4)
|
|
2270
|
+
RETURN_ADDR = SimRegArg("ip_at_syscall", 4)
|
|
2271
|
+
ARCH = archinfo.ArchPPC32
|
|
2272
|
+
|
|
2273
|
+
ERROR_REG = SimRegArg("cr0_0", 1)
|
|
2274
|
+
SYSCALL_ERRNO_START = -515
|
|
2275
|
+
|
|
2276
|
+
@classmethod
|
|
2277
|
+
def _match(cls, arch, args, sp_delta): # pylint: disable=unused-argument
|
|
2278
|
+
# never appears anywhere except syscalls
|
|
2279
|
+
return False
|
|
2280
|
+
|
|
2281
|
+
@staticmethod
|
|
2282
|
+
def syscall_num(state):
|
|
2283
|
+
return state.regs.r0
|
|
2284
|
+
|
|
2285
|
+
|
|
2286
|
+
class SimCCPowerPC64(SimCC):
|
|
2287
|
+
ARG_REGS = ["r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10"]
|
|
2288
|
+
FP_ARG_REGS = [] # TODO: ???
|
|
2289
|
+
STACKARG_SP_BUFF = 0x70
|
|
2290
|
+
RETURN_ADDR = SimRegArg("lr", 8)
|
|
2291
|
+
RETURN_VAL = SimRegArg("r3", 8)
|
|
2292
|
+
ARCH = archinfo.ArchPPC64
|
|
2293
|
+
|
|
2294
|
+
|
|
2295
|
+
class SimCCPowerPC64LinuxSyscall(SimCCSyscall):
|
|
2296
|
+
# TODO: Make sure all the information is correct
|
|
2297
|
+
ARG_REGS = ["r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10"]
|
|
2298
|
+
FP_ARG_REGS = []
|
|
2299
|
+
RETURN_VAL = SimRegArg("r3", 8)
|
|
2300
|
+
RETURN_ADDR = SimRegArg("ip_at_syscall", 8)
|
|
2301
|
+
ARCH = archinfo.ArchPPC64
|
|
2302
|
+
|
|
2303
|
+
ERROR_REG = SimRegArg("cr0_0", 1)
|
|
2304
|
+
SYSCALL_ERRNO_START = -515
|
|
2305
|
+
|
|
2306
|
+
@classmethod
|
|
2307
|
+
def _match(cls, arch, args, sp_delta): # pylint: disable=unused-argument
|
|
2308
|
+
# never appears anywhere except syscalls
|
|
2309
|
+
return False
|
|
2310
|
+
|
|
2311
|
+
@staticmethod
|
|
2312
|
+
def syscall_num(state):
|
|
2313
|
+
return state.regs.r0
|
|
2314
|
+
|
|
2315
|
+
|
|
2316
|
+
class SimCCSoot(SimCC):
|
|
2317
|
+
ARCH = archinfo.ArchSoot
|
|
2318
|
+
ARG_REGS = []
|
|
2319
|
+
|
|
2320
|
+
def setup_callsite(self, state, ret_addr, args, prototype, stack_base=None, alloc_base=None, grow_like_stack=True):
|
|
2321
|
+
angr.engines.SootMixin.setup_callsite(state, args, ret_addr)
|
|
2322
|
+
|
|
2323
|
+
@staticmethod
|
|
2324
|
+
def guess_prototype(args, prototype=None):
|
|
2325
|
+
# uhhhhhhhhhhhhhhhh
|
|
2326
|
+
return None
|
|
2327
|
+
|
|
2328
|
+
|
|
2329
|
+
class SimCCUnknown(SimCC):
|
|
2330
|
+
"""
|
|
2331
|
+
Represent an unknown calling convention.
|
|
2332
|
+
"""
|
|
2333
|
+
|
|
2334
|
+
@staticmethod
|
|
2335
|
+
def _match(arch, args, sp_delta): # type:ignore # pylint: disable=unused-argument
|
|
2336
|
+
# It always returns True
|
|
2337
|
+
return True
|
|
2338
|
+
|
|
2339
|
+
def __repr__(self):
|
|
2340
|
+
return f"<SimCCUnknown - {self.arch.name}>"
|
|
2341
|
+
|
|
2342
|
+
|
|
2343
|
+
class SimCCS390X(SimCC):
|
|
2344
|
+
ARG_REGS = ["r2", "r3", "r4", "r5", "r6"]
|
|
2345
|
+
FP_ARG_REGS = ["f0", "f2", "f4", "f6"]
|
|
2346
|
+
STACKARG_SP_BUFF = 0xA0
|
|
2347
|
+
RETURN_ADDR = SimRegArg("r14", 8)
|
|
2348
|
+
RETURN_VAL = SimRegArg("r2", 8)
|
|
2349
|
+
ARCH = archinfo.ArchS390X
|
|
2350
|
+
|
|
2351
|
+
|
|
2352
|
+
class SimCCS390XLinuxSyscall(SimCCSyscall):
|
|
2353
|
+
ARG_REGS = ["r2", "r3", "r4", "r5", "r6", "r7"]
|
|
2354
|
+
FP_ARG_REGS = []
|
|
2355
|
+
RETURN_VAL = SimRegArg("r2", 8)
|
|
2356
|
+
RETURN_ADDR = SimRegArg("ip_at_syscall", 8)
|
|
2357
|
+
ARCH = archinfo.ArchS390X
|
|
2358
|
+
|
|
2359
|
+
@classmethod
|
|
2360
|
+
def _match(cls, arch, args, sp_delta): # pylint: disable=unused-argument
|
|
2361
|
+
# never appears anywhere except syscalls
|
|
2362
|
+
return False
|
|
2363
|
+
|
|
2364
|
+
@staticmethod
|
|
2365
|
+
def syscall_num(state):
|
|
2366
|
+
return state.regs.r1
|
|
2367
|
+
|
|
2368
|
+
|
|
2369
|
+
CC: dict[str, dict[str, list[type[SimCC]]]] = {
|
|
2370
|
+
"AMD64": {
|
|
2371
|
+
"default": [SimCCSystemVAMD64],
|
|
2372
|
+
"Linux": [SimCCSystemVAMD64],
|
|
2373
|
+
"Win32": [SimCCMicrosoftAMD64],
|
|
2374
|
+
},
|
|
2375
|
+
"X86": {
|
|
2376
|
+
"default": [SimCCCdecl],
|
|
2377
|
+
"Linux": [SimCCCdecl],
|
|
2378
|
+
"CGC": [SimCCCdecl],
|
|
2379
|
+
"Win32": [SimCCMicrosoftCdecl, SimCCMicrosoftFastcall, SimCCMicrosoftThiscall],
|
|
2380
|
+
},
|
|
2381
|
+
"ARMEL": {
|
|
2382
|
+
"default": [SimCCARM],
|
|
2383
|
+
"Linux": [SimCCARM],
|
|
2384
|
+
},
|
|
2385
|
+
"ARMHF": {
|
|
2386
|
+
"default": [SimCCARMHF, SimCCARM],
|
|
2387
|
+
"Linux": [SimCCARMHF, SimCCARM],
|
|
2388
|
+
},
|
|
2389
|
+
"ARMCortexM": {
|
|
2390
|
+
"default": [SimCCARMHF, SimCCARM],
|
|
2391
|
+
"Linux": [SimCCARMHF, SimCCARM],
|
|
2392
|
+
},
|
|
2393
|
+
"MIPS32": {
|
|
2394
|
+
"default": [SimCCO32],
|
|
2395
|
+
"Linux": [SimCCO32],
|
|
2396
|
+
},
|
|
2397
|
+
"MIPS64": {
|
|
2398
|
+
"default": [SimCCN64],
|
|
2399
|
+
"Linux": [SimCCN64],
|
|
2400
|
+
},
|
|
2401
|
+
"PPC32": {
|
|
2402
|
+
"default": [SimCCPowerPC],
|
|
2403
|
+
"Linux": [SimCCPowerPC],
|
|
2404
|
+
},
|
|
2405
|
+
"PPC64": {
|
|
2406
|
+
"default": [SimCCPowerPC64],
|
|
2407
|
+
"Linux": [SimCCPowerPC64],
|
|
2408
|
+
},
|
|
2409
|
+
"AARCH64": {
|
|
2410
|
+
"default": [SimCCAArch64],
|
|
2411
|
+
"Linux": [SimCCAArch64],
|
|
2412
|
+
},
|
|
2413
|
+
"S390X": {
|
|
2414
|
+
"default": [SimCCS390X],
|
|
2415
|
+
"Linux": [SimCCS390X],
|
|
2416
|
+
},
|
|
2417
|
+
}
|
|
2418
|
+
|
|
2419
|
+
|
|
2420
|
+
DEFAULT_CC: dict[str, dict[str, type[SimCC]]] = {
|
|
2421
|
+
"AMD64": {"Linux": SimCCSystemVAMD64, "Win32": SimCCMicrosoftAMD64},
|
|
2422
|
+
"X86": {"Linux": SimCCCdecl, "CGC": SimCCCdecl, "Win32": SimCCMicrosoftCdecl},
|
|
2423
|
+
"ARMEL": {"Linux": SimCCARM},
|
|
2424
|
+
"ARMHF": {"Linux": SimCCARMHF},
|
|
2425
|
+
"ARMCortexM": {"Linux": SimCCARMHF},
|
|
2426
|
+
"MIPS32": {"Linux": SimCCO32},
|
|
2427
|
+
"MIPS64": {"Linux": SimCCN64},
|
|
2428
|
+
"PPC32": {"Linux": SimCCPowerPC},
|
|
2429
|
+
"PPC64": {"Linux": SimCCPowerPC64},
|
|
2430
|
+
"AARCH64": {"Linux": SimCCAArch64},
|
|
2431
|
+
"Soot": {"Linux": SimCCSoot},
|
|
2432
|
+
"AVR8": {"Linux": SimCCUnknown},
|
|
2433
|
+
"MSP": {"Linux": SimCCUnknown},
|
|
2434
|
+
"S390X": {"Linux": SimCCS390X},
|
|
2435
|
+
}
|
|
2436
|
+
|
|
2437
|
+
|
|
2438
|
+
def register_default_cc(arch: str, cc: type[SimCC], platform: str = "Linux"):
|
|
2439
|
+
if arch not in DEFAULT_CC:
|
|
2440
|
+
DEFAULT_CC[arch] = {}
|
|
2441
|
+
DEFAULT_CC[arch][platform] = cc
|
|
2442
|
+
if arch not in CC:
|
|
2443
|
+
CC[arch] = {}
|
|
2444
|
+
if platform not in CC[arch]:
|
|
2445
|
+
CC[arch][platform] = [cc]
|
|
2446
|
+
if platform != "default":
|
|
2447
|
+
CC[arch]["default"] = [cc]
|
|
2448
|
+
else:
|
|
2449
|
+
if cc not in CC[arch][platform]:
|
|
2450
|
+
CC[arch][platform].append(cc)
|
|
2451
|
+
|
|
2452
|
+
|
|
2453
|
+
ARCH_NAME_ALIASES = {
|
|
2454
|
+
"X86": ["x8632"],
|
|
2455
|
+
"AMD64": ["x86-64", "x86_64", "x8664"],
|
|
2456
|
+
"ARMEL": [],
|
|
2457
|
+
"ARMHF": [],
|
|
2458
|
+
"ARMCortexM": [],
|
|
2459
|
+
"AARCH64": ["arm64", "aarch64"],
|
|
2460
|
+
"MIPS32": [],
|
|
2461
|
+
"MIPS64": [],
|
|
2462
|
+
"PPC32": ["powerpc32"],
|
|
2463
|
+
"PPC64": ["powerpc64"],
|
|
2464
|
+
"Soot": [],
|
|
2465
|
+
"AVR8": ["avr8"],
|
|
2466
|
+
"MSP": [],
|
|
2467
|
+
"S390X": [],
|
|
2468
|
+
}
|
|
2469
|
+
|
|
2470
|
+
ALIAS_TO_ARCH_NAME = {}
|
|
2471
|
+
for k, vs in ARCH_NAME_ALIASES.items():
|
|
2472
|
+
for v in vs:
|
|
2473
|
+
ALIAS_TO_ARCH_NAME[v] = k
|
|
2474
|
+
|
|
2475
|
+
|
|
2476
|
+
def default_cc( # pylint:disable=unused-argument
|
|
2477
|
+
arch: str,
|
|
2478
|
+
platform: str | None = "Linux",
|
|
2479
|
+
language: str | None = None,
|
|
2480
|
+
syscall: bool = False,
|
|
2481
|
+
default: type[SimCC] | None = None,
|
|
2482
|
+
) -> type[SimCC] | None:
|
|
2483
|
+
"""
|
|
2484
|
+
Return the default calling convention for a given architecture, platform, and language combination.
|
|
2485
|
+
|
|
2486
|
+
:param arch: The architecture name.
|
|
2487
|
+
:param platform: The platform name (e.g., "Linux" or "Win32").
|
|
2488
|
+
:param language: The programming language name (e.g., "go").
|
|
2489
|
+
:param syscall: Return syscall convention (True), or normal calling convention (False, default).
|
|
2490
|
+
:param default: The default calling convention to return if nothing fits.
|
|
2491
|
+
:return: A default calling convention class if we can find one for the architecture, platform, and
|
|
2492
|
+
language combination, or the default if nothing fits.
|
|
2493
|
+
"""
|
|
2494
|
+
|
|
2495
|
+
if platform is None:
|
|
2496
|
+
platform = "Linux"
|
|
2497
|
+
|
|
2498
|
+
cc_map = SYSCALL_CC if syscall else DEFAULT_CC
|
|
2499
|
+
|
|
2500
|
+
if arch in cc_map:
|
|
2501
|
+
if platform not in cc_map[arch]:
|
|
2502
|
+
if default is not None:
|
|
2503
|
+
return default
|
|
2504
|
+
if "Linux" in cc_map[arch]:
|
|
2505
|
+
return cc_map[arch]["Linux"]
|
|
2506
|
+
if "default" in cc_map[arch]:
|
|
2507
|
+
return cc_map[arch]["default"]
|
|
2508
|
+
return cc_map[arch][platform]
|
|
2509
|
+
|
|
2510
|
+
alias = unify_arch_name(arch)
|
|
2511
|
+
if alias not in cc_map or platform not in cc_map[alias]:
|
|
2512
|
+
return default
|
|
2513
|
+
return cc_map[alias][platform]
|
|
2514
|
+
|
|
2515
|
+
|
|
2516
|
+
def unify_arch_name(arch: str) -> str:
|
|
2517
|
+
"""
|
|
2518
|
+
Return the unified architecture name.
|
|
2519
|
+
|
|
2520
|
+
:param arch: The architecture name.
|
|
2521
|
+
:return: A unified architecture name.
|
|
2522
|
+
"""
|
|
2523
|
+
|
|
2524
|
+
if ":" in arch:
|
|
2525
|
+
# Sleigh architecture names
|
|
2526
|
+
chunks = arch.lower().split(":")
|
|
2527
|
+
if len(chunks) >= 3:
|
|
2528
|
+
arch_base, _, bits = chunks[:3]
|
|
2529
|
+
|
|
2530
|
+
if arch_base in ALIAS_TO_ARCH_NAME:
|
|
2531
|
+
return ALIAS_TO_ARCH_NAME[arch_base]
|
|
2532
|
+
|
|
2533
|
+
base_with_bits = f"{arch_base}{bits}"
|
|
2534
|
+
if base_with_bits in ALIAS_TO_ARCH_NAME:
|
|
2535
|
+
return ALIAS_TO_ARCH_NAME[base_with_bits]
|
|
2536
|
+
|
|
2537
|
+
return arch
|
|
2538
|
+
|
|
2539
|
+
|
|
2540
|
+
SYSCALL_CC: dict[str, dict[str, type[SimCCSyscall]]] = {
|
|
2541
|
+
"X86": {
|
|
2542
|
+
"default": SimCCX86LinuxSyscall,
|
|
2543
|
+
"Linux": SimCCX86LinuxSyscall,
|
|
2544
|
+
"Win32": SimCCX86WindowsSyscall,
|
|
2545
|
+
"CGC": SimCCX86LinuxSyscall,
|
|
2546
|
+
},
|
|
2547
|
+
"AMD64": {
|
|
2548
|
+
"default": SimCCAMD64LinuxSyscall,
|
|
2549
|
+
"Linux": SimCCAMD64LinuxSyscall,
|
|
2550
|
+
"Win32": SimCCAMD64WindowsSyscall,
|
|
2551
|
+
},
|
|
2552
|
+
"ARMEL": {
|
|
2553
|
+
"default": SimCCARMLinuxSyscall,
|
|
2554
|
+
"Linux": SimCCARMLinuxSyscall,
|
|
2555
|
+
},
|
|
2556
|
+
"ARMCortexM": {
|
|
2557
|
+
# FIXME: TODO: This is wrong. Fill in with a real CC when we support CM syscalls
|
|
2558
|
+
"default": SimCCARMLinuxSyscall,
|
|
2559
|
+
},
|
|
2560
|
+
"ARMHF": {
|
|
2561
|
+
"default": SimCCARMLinuxSyscall,
|
|
2562
|
+
"Linux": SimCCARMLinuxSyscall,
|
|
2563
|
+
},
|
|
2564
|
+
"AARCH64": {
|
|
2565
|
+
"default": SimCCAArch64LinuxSyscall,
|
|
2566
|
+
"Linux": SimCCAArch64LinuxSyscall,
|
|
2567
|
+
},
|
|
2568
|
+
"MIPS32": {
|
|
2569
|
+
"default": SimCCO32LinuxSyscall,
|
|
2570
|
+
"Linux": SimCCO32LinuxSyscall,
|
|
2571
|
+
},
|
|
2572
|
+
"MIPS64": {
|
|
2573
|
+
"default": SimCCN64LinuxSyscall,
|
|
2574
|
+
"Linux": SimCCN64LinuxSyscall,
|
|
2575
|
+
},
|
|
2576
|
+
"PPC32": {
|
|
2577
|
+
"default": SimCCPowerPCLinuxSyscall,
|
|
2578
|
+
"Linux": SimCCPowerPCLinuxSyscall,
|
|
2579
|
+
},
|
|
2580
|
+
"PPC64": {
|
|
2581
|
+
"default": SimCCPowerPC64LinuxSyscall,
|
|
2582
|
+
"Linux": SimCCPowerPC64LinuxSyscall,
|
|
2583
|
+
},
|
|
2584
|
+
"S390X": {
|
|
2585
|
+
"default": SimCCS390XLinuxSyscall,
|
|
2586
|
+
"Linux": SimCCS390XLinuxSyscall,
|
|
2587
|
+
},
|
|
2588
|
+
"RISCV64": {
|
|
2589
|
+
"default": SimCCRISCV64LinuxSyscall,
|
|
2590
|
+
"Linux": SimCCRISCV64LinuxSyscall,
|
|
2591
|
+
},
|
|
2592
|
+
}
|
|
2593
|
+
|
|
2594
|
+
|
|
2595
|
+
def register_syscall_cc(arch, os, cc):
|
|
2596
|
+
if arch not in SYSCALL_CC:
|
|
2597
|
+
SYSCALL_CC[arch] = {}
|
|
2598
|
+
SYSCALL_CC[arch][os] = cc
|
|
2599
|
+
|
|
2600
|
+
|
|
2601
|
+
CC_NAMES = {}
|
|
2602
|
+
|
|
2603
|
+
cls_queue = [SimCC]
|
|
2604
|
+
while cls_queue:
|
|
2605
|
+
cls_ = cls_queue.pop()
|
|
2606
|
+
if not cls_.__subclasses__():
|
|
2607
|
+
CC_NAMES[cls_.__name__] = cls_
|
|
2608
|
+
else:
|
|
2609
|
+
cls_queue.extend(cls_.__subclasses__())
|
|
2610
|
+
|
|
2611
|
+
|
|
2612
|
+
SyscallCC = SYSCALL_CC
|
|
2613
|
+
DefaultCC = DEFAULT_CC
|