angr 9.2.131__py3-none-manylinux2014_aarch64.whl → 9.2.133__py3-none-manylinux2014_aarch64.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 +128 -128
- angr/analyses/__init__.py +38 -38
- angr/analyses/analysis.py +6 -2
- angr/analyses/backward_slice.py +3 -4
- angr/analyses/binary_optimizer.py +5 -12
- angr/analyses/bindiff.py +3 -6
- angr/analyses/calling_convention.py +3 -4
- angr/analyses/cfg/__init__.py +3 -3
- angr/analyses/cfg/cfg_base.py +1 -1
- angr/analyses/cfg/cfg_emulated.py +5 -5
- angr/analyses/cfg/cfg_fast.py +19 -17
- angr/analyses/cfg/indirect_jump_resolvers/__init__.py +5 -5
- angr/analyses/cfg/indirect_jump_resolvers/amd64_elf_got.py +1 -1
- angr/analyses/cfg/indirect_jump_resolvers/jumptable.py +148 -101
- angr/analyses/cfg/indirect_jump_resolvers/x86_elf_pic_plt.py +1 -1
- angr/analyses/data_dep/__init__.py +4 -4
- angr/analyses/datagraph_meta.py +1 -1
- angr/analyses/ddg.py +16 -17
- angr/analyses/decompiler/__init__.py +12 -12
- angr/analyses/decompiler/ail_simplifier.py +24 -12
- angr/analyses/decompiler/block_similarity.py +2 -4
- angr/analyses/decompiler/block_simplifier.py +10 -21
- angr/analyses/decompiler/callsite_maker.py +1 -1
- angr/analyses/decompiler/ccall_rewriters/rewriter_base.py +1 -1
- angr/analyses/decompiler/clinic.py +122 -41
- angr/analyses/decompiler/condition_processor.py +57 -39
- angr/analyses/decompiler/counters/__init__.py +3 -3
- angr/analyses/decompiler/decompilation_cache.py +7 -7
- angr/analyses/decompiler/dephication/__init__.py +1 -1
- angr/analyses/decompiler/dephication/graph_rewriting.py +1 -1
- angr/analyses/decompiler/dephication/graph_vvar_mapping.py +11 -3
- angr/analyses/decompiler/dephication/rewriting_engine.py +169 -45
- angr/analyses/decompiler/dephication/seqnode_dephication.py +5 -4
- angr/analyses/decompiler/expression_narrower.py +1 -1
- angr/analyses/decompiler/graph_region.py +8 -8
- angr/analyses/decompiler/optimization_passes/__init__.py +20 -20
- angr/analyses/decompiler/optimization_passes/const_derefs.py +1 -0
- angr/analyses/decompiler/optimization_passes/deadblock_remover.py +1 -2
- angr/analyses/decompiler/optimization_passes/div_simplifier.py +41 -16
- angr/analyses/decompiler/optimization_passes/duplication_reverter/duplication_reverter.py +8 -7
- angr/analyses/decompiler/optimization_passes/duplication_reverter/utils.py +1 -3
- angr/analyses/decompiler/optimization_passes/engine_base.py +262 -84
- angr/analyses/decompiler/optimization_passes/inlined_string_transformation_simplifier.py +175 -39
- angr/analyses/decompiler/optimization_passes/ite_region_converter.py +2 -5
- angr/analyses/decompiler/optimization_passes/lowered_switch_simplifier.py +5 -5
- angr/analyses/decompiler/optimization_passes/mod_simplifier.py +12 -3
- angr/analyses/decompiler/optimization_passes/optimization_pass.py +42 -19
- angr/analyses/decompiler/optimization_passes/stack_canary_simplifier.py +9 -5
- angr/analyses/decompiler/peephole_optimizations/__init__.py +1 -1
- angr/analyses/decompiler/peephole_optimizations/base.py +6 -6
- angr/analyses/decompiler/peephole_optimizations/remove_noop_conversions.py +2 -0
- angr/analyses/decompiler/peephole_optimizations/rewrite_bit_extractions.py +1 -1
- angr/analyses/decompiler/presets/__init__.py +1 -1
- angr/analyses/decompiler/region_simplifiers/expr_folding.py +3 -3
- angr/analyses/decompiler/region_simplifiers/switch_cluster_simplifier.py +8 -12
- angr/analyses/decompiler/ssailification/rewriting.py +1 -2
- angr/analyses/decompiler/ssailification/rewriting_engine.py +139 -56
- angr/analyses/decompiler/ssailification/ssailification.py +2 -1
- angr/analyses/decompiler/ssailification/traversal.py +4 -6
- angr/analyses/decompiler/ssailification/traversal_engine.py +125 -42
- angr/analyses/decompiler/structured_codegen/__init__.py +5 -5
- angr/analyses/decompiler/structured_codegen/base.py +3 -3
- angr/analyses/decompiler/structured_codegen/c.py +39 -40
- angr/analyses/decompiler/structuring/__init__.py +3 -3
- angr/analyses/decompiler/structuring/phoenix.py +45 -29
- angr/analyses/decompiler/structuring/structurer_base.py +2 -2
- angr/analyses/decompiler/structuring/structurer_nodes.py +23 -14
- angr/analyses/deobfuscator/__init__.py +3 -3
- angr/analyses/deobfuscator/irsb_reg_collector.py +29 -60
- angr/analyses/deobfuscator/string_obf_finder.py +2 -2
- angr/analyses/deobfuscator/string_obf_opt_passes.py +1 -1
- angr/analyses/disassembly.py +4 -4
- angr/analyses/forward_analysis/__init__.py +1 -1
- angr/analyses/forward_analysis/visitors/graph.py +6 -6
- angr/analyses/init_finder.py +47 -22
- angr/analyses/loop_analysis.py +1 -1
- angr/analyses/loopfinder.py +1 -1
- angr/analyses/propagator/engine_base.py +21 -14
- angr/analyses/propagator/engine_vex.py +149 -179
- angr/analyses/propagator/outdated_definition_walker.py +12 -6
- angr/analyses/propagator/propagator.py +10 -28
- angr/analyses/propagator/top_checker_mixin.py +211 -5
- angr/analyses/propagator/vex_vars.py +4 -4
- angr/analyses/reaching_definitions/__init__.py +9 -9
- angr/analyses/reaching_definitions/call_trace.py +2 -2
- angr/analyses/reaching_definitions/dep_graph.py +1 -1
- angr/analyses/reaching_definitions/engine_ail.py +304 -329
- angr/analyses/reaching_definitions/engine_vex.py +243 -229
- angr/analyses/reaching_definitions/function_handler.py +3 -3
- angr/analyses/reaching_definitions/function_handler_library/__init__.py +1 -1
- angr/analyses/reaching_definitions/rd_state.py +47 -42
- angr/analyses/reassembler.py +26 -31
- angr/analyses/s_liveness.py +8 -0
- angr/analyses/s_propagator.py +18 -3
- angr/analyses/s_reaching_definitions/s_rda_view.py +2 -5
- angr/analyses/s_reaching_definitions/s_reaching_definitions.py +9 -5
- angr/analyses/stack_pointer_tracker.py +4 -4
- angr/analyses/typehoon/simple_solver.py +14 -14
- angr/analyses/typehoon/translator.py +10 -2
- angr/analyses/typehoon/typeconsts.py +11 -3
- angr/analyses/typehoon/typevars.py +26 -26
- angr/analyses/unpacker/__init__.py +1 -1
- angr/analyses/variable_recovery/engine_ail.py +299 -259
- angr/analyses/variable_recovery/engine_base.py +138 -121
- angr/analyses/variable_recovery/engine_vex.py +175 -185
- angr/analyses/variable_recovery/irsb_scanner.py +49 -38
- angr/analyses/variable_recovery/variable_recovery.py +28 -5
- angr/analyses/variable_recovery/variable_recovery_base.py +33 -34
- angr/analyses/variable_recovery/variable_recovery_fast.py +4 -8
- angr/analyses/veritesting.py +2 -2
- angr/analyses/vfg.py +5 -5
- angr/analyses/xrefs.py +46 -19
- angr/angrdb/serializers/__init__.py +1 -1
- angr/annocfg.py +20 -15
- angr/blade.py +2 -2
- angr/block.py +20 -25
- angr/calling_conventions.py +12 -14
- angr/code_location.py +6 -10
- angr/codenode.py +3 -3
- angr/engines/__init__.py +12 -14
- angr/engines/engine.py +24 -61
- angr/engines/light/__init__.py +13 -5
- angr/engines/light/data.py +1 -1
- angr/engines/light/engine.py +1003 -1185
- angr/engines/pcode/__init__.py +1 -1
- angr/engines/pcode/behavior.py +1 -1
- angr/engines/pcode/cc.py +2 -0
- angr/engines/pcode/lifter.py +13 -15
- angr/engines/soot/expressions/__init__.py +12 -12
- angr/engines/soot/statements/__init__.py +6 -6
- angr/engines/soot/values/__init__.py +6 -6
- angr/engines/soot/values/arrayref.py +2 -2
- angr/engines/soot/values/constants.py +1 -1
- angr/engines/soot/values/instancefieldref.py +1 -1
- angr/engines/soot/values/paramref.py +1 -1
- angr/engines/soot/values/staticfieldref.py +1 -1
- angr/engines/successors.py +15 -14
- angr/engines/vex/__init__.py +5 -5
- angr/engines/vex/claripy/ccall.py +2 -2
- angr/engines/vex/claripy/datalayer.py +1 -1
- angr/engines/vex/claripy/irop.py +19 -19
- angr/engines/vex/heavy/__init__.py +2 -2
- angr/engines/vex/heavy/actions.py +1 -3
- angr/engines/vex/heavy/heavy.py +4 -6
- angr/engines/vex/lifter.py +2 -4
- angr/engines/vex/light/light.py +0 -2
- angr/engines/vex/light/slicing.py +5 -5
- angr/exploration_techniques/__init__.py +19 -142
- angr/exploration_techniques/base.py +126 -0
- angr/exploration_techniques/bucketizer.py +1 -1
- angr/exploration_techniques/dfs.py +3 -1
- angr/exploration_techniques/director.py +2 -3
- angr/exploration_techniques/driller_core.py +1 -1
- angr/exploration_techniques/explorer.py +4 -2
- angr/exploration_techniques/lengthlimiter.py +2 -1
- angr/exploration_techniques/local_loop_seer.py +2 -1
- angr/exploration_techniques/loop_seer.py +5 -5
- angr/exploration_techniques/manual_mergepoint.py +2 -1
- angr/exploration_techniques/memory_watcher.py +3 -1
- angr/exploration_techniques/oppologist.py +4 -5
- angr/exploration_techniques/slicecutor.py +4 -2
- angr/exploration_techniques/spiller.py +1 -1
- angr/exploration_techniques/stochastic.py +2 -1
- angr/exploration_techniques/stub_stasher.py +2 -1
- angr/exploration_techniques/suggestions.py +3 -1
- angr/exploration_techniques/symbion.py +3 -1
- angr/exploration_techniques/tech_builder.py +2 -1
- angr/exploration_techniques/threading.py +2 -11
- angr/exploration_techniques/timeout.py +4 -2
- angr/exploration_techniques/tracer.py +4 -3
- angr/exploration_techniques/unique.py +3 -2
- angr/exploration_techniques/veritesting.py +1 -1
- angr/factory.py +36 -6
- angr/keyed_region.py +4 -4
- angr/knowledge_base.py +1 -1
- angr/knowledge_plugins/__init__.py +11 -11
- angr/knowledge_plugins/cfg/__init__.py +5 -5
- angr/knowledge_plugins/cfg/cfg_manager.py +2 -2
- angr/knowledge_plugins/cfg/cfg_model.py +8 -8
- angr/knowledge_plugins/cfg/cfg_node.py +19 -19
- angr/knowledge_plugins/cfg/indirect_jump.py +6 -6
- angr/knowledge_plugins/cfg/memory_data.py +5 -7
- angr/knowledge_plugins/functions/function.py +48 -52
- angr/knowledge_plugins/functions/function_parser.py +4 -4
- angr/knowledge_plugins/key_definitions/__init__.py +3 -3
- angr/knowledge_plugins/key_definitions/atoms.py +8 -8
- angr/knowledge_plugins/key_definitions/definition.py +1 -1
- angr/knowledge_plugins/key_definitions/live_definitions.py +30 -27
- angr/knowledge_plugins/labels.py +1 -1
- angr/knowledge_plugins/propagations/__init__.py +1 -1
- angr/knowledge_plugins/propagations/prop_value.py +2 -2
- angr/knowledge_plugins/propagations/propagation_model.py +7 -8
- angr/knowledge_plugins/propagations/states.py +44 -39
- angr/knowledge_plugins/variables/variable_access.py +2 -2
- angr/knowledge_plugins/variables/variable_manager.py +24 -10
- angr/knowledge_plugins/xrefs/xref.py +5 -8
- angr/misc/__init__.py +4 -4
- angr/misc/hookset.py +4 -5
- angr/misc/loggers.py +2 -2
- angr/misc/telemetry.py +1 -1
- angr/procedures/__init__.py +1 -1
- angr/procedures/cgc/fdwait.py +2 -2
- angr/procedures/definitions/__init__.py +2 -2
- angr/procedures/definitions/linux_kernel.py +0 -1
- angr/procedures/definitions/parse_syscalls_from_local_system.py +1 -1
- angr/procedures/definitions/parse_win32json.py +0 -1
- angr/procedures/ntdll/exceptions.py +1 -1
- angr/procedures/stubs/format_parser.py +3 -3
- angr/procedures/win32/dynamic_loading.py +1 -1
- angr/protos/__init__.py +3 -3
- angr/sim_manager.py +3 -5
- angr/sim_state.py +40 -42
- angr/sim_state_options.py +3 -3
- angr/sim_type.py +15 -14
- angr/sim_variable.py +42 -45
- angr/simos/__init__.py +4 -4
- angr/simos/cgc.py +1 -1
- angr/simos/simos.py +1 -1
- angr/simos/userland.py +1 -1
- angr/slicer.py +4 -7
- angr/state_plugins/__init__.py +34 -34
- angr/state_plugins/callstack.py +5 -12
- angr/state_plugins/heap/__init__.py +2 -2
- angr/state_plugins/heap/heap_brk.py +2 -4
- angr/state_plugins/heap/heap_ptmalloc.py +1 -1
- angr/state_plugins/jni_references.py +3 -2
- angr/state_plugins/scratch.py +1 -1
- angr/state_plugins/sim_action.py +1 -4
- angr/state_plugins/sim_event.py +1 -1
- angr/state_plugins/solver.py +7 -9
- angr/state_plugins/uc_manager.py +1 -1
- angr/state_plugins/view.py +2 -2
- angr/storage/__init__.py +1 -1
- angr/storage/file.py +10 -10
- angr/storage/memory_mixins/__init__.py +46 -46
- angr/storage/memory_mixins/default_filler_mixin.py +1 -3
- angr/storage/memory_mixins/javavm_memory_mixin.py +2 -2
- angr/storage/memory_mixins/name_resolution_mixin.py +2 -2
- angr/storage/memory_mixins/paged_memory/paged_memory_mixin.py +1 -3
- angr/storage/memory_mixins/paged_memory/pages/__init__.py +6 -6
- angr/storage/memory_mixins/paged_memory/pages/list_page.py +1 -1
- angr/storage/memory_mixins/paged_memory/pages/multi_values.py +1 -1
- angr/storage/memory_mixins/paged_memory/pages/mv_list_page.py +1 -1
- angr/storage/memory_mixins/paged_memory/pages/ultra_page.py +2 -4
- angr/storage/memory_mixins/regioned_memory/__init__.py +3 -3
- angr/storage/memory_mixins/regioned_memory/region_data.py +5 -5
- angr/storage/memory_mixins/regioned_memory/region_meta_mixin.py +7 -9
- angr/storage/memory_mixins/regioned_memory/regioned_memory_mixin.py +4 -4
- angr/storage/memory_object.py +4 -4
- angr/utils/__init__.py +3 -3
- angr/utils/bits.py +12 -0
- angr/utils/dynamic_dictlist.py +1 -1
- angr/utils/graph.py +1 -1
- angr/utils/orderedset.py +4 -1
- angr/utils/segment_list.py +2 -2
- angr/utils/ssa/__init__.py +33 -8
- {angr-9.2.131.dist-info → angr-9.2.133.dist-info}/METADATA +6 -6
- {angr-9.2.131.dist-info → angr-9.2.133.dist-info}/RECORD +262 -263
- angr/analyses/propagator/engine_ail.py +0 -1562
- angr/storage/memory_mixins/__init__.pyi +0 -48
- {angr-9.2.131.dist-info → angr-9.2.133.dist-info}/LICENSE +0 -0
- {angr-9.2.131.dist-info → angr-9.2.133.dist-info}/WHEEL +0 -0
- {angr-9.2.131.dist-info → angr-9.2.133.dist-info}/entry_points.txt +0 -0
- {angr-9.2.131.dist-info → angr-9.2.133.dist-info}/top_level.txt +0 -0
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
# pylint:disable=wrong-import-position,wrong-import-order
|
|
2
2
|
from __future__ import annotations
|
|
3
3
|
import enum
|
|
4
|
-
from typing import TYPE_CHECKING
|
|
4
|
+
from typing import TYPE_CHECKING, Any, Literal, cast
|
|
5
5
|
from collections.abc import Sequence
|
|
6
|
+
from collections import defaultdict, OrderedDict
|
|
6
7
|
import logging
|
|
7
8
|
import functools
|
|
8
|
-
from collections import defaultdict, OrderedDict
|
|
9
9
|
|
|
10
10
|
import pyvex
|
|
11
11
|
import claripy
|
|
@@ -18,15 +18,18 @@ from angr.code_location import CodeLocation
|
|
|
18
18
|
from angr.concretization_strategies import SimConcretizationStrategyAny
|
|
19
19
|
from angr.knowledge_plugins.cfg import IndirectJump, IndirectJumpType
|
|
20
20
|
from angr.engines.vex.claripy import ccall
|
|
21
|
-
from angr.engines.light import
|
|
21
|
+
from angr.engines.light import SimEngineNostmtVEX, SpOffset, RegisterOffset
|
|
22
22
|
from angr.errors import AngrError, SimError
|
|
23
23
|
from angr.blade import Blade
|
|
24
24
|
from angr.annocfg import AnnotatedCFG
|
|
25
25
|
from angr.exploration_techniques.slicecutor import Slicecutor
|
|
26
26
|
from angr.exploration_techniques.local_loop_seer import LocalLoopSeer
|
|
27
27
|
from angr.exploration_techniques.explorer import Explorer
|
|
28
|
+
from angr.project import Project
|
|
28
29
|
from angr.utils.constants import DEFAULT_STATEMENT
|
|
29
30
|
from angr.analyses.propagator.vex_vars import VEXReg
|
|
31
|
+
from angr.analyses.propagator.top_checker_mixin import ClaripyDataVEXEngineMixin
|
|
32
|
+
from angr.engines.vex.claripy.datalayer import value
|
|
30
33
|
from .resolver import IndirectJumpResolver
|
|
31
34
|
from .propagator_utils import PropagatorLoadCallback
|
|
32
35
|
|
|
@@ -113,12 +116,14 @@ class JumpTargetBaseAddr:
|
|
|
113
116
|
Model for jump targets and their data origin.
|
|
114
117
|
"""
|
|
115
118
|
|
|
116
|
-
def __init__(
|
|
119
|
+
def __init__(
|
|
120
|
+
self, stmt_loc, stmt: pyvex.stmt.IRStmt, tmp: int, base_addr: int | None = None, tmp_1: int | None = None
|
|
121
|
+
):
|
|
117
122
|
self.stmt_loc = stmt_loc
|
|
118
123
|
self.stmt = stmt
|
|
119
|
-
self.tmp
|
|
124
|
+
self.tmp = tmp
|
|
120
125
|
self.tmp_1 = tmp_1
|
|
121
|
-
self.base_addr
|
|
126
|
+
self.base_addr = base_addr
|
|
122
127
|
|
|
123
128
|
assert base_addr is not None or tmp_1 is not None
|
|
124
129
|
|
|
@@ -138,22 +143,23 @@ class ConstantValueManager:
|
|
|
138
143
|
"""
|
|
139
144
|
|
|
140
145
|
__slots__ = (
|
|
141
|
-
"project",
|
|
142
|
-
"kb",
|
|
143
146
|
"func",
|
|
147
|
+
"kb",
|
|
144
148
|
"mapping",
|
|
149
|
+
"project",
|
|
145
150
|
)
|
|
146
151
|
|
|
147
|
-
def __init__(self, project, kb, func: Function):
|
|
152
|
+
def __init__(self, project: Project, kb, func: Function):
|
|
148
153
|
self.project = project
|
|
149
154
|
self.kb = kb
|
|
150
155
|
self.func = func
|
|
151
156
|
|
|
152
|
-
self.mapping = None
|
|
157
|
+
self.mapping: dict[Any, dict[Any, claripy.ast.Base]] | None = None
|
|
153
158
|
|
|
154
159
|
def reg_read_callback(self, state: SimState):
|
|
155
160
|
if not self.mapping:
|
|
156
161
|
self._build_mapping()
|
|
162
|
+
assert self.mapping is not None
|
|
157
163
|
|
|
158
164
|
codeloc = CodeLocation(state.scratch.bbl_addr, state.scratch.stmt_idx, ins_addr=state.scratch.ins_addr)
|
|
159
165
|
if codeloc in self.mapping:
|
|
@@ -234,13 +240,13 @@ class JumpTableProcessorState:
|
|
|
234
240
|
"""
|
|
235
241
|
|
|
236
242
|
__slots__ = (
|
|
237
|
-
"arch",
|
|
238
243
|
"_registers",
|
|
239
244
|
"_stack",
|
|
240
245
|
"_tmpvar_source",
|
|
246
|
+
"arch",
|
|
241
247
|
"is_jumptable",
|
|
242
|
-
"stmts_to_instrument",
|
|
243
248
|
"regs_to_initialize",
|
|
249
|
+
"stmts_to_instrument",
|
|
244
250
|
)
|
|
245
251
|
|
|
246
252
|
def __init__(self, arch):
|
|
@@ -250,7 +256,7 @@ class JumpTableProcessorState:
|
|
|
250
256
|
self._stack = {}
|
|
251
257
|
self._tmpvar_source = {} # a mapping from temporary variables to their origins
|
|
252
258
|
|
|
253
|
-
self.is_jumptable = None # is the current slice representing a jump table?
|
|
259
|
+
self.is_jumptable: bool | None = None # is the current slice representing a jump table?
|
|
254
260
|
self.stmts_to_instrument = [] # Store/Put statements that we should instrument
|
|
255
261
|
self.regs_to_initialize = [] # registers that we should initialize
|
|
256
262
|
|
|
@@ -274,9 +280,12 @@ class RegOffsetAnnotation(claripy.Annotation):
|
|
|
274
280
|
return False
|
|
275
281
|
|
|
276
282
|
|
|
283
|
+
binop_handler = SimEngineNostmtVEX[JumpTableProcessorState, claripy.ast.BV, JumpTableProcessorState].binop_handler
|
|
284
|
+
|
|
285
|
+
|
|
277
286
|
class JumpTableProcessor(
|
|
278
|
-
|
|
279
|
-
|
|
287
|
+
SimEngineNostmtVEX[JumpTableProcessorState, claripy.ast.BV, JumpTableProcessorState],
|
|
288
|
+
ClaripyDataVEXEngineMixin[JumpTableProcessorState, claripy.ast.BV, JumpTableProcessorState, None],
|
|
280
289
|
): # pylint:disable=abstract-method
|
|
281
290
|
"""
|
|
282
291
|
Implements a simple and stupid data dependency tracking for stack and register variables.
|
|
@@ -298,20 +307,18 @@ class JumpTableProcessor(
|
|
|
298
307
|
"""
|
|
299
308
|
|
|
300
309
|
def __init__(self, project, indirect_jump_node_pred_addrs: set[int], bp_sp_diff=0x100):
|
|
301
|
-
super().__init__()
|
|
302
|
-
self.project = project
|
|
310
|
+
super().__init__(project)
|
|
303
311
|
self._bp_sp_diff = bp_sp_diff # bp - sp
|
|
304
|
-
self._tsrc
|
|
312
|
+
self._tsrc: set[Literal["const"] | tuple[int, int]] = (
|
|
313
|
+
set()
|
|
314
|
+
) # a scratch variable to store source information for values
|
|
305
315
|
self._indirect_jump_node_pred_addrs = indirect_jump_node_pred_addrs
|
|
306
316
|
|
|
307
317
|
self._SPOFFSET_BASE = claripy.BVS("SpOffset", self.project.arch.bits, explicit_name=True)
|
|
308
318
|
self._REGOFFSET_BASE: dict[int, claripy.ast.BV] = {}
|
|
309
319
|
|
|
310
|
-
def
|
|
311
|
-
return
|
|
312
|
-
|
|
313
|
-
def _is_top(self, expr) -> bool:
|
|
314
|
-
return expr is None
|
|
320
|
+
def _process_block_end(self, stmt_result, whitelist):
|
|
321
|
+
return self.state
|
|
315
322
|
|
|
316
323
|
@staticmethod
|
|
317
324
|
def _is_spoffset(expr) -> bool:
|
|
@@ -321,23 +328,23 @@ class JumpTableProcessor(
|
|
|
321
328
|
return self._SPOFFSET_BASE.annotate(RegOffsetAnnotation(sp_offset))
|
|
322
329
|
|
|
323
330
|
@staticmethod
|
|
324
|
-
def _extract_spoffset_from_expr(expr: claripy.ast.Base) ->
|
|
331
|
+
def _extract_spoffset_from_expr(expr: claripy.ast.Base) -> RegisterOffset | None:
|
|
325
332
|
if expr.op == "BVS":
|
|
326
333
|
for anno in expr.annotations:
|
|
327
334
|
if isinstance(anno, RegOffsetAnnotation):
|
|
328
335
|
return anno.reg_offset
|
|
329
336
|
elif expr.op == "__add__":
|
|
330
337
|
if len(expr.args) == 1:
|
|
331
|
-
return JumpTableProcessor._extract_spoffset_from_expr(expr.args[0])
|
|
332
|
-
if len(expr.args) == 2 and expr.args[1].op == "BVV":
|
|
333
|
-
sp_offset = JumpTableProcessor._extract_spoffset_from_expr(expr.args[0])
|
|
338
|
+
return JumpTableProcessor._extract_spoffset_from_expr(cast(claripy.ast.BV, expr.args[0]))
|
|
339
|
+
if len(expr.args) == 2 and cast(claripy.ast.BV, expr.args[1]).op == "BVV":
|
|
340
|
+
sp_offset = JumpTableProcessor._extract_spoffset_from_expr(cast(claripy.ast.BV, expr.args[0]))
|
|
334
341
|
if sp_offset is not None:
|
|
335
|
-
delta = expr.args[1].concrete_value
|
|
342
|
+
delta = cast(claripy.ast.BV, expr.args[1]).concrete_value
|
|
336
343
|
sp_offset += delta
|
|
337
344
|
return sp_offset
|
|
338
|
-
elif expr.op == "__and__" and len(expr.args) == 2 and expr.args[1].op == "BVV":
|
|
345
|
+
elif expr.op == "__and__" and len(expr.args) == 2 and cast(claripy.ast.BV, expr.args[1]).op == "BVV":
|
|
339
346
|
# ignore all masking on SpOffsets
|
|
340
|
-
return JumpTableProcessor._extract_spoffset_from_expr(expr.args[0])
|
|
347
|
+
return JumpTableProcessor._extract_spoffset_from_expr(cast(claripy.ast.BV, expr.args[0]))
|
|
341
348
|
return None
|
|
342
349
|
|
|
343
350
|
@staticmethod
|
|
@@ -357,33 +364,33 @@ class JumpTableProcessor(
|
|
|
357
364
|
return anno.reg_offset
|
|
358
365
|
elif expr.op == "__add__":
|
|
359
366
|
if len(expr.args) == 1:
|
|
360
|
-
return JumpTableProcessor._extract_regoffset_from_expr(expr.args[0])
|
|
361
|
-
if len(expr.args) == 2 and expr.args[1].op == "BVV":
|
|
362
|
-
reg_offset = JumpTableProcessor._extract_regoffset_from_expr(expr.args[0])
|
|
367
|
+
return JumpTableProcessor._extract_regoffset_from_expr(cast(claripy.ast.BV, expr.args[0]))
|
|
368
|
+
if len(expr.args) == 2 and cast(claripy.ast.BV, expr.args[1]).op == "BVV":
|
|
369
|
+
reg_offset = JumpTableProcessor._extract_regoffset_from_expr(cast(claripy.ast.BV, expr.args[0]))
|
|
363
370
|
if reg_offset is not None:
|
|
364
|
-
delta = expr.args[1].concrete_value
|
|
371
|
+
delta = cast(claripy.ast.BV, expr.args[1]).concrete_value
|
|
365
372
|
reg_offset += delta
|
|
366
373
|
return reg_offset
|
|
367
|
-
elif expr.op == "__and__" and len(expr.args) == 2 and expr.args[1].op == "BVV":
|
|
374
|
+
elif expr.op == "__and__" and len(expr.args) == 2 and cast(claripy.ast.BV, expr.args[1]).op == "BVV":
|
|
368
375
|
# ignore all masking on SpOffsets
|
|
369
|
-
return JumpTableProcessor._extract_spoffset_from_expr(expr.args[0])
|
|
376
|
+
return JumpTableProcessor._extract_spoffset_from_expr(cast(claripy.ast.BV, expr.args[0]))
|
|
370
377
|
return None
|
|
371
378
|
|
|
372
|
-
def
|
|
379
|
+
def _handle_stmt_WrTmp(self, stmt):
|
|
373
380
|
self._tsrc = set()
|
|
374
|
-
super()._handle_WrTmp(stmt)
|
|
375
381
|
|
|
382
|
+
self.tmps[stmt.tmp] = self._expr(stmt.data)
|
|
376
383
|
if self._tsrc:
|
|
377
384
|
self.state._tmpvar_source[stmt.tmp] = self._tsrc
|
|
378
385
|
|
|
379
|
-
def
|
|
386
|
+
def _handle_stmt_Put(self, stmt):
|
|
380
387
|
self._tsrc = set()
|
|
381
388
|
offset = stmt.offset
|
|
382
389
|
data = self._expr(stmt.data)
|
|
383
390
|
r = (self._tsrc, data) if self._tsrc is not None else ((self.block.addr, self.stmt_idx), data)
|
|
384
391
|
self.state._registers[offset] = r
|
|
385
392
|
|
|
386
|
-
def
|
|
393
|
+
def _handle_stmt_Store(self, stmt):
|
|
387
394
|
self._tsrc = set()
|
|
388
395
|
addr = self._expr(stmt.addr)
|
|
389
396
|
data = self._expr(stmt.data)
|
|
@@ -394,13 +401,16 @@ class JumpTableProcessor(
|
|
|
394
401
|
if isinstance(addr, SpOffset):
|
|
395
402
|
self.state._stack[addr.offset] = ((self.block.addr, self.stmt_idx), data)
|
|
396
403
|
|
|
397
|
-
def
|
|
398
|
-
|
|
404
|
+
def _handle_expr_RdTmp(self, expr):
|
|
405
|
+
try:
|
|
406
|
+
v = self.tmps[expr.tmp]
|
|
407
|
+
except KeyError:
|
|
408
|
+
v = self._top(expr.result_size(self.tyenv))
|
|
399
409
|
if expr.tmp in self.state._tmpvar_source:
|
|
400
410
|
self._tsrc |= set(self.state._tmpvar_source[expr.tmp])
|
|
401
411
|
return v
|
|
402
412
|
|
|
403
|
-
def
|
|
413
|
+
def _handle_expr_Get(self, expr):
|
|
404
414
|
if expr.offset == self.arch.bp_offset:
|
|
405
415
|
v = self._get_spoffset_expr(SpOffset(self.arch.bits, self._bp_sp_diff))
|
|
406
416
|
elif expr.offset == self.arch.sp_offset:
|
|
@@ -433,55 +443,77 @@ class JumpTableProcessor(
|
|
|
433
443
|
def _handle_function(self, expr): # pylint:disable=unused-argument,no-self-use
|
|
434
444
|
return None # This analysis is not interprocedural
|
|
435
445
|
|
|
436
|
-
def
|
|
446
|
+
def _handle_expr_Load(self, expr):
|
|
437
447
|
addr = self._expr(expr.addr)
|
|
438
448
|
size = expr.result_size(self.tyenv) // 8
|
|
439
449
|
return self._do_load(addr, size)
|
|
440
450
|
|
|
441
|
-
def
|
|
442
|
-
|
|
443
|
-
if guard is True:
|
|
444
|
-
return self._do_load(stmt.addr, stmt.addr.result_size(self.tyenv) // 8)
|
|
445
|
-
if guard is False:
|
|
446
|
-
return self._do_load(stmt.alt, stmt.alt.result_size(self.tyenv) // 8)
|
|
447
|
-
return None
|
|
451
|
+
def _handle_stmt_LoadG(self, stmt: pyvex.stmt.LoadG):
|
|
452
|
+
self._tsrc = set()
|
|
448
453
|
|
|
449
|
-
|
|
450
|
-
|
|
454
|
+
guard = self._expr(stmt.guard) != 0
|
|
455
|
+
iftrue = self._do_load(self._expr(stmt.addr), stmt.addr.result_size(self.tyenv) // 8)
|
|
456
|
+
iffalse = self._expr(stmt.alt)
|
|
457
|
+
result = claripy.If(guard, iftrue, iffalse)
|
|
458
|
+
self.tmps[stmt.dst] = result
|
|
459
|
+
if self._tsrc:
|
|
460
|
+
self.state._tmpvar_source[stmt.dst] = self._tsrc
|
|
461
|
+
|
|
462
|
+
def _handle_expr_Const(self, expr):
|
|
463
|
+
v = value(expr.con.type, expr.con.value)
|
|
451
464
|
self._tsrc.add("const")
|
|
465
|
+
if not isinstance(v, claripy.ast.BV):
|
|
466
|
+
return self._top(expr.result_size(self.tyenv))
|
|
452
467
|
return v
|
|
453
468
|
|
|
454
|
-
|
|
455
|
-
|
|
469
|
+
@binop_handler
|
|
470
|
+
def _handle_binop_CmpLE(self, expr):
|
|
471
|
+
return self._handle_Comparison(*expr.args)
|
|
456
472
|
|
|
457
|
-
|
|
458
|
-
|
|
473
|
+
@binop_handler
|
|
474
|
+
def _handle_binop_CmpGE(self, expr):
|
|
475
|
+
return self._handle_Comparison(*expr.args)
|
|
459
476
|
|
|
460
|
-
|
|
461
|
-
|
|
477
|
+
@binop_handler
|
|
478
|
+
def _handle_binop_CmpLT(self, expr):
|
|
479
|
+
return self._handle_Comparison(*expr.args)
|
|
462
480
|
|
|
463
|
-
|
|
464
|
-
|
|
481
|
+
@binop_handler
|
|
482
|
+
def _handle_binop_CmpGT(self, expr):
|
|
483
|
+
return self._handle_Comparison(*expr.args)
|
|
465
484
|
|
|
466
|
-
def
|
|
467
|
-
if
|
|
468
|
-
|
|
469
|
-
cond_type_enum = expr.args[0].con.value
|
|
485
|
+
def _handle_expr_CCall(self, expr):
|
|
486
|
+
if isinstance(expr.args[0], pyvex.IRExpr.Const):
|
|
487
|
+
cond_type_enum = expr.args[0].con.value
|
|
470
488
|
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
489
|
+
if self.arch.name in {"X86", "AMD64", "AARCH64"}:
|
|
490
|
+
if cond_type_enum in EXPECTED_COND_TYPES[self.arch.name]:
|
|
491
|
+
self._handle_Comparison(expr.args[2], expr.args[3])
|
|
492
|
+
elif is_arm_arch(self.arch):
|
|
493
|
+
if cond_type_enum in EXPECTED_COND_TYPES["ARM"]:
|
|
494
|
+
self._handle_Comparison(expr.args[2], expr.args[3])
|
|
495
|
+
else:
|
|
496
|
+
# other architectures
|
|
497
|
+
l.warning("Please fill in EXPECTED_COND_TYPES for %s.", self.arch.name)
|
|
476
498
|
self._handle_Comparison(expr.args[2], expr.args[3])
|
|
477
|
-
else:
|
|
478
|
-
# other architectures
|
|
479
|
-
l.warning("Please fill in EXPECTED_COND_TYPES for %s.", self.arch.name)
|
|
480
|
-
self._handle_Comparison(expr.args[2], expr.args[3])
|
|
481
499
|
|
|
482
|
-
|
|
500
|
+
return self._top(expr.result_size(self.tyenv))
|
|
501
|
+
|
|
502
|
+
def _handle_expr_VECRET(self, expr):
|
|
503
|
+
return self._top(expr.result_size(self.tyenv))
|
|
504
|
+
|
|
505
|
+
def _handle_expr_GSPTR(self, expr):
|
|
506
|
+
return self._top(expr.result_size(self.tyenv))
|
|
507
|
+
|
|
508
|
+
def _handle_expr_GetI(self, expr):
|
|
509
|
+
return self._top(expr.result_size(self.tyenv))
|
|
510
|
+
|
|
511
|
+
def _handle_expr_ITE(self, expr):
|
|
512
|
+
return self._top(expr.result_size(self.tyenv))
|
|
513
|
+
|
|
514
|
+
def _handle_Comparison(self, arg0: pyvex.expr.IRExpr, arg1: pyvex.expr.IRExpr) -> claripy.ast.BV:
|
|
483
515
|
if self.block.addr not in self._indirect_jump_node_pred_addrs:
|
|
484
|
-
return
|
|
516
|
+
return self._top(1)
|
|
485
517
|
|
|
486
518
|
# found the comparison
|
|
487
519
|
arg0_src, arg1_src = None, None
|
|
@@ -502,10 +534,10 @@ class JumpTableProcessor(
|
|
|
502
534
|
if arg0_src == "const" and arg1_src == "const":
|
|
503
535
|
# comparison of two consts... there is nothing we can do
|
|
504
536
|
self.state.is_jumptable = True
|
|
505
|
-
return
|
|
537
|
+
return self._top(1)
|
|
506
538
|
if arg0_src not in {"const", None} and arg1_src not in {"const", None}:
|
|
507
539
|
# this is probably not a jump table
|
|
508
|
-
return
|
|
540
|
+
return self._top(1)
|
|
509
541
|
if arg1_src == "const":
|
|
510
542
|
# make sure arg0_src is const
|
|
511
543
|
arg0_src, arg1_src = arg1_src, arg0_src
|
|
@@ -515,7 +547,7 @@ class JumpTableProcessor(
|
|
|
515
547
|
if arg0_src != "const":
|
|
516
548
|
# we failed during dependency tracking so arg0_src couldn't be determined
|
|
517
549
|
# but we will still try to resolve it as a jump table as a fall back
|
|
518
|
-
return
|
|
550
|
+
return self._top(1)
|
|
519
551
|
|
|
520
552
|
if isinstance(arg1_src, tuple):
|
|
521
553
|
arg1_src_stmt = self.project.factory.block(arg1_src[0], cross_insn_opt=True).vex.statements[arg1_src[1]]
|
|
@@ -563,23 +595,17 @@ class JumpTableProcessor(
|
|
|
563
595
|
#
|
|
564
596
|
self.state.stmts_to_instrument.append(("reg_write", *arg1_src))
|
|
565
597
|
|
|
566
|
-
|
|
598
|
+
return self._top(1)
|
|
599
|
+
|
|
600
|
+
def _do_load(self, addr: claripy.ast.BV, size: int) -> claripy.ast.BV:
|
|
567
601
|
src = (self.block.addr, self.stmt_idx)
|
|
568
602
|
self._tsrc = {src}
|
|
569
|
-
if addr is None:
|
|
570
|
-
return None
|
|
571
603
|
|
|
572
604
|
if self._is_spoffset(addr):
|
|
573
605
|
spoffset = self._extract_spoffset_from_expr(addr)
|
|
574
606
|
if spoffset is not None and spoffset.offset in self.state._stack:
|
|
575
607
|
self._tsrc = {self.state._stack[spoffset.offset][0]}
|
|
576
608
|
return self.state._stack[spoffset.offset][1]
|
|
577
|
-
elif isinstance(addr, int):
|
|
578
|
-
# Load data from memory if it is mapped
|
|
579
|
-
try:
|
|
580
|
-
return self.project.loader.memory.unpack_word(addr, size=size)
|
|
581
|
-
except KeyError:
|
|
582
|
-
return None
|
|
583
609
|
elif self._is_registeroffset(addr):
|
|
584
610
|
# Load data from a register, but this register hasn't been initialized at this point
|
|
585
611
|
# We will need to initialize this register during slice execution later
|
|
@@ -598,9 +624,7 @@ class JumpTableProcessor(
|
|
|
598
624
|
# function call sub_375c04. Since we do not analyze sub_375c04, we treat r0@11e918 as a constant 0.
|
|
599
625
|
pass
|
|
600
626
|
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
return None
|
|
627
|
+
return self._top(size)
|
|
604
628
|
|
|
605
629
|
|
|
606
630
|
#
|
|
@@ -658,10 +682,10 @@ class RegisterInitializerHook:
|
|
|
658
682
|
Hook for register init.
|
|
659
683
|
"""
|
|
660
684
|
|
|
661
|
-
def __init__(self, reg_offset, reg_bits,
|
|
685
|
+
def __init__(self, reg_offset, reg_bits, initial_value):
|
|
662
686
|
self.reg_offset = reg_offset
|
|
663
687
|
self.reg_bits = reg_bits
|
|
664
|
-
self.value =
|
|
688
|
+
self.value = initial_value
|
|
665
689
|
|
|
666
690
|
def hook(self, state):
|
|
667
691
|
state.registers.store(self.reg_offset, claripy.BVV(self.value, self.reg_bits))
|
|
@@ -786,7 +810,7 @@ class JumpTableResolver(IndirectJumpResolver):
|
|
|
786
810
|
|
|
787
811
|
self._bss_regions = None
|
|
788
812
|
# the maximum number of resolved targets. Will be initialized from CFG.
|
|
789
|
-
self._max_targets =
|
|
813
|
+
self._max_targets = 0
|
|
790
814
|
|
|
791
815
|
# cached memory read addresses that are used to initialize uninitialized registers
|
|
792
816
|
# should be cleared before every symbolic execution run on the slice
|
|
@@ -1044,8 +1068,10 @@ class JumpTableResolver(IndirectJumpResolver):
|
|
|
1044
1068
|
simgr.use_technique(slicecutor)
|
|
1045
1069
|
simgr.use_technique(LocalLoopSeer(bound=1))
|
|
1046
1070
|
if load_stmt is not None:
|
|
1071
|
+
assert load_stmt_loc is not None
|
|
1047
1072
|
explorer = Explorer(find=load_stmt_loc[0])
|
|
1048
1073
|
elif ite_stmt is not None:
|
|
1074
|
+
assert ite_stmt_loc is not None
|
|
1049
1075
|
explorer = Explorer(find=ite_stmt_loc[0])
|
|
1050
1076
|
else:
|
|
1051
1077
|
raise TypeError("Unsupported type of jump table.")
|
|
@@ -1144,7 +1170,14 @@ class JumpTableResolver(IndirectJumpResolver):
|
|
|
1144
1170
|
l.info("Could not resolve indirect jump %#x in function %#x.", addr, func_addr)
|
|
1145
1171
|
return False, None
|
|
1146
1172
|
|
|
1147
|
-
def _find_load_statement(self, b, stmt_loc)
|
|
1173
|
+
def _find_load_statement(self, b, stmt_loc: tuple[int, int]) -> tuple[
|
|
1174
|
+
tuple[int, int] | None,
|
|
1175
|
+
pyvex.stmt.IRStmt | None,
|
|
1176
|
+
int | None,
|
|
1177
|
+
list[tuple[int, int]],
|
|
1178
|
+
list[JumpTargetBaseAddr],
|
|
1179
|
+
OrderedDict[tuple[int, int], AddressTransformation],
|
|
1180
|
+
]:
|
|
1148
1181
|
"""
|
|
1149
1182
|
Find the location of the final Load statement that loads indirect jump targets from the jump table.
|
|
1150
1183
|
"""
|
|
@@ -1306,6 +1339,7 @@ class JumpTableResolver(IndirectJumpResolver):
|
|
|
1306
1339
|
if isinstance(stmt.data.args[0], pyvex.IRExpr.Const) and isinstance(
|
|
1307
1340
|
stmt.data.args[1], pyvex.IRExpr.RdTmp
|
|
1308
1341
|
):
|
|
1342
|
+
assert isinstance(stmt, pyvex.stmt.WrTmp)
|
|
1309
1343
|
transformations[(stmt_loc[0], stmt.tmp)] = AddressTransformation(
|
|
1310
1344
|
AddressTransformationTypes.Add, [stmt.data.args[0].con.value, AddressSingleton]
|
|
1311
1345
|
)
|
|
@@ -1315,6 +1349,7 @@ class JumpTableResolver(IndirectJumpResolver):
|
|
|
1315
1349
|
elif isinstance(stmt.data.args[0], pyvex.IRExpr.RdTmp) and isinstance(
|
|
1316
1350
|
stmt.data.args[1], pyvex.IRExpr.Const
|
|
1317
1351
|
):
|
|
1352
|
+
assert isinstance(stmt, pyvex.stmt.WrTmp)
|
|
1318
1353
|
transformations[(stmt_loc[0], stmt.tmp)] = AddressTransformation(
|
|
1319
1354
|
AddressTransformationTypes.Add, [AddressSingleton, stmt.data.args[1].con.value]
|
|
1320
1355
|
)
|
|
@@ -1363,6 +1398,7 @@ class JumpTableResolver(IndirectJumpResolver):
|
|
|
1363
1398
|
and isinstance(stmt.data.args[1], pyvex.IRExpr.Const)
|
|
1364
1399
|
and stmt.data.args[1].con.value == 1
|
|
1365
1400
|
):
|
|
1401
|
+
assert isinstance(stmt, pyvex.stmt.WrTmp)
|
|
1366
1402
|
# great. here it is
|
|
1367
1403
|
stmts_to_remove.append(stmt_loc)
|
|
1368
1404
|
transformations[(stmt_loc[0], stmt.tmp)] = AddressTransformation(
|
|
@@ -1387,6 +1423,7 @@ class JumpTableResolver(IndirectJumpResolver):
|
|
|
1387
1423
|
if isinstance(stmt.data.args[0], pyvex.IRExpr.RdTmp) and isinstance(
|
|
1388
1424
|
stmt.data.args[1], pyvex.IRExpr.Const
|
|
1389
1425
|
):
|
|
1426
|
+
assert isinstance(stmt, pyvex.stmt.WrTmp)
|
|
1390
1427
|
# found it
|
|
1391
1428
|
stmts_to_remove.append(stmt_loc)
|
|
1392
1429
|
transformations[(stmt_loc[0], stmt.tmp)] = AddressTransformation(
|
|
@@ -1424,6 +1461,7 @@ class JumpTableResolver(IndirectJumpResolver):
|
|
|
1424
1461
|
and isinstance(stmt.data.args[0], pyvex.IRExpr.RdTmp)
|
|
1425
1462
|
and isinstance(stmt.data.args[1], pyvex.IRExpr.Const)
|
|
1426
1463
|
):
|
|
1464
|
+
assert isinstance(stmt, pyvex.stmt.WrTmp)
|
|
1427
1465
|
# found it
|
|
1428
1466
|
stmts_to_remove.append(stmt_loc)
|
|
1429
1467
|
transformations[(stmt_loc[0], stmt.tmp)] = AddressTransformation(
|
|
@@ -1431,6 +1469,7 @@ class JumpTableResolver(IndirectJumpResolver):
|
|
|
1431
1469
|
)
|
|
1432
1470
|
continue
|
|
1433
1471
|
elif isinstance(stmt.data, pyvex.IRExpr.Load):
|
|
1472
|
+
assert isinstance(stmt, pyvex.stmt.WrTmp)
|
|
1434
1473
|
# Got it!
|
|
1435
1474
|
load_stmt, load_stmt_loc, load_size = (
|
|
1436
1475
|
stmt,
|
|
@@ -1558,9 +1597,10 @@ class JumpTableResolver(IndirectJumpResolver):
|
|
|
1558
1597
|
|
|
1559
1598
|
block = self.project.factory.block(block_addr, cross_insn_opt=True, backup_state=self.base_state)
|
|
1560
1599
|
stmt_whitelist = annotatedcfg.get_whitelisted_statements(block_addr)
|
|
1600
|
+
assert isinstance(stmt_whitelist, list)
|
|
1561
1601
|
try:
|
|
1562
1602
|
engine.process(state, block=block, whitelist=stmt_whitelist)
|
|
1563
|
-
except (claripy.
|
|
1603
|
+
except (claripy.ClaripyError, SimError, AngrError):
|
|
1564
1604
|
# anything can happen
|
|
1565
1605
|
break
|
|
1566
1606
|
|
|
@@ -1598,6 +1638,7 @@ class JumpTableResolver(IndirectJumpResolver):
|
|
|
1598
1638
|
|
|
1599
1639
|
# If we're just reading a constant, don't bother with the rest of this mess!
|
|
1600
1640
|
if isinstance(load_stmt, pyvex.IRStmt.WrTmp):
|
|
1641
|
+
assert isinstance(load_stmt.data, pyvex.IRExpr.Load)
|
|
1601
1642
|
if type(load_stmt.data.addr) is pyvex.IRExpr.Const:
|
|
1602
1643
|
# It's directly loading from a constant address
|
|
1603
1644
|
# e.g.,
|
|
@@ -1717,7 +1758,7 @@ class JumpTableResolver(IndirectJumpResolver):
|
|
|
1717
1758
|
# full-function data propagation before performing jump table recovery.
|
|
1718
1759
|
l.debug("Multiple statements adding bases, not supported yet") # FIXME: Just check the addresses?
|
|
1719
1760
|
|
|
1720
|
-
if jumptable_addr.has_annotation_type(claripy.
|
|
1761
|
+
if jumptable_addr.has_annotation_type(claripy.RegionAnnotation):
|
|
1721
1762
|
return None
|
|
1722
1763
|
|
|
1723
1764
|
all_targets = []
|
|
@@ -1730,7 +1771,7 @@ class JumpTableResolver(IndirectJumpResolver):
|
|
|
1730
1771
|
jumptable_si = claripy.backends.vsa.simplify(jumptable_addr)
|
|
1731
1772
|
si_annotation = jumptable_si.get_annotation(claripy.annotation.StridedIntervalAnnotation)
|
|
1732
1773
|
stride = si_annotation.stride if si_annotation is not None else 0
|
|
1733
|
-
except claripy.
|
|
1774
|
+
except claripy.ClaripyError:
|
|
1734
1775
|
return None
|
|
1735
1776
|
|
|
1736
1777
|
# we may resolve a vtable (in C, e.g., the IO_JUMPS_FUNC in libc), but the stride of this load is usually 1
|
|
@@ -1745,6 +1786,7 @@ class JumpTableResolver(IndirectJumpResolver):
|
|
|
1745
1786
|
total_cases = jumptable_addr.cardinality
|
|
1746
1787
|
sort = "jumptable"
|
|
1747
1788
|
|
|
1789
|
+
assert self._max_targets is not None
|
|
1748
1790
|
if total_cases > self._max_targets:
|
|
1749
1791
|
if (
|
|
1750
1792
|
potential_call_table
|
|
@@ -1755,6 +1797,7 @@ class JumpTableResolver(IndirectJumpResolver):
|
|
|
1755
1797
|
# Undetermined table size. Take a guess based on target plausibility.
|
|
1756
1798
|
table_base_addr = None
|
|
1757
1799
|
for arg in jumptable_addr.args:
|
|
1800
|
+
assert isinstance(arg, (claripy.ast.BV, claripy.ast.FP, claripy.ast.Bool))
|
|
1758
1801
|
if arg.concrete:
|
|
1759
1802
|
table_base_addr = state.solver.eval(arg)
|
|
1760
1803
|
break
|
|
@@ -2132,10 +2175,12 @@ class JumpTableResolver(IndirectJumpResolver):
|
|
|
2132
2175
|
stmt_taken = i in stmt_ids
|
|
2133
2176
|
display = stmt_taken if in_slice_stmts_only else True
|
|
2134
2177
|
if display:
|
|
2135
|
-
s =
|
|
2136
|
-
|
|
2178
|
+
s = (
|
|
2179
|
+
f"{'+' if stmt_taken else ' '} {addr:x}:{i:02d} | "
|
|
2180
|
+
f"{stmt.pp_str(arch=self.project.arch, tyenv=irsb.tyenv)} "
|
|
2181
|
+
)
|
|
2137
2182
|
if stmt_taken:
|
|
2138
|
-
s += "IN:
|
|
2183
|
+
s += f"IN: {blade.slice.in_degree((addr, i))}"
|
|
2139
2184
|
print(s)
|
|
2140
2185
|
|
|
2141
2186
|
# the default exit
|
|
@@ -2223,6 +2268,7 @@ class JumpTableResolver(IndirectJumpResolver):
|
|
|
2223
2268
|
load_addr_tmp = None
|
|
2224
2269
|
|
|
2225
2270
|
if isinstance(load_stmt, pyvex.IRStmt.WrTmp):
|
|
2271
|
+
assert isinstance(load_stmt.data, pyvex.IRExpr.Load)
|
|
2226
2272
|
if type(load_stmt.data.addr) is pyvex.IRExpr.RdTmp:
|
|
2227
2273
|
load_addr_tmp = load_stmt.data.addr.tmp
|
|
2228
2274
|
elif type(load_stmt.data.addr) is pyvex.IRExpr.Const:
|
|
@@ -2260,6 +2306,7 @@ class JumpTableResolver(IndirectJumpResolver):
|
|
|
2260
2306
|
|
|
2261
2307
|
if isinstance(load_stmt, pyvex.IRStmt.LoadG) and not isinstance(load_stmt.guard, pyvex.IRExpr.Const):
|
|
2262
2308
|
# LoadG comes with a guard. We should apply this guard to the load expression
|
|
2309
|
+
assert isinstance(load_stmt.guard, pyvex.expr.RdTmp)
|
|
2263
2310
|
guard_tmp = load_stmt.guard.tmp
|
|
2264
2311
|
guard = state.scratch.temps[guard_tmp] != 0
|
|
2265
2312
|
try:
|
|
@@ -78,7 +78,7 @@ class X86ElfPicPltResolver(IndirectJumpResolver):
|
|
|
78
78
|
state = cfg._initial_state.copy() if cfg._initial_state is not None else self.project.factory.blank_state()
|
|
79
79
|
state.regs.ebx = got_addr
|
|
80
80
|
|
|
81
|
-
successors = self.project.factory.default_engine.process(state, block, force_addr=addr)
|
|
81
|
+
successors = self.project.factory.default_engine.process(state, block=block, force_addr=addr)
|
|
82
82
|
|
|
83
83
|
if len(successors.flat_successors) != 1:
|
|
84
84
|
return False, []
|
|
@@ -5,12 +5,12 @@ from .dep_nodes import DepNodeTypes, BaseDepNode, VarDepNode, MemDepNode, Consta
|
|
|
5
5
|
|
|
6
6
|
|
|
7
7
|
__all__ = (
|
|
8
|
+
"BaseDepNode",
|
|
9
|
+
"ConstantDepNode",
|
|
8
10
|
"DataDependencyGraphAnalysis",
|
|
9
11
|
"DepNodeTypes",
|
|
10
|
-
"BaseDepNode",
|
|
11
|
-
"VarDepNode",
|
|
12
12
|
"MemDepNode",
|
|
13
|
-
"ConstantDepNode",
|
|
14
|
-
"TmpDepNode",
|
|
15
13
|
"RegDepNode",
|
|
14
|
+
"TmpDepNode",
|
|
15
|
+
"VarDepNode",
|
|
16
16
|
)
|
angr/analyses/datagraph_meta.py
CHANGED
|
@@ -51,7 +51,7 @@ class DataGraphMeta:
|
|
|
51
51
|
pp = []
|
|
52
52
|
for stmt in e:
|
|
53
53
|
# true case is a SimProcedure
|
|
54
|
-
s = "(0x
|
|
54
|
+
s = f"(0x{stmt[0]:x}, {stmt[1]})" if imarks is False or stmt[1] == -1 else f"[0x{self._imarks[stmt]:x}]"
|
|
55
55
|
pp.append(s)
|
|
56
56
|
|
|
57
57
|
print(pp[0] + " -> " + pp[1] + " : " + str(data))
|