angr 9.2.101__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 +56 -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.101.dist-info → angr-9.2.103.dist-info}/METADATA +9 -11
- {angr-9.2.101.dist-info → angr-9.2.103.dist-info}/RECORD +239 -236
- {angr-9.2.101.dist-info → angr-9.2.103.dist-info}/LICENSE +0 -0
- {angr-9.2.101.dist-info → angr-9.2.103.dist-info}/WHEEL +0 -0
- {angr-9.2.101.dist-info → angr-9.2.103.dist-info}/entry_points.txt +0 -0
- {angr-9.2.101.dist-info → angr-9.2.103.dist-info}/top_level.txt +0 -0
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
from typing import
|
|
1
|
+
from typing import Any, Optional, TYPE_CHECKING
|
|
2
|
+
from collections.abc import Iterable, Generator
|
|
2
3
|
|
|
3
4
|
import claripy
|
|
4
5
|
import ailment
|
|
@@ -17,7 +18,7 @@ class Detail:
|
|
|
17
18
|
|
|
18
19
|
__slots__ = ("size", "expr", "def_at")
|
|
19
20
|
|
|
20
|
-
def __init__(self, size: int, expr:
|
|
21
|
+
def __init__(self, size: int, expr: ailment.Expression | None, def_at: Optional["CodeLocation"]):
|
|
21
22
|
self.size = size
|
|
22
23
|
self.expr = expr
|
|
23
24
|
self.def_at = def_at
|
|
@@ -39,7 +40,7 @@ class PropValue:
|
|
|
39
40
|
"offset_and_details",
|
|
40
41
|
)
|
|
41
42
|
|
|
42
|
-
def __init__(self, value: claripy.ast.Bits, offset_and_details:
|
|
43
|
+
def __init__(self, value: claripy.ast.Bits, offset_and_details: dict[int, Detail] | None = None):
|
|
43
44
|
self.value = value
|
|
44
45
|
self.offset_and_details = offset_and_details
|
|
45
46
|
|
|
@@ -48,7 +49,7 @@ class PropValue:
|
|
|
48
49
|
return not bool(self.offset_and_details)
|
|
49
50
|
|
|
50
51
|
@property
|
|
51
|
-
def one_expr(self) ->
|
|
52
|
+
def one_expr(self) -> ailment.Expression | None:
|
|
52
53
|
"""
|
|
53
54
|
Get the expression that starts at offset 0 and covers the entire PropValue. Returns None if there are no
|
|
54
55
|
expressions or multiple expressions.
|
|
@@ -109,7 +110,7 @@ class PropValue:
|
|
|
109
110
|
value = claripy.fpToIEEEBV(value)
|
|
110
111
|
return value[chop_start:chop_end]
|
|
111
112
|
|
|
112
|
-
def value_and_labels(self) -> Generator[
|
|
113
|
+
def value_and_labels(self) -> Generator[tuple[int, claripy.ast.Bits, int, dict | None], None, None]:
|
|
113
114
|
if not self.offset_and_details:
|
|
114
115
|
return
|
|
115
116
|
keys = list(sorted(self.offset_and_details.keys()))
|
|
@@ -140,7 +141,7 @@ class PropValue:
|
|
|
140
141
|
|
|
141
142
|
@staticmethod
|
|
142
143
|
def from_value_and_labels(
|
|
143
|
-
value: claripy.ast.Bits, labels: Iterable[
|
|
144
|
+
value: claripy.ast.Bits, labels: Iterable[tuple[int, int, int, dict[str, Any]]]
|
|
144
145
|
) -> "PropValue":
|
|
145
146
|
if not labels:
|
|
146
147
|
return PropValue(value)
|
|
@@ -164,8 +165,8 @@ class PropValue:
|
|
|
164
165
|
|
|
165
166
|
@staticmethod
|
|
166
167
|
def extract_ail_expression(
|
|
167
|
-
start: int, bits: int, expr:
|
|
168
|
-
) ->
|
|
168
|
+
start: int, bits: int, expr: ailment.Expr.Expression | None
|
|
169
|
+
) -> ailment.Expr.Expression | None:
|
|
169
170
|
if expr is None:
|
|
170
171
|
return None
|
|
171
172
|
|
|
@@ -182,7 +183,7 @@ class PropValue:
|
|
|
182
183
|
return ailment.Expr.Convert(None, a.bits, bits, False, a, **expr.tags)
|
|
183
184
|
|
|
184
185
|
@staticmethod
|
|
185
|
-
def extend_ail_expression(bits: int, expr:
|
|
186
|
+
def extend_ail_expression(bits: int, expr: ailment.Expr.Expression | None) -> ailment.Expr.Expression | None:
|
|
186
187
|
if expr is None:
|
|
187
188
|
return None
|
|
188
189
|
if isinstance(expr, ailment.Expr.Const):
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
from typing import Dict, Tuple
|
|
2
|
-
|
|
3
1
|
from angr.knowledge_plugins.plugin import KnowledgeBasePlugin
|
|
4
2
|
from .propagation_model import PropagationModel
|
|
5
3
|
|
|
@@ -11,9 +9,9 @@ class PropagationManager(KnowledgeBasePlugin):
|
|
|
11
9
|
|
|
12
10
|
def __init__(self, kb):
|
|
13
11
|
super().__init__(kb=kb)
|
|
14
|
-
self._propagations:
|
|
12
|
+
self._propagations: dict[tuple, PropagationModel] = {}
|
|
15
13
|
|
|
16
|
-
def exists(self, prop_key:
|
|
14
|
+
def exists(self, prop_key: tuple) -> bool:
|
|
17
15
|
"""
|
|
18
16
|
Internal function to check if a func, specified as a CodeLocation
|
|
19
17
|
exists in our known propagations
|
|
@@ -23,7 +21,7 @@ class PropagationManager(KnowledgeBasePlugin):
|
|
|
23
21
|
"""
|
|
24
22
|
return prop_key in self._propagations
|
|
25
23
|
|
|
26
|
-
def update(self, prop_key:
|
|
24
|
+
def update(self, prop_key: tuple, model: PropagationModel) -> None:
|
|
27
25
|
"""
|
|
28
26
|
Add the replacements to known propagations
|
|
29
27
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
from typing import
|
|
1
|
+
from typing import DefaultDict, Any
|
|
2
2
|
from collections import defaultdict
|
|
3
3
|
|
|
4
4
|
import claripy
|
|
@@ -29,14 +29,14 @@ class PropagationModel(Serializable):
|
|
|
29
29
|
|
|
30
30
|
def __init__(
|
|
31
31
|
self,
|
|
32
|
-
prop_key:
|
|
33
|
-
node_iterations:
|
|
34
|
-
states:
|
|
35
|
-
block_initial_reg_values:
|
|
36
|
-
replacements:
|
|
37
|
-
equivalence:
|
|
38
|
-
function:
|
|
39
|
-
input_states:
|
|
32
|
+
prop_key: tuple,
|
|
33
|
+
node_iterations: DefaultDict[Any, int] | None = None,
|
|
34
|
+
states: dict | None = None,
|
|
35
|
+
block_initial_reg_values: dict | None = None,
|
|
36
|
+
replacements: DefaultDict[Any, dict] | None = None,
|
|
37
|
+
equivalence: set | None = None,
|
|
38
|
+
function: Function | None = None,
|
|
39
|
+
input_states: dict | None = None,
|
|
40
40
|
):
|
|
41
41
|
self.key = prop_key
|
|
42
42
|
self.node_iterations = node_iterations if node_iterations is not None else defaultdict(int)
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
# pylint:disable=too-many-boolean-expressions
|
|
2
|
-
from typing import
|
|
2
|
+
from typing import Optional, Union, DefaultDict, Any, TYPE_CHECKING
|
|
3
3
|
from collections import defaultdict
|
|
4
4
|
import weakref
|
|
5
5
|
|
|
@@ -39,7 +39,7 @@ class CallExprFinder(ailment.AILBlockWalker):
|
|
|
39
39
|
expr: ailment.Stmt.Call,
|
|
40
40
|
stmt_idx: int,
|
|
41
41
|
stmt: ailment.Stmt.Statement,
|
|
42
|
-
block:
|
|
42
|
+
block: ailment.Block | None,
|
|
43
43
|
):
|
|
44
44
|
self.has_call = True
|
|
45
45
|
|
|
@@ -73,6 +73,7 @@ class PropagatorState:
|
|
|
73
73
|
"_gp",
|
|
74
74
|
"_max_prop_expr_occurrence",
|
|
75
75
|
"model",
|
|
76
|
+
"_artificial_reg_offsets",
|
|
76
77
|
"__weakref__",
|
|
77
78
|
)
|
|
78
79
|
|
|
@@ -83,14 +84,15 @@ class PropagatorState:
|
|
|
83
84
|
arch: "Arch",
|
|
84
85
|
project: Optional["Project"] = None,
|
|
85
86
|
rda=None,
|
|
86
|
-
replacements:
|
|
87
|
+
replacements: DefaultDict[CodeLocation, dict] | None = None,
|
|
87
88
|
only_consts: bool = False,
|
|
88
|
-
expr_used_locs:
|
|
89
|
-
equivalence:
|
|
89
|
+
expr_used_locs: DefaultDict[Any, set[CodeLocation]] | None = None,
|
|
90
|
+
equivalence: set["Equivalence"] | None = None,
|
|
90
91
|
store_tops: bool = True,
|
|
91
|
-
gp:
|
|
92
|
+
gp: int | None = None,
|
|
92
93
|
max_prop_expr_occurrence: int = 1,
|
|
93
94
|
model=None,
|
|
95
|
+
artificial_reg_offsets=None,
|
|
94
96
|
):
|
|
95
97
|
self.arch = arch
|
|
96
98
|
self.gpr_size = arch.bits // arch.byte_width # size of the general-purpose registers
|
|
@@ -99,12 +101,13 @@ class PropagatorState:
|
|
|
99
101
|
self._expr_used_locs = defaultdict(list) if expr_used_locs is None else expr_used_locs
|
|
100
102
|
self._only_consts = only_consts
|
|
101
103
|
self._replacements = defaultdict(dict) if replacements is None else replacements
|
|
102
|
-
self._equivalence:
|
|
104
|
+
self._equivalence: set[Equivalence] = equivalence if equivalence is not None else set()
|
|
103
105
|
self._store_tops = store_tops
|
|
104
106
|
self._max_prop_expr_occurrence = max_prop_expr_occurrence
|
|
107
|
+
self._artificial_reg_offsets = artificial_reg_offsets if artificial_reg_offsets is not None else set()
|
|
105
108
|
|
|
106
109
|
# architecture-specific information
|
|
107
|
-
self._gp:
|
|
110
|
+
self._gp: int | None = gp # Value of gp for MIPS32 and 64 binaries
|
|
108
111
|
|
|
109
112
|
self.project = project
|
|
110
113
|
self.model = model
|
|
@@ -202,7 +205,7 @@ class PropagatorState:
|
|
|
202
205
|
:return: Whether merging has happened or not.
|
|
203
206
|
"""
|
|
204
207
|
|
|
205
|
-
def _get_repl_size(repl_value:
|
|
208
|
+
def _get_repl_size(repl_value: dict | ailment.Expression | claripy.ast.Bits) -> int:
|
|
206
209
|
if isinstance(repl_value, dict):
|
|
207
210
|
return _get_repl_size(repl_value["expr"])
|
|
208
211
|
if isinstance(repl_value, ailment.Expression):
|
|
@@ -384,6 +387,7 @@ class PropagatorVEXState(PropagatorState):
|
|
|
384
387
|
gp=None,
|
|
385
388
|
max_prop_expr_occurrence: int = 1,
|
|
386
389
|
model=None,
|
|
390
|
+
artificial_reg_offsets=None,
|
|
387
391
|
):
|
|
388
392
|
super().__init__(
|
|
389
393
|
arch,
|
|
@@ -396,6 +400,7 @@ class PropagatorVEXState(PropagatorState):
|
|
|
396
400
|
gp=gp,
|
|
397
401
|
max_prop_expr_occurrence=max_prop_expr_occurrence,
|
|
398
402
|
model=model,
|
|
403
|
+
artificial_reg_offsets=artificial_reg_offsets,
|
|
399
404
|
)
|
|
400
405
|
self.do_binops = do_binops
|
|
401
406
|
self._registers = (
|
|
@@ -487,11 +492,12 @@ class PropagatorVEXState(PropagatorState):
|
|
|
487
492
|
gp=self._gp,
|
|
488
493
|
max_prop_expr_occurrence=self._max_prop_expr_occurrence,
|
|
489
494
|
model=self.model,
|
|
495
|
+
artificial_reg_offsets=self._artificial_reg_offsets,
|
|
490
496
|
)
|
|
491
497
|
|
|
492
498
|
return cp
|
|
493
499
|
|
|
494
|
-
def merge(self, *others: "PropagatorVEXState") ->
|
|
500
|
+
def merge(self, *others: "PropagatorVEXState") -> tuple["PropagatorVEXState", bool]:
|
|
495
501
|
state = self.copy()
|
|
496
502
|
merge_occurred = state._registers.merge([o._registers for o in others], None)
|
|
497
503
|
merge_occurred |= state._stack_variables.merge([o._stack_variables for o in others], None)
|
|
@@ -524,7 +530,7 @@ class PropagatorVEXState(PropagatorState):
|
|
|
524
530
|
except SimMemoryMissingError:
|
|
525
531
|
return self.top(size * self.arch.byte_width).annotate(RegisterAnnotation(offset, size))
|
|
526
532
|
|
|
527
|
-
def register_results(self) ->
|
|
533
|
+
def register_results(self) -> dict[str, claripy.ast.BV]:
|
|
528
534
|
result = {}
|
|
529
535
|
for reg, (offset, size) in self.arch.registers.items():
|
|
530
536
|
val = self.load_register(offset, size)
|
|
@@ -600,6 +606,7 @@ class PropagatorAILState(PropagatorState):
|
|
|
600
606
|
max_prop_expr_occurrence: int = 1,
|
|
601
607
|
sp_adjusted: bool = False,
|
|
602
608
|
model=None,
|
|
609
|
+
artificial_reg_offsets=None,
|
|
603
610
|
):
|
|
604
611
|
super().__init__(
|
|
605
612
|
arch,
|
|
@@ -612,6 +619,7 @@ class PropagatorAILState(PropagatorState):
|
|
|
612
619
|
gp=gp,
|
|
613
620
|
max_prop_expr_occurrence=max_prop_expr_occurrence,
|
|
614
621
|
model=model,
|
|
622
|
+
artificial_reg_offsets=artificial_reg_offsets,
|
|
615
623
|
)
|
|
616
624
|
|
|
617
625
|
self._stack_variables = (
|
|
@@ -628,7 +636,7 @@ class PropagatorAILState(PropagatorState):
|
|
|
628
636
|
self.temp_expressions = {}
|
|
629
637
|
self.register_expressions = {}
|
|
630
638
|
self.block_initial_reg_values: DefaultDict[
|
|
631
|
-
|
|
639
|
+
tuple[int, int], list[tuple[ailment.Expr.Register, ailment.Expr.Const]]
|
|
632
640
|
] = (defaultdict(list) if block_initial_reg_values is None else block_initial_reg_values)
|
|
633
641
|
self._sp_adjusted: bool = sp_adjusted
|
|
634
642
|
|
|
@@ -637,8 +645,8 @@ class PropagatorAILState(PropagatorState):
|
|
|
637
645
|
# last_stack_store stores the most recent stack store statement with a non-concrete or unresolvable address. we
|
|
638
646
|
# use this information to determine if stack reads after this store can be safely resolved to definitions prior
|
|
639
647
|
# to the stack read.
|
|
640
|
-
self.last_stack_store:
|
|
641
|
-
self.global_stores:
|
|
648
|
+
self.last_stack_store: tuple[int, int, ailment.Stmt.Store] | None = None
|
|
649
|
+
self.global_stores: list[tuple[int, int, Any, ailment.Stmt.Store]] = []
|
|
642
650
|
|
|
643
651
|
def __repr__(self):
|
|
644
652
|
return "<PropagatorAILState>"
|
|
@@ -711,6 +719,18 @@ class PropagatorAILState(PropagatorState):
|
|
|
711
719
|
PropValue(claripy.BVV(0, 32), offset_and_details={0: Detail(4, reg_value, initial_codeloc)}),
|
|
712
720
|
)
|
|
713
721
|
|
|
722
|
+
elif project.arch.name.startswith("PowerPC:"):
|
|
723
|
+
# pcode PowerPC
|
|
724
|
+
state._artificial_reg_offsets = {project.arch.registers["tea"][0]}
|
|
725
|
+
|
|
726
|
+
# clear xer_so
|
|
727
|
+
reg_expr = ailment.Expr.Register(None, None, *project.arch.registers["xer_so"])
|
|
728
|
+
reg_value = ailment.Expr.Const(None, None, 0, 8)
|
|
729
|
+
state.store_register(
|
|
730
|
+
reg_expr,
|
|
731
|
+
PropValue(claripy.BVV(0, 8), offset_and_details={0: Detail(1, reg_value, initial_codeloc)}),
|
|
732
|
+
)
|
|
733
|
+
|
|
714
734
|
if project is not None and project.simos is not None and project.simos.function_initial_registers:
|
|
715
735
|
if func_addr is not None:
|
|
716
736
|
for reg_name, reg_value in project.simos.function_initial_registers.items():
|
|
@@ -744,12 +764,13 @@ class PropagatorAILState(PropagatorState):
|
|
|
744
764
|
max_prop_expr_occurrence=self._max_prop_expr_occurrence,
|
|
745
765
|
sp_adjusted=self._sp_adjusted,
|
|
746
766
|
model=self.model,
|
|
767
|
+
artificial_reg_offsets=self._artificial_reg_offsets,
|
|
747
768
|
)
|
|
748
769
|
|
|
749
770
|
return rd
|
|
750
771
|
|
|
751
772
|
@staticmethod
|
|
752
|
-
def is_const_or_register(value:
|
|
773
|
+
def is_const_or_register(value: ailment.Expr.Expression | claripy.ast.Bits | None) -> bool:
|
|
753
774
|
if value is None:
|
|
754
775
|
return False
|
|
755
776
|
if isinstance(value, claripy.ast.BV):
|
|
@@ -769,7 +790,7 @@ class PropagatorAILState(PropagatorState):
|
|
|
769
790
|
return True
|
|
770
791
|
return False
|
|
771
792
|
|
|
772
|
-
def merge(self, *others) ->
|
|
793
|
+
def merge(self, *others) -> tuple["PropagatorAILState", bool]:
|
|
773
794
|
state, merge_occurred = super().merge(*others)
|
|
774
795
|
state: "PropagatorAILState"
|
|
775
796
|
|
|
@@ -781,7 +802,7 @@ class PropagatorAILState(PropagatorState):
|
|
|
781
802
|
def store_temp(self, tmp_idx: int, value: PropValue):
|
|
782
803
|
self._tmps[tmp_idx] = value
|
|
783
804
|
|
|
784
|
-
def load_tmp(self, tmp_idx: int) ->
|
|
805
|
+
def load_tmp(self, tmp_idx: int) -> PropValue | None:
|
|
785
806
|
return self._tmps.get(tmp_idx, None)
|
|
786
807
|
|
|
787
808
|
def store_register(self, reg: ailment.Expr.Register, value: PropValue) -> None:
|
|
@@ -807,7 +828,7 @@ class PropagatorAILState(PropagatorState):
|
|
|
807
828
|
for offset, value, size, label in new.value_and_labels():
|
|
808
829
|
self._stack_variables.store(sp_offset + offset, value, size=size, endness=endness, label=label)
|
|
809
830
|
|
|
810
|
-
def load_register(self, reg: ailment.Expr.Register) ->
|
|
831
|
+
def load_register(self, reg: ailment.Expr.Register) -> PropValue | None:
|
|
811
832
|
try:
|
|
812
833
|
value, labels = self._registers.load_with_labels(
|
|
813
834
|
reg.reg_offset, size=reg.size, endness=self.project.arch.register_endness
|
|
@@ -819,7 +840,7 @@ class PropagatorAILState(PropagatorState):
|
|
|
819
840
|
prop_value = PropValue.from_value_and_labels(value, labels)
|
|
820
841
|
return prop_value
|
|
821
842
|
|
|
822
|
-
def load_stack_variable(self, sp_offset: int, size, endness=None) ->
|
|
843
|
+
def load_stack_variable(self, sp_offset: int, size, endness=None) -> PropValue | None:
|
|
823
844
|
# normalize sp_offset to handle negative offsets
|
|
824
845
|
sp_offset += 0x65536
|
|
825
846
|
sp_offset &= (1 << self.arch.bits) - 1
|
|
@@ -847,13 +868,22 @@ class PropagatorAILState(PropagatorState):
|
|
|
847
868
|
prop_value = PropValue.from_value_and_labels(value, labels)
|
|
848
869
|
return prop_value
|
|
849
870
|
|
|
871
|
+
def should_replace_reg(self, old_reg_offset: int, bp_as_gpr: bool, new_value) -> bool:
|
|
872
|
+
if old_reg_offset == self.arch.sp_offset or (not bp_as_gpr and old_reg_offset == self.arch.bp_offset):
|
|
873
|
+
return True
|
|
874
|
+
if old_reg_offset in self._artificial_reg_offsets:
|
|
875
|
+
return True
|
|
876
|
+
if isinstance(new_value, ailment.Expr.StackBaseOffset):
|
|
877
|
+
return True
|
|
878
|
+
return False
|
|
879
|
+
|
|
850
880
|
def add_replacement(
|
|
851
881
|
self,
|
|
852
882
|
codeloc: CodeLocation,
|
|
853
883
|
old,
|
|
854
884
|
new,
|
|
855
885
|
force_replace: bool = False,
|
|
856
|
-
stmt_to_remove:
|
|
886
|
+
stmt_to_remove: CodeLocation | None = None,
|
|
857
887
|
bp_as_gpr: bool = False,
|
|
858
888
|
) -> bool:
|
|
859
889
|
if self._only_consts:
|
|
@@ -889,7 +919,7 @@ class PropagatorAILState(PropagatorState):
|
|
|
889
919
|
if (
|
|
890
920
|
isinstance(old, ailment.Expr.Tmp)
|
|
891
921
|
or isinstance(old, ailment.Expr.Register)
|
|
892
|
-
and
|
|
922
|
+
and self.should_replace_reg(old.reg_offset, bp_as_gpr, new)
|
|
893
923
|
):
|
|
894
924
|
self._replacements[codeloc][old] = (
|
|
895
925
|
new if stmt_to_remove is None else {"expr": new, "stmt_to_remove": stmt_to_remove}
|
|
@@ -955,7 +985,7 @@ class PropagatorAILState(PropagatorState):
|
|
|
955
985
|
|
|
956
986
|
return replaced
|
|
957
987
|
|
|
958
|
-
def revert_past_replacements(self, replaced_by, to_replace=None, to_replace_def=None) ->
|
|
988
|
+
def revert_past_replacements(self, replaced_by, to_replace=None, to_replace_def=None) -> set[CodeLocation]:
|
|
959
989
|
updated_codelocs = set()
|
|
960
990
|
if self.model.replacements is not None:
|
|
961
991
|
for codeloc_ in self._expr_used_locs[to_replace_def if to_replace_def is not None else to_replace]:
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
# pylint:disable=import-outside-toplevel
|
|
2
|
-
from typing import
|
|
2
|
+
from typing import Any, Union, TYPE_CHECKING
|
|
3
3
|
|
|
4
4
|
from .. import KnowledgeBasePlugin
|
|
5
5
|
|
|
@@ -11,7 +11,7 @@ if TYPE_CHECKING:
|
|
|
11
11
|
class StructuredCodeManager(KnowledgeBasePlugin):
|
|
12
12
|
def __init__(self, kb):
|
|
13
13
|
super().__init__(kb=kb)
|
|
14
|
-
self.cached:
|
|
14
|
+
self.cached: dict[Any, "DecompilationCache"] = {}
|
|
15
15
|
|
|
16
16
|
def _normalize_key(self, item):
|
|
17
17
|
if type(item) is not tuple:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# pylint:disable=import-outside-toplevel
|
|
2
2
|
from functools import wraps
|
|
3
|
-
from typing import Optional
|
|
3
|
+
from typing import Optional
|
|
4
4
|
|
|
5
5
|
from ... import knowledge_plugins
|
|
6
6
|
from ...knowledge_plugins.plugin import KnowledgeBasePlugin
|
|
@@ -172,7 +172,7 @@ class SyncController(KnowledgeBasePlugin):
|
|
|
172
172
|
@init_checker
|
|
173
173
|
@make_state
|
|
174
174
|
# pylint:disable=unused-argument,no-self-use
|
|
175
|
-
def push_comments(self, comments:
|
|
175
|
+
def push_comments(self, comments: list["binsync.data.Comment"], user=None, state=None):
|
|
176
176
|
"""
|
|
177
177
|
Push a bunch of comments upwards.
|
|
178
178
|
|
|
@@ -189,7 +189,7 @@ class SyncController(KnowledgeBasePlugin):
|
|
|
189
189
|
@make_state
|
|
190
190
|
# pylint:disable=unused-argument,no-self-use
|
|
191
191
|
def push_stack_variables(
|
|
192
|
-
self, stack_variables:
|
|
192
|
+
self, stack_variables: list[SimStackVariable], var_manager: VariableManagerInternal, user=None, state=None
|
|
193
193
|
):
|
|
194
194
|
"""
|
|
195
195
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
# pylint:disable=arguments-differ,no-member
|
|
2
|
-
from typing import
|
|
2
|
+
from typing import TYPE_CHECKING
|
|
3
3
|
|
|
4
4
|
from ...code_location import CodeLocation
|
|
5
5
|
from ...serializable import Serializable
|
|
@@ -36,8 +36,8 @@ class VariableAccess(Serializable):
|
|
|
36
36
|
self.variable: "SimVariable" = variable
|
|
37
37
|
self.access_type: int = access_type
|
|
38
38
|
self.location: CodeLocation = location
|
|
39
|
-
self.offset:
|
|
40
|
-
self.atom_hash:
|
|
39
|
+
self.offset: int | None = offset
|
|
40
|
+
self.atom_hash: int | None = atom_hash
|
|
41
41
|
|
|
42
42
|
def __repr__(self):
|
|
43
43
|
access_type = {
|
|
@@ -90,7 +90,7 @@ class VariableAccess(Serializable):
|
|
|
90
90
|
|
|
91
91
|
@classmethod
|
|
92
92
|
def parse_from_cmessage(
|
|
93
|
-
cls, cmsg, variable_by_ident:
|
|
93
|
+
cls, cmsg, variable_by_ident: dict[str, "SimVariable"] | None = None, **kwargs
|
|
94
94
|
) -> "VariableAccess":
|
|
95
95
|
assert variable_by_ident is not None
|
|
96
96
|
|