angr 9.2.102__py3-none-manylinux2014_x86_64.whl → 9.2.103__py3-none-manylinux2014_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.
Potentially problematic release.
This version of angr might be problematic. Click here for more details.
- angr/__init__.py +1 -1
- angr/analyses/analysis.py +7 -6
- angr/analyses/calling_convention.py +33 -35
- angr/analyses/cdg.py +2 -4
- angr/analyses/cfg/cfb.py +4 -3
- angr/analyses/cfg/cfg_base.py +14 -14
- angr/analyses/cfg/cfg_emulated.py +3 -4
- angr/analyses/cfg/cfg_fast.py +46 -46
- angr/analyses/cfg/cfg_fast_soot.py +1 -2
- angr/analyses/cfg/cfg_job_base.py +2 -2
- angr/analyses/cfg/indirect_jump_resolvers/jumptable.py +14 -13
- angr/analyses/cfg/indirect_jump_resolvers/mips_elf_fast.py +5 -5
- angr/analyses/cfg_slice_to_sink/cfg_slice_to_sink.py +3 -3
- angr/analyses/complete_calling_conventions.py +13 -12
- angr/analyses/data_dep/data_dependency_analysis.py +24 -24
- angr/analyses/data_dep/dep_nodes.py +3 -3
- angr/analyses/ddg.py +1 -2
- angr/analyses/decompiler/ail_simplifier.py +35 -34
- angr/analyses/decompiler/block_io_finder.py +20 -20
- angr/analyses/decompiler/block_similarity.py +4 -6
- angr/analyses/decompiler/block_simplifier.py +17 -16
- angr/analyses/decompiler/callsite_maker.py +25 -10
- angr/analyses/decompiler/ccall_rewriters/amd64_ccalls.py +1 -3
- angr/analyses/decompiler/ccall_rewriters/rewriter_base.py +2 -4
- angr/analyses/decompiler/clinic.py +250 -45
- angr/analyses/decompiler/condition_processor.py +15 -8
- angr/analyses/decompiler/decompilation_cache.py +7 -7
- angr/analyses/decompiler/decompilation_options.py +4 -4
- angr/analyses/decompiler/decompiler.py +19 -15
- angr/analyses/decompiler/expression_counters.py +10 -9
- angr/analyses/decompiler/goto_manager.py +2 -4
- angr/analyses/decompiler/graph_region.py +9 -9
- angr/analyses/decompiler/jump_target_collector.py +1 -2
- angr/analyses/decompiler/optimization_passes/__init__.py +4 -3
- angr/analyses/decompiler/optimization_passes/code_motion.py +5 -6
- angr/analyses/decompiler/optimization_passes/const_derefs.py +4 -4
- angr/analyses/decompiler/optimization_passes/deadblock_remover.py +73 -0
- angr/analyses/decompiler/optimization_passes/engine_base.py +25 -3
- angr/analyses/decompiler/optimization_passes/expr_op_swapper.py +6 -5
- angr/analyses/decompiler/optimization_passes/flip_boolean_cmp.py +2 -2
- angr/analyses/decompiler/optimization_passes/inlined_string_transformation_simplifier.py +3 -0
- angr/analyses/decompiler/optimization_passes/ite_expr_converter.py +2 -2
- angr/analyses/decompiler/optimization_passes/lowered_switch_simplifier.py +17 -17
- angr/analyses/decompiler/optimization_passes/optimization_pass.py +12 -13
- angr/analyses/decompiler/optimization_passes/register_save_area_simplifier.py +25 -21
- angr/analyses/decompiler/optimization_passes/ret_addr_save_simplifier.py +3 -3
- angr/analyses/decompiler/optimization_passes/ret_deduplicator.py +1 -2
- angr/analyses/decompiler/optimization_passes/return_duplicator_base.py +7 -7
- angr/analyses/decompiler/optimization_passes/spilled_register_finder.py +18 -0
- angr/analyses/decompiler/optimization_passes/stack_canary_simplifier.py +2 -3
- angr/analyses/decompiler/optimization_passes/win_stack_canary_simplifier.py +1 -2
- angr/analyses/decompiler/optimization_passes/x86_gcc_getpc_simplifier.py +2 -2
- angr/analyses/decompiler/peephole_optimizations/__init__.py +4 -3
- angr/analyses/decompiler/peephole_optimizations/base.py +13 -15
- angr/analyses/decompiler/peephole_optimizations/bswap.py +1 -3
- angr/analyses/decompiler/peephole_optimizations/cmpord_rewriter.py +72 -0
- angr/analyses/decompiler/peephole_optimizations/const_mull_a_shift.py +1 -2
- angr/analyses/decompiler/peephole_optimizations/eager_eval.py +1 -1
- angr/analyses/decompiler/peephole_optimizations/inlined_strcpy.py +5 -10
- angr/analyses/decompiler/peephole_optimizations/inlined_strcpy_consolidation.py +3 -4
- angr/analyses/decompiler/peephole_optimizations/inlined_wstrcpy.py +7 -10
- angr/analyses/decompiler/peephole_optimizations/rewrite_bit_extractions.py +2 -3
- angr/analyses/decompiler/peephole_optimizations/sar_to_signed_div.py +1 -2
- angr/analyses/decompiler/peephole_optimizations/tidy_stack_addr.py +4 -4
- angr/analyses/decompiler/redundant_label_remover.py +4 -5
- angr/analyses/decompiler/region_identifier.py +4 -5
- angr/analyses/decompiler/region_simplifiers/cascading_cond_transformer.py +1 -2
- angr/analyses/decompiler/region_simplifiers/expr_folding.py +19 -20
- angr/analyses/decompiler/region_simplifiers/goto.py +2 -3
- angr/analyses/decompiler/region_simplifiers/loop.py +1 -2
- angr/analyses/decompiler/region_simplifiers/node_address_finder.py +1 -2
- angr/analyses/decompiler/region_simplifiers/region_simplifier.py +1 -3
- angr/analyses/decompiler/region_simplifiers/switch_cluster_simplifier.py +19 -19
- angr/analyses/decompiler/return_maker.py +1 -2
- angr/analyses/decompiler/structured_codegen/base.py +5 -6
- angr/analyses/decompiler/structured_codegen/c.py +39 -38
- angr/analyses/decompiler/structuring/__init__.py +1 -1
- angr/analyses/decompiler/structuring/dream.py +17 -16
- angr/analyses/decompiler/structuring/phoenix.py +45 -46
- angr/analyses/decompiler/structuring/recursive_structurer.py +4 -4
- angr/analyses/decompiler/structuring/structurer_base.py +16 -15
- angr/analyses/decompiler/structuring/structurer_nodes.py +10 -9
- angr/analyses/decompiler/utils.py +17 -16
- angr/analyses/disassembly.py +7 -6
- angr/analyses/flirt.py +9 -9
- angr/analyses/forward_analysis/forward_analysis.py +15 -14
- angr/analyses/forward_analysis/visitors/function_graph.py +1 -2
- angr/analyses/forward_analysis/visitors/graph.py +16 -15
- angr/analyses/propagator/engine_ail.py +30 -26
- angr/analyses/propagator/outdated_definition_walker.py +8 -7
- angr/analyses/propagator/propagator.py +11 -13
- angr/analyses/proximity_graph.py +21 -21
- angr/analyses/reaching_definitions/__init__.py +3 -3
- angr/analyses/reaching_definitions/call_trace.py +3 -6
- angr/analyses/reaching_definitions/dep_graph.py +41 -48
- angr/analyses/reaching_definitions/engine_ail.py +11 -5
- angr/analyses/reaching_definitions/engine_vex.py +9 -8
- angr/analyses/reaching_definitions/function_handler.py +51 -34
- angr/analyses/reaching_definitions/heap_allocator.py +3 -4
- angr/analyses/reaching_definitions/rd_initializer.py +8 -8
- angr/analyses/reaching_definitions/rd_state.py +57 -58
- angr/analyses/reaching_definitions/reaching_definitions.py +18 -17
- angr/analyses/reaching_definitions/subject.py +2 -3
- angr/analyses/stack_pointer_tracker.py +15 -6
- angr/analyses/typehoon/dfa.py +4 -4
- angr/analyses/typehoon/simple_solver.py +48 -52
- angr/analyses/typehoon/translator.py +3 -6
- angr/analyses/typehoon/typeconsts.py +13 -14
- angr/analyses/typehoon/typehoon.py +9 -9
- angr/analyses/typehoon/typevars.py +18 -17
- angr/analyses/variable_recovery/engine_ail.py +5 -5
- angr/analyses/variable_recovery/engine_base.py +25 -21
- angr/analyses/variable_recovery/irsb_scanner.py +8 -9
- angr/analyses/variable_recovery/variable_recovery.py +1 -2
- angr/analyses/variable_recovery/variable_recovery_base.py +14 -13
- angr/analyses/variable_recovery/variable_recovery_fast.py +8 -8
- angr/analyses/veritesting.py +1 -2
- angr/analyses/vfg.py +57 -56
- angr/analyses/xrefs.py +1 -2
- angr/angrdb/db.py +7 -7
- angr/angrdb/serializers/kb.py +16 -13
- angr/angrdb/serializers/loader.py +1 -2
- angr/angrdb/serializers/structured_code.py +2 -2
- angr/annocfg.py +1 -2
- angr/block.py +16 -6
- angr/calling_conventions.py +27 -27
- angr/code_location.py +8 -8
- angr/codenode.py +1 -2
- angr/concretization_strategies/max.py +1 -3
- angr/distributed/server.py +1 -3
- angr/distributed/worker.py +1 -2
- angr/engines/engine.py +2 -3
- angr/engines/light/engine.py +4 -4
- angr/engines/pcode/behavior.py +20 -2
- angr/engines/pcode/emulate.py +1 -1
- angr/engines/pcode/engine.py +7 -7
- angr/engines/pcode/lifter.py +78 -77
- angr/engines/vex/claripy/ccall.py +1 -2
- angr/engines/vex/claripy/datalayer.py +1 -2
- angr/engines/vex/light/light.py +1 -2
- angr/exploration_techniques/tracer.py +4 -4
- angr/factory.py +12 -15
- angr/flirt/__init__.py +8 -8
- angr/flirt/build_sig.py +2 -3
- angr/keyed_region.py +2 -2
- angr/knowledge_base/knowledge_base.py +3 -3
- angr/knowledge_plugins/callsite_prototypes.py +4 -6
- angr/knowledge_plugins/cfg/cfg_manager.py +19 -6
- angr/knowledge_plugins/cfg/cfg_model.py +26 -27
- angr/knowledge_plugins/cfg/cfg_node.py +2 -2
- angr/knowledge_plugins/cfg/indirect_jump.py +6 -8
- angr/knowledge_plugins/cfg/memory_data.py +8 -9
- angr/knowledge_plugins/custom_strings.py +1 -3
- angr/knowledge_plugins/debug_variables.py +2 -2
- angr/knowledge_plugins/functions/function.py +21 -22
- angr/knowledge_plugins/functions/function_manager.py +5 -5
- angr/knowledge_plugins/indirect_jumps.py +1 -3
- angr/knowledge_plugins/key_definitions/atoms.py +7 -7
- angr/knowledge_plugins/key_definitions/definition.py +14 -14
- angr/knowledge_plugins/key_definitions/environment.py +5 -7
- angr/knowledge_plugins/key_definitions/heap_address.py +1 -3
- angr/knowledge_plugins/key_definitions/key_definition_manager.py +3 -2
- angr/knowledge_plugins/key_definitions/live_definitions.py +60 -59
- angr/knowledge_plugins/key_definitions/liveness.py +16 -16
- angr/knowledge_plugins/key_definitions/rd_model.py +15 -15
- angr/knowledge_plugins/key_definitions/uses.py +11 -11
- angr/knowledge_plugins/patches.py +4 -8
- angr/knowledge_plugins/propagations/prop_value.py +10 -9
- angr/knowledge_plugins/propagations/propagation_manager.py +3 -5
- angr/knowledge_plugins/propagations/propagation_model.py +9 -9
- angr/knowledge_plugins/propagations/states.py +52 -22
- angr/knowledge_plugins/structured_code/manager.py +2 -2
- angr/knowledge_plugins/sync/sync_controller.py +3 -3
- angr/knowledge_plugins/variables/variable_access.py +4 -4
- angr/knowledge_plugins/variables/variable_manager.py +39 -39
- angr/knowledge_plugins/xrefs/xref.py +9 -11
- angr/knowledge_plugins/xrefs/xref_manager.py +3 -4
- angr/misc/ansi.py +1 -2
- angr/misc/autoimport.py +3 -3
- angr/misc/plugins.py +9 -9
- angr/procedures/definitions/__init__.py +16 -16
- angr/procedures/definitions/linux_kernel.py +1 -1
- angr/procedures/definitions/parse_win32json.py +1 -1
- angr/procedures/java_jni/__init__.py +1 -1
- angr/procedures/java_jni/array_operations.py +1 -2
- angr/procedures/java_jni/method_calls.py +1 -2
- angr/procedures/posix/inet_ntoa.py +1 -2
- angr/procedures/stubs/format_parser.py +3 -3
- angr/project.py +13 -11
- angr/sim_manager.py +12 -12
- angr/sim_procedure.py +7 -3
- angr/sim_state.py +2 -2
- angr/sim_type.py +60 -45
- angr/sim_variable.py +5 -5
- angr/simos/simos.py +1 -2
- angr/simos/userland.py +1 -2
- angr/state_plugins/callstack.py +3 -2
- angr/state_plugins/history.py +1 -2
- angr/state_plugins/solver.py +34 -34
- angr/storage/memory_mixins/__init__.py +4 -3
- angr/storage/memory_mixins/actions_mixin.py +1 -3
- angr/storage/memory_mixins/address_concretization_mixin.py +1 -3
- angr/storage/memory_mixins/convenient_mappings_mixin.py +3 -4
- angr/storage/memory_mixins/default_filler_mixin.py +1 -1
- angr/storage/memory_mixins/label_merger_mixin.py +2 -2
- angr/storage/memory_mixins/multi_value_merger_mixin.py +4 -3
- angr/storage/memory_mixins/paged_memory/page_backer_mixins.py +9 -8
- angr/storage/memory_mixins/paged_memory/paged_memory_mixin.py +12 -11
- angr/storage/memory_mixins/paged_memory/pages/cooperation.py +8 -8
- angr/storage/memory_mixins/paged_memory/pages/history_tracking_mixin.py +2 -3
- angr/storage/memory_mixins/paged_memory/pages/list_page.py +10 -11
- angr/storage/memory_mixins/paged_memory/pages/multi_values.py +11 -10
- angr/storage/memory_mixins/paged_memory/pages/mv_list_page.py +18 -17
- angr/storage/memory_mixins/paged_memory/pages/ultra_page.py +12 -11
- angr/storage/memory_mixins/regioned_memory/abstract_address_descriptor.py +3 -3
- angr/storage/memory_mixins/regioned_memory/abstract_merger_mixin.py +3 -2
- angr/storage/memory_mixins/regioned_memory/region_data.py +1 -2
- angr/storage/memory_mixins/regioned_memory/region_meta_mixin.py +2 -2
- angr/storage/memory_mixins/regioned_memory/regioned_address_concretization_mixin.py +3 -3
- angr/storage/memory_mixins/regioned_memory/regioned_memory_mixin.py +18 -21
- angr/storage/memory_mixins/size_resolution_mixin.py +1 -2
- angr/storage/memory_mixins/symbolic_merger_mixin.py +3 -2
- angr/storage/memory_mixins/top_merger_mixin.py +3 -2
- angr/storage/memory_object.py +2 -4
- angr/utils/algo.py +3 -2
- angr/utils/dynamic_dictlist.py +5 -5
- angr/utils/formatting.py +4 -4
- angr/utils/funcid.py +1 -2
- angr/utils/graph.py +5 -6
- angr/utils/library.py +5 -5
- angr/utils/mp.py +5 -4
- angr/utils/segment_list.py +3 -4
- angr/utils/typing.py +3 -2
- {angr-9.2.102.dist-info → angr-9.2.103.dist-info}/METADATA +9 -11
- {angr-9.2.102.dist-info → angr-9.2.103.dist-info}/RECORD +239 -236
- {angr-9.2.102.dist-info → angr-9.2.103.dist-info}/LICENSE +0 -0
- {angr-9.2.102.dist-info → angr-9.2.103.dist-info}/WHEEL +0 -0
- {angr-9.2.102.dist-info → angr-9.2.103.dist-info}/entry_points.txt +0 -0
- {angr-9.2.102.dist-info → angr-9.2.103.dist-info}/top_level.txt +0 -0
angr/__init__.py
CHANGED
angr/analyses/analysis.py
CHANGED
|
@@ -4,7 +4,8 @@ import sys
|
|
|
4
4
|
import contextlib
|
|
5
5
|
from collections import defaultdict
|
|
6
6
|
from inspect import Signature
|
|
7
|
-
from typing import TYPE_CHECKING, TypeVar, Type, Generic,
|
|
7
|
+
from typing import TYPE_CHECKING, TypeVar, Type, Generic, Optional
|
|
8
|
+
from collections.abc import Callable
|
|
8
9
|
|
|
9
10
|
import logging
|
|
10
11
|
import time
|
|
@@ -113,7 +114,7 @@ class AnalysesHub(PluginVendor[A]):
|
|
|
113
114
|
def reload_analyses(self): # pylint: disable=no-self-use
|
|
114
115
|
return
|
|
115
116
|
|
|
116
|
-
def _init_plugin(self, plugin_cls:
|
|
117
|
+
def _init_plugin(self, plugin_cls: type[A]) -> "AnalysisFactory[A]":
|
|
117
118
|
return AnalysisFactory(self.project, plugin_cls)
|
|
118
119
|
|
|
119
120
|
def __getstate__(self):
|
|
@@ -124,7 +125,7 @@ class AnalysesHub(PluginVendor[A]):
|
|
|
124
125
|
s, self.project = sd
|
|
125
126
|
super().__setstate__(s)
|
|
126
127
|
|
|
127
|
-
def __getitem__(self, plugin_cls:
|
|
128
|
+
def __getitem__(self, plugin_cls: type[A]) -> "AnalysisFactory[A]":
|
|
128
129
|
return AnalysisFactory(self.project, plugin_cls)
|
|
129
130
|
|
|
130
131
|
|
|
@@ -169,7 +170,7 @@ class AnalysesHubWithDefault(AnalysesHub, KnownAnalysesPlugin):
|
|
|
169
170
|
|
|
170
171
|
|
|
171
172
|
class AnalysisFactory(Generic[A]):
|
|
172
|
-
def __init__(self, project: "Project", analysis_cls:
|
|
173
|
+
def __init__(self, project: "Project", analysis_cls: type[A]):
|
|
173
174
|
self._project = project
|
|
174
175
|
self._analysis_cls = analysis_cls
|
|
175
176
|
self.__doc__ = ""
|
|
@@ -181,9 +182,9 @@ class AnalysisFactory(Generic[A]):
|
|
|
181
182
|
self,
|
|
182
183
|
fail_fast=False,
|
|
183
184
|
kb: Optional["KnowledgeBase"] = None,
|
|
184
|
-
progress_callback:
|
|
185
|
+
progress_callback: Callable | None = None,
|
|
185
186
|
show_progressbar: bool = False,
|
|
186
|
-
) ->
|
|
187
|
+
) -> type[A]:
|
|
187
188
|
@functools.wraps(self._analysis_cls.__init__)
|
|
188
189
|
def wrapper(*args, **kwargs):
|
|
189
190
|
oself = object.__new__(self._analysis_cls)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# pylint:disable=no-self-use
|
|
2
2
|
from collections import defaultdict
|
|
3
|
-
from typing import Optional,
|
|
3
|
+
from typing import Optional, Union, TYPE_CHECKING
|
|
4
4
|
import logging
|
|
5
5
|
|
|
6
6
|
import networkx
|
|
@@ -87,13 +87,13 @@ class CallingConventionAnalysis(Analysis):
|
|
|
87
87
|
|
|
88
88
|
def __init__(
|
|
89
89
|
self,
|
|
90
|
-
func:
|
|
90
|
+
func: Union["Function", int, str] | None,
|
|
91
91
|
cfg: Optional["CFGModel"] = None,
|
|
92
92
|
analyze_callsites: bool = False,
|
|
93
|
-
caller_func_addr:
|
|
94
|
-
callsite_block_addr:
|
|
95
|
-
callsite_insn_addr:
|
|
96
|
-
func_graph:
|
|
93
|
+
caller_func_addr: int | None = None,
|
|
94
|
+
callsite_block_addr: int | None = None,
|
|
95
|
+
callsite_insn_addr: int | None = None,
|
|
96
|
+
func_graph: networkx.DiGraph | None = None,
|
|
97
97
|
):
|
|
98
98
|
if func is not None and not isinstance(func, Function):
|
|
99
99
|
func = self.kb.functions[func]
|
|
@@ -106,9 +106,9 @@ class CallingConventionAnalysis(Analysis):
|
|
|
106
106
|
self.callsite_insn_addr = callsite_insn_addr
|
|
107
107
|
self._func_graph = func_graph
|
|
108
108
|
|
|
109
|
-
self.cc:
|
|
110
|
-
self.prototype:
|
|
111
|
-
self.prototype_libname:
|
|
109
|
+
self.cc: SimCC | None = None
|
|
110
|
+
self.prototype: SimTypeFunction | None = None
|
|
111
|
+
self.prototype_libname: str | None = None
|
|
112
112
|
|
|
113
113
|
if self._cfg is None and "CFGFast" in self.kb.cfgs:
|
|
114
114
|
self._cfg = self.kb.cfgs["CFGFast"]
|
|
@@ -246,7 +246,7 @@ class CallingConventionAnalysis(Analysis):
|
|
|
246
246
|
self.cc = cc
|
|
247
247
|
self.prototype = prototype
|
|
248
248
|
|
|
249
|
-
def _analyze_plt(self) ->
|
|
249
|
+
def _analyze_plt(self) -> tuple[SimCC, SimTypeFunction] | None:
|
|
250
250
|
"""
|
|
251
251
|
Get the calling convention for a PLT stub.
|
|
252
252
|
|
|
@@ -305,7 +305,7 @@ class CallingConventionAnalysis(Analysis):
|
|
|
305
305
|
|
|
306
306
|
return None
|
|
307
307
|
|
|
308
|
-
def _analyze_function(self) ->
|
|
308
|
+
def _analyze_function(self) -> tuple[SimCC, SimTypeFunction] | None:
|
|
309
309
|
"""
|
|
310
310
|
Go over the variable information in variable manager for this function, and return all uninitialized
|
|
311
311
|
register/stack variables.
|
|
@@ -368,7 +368,7 @@ class CallingConventionAnalysis(Analysis):
|
|
|
368
368
|
func = self.kb.functions[caller_addr]
|
|
369
369
|
subgraph = self._generate_callsite_subgraph(func, caller_block_addr, include_preds=include_preds)
|
|
370
370
|
|
|
371
|
-
observation_points:
|
|
371
|
+
observation_points: list = [("insn", call_insn_addr, OP_BEFORE), ("node", caller_block_addr, OP_AFTER)]
|
|
372
372
|
|
|
373
373
|
# find the return site
|
|
374
374
|
caller_block = next(iter(bb for bb in subgraph if bb.addr == caller_block_addr))
|
|
@@ -389,7 +389,7 @@ class CallingConventionAnalysis(Analysis):
|
|
|
389
389
|
self,
|
|
390
390
|
max_analyzing_callsites: int = 3,
|
|
391
391
|
include_callsite_preds: bool = False,
|
|
392
|
-
) ->
|
|
392
|
+
) -> list[CallSiteFact]: # pylint:disable=no-self-use
|
|
393
393
|
"""
|
|
394
394
|
Analyze all call sites of the function and determine the possible number of arguments and if the function
|
|
395
395
|
returns anything or not.
|
|
@@ -406,7 +406,7 @@ class CallingConventionAnalysis(Analysis):
|
|
|
406
406
|
facts = []
|
|
407
407
|
in_edges = self._cfg.graph.in_edges(node, data=True)
|
|
408
408
|
|
|
409
|
-
call_sites_by_function:
|
|
409
|
+
call_sites_by_function: dict["Function", list[tuple[int, int]]] = defaultdict(list)
|
|
410
410
|
for src, _, data in sorted(in_edges, key=lambda x: x[0].addr):
|
|
411
411
|
edge_type = data.get("jumpkind", "Ijk_Call")
|
|
412
412
|
if edge_type != "Ijk_Call":
|
|
@@ -451,7 +451,7 @@ class CallingConventionAnalysis(Analysis):
|
|
|
451
451
|
func: "Function",
|
|
452
452
|
callsite_block_addr: int,
|
|
453
453
|
include_preds: bool = False,
|
|
454
|
-
) ->
|
|
454
|
+
) -> networkx.DiGraph | None:
|
|
455
455
|
func_graph = self._func_graph if self._func_graph is not None else func.graph
|
|
456
456
|
|
|
457
457
|
the_block = next(iter(nn for nn in func_graph if nn.addr == callsite_block_addr), None)
|
|
@@ -512,7 +512,7 @@ class CallingConventionAnalysis(Analysis):
|
|
|
512
512
|
def _analyze_callsite_return_value_uses(
|
|
513
513
|
self, cc: SimCC, caller_block_addr: int, rda: ReachingDefinitionsModel, fact: CallSiteFact
|
|
514
514
|
) -> None:
|
|
515
|
-
all_defs:
|
|
515
|
+
all_defs: set["Definition"] = {
|
|
516
516
|
def_
|
|
517
517
|
for def_ in rda.all_uses._uses_by_definition.keys()
|
|
518
518
|
if (
|
|
@@ -556,9 +556,9 @@ class CallingConventionAnalysis(Analysis):
|
|
|
556
556
|
) -> None:
|
|
557
557
|
# determine if potential register and stack arguments are set
|
|
558
558
|
state = rda.observed_results[("insn", call_insn_addr, OP_BEFORE)]
|
|
559
|
-
defs_by_reg_offset:
|
|
560
|
-
all_reg_defs:
|
|
561
|
-
all_stack_defs:
|
|
559
|
+
defs_by_reg_offset: dict[int, list["Definition"]] = defaultdict(list)
|
|
560
|
+
all_reg_defs: set["Definition"] = get_all_definitions(state.registers)
|
|
561
|
+
all_stack_defs: set["Definition"] = get_all_definitions(state.stack)
|
|
562
562
|
for d in all_reg_defs:
|
|
563
563
|
if (
|
|
564
564
|
isinstance(d.atom, Register)
|
|
@@ -592,7 +592,7 @@ class CallingConventionAnalysis(Analysis):
|
|
|
592
592
|
|
|
593
593
|
default_type_cls = SimTypeInt if self.project.arch.bits == 32 else SimTypeLongLong
|
|
594
594
|
arg_session = cc.arg_session(default_type_cls().with_arch(self.project.arch))
|
|
595
|
-
temp_args:
|
|
595
|
+
temp_args: list[SimFunctionArgument | None] = []
|
|
596
596
|
for _ in range(30): # at most 30 arguments
|
|
597
597
|
arg_loc = cc.next_arg(arg_session, default_type_cls().with_arch(self.project.arch))
|
|
598
598
|
if isinstance(arg_loc, SimRegArg):
|
|
@@ -621,10 +621,10 @@ class CallingConventionAnalysis(Analysis):
|
|
|
621
621
|
|
|
622
622
|
def _adjust_prototype(
|
|
623
623
|
self,
|
|
624
|
-
proto:
|
|
625
|
-
facts:
|
|
624
|
+
proto: SimTypeFunction | None,
|
|
625
|
+
facts: list[CallSiteFact],
|
|
626
626
|
update_arguments: int = UpdateArgumentsOption.DoNotUpdate,
|
|
627
|
-
) ->
|
|
627
|
+
) -> SimTypeFunction | None:
|
|
628
628
|
if proto is None:
|
|
629
629
|
return None
|
|
630
630
|
|
|
@@ -647,7 +647,7 @@ class CallingConventionAnalysis(Analysis):
|
|
|
647
647
|
|
|
648
648
|
return proto
|
|
649
649
|
|
|
650
|
-
def _args_from_vars(self, variables:
|
|
650
|
+
def _args_from_vars(self, variables: list, var_manager):
|
|
651
651
|
"""
|
|
652
652
|
Derive function arguments from input variables.
|
|
653
653
|
|
|
@@ -662,7 +662,7 @@ class CallingConventionAnalysis(Analysis):
|
|
|
662
662
|
else:
|
|
663
663
|
ret_addr_offset = self.project.arch.bytes
|
|
664
664
|
|
|
665
|
-
reg_vars_with_single_access:
|
|
665
|
+
reg_vars_with_single_access: list[SimRegisterVariable] = []
|
|
666
666
|
|
|
667
667
|
def_cc = default_cc(
|
|
668
668
|
self.project.arch.name,
|
|
@@ -702,7 +702,7 @@ class CallingConventionAnalysis(Analysis):
|
|
|
702
702
|
# we should remove all registers that are strictly callee-saved and are not used anywhere in this function
|
|
703
703
|
end_blocks = [(endpoint.addr, endpoint.size) for endpoint in self._function.endpoints_with_type["return"]]
|
|
704
704
|
|
|
705
|
-
restored_reg_vars:
|
|
705
|
+
restored_reg_vars: set[SimRegArg] = set()
|
|
706
706
|
|
|
707
707
|
# is there any instruction that restores this register in any end blocks?
|
|
708
708
|
if reg_vars_with_single_access:
|
|
@@ -713,7 +713,7 @@ class CallingConventionAnalysis(Analysis):
|
|
|
713
713
|
restored_reg_vars.add(SimRegArg(reg_name, var_.size))
|
|
714
714
|
|
|
715
715
|
else:
|
|
716
|
-
reg_offsets:
|
|
716
|
+
reg_offsets: set[int] = {r.reg for r in reg_vars_with_single_access}
|
|
717
717
|
for var_ in var_manager.get_variables(sort="reg"):
|
|
718
718
|
if var_.reg in (reg_offsets - {self.project.arch.ret_offset}):
|
|
719
719
|
# check if there is only a write to it
|
|
@@ -731,7 +731,7 @@ class CallingConventionAnalysis(Analysis):
|
|
|
731
731
|
|
|
732
732
|
return args.difference(restored_reg_vars)
|
|
733
733
|
|
|
734
|
-
def _is_sane_register_variable(self, variable: SimRegisterVariable, def_cc:
|
|
734
|
+
def _is_sane_register_variable(self, variable: SimRegisterVariable, def_cc: SimCC | None = None) -> bool:
|
|
735
735
|
"""
|
|
736
736
|
Filters all registers that are surly not members of function arguments.
|
|
737
737
|
This can be seen as a workaround, since VariableRecoveryFast sometimes gives input variables of cc_ndep (which
|
|
@@ -780,9 +780,7 @@ class CallingConventionAnalysis(Analysis):
|
|
|
780
780
|
l.critical("Unsupported architecture %s.", arch.name)
|
|
781
781
|
return True
|
|
782
782
|
|
|
783
|
-
def _reorder_args(
|
|
784
|
-
self, args: List[Union[SimRegArg, SimStackArg]], cc: SimCC
|
|
785
|
-
) -> List[Union[SimRegArg, SimStackArg]]:
|
|
783
|
+
def _reorder_args(self, args: list[SimRegArg | SimStackArg], cc: SimCC) -> list[SimRegArg | SimStackArg]:
|
|
786
784
|
"""
|
|
787
785
|
Reorder arguments according to the calling convention identified.
|
|
788
786
|
|
|
@@ -839,7 +837,7 @@ class CallingConventionAnalysis(Analysis):
|
|
|
839
837
|
|
|
840
838
|
return reg_args + int_args + fp_args + stack_args
|
|
841
839
|
|
|
842
|
-
def _guess_arg_type(self, arg: SimFunctionArgument, cc:
|
|
840
|
+
def _guess_arg_type(self, arg: SimFunctionArgument, cc: SimCC | None = None) -> SimType:
|
|
843
841
|
if cc is not None:
|
|
844
842
|
if cc.FP_ARG_REGS and isinstance(arg, SimRegArg) and arg.reg_name in cc.FP_ARG_REGS:
|
|
845
843
|
if arg.size == 4:
|
|
@@ -859,7 +857,7 @@ class CallingConventionAnalysis(Analysis):
|
|
|
859
857
|
# Unsupported for now
|
|
860
858
|
return SimTypeBottom()
|
|
861
859
|
|
|
862
|
-
def _guess_retval_type(self, cc: SimCC, ret_val_size:
|
|
860
|
+
def _guess_retval_type(self, cc: SimCC, ret_val_size: int | None) -> SimType:
|
|
863
861
|
if cc.FP_RETURN_VAL:
|
|
864
862
|
# examine the last block of the function and see which registers are assigned to
|
|
865
863
|
if self._function.ret_sites:
|
|
@@ -888,7 +886,7 @@ class CallingConventionAnalysis(Analysis):
|
|
|
888
886
|
return SimTypeInt() if cc.arch.bits == 32 else SimTypeLongLong()
|
|
889
887
|
|
|
890
888
|
@staticmethod
|
|
891
|
-
def _likely_saving_temp_reg(ail_block: ailment.Block, d: "Definition", all_reg_defs:
|
|
889
|
+
def _likely_saving_temp_reg(ail_block: ailment.Block, d: "Definition", all_reg_defs: set["Definition"]) -> bool:
|
|
892
890
|
if d.codeloc.block_addr == ail_block.addr and d.codeloc.stmt_idx < len(ail_block.statements):
|
|
893
891
|
stmt = ail_block.statements[d.codeloc.stmt_idx]
|
|
894
892
|
if isinstance(stmt, ailment.Stmt.Assignment) and isinstance(stmt.src, ailment.Expr.Register):
|
|
@@ -904,7 +902,7 @@ class CallingConventionAnalysis(Analysis):
|
|
|
904
902
|
return True
|
|
905
903
|
return False
|
|
906
904
|
|
|
907
|
-
def is_va_start_amd64(self, func: Function) ->
|
|
905
|
+
def is_va_start_amd64(self, func: Function) -> tuple[bool, int | None]:
|
|
908
906
|
# TODO: Use a better pattern matching approach
|
|
909
907
|
if len(func.block_addrs_set) < 3:
|
|
910
908
|
return False, None
|
angr/analyses/cdg.py
CHANGED
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
from typing import Optional
|
|
2
|
-
|
|
3
1
|
import logging
|
|
4
2
|
|
|
5
3
|
import networkx
|
|
@@ -28,9 +26,9 @@ class CDG(Analysis):
|
|
|
28
26
|
|
|
29
27
|
self._ancestor = None
|
|
30
28
|
self._semi = None
|
|
31
|
-
self._post_dom:
|
|
29
|
+
self._post_dom: networkx.DiGraph | None = None
|
|
32
30
|
|
|
33
|
-
self._graph:
|
|
31
|
+
self._graph: networkx.DiGraph | None = None
|
|
34
32
|
self._normalized_cfg = None
|
|
35
33
|
|
|
36
34
|
if not no_construct:
|
angr/analyses/cfg/cfb.py
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import logging
|
|
2
|
-
from typing import Any
|
|
2
|
+
from typing import Any
|
|
3
|
+
from collections.abc import Callable
|
|
3
4
|
|
|
4
5
|
import cle
|
|
5
6
|
from cle.backends.externs import KernelObject, ExternObject
|
|
@@ -95,8 +96,8 @@ class CFBlanket(Analysis):
|
|
|
95
96
|
|
|
96
97
|
def __init__(
|
|
97
98
|
self,
|
|
98
|
-
exclude_region_types:
|
|
99
|
-
on_object_added:
|
|
99
|
+
exclude_region_types: set[str] | None = None,
|
|
100
|
+
on_object_added: Callable[[int, Any], None] | None = None,
|
|
100
101
|
):
|
|
101
102
|
"""
|
|
102
103
|
:param on_object_added: Callable with parameters (addr, obj) called after an object is added to the blanket.
|
angr/analyses/cfg/cfg_base.py
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
# pylint:disable=line-too-long,multiple-statements
|
|
2
|
-
from typing import
|
|
2
|
+
from typing import Optional, TYPE_CHECKING, Any
|
|
3
3
|
import logging
|
|
4
4
|
from collections import defaultdict
|
|
5
5
|
|
|
@@ -48,7 +48,7 @@ class CFGBase(Analysis):
|
|
|
48
48
|
The base class for control flow graphs.
|
|
49
49
|
"""
|
|
50
50
|
|
|
51
|
-
tag:
|
|
51
|
+
tag: str | None = None
|
|
52
52
|
_cle_pseudo_objects = (ExternObject, KernelObject, TLSObject)
|
|
53
53
|
|
|
54
54
|
def __init__(
|
|
@@ -128,7 +128,7 @@ class CFGBase(Analysis):
|
|
|
128
128
|
|
|
129
129
|
# Store all the functions analyzed before the set is cleared
|
|
130
130
|
# Used for performance optimization
|
|
131
|
-
self._updated_nonreturning_functions:
|
|
131
|
+
self._updated_nonreturning_functions: set[int] | None = None
|
|
132
132
|
|
|
133
133
|
self._normalize = normalize
|
|
134
134
|
|
|
@@ -137,7 +137,7 @@ class CFGBase(Analysis):
|
|
|
137
137
|
|
|
138
138
|
# IndirectJump object that describe all indirect exits found in the binary
|
|
139
139
|
# stores as a map between addresses and IndirectJump objects
|
|
140
|
-
self.indirect_jumps:
|
|
140
|
+
self.indirect_jumps: dict[int, IndirectJump] = {}
|
|
141
141
|
self._indirect_jumps_to_resolve = set()
|
|
142
142
|
|
|
143
143
|
# Indirect jump resolvers
|
|
@@ -245,7 +245,7 @@ class CFGBase(Analysis):
|
|
|
245
245
|
)
|
|
246
246
|
|
|
247
247
|
self._regions_size = sum((end - start) for start, end in regions)
|
|
248
|
-
self._regions:
|
|
248
|
+
self._regions: dict[int, int] = SortedDict(regions)
|
|
249
249
|
|
|
250
250
|
l.debug("CFG recovery covers %d regions:", len(self._regions))
|
|
251
251
|
for start, end in self._regions.items():
|
|
@@ -610,7 +610,7 @@ class CFGBase(Analysis):
|
|
|
610
610
|
|
|
611
611
|
# Methods for determining scanning scope
|
|
612
612
|
|
|
613
|
-
def _inside_regions(self, address:
|
|
613
|
+
def _inside_regions(self, address: int | None) -> bool:
|
|
614
614
|
"""
|
|
615
615
|
Check if the address is inside any existing region.
|
|
616
616
|
|
|
@@ -625,7 +625,7 @@ class CFGBase(Analysis):
|
|
|
625
625
|
else:
|
|
626
626
|
return address < self._regions[start_addr]
|
|
627
627
|
|
|
628
|
-
def _get_min_addr(self) ->
|
|
628
|
+
def _get_min_addr(self) -> int | None:
|
|
629
629
|
"""
|
|
630
630
|
Get the minimum address out of all regions. We assume self._regions is sorted.
|
|
631
631
|
|
|
@@ -639,7 +639,7 @@ class CFGBase(Analysis):
|
|
|
639
639
|
|
|
640
640
|
return next(self._regions.irange())
|
|
641
641
|
|
|
642
|
-
def _next_address_in_regions(self, address:
|
|
642
|
+
def _next_address_in_regions(self, address: int | None) -> int | None:
|
|
643
643
|
"""
|
|
644
644
|
Return the next immediate address that is inside any of the regions.
|
|
645
645
|
|
|
@@ -2049,7 +2049,7 @@ class CFGBase(Analysis):
|
|
|
2049
2049
|
|
|
2050
2050
|
def _process_jump_table_targeted_functions(
|
|
2051
2051
|
self, functions, predetermined_function_addrs, blockaddr_to_function
|
|
2052
|
-
) ->
|
|
2052
|
+
) -> set[int]:
|
|
2053
2053
|
"""
|
|
2054
2054
|
Sometimes compilers will optimize "cold" code regions, make them separate functions, mark them as cold, which
|
|
2055
2055
|
conflicts with how angr handles jumps to these functions (because they weren't functions to start with). Here
|
|
@@ -2073,7 +2073,7 @@ class CFGBase(Analysis):
|
|
|
2073
2073
|
source function where the corresponding jump table belongs.
|
|
2074
2074
|
"""
|
|
2075
2075
|
|
|
2076
|
-
jumptable_entries:
|
|
2076
|
+
jumptable_entries: set[int] = set()
|
|
2077
2077
|
for jt in self.model.jump_tables.values():
|
|
2078
2078
|
assert jt.jumptable_entries is not None
|
|
2079
2079
|
jumptable_entries |= set(jt.jumptable_entries)
|
|
@@ -2162,7 +2162,7 @@ class CFGBase(Analysis):
|
|
|
2162
2162
|
src_addr,
|
|
2163
2163
|
dst_addr,
|
|
2164
2164
|
src_function,
|
|
2165
|
-
all_edges:
|
|
2165
|
+
all_edges: list[tuple[CFGNode, CFGNode, Any]],
|
|
2166
2166
|
known_functions,
|
|
2167
2167
|
blockaddr_to_function,
|
|
2168
2168
|
):
|
|
@@ -2793,8 +2793,8 @@ class CFGBase(Analysis):
|
|
|
2793
2793
|
cfg_node: CFGNode,
|
|
2794
2794
|
irsb: pyvex.IRSB,
|
|
2795
2795
|
func_addr: int,
|
|
2796
|
-
stmt_idx:
|
|
2797
|
-
) ->
|
|
2796
|
+
stmt_idx: int | str = DEFAULT_STATEMENT,
|
|
2797
|
+
) -> tuple[bool, set[int], IndirectJump | None]:
|
|
2798
2798
|
"""
|
|
2799
2799
|
Called when we encounter an indirect jump. We will try to resolve this indirect jump using timeless (fast)
|
|
2800
2800
|
indirect jump resolvers. If it cannot be resolved, we will see if this indirect jump has been resolved before.
|
|
@@ -2877,7 +2877,7 @@ class CFGBase(Analysis):
|
|
|
2877
2877
|
|
|
2878
2878
|
return all_targets
|
|
2879
2879
|
|
|
2880
|
-
def _process_one_indirect_jump(self, jump: IndirectJump, func_graph_complete: bool = True) ->
|
|
2880
|
+
def _process_one_indirect_jump(self, jump: IndirectJump, func_graph_complete: bool = True) -> set:
|
|
2881
2881
|
"""
|
|
2882
2882
|
Resolve a given indirect jump.
|
|
2883
2883
|
|
|
@@ -3,7 +3,6 @@ import logging
|
|
|
3
3
|
import sys
|
|
4
4
|
from collections import defaultdict
|
|
5
5
|
from functools import reduce
|
|
6
|
-
from typing import Dict, List
|
|
7
6
|
|
|
8
7
|
import angr
|
|
9
8
|
import claripy
|
|
@@ -768,7 +767,7 @@ class CFGEmulated(ForwardAnalysis, CFGBase): # pylint: disable=abstract-method
|
|
|
768
767
|
|
|
769
768
|
def __setstate__(self, s):
|
|
770
769
|
self.project: angr.Project = s["project"]
|
|
771
|
-
self.indirect_jumps:
|
|
770
|
+
self.indirect_jumps: dict[int, IndirectJump] = s["indirect_jumps"]
|
|
772
771
|
self._loop_back_edges = s["_loop_back_edges"]
|
|
773
772
|
self._thumb_addrs = s["_thumb_addrs"]
|
|
774
773
|
self._unresolvable_runs = s["_unresolvable_runs"]
|
|
@@ -1501,7 +1500,7 @@ class CFGEmulated(ForwardAnalysis, CFGBase): # pylint: disable=abstract-method
|
|
|
1501
1500
|
|
|
1502
1501
|
return successors
|
|
1503
1502
|
|
|
1504
|
-
def _post_job_handling(self, job: CFGJob, _new_jobs, successors:
|
|
1503
|
+
def _post_job_handling(self, job: CFGJob, _new_jobs, successors: list[SimState]): # type: ignore[override]
|
|
1505
1504
|
"""
|
|
1506
1505
|
|
|
1507
1506
|
:param CFGJob job:
|
|
@@ -1564,7 +1563,7 @@ class CFGEmulated(ForwardAnalysis, CFGBase): # pylint: disable=abstract-method
|
|
|
1564
1563
|
|
|
1565
1564
|
return successors, extra_info
|
|
1566
1565
|
|
|
1567
|
-
def _post_handle_job_debug(self, job: CFGJob, successors:
|
|
1566
|
+
def _post_handle_job_debug(self, job: CFGJob, successors: list[SimState]) -> None:
|
|
1568
1567
|
"""
|
|
1569
1568
|
Post job handling: print debugging information regarding the current job.
|
|
1570
1569
|
|