angr 9.2.102__py3-none-manylinux2014_x86_64.whl → 9.2.104__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 +28 -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.104.dist-info}/METADATA +9 -11
- {angr-9.2.102.dist-info → angr-9.2.104.dist-info}/RECORD +239 -236
- {angr-9.2.102.dist-info → angr-9.2.104.dist-info}/LICENSE +0 -0
- {angr-9.2.102.dist-info → angr-9.2.104.dist-info}/WHEEL +0 -0
- {angr-9.2.102.dist-info → angr-9.2.104.dist-info}/entry_points.txt +0 -0
- {angr-9.2.102.dist-info → angr-9.2.104.dist-info}/top_level.txt +0 -0
|
@@ -3,7 +3,6 @@
|
|
|
3
3
|
All type constants used in type inference. They can be mapped, translated, or rewritten to C-style types.
|
|
4
4
|
"""
|
|
5
5
|
|
|
6
|
-
from typing import List, Optional, Set
|
|
7
6
|
import functools
|
|
8
7
|
|
|
9
8
|
|
|
@@ -30,7 +29,7 @@ class TypeConstant:
|
|
|
30
29
|
def pp_str(self, mapping) -> str: # pylint:disable=unused-argument
|
|
31
30
|
return repr(self)
|
|
32
31
|
|
|
33
|
-
def _hash(self, visited:
|
|
32
|
+
def _hash(self, visited: set[int]): # pylint:disable=unused-argument
|
|
34
33
|
return hash(type(self))
|
|
35
34
|
|
|
36
35
|
def __eq__(self, other):
|
|
@@ -123,13 +122,13 @@ class Double(FloatBase):
|
|
|
123
122
|
|
|
124
123
|
|
|
125
124
|
class Pointer(TypeConstant):
|
|
126
|
-
def __init__(self, basetype:
|
|
127
|
-
self.basetype:
|
|
125
|
+
def __init__(self, basetype: TypeConstant | None):
|
|
126
|
+
self.basetype: TypeConstant | None = basetype
|
|
128
127
|
|
|
129
128
|
def __eq__(self, other):
|
|
130
129
|
return type(self) is type(other) and self.basetype == other.basetype
|
|
131
130
|
|
|
132
|
-
def _hash(self, visited:
|
|
131
|
+
def _hash(self, visited: set[int]):
|
|
133
132
|
if self.basetype is None:
|
|
134
133
|
return hash(type(self))
|
|
135
134
|
return hash((type(self), self.basetype._hash(visited)))
|
|
@@ -171,8 +170,8 @@ class Pointer64(Pointer, Int64):
|
|
|
171
170
|
|
|
172
171
|
class Array(TypeConstant):
|
|
173
172
|
def __init__(self, element=None, count=None):
|
|
174
|
-
self.element:
|
|
175
|
-
self.count:
|
|
173
|
+
self.element: TypeConstant | None = element
|
|
174
|
+
self.count: int | None = count
|
|
176
175
|
|
|
177
176
|
@memoize
|
|
178
177
|
def __repr__(self, memo=None):
|
|
@@ -184,7 +183,7 @@ class Array(TypeConstant):
|
|
|
184
183
|
def __eq__(self, other):
|
|
185
184
|
return type(other) is type(self) and self.element == other.element and self.count == other.count
|
|
186
185
|
|
|
187
|
-
def _hash(self, visited:
|
|
186
|
+
def _hash(self, visited: set[int]):
|
|
188
187
|
if id(self) in visited:
|
|
189
188
|
return 0
|
|
190
189
|
visited.add(id(self))
|
|
@@ -200,13 +199,13 @@ class Struct(TypeConstant):
|
|
|
200
199
|
self.name = name
|
|
201
200
|
self.field_names = field_names
|
|
202
201
|
|
|
203
|
-
def _hash(self, visited:
|
|
202
|
+
def _hash(self, visited: set[int]):
|
|
204
203
|
if id(self) in visited:
|
|
205
204
|
return 0
|
|
206
205
|
visited.add(id(self))
|
|
207
206
|
return hash((type(self), self._hash_fields(visited)))
|
|
208
207
|
|
|
209
|
-
def _hash_fields(self, visited:
|
|
208
|
+
def _hash_fields(self, visited: set[int]):
|
|
210
209
|
keys = sorted(self.fields.keys())
|
|
211
210
|
tpl = tuple((k, self.fields[k]._hash(visited) if self.fields[k] is not None else None) for k in keys)
|
|
212
211
|
return hash(tpl)
|
|
@@ -226,7 +225,7 @@ class Struct(TypeConstant):
|
|
|
226
225
|
|
|
227
226
|
|
|
228
227
|
class Function(TypeConstant):
|
|
229
|
-
def __init__(self, params:
|
|
228
|
+
def __init__(self, params: list, outputs: list):
|
|
230
229
|
self.params = params
|
|
231
230
|
self.outputs = outputs
|
|
232
231
|
|
|
@@ -241,7 +240,7 @@ class Function(TypeConstant):
|
|
|
241
240
|
return False
|
|
242
241
|
return self.params == other.params and self.outputs == other.outputs
|
|
243
242
|
|
|
244
|
-
def _hash(self, visited:
|
|
243
|
+
def _hash(self, visited: set[int]):
|
|
245
244
|
if id(self) in visited:
|
|
246
245
|
return 0
|
|
247
246
|
visited.add(id(self))
|
|
@@ -273,7 +272,7 @@ class TypeVariableReference(TypeConstant):
|
|
|
273
272
|
#
|
|
274
273
|
|
|
275
274
|
|
|
276
|
-
def int_type(bits: int) ->
|
|
275
|
+
def int_type(bits: int) -> Int | None:
|
|
277
276
|
mapping = {
|
|
278
277
|
1: Int1,
|
|
279
278
|
8: Int8,
|
|
@@ -287,7 +286,7 @@ def int_type(bits: int) -> Optional[Int]:
|
|
|
287
286
|
return None
|
|
288
287
|
|
|
289
288
|
|
|
290
|
-
def float_type(bits: int) ->
|
|
289
|
+
def float_type(bits: int) -> FloatBase | None:
|
|
291
290
|
if bits == 32:
|
|
292
291
|
return Float()
|
|
293
292
|
elif bits == 64:
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
# pylint:disable=bad-builtin
|
|
2
|
-
from typing import
|
|
2
|
+
from typing import TYPE_CHECKING
|
|
3
3
|
|
|
4
4
|
from ...sim_type import SimStruct, SimTypePointer, SimTypeArray
|
|
5
5
|
from ..analysis import Analysis, AnalysesHub
|
|
@@ -33,8 +33,8 @@ class Typehoon(Analysis):
|
|
|
33
33
|
constraints,
|
|
34
34
|
func_var,
|
|
35
35
|
ground_truth=None,
|
|
36
|
-
var_mapping:
|
|
37
|
-
must_struct:
|
|
36
|
+
var_mapping: dict["SimVariable", set["TypeVariable"]] | None = None,
|
|
37
|
+
must_struct: set["TypeVariable"] | None = None,
|
|
38
38
|
):
|
|
39
39
|
"""
|
|
40
40
|
|
|
@@ -46,8 +46,8 @@ class Typehoon(Analysis):
|
|
|
46
46
|
"""
|
|
47
47
|
|
|
48
48
|
self.func_var: "TypeVariable" = func_var
|
|
49
|
-
self._constraints:
|
|
50
|
-
self._ground_truth:
|
|
49
|
+
self._constraints: dict["TypeVariable", set["TypeConstraint"]] = constraints
|
|
50
|
+
self._ground_truth: dict["TypeVariable", "SimType"] | None = ground_truth
|
|
51
51
|
self._var_mapping = var_mapping
|
|
52
52
|
self._must_struct = must_struct
|
|
53
53
|
|
|
@@ -66,7 +66,7 @@ class Typehoon(Analysis):
|
|
|
66
66
|
# Public methods
|
|
67
67
|
#
|
|
68
68
|
|
|
69
|
-
def update_variable_types(self, func_addr:
|
|
69
|
+
def update_variable_types(self, func_addr: int | str, var_to_typevars):
|
|
70
70
|
for var, typevars in var_to_typevars.items():
|
|
71
71
|
for typevar in typevars:
|
|
72
72
|
type_ = self.simtypes_solution.get(typevar, None)
|
|
@@ -179,7 +179,7 @@ class Typehoon(Analysis):
|
|
|
179
179
|
if specialized is not None:
|
|
180
180
|
self.solution[tv] = specialized
|
|
181
181
|
|
|
182
|
-
def _specialize_struct(self, tc, memo:
|
|
182
|
+
def _specialize_struct(self, tc, memo: set | None = None):
|
|
183
183
|
if isinstance(tc, Pointer):
|
|
184
184
|
if memo is not None and tc in memo:
|
|
185
185
|
return None
|
|
@@ -188,8 +188,8 @@ class Typehoon(Analysis):
|
|
|
188
188
|
return None
|
|
189
189
|
return tc.new(specialized)
|
|
190
190
|
|
|
191
|
-
if isinstance(tc, Struct) and tc.fields:
|
|
192
|
-
offsets:
|
|
191
|
+
if isinstance(tc, Struct) and tc.fields and min(tc.fields) >= 0:
|
|
192
|
+
offsets: list[int] = sorted(list(tc.fields.keys())) # get a sorted list of offsets
|
|
193
193
|
offset0 = offsets[0]
|
|
194
194
|
field0: TypeConstant = tc.fields[offset0]
|
|
195
195
|
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
# pylint:disable=missing-class-docstring
|
|
2
|
-
from typing import
|
|
2
|
+
from typing import Any, Optional, Union, TYPE_CHECKING
|
|
3
|
+
from collections.abc import Iterable
|
|
3
4
|
from itertools import count
|
|
4
5
|
|
|
5
6
|
from angr.utils.constants import MAX_POINTSTO_BITS
|
|
@@ -18,7 +19,7 @@ TypeType = Union["TypeConstant", "TypeVariable", "DerivedTypeVariable"]
|
|
|
18
19
|
class TypeConstraint:
|
|
19
20
|
__slots__ = ()
|
|
20
21
|
|
|
21
|
-
def pp_str(self, mapping:
|
|
22
|
+
def pp_str(self, mapping: dict["TypeVariable", Any]) -> str:
|
|
22
23
|
raise NotImplementedError()
|
|
23
24
|
|
|
24
25
|
|
|
@@ -32,7 +33,7 @@ class Equivalence(TypeConstraint):
|
|
|
32
33
|
self.type_a = type_a
|
|
33
34
|
self.type_b = type_b
|
|
34
35
|
|
|
35
|
-
def pp_str(self, mapping:
|
|
36
|
+
def pp_str(self, mapping: dict["TypeVariable", Any]) -> str:
|
|
36
37
|
return f"{self.type_a.pp_str(mapping)} == {self.type_b.pp_str(mapping)}"
|
|
37
38
|
|
|
38
39
|
def __repr__(self):
|
|
@@ -56,7 +57,7 @@ class Existence(TypeConstraint):
|
|
|
56
57
|
def __init__(self, type_):
|
|
57
58
|
self.type_ = type_
|
|
58
59
|
|
|
59
|
-
def pp_str(self, mapping:
|
|
60
|
+
def pp_str(self, mapping: dict["TypeVariable", Any]) -> str:
|
|
60
61
|
return f"V {self.type_.pp_str(mapping)}"
|
|
61
62
|
|
|
62
63
|
def __repr__(self):
|
|
@@ -89,7 +90,7 @@ class Subtype(TypeConstraint):
|
|
|
89
90
|
self.super_type = super_type
|
|
90
91
|
self.sub_type = sub_type
|
|
91
92
|
|
|
92
|
-
def pp_str(self, mapping:
|
|
93
|
+
def pp_str(self, mapping: dict["TypeVariable", Any]) -> str:
|
|
93
94
|
return f"{self.sub_type.pp_str(mapping)} <: {self.super_type.pp_str(mapping)}"
|
|
94
95
|
|
|
95
96
|
def __repr__(self):
|
|
@@ -146,7 +147,7 @@ class Add(TypeConstraint):
|
|
|
146
147
|
self.type_1 = type_1
|
|
147
148
|
self.type_r = type_r
|
|
148
149
|
|
|
149
|
-
def pp_str(self, mapping:
|
|
150
|
+
def pp_str(self, mapping: dict["TypeVariable", Any]) -> str:
|
|
150
151
|
return "{} == {} + {}".format(
|
|
151
152
|
self.type_r.pp_str(mapping),
|
|
152
153
|
self.type_0.pp_str(mapping),
|
|
@@ -218,7 +219,7 @@ class Sub(TypeConstraint):
|
|
|
218
219
|
self.type_1 = type_1
|
|
219
220
|
self.type_r = type_r
|
|
220
221
|
|
|
221
|
-
def pp_str(self, mapping:
|
|
222
|
+
def pp_str(self, mapping: dict["TypeVariable", Any]) -> str:
|
|
222
223
|
return "{} == {} - {}".format(
|
|
223
224
|
self.type_r.pp_str(mapping),
|
|
224
225
|
self.type_0.pp_str(mapping),
|
|
@@ -280,14 +281,14 @@ _typevariable_counter = count()
|
|
|
280
281
|
class TypeVariable:
|
|
281
282
|
__slots__ = ("idx", "name")
|
|
282
283
|
|
|
283
|
-
def __init__(self, idx:
|
|
284
|
+
def __init__(self, idx: int | None = None, name: str | None = None):
|
|
284
285
|
if idx is None:
|
|
285
286
|
self.idx: int = next(_typevariable_counter)
|
|
286
287
|
else:
|
|
287
288
|
self.idx: int = idx
|
|
288
289
|
self.name = name
|
|
289
290
|
|
|
290
|
-
def pp_str(self, mapping:
|
|
291
|
+
def pp_str(self, mapping: dict["TypeVariable", Any]) -> str:
|
|
291
292
|
varname = mapping.get(self, self.name)
|
|
292
293
|
if varname is None:
|
|
293
294
|
return repr(self)
|
|
@@ -321,9 +322,9 @@ class DerivedTypeVariable(TypeVariable):
|
|
|
321
322
|
|
|
322
323
|
def __init__(
|
|
323
324
|
self,
|
|
324
|
-
type_var:
|
|
325
|
+
type_var: Union[TypeVariable, "DerivedTypeVariable"] | None,
|
|
325
326
|
label,
|
|
326
|
-
labels:
|
|
327
|
+
labels: Iterable["BaseLabel"] | None = None,
|
|
327
328
|
idx=None,
|
|
328
329
|
):
|
|
329
330
|
super().__init__(idx=idx)
|
|
@@ -341,7 +342,7 @@ class DerivedTypeVariable(TypeVariable):
|
|
|
341
342
|
if label is not None:
|
|
342
343
|
self.labels = existing_labels + (label,)
|
|
343
344
|
else:
|
|
344
|
-
self.labels:
|
|
345
|
+
self.labels: tuple["BaseLabel"] = existing_labels + tuple(labels)
|
|
345
346
|
|
|
346
347
|
if not self.labels:
|
|
347
348
|
raise ValueError("A DerivedTypeVariable must have at least one label")
|
|
@@ -349,17 +350,17 @@ class DerivedTypeVariable(TypeVariable):
|
|
|
349
350
|
def one_label(self) -> Optional["BaseLabel"]:
|
|
350
351
|
return self.labels[0] if len(self.labels) == 1 else None
|
|
351
352
|
|
|
352
|
-
def path(self) ->
|
|
353
|
+
def path(self) -> tuple["BaseLabel"]:
|
|
353
354
|
return self.labels
|
|
354
355
|
|
|
355
|
-
def longest_prefix(self) ->
|
|
356
|
+
def longest_prefix(self) -> Union[TypeVariable, "DerivedTypeVariable"] | None:
|
|
356
357
|
if not self.labels:
|
|
357
358
|
return None
|
|
358
359
|
if len(self.labels) == 1:
|
|
359
360
|
return self.type_var
|
|
360
361
|
return DerivedTypeVariable(self.type_var, None, labels=self.labels[:-1])
|
|
361
362
|
|
|
362
|
-
def pp_str(self, mapping:
|
|
363
|
+
def pp_str(self, mapping: dict["TypeVariable", Any]) -> str:
|
|
363
364
|
return ".".join([self.type_var.pp_str(mapping)] + [repr(lbl) for lbl in self.labels])
|
|
364
365
|
|
|
365
366
|
def __eq__(self, other):
|
|
@@ -401,8 +402,8 @@ class TypeVariables:
|
|
|
401
402
|
)
|
|
402
403
|
|
|
403
404
|
def __init__(self):
|
|
404
|
-
self._typevars:
|
|
405
|
-
self._last_typevars:
|
|
405
|
+
self._typevars: dict["SimVariable", set[TypeVariable]] = {}
|
|
406
|
+
self._last_typevars: dict[SimVariable, TypeVariable] = {}
|
|
406
407
|
|
|
407
408
|
def copy(self):
|
|
408
409
|
copied = TypeVariables()
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
# pylint:disable=arguments-differ,invalid-unary-operand-type
|
|
2
|
-
from typing import
|
|
2
|
+
from typing import TYPE_CHECKING
|
|
3
3
|
import logging
|
|
4
4
|
|
|
5
5
|
import ailment
|
|
@@ -81,7 +81,7 @@ class SimEngineVRAIL(
|
|
|
81
81
|
def _ail_handle_ConditionalJump(self, stmt):
|
|
82
82
|
self._expr(stmt.condition)
|
|
83
83
|
|
|
84
|
-
def _ail_handle_Call(self, stmt: ailment.Stmt.Call, is_expr=False) ->
|
|
84
|
+
def _ail_handle_Call(self, stmt: ailment.Stmt.Call, is_expr=False) -> RichR | None:
|
|
85
85
|
target = stmt.target
|
|
86
86
|
args = []
|
|
87
87
|
if stmt.args:
|
|
@@ -98,7 +98,7 @@ class SimEngineVRAIL(
|
|
|
98
98
|
create_variable = True
|
|
99
99
|
if not is_expr:
|
|
100
100
|
# this is a call statement. we need to update the return value register later
|
|
101
|
-
ret_expr:
|
|
101
|
+
ret_expr: ailment.Expr.Register | None = stmt.ret_expr
|
|
102
102
|
if ret_expr is not None:
|
|
103
103
|
ret_reg_offset = ret_expr.reg_offset
|
|
104
104
|
ret_expr_bits = ret_expr.bits
|
|
@@ -130,8 +130,8 @@ class SimEngineVRAIL(
|
|
|
130
130
|
self.state.add_type_constraint(typevars.Subtype(funcaddr_typevar, load_typevar))
|
|
131
131
|
|
|
132
132
|
# discover the prototype
|
|
133
|
-
prototype:
|
|
134
|
-
prototype_libname:
|
|
133
|
+
prototype: SimTypeFunction | None = None
|
|
134
|
+
prototype_libname: str | None = None
|
|
135
135
|
if stmt.prototype is not None:
|
|
136
136
|
prototype = stmt.prototype
|
|
137
137
|
if isinstance(stmt.target, ailment.Expr.Const):
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
from typing import Optional,
|
|
1
|
+
from typing import Optional, TYPE_CHECKING
|
|
2
2
|
import logging
|
|
3
3
|
|
|
4
|
+
import ailment
|
|
4
5
|
import claripy
|
|
5
6
|
|
|
6
7
|
from ...storage.memory_mixins.paged_memory.pages.multi_values import MultiValues
|
|
@@ -38,7 +39,7 @@ class RichR:
|
|
|
38
39
|
self,
|
|
39
40
|
data: claripy.ast.Base,
|
|
40
41
|
variable=None,
|
|
41
|
-
typevar:
|
|
42
|
+
typevar: typevars.TypeVariable | None = None,
|
|
42
43
|
type_constraints=None,
|
|
43
44
|
):
|
|
44
45
|
self.data: claripy.ast.Base = data
|
|
@@ -110,7 +111,7 @@ class SimEngineVRBase(SimEngineLight):
|
|
|
110
111
|
return False
|
|
111
112
|
|
|
112
113
|
@staticmethod
|
|
113
|
-
def _parse_offseted_addr(addr: claripy.ast.BV) ->
|
|
114
|
+
def _parse_offseted_addr(addr: claripy.ast.BV) -> tuple[claripy.ast.BV, claripy.ast.BV, claripy.ast.BV] | None:
|
|
114
115
|
if addr.op == "__add__":
|
|
115
116
|
if len(addr.args) == 2:
|
|
116
117
|
concrete_base, byte_offset = None, None
|
|
@@ -142,7 +143,7 @@ class SimEngineVRBase(SimEngineLight):
|
|
|
142
143
|
|
|
143
144
|
def _ensure_variable_existence(
|
|
144
145
|
self, richr_addr: RichR, codeloc: CodeLocation, src_expr=None
|
|
145
|
-
) ->
|
|
146
|
+
) -> list[tuple[SimVariable, int]] | None:
|
|
146
147
|
data: claripy.ast.Base = richr_addr.data
|
|
147
148
|
|
|
148
149
|
if data is None:
|
|
@@ -151,15 +152,15 @@ class SimEngineVRBase(SimEngineLight):
|
|
|
151
152
|
if self.state.is_stack_address(data):
|
|
152
153
|
# this is a stack address
|
|
153
154
|
# extract stack offset
|
|
154
|
-
stack_offset:
|
|
155
|
+
stack_offset: int | None = self.state.get_stack_offset(data)
|
|
155
156
|
|
|
156
157
|
variable_manager = self.variable_manager[self.func_addr]
|
|
157
|
-
var_candidates:
|
|
158
|
+
var_candidates: list[tuple[SimVariable, int]] = variable_manager.find_variables_by_stmt(
|
|
158
159
|
self.block.addr, self.stmt_idx, "memory"
|
|
159
160
|
)
|
|
160
161
|
|
|
161
162
|
# find the correct variable
|
|
162
|
-
existing_vars:
|
|
163
|
+
existing_vars: list[tuple[SimVariable, int]] = []
|
|
163
164
|
for candidate, offset in var_candidates:
|
|
164
165
|
if isinstance(candidate, SimStackVariable) and candidate.offset == stack_offset:
|
|
165
166
|
existing_vars.append((candidate, offset))
|
|
@@ -173,7 +174,7 @@ class SimEngineVRBase(SimEngineLight):
|
|
|
173
174
|
if variable is None:
|
|
174
175
|
# TODO: how to determine the size for a lea?
|
|
175
176
|
try:
|
|
176
|
-
vs:
|
|
177
|
+
vs: MultiValues | None = self.state.stack_region.load(stack_addr, size=1)
|
|
177
178
|
except SimMemoryMissingError:
|
|
178
179
|
vs = None
|
|
179
180
|
|
|
@@ -248,15 +249,18 @@ class SimEngineVRBase(SimEngineLight):
|
|
|
248
249
|
if self.state.is_stack_address(data):
|
|
249
250
|
# this is a stack address
|
|
250
251
|
# extract stack offset
|
|
251
|
-
stack_offset:
|
|
252
|
+
stack_offset: int | None = self.state.get_stack_offset(data)
|
|
252
253
|
|
|
253
254
|
variable_manager = self.variable_manager[self.func_addr]
|
|
254
|
-
var_candidates:
|
|
255
|
-
self.block.addr,
|
|
255
|
+
var_candidates: list[tuple[SimVariable, int]] = variable_manager.find_variables_by_stmt(
|
|
256
|
+
self.block.addr,
|
|
257
|
+
self.stmt_idx,
|
|
258
|
+
"memory",
|
|
259
|
+
block_idx=self.block.idx if isinstance(self.block, ailment.Block) else None,
|
|
256
260
|
)
|
|
257
261
|
|
|
258
262
|
# find the correct variable
|
|
259
|
-
existing_vars:
|
|
263
|
+
existing_vars: list[tuple[SimVariable, int]] = []
|
|
260
264
|
for candidate, offset in var_candidates:
|
|
261
265
|
if isinstance(candidate, SimStackVariable) and candidate.offset == stack_offset:
|
|
262
266
|
existing_vars.append((candidate, offset))
|
|
@@ -313,7 +317,7 @@ class SimEngineVRBase(SimEngineLight):
|
|
|
313
317
|
# handle register writes
|
|
314
318
|
|
|
315
319
|
# first check if there is an existing variable for the atom at this location already
|
|
316
|
-
existing_vars:
|
|
320
|
+
existing_vars: set[tuple[SimVariable, int]] = self.variable_manager[self.func_addr].find_variables_by_atom(
|
|
317
321
|
self.block.addr, self.stmt_idx, dst
|
|
318
322
|
)
|
|
319
323
|
if not existing_vars:
|
|
@@ -473,8 +477,8 @@ class SimEngineVRBase(SimEngineLight):
|
|
|
473
477
|
data: RichR,
|
|
474
478
|
size: int,
|
|
475
479
|
stmt=None,
|
|
476
|
-
offset:
|
|
477
|
-
elem_size:
|
|
480
|
+
offset: claripy.ast.BV | None = None,
|
|
481
|
+
elem_size: claripy.ast.BV | None = None,
|
|
478
482
|
):
|
|
479
483
|
variable_manager = self.variable_manager["global"]
|
|
480
484
|
if stmt is None:
|
|
@@ -636,7 +640,7 @@ class SimEngineVRBase(SimEngineLight):
|
|
|
636
640
|
dynamic_offset = None
|
|
637
641
|
|
|
638
642
|
try:
|
|
639
|
-
values:
|
|
643
|
+
values: MultiValues | None = self.state.stack_region.load(
|
|
640
644
|
self.state.stack_addr_from_offset(concrete_offset),
|
|
641
645
|
size=size,
|
|
642
646
|
endness=self.state.arch.memory_endness,
|
|
@@ -645,7 +649,7 @@ class SimEngineVRBase(SimEngineLight):
|
|
|
645
649
|
except SimMemoryMissingError:
|
|
646
650
|
values = None
|
|
647
651
|
|
|
648
|
-
all_vars:
|
|
652
|
+
all_vars: set[tuple[int, SimVariable]] = set()
|
|
649
653
|
if values:
|
|
650
654
|
for vs in values.values():
|
|
651
655
|
for v in vs:
|
|
@@ -788,8 +792,8 @@ class SimEngineVRBase(SimEngineLight):
|
|
|
788
792
|
addr: int,
|
|
789
793
|
size,
|
|
790
794
|
expr=None,
|
|
791
|
-
offset:
|
|
792
|
-
elem_size:
|
|
795
|
+
offset: claripy.ast.BV | None = None,
|
|
796
|
+
elem_size: claripy.ast.BV | None = None,
|
|
793
797
|
) -> RichR:
|
|
794
798
|
variable_manager = self.variable_manager["global"]
|
|
795
799
|
if expr is None:
|
|
@@ -862,7 +866,7 @@ class SimEngineVRBase(SimEngineLight):
|
|
|
862
866
|
codeloc = self._codeloc()
|
|
863
867
|
|
|
864
868
|
try:
|
|
865
|
-
values:
|
|
869
|
+
values: MultiValues | None = self.state.register_region.load(offset, size=size)
|
|
866
870
|
except SimMemoryMissingError:
|
|
867
871
|
values = None
|
|
868
872
|
|
|
@@ -935,7 +939,7 @@ class SimEngineVRBase(SimEngineLight):
|
|
|
935
939
|
return RichR(r_value, variable=var, typevar=typevar)
|
|
936
940
|
|
|
937
941
|
def _create_access_typevar(
|
|
938
|
-
self, typevar:
|
|
942
|
+
self, typevar: TypeVariable | DerivedTypeVariable, is_store: bool, size: int, offset: int
|
|
939
943
|
) -> DerivedTypeVariable:
|
|
940
944
|
if isinstance(typevar, DerivedTypeVariable):
|
|
941
945
|
if isinstance(typevar.labels[-1], AddN):
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
# pylint:disable=no-self-use,unused-argument
|
|
2
|
-
from typing import Set, Dict
|
|
3
2
|
|
|
4
3
|
import pyvex
|
|
5
4
|
|
|
@@ -17,10 +16,10 @@ class VEXIRSBScanner(SimEngineLightVEXMixin):
|
|
|
17
16
|
|
|
18
17
|
# the following variables are for narrowing argument-passing register on 64-bit architectures. they are
|
|
19
18
|
# initialized before processing each block.
|
|
20
|
-
self.tmps_with_64bit_regs:
|
|
21
|
-
self.tmps_converted_to_32bit:
|
|
22
|
-
self.tmps_assignment_stmtidx:
|
|
23
|
-
self.stmts_to_lower:
|
|
19
|
+
self.tmps_with_64bit_regs: set[int] = set() # tmps that store 64-bit register values
|
|
20
|
+
self.tmps_converted_to_32bit: set[int] = set() # tmps that store the 64-to-32-bit converted values
|
|
21
|
+
self.tmps_assignment_stmtidx: dict[int, int] = {} # statement IDs for the assignment of each tmp
|
|
22
|
+
self.stmts_to_lower: set[int] = set()
|
|
24
23
|
|
|
25
24
|
# the following variables are for recognizing redundant argument register reads in gcc(?) -O0 binaries.
|
|
26
25
|
# e.g.,
|
|
@@ -28,10 +27,10 @@ class VEXIRSBScanner(SimEngineLightVEXMixin):
|
|
|
28
27
|
# mov rdi, rax
|
|
29
28
|
#
|
|
30
29
|
# we will not create a variable for the register read in the first instruction (read from r9) in this case.
|
|
31
|
-
self.tmp_with_reg_as_value:
|
|
32
|
-
self.reg_with_reg_as_value:
|
|
33
|
-
self.reg_read_stmt_id:
|
|
34
|
-
self.reg_read_stmts_to_ignore:
|
|
30
|
+
self.tmp_with_reg_as_value: dict[int, int] = {}
|
|
31
|
+
self.reg_with_reg_as_value: dict[int, int] = {}
|
|
32
|
+
self.reg_read_stmt_id: dict[int, int] = {}
|
|
33
|
+
self.reg_read_stmts_to_ignore: set[int] = set()
|
|
35
34
|
|
|
36
35
|
def _top(self, size: int):
|
|
37
36
|
return None
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import logging
|
|
2
2
|
from collections import defaultdict
|
|
3
|
-
from typing import Tuple
|
|
4
3
|
|
|
5
4
|
import claripy
|
|
6
5
|
|
|
@@ -90,7 +89,7 @@ class VariableRecoveryState(VariableRecoveryStateBase):
|
|
|
90
89
|
)
|
|
91
90
|
concrete_state.inspect.add_breakpoint("mem_write", BP(enabled=True, action=self._hook_memory_write))
|
|
92
91
|
|
|
93
|
-
def merge(self, others:
|
|
92
|
+
def merge(self, others: tuple["VariableRecoveryState"], successor=None) -> tuple["VariableRecoveryState", bool]:
|
|
94
93
|
"""
|
|
95
94
|
Merge two abstract states.
|
|
96
95
|
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import weakref
|
|
2
|
-
from typing import
|
|
2
|
+
from typing import Any, TYPE_CHECKING
|
|
3
|
+
from collections.abc import Generator, Iterable
|
|
3
4
|
import logging
|
|
4
5
|
from collections import defaultdict
|
|
5
6
|
|
|
@@ -51,7 +52,7 @@ def parse_stack_pointer(sp):
|
|
|
51
52
|
class VariableAnnotation(Annotation):
|
|
52
53
|
__slots__ = ("addr_and_variables",)
|
|
53
54
|
|
|
54
|
-
def __init__(self, addr_and_variables:
|
|
55
|
+
def __init__(self, addr_and_variables: list[tuple[int, SimVariable]]):
|
|
55
56
|
self.addr_and_variables = addr_and_variables
|
|
56
57
|
|
|
57
58
|
@property
|
|
@@ -87,7 +88,7 @@ class VariableRecoveryBase(Analysis):
|
|
|
87
88
|
self._store_live_variables = store_live_variables
|
|
88
89
|
|
|
89
90
|
self._outstates = {}
|
|
90
|
-
self._instates:
|
|
91
|
+
self._instates: dict[Any, VariableRecoveryStateBase] = {}
|
|
91
92
|
self._dominance_frontiers = None
|
|
92
93
|
|
|
93
94
|
#
|
|
@@ -211,8 +212,8 @@ class VariableRecoveryStateBase:
|
|
|
211
212
|
self.global_region.set_state(self)
|
|
212
213
|
|
|
213
214
|
# Used during merging
|
|
214
|
-
self.successor_block_addr:
|
|
215
|
-
self.phi_variables:
|
|
215
|
+
self.successor_block_addr: int | None = None
|
|
216
|
+
self.phi_variables: dict[SimVariable, SimVariable] = {}
|
|
216
217
|
|
|
217
218
|
self.typevars = TypeVariables() if typevars is None else typevars
|
|
218
219
|
self.type_constraints = defaultdict(set) if type_constraints is None else type_constraints
|
|
@@ -222,7 +223,7 @@ class VariableRecoveryStateBase:
|
|
|
222
223
|
if delayed_type_constraints is None
|
|
223
224
|
else delayed_type_constraints
|
|
224
225
|
)
|
|
225
|
-
self.stack_offset_typevars:
|
|
226
|
+
self.stack_offset_typevars: dict[int, TypeVariable] = (
|
|
226
227
|
{} if stack_offset_typevars is None else stack_offset_typevars
|
|
227
228
|
)
|
|
228
229
|
|
|
@@ -244,14 +245,14 @@ class VariableRecoveryStateBase:
|
|
|
244
245
|
return False
|
|
245
246
|
|
|
246
247
|
@staticmethod
|
|
247
|
-
def extract_variables(expr: claripy.ast.Base) -> Generator[
|
|
248
|
+
def extract_variables(expr: claripy.ast.Base) -> Generator[tuple[int, SimVariable | SpOffset], None, None]:
|
|
248
249
|
for anno in expr.annotations:
|
|
249
250
|
if isinstance(anno, VariableAnnotation):
|
|
250
251
|
yield from anno.addr_and_variables
|
|
251
252
|
|
|
252
253
|
@staticmethod
|
|
253
254
|
def annotate_with_variables(
|
|
254
|
-
expr: claripy.ast.Base, addr_and_variables: Iterable[
|
|
255
|
+
expr: claripy.ast.Base, addr_and_variables: Iterable[tuple[int, SimVariable | SpOffset]]
|
|
255
256
|
) -> claripy.ast.Base:
|
|
256
257
|
expr = expr.replace_annotations((VariableAnnotation(list(addr_and_variables)),))
|
|
257
258
|
return expr
|
|
@@ -276,7 +277,7 @@ class VariableRecoveryStateBase:
|
|
|
276
277
|
return False
|
|
277
278
|
|
|
278
279
|
@staticmethod
|
|
279
|
-
def extract_stack_offset_from_addr(addr: claripy.ast.Base) ->
|
|
280
|
+
def extract_stack_offset_from_addr(addr: claripy.ast.Base) -> claripy.ast.Base | None:
|
|
280
281
|
r = None
|
|
281
282
|
if addr.op == "BVS":
|
|
282
283
|
if addr.args[0] == "stack_base":
|
|
@@ -300,7 +301,7 @@ class VariableRecoveryStateBase:
|
|
|
300
301
|
r = r1 - r2
|
|
301
302
|
return r
|
|
302
303
|
|
|
303
|
-
def get_stack_offset(self, addr: claripy.ast.Base) ->
|
|
304
|
+
def get_stack_offset(self, addr: claripy.ast.Base) -> int | None:
|
|
304
305
|
if "stack_base" in addr.variables:
|
|
305
306
|
r = VariableRecoveryStateBase.extract_stack_offset_from_addr(addr)
|
|
306
307
|
if r is None:
|
|
@@ -406,17 +407,17 @@ class VariableRecoveryStateBase:
|
|
|
406
407
|
|
|
407
408
|
@staticmethod
|
|
408
409
|
def _mo_cmp(
|
|
409
|
-
mos_self:
|
|
410
|
+
mos_self: set["SimMemoryObject"], mos_other: set["SimMemoryObject"], addr: int, size: int
|
|
410
411
|
): # pylint:disable=unused-argument
|
|
411
412
|
# comparing bytes from two sets of memory objects
|
|
412
413
|
# we don't need to resort to byte-level comparison. object-level is good enough.
|
|
413
414
|
|
|
414
415
|
return mos_self == mos_other
|
|
415
416
|
|
|
416
|
-
def _make_phi_variable(self, values:
|
|
417
|
+
def _make_phi_variable(self, values: set[claripy.ast.Base]) -> claripy.ast.Base | None:
|
|
417
418
|
# we only create a new phi variable if the there is at least one variable involved
|
|
418
419
|
variables = set()
|
|
419
|
-
bits:
|
|
420
|
+
bits: int | None = None
|
|
420
421
|
for v in values:
|
|
421
422
|
bits = v.size()
|
|
422
423
|
for _, var in self.extract_variables(v):
|