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,3 @@
|
|
|
1
|
-
from typing import Optional
|
|
2
1
|
import logging
|
|
3
2
|
|
|
4
3
|
import ailment
|
|
@@ -28,7 +27,7 @@ class ReturnMaker(AILGraphWalker):
|
|
|
28
27
|
return self.ail_manager.next_atom()
|
|
29
28
|
|
|
30
29
|
def _handle_Return(
|
|
31
|
-
self, stmt_idx: int, stmt: ailment.Stmt.Return, block:
|
|
30
|
+
self, stmt_idx: int, stmt: ailment.Stmt.Return, block: ailment.Block | None
|
|
32
31
|
): # pylint:disable=unused-argument
|
|
33
32
|
if (
|
|
34
33
|
block is not None
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
from typing import Dict, Optional, Set, Union
|
|
2
1
|
from sortedcontainers import SortedDict
|
|
3
2
|
|
|
4
3
|
from ....sim_variable import SimVariable
|
|
@@ -29,7 +28,7 @@ class PositionMapping:
|
|
|
29
28
|
DUPLICATION_CHECK = True
|
|
30
29
|
|
|
31
30
|
def __init__(self):
|
|
32
|
-
self._posmap:
|
|
31
|
+
self._posmap: SortedDict | dict[int, PositionMappingElement] = SortedDict()
|
|
33
32
|
|
|
34
33
|
def items(self):
|
|
35
34
|
return self._posmap.items()
|
|
@@ -56,7 +55,7 @@ class PositionMapping:
|
|
|
56
55
|
return None
|
|
57
56
|
return element.obj
|
|
58
57
|
|
|
59
|
-
def get_element(self, pos: int) ->
|
|
58
|
+
def get_element(self, pos: int) -> PositionMappingElement | None:
|
|
60
59
|
try:
|
|
61
60
|
pre = next(self._posmap.irange(maximum=pos, reverse=True))
|
|
62
61
|
except StopIteration:
|
|
@@ -86,7 +85,7 @@ class InstructionMapping:
|
|
|
86
85
|
__slots__ = ("_insmap",)
|
|
87
86
|
|
|
88
87
|
def __init__(self):
|
|
89
|
-
self._insmap:
|
|
88
|
+
self._insmap: SortedDict | dict[int, InstructionMappingElement] = SortedDict()
|
|
90
89
|
|
|
91
90
|
def items(self):
|
|
92
91
|
return self._insmap.items()
|
|
@@ -98,7 +97,7 @@ class InstructionMapping:
|
|
|
98
97
|
else:
|
|
99
98
|
self._insmap[ins_addr] = InstructionMappingElement(ins_addr, posmap_pos)
|
|
100
99
|
|
|
101
|
-
def get_nearest_pos(self, ins_addr: int) ->
|
|
100
|
+
def get_nearest_pos(self, ins_addr: int) -> int | None:
|
|
102
101
|
try:
|
|
103
102
|
pre_max = next(self._insmap.irange(maximum=ins_addr, reverse=True))
|
|
104
103
|
pre_min = next(self._insmap.irange(minimum=ins_addr, reverse=True))
|
|
@@ -121,7 +120,7 @@ class BaseStructuredCodeGenerator:
|
|
|
121
120
|
self.map_pos_to_node = None
|
|
122
121
|
self.map_pos_to_addr = None
|
|
123
122
|
self.map_addr_to_pos = None
|
|
124
|
-
self.map_ast_to_pos:
|
|
123
|
+
self.map_ast_to_pos: dict[SimVariable, set[PositionMappingElement]] | None = None
|
|
125
124
|
|
|
126
125
|
def reapply_options(self, options):
|
|
127
126
|
pass
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
# pylint:disable=missing-class-docstring,too-many-boolean-expressions,unused-argument,no-self-use
|
|
2
|
-
from typing import Optional,
|
|
2
|
+
from typing import Optional, Any, TYPE_CHECKING
|
|
3
|
+
from collections.abc import Callable
|
|
3
4
|
from collections import defaultdict
|
|
4
5
|
import logging
|
|
5
6
|
import struct
|
|
@@ -72,13 +73,13 @@ def unpack_typeref(ty):
|
|
|
72
73
|
return ty
|
|
73
74
|
|
|
74
75
|
|
|
75
|
-
def unpack_pointer(ty) ->
|
|
76
|
+
def unpack_pointer(ty) -> SimType | None:
|
|
76
77
|
if isinstance(ty, SimTypePointer):
|
|
77
78
|
return ty.pts_to
|
|
78
79
|
return None
|
|
79
80
|
|
|
80
81
|
|
|
81
|
-
def unpack_array(ty) ->
|
|
82
|
+
def unpack_array(ty) -> SimType | None:
|
|
82
83
|
if isinstance(ty, SimTypeArray):
|
|
83
84
|
return ty.elem_type
|
|
84
85
|
if isinstance(ty, SimTypeFixedSizeArray):
|
|
@@ -119,7 +120,7 @@ def qualifies_for_implicit_cast(ty1, ty2):
|
|
|
119
120
|
return ty1.size <= ty2.size
|
|
120
121
|
|
|
121
122
|
|
|
122
|
-
def extract_terms(expr: "CExpression") ->
|
|
123
|
+
def extract_terms(expr: "CExpression") -> tuple[int, list[tuple[int, "CExpression"]]]:
|
|
123
124
|
# handle unnecessary type casts
|
|
124
125
|
if isinstance(expr, CTypeCast):
|
|
125
126
|
expr = MakeTypecastsImplicit.collapse(expr.dst_type, expr.expr)
|
|
@@ -166,7 +167,7 @@ def is_machine_word_size_type(type_: SimType, arch: "archinfo.Arch") -> bool:
|
|
|
166
167
|
return isinstance(type_, SimTypeReg) and type_.size == arch.bits
|
|
167
168
|
|
|
168
169
|
|
|
169
|
-
def guess_value_type(value: int, project: "angr.Project") ->
|
|
170
|
+
def guess_value_type(value: int, project: "angr.Project") -> SimType | None:
|
|
170
171
|
if project.kb.functions.contains_addr(value):
|
|
171
172
|
# might be a function pointer
|
|
172
173
|
return SimTypePointer(SimTypeBottom(label="void")).with_arch(project.arch)
|
|
@@ -399,7 +400,7 @@ class CFunction(CConstruct): # pylint:disable=abstract-method
|
|
|
399
400
|
addr,
|
|
400
401
|
name,
|
|
401
402
|
functy: SimTypeFunction,
|
|
402
|
-
arg_list:
|
|
403
|
+
arg_list: list["CVariable"],
|
|
403
404
|
statements,
|
|
404
405
|
variables_in_use,
|
|
405
406
|
variable_manager,
|
|
@@ -418,14 +419,14 @@ class CFunction(CConstruct): # pylint:disable=abstract-method
|
|
|
418
419
|
self.variables_in_use = variables_in_use
|
|
419
420
|
self.variable_manager: "VariableManagerInternal" = variable_manager
|
|
420
421
|
self.demangled_name = demangled_name
|
|
421
|
-
self.unified_local_vars:
|
|
422
|
+
self.unified_local_vars: dict[SimVariable, set[tuple[CVariable, SimType]]] = self.get_unified_local_vars()
|
|
422
423
|
self.show_demangled_name = show_demangled_name
|
|
423
424
|
self.omit_header = omit_header
|
|
424
425
|
|
|
425
|
-
def get_unified_local_vars(self) ->
|
|
426
|
-
unified_to_var_and_types:
|
|
426
|
+
def get_unified_local_vars(self) -> dict[SimVariable, set[tuple["CVariable", SimType]]]:
|
|
427
|
+
unified_to_var_and_types: dict[SimVariable, set[tuple[CVariable, SimType]]] = defaultdict(set)
|
|
427
428
|
|
|
428
|
-
arg_set:
|
|
429
|
+
arg_set: set[SimVariable] = set()
|
|
429
430
|
for arg in self.arg_list:
|
|
430
431
|
# TODO: Handle CIndexedVariable
|
|
431
432
|
if isinstance(arg, CVariable):
|
|
@@ -882,7 +883,7 @@ class CIfElse(CStatement):
|
|
|
882
883
|
|
|
883
884
|
def __init__(
|
|
884
885
|
self,
|
|
885
|
-
condition_and_nodes:
|
|
886
|
+
condition_and_nodes: list[tuple[CExpression, CStatement | None]],
|
|
886
887
|
else_node=None,
|
|
887
888
|
simplify_else_scope=False,
|
|
888
889
|
cstyle_ifs=True,
|
|
@@ -1091,7 +1092,7 @@ class CSwitchCase(CStatement):
|
|
|
1091
1092
|
super().__init__(**kwargs)
|
|
1092
1093
|
|
|
1093
1094
|
self.switch = switch
|
|
1094
|
-
self.cases:
|
|
1095
|
+
self.cases: list[tuple[int | tuple[int], CStatements]] = cases
|
|
1095
1096
|
self.default = default
|
|
1096
1097
|
self.tags = tags
|
|
1097
1098
|
|
|
@@ -1241,7 +1242,7 @@ class CFunctionCall(CStatement, CExpression):
|
|
|
1241
1242
|
self.show_disambiguated_name = show_disambiguated_name
|
|
1242
1243
|
|
|
1243
1244
|
@property
|
|
1244
|
-
def prototype(self) ->
|
|
1245
|
+
def prototype(self) -> SimTypeFunction | None: # TODO there should be a prototype for each callsite!
|
|
1245
1246
|
if self.callee_func is not None and self.callee_func.prototype is not None:
|
|
1246
1247
|
proto = self.callee_func.prototype
|
|
1247
1248
|
if self.callee_func.prototype_libname is not None:
|
|
@@ -1361,7 +1362,7 @@ class CGoto(CStatement):
|
|
|
1361
1362
|
# unpack target
|
|
1362
1363
|
target = target.value
|
|
1363
1364
|
|
|
1364
|
-
self.target:
|
|
1365
|
+
self.target: int | CExpression = target
|
|
1365
1366
|
self.target_idx = target_idx
|
|
1366
1367
|
self.tags = tags
|
|
1367
1368
|
|
|
@@ -1440,7 +1441,7 @@ class CLabel(CStatement):
|
|
|
1440
1441
|
"tags",
|
|
1441
1442
|
)
|
|
1442
1443
|
|
|
1443
|
-
def __init__(self, name: str, ins_addr: int, block_idx:
|
|
1444
|
+
def __init__(self, name: str, ins_addr: int, block_idx: int | None, tags=None, **kwargs):
|
|
1444
1445
|
super().__init__(**kwargs)
|
|
1445
1446
|
self.name = name
|
|
1446
1447
|
self.ins_addr = ins_addr
|
|
@@ -1521,7 +1522,7 @@ class CVariable(CExpression):
|
|
|
1521
1522
|
super().__init__(**kwargs)
|
|
1522
1523
|
|
|
1523
1524
|
self.variable: SimVariable = variable
|
|
1524
|
-
self.unified_variable:
|
|
1525
|
+
self.unified_variable: SimVariable | None = unified_variable
|
|
1525
1526
|
self.variable_type: SimType = variable_type.with_arch(self.codegen.project.arch)
|
|
1526
1527
|
self.tags = tags
|
|
1527
1528
|
|
|
@@ -1726,7 +1727,7 @@ class CBinaryOp(CExpression):
|
|
|
1726
1727
|
|
|
1727
1728
|
__slots__ = ("op", "lhs", "rhs", "tags", "common_type", "_cstyle_null_cmp")
|
|
1728
1729
|
|
|
1729
|
-
def __init__(self, op, lhs, rhs, tags:
|
|
1730
|
+
def __init__(self, op, lhs, rhs, tags: dict | None = None, **kwargs):
|
|
1730
1731
|
super().__init__(**kwargs)
|
|
1731
1732
|
|
|
1732
1733
|
self.op = op
|
|
@@ -2005,7 +2006,7 @@ class CTypeCast(CExpression):
|
|
|
2005
2006
|
"tags",
|
|
2006
2007
|
)
|
|
2007
2008
|
|
|
2008
|
-
def __init__(self, src_type:
|
|
2009
|
+
def __init__(self, src_type: SimType | None, dst_type: SimType, expr: CExpression, tags=None, **kwargs):
|
|
2009
2010
|
super().__init__(**kwargs)
|
|
2010
2011
|
|
|
2011
2012
|
self.src_type = (src_type or expr.type).with_arch(self.codegen.project.arch)
|
|
@@ -2046,7 +2047,7 @@ class CConstant(CExpression):
|
|
|
2046
2047
|
"tags",
|
|
2047
2048
|
)
|
|
2048
2049
|
|
|
2049
|
-
def __init__(self, value, type_: SimType, reference_values=None, tags:
|
|
2050
|
+
def __init__(self, value, type_: SimType, reference_values=None, tags: dict | None = None, **kwargs):
|
|
2050
2051
|
super().__init__(**kwargs)
|
|
2051
2052
|
|
|
2052
2053
|
self.value = value
|
|
@@ -2391,7 +2392,7 @@ class CStructuredCodeGenerator(BaseStructuredCodeGenerator, Analysis):
|
|
|
2391
2392
|
indent=0,
|
|
2392
2393
|
cfg=None,
|
|
2393
2394
|
variable_kb=None,
|
|
2394
|
-
func_args:
|
|
2395
|
+
func_args: list[SimVariable] | None = None,
|
|
2395
2396
|
binop_depth_cutoff: int = 16,
|
|
2396
2397
|
show_casts=True,
|
|
2397
2398
|
braces_on_own_lines=True,
|
|
@@ -2457,11 +2458,11 @@ class CStructuredCodeGenerator(BaseStructuredCodeGenerator, Analysis):
|
|
|
2457
2458
|
self._variable_kb = variable_kb if variable_kb is not None else self.kb
|
|
2458
2459
|
self.binop_depth_cutoff = binop_depth_cutoff
|
|
2459
2460
|
|
|
2460
|
-
self._variables_in_use:
|
|
2461
|
-
self._inlined_strings:
|
|
2462
|
-
self._function_pointers:
|
|
2463
|
-
self.ailexpr2cnode:
|
|
2464
|
-
self.cnode2ailexpr:
|
|
2461
|
+
self._variables_in_use: dict | None = None
|
|
2462
|
+
self._inlined_strings: set[SimMemoryVariable] = set()
|
|
2463
|
+
self._function_pointers: set[SimMemoryVariable] = set()
|
|
2464
|
+
self.ailexpr2cnode: dict[tuple[Expr.Expression, bool], CExpression] | None = None
|
|
2465
|
+
self.cnode2ailexpr: dict[CExpression, Expr.Expression] | None = None
|
|
2465
2466
|
self._indent = indent
|
|
2466
2467
|
self.show_casts = show_casts
|
|
2467
2468
|
self.comment_gotos = comment_gotos
|
|
@@ -2469,9 +2470,9 @@ class CStructuredCodeGenerator(BaseStructuredCodeGenerator, Analysis):
|
|
|
2469
2470
|
self.use_compound_assignments = use_compound_assignments
|
|
2470
2471
|
self.show_local_types = show_local_types
|
|
2471
2472
|
self.cstyle_null_cmp = cstyle_null_cmp
|
|
2472
|
-
self.expr_comments:
|
|
2473
|
-
self.stmt_comments:
|
|
2474
|
-
self.const_formats:
|
|
2473
|
+
self.expr_comments: dict[int, str] = expr_comments if expr_comments is not None else {}
|
|
2474
|
+
self.stmt_comments: dict[int, str] = stmt_comments if stmt_comments is not None else {}
|
|
2475
|
+
self.const_formats: dict[Any, dict[str, Any]] = const_formats if const_formats is not None else {}
|
|
2475
2476
|
self.externs = externs or set()
|
|
2476
2477
|
self.show_externs = show_externs
|
|
2477
2478
|
self.show_demangled_name = show_demangled_name
|
|
@@ -2484,10 +2485,10 @@ class CStructuredCodeGenerator(BaseStructuredCodeGenerator, Analysis):
|
|
|
2484
2485
|
self.map_pos_to_node = None
|
|
2485
2486
|
self.map_pos_to_addr = None
|
|
2486
2487
|
self.map_addr_to_pos = None
|
|
2487
|
-
self.map_ast_to_pos:
|
|
2488
|
-
self.map_addr_to_label:
|
|
2489
|
-
self.cfunc:
|
|
2490
|
-
self.cexterns:
|
|
2488
|
+
self.map_ast_to_pos: dict[SimVariable, set[PositionMappingElement]] | None = None
|
|
2489
|
+
self.map_addr_to_label: dict[tuple[int, int | None], CLabel] = {}
|
|
2490
|
+
self.cfunc: CFunction | None = None
|
|
2491
|
+
self.cexterns: set[CVariable] | None = None
|
|
2491
2492
|
|
|
2492
2493
|
self._analyze()
|
|
2493
2494
|
|
|
@@ -2581,7 +2582,7 @@ class CStructuredCodeGenerator(BaseStructuredCodeGenerator, Analysis):
|
|
|
2581
2582
|
self.map_ast_to_pos,
|
|
2582
2583
|
) = self.render_text(self.cfunc)
|
|
2583
2584
|
|
|
2584
|
-
RENDER_TYPE =
|
|
2585
|
+
RENDER_TYPE = tuple[str, PositionMapping, PositionMapping, InstructionMapping, dict[Any, set[Any]]]
|
|
2585
2586
|
|
|
2586
2587
|
def render_text(self, cfunc: CFunction) -> RENDER_TYPE:
|
|
2587
2588
|
pos_to_node = PositionMapping()
|
|
@@ -2622,7 +2623,7 @@ class CStructuredCodeGenerator(BaseStructuredCodeGenerator, Analysis):
|
|
|
2622
2623
|
else:
|
|
2623
2624
|
return self._variable_kb.variables[self._func.addr].get_variable_type(var)
|
|
2624
2625
|
|
|
2625
|
-
def _get_derefed_type(self, ty: SimType) ->
|
|
2626
|
+
def _get_derefed_type(self, ty: SimType) -> SimType | None:
|
|
2626
2627
|
if ty is None:
|
|
2627
2628
|
return None
|
|
2628
2629
|
ty = unpack_typeref(ty)
|
|
@@ -2669,7 +2670,7 @@ class CStructuredCodeGenerator(BaseStructuredCodeGenerator, Analysis):
|
|
|
2669
2670
|
return _mapping.get(n)(signed=signed).with_arch(self.project.arch)
|
|
2670
2671
|
return SimTypeNum(n * self.project.arch.byte_width, signed=signed).with_arch(self.project.arch)
|
|
2671
2672
|
|
|
2672
|
-
def _variable(self, variable: SimVariable, fallback_type_size:
|
|
2673
|
+
def _variable(self, variable: SimVariable, fallback_type_size: int | None) -> CVariable:
|
|
2673
2674
|
# TODO: we need to fucking make sure that variable recovery and type inference actually generates a size
|
|
2674
2675
|
# TODO: for each variable it links into the fucking ail. then we can remove fallback_type_size.
|
|
2675
2676
|
unified = self._variable_kb.variables[self._func.addr].unified_variable(variable)
|
|
@@ -2707,7 +2708,7 @@ class CStructuredCodeGenerator(BaseStructuredCodeGenerator, Analysis):
|
|
|
2707
2708
|
return result
|
|
2708
2709
|
|
|
2709
2710
|
def _access_constant_offset_reference(
|
|
2710
|
-
self, expr: CExpression, offset: int, data_type:
|
|
2711
|
+
self, expr: CExpression, offset: int, data_type: SimType | None
|
|
2711
2712
|
) -> CExpression:
|
|
2712
2713
|
result = self._access_constant_offset(expr, offset, data_type or SimTypeBottom(), True)
|
|
2713
2714
|
if isinstance(result, CTypeCast) and data_type is None:
|
|
@@ -3048,7 +3049,7 @@ class CStructuredCodeGenerator(BaseStructuredCodeGenerator, Analysis):
|
|
|
3048
3049
|
if (node, is_expr) in self.ailexpr2cnode:
|
|
3049
3050
|
return self.ailexpr2cnode[(node, is_expr)]
|
|
3050
3051
|
|
|
3051
|
-
handler:
|
|
3052
|
+
handler: Callable | None = self._handlers.get(node.__class__, None)
|
|
3052
3053
|
if handler is not None:
|
|
3053
3054
|
if isinstance(node, Stmt.Call):
|
|
3054
3055
|
# special case for Call
|
|
@@ -3494,7 +3495,7 @@ class CStructuredCodeGenerator(BaseStructuredCodeGenerator, Analysis):
|
|
|
3494
3495
|
def _handle_Expr_Convert(self, expr: Expr.Convert, **kwargs):
|
|
3495
3496
|
# width of converted type is easy
|
|
3496
3497
|
if 64 >= expr.to_bits > 32:
|
|
3497
|
-
dst_type:
|
|
3498
|
+
dst_type: SimTypeInt | SimTypeChar = SimTypeLongLong()
|
|
3498
3499
|
elif 32 >= expr.to_bits > 16:
|
|
3499
3500
|
dst_type = SimTypeInt()
|
|
3500
3501
|
elif 16 >= expr.to_bits > 8:
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
# pylint:disable=multiple-statements,line-too-long,consider-using-enumerate
|
|
2
|
-
from typing import
|
|
2
|
+
from typing import Optional, Any, TYPE_CHECKING
|
|
3
|
+
from collections import OrderedDict as ODict
|
|
3
4
|
import logging
|
|
4
5
|
from collections import defaultdict, OrderedDict
|
|
5
6
|
|
|
@@ -68,7 +69,7 @@ class DreamStructurer(StructurerBase):
|
|
|
68
69
|
parent_map=None,
|
|
69
70
|
condition_processor=None,
|
|
70
71
|
func: Optional["Function"] = None,
|
|
71
|
-
case_entry_to_switch_head:
|
|
72
|
+
case_entry_to_switch_head: dict[int, int] | None = None,
|
|
72
73
|
parent_region=None,
|
|
73
74
|
**kwargs,
|
|
74
75
|
):
|
|
@@ -488,7 +489,7 @@ class DreamStructurer(StructurerBase):
|
|
|
488
489
|
|
|
489
490
|
jump_tables = self.kb.cfgs["CFGFast"].jump_tables
|
|
490
491
|
|
|
491
|
-
addr2nodes:
|
|
492
|
+
addr2nodes: dict[int, set[CodeNode]] = defaultdict(set)
|
|
492
493
|
for node in seq.nodes:
|
|
493
494
|
addr2nodes[node.addr].add(node)
|
|
494
495
|
|
|
@@ -513,7 +514,7 @@ class DreamStructurer(StructurerBase):
|
|
|
513
514
|
break
|
|
514
515
|
|
|
515
516
|
def _make_switch_cases_address_loaded_from_memory(
|
|
516
|
-
self, seq, i, node, addr2nodes:
|
|
517
|
+
self, seq, i, node, addr2nodes: dict[int, set[CodeNode]], jump_tables: dict[int, IndirectJump]
|
|
517
518
|
) -> bool:
|
|
518
519
|
"""
|
|
519
520
|
A typical jump table involves multiple nodes, which look like the following:
|
|
@@ -596,7 +597,7 @@ class DreamStructurer(StructurerBase):
|
|
|
596
597
|
return True
|
|
597
598
|
|
|
598
599
|
def _make_switch_cases_address_computed(
|
|
599
|
-
self, seq, i, node, addr2nodes:
|
|
600
|
+
self, seq, i, node, addr2nodes: dict[int, set[CodeNode]], jump_tables: dict[int, IndirectJump]
|
|
600
601
|
) -> bool:
|
|
601
602
|
if node.addr not in jump_tables:
|
|
602
603
|
return False
|
|
@@ -696,8 +697,8 @@ class DreamStructurer(StructurerBase):
|
|
|
696
697
|
rewriter.walk(seq) # update SequenceNodes in-place
|
|
697
698
|
|
|
698
699
|
def _switch_unpack_sequence_node(
|
|
699
|
-
self, seq: SequenceNode, node_a, node_b_addr: int, jumptable, addr2nodes:
|
|
700
|
-
) ->
|
|
700
|
+
self, seq: SequenceNode, node_a, node_b_addr: int, jumptable, addr2nodes: dict[int, set[CodeNode]]
|
|
701
|
+
) -> tuple[bool, CodeNode | None]:
|
|
701
702
|
"""
|
|
702
703
|
We might have already structured the actual body of the switch-case structure into a single Sequence node (node
|
|
703
704
|
A). If that is the case, we un-structure the sequence node in this method.
|
|
@@ -752,7 +753,7 @@ class DreamStructurer(StructurerBase):
|
|
|
752
753
|
# should have been handling it when dealing with multi-exit regions. ignore it here.
|
|
753
754
|
return True, node_a
|
|
754
755
|
|
|
755
|
-
def _switch_unpack_condition_node(self, cond_node: ConditionNode, jumptable) ->
|
|
756
|
+
def _switch_unpack_condition_node(self, cond_node: ConditionNode, jumptable) -> CodeNode | None:
|
|
756
757
|
"""
|
|
757
758
|
Unpack condition nodes by only removing one condition in the form of
|
|
758
759
|
<Bool jump_table_402020 == 0x402ac4>.
|
|
@@ -818,8 +819,8 @@ class DreamStructurer(StructurerBase):
|
|
|
818
819
|
def _switch_check_existence_of_jumptable_entries(
|
|
819
820
|
self,
|
|
820
821
|
jumptable_entries,
|
|
821
|
-
node_a_block_addrs:
|
|
822
|
-
known_node_addrs:
|
|
822
|
+
node_a_block_addrs: set[int],
|
|
823
|
+
known_node_addrs: set[int],
|
|
823
824
|
node_a_addr: int,
|
|
824
825
|
node_b_addr: int,
|
|
825
826
|
) -> bool:
|
|
@@ -862,7 +863,7 @@ class DreamStructurer(StructurerBase):
|
|
|
862
863
|
# not sure what is going on...
|
|
863
864
|
return False
|
|
864
865
|
|
|
865
|
-
def _switch_find_jumptable_entry_node(self, entry_addr: int, addr2nodes:
|
|
866
|
+
def _switch_find_jumptable_entry_node(self, entry_addr: int, addr2nodes: dict[int, set[CodeNode]]) -> Any | None:
|
|
866
867
|
"""
|
|
867
868
|
Find the correct node for a given jump table entry address in addr2nodes.
|
|
868
869
|
|
|
@@ -904,11 +905,11 @@ class DreamStructurer(StructurerBase):
|
|
|
904
905
|
self,
|
|
905
906
|
seq: SequenceNode,
|
|
906
907
|
cmp_lb: int,
|
|
907
|
-
jumptable_entries:
|
|
908
|
+
jumptable_entries: list[int],
|
|
908
909
|
head_node_idx: int,
|
|
909
910
|
node_b_addr: int,
|
|
910
|
-
addr2nodes:
|
|
911
|
-
) ->
|
|
911
|
+
addr2nodes: dict[int, set[CodeNode]],
|
|
912
|
+
) -> tuple[ODict, Any, Any]:
|
|
912
913
|
"""
|
|
913
914
|
Discover all cases for the switch-case structure and build the switch-cases dict.
|
|
914
915
|
|
|
@@ -921,14 +922,14 @@ class DreamStructurer(StructurerBase):
|
|
|
921
922
|
:return: A tuple of (dict of cases, the default node if exists, nodes to remove).
|
|
922
923
|
"""
|
|
923
924
|
|
|
924
|
-
cases: ODict[
|
|
925
|
+
cases: ODict[int | tuple[int, ...], SequenceNode] = OrderedDict()
|
|
925
926
|
to_remove = set()
|
|
926
927
|
node_default = addr2nodes.get(node_b_addr, None)
|
|
927
928
|
if node_default is not None:
|
|
928
929
|
node_default = next(iter(node_default))
|
|
929
930
|
|
|
930
931
|
entry_addrs_set = set(jumptable_entries)
|
|
931
|
-
converted_nodes:
|
|
932
|
+
converted_nodes: dict[int, Any] = {}
|
|
932
933
|
entry_addr_to_ids = defaultdict(set)
|
|
933
934
|
|
|
934
935
|
for j, entry_addr in enumerate(jumptable_entries):
|