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
|
@@ -7,10 +7,9 @@ import logging
|
|
|
7
7
|
import pyvex
|
|
8
8
|
import claripy
|
|
9
9
|
|
|
10
|
-
from angr.storage.memory_mixins.paged_memory.pages.multi_values import MultiValues
|
|
11
|
-
from angr.engines.light import
|
|
10
|
+
from angr.storage.memory_mixins.paged_memory.pages.multi_values import MultiValues, mv_is_bv
|
|
11
|
+
from angr.engines.light import SimEngineNostmtVEX, SpOffset
|
|
12
12
|
from angr.engines.vex.claripy.datalayer import value as claripy_value
|
|
13
|
-
from angr.engines.vex.claripy.irop import operations as vex_operations
|
|
14
13
|
from angr.errors import SimEngineError, SimMemoryMissingError
|
|
15
14
|
from angr.utils.constants import DEFAULT_STATEMENT
|
|
16
15
|
from angr.knowledge_plugins.key_definitions.live_definitions import Definition, LiveDefinitions
|
|
@@ -29,36 +28,43 @@ if TYPE_CHECKING:
|
|
|
29
28
|
|
|
30
29
|
l = logging.getLogger(name=__name__)
|
|
31
30
|
|
|
31
|
+
unop_handler = SimEngineNostmtVEX[
|
|
32
|
+
ReachingDefinitionsState, MultiValues[claripy.ast.BV | claripy.ast.FP], ReachingDefinitionsState
|
|
33
|
+
].unop_handler
|
|
34
|
+
binop_handler = SimEngineNostmtVEX[
|
|
35
|
+
ReachingDefinitionsState, MultiValues[claripy.ast.BV | claripy.ast.FP], ReachingDefinitionsState
|
|
36
|
+
].binop_handler
|
|
37
|
+
|
|
32
38
|
|
|
33
39
|
class SimEngineRDVEX(
|
|
34
|
-
|
|
35
|
-
|
|
40
|
+
SimEngineNostmtVEX[
|
|
41
|
+
ReachingDefinitionsState, MultiValues[claripy.ast.BV | claripy.ast.FP], ReachingDefinitionsState
|
|
42
|
+
],
|
|
36
43
|
): # pylint:disable=abstract-method
|
|
37
44
|
"""
|
|
38
45
|
Implements the VEX execution engine for reaching definition analysis.
|
|
39
46
|
"""
|
|
40
47
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
self.project = project
|
|
46
|
-
self.functions: FunctionManager | None = functions
|
|
47
|
-
self._function_handler: FunctionHandler | None = function_handler
|
|
48
|
+
def __init__(self, project, function_handler: FunctionHandler, functions: FunctionManager):
|
|
49
|
+
super().__init__(project)
|
|
50
|
+
self.functions = functions
|
|
51
|
+
self._function_handler = function_handler
|
|
48
52
|
self._visited_blocks = None
|
|
49
53
|
self._dep_graph = None
|
|
50
54
|
|
|
51
55
|
self.state: ReachingDefinitionsState
|
|
52
56
|
|
|
53
|
-
def process(
|
|
57
|
+
def process(
|
|
58
|
+
self, state, *, block=None, fail_fast=False, visited_blocks=None, dep_graph=None, whitelist=None, **kwargs
|
|
59
|
+
):
|
|
54
60
|
self._visited_blocks = visited_blocks
|
|
55
61
|
self._dep_graph = dep_graph
|
|
56
62
|
# we are using a completely different state. Therefore, we directly call our _process() method before
|
|
57
63
|
# SimEngine becomes flexible enough.
|
|
58
64
|
try:
|
|
59
|
-
|
|
65
|
+
return super().process(
|
|
60
66
|
state,
|
|
61
|
-
|
|
67
|
+
whitelist=whitelist,
|
|
62
68
|
block=block,
|
|
63
69
|
)
|
|
64
70
|
except SimEngineError as e:
|
|
@@ -67,16 +73,16 @@ class SimEngineRDVEX(
|
|
|
67
73
|
l.error(e)
|
|
68
74
|
return self.state
|
|
69
75
|
|
|
70
|
-
def _process_block_end(self):
|
|
76
|
+
def _process_block_end(self, stmt_result, whitelist):
|
|
71
77
|
self.stmt_idx = DEFAULT_STATEMENT
|
|
72
78
|
self._set_codeloc()
|
|
73
79
|
if self.block.vex.jumpkind == "Ijk_Call":
|
|
74
80
|
# it has to be a function
|
|
75
|
-
addr = self.
|
|
81
|
+
addr = self._expr_bv(self.block.vex.next)
|
|
76
82
|
self._handle_function(addr)
|
|
77
83
|
elif self.block.vex.jumpkind == "Ijk_Boring":
|
|
78
84
|
# test if the target addr is a function or not
|
|
79
|
-
addr = self.
|
|
85
|
+
addr = self._expr_bv(self.block.vex.next)
|
|
80
86
|
addr_v = addr.one_value()
|
|
81
87
|
if addr_v is not None and addr_v.concrete:
|
|
82
88
|
addr_int = addr_v.concrete_value
|
|
@@ -84,10 +90,28 @@ class SimEngineRDVEX(
|
|
|
84
90
|
# yes it's a jump to a function
|
|
85
91
|
self._handle_function(addr)
|
|
86
92
|
|
|
93
|
+
return self.state
|
|
94
|
+
|
|
87
95
|
#
|
|
88
96
|
# Private methods
|
|
89
97
|
#
|
|
90
98
|
|
|
99
|
+
def _expr_bv(self, expr: pyvex.expr.IRExpr) -> MultiValues[claripy.ast.BV]:
|
|
100
|
+
result = self._expr(expr)
|
|
101
|
+
assert mv_is_bv(result)
|
|
102
|
+
return result
|
|
103
|
+
|
|
104
|
+
def _expr_pair(
|
|
105
|
+
self, arg0: pyvex.expr.IRExpr, arg1: pyvex.expr.IRExpr
|
|
106
|
+
) -> (
|
|
107
|
+
tuple[MultiValues[claripy.ast.BV], MultiValues[claripy.ast.BV]]
|
|
108
|
+
| tuple[MultiValues[claripy.ast.FP], MultiValues[claripy.ast.FP]]
|
|
109
|
+
):
|
|
110
|
+
r0 = self._expr(arg0)
|
|
111
|
+
r1 = self._expr(arg1)
|
|
112
|
+
assert type(r0) is type(r1)
|
|
113
|
+
return r0, r1 # type: ignore
|
|
114
|
+
|
|
91
115
|
def _external_codeloc(self):
|
|
92
116
|
return ExternalCodeLocation(self.state.codeloc.context)
|
|
93
117
|
|
|
@@ -106,34 +130,29 @@ class SimEngineRDVEX(
|
|
|
106
130
|
"""
|
|
107
131
|
return False
|
|
108
132
|
|
|
109
|
-
def _top(self,
|
|
110
|
-
|
|
111
|
-
Because _is_top is always False, this method is only very rarely called.
|
|
112
|
-
Currently, it is only expected to be called from the _handle_Cmp*_v methods that aren't
|
|
113
|
-
implemented in the SimEngineLightVexMixin, which then falls back to returning top
|
|
114
|
-
:param size:
|
|
115
|
-
:return:
|
|
116
|
-
"""
|
|
117
|
-
return MultiValues(self.state.top(size))
|
|
133
|
+
def _top(self, bits) -> MultiValues[claripy.ast.BV | claripy.ast.FP]:
|
|
134
|
+
return MultiValues(self.state.top(bits))
|
|
118
135
|
|
|
119
136
|
#
|
|
120
137
|
# VEX statement handlers
|
|
121
138
|
#
|
|
122
139
|
|
|
123
|
-
def
|
|
140
|
+
def _stmt(self, stmt):
|
|
124
141
|
if self.state.analysis:
|
|
125
142
|
self.state.analysis.stmt_observe(self.stmt_idx, stmt, self.block, self.state, OP_BEFORE)
|
|
126
143
|
self.state.analysis.insn_observe(self.ins_addr, stmt, self.block, self.state, OP_BEFORE)
|
|
127
144
|
|
|
128
145
|
self._set_codeloc()
|
|
129
|
-
super().
|
|
146
|
+
result = super()._stmt(stmt)
|
|
130
147
|
|
|
131
148
|
if self.state.analysis:
|
|
132
149
|
self.state.analysis.stmt_observe(self.stmt_idx, stmt, self.block, self.state, OP_AFTER)
|
|
133
150
|
self.state.analysis.insn_observe(self.ins_addr, stmt, self.block, self.state, OP_AFTER)
|
|
134
151
|
|
|
135
|
-
|
|
136
|
-
|
|
152
|
+
return result
|
|
153
|
+
|
|
154
|
+
def _handle_stmt_WrTmp(self, stmt):
|
|
155
|
+
data = self._expr(stmt.data)
|
|
137
156
|
|
|
138
157
|
tmp_atom = Tmp(stmt.tmp, self.tyenv.sizeof(stmt.tmp) // self.arch.byte_width)
|
|
139
158
|
# if len(data.values) == 1 and 0 in data.values:
|
|
@@ -151,15 +170,10 @@ class SimEngineRDVEX(
|
|
|
151
170
|
data,
|
|
152
171
|
)
|
|
153
172
|
|
|
154
|
-
def _handle_WrTmpData(self, tmp: int, data):
|
|
155
|
-
super()._handle_WrTmpData(tmp, data)
|
|
156
|
-
self.state.kill_and_add_definition(Tmp(tmp, self.tyenv.sizeof(tmp)), self.tmps[tmp])
|
|
157
|
-
|
|
158
173
|
# e.g. PUT(rsp) = t2, t2 might include multiple values
|
|
159
|
-
def
|
|
160
|
-
reg_offset: int = stmt.offset
|
|
174
|
+
def _handle_stmt_Put(self, stmt):
|
|
161
175
|
size: int = stmt.data.result_size(self.tyenv) // 8
|
|
162
|
-
reg = Register(
|
|
176
|
+
reg = Register(stmt.offset, size, self.arch)
|
|
163
177
|
data = self._expr(stmt.data)
|
|
164
178
|
|
|
165
179
|
# special handling for references to heap or stack variables
|
|
@@ -174,16 +188,16 @@ class SimEngineRDVEX(
|
|
|
174
188
|
if stack_offset is not None:
|
|
175
189
|
self.state.add_stack_use(stack_offset, 1)
|
|
176
190
|
|
|
177
|
-
if self.state.exit_observed and
|
|
191
|
+
if self.state.exit_observed and stmt.offset == self.arch.sp_offset:
|
|
178
192
|
return
|
|
179
193
|
self.state.kill_and_add_definition(reg, data)
|
|
180
194
|
|
|
181
|
-
def
|
|
195
|
+
def _handle_stmt_PutI(self, stmt):
|
|
182
196
|
pass
|
|
183
197
|
|
|
184
198
|
# e.g. STle(t6) = t21, t6 and/or t21 might include multiple values
|
|
185
|
-
def
|
|
186
|
-
addr = self.
|
|
199
|
+
def _handle_stmt_Store(self, stmt):
|
|
200
|
+
addr = self._expr_bv(stmt.addr)
|
|
187
201
|
size = stmt.data.result_size(self.tyenv) // 8
|
|
188
202
|
data = self._expr(stmt.data)
|
|
189
203
|
|
|
@@ -191,23 +205,23 @@ class SimEngineRDVEX(
|
|
|
191
205
|
addrs = next(iter(addr.values()))
|
|
192
206
|
self._store_core(addrs, size, data, endness=stmt.endness)
|
|
193
207
|
|
|
194
|
-
def
|
|
195
|
-
guard = self.
|
|
208
|
+
def _handle_stmt_StoreG(self, stmt):
|
|
209
|
+
guard = self._expr_bv(stmt.guard)
|
|
196
210
|
guard_v = guard.one_value()
|
|
197
211
|
|
|
198
|
-
if claripy.is_true(guard_v):
|
|
199
|
-
addr = self.
|
|
212
|
+
if guard_v is not None and claripy.is_true(guard_v != 0):
|
|
213
|
+
addr = self._expr_bv(stmt.addr)
|
|
200
214
|
if addr.count() == 1:
|
|
201
215
|
addrs = next(iter(addr.values()))
|
|
202
216
|
size = stmt.data.result_size(self.tyenv) // 8
|
|
203
217
|
data = self._expr(stmt.data)
|
|
204
218
|
self._store_core(addrs, size, data)
|
|
205
|
-
elif claripy.is_false(guard_v):
|
|
219
|
+
elif guard_v is not None and claripy.is_false(guard_v != 0):
|
|
206
220
|
pass
|
|
207
221
|
else:
|
|
208
222
|
# guard.data == {True, False}
|
|
209
223
|
# get current data
|
|
210
|
-
addr = self.
|
|
224
|
+
addr = self._expr_bv(stmt.addr)
|
|
211
225
|
if addr.count() == 1:
|
|
212
226
|
addrs = next(iter(addr.values()))
|
|
213
227
|
size = stmt.data.result_size(self.tyenv) // 8
|
|
@@ -270,20 +284,20 @@ class SimEngineRDVEX(
|
|
|
270
284
|
# with same index and same size
|
|
271
285
|
self.state.kill_and_add_definition(atom, data, tags=tags, endness=endness)
|
|
272
286
|
|
|
273
|
-
def
|
|
274
|
-
guard = self.
|
|
287
|
+
def _handle_stmt_LoadG(self, stmt):
|
|
288
|
+
guard = self._expr_bv(stmt.guard)
|
|
275
289
|
guard_v = guard.one_value()
|
|
276
290
|
|
|
277
|
-
if claripy.is_true(guard_v):
|
|
291
|
+
if guard_v is not None and claripy.is_true(guard_v != 0):
|
|
278
292
|
# FIXME: full conversion support
|
|
279
293
|
if stmt.cvt.find("Ident") < 0:
|
|
280
294
|
l.warning("Unsupported conversion %s in LoadG.", stmt.cvt)
|
|
281
295
|
load_expr = pyvex.expr.Load(stmt.end, stmt.cvt_types[1], stmt.addr)
|
|
282
296
|
wr_tmp_stmt = pyvex.stmt.WrTmp(stmt.dst, load_expr)
|
|
283
|
-
self.
|
|
284
|
-
elif claripy.is_false(guard_v):
|
|
297
|
+
self._handle_stmt_WrTmp(wr_tmp_stmt)
|
|
298
|
+
elif guard_v is not None and claripy.is_false(guard_v != 0):
|
|
285
299
|
wr_tmp_stmt = pyvex.stmt.WrTmp(stmt.dst, stmt.alt)
|
|
286
|
-
self.
|
|
300
|
+
self._handle_stmt_WrTmp(wr_tmp_stmt)
|
|
287
301
|
else:
|
|
288
302
|
if stmt.cvt.find("Ident") < 0:
|
|
289
303
|
l.warning("Unsupported conversion %s in LoadG.", stmt.cvt)
|
|
@@ -293,9 +307,9 @@ class SimEngineRDVEX(
|
|
|
293
307
|
alt_v = self._expr(stmt.alt)
|
|
294
308
|
|
|
295
309
|
data = load_expr_v.merge(alt_v)
|
|
296
|
-
self.
|
|
310
|
+
self.state.kill_and_add_definition(Tmp(stmt.dst, self.tyenv.sizeof(stmt.dst)), data)
|
|
297
311
|
|
|
298
|
-
def
|
|
312
|
+
def _handle_stmt_Exit(self, stmt):
|
|
299
313
|
_ = self._expr(stmt.guard)
|
|
300
314
|
target = stmt.dst.value
|
|
301
315
|
self.state.mark_guard(target)
|
|
@@ -305,7 +319,6 @@ class SimEngineRDVEX(
|
|
|
305
319
|
self.stmt_idx,
|
|
306
320
|
self.block,
|
|
307
321
|
self.state,
|
|
308
|
-
node_idx=self.block.block_idx if hasattr(self.block, "block_idx") else None,
|
|
309
322
|
)
|
|
310
323
|
if (
|
|
311
324
|
self.block.instruction_addrs
|
|
@@ -314,16 +327,16 @@ class SimEngineRDVEX(
|
|
|
314
327
|
):
|
|
315
328
|
self.state.exit_observed = True
|
|
316
329
|
|
|
317
|
-
def
|
|
330
|
+
def _handle_stmt_IMark(self, stmt):
|
|
318
331
|
pass
|
|
319
332
|
|
|
320
|
-
def
|
|
333
|
+
def _handle_stmt_AbiHint(self, stmt):
|
|
321
334
|
pass
|
|
322
335
|
|
|
323
|
-
def
|
|
336
|
+
def _handle_stmt_LLSC(self, stmt):
|
|
324
337
|
if stmt.storedata is None:
|
|
325
338
|
# load-link
|
|
326
|
-
addr = self.
|
|
339
|
+
addr = self._expr_bv(stmt.addr)
|
|
327
340
|
if addr.count() == 1:
|
|
328
341
|
addrs = next(iter(addr.values()))
|
|
329
342
|
size = self.tyenv.sizeof(stmt.result) // self.arch.byte_width
|
|
@@ -336,12 +349,13 @@ class SimEngineRDVEX(
|
|
|
336
349
|
else:
|
|
337
350
|
# store-conditional
|
|
338
351
|
storedata = self._expr(stmt.storedata)
|
|
339
|
-
addr = self.
|
|
352
|
+
addr = self._expr_bv(stmt.addr)
|
|
340
353
|
if addr.count() == 1:
|
|
341
354
|
addrs = next(iter(addr.values()))
|
|
342
|
-
if isinstance(stmt.storedata, pyvex.
|
|
355
|
+
if isinstance(stmt.storedata, pyvex.expr.Const):
|
|
343
356
|
size = stmt.storedata.con.size // self.arch.byte_width
|
|
344
357
|
else:
|
|
358
|
+
assert isinstance(stmt.storedata, pyvex.expr.RdTmp)
|
|
345
359
|
size = self.tyenv.sizeof(stmt.storedata.tmp) // self.arch.byte_width
|
|
346
360
|
|
|
347
361
|
self._store_core(addrs, size, storedata)
|
|
@@ -355,32 +369,21 @@ class SimEngineRDVEX(
|
|
|
355
369
|
# VEX expression handlers
|
|
356
370
|
#
|
|
357
371
|
|
|
358
|
-
def
|
|
359
|
-
|
|
360
|
-
if data is None:
|
|
361
|
-
bits = expr.result_size(self.tyenv)
|
|
362
|
-
top = self.state.top(bits)
|
|
363
|
-
data = MultiValues(top)
|
|
364
|
-
return data
|
|
372
|
+
def _handle_expr_RdTmp(self, expr: pyvex.expr.RdTmp):
|
|
373
|
+
self.state.add_tmp_use(expr.tmp)
|
|
365
374
|
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
self.state.add_tmp_use(tmp)
|
|
370
|
-
|
|
371
|
-
if tmp in self.tmps:
|
|
372
|
-
return self.tmps[tmp]
|
|
373
|
-
return None
|
|
375
|
+
if expr.tmp in self.tmps:
|
|
376
|
+
return self.tmps[expr.tmp]
|
|
377
|
+
return self._top(pyvex.get_type_size(self.tyenv.lookup(expr.tmp)))
|
|
374
378
|
|
|
375
379
|
# e.g. t0 = GET:I64(rsp), rsp might be defined multiple times
|
|
376
|
-
def
|
|
377
|
-
reg_offset: int = expr.offset
|
|
380
|
+
def _handle_expr_Get(self, expr: pyvex.expr.Get):
|
|
378
381
|
bits: int = expr.result_size(self.tyenv)
|
|
379
382
|
size: int = bits // self.arch.byte_width
|
|
380
383
|
|
|
381
|
-
reg_atom = Register(
|
|
384
|
+
reg_atom = Register(expr.offset, size, self.arch)
|
|
382
385
|
try:
|
|
383
|
-
values: MultiValues = self.state.registers.load(
|
|
386
|
+
values: MultiValues = self.state.registers.load(expr.offset, size=size)
|
|
384
387
|
except SimMemoryMissingError:
|
|
385
388
|
top = self.state.top(size * self.arch.byte_width)
|
|
386
389
|
# annotate it
|
|
@@ -389,7 +392,7 @@ class SimEngineRDVEX(
|
|
|
389
392
|
# write it to registers
|
|
390
393
|
self.state.kill_and_add_definition(reg_atom, values, override_codeloc=self._external_codeloc())
|
|
391
394
|
|
|
392
|
-
current_defs: Iterable[Definition] | None = None
|
|
395
|
+
current_defs: Iterable[Definition[Atom]] | None = None
|
|
393
396
|
for vs in values.values():
|
|
394
397
|
for v in vs:
|
|
395
398
|
if current_defs is None:
|
|
@@ -397,32 +400,24 @@ class SimEngineRDVEX(
|
|
|
397
400
|
else:
|
|
398
401
|
current_defs = chain(current_defs, self.state.extract_defs(v))
|
|
399
402
|
|
|
400
|
-
|
|
401
|
-
# no defs can be found. add a fake definition
|
|
402
|
-
mv = self.state.kill_and_add_definition(reg_atom, values, override_codeloc=self._external_codeloc())
|
|
403
|
-
current_defs = set()
|
|
404
|
-
for vs in mv.values():
|
|
405
|
-
for v in vs:
|
|
406
|
-
current_defs |= self.state.extract_defs(v)
|
|
407
|
-
|
|
403
|
+
assert current_defs is not None
|
|
408
404
|
self.state.add_register_use_by_defs(current_defs)
|
|
409
405
|
|
|
410
406
|
return values
|
|
411
407
|
|
|
412
|
-
def
|
|
408
|
+
def _handle_expr_GetI(self, expr) -> MultiValues[claripy.ast.BV | claripy.ast.FP]:
|
|
413
409
|
return MultiValues(self.state.top(expr.result_size(self.tyenv)))
|
|
414
410
|
|
|
415
411
|
# e.g. t27 = LDle:I64(t9), t9 might include multiple values
|
|
416
412
|
# caution: Is also called from StoreG
|
|
417
|
-
def
|
|
418
|
-
addr = self.
|
|
413
|
+
def _handle_expr_Load(self, expr) -> MultiValues[claripy.ast.BV | claripy.ast.FP]:
|
|
414
|
+
addr = self._expr_bv(expr.addr)
|
|
419
415
|
bits = expr.result_size(self.tyenv)
|
|
420
416
|
size = bits // self.arch.byte_width
|
|
421
417
|
|
|
422
418
|
# convert addr from MultiValues to a list of valid addresses
|
|
423
|
-
if addr.
|
|
424
|
-
|
|
425
|
-
return self._load_core(addrs, size, expr.endness)
|
|
419
|
+
if (one_addr := addr.one_value()) is not None:
|
|
420
|
+
return self._load_core([one_addr], size, expr.endness)
|
|
426
421
|
|
|
427
422
|
top = self.state.top(bits)
|
|
428
423
|
# annotate it
|
|
@@ -433,7 +428,9 @@ class SimEngineRDVEX(
|
|
|
433
428
|
self.state.add_memory_use_by_def(def_)
|
|
434
429
|
return MultiValues(top)
|
|
435
430
|
|
|
436
|
-
def _load_core(
|
|
431
|
+
def _load_core(
|
|
432
|
+
self, addrs: Iterable[claripy.ast.BV], size: int, endness: str
|
|
433
|
+
) -> MultiValues[claripy.ast.BV | claripy.ast.FP]:
|
|
437
434
|
result: MultiValues | None = None
|
|
438
435
|
# we may get more than one stack addrs with the same value but different annotations (because they are defined
|
|
439
436
|
# at different locations). only load them once.
|
|
@@ -506,7 +503,7 @@ class SimEngineRDVEX(
|
|
|
506
503
|
return result
|
|
507
504
|
|
|
508
505
|
# CAUTION: experimental
|
|
509
|
-
def
|
|
506
|
+
def _handle_expr_ITE(self, expr):
|
|
510
507
|
cond = self._expr(expr.cond)
|
|
511
508
|
cond_v = cond.one_value()
|
|
512
509
|
iftrue = self._expr(expr.iftrue)
|
|
@@ -522,51 +519,40 @@ class SimEngineRDVEX(
|
|
|
522
519
|
# Unary operation handlers
|
|
523
520
|
#
|
|
524
521
|
|
|
525
|
-
def
|
|
522
|
+
def _handle_expr_Const(self, expr):
|
|
526
523
|
clrp = claripy_value(expr.con.type, expr.con.value)
|
|
527
524
|
self.state.mark_const(expr.con.value, len(clrp) // 8)
|
|
528
525
|
return MultiValues(clrp)
|
|
529
526
|
|
|
530
|
-
def
|
|
531
|
-
|
|
532
|
-
bits = int(simop.op_attrs["to_size"])
|
|
533
|
-
arg_0 = self._expr(expr.args[0])
|
|
527
|
+
def _handle_conversion(self, from_size, to_size, signed, operand) -> MultiValues[claripy.ast.BV | claripy.ast.FP]:
|
|
528
|
+
arg_0 = self._expr_bv(operand)
|
|
534
529
|
|
|
535
530
|
# if there are multiple values with only one offset, we apply conversion to each one of them
|
|
536
531
|
# otherwise, we return a TOP
|
|
537
532
|
|
|
538
533
|
if arg_0.count() == 1:
|
|
539
534
|
# extension, extract, or doing nothing
|
|
540
|
-
data = set()
|
|
535
|
+
data: set[claripy.ast.BV | claripy.ast.FP] = set()
|
|
541
536
|
for v in next(iter(arg_0.values())):
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
data.add(v.val_to_bv(bits))
|
|
537
|
+
assert v.size() == from_size
|
|
538
|
+
if to_size > from_size:
|
|
539
|
+
if signed:
|
|
540
|
+
data.add(v.sign_extend(to_size - from_size))
|
|
547
541
|
else:
|
|
548
|
-
data.add(v
|
|
549
|
-
|
|
542
|
+
data.add(v.zero_extend(to_size - from_size))
|
|
543
|
+
else:
|
|
544
|
+
data.add(v[to_size - 1 : 0])
|
|
545
|
+
r = MultiValues({next(iter(arg_0.keys())): data})
|
|
550
546
|
|
|
551
547
|
else:
|
|
552
|
-
r =
|
|
548
|
+
r = self._top(to_size)
|
|
553
549
|
|
|
554
550
|
return r
|
|
555
551
|
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
expr_0 = self._expr(arg0)
|
|
559
|
-
|
|
560
|
-
e0 = expr_0.one_value()
|
|
561
|
-
|
|
562
|
-
if e0 is not None and not e0.symbolic:
|
|
563
|
-
return MultiValues(claripy.BVV(1, 1) if e0.concrete_value != 1 else claripy.BVV(0, 1))
|
|
564
|
-
|
|
565
|
-
return MultiValues(self.state.top(1))
|
|
566
|
-
|
|
567
|
-
def _handle_Not(self, expr):
|
|
552
|
+
@unop_handler
|
|
553
|
+
def _handle_unop_Not(self, expr):
|
|
568
554
|
arg0 = expr.args[0]
|
|
569
|
-
expr_0 = self.
|
|
555
|
+
expr_0 = self._expr_bv(arg0)
|
|
570
556
|
bits = expr.result_size(self.tyenv)
|
|
571
557
|
|
|
572
558
|
e0 = expr_0.one_value()
|
|
@@ -576,14 +562,16 @@ class SimEngineRDVEX(
|
|
|
576
562
|
|
|
577
563
|
return MultiValues(self.state.top(bits))
|
|
578
564
|
|
|
579
|
-
|
|
565
|
+
@unop_handler
|
|
566
|
+
def _handle_unop_Clz(self, expr):
|
|
580
567
|
arg0 = expr.args[0]
|
|
581
568
|
_ = self._expr(arg0)
|
|
582
569
|
bits = expr.result_size(self.tyenv)
|
|
583
570
|
# Need to actually implement this later
|
|
584
571
|
return MultiValues(self.state.top(bits))
|
|
585
572
|
|
|
586
|
-
|
|
573
|
+
@unop_handler
|
|
574
|
+
def _handle_unop_Ctz(self, expr):
|
|
587
575
|
arg0 = expr.args[0]
|
|
588
576
|
_ = self._expr(arg0)
|
|
589
577
|
bits = expr.result_size(self.tyenv)
|
|
@@ -593,29 +581,30 @@ class SimEngineRDVEX(
|
|
|
593
581
|
#
|
|
594
582
|
# Binary operation handlers
|
|
595
583
|
#
|
|
596
|
-
|
|
584
|
+
@binop_handler
|
|
585
|
+
def _handle_binop_ExpCmpNE64(self, expr):
|
|
597
586
|
_, _ = self._expr(expr.args[0]), self._expr(expr.args[1])
|
|
598
587
|
bits = expr.result_size(self.tyenv)
|
|
599
588
|
# Need to actually implement this later
|
|
600
589
|
return MultiValues(self.state.top(bits))
|
|
601
590
|
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
return MultiValues(self.state.top(bits))
|
|
591
|
+
@binop_handler
|
|
592
|
+
def _handle_binop_16HLto32(self, expr):
|
|
593
|
+
expr0, expr1 = self._expr_bv(expr.args[0]), self._expr_bv(expr.args[1])
|
|
594
|
+
return expr0.concat(expr1)
|
|
607
595
|
|
|
608
|
-
|
|
609
|
-
|
|
596
|
+
@binop_handler
|
|
597
|
+
def _handle_binop_Add(self, expr):
|
|
598
|
+
expr0, expr1 = self._expr_bv(expr.args[0]), self._expr_bv(expr.args[1])
|
|
610
599
|
bits = expr.result_size(self.tyenv)
|
|
611
600
|
|
|
612
601
|
r = None
|
|
613
602
|
expr0_v = expr0.one_value()
|
|
614
603
|
expr1_v = expr1.one_value()
|
|
615
604
|
|
|
616
|
-
if expr0_v is None and expr1_v is None:
|
|
617
|
-
#
|
|
618
|
-
r = MultiValues(
|
|
605
|
+
if expr0_v is not None and expr1_v is not None:
|
|
606
|
+
# adding two single values together
|
|
607
|
+
r = MultiValues(expr0_v + expr1_v)
|
|
619
608
|
elif expr0_v is None and expr1_v is not None:
|
|
620
609
|
# adding a single value to a multivalue
|
|
621
610
|
if expr0.count() == 1 and 0 in expr0:
|
|
@@ -627,25 +616,26 @@ class SimEngineRDVEX(
|
|
|
627
616
|
vs = {expr0_v + v.sign_extend(expr0_v.size() - v.size()) for v in expr1[0]}
|
|
628
617
|
r = MultiValues(offset_to_values={0: vs})
|
|
629
618
|
else:
|
|
630
|
-
#
|
|
631
|
-
r = MultiValues(
|
|
619
|
+
# we do not support addition between two real multivalues
|
|
620
|
+
r = MultiValues(self.state.top(bits))
|
|
632
621
|
|
|
633
622
|
if r is None:
|
|
634
623
|
r = MultiValues(self.state.top(bits))
|
|
635
624
|
|
|
636
625
|
return r
|
|
637
626
|
|
|
638
|
-
|
|
639
|
-
|
|
627
|
+
@binop_handler
|
|
628
|
+
def _handle_binop_Sub(self, expr):
|
|
629
|
+
expr0, expr1 = self._expr_bv(expr.args[0]), self._expr_bv(expr.args[1])
|
|
640
630
|
bits = expr.result_size(self.tyenv)
|
|
641
631
|
|
|
642
632
|
r = None
|
|
643
633
|
expr0_v = expr0.one_value()
|
|
644
634
|
expr1_v = expr1.one_value()
|
|
645
635
|
|
|
646
|
-
if expr0_v is None and expr1_v is None:
|
|
647
|
-
#
|
|
648
|
-
r = MultiValues(
|
|
636
|
+
if expr0_v is not None and expr1_v is not None:
|
|
637
|
+
# subtracting a single value from another single value
|
|
638
|
+
r = MultiValues(expr0_v - expr1_v)
|
|
649
639
|
elif expr0_v is None and expr1_v is not None:
|
|
650
640
|
# subtracting a single value from a multivalue
|
|
651
641
|
if expr0.count() == 1 and 0 in expr0:
|
|
@@ -657,16 +647,17 @@ class SimEngineRDVEX(
|
|
|
657
647
|
vs = {expr0_v - v for v in expr1[0]}
|
|
658
648
|
r = MultiValues(offset_to_values={0: vs})
|
|
659
649
|
else:
|
|
660
|
-
#
|
|
661
|
-
r = MultiValues(
|
|
650
|
+
# we do not support addition between two real multivalues
|
|
651
|
+
r = MultiValues(self.state.top(bits))
|
|
662
652
|
|
|
663
653
|
if r is None:
|
|
664
654
|
r = MultiValues(self.state.top(bits))
|
|
665
655
|
|
|
666
656
|
return r
|
|
667
657
|
|
|
668
|
-
|
|
669
|
-
|
|
658
|
+
@binop_handler
|
|
659
|
+
def _handle_binop_Mul(self, expr):
|
|
660
|
+
expr0, expr1 = self._expr_pair(expr.args[0], expr.args[1])
|
|
670
661
|
bits = expr.result_size(self.tyenv)
|
|
671
662
|
|
|
672
663
|
r = None
|
|
@@ -679,59 +670,64 @@ class SimEngineRDVEX(
|
|
|
679
670
|
elif expr0_v is None and expr1_v is not None:
|
|
680
671
|
# multiplying a single value to a multivalue
|
|
681
672
|
if expr0.count() == 1 and 0 in expr0:
|
|
682
|
-
vs = {v * expr1_v for v in expr0[0]}
|
|
673
|
+
vs = {v * expr1_v for v in expr0[0]} # type: ignore
|
|
683
674
|
r = MultiValues(offset_to_values={0: vs})
|
|
684
675
|
elif expr0_v is not None and expr1_v is None:
|
|
685
676
|
# multiplying a single value to a multivalue
|
|
686
677
|
if expr1.count() == 1 and 0 in expr1:
|
|
687
|
-
vs = {v * expr0_v for v in expr1[0]}
|
|
678
|
+
vs = {v * expr0_v for v in expr1[0]} # type: ignore
|
|
688
679
|
r = MultiValues(offset_to_values={0: vs})
|
|
689
680
|
else:
|
|
690
681
|
# multiplying two single values together
|
|
691
|
-
r = MultiValues(expr0_v * expr1_v)
|
|
682
|
+
r = MultiValues(expr0_v * expr1_v) # type: ignore
|
|
692
683
|
|
|
693
684
|
if r is None:
|
|
694
685
|
r = MultiValues(self.state.top(bits))
|
|
695
686
|
|
|
696
687
|
return r
|
|
697
688
|
|
|
698
|
-
|
|
689
|
+
@binop_handler
|
|
690
|
+
def _handle_binop_Mull(self, expr):
|
|
699
691
|
_, _ = self._expr(expr.args[0]), self._expr(expr.args[1])
|
|
700
692
|
bits = expr.result_size(self.tyenv)
|
|
701
693
|
return MultiValues(self.state.top(bits))
|
|
702
694
|
|
|
703
|
-
|
|
704
|
-
|
|
695
|
+
@binop_handler
|
|
696
|
+
def _handle_binop_Div(self, expr):
|
|
697
|
+
expr0, expr1 = self._expr_pair(expr.args[0], expr.args[1])
|
|
705
698
|
bits = expr.result_size(self.tyenv)
|
|
706
699
|
|
|
707
700
|
r = None
|
|
708
701
|
expr0_v = expr0.one_value()
|
|
709
702
|
expr1_v = expr1.one_value()
|
|
710
703
|
|
|
711
|
-
if expr0_v is None and expr1_v is None:
|
|
712
|
-
|
|
713
|
-
|
|
704
|
+
if expr0_v is not None and expr1_v is not None:
|
|
705
|
+
if expr0_v.concrete and expr1_v.concrete:
|
|
706
|
+
# dividing two single values
|
|
707
|
+
r = (
|
|
708
|
+
MultiValues(self.state.top(bits)) if expr1_v.concrete_value == 0 else MultiValues(expr0_v / expr1_v)
|
|
709
|
+
) # type: ignore
|
|
714
710
|
elif expr0_v is None and expr1_v is not None:
|
|
715
711
|
if expr1_v.concrete and expr1_v.concrete_value == 0:
|
|
716
712
|
r = MultiValues(self.state.top(bits))
|
|
717
713
|
elif expr0.count() == 1 and 0 in expr0:
|
|
718
|
-
vs = {v / expr1_v for v in expr0[0]}
|
|
714
|
+
vs = {v / expr1_v for v in expr0[0]} # type: ignore
|
|
719
715
|
r = MultiValues(offset_to_values={0: vs})
|
|
720
716
|
elif expr0_v is not None and expr1_v is None:
|
|
721
717
|
if expr1.count() == 1 and 0 in expr1:
|
|
722
|
-
vs = {expr0_v / v for v in expr1[0] if (not v.concrete) or v.concrete_value != 0}
|
|
718
|
+
vs = {expr0_v / v for v in expr1[0] if (not v.concrete) or v.concrete_value != 0} # type: ignore
|
|
723
719
|
r = MultiValues(offset_to_values={0: vs})
|
|
724
720
|
else:
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
r = MultiValues(self.state.top(bits)) if expr1_v.concrete_value == 0 else MultiValues(expr0_v / expr1_v)
|
|
721
|
+
# we do not support division between two real multivalues
|
|
722
|
+
r = MultiValues(self.state.top(bits))
|
|
728
723
|
|
|
729
724
|
if r is None:
|
|
730
725
|
r = MultiValues(self.state.top(bits))
|
|
731
726
|
|
|
732
727
|
return r
|
|
733
728
|
|
|
734
|
-
|
|
729
|
+
@binop_handler
|
|
730
|
+
def _handle_binop_DivMod(self, expr):
|
|
735
731
|
_, _ = self._expr(expr.args[0]), self._expr(expr.args[1])
|
|
736
732
|
bits = expr.result_size(self.tyenv)
|
|
737
733
|
|
|
@@ -742,17 +738,19 @@ class SimEngineRDVEX(
|
|
|
742
738
|
bits = expr.result_size(self.tyenv)
|
|
743
739
|
return MultiValues(self.state.top(bits))
|
|
744
740
|
|
|
745
|
-
|
|
746
|
-
|
|
741
|
+
@binop_handler
|
|
742
|
+
def _handle_binop_And(self, expr):
|
|
743
|
+
expr0, expr1 = self._expr_bv(expr.args[0]), self._expr_bv(expr.args[1])
|
|
747
744
|
bits = expr.result_size(self.tyenv)
|
|
748
745
|
|
|
749
746
|
r = None
|
|
750
747
|
expr0_v = expr0.one_value()
|
|
751
748
|
expr1_v = expr1.one_value()
|
|
752
749
|
|
|
753
|
-
if expr0_v is None and expr1_v is None:
|
|
754
|
-
|
|
755
|
-
|
|
750
|
+
if expr0_v is not None and expr1_v is not None:
|
|
751
|
+
if expr0_v.concrete and expr1_v.concrete:
|
|
752
|
+
# bitwise-and two single values together
|
|
753
|
+
r = MultiValues(expr0_v & expr1_v)
|
|
756
754
|
elif expr0_v is None and expr1_v is not None:
|
|
757
755
|
# bitwise-and a single value with a multivalue
|
|
758
756
|
if expr0.count() == 1 and 0 in expr0:
|
|
@@ -764,26 +762,27 @@ class SimEngineRDVEX(
|
|
|
764
762
|
vs = {v & expr0_v for v in expr1[0]}
|
|
765
763
|
r = MultiValues(offset_to_values={0: vs})
|
|
766
764
|
else:
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
r = MultiValues(expr0_v & expr1_v)
|
|
765
|
+
# we do not support addition between two real multivalues
|
|
766
|
+
r = MultiValues(self.state.top(bits))
|
|
770
767
|
|
|
771
768
|
if r is None:
|
|
772
769
|
r = MultiValues(self.state.top(bits))
|
|
773
770
|
|
|
774
771
|
return r
|
|
775
772
|
|
|
776
|
-
|
|
777
|
-
|
|
773
|
+
@binop_handler
|
|
774
|
+
def _handle_binop_Xor(self, expr):
|
|
775
|
+
expr0, expr1 = self._expr_bv(expr.args[0]), self._expr_bv(expr.args[1])
|
|
778
776
|
bits = expr.result_size(self.tyenv)
|
|
779
777
|
|
|
780
778
|
r = None
|
|
781
779
|
expr0_v = expr0.one_value()
|
|
782
780
|
expr1_v = expr1.one_value()
|
|
783
781
|
|
|
784
|
-
if expr0_v is None and expr1_v is None:
|
|
785
|
-
|
|
786
|
-
|
|
782
|
+
if expr0_v is not None and expr1_v is not None:
|
|
783
|
+
if expr0_v.concrete and expr1_v.concrete:
|
|
784
|
+
# bitwise-xor two single values together
|
|
785
|
+
r = MultiValues(expr0_v ^ expr1_v)
|
|
787
786
|
elif expr0_v is None and expr1_v is not None:
|
|
788
787
|
# bitwise-xor a single value with a multivalue
|
|
789
788
|
if expr0.count() == 1 and 0 in expr0:
|
|
@@ -795,26 +794,26 @@ class SimEngineRDVEX(
|
|
|
795
794
|
vs = {v.sign_extend(expr0_v.size() - v.size()) ^ expr0_v for v in expr1[0]}
|
|
796
795
|
r = MultiValues(offset_to_values={0: vs})
|
|
797
796
|
else:
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
r = MultiValues(expr0_v ^ expr1_v)
|
|
797
|
+
# we do not support xor between two real multivalues
|
|
798
|
+
r = MultiValues(self.state.top(bits))
|
|
801
799
|
|
|
802
800
|
if r is None:
|
|
803
801
|
r = MultiValues(self.state.top(bits))
|
|
804
802
|
|
|
805
803
|
return r
|
|
806
804
|
|
|
807
|
-
|
|
808
|
-
|
|
805
|
+
@binop_handler
|
|
806
|
+
def _handle_binop_Or(self, expr):
|
|
807
|
+
expr0, expr1 = self._expr_bv(expr.args[0]), self._expr_bv(expr.args[1])
|
|
809
808
|
bits = expr.result_size(self.tyenv)
|
|
810
809
|
|
|
811
810
|
r = None
|
|
812
811
|
expr0_v = expr0.one_value()
|
|
813
812
|
expr1_v = expr1.one_value()
|
|
814
813
|
|
|
815
|
-
if expr0_v is None and expr1_v is None:
|
|
816
|
-
#
|
|
817
|
-
r = MultiValues(
|
|
814
|
+
if expr0_v is not None and expr1_v is not None:
|
|
815
|
+
# bitwise-and two single values together
|
|
816
|
+
r = MultiValues(expr0_v | expr1_v)
|
|
818
817
|
elif expr0_v is None and expr1_v is not None:
|
|
819
818
|
# bitwise-or a single value with a multivalue
|
|
820
819
|
if expr0.count() == 1 and 0 in expr0:
|
|
@@ -826,37 +825,38 @@ class SimEngineRDVEX(
|
|
|
826
825
|
vs = {v | expr0_v for v in expr1[0]}
|
|
827
826
|
r = MultiValues(offset_to_values={0: vs})
|
|
828
827
|
else:
|
|
829
|
-
#
|
|
830
|
-
r = MultiValues(
|
|
828
|
+
# we do not support or between two real multivalues
|
|
829
|
+
r = MultiValues(self.state.top(bits))
|
|
831
830
|
|
|
832
831
|
if r is None:
|
|
833
832
|
r = MultiValues(self.state.top(bits))
|
|
834
833
|
|
|
835
834
|
return r
|
|
836
835
|
|
|
837
|
-
|
|
838
|
-
|
|
836
|
+
@binop_handler
|
|
837
|
+
def _handle_binop_Sar(self, expr):
|
|
838
|
+
expr0, expr1 = self._expr_bv(expr.args[0]), self._expr_bv(expr.args[1])
|
|
839
839
|
bits = expr.result_size(self.tyenv)
|
|
840
840
|
|
|
841
841
|
r = None
|
|
842
842
|
expr0_v = expr0.one_value()
|
|
843
843
|
expr1_v = expr1.one_value()
|
|
844
844
|
|
|
845
|
-
def _shift_sar(e0, e1):
|
|
845
|
+
def _shift_sar(e0: claripy.ast.BV, e1: claripy.ast.BV):
|
|
846
846
|
# convert e1 to an integer to prevent claripy from complaining "args' lengths must all be equal"
|
|
847
847
|
if e1.symbolic:
|
|
848
848
|
return self.state.top(bits)
|
|
849
|
-
|
|
849
|
+
e1_int = e1.concrete_value
|
|
850
850
|
|
|
851
|
-
if
|
|
851
|
+
if e1_int > bits:
|
|
852
852
|
return claripy.BVV(0, bits)
|
|
853
853
|
|
|
854
|
-
head = claripy.BVV(0, bits) if claripy.is_true(e0 >> bits - 1 == 0) else (1 <<
|
|
855
|
-
return head | (e0 >>
|
|
854
|
+
head = claripy.BVV(0, bits) if claripy.is_true(e0 >> bits - 1 == 0) else (1 << e1_int) - 1 << bits - e1_int
|
|
855
|
+
return head | (e0 >> e1_int)
|
|
856
856
|
|
|
857
|
-
if expr0_v is None and expr1_v is None:
|
|
858
|
-
#
|
|
859
|
-
r = MultiValues(
|
|
857
|
+
if expr0_v is not None and expr1_v is not None:
|
|
858
|
+
# subtracting a single value from another single value
|
|
859
|
+
r = MultiValues(_shift_sar(expr0_v, expr1_v))
|
|
860
860
|
elif expr0_v is None and expr1_v is not None:
|
|
861
861
|
# shifting a single value by a multivalue
|
|
862
862
|
if expr0.count() == 1 and 0 in expr0:
|
|
@@ -868,16 +868,17 @@ class SimEngineRDVEX(
|
|
|
868
868
|
vs = {_shift_sar(expr0_v, v) for v in expr1[0]}
|
|
869
869
|
r = MultiValues(offset_to_values={0: vs})
|
|
870
870
|
else:
|
|
871
|
-
#
|
|
872
|
-
r = MultiValues(
|
|
871
|
+
# we do not support shifting between two real multivalues
|
|
872
|
+
r = MultiValues(self.state.top(bits))
|
|
873
873
|
|
|
874
874
|
if r is None:
|
|
875
875
|
r = MultiValues(self.state.top(bits))
|
|
876
876
|
|
|
877
877
|
return r
|
|
878
878
|
|
|
879
|
-
|
|
880
|
-
|
|
879
|
+
@binop_handler
|
|
880
|
+
def _handle_binop_Shr(self, expr):
|
|
881
|
+
expr0, expr1 = self._expr_bv(expr.args[0]), self._expr_bv(expr.args[1])
|
|
881
882
|
bits = expr.result_size(self.tyenv)
|
|
882
883
|
|
|
883
884
|
r = None
|
|
@@ -916,7 +917,8 @@ class SimEngineRDVEX(
|
|
|
916
917
|
|
|
917
918
|
return r
|
|
918
919
|
|
|
919
|
-
|
|
920
|
+
@binop_handler
|
|
921
|
+
def _handle_binop_Shl(self, expr):
|
|
920
922
|
expr0, expr1 = self._expr(expr.args[0]), self._expr(expr.args[1])
|
|
921
923
|
bits = expr.result_size(self.tyenv)
|
|
922
924
|
|
|
@@ -953,7 +955,8 @@ class SimEngineRDVEX(
|
|
|
953
955
|
|
|
954
956
|
return r
|
|
955
957
|
|
|
956
|
-
|
|
958
|
+
@binop_handler
|
|
959
|
+
def _handle_binop_CmpEQ(self, expr):
|
|
957
960
|
arg0, arg1 = expr.args
|
|
958
961
|
expr_0 = self._expr(arg0)
|
|
959
962
|
expr_1 = self._expr(arg1)
|
|
@@ -970,7 +973,8 @@ class SimEngineRDVEX(
|
|
|
970
973
|
|
|
971
974
|
return MultiValues(self.state.top(1))
|
|
972
975
|
|
|
973
|
-
|
|
976
|
+
@binop_handler
|
|
977
|
+
def _handle_binop_CmpNE(self, expr):
|
|
974
978
|
arg0, arg1 = expr.args
|
|
975
979
|
expr_0 = self._expr(arg0)
|
|
976
980
|
expr_1 = self._expr(arg1)
|
|
@@ -984,67 +988,71 @@ class SimEngineRDVEX(
|
|
|
984
988
|
return MultiValues(claripy.BVV(0, 1))
|
|
985
989
|
return MultiValues(self.state.top(1))
|
|
986
990
|
|
|
987
|
-
|
|
991
|
+
@binop_handler
|
|
992
|
+
def _handle_binop_CmpLT(self, expr):
|
|
988
993
|
arg0, arg1 = expr.args
|
|
989
|
-
expr_0 = self.
|
|
990
|
-
expr_1 = self._expr(arg1)
|
|
994
|
+
expr_0, expr_1 = self._expr_pair(arg0, arg1)
|
|
991
995
|
|
|
992
996
|
e0 = expr_0.one_value()
|
|
993
997
|
e1 = expr_1.one_value()
|
|
994
998
|
if e0 is not None and e1 is not None:
|
|
995
999
|
if not e0.symbolic and not e1.symbolic:
|
|
996
|
-
|
|
1000
|
+
cmp = e0.concrete_value < e1.concrete_value # type: ignore
|
|
1001
|
+
return MultiValues(claripy.BVV(1, 1) if cmp else claripy.BVV(0, 1))
|
|
997
1002
|
if e0 is e1:
|
|
998
1003
|
return MultiValues(claripy.BVV(0, 1))
|
|
999
1004
|
return MultiValues(self.state.top(1))
|
|
1000
1005
|
|
|
1001
|
-
|
|
1006
|
+
@binop_handler
|
|
1007
|
+
def _handle_binop_CmpLE(self, expr):
|
|
1002
1008
|
arg0, arg1 = expr.args
|
|
1003
|
-
expr_0 = self.
|
|
1004
|
-
expr_1 = self._expr(arg1)
|
|
1009
|
+
expr_0, expr_1 = self._expr_pair(arg0, arg1)
|
|
1005
1010
|
|
|
1006
1011
|
e0 = expr_0.one_value()
|
|
1007
1012
|
e1 = expr_1.one_value()
|
|
1008
1013
|
if e0 is not None and e1 is not None:
|
|
1009
1014
|
if not e0.symbolic and not e1.symbolic:
|
|
1010
|
-
|
|
1015
|
+
cmp = e0.concrete_value <= e1.concrete_value # type: ignore
|
|
1016
|
+
return MultiValues(claripy.BVV(1, 1) if cmp else claripy.BVV(0, 1))
|
|
1011
1017
|
if e0 is e1:
|
|
1012
1018
|
return MultiValues(claripy.BVV(0, 1))
|
|
1013
1019
|
return MultiValues(self.state.top(1))
|
|
1014
1020
|
|
|
1015
|
-
|
|
1021
|
+
@binop_handler
|
|
1022
|
+
def _handle_binop_CmpGT(self, expr):
|
|
1016
1023
|
arg0, arg1 = expr.args
|
|
1017
|
-
expr_0 = self.
|
|
1018
|
-
expr_1 = self._expr(arg1)
|
|
1024
|
+
expr_0, expr_1 = self._expr_pair(arg0, arg1)
|
|
1019
1025
|
|
|
1020
1026
|
e0 = expr_0.one_value()
|
|
1021
1027
|
e1 = expr_1.one_value()
|
|
1022
1028
|
if e0 is not None and e1 is not None:
|
|
1023
1029
|
if not e0.symbolic and not e1.symbolic:
|
|
1024
|
-
|
|
1030
|
+
cmp = e0.concrete_value > e1.concrete_value # type: ignore
|
|
1031
|
+
return MultiValues(claripy.BVV(1, 1) if cmp else claripy.BVV(0, 1))
|
|
1025
1032
|
if e0 is e1:
|
|
1026
1033
|
return MultiValues(claripy.BVV(0, 1))
|
|
1027
1034
|
return MultiValues(self.state.top(1))
|
|
1028
1035
|
|
|
1029
|
-
|
|
1036
|
+
@binop_handler
|
|
1037
|
+
def _handle_binop_CmpGE(self, expr):
|
|
1030
1038
|
arg0, arg1 = expr.args
|
|
1031
|
-
expr_0 = self.
|
|
1032
|
-
expr_1 = self._expr(arg1)
|
|
1039
|
+
expr_0, expr_1 = self._expr_pair(arg0, arg1)
|
|
1033
1040
|
|
|
1034
1041
|
e0 = expr_0.one_value()
|
|
1035
1042
|
e1 = expr_1.one_value()
|
|
1036
1043
|
if e0 is not None and e1 is not None:
|
|
1037
1044
|
if not e0.symbolic and not e1.symbolic:
|
|
1038
|
-
|
|
1045
|
+
cmp = e0.concrete_value >= e1.concrete_value # type: ignore
|
|
1046
|
+
return MultiValues(claripy.BVV(1, 1) if cmp else claripy.BVV(0, 1))
|
|
1039
1047
|
if e0 is e1:
|
|
1040
1048
|
return MultiValues(claripy.BVV(0, 1))
|
|
1041
1049
|
return MultiValues(self.state.top(1))
|
|
1042
1050
|
|
|
1043
1051
|
# ppc only
|
|
1044
|
-
|
|
1052
|
+
@binop_handler
|
|
1053
|
+
def _handle_binop_CmpORD(self, expr):
|
|
1045
1054
|
arg0, arg1 = expr.args
|
|
1046
|
-
expr_0 = self.
|
|
1047
|
-
expr_1 = self._expr(arg1)
|
|
1055
|
+
expr_0, expr_1 = self._expr_pair(arg0, arg1)
|
|
1048
1056
|
|
|
1049
1057
|
e0 = expr_0.one_value()
|
|
1050
1058
|
e1 = expr_1.one_value()
|
|
@@ -1054,9 +1062,9 @@ class SimEngineRDVEX(
|
|
|
1054
1062
|
if not e0.symbolic and not e1.symbolic:
|
|
1055
1063
|
e0 = e0.concrete_value
|
|
1056
1064
|
e1 = e1.concrete_value
|
|
1057
|
-
if e0 < e1:
|
|
1065
|
+
if e0 < e1: # type: ignore
|
|
1058
1066
|
return MultiValues(claripy.BVV(0x8, bits))
|
|
1059
|
-
if e0 > e1:
|
|
1067
|
+
if e0 > e1: # type: ignore
|
|
1060
1068
|
return MultiValues(claripy.BVV(0x4, bits))
|
|
1061
1069
|
return MultiValues(claripy.BVV(0x2, bits))
|
|
1062
1070
|
if e0 is e1:
|
|
@@ -1064,19 +1072,25 @@ class SimEngineRDVEX(
|
|
|
1064
1072
|
|
|
1065
1073
|
return MultiValues(self.state.top(1))
|
|
1066
1074
|
|
|
1067
|
-
def
|
|
1075
|
+
def _handle_expr_CCall(self, expr) -> MultiValues[claripy.ast.BV | claripy.ast.FP]:
|
|
1068
1076
|
bits = expr.result_size(self.tyenv)
|
|
1069
1077
|
for arg_expr in expr.args:
|
|
1070
1078
|
self._expr(arg_expr)
|
|
1071
1079
|
return MultiValues(self.state.top(bits))
|
|
1072
1080
|
|
|
1081
|
+
def _handle_expr_GSPTR(self, expr):
|
|
1082
|
+
return self._top(expr.result_size(self.tyenv))
|
|
1083
|
+
|
|
1084
|
+
def _handle_expr_VECRET(self, expr):
|
|
1085
|
+
return self._top(expr.result_size(self.tyenv))
|
|
1086
|
+
|
|
1073
1087
|
#
|
|
1074
1088
|
# User defined high level statement handlers
|
|
1075
1089
|
#
|
|
1076
1090
|
|
|
1077
|
-
def _handle_function(self, func_addr: MultiValues | None):
|
|
1091
|
+
def _handle_function(self, func_addr: MultiValues[claripy.ast.BV] | None):
|
|
1078
1092
|
if func_addr is None:
|
|
1079
|
-
func_addr = self.state.top(self.state.arch.bits)
|
|
1093
|
+
func_addr = MultiValues(self.state.top(self.state.arch.bits))
|
|
1080
1094
|
|
|
1081
1095
|
callsite = self.state.codeloc
|
|
1082
1096
|
data = FunctionCallData(
|