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
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
from typing import Optional,
|
|
1
|
+
from typing import Optional, Union, Any, TYPE_CHECKING, overload
|
|
2
|
+
from collections.abc import Iterable, Generator
|
|
2
3
|
import weakref
|
|
3
4
|
import logging
|
|
4
5
|
from enum import Enum, auto
|
|
@@ -182,8 +183,8 @@ class LiveDefinitions:
|
|
|
182
183
|
if heap is None
|
|
183
184
|
else heap
|
|
184
185
|
)
|
|
185
|
-
self.tmps:
|
|
186
|
-
self.others:
|
|
186
|
+
self.tmps: dict[int, set[Definition]] = {} if tmps is None else tmps
|
|
187
|
+
self.others: dict[Atom, MultiValues] = others if others is not None else {}
|
|
187
188
|
|
|
188
189
|
# set state
|
|
189
190
|
self.registers.set_state(self)
|
|
@@ -195,10 +196,10 @@ class LiveDefinitions:
|
|
|
195
196
|
self.stack_uses = Uses() if stack_uses is None else stack_uses
|
|
196
197
|
self.heap_uses = Uses() if heap_uses is None else heap_uses
|
|
197
198
|
self.memory_uses = Uses() if memory_uses is None else memory_uses
|
|
198
|
-
self.tmp_uses:
|
|
199
|
+
self.tmp_uses: dict[int, set[CodeLocation]] = defaultdict(set) if tmp_uses is None else tmp_uses
|
|
199
200
|
self.other_uses = Uses() if other_uses is None else other_uses
|
|
200
201
|
|
|
201
|
-
self.uses_by_codeloc:
|
|
202
|
+
self.uses_by_codeloc: dict[CodeLocation, set[Definition]] = defaultdict(set)
|
|
202
203
|
|
|
203
204
|
@property
|
|
204
205
|
@deprecated("registers")
|
|
@@ -260,8 +261,8 @@ class LiveDefinitions:
|
|
|
260
261
|
|
|
261
262
|
@staticmethod
|
|
262
263
|
def _mo_cmp(
|
|
263
|
-
mo_self: Union["SimMemoryObject",
|
|
264
|
-
mo_other: Union["SimMemoryObject",
|
|
264
|
+
mo_self: Union["SimMemoryObject", set["SimMemoryObject"]],
|
|
265
|
+
mo_other: Union["SimMemoryObject", set["SimMemoryObject"]],
|
|
265
266
|
addr: int,
|
|
266
267
|
size: int,
|
|
267
268
|
): # pylint:disable=unused-argument
|
|
@@ -317,7 +318,7 @@ class LiveDefinitions:
|
|
|
317
318
|
return True
|
|
318
319
|
return False
|
|
319
320
|
|
|
320
|
-
def stack_address(self, offset: int) ->
|
|
321
|
+
def stack_address(self, offset: int) -> claripy.ast.bv.BV | None:
|
|
321
322
|
base = claripy.BVS("stack_base", self.arch.bits, explicit_name=True)
|
|
322
323
|
if offset:
|
|
323
324
|
return base + offset
|
|
@@ -328,7 +329,7 @@ class LiveDefinitions:
|
|
|
328
329
|
return "stack_base" in addr.variables
|
|
329
330
|
|
|
330
331
|
@staticmethod
|
|
331
|
-
def get_stack_offset(addr: claripy.ast.Base, had_stack_base=False) ->
|
|
332
|
+
def get_stack_offset(addr: claripy.ast.Base, had_stack_base=False) -> int | None:
|
|
332
333
|
if had_stack_base and addr.op == "BVV":
|
|
333
334
|
assert isinstance(addr, claripy.ast.BV)
|
|
334
335
|
return addr.concrete_value
|
|
@@ -377,7 +378,7 @@ class LiveDefinitions:
|
|
|
377
378
|
yield anno.definition
|
|
378
379
|
|
|
379
380
|
@staticmethod
|
|
380
|
-
def extract_defs_from_annotations(annos: Iterable["Annotation"]) ->
|
|
381
|
+
def extract_defs_from_annotations(annos: Iterable["Annotation"]) -> set[Definition]:
|
|
381
382
|
defs = set()
|
|
382
383
|
for anno in annos:
|
|
383
384
|
if isinstance(anno, DefinitionAnnotation):
|
|
@@ -410,7 +411,7 @@ class LiveDefinitions:
|
|
|
410
411
|
assert result is not None
|
|
411
412
|
return result
|
|
412
413
|
|
|
413
|
-
def get_sp_offset(self) ->
|
|
414
|
+
def get_sp_offset(self) -> int | None:
|
|
414
415
|
"""
|
|
415
416
|
Return the offset of the stack pointer.
|
|
416
417
|
"""
|
|
@@ -426,7 +427,7 @@ class LiveDefinitions:
|
|
|
426
427
|
result = self.get_stack_offset(sp_v)
|
|
427
428
|
return result
|
|
428
429
|
|
|
429
|
-
def get_stack_address(self, offset: claripy.ast.Base) ->
|
|
430
|
+
def get_stack_address(self, offset: claripy.ast.Base) -> int | None:
|
|
430
431
|
offset_int = self.get_stack_offset(offset)
|
|
431
432
|
if offset_int is None:
|
|
432
433
|
return None
|
|
@@ -443,7 +444,7 @@ class LiveDefinitions:
|
|
|
443
444
|
raise ValueError("Unsupported architecture word size %d" % self.arch.bits)
|
|
444
445
|
return (base_v + offset) & mask
|
|
445
446
|
|
|
446
|
-
def merge(self, *others: "LiveDefinitions") ->
|
|
447
|
+
def merge(self, *others: "LiveDefinitions") -> tuple["LiveDefinitions", bool]:
|
|
447
448
|
state = self.copy()
|
|
448
449
|
|
|
449
450
|
merge_occurred = state.registers.merge([other.registers for other in others], None)
|
|
@@ -545,10 +546,10 @@ class LiveDefinitions:
|
|
|
545
546
|
code_loc: CodeLocation,
|
|
546
547
|
data: MultiValues,
|
|
547
548
|
dummy=False,
|
|
548
|
-
tags:
|
|
549
|
+
tags: set[Tag] | None = None,
|
|
549
550
|
endness=None,
|
|
550
551
|
annotated=False,
|
|
551
|
-
) ->
|
|
552
|
+
) -> MultiValues | None:
|
|
552
553
|
if data is None:
|
|
553
554
|
raise TypeError("kill_and_add_definition() does not take None as data.")
|
|
554
555
|
|
|
@@ -612,7 +613,7 @@ class LiveDefinitions:
|
|
|
612
613
|
|
|
613
614
|
return d
|
|
614
615
|
|
|
615
|
-
def add_use(self, atom: Atom, code_loc: CodeLocation, expr:
|
|
616
|
+
def add_use(self, atom: Atom, code_loc: CodeLocation, expr: Any | None = None) -> None:
|
|
616
617
|
if isinstance(atom, Register):
|
|
617
618
|
self.add_register_use(atom.reg_offset, atom.size, code_loc, expr=expr)
|
|
618
619
|
elif isinstance(atom, MemoryLocation):
|
|
@@ -654,8 +655,8 @@ class LiveDefinitions:
|
|
|
654
655
|
self.other_uses.add_use(definition, code_loc, expr)
|
|
655
656
|
|
|
656
657
|
def get_definitions(
|
|
657
|
-
self, thing:
|
|
658
|
-
) ->
|
|
658
|
+
self, thing: Atom | Definition[Atom] | Iterable[Atom] | Iterable[Definition[Atom]] | MultiValues
|
|
659
|
+
) -> set[Definition[Atom]]:
|
|
659
660
|
if isinstance(thing, MultiValues):
|
|
660
661
|
defs = set()
|
|
661
662
|
for vs in thing.values():
|
|
@@ -692,13 +693,13 @@ class LiveDefinitions:
|
|
|
692
693
|
defs |= self.get_definitions(mv)
|
|
693
694
|
return defs
|
|
694
695
|
|
|
695
|
-
def get_tmp_definitions(self, tmp_idx: int) ->
|
|
696
|
+
def get_tmp_definitions(self, tmp_idx: int) -> set[Definition]:
|
|
696
697
|
if tmp_idx in self.tmps:
|
|
697
698
|
return self.tmps[tmp_idx]
|
|
698
699
|
else:
|
|
699
700
|
return set()
|
|
700
701
|
|
|
701
|
-
def get_register_definitions(self, reg_offset: int, size: int) ->
|
|
702
|
+
def get_register_definitions(self, reg_offset: int, size: int) -> set[Definition]:
|
|
702
703
|
try:
|
|
703
704
|
annotations = self.registers.load_annotations(reg_offset, size)
|
|
704
705
|
except SimMemoryMissingError as ex:
|
|
@@ -710,14 +711,14 @@ class LiveDefinitions:
|
|
|
710
711
|
|
|
711
712
|
return LiveDefinitions.extract_defs_from_annotations(annotations)
|
|
712
713
|
|
|
713
|
-
def get_stack_values(self, stack_offset: int, size: int, endness: str) ->
|
|
714
|
+
def get_stack_values(self, stack_offset: int, size: int, endness: str) -> MultiValues | None:
|
|
714
715
|
stack_addr = self.stack_offset_to_stack_addr(stack_offset)
|
|
715
716
|
try:
|
|
716
717
|
return self.stack.load(stack_addr, size=size, endness=endness)
|
|
717
718
|
except SimMemoryMissingError:
|
|
718
719
|
return None
|
|
719
720
|
|
|
720
|
-
def get_stack_definitions(self, stack_offset: int, size: int) ->
|
|
721
|
+
def get_stack_definitions(self, stack_offset: int, size: int) -> set[Definition]:
|
|
721
722
|
try:
|
|
722
723
|
stack_addr = self.stack_offset_to_stack_addr(stack_offset)
|
|
723
724
|
annotations = self.stack.load_annotations(stack_addr, size)
|
|
@@ -726,7 +727,7 @@ class LiveDefinitions:
|
|
|
726
727
|
|
|
727
728
|
return LiveDefinitions.extract_defs_from_annotations(annotations)
|
|
728
729
|
|
|
729
|
-
def get_heap_definitions(self, heap_addr: int, size: int) ->
|
|
730
|
+
def get_heap_definitions(self, heap_addr: int, size: int) -> set[Definition]:
|
|
730
731
|
try:
|
|
731
732
|
annotations = self.heap.load_annotations(heap_addr, size)
|
|
732
733
|
except SimMemoryMissingError:
|
|
@@ -734,7 +735,7 @@ class LiveDefinitions:
|
|
|
734
735
|
|
|
735
736
|
return LiveDefinitions.extract_defs_from_annotations(annotations)
|
|
736
737
|
|
|
737
|
-
def get_memory_definitions(self, addr: int, size: int) ->
|
|
738
|
+
def get_memory_definitions(self, addr: int, size: int) -> set[Definition]:
|
|
738
739
|
try:
|
|
739
740
|
annotations = self.memory.load_annotations(addr, size)
|
|
740
741
|
except SimMemoryMissingError:
|
|
@@ -750,19 +751,19 @@ class LiveDefinitions:
|
|
|
750
751
|
return result
|
|
751
752
|
|
|
752
753
|
@deprecated("get_values")
|
|
753
|
-
def get_value_from_definition(self, definition: Definition) ->
|
|
754
|
+
def get_value_from_definition(self, definition: Definition) -> MultiValues | None:
|
|
754
755
|
return self.get_value_from_atom(definition.atom)
|
|
755
756
|
|
|
756
757
|
@deprecated("get_one_value")
|
|
757
|
-
def get_one_value_from_definition(self, definition: Definition) ->
|
|
758
|
+
def get_one_value_from_definition(self, definition: Definition) -> claripy.ast.bv.BV | None:
|
|
758
759
|
return self.get_one_value_from_atom(definition.atom)
|
|
759
760
|
|
|
760
761
|
@deprecated("get_concrete_value")
|
|
761
|
-
def get_concrete_value_from_definition(self, definition: Definition) ->
|
|
762
|
+
def get_concrete_value_from_definition(self, definition: Definition) -> int | None:
|
|
762
763
|
return self.get_concrete_value_from_atom(definition.atom)
|
|
763
764
|
|
|
764
765
|
@deprecated("get_values")
|
|
765
|
-
def get_value_from_atom(self, atom: Atom) ->
|
|
766
|
+
def get_value_from_atom(self, atom: Atom) -> MultiValues | None:
|
|
766
767
|
if isinstance(atom, Register):
|
|
767
768
|
try:
|
|
768
769
|
return self.registers.load(atom.reg_offset, size=atom.size)
|
|
@@ -792,14 +793,14 @@ class LiveDefinitions:
|
|
|
792
793
|
return None
|
|
793
794
|
|
|
794
795
|
@deprecated("get_one_value")
|
|
795
|
-
def get_one_value_from_atom(self, atom: Atom) ->
|
|
796
|
+
def get_one_value_from_atom(self, atom: Atom) -> claripy.ast.bv.BV | None:
|
|
796
797
|
r = self.get_value_from_atom(atom)
|
|
797
798
|
if r is None:
|
|
798
799
|
return None
|
|
799
800
|
return r.one_value()
|
|
800
801
|
|
|
801
802
|
@deprecated("get_concrete_value")
|
|
802
|
-
def get_concrete_value_from_atom(self, atom: Atom) ->
|
|
803
|
+
def get_concrete_value_from_atom(self, atom: Atom) -> int | None:
|
|
803
804
|
r = self.get_one_value_from_atom(atom)
|
|
804
805
|
if r is None:
|
|
805
806
|
return None
|
|
@@ -808,8 +809,8 @@ class LiveDefinitions:
|
|
|
808
809
|
return r.concrete_value
|
|
809
810
|
|
|
810
811
|
def get_values(
|
|
811
|
-
self, spec:
|
|
812
|
-
) ->
|
|
812
|
+
self, spec: Atom | Definition[Atom] | Iterable[Atom] | Iterable[Definition[Atom]]
|
|
813
|
+
) -> MultiValues | None:
|
|
813
814
|
if isinstance(spec, Definition):
|
|
814
815
|
atom = spec.atom
|
|
815
816
|
elif isinstance(spec, Atom):
|
|
@@ -868,9 +869,9 @@ class LiveDefinitions:
|
|
|
868
869
|
|
|
869
870
|
def get_one_value(
|
|
870
871
|
self,
|
|
871
|
-
spec:
|
|
872
|
+
spec: Atom | Definition | Iterable[Atom] | Iterable[Definition[Atom]],
|
|
872
873
|
strip_annotations: bool = False,
|
|
873
|
-
) ->
|
|
874
|
+
) -> claripy.ast.bv.BV | None:
|
|
874
875
|
r = self.get_values(spec)
|
|
875
876
|
if r is None:
|
|
876
877
|
return None
|
|
@@ -878,21 +879,21 @@ class LiveDefinitions:
|
|
|
878
879
|
|
|
879
880
|
@overload
|
|
880
881
|
def get_concrete_value(
|
|
881
|
-
self, spec:
|
|
882
|
-
) ->
|
|
882
|
+
self, spec: Atom | Definition[Atom] | Iterable[Atom] | Iterable[Definition[Atom]], cast_to: type[int] = ...
|
|
883
|
+
) -> int | None: ...
|
|
883
884
|
|
|
884
885
|
@overload
|
|
885
886
|
def get_concrete_value(
|
|
886
887
|
self,
|
|
887
|
-
spec:
|
|
888
|
-
cast_to:
|
|
889
|
-
) ->
|
|
888
|
+
spec: Atom | Definition[Atom] | Iterable[Atom] | Iterable[Definition[Atom]],
|
|
889
|
+
cast_to: type[bytes] = ...,
|
|
890
|
+
) -> bytes | None: ...
|
|
890
891
|
|
|
891
892
|
def get_concrete_value(
|
|
892
893
|
self,
|
|
893
|
-
spec:
|
|
894
|
-
cast_to:
|
|
895
|
-
) ->
|
|
894
|
+
spec: Atom | Definition[Atom] | Iterable[Atom] | Iterable[Definition[Atom]],
|
|
895
|
+
cast_to: type[int] | type[bytes] = int,
|
|
896
|
+
) -> int | bytes | None:
|
|
896
897
|
r = self.get_one_value(spec, strip_annotations=True)
|
|
897
898
|
if r is None:
|
|
898
899
|
return None
|
|
@@ -903,7 +904,7 @@ class LiveDefinitions:
|
|
|
903
904
|
return result.to_bytes(len(r) // 8, "big")
|
|
904
905
|
return result
|
|
905
906
|
|
|
906
|
-
def add_register_use(self, reg_offset: int, size: int, code_loc: CodeLocation, expr:
|
|
907
|
+
def add_register_use(self, reg_offset: int, size: int, code_loc: CodeLocation, expr: Any | None = None) -> None:
|
|
907
908
|
# get all current definitions
|
|
908
909
|
try:
|
|
909
910
|
mvs: MultiValues = self.registers.load(reg_offset, size=size)
|
|
@@ -915,22 +916,22 @@ class LiveDefinitions:
|
|
|
915
916
|
for def_ in self.extract_defs(v):
|
|
916
917
|
self.add_register_use_by_def(def_, code_loc, expr=expr)
|
|
917
918
|
|
|
918
|
-
def add_register_use_by_def(self, def_: Definition, code_loc: CodeLocation, expr:
|
|
919
|
+
def add_register_use_by_def(self, def_: Definition, code_loc: CodeLocation, expr: Any | None = None) -> None:
|
|
919
920
|
self.register_uses.add_use(def_, code_loc, expr=expr)
|
|
920
921
|
self.uses_by_codeloc[code_loc].add(def_)
|
|
921
922
|
|
|
922
|
-
def add_stack_use(self, atom: MemoryLocation, code_loc: CodeLocation, expr:
|
|
923
|
+
def add_stack_use(self, atom: MemoryLocation, code_loc: CodeLocation, expr: Any | None = None) -> None:
|
|
923
924
|
if not isinstance(atom.addr, SpOffset):
|
|
924
925
|
raise TypeError("Atom %r is not a stack location atom." % atom)
|
|
925
926
|
|
|
926
927
|
for current_def in self.get_definitions(atom):
|
|
927
928
|
self.add_stack_use_by_def(current_def, code_loc, expr=expr)
|
|
928
929
|
|
|
929
|
-
def add_stack_use_by_def(self, def_: Definition, code_loc: CodeLocation, expr:
|
|
930
|
+
def add_stack_use_by_def(self, def_: Definition, code_loc: CodeLocation, expr: Any | None = None) -> None:
|
|
930
931
|
self.stack_uses.add_use(def_, code_loc, expr=expr)
|
|
931
932
|
self.uses_by_codeloc[code_loc].add(def_)
|
|
932
933
|
|
|
933
|
-
def add_heap_use(self, atom: MemoryLocation, code_loc: CodeLocation, expr:
|
|
934
|
+
def add_heap_use(self, atom: MemoryLocation, code_loc: CodeLocation, expr: Any | None = None) -> None:
|
|
934
935
|
if not isinstance(atom.addr, HeapAddress):
|
|
935
936
|
raise TypeError("Atom %r is not a heap location atom." % atom)
|
|
936
937
|
|
|
@@ -939,18 +940,18 @@ class LiveDefinitions:
|
|
|
939
940
|
for current_def in current_defs:
|
|
940
941
|
self.add_heap_use_by_def(current_def, code_loc, expr=expr)
|
|
941
942
|
|
|
942
|
-
def add_heap_use_by_def(self, def_: Definition, code_loc: CodeLocation, expr:
|
|
943
|
+
def add_heap_use_by_def(self, def_: Definition, code_loc: CodeLocation, expr: Any | None = None) -> None:
|
|
943
944
|
self.heap_uses.add_use(def_, code_loc, expr=expr)
|
|
944
945
|
self.uses_by_codeloc[code_loc].add(def_)
|
|
945
946
|
|
|
946
|
-
def add_memory_use(self, atom: MemoryLocation, code_loc: CodeLocation, expr:
|
|
947
|
+
def add_memory_use(self, atom: MemoryLocation, code_loc: CodeLocation, expr: Any | None = None) -> None:
|
|
947
948
|
# get all current definitions
|
|
948
|
-
current_defs:
|
|
949
|
+
current_defs: set[Definition] = self.get_definitions(atom)
|
|
949
950
|
|
|
950
951
|
for current_def in current_defs:
|
|
951
952
|
self.add_memory_use_by_def(current_def, code_loc, expr=expr)
|
|
952
953
|
|
|
953
|
-
def add_memory_use_by_def(self, def_: Definition, code_loc: CodeLocation, expr:
|
|
954
|
+
def add_memory_use_by_def(self, def_: Definition, code_loc: CodeLocation, expr: Any | None = None) -> None:
|
|
954
955
|
self.memory_uses.add_use(def_, code_loc, expr=expr)
|
|
955
956
|
self.uses_by_codeloc[code_loc].add(def_)
|
|
956
957
|
|
|
@@ -977,18 +978,18 @@ class LiveDefinitions:
|
|
|
977
978
|
@overload
|
|
978
979
|
def deref(
|
|
979
980
|
self,
|
|
980
|
-
pointer:
|
|
981
|
-
size:
|
|
981
|
+
pointer: MultiValues | Atom | Definition | Iterable[Atom] | Iterable[Definition],
|
|
982
|
+
size: int | DerefSize,
|
|
982
983
|
endness: archinfo.Endness = ...,
|
|
983
|
-
) ->
|
|
984
|
+
) -> set[MemoryLocation]: ...
|
|
984
985
|
|
|
985
986
|
@overload
|
|
986
987
|
def deref(
|
|
987
988
|
self,
|
|
988
|
-
pointer:
|
|
989
|
-
size:
|
|
989
|
+
pointer: int | claripy.ast.BV | HeapAddress | SpOffset,
|
|
990
|
+
size: int | DerefSize,
|
|
990
991
|
endness: archinfo.Endness = ...,
|
|
991
|
-
) ->
|
|
992
|
+
) -> MemoryLocation | None: ...
|
|
992
993
|
|
|
993
994
|
def deref(self, pointer, size, endness=archinfo.Endness.BE):
|
|
994
995
|
if isinstance(pointer, (Atom, Definition)):
|
|
@@ -1054,7 +1055,7 @@ class LiveDefinitions:
|
|
|
1054
1055
|
return "heap_base" in addr.variables
|
|
1055
1056
|
|
|
1056
1057
|
@staticmethod
|
|
1057
|
-
def get_heap_offset(addr: claripy.ast.Base) ->
|
|
1058
|
+
def get_heap_offset(addr: claripy.ast.Base) -> int | None:
|
|
1058
1059
|
if "heap_base" in addr.variables:
|
|
1059
1060
|
if addr.op == "BVS":
|
|
1060
1061
|
return 0
|
|
@@ -1062,7 +1063,7 @@ class LiveDefinitions:
|
|
|
1062
1063
|
return addr.args[1].concrete_value
|
|
1063
1064
|
return None
|
|
1064
1065
|
|
|
1065
|
-
def heap_address(self, offset:
|
|
1066
|
+
def heap_address(self, offset: int | HeapAddress) -> claripy.ast.BV:
|
|
1066
1067
|
if isinstance(offset, HeapAddress):
|
|
1067
1068
|
if not isinstance(offset.value, int):
|
|
1068
1069
|
raise TypeError("TODO: what's this? contact @rhelmot")
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
from typing import DefaultDict, Optional,
|
|
1
|
+
from typing import DefaultDict, Optional, TYPE_CHECKING
|
|
2
2
|
|
|
3
3
|
from collections import defaultdict
|
|
4
4
|
from itertools import chain
|
|
@@ -13,11 +13,11 @@ if TYPE_CHECKING:
|
|
|
13
13
|
from angr.code_location import CodeLocation
|
|
14
14
|
|
|
15
15
|
|
|
16
|
-
LocationType =
|
|
17
|
-
LocationWithPosType =
|
|
16
|
+
LocationType = tuple[int, Optional[int], Optional[int]] # block addr, block ID, stmt ID
|
|
17
|
+
LocationWithPosType = tuple[
|
|
18
18
|
int, Optional[int], Optional[int], ObservationPointType
|
|
19
19
|
] # block addr, block ID, stmt ID, before/after
|
|
20
|
-
BlockAddrType =
|
|
20
|
+
BlockAddrType = tuple[int, Optional[int]] # block addr, block ID
|
|
21
21
|
|
|
22
22
|
|
|
23
23
|
class Liveness:
|
|
@@ -26,14 +26,14 @@ class Liveness:
|
|
|
26
26
|
"""
|
|
27
27
|
|
|
28
28
|
def __init__(self):
|
|
29
|
-
self.curr_live_defs:
|
|
30
|
-
self.curr_loc:
|
|
31
|
-
self.curr_block:
|
|
32
|
-
self.curr_stmt_idx:
|
|
33
|
-
self.blockstart_to_defs: DefaultDict[BlockAddrType,
|
|
34
|
-
self.blockend_to_defs: DefaultDict[BlockAddrType,
|
|
35
|
-
self.loc_to_killed_defs: DefaultDict[BlockAddrType,
|
|
36
|
-
self.loc_to_added_defs: DefaultDict[BlockAddrType,
|
|
29
|
+
self.curr_live_defs: set["Definition"] = set()
|
|
30
|
+
self.curr_loc: LocationType | None = None
|
|
31
|
+
self.curr_block: BlockAddrType | None = None
|
|
32
|
+
self.curr_stmt_idx: int | None = None
|
|
33
|
+
self.blockstart_to_defs: DefaultDict[BlockAddrType, set["Definition"]] = defaultdict(set)
|
|
34
|
+
self.blockend_to_defs: DefaultDict[BlockAddrType, set["Definition"]] = defaultdict(set)
|
|
35
|
+
self.loc_to_killed_defs: DefaultDict[BlockAddrType, dict[int, set["Definition"]]] = defaultdict(dict)
|
|
36
|
+
self.loc_to_added_defs: DefaultDict[BlockAddrType, dict[int, set["Definition"]]] = defaultdict(dict)
|
|
37
37
|
self._node_max_stmt_id: DefaultDict[BlockAddrType, int] = defaultdict(int)
|
|
38
38
|
|
|
39
39
|
def add_def(self, d: "Definition") -> None:
|
|
@@ -65,7 +65,7 @@ class Liveness:
|
|
|
65
65
|
):
|
|
66
66
|
self._node_max_stmt_id[(code_loc.block_addr, code_loc.block_idx)] = code_loc.stmt_idx
|
|
67
67
|
|
|
68
|
-
def at_new_block(self, code_loc: "CodeLocation", pred_codelocs:
|
|
68
|
+
def at_new_block(self, code_loc: "CodeLocation", pred_codelocs: list["CodeLocation"]) -> None:
|
|
69
69
|
"""
|
|
70
70
|
Only support moving to a new block from one or more blocks.
|
|
71
71
|
"""
|
|
@@ -87,12 +87,12 @@ class Liveness:
|
|
|
87
87
|
self.curr_loc = loc
|
|
88
88
|
self.curr_stmt_idx = 0
|
|
89
89
|
|
|
90
|
-
def find_defs_at(self, code_loc: "CodeLocation", op: int = OP_BEFORE) ->
|
|
90
|
+
def find_defs_at(self, code_loc: "CodeLocation", op: int = OP_BEFORE) -> set["Definition"]:
|
|
91
91
|
return self.find_defs_at_raw(code_loc.block_addr, code_loc.block_idx, code_loc.stmt_idx, op=op)
|
|
92
92
|
|
|
93
93
|
def find_defs_at_raw(
|
|
94
|
-
self, block_addr: int, block_idx:
|
|
95
|
-
) ->
|
|
94
|
+
self, block_addr: int, block_idx: int | None, stmt_idx: int | None, op: int = OP_BEFORE
|
|
95
|
+
) -> set["Definition"]:
|
|
96
96
|
block: BlockAddrType = block_addr, block_idx
|
|
97
97
|
if block not in self.blockstart_to_defs:
|
|
98
98
|
defs = set()
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
from typing import
|
|
1
|
+
from typing import Union, TYPE_CHECKING, overload
|
|
2
2
|
|
|
3
3
|
from .atoms import Atom, Register, MemoryLocation, SpOffset
|
|
4
4
|
from .uses import Uses
|
|
@@ -17,12 +17,12 @@ class ReachingDefinitionsModel:
|
|
|
17
17
|
Models the definitions, uses, and memory of a ReachingDefinitionState object
|
|
18
18
|
"""
|
|
19
19
|
|
|
20
|
-
def __init__(self, func_addr:
|
|
20
|
+
def __init__(self, func_addr: int | None = None, track_liveness: bool = True):
|
|
21
21
|
self.func_addr = func_addr # do not use. only for pretty-printing
|
|
22
|
-
self.observed_results:
|
|
23
|
-
|
|
22
|
+
self.observed_results: dict[
|
|
23
|
+
tuple[str, int | tuple[int, int] | tuple[int, int, int], ObservationPointType], LiveDefinitions
|
|
24
24
|
] = {}
|
|
25
|
-
self.all_definitions:
|
|
25
|
+
self.all_definitions: set["Definition"] = set()
|
|
26
26
|
self.all_uses = Uses()
|
|
27
27
|
self.liveness = Liveness() if track_liveness else None
|
|
28
28
|
|
|
@@ -44,7 +44,7 @@ class ReachingDefinitionsModel:
|
|
|
44
44
|
if self.liveness is not None:
|
|
45
45
|
self.liveness.at_new_stmt(codeloc)
|
|
46
46
|
|
|
47
|
-
def at_new_block(self, code_loc: "CodeLocation", pred_codelocs:
|
|
47
|
+
def at_new_block(self, code_loc: "CodeLocation", pred_codelocs: list["CodeLocation"]) -> None:
|
|
48
48
|
if self.liveness is not None:
|
|
49
49
|
self.liveness.at_new_block(code_loc, pred_codelocs)
|
|
50
50
|
|
|
@@ -52,10 +52,10 @@ class ReachingDefinitionsModel:
|
|
|
52
52
|
if self.liveness is not None:
|
|
53
53
|
self.liveness.make_liveness_snapshot()
|
|
54
54
|
|
|
55
|
-
def find_defs_at(self, code_loc: "CodeLocation", op: int = OP_BEFORE) ->
|
|
55
|
+
def find_defs_at(self, code_loc: "CodeLocation", op: int = OP_BEFORE) -> set["Definition"]:
|
|
56
56
|
return self.liveness.find_defs_at(code_loc, op=op)
|
|
57
57
|
|
|
58
|
-
def get_defs(self, atom: Atom, code_loc: "CodeLocation", op: int) ->
|
|
58
|
+
def get_defs(self, atom: Atom, code_loc: "CodeLocation", op: int) -> set["Definition"]:
|
|
59
59
|
all_defs = self.liveness.find_defs_at(code_loc, op=op)
|
|
60
60
|
defs = None
|
|
61
61
|
if isinstance(atom, Register):
|
|
@@ -117,7 +117,7 @@ class ReachingDefinitionsModel:
|
|
|
117
117
|
|
|
118
118
|
def get_observation_by_insn(
|
|
119
119
|
self, ins_addr: Union[int, "CodeLocation"], kind: ObservationPointType
|
|
120
|
-
) ->
|
|
120
|
+
) -> LiveDefinitions | None:
|
|
121
121
|
if isinstance(ins_addr, int):
|
|
122
122
|
return self.observed_results.get(("insn", ins_addr, kind), None)
|
|
123
123
|
elif ins_addr.ins_addr is None:
|
|
@@ -125,8 +125,8 @@ class ReachingDefinitionsModel:
|
|
|
125
125
|
return self.observed_results.get(("insn", ins_addr.ins_addr, kind))
|
|
126
126
|
|
|
127
127
|
def get_observation_by_node(
|
|
128
|
-
self, node_addr: Union[int, "CodeLocation"], kind: ObservationPointType, node_idx:
|
|
129
|
-
) ->
|
|
128
|
+
self, node_addr: Union[int, "CodeLocation"], kind: ObservationPointType, node_idx: int | None = None
|
|
129
|
+
) -> LiveDefinitions | None:
|
|
130
130
|
if isinstance(node_addr, int):
|
|
131
131
|
key = ("node", node_addr, kind) if node_idx is None else ("node", (node_addr, node_idx), kind)
|
|
132
132
|
return self.observed_results.get(key, None)
|
|
@@ -141,11 +141,11 @@ class ReachingDefinitionsModel:
|
|
|
141
141
|
@overload
|
|
142
142
|
def get_observation_by_stmt(
|
|
143
143
|
self, codeloc: "CodeLocation", kind: ObservationPointType
|
|
144
|
-
) ->
|
|
144
|
+
) -> LiveDefinitions | None: ...
|
|
145
145
|
|
|
146
146
|
@overload
|
|
147
147
|
def get_observation_by_stmt(
|
|
148
|
-
self, node_addr: int, stmt_idx: int, kind: ObservationPointType, *, block_idx:
|
|
148
|
+
self, node_addr: int, stmt_idx: int, kind: ObservationPointType, *, block_idx: int | None = None
|
|
149
149
|
): ...
|
|
150
150
|
|
|
151
151
|
def get_observation_by_stmt(self, arg1, arg2, arg3=None, *, block_idx=None):
|
|
@@ -166,8 +166,8 @@ class ReachingDefinitionsModel:
|
|
|
166
166
|
self,
|
|
167
167
|
node_addr: int,
|
|
168
168
|
stmt_idx: int,
|
|
169
|
-
src_node_idx:
|
|
170
|
-
) ->
|
|
169
|
+
src_node_idx: int | None = None,
|
|
170
|
+
) -> LiveDefinitions | None:
|
|
171
171
|
key = (
|
|
172
172
|
("exit", (node_addr, stmt_idx), ObservationPointType.OP_AFTER)
|
|
173
173
|
if src_node_idx is None
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
# pylint:disable=unsubscriptable-object
|
|
2
|
-
from typing import
|
|
2
|
+
from typing import Any, TYPE_CHECKING
|
|
3
3
|
|
|
4
4
|
from ...utils.cowdict import DefaultChainMapCOW
|
|
5
5
|
from ...code_location import CodeLocation
|
|
@@ -17,21 +17,21 @@ class Uses:
|
|
|
17
17
|
|
|
18
18
|
def __init__(
|
|
19
19
|
self,
|
|
20
|
-
uses_by_definition:
|
|
21
|
-
uses_by_location:
|
|
20
|
+
uses_by_definition: DefaultChainMapCOW | None = None,
|
|
21
|
+
uses_by_location: DefaultChainMapCOW | None = None,
|
|
22
22
|
):
|
|
23
|
-
self._uses_by_definition: DefaultChainMapCOW["Definition",
|
|
23
|
+
self._uses_by_definition: DefaultChainMapCOW["Definition", set[tuple[CodeLocation, Any | None]]] = (
|
|
24
24
|
DefaultChainMapCOW(default_factory=set, collapse_threshold=25)
|
|
25
25
|
if uses_by_definition is None
|
|
26
26
|
else uses_by_definition
|
|
27
27
|
)
|
|
28
|
-
self._uses_by_location: DefaultChainMapCOW[CodeLocation,
|
|
28
|
+
self._uses_by_location: DefaultChainMapCOW[CodeLocation, set[tuple["Definition", Any | None]]] = (
|
|
29
29
|
DefaultChainMapCOW(default_factory=set, collapse_threshold=25)
|
|
30
30
|
if uses_by_location is None
|
|
31
31
|
else uses_by_location
|
|
32
32
|
)
|
|
33
33
|
|
|
34
|
-
def add_use(self, definition: "Definition", codeloc: CodeLocation, expr:
|
|
34
|
+
def add_use(self, definition: "Definition", codeloc: CodeLocation, expr: Any | None = None):
|
|
35
35
|
"""
|
|
36
36
|
Add a use for a given definition.
|
|
37
37
|
|
|
@@ -44,7 +44,7 @@ class Uses:
|
|
|
44
44
|
self._uses_by_location = self._uses_by_location.clean()
|
|
45
45
|
self._uses_by_location[codeloc].add((definition, expr))
|
|
46
46
|
|
|
47
|
-
def get_uses(self, definition: "Definition") ->
|
|
47
|
+
def get_uses(self, definition: "Definition") -> set[CodeLocation]:
|
|
48
48
|
"""
|
|
49
49
|
Retrieve the uses of a given definition.
|
|
50
50
|
|
|
@@ -52,7 +52,7 @@ class Uses:
|
|
|
52
52
|
"""
|
|
53
53
|
return {codeloc for codeloc, _ in self._uses_by_definition.get(definition, set())}
|
|
54
54
|
|
|
55
|
-
def get_uses_with_expr(self, definition: "Definition") ->
|
|
55
|
+
def get_uses_with_expr(self, definition: "Definition") -> set[tuple[CodeLocation, Any | None]]:
|
|
56
56
|
"""
|
|
57
57
|
Retrieve the uses and the corresponding expressions of a given definition.
|
|
58
58
|
|
|
@@ -60,7 +60,7 @@ class Uses:
|
|
|
60
60
|
"""
|
|
61
61
|
return self._uses_by_definition.get(definition, set())
|
|
62
62
|
|
|
63
|
-
def remove_use(self, definition: "Definition", codeloc: "CodeLocation", expr:
|
|
63
|
+
def remove_use(self, definition: "Definition", codeloc: "CodeLocation", expr: Any | None = None) -> None:
|
|
64
64
|
"""
|
|
65
65
|
Remove one use of a given definition.
|
|
66
66
|
|
|
@@ -105,7 +105,7 @@ class Uses:
|
|
|
105
105
|
|
|
106
106
|
def get_uses_by_location(
|
|
107
107
|
self, codeloc: CodeLocation, exprs: bool = False
|
|
108
|
-
) ->
|
|
108
|
+
) -> set["Definition"] | set[tuple["Definition", Any | None]]:
|
|
109
109
|
"""
|
|
110
110
|
Retrieve all definitions that are used at a given location.
|
|
111
111
|
|
|
@@ -118,7 +118,7 @@ class Uses:
|
|
|
118
118
|
|
|
119
119
|
def get_uses_by_insaddr(
|
|
120
120
|
self, ins_addr: int, exprs: bool = False
|
|
121
|
-
) ->
|
|
121
|
+
) -> set["Definition"] | set[tuple["Definition", Any | None]]:
|
|
122
122
|
"""
|
|
123
123
|
Retrieve all definitions that are used at a given location specified by the instruction address.
|
|
124
124
|
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
from typing import Optional, List, Dict
|
|
2
|
-
|
|
3
1
|
from cle.address_translator import AddressTranslator
|
|
4
2
|
from sortedcontainers import SortedDict
|
|
5
3
|
|
|
@@ -8,7 +6,7 @@ from .plugin import KnowledgeBasePlugin
|
|
|
8
6
|
|
|
9
7
|
# TODO: Serializable
|
|
10
8
|
class Patch:
|
|
11
|
-
def __init__(self, addr, new_bytes, comment:
|
|
9
|
+
def __init__(self, addr, new_bytes, comment: str | None = None):
|
|
12
10
|
self.addr = addr
|
|
13
11
|
self.new_bytes = new_bytes
|
|
14
12
|
self.comment = comment
|
|
@@ -29,10 +27,10 @@ class PatchManager(KnowledgeBasePlugin):
|
|
|
29
27
|
def __init__(self, kb):
|
|
30
28
|
super().__init__(kb=kb)
|
|
31
29
|
|
|
32
|
-
self._patches:
|
|
30
|
+
self._patches: dict[int, Patch] = SortedDict()
|
|
33
31
|
self._patched_entry_state = None
|
|
34
32
|
|
|
35
|
-
def add_patch(self, addr, new_bytes, comment:
|
|
33
|
+
def add_patch(self, addr, new_bytes, comment: str | None = None):
|
|
36
34
|
self._patches[addr] = Patch(addr, new_bytes, comment=comment)
|
|
37
35
|
self._patched_entry_state = None
|
|
38
36
|
|
|
@@ -93,9 +91,7 @@ class PatchManager(KnowledgeBasePlugin):
|
|
|
93
91
|
def overlap(a0, a1, b0, b1):
|
|
94
92
|
return a0 <= b0 < a1 or a0 <= b1 < a1 or b0 <= a0 < b1
|
|
95
93
|
|
|
96
|
-
def apply_patches_to_binary(
|
|
97
|
-
self, binary_bytes: Optional[bytes] = None, patches: Optional[List[Patch]] = None
|
|
98
|
-
) -> bytes:
|
|
94
|
+
def apply_patches_to_binary(self, binary_bytes: bytes | None = None, patches: list[Patch] | None = None) -> bytes:
|
|
99
95
|
if patches is None:
|
|
100
96
|
patches = sorted(list(self._patches.values()), key=lambda x: x.addr)
|
|
101
97
|
|