angr 9.2.138__py3-none-macosx_11_0_arm64.whl → 9.2.139__py3-none-macosx_11_0_arm64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of angr might be problematic. Click here for more details.
- angr/__init__.py +1 -1
- angr/analyses/calling_convention/fact_collector.py +59 -12
- angr/analyses/calling_convention/utils.py +2 -2
- angr/analyses/cfg/cfg_fast.py +12 -4
- angr/analyses/decompiler/ail_simplifier.py +14 -3
- angr/analyses/decompiler/block_simplifier.py +0 -2
- angr/analyses/decompiler/callsite_maker.py +80 -14
- angr/analyses/decompiler/clinic.py +31 -37
- angr/analyses/decompiler/condition_processor.py +2 -2
- angr/analyses/decompiler/decompiler.py +2 -0
- angr/analyses/decompiler/dephication/rewriting_engine.py +16 -7
- angr/analyses/decompiler/optimization_passes/__init__.py +3 -0
- angr/analyses/decompiler/optimization_passes/condition_constprop.py +149 -0
- angr/analyses/decompiler/optimization_passes/deadblock_remover.py +12 -3
- angr/analyses/decompiler/optimization_passes/inlined_string_transformation_simplifier.py +1 -1
- angr/analyses/decompiler/optimization_passes/optimization_pass.py +5 -2
- angr/analyses/decompiler/optimization_passes/return_duplicator_base.py +15 -7
- angr/analyses/decompiler/optimization_passes/return_duplicator_high.py +7 -10
- angr/analyses/decompiler/peephole_optimizations/eager_eval.py +12 -1
- angr/analyses/decompiler/peephole_optimizations/remove_redundant_conversions.py +61 -25
- angr/analyses/decompiler/peephole_optimizations/remove_redundant_shifts.py +50 -1
- angr/analyses/decompiler/presets/fast.py +2 -0
- angr/analyses/decompiler/presets/full.py +2 -0
- angr/analyses/decompiler/region_simplifiers/region_simplifier.py +4 -0
- angr/analyses/decompiler/ssailification/rewriting_engine.py +20 -2
- angr/analyses/decompiler/ssailification/traversal_engine.py +4 -3
- angr/analyses/decompiler/structured_codegen/c.py +10 -3
- angr/analyses/decompiler/structuring/dream.py +7 -2
- angr/analyses/decompiler/structuring/phoenix.py +101 -49
- angr/analyses/decompiler/structuring/structurer_base.py +85 -36
- angr/analyses/decompiler/structuring/structurer_nodes.py +3 -1
- angr/analyses/deobfuscator/api_obf_finder.py +6 -1
- angr/analyses/deobfuscator/api_obf_type2_finder.py +158 -0
- angr/analyses/s_propagator.py +127 -50
- angr/analyses/s_reaching_definitions/s_rda_view.py +2 -2
- angr/analyses/s_reaching_definitions/s_reaching_definitions.py +3 -1
- angr/analyses/variable_recovery/engine_ail.py +1 -1
- angr/analyses/variable_recovery/engine_base.py +55 -62
- angr/analyses/variable_recovery/engine_vex.py +1 -1
- angr/analyses/variable_recovery/irsb_scanner.py +2 -2
- angr/calling_conventions.py +66 -9
- angr/engines/engine.py +2 -18
- angr/engines/light/engine.py +3 -8
- angr/engines/pcode/emulate.py +2 -2
- angr/engines/pcode/lifter.py +2 -2
- angr/engines/successors.py +1 -8
- angr/engines/vex/lifter.py +2 -2
- angr/engines/vex/light/light.py +2 -2
- angr/knowledge_plugins/cfg/cfg_model.py +3 -2
- angr/knowledge_plugins/labels.py +2 -2
- angr/knowledge_plugins/obfuscations.py +1 -0
- angr/knowledge_plugins/xrefs/xref_manager.py +4 -0
- angr/lib/angr_native.dylib +0 -0
- {angr-9.2.138.dist-info → angr-9.2.139.dist-info}/METADATA +6 -6
- {angr-9.2.138.dist-info → angr-9.2.139.dist-info}/RECORD +59 -57
- {angr-9.2.138.dist-info → angr-9.2.139.dist-info}/LICENSE +0 -0
- {angr-9.2.138.dist-info → angr-9.2.139.dist-info}/WHEEL +0 -0
- {angr-9.2.138.dist-info → angr-9.2.139.dist-info}/entry_points.txt +0 -0
- {angr-9.2.138.dist-info → angr-9.2.139.dist-info}/top_level.txt +0 -0
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
|
-
from typing import Any,
|
|
2
|
+
from typing import Any, Generic, TypeVar, cast
|
|
3
3
|
import contextlib
|
|
4
4
|
import logging
|
|
5
5
|
|
|
@@ -16,8 +16,6 @@ from angr.code_location import CodeLocation
|
|
|
16
16
|
from angr.analyses.typehoon import typevars, typeconsts
|
|
17
17
|
from angr.analyses.typehoon.typevars import TypeVariable, DerivedTypeVariable, AddN, SubN, Load, Store
|
|
18
18
|
|
|
19
|
-
if TYPE_CHECKING:
|
|
20
|
-
from angr.knowledge_plugins.variables.variable_manager import VariableManager
|
|
21
19
|
|
|
22
20
|
#
|
|
23
21
|
# The base engine used in VariableRecoveryFast
|
|
@@ -72,8 +70,6 @@ class SimEngineVRBase(
|
|
|
72
70
|
and storing data.
|
|
73
71
|
"""
|
|
74
72
|
|
|
75
|
-
variable_manager: VariableManager
|
|
76
|
-
|
|
77
73
|
def __init__(self, project, kb):
|
|
78
74
|
super().__init__(project)
|
|
79
75
|
|
|
@@ -86,10 +82,6 @@ class SimEngineVRBase(
|
|
|
86
82
|
return None
|
|
87
83
|
return self.state.function.addr
|
|
88
84
|
|
|
89
|
-
def process(self, state, *args, **kwargs):
|
|
90
|
-
self.variable_manager = state.variable_manager
|
|
91
|
-
super().process(state, *args, **kwargs)
|
|
92
|
-
|
|
93
85
|
def _top(self, bits):
|
|
94
86
|
return RichR(self.state.top(bits))
|
|
95
87
|
|
|
@@ -130,9 +122,9 @@ class SimEngineVRBase(
|
|
|
130
122
|
if abs_offset.op == "__lshift__" and cast(claripy.ast.BV, abs_offset.args[1]).concrete:
|
|
131
123
|
offset = cast(claripy.ast.BV, abs_offset.args[0])
|
|
132
124
|
elem_size = 2 ** cast(claripy.ast.BV, abs_offset.args[1]).concrete_value
|
|
133
|
-
elif abs_offset.op == "__mul__" and abs_offset.args[1].concrete:
|
|
134
|
-
offset = abs_offset.args[0]
|
|
135
|
-
elem_size = abs_offset.args[1].concrete_value
|
|
125
|
+
elif abs_offset.op == "__mul__" and cast(claripy.ast.BV, abs_offset.args[1]).concrete:
|
|
126
|
+
offset = cast(claripy.ast.BV, abs_offset.args[0])
|
|
127
|
+
elem_size = cast(claripy.ast.BV, abs_offset.args[1]).concrete_value
|
|
136
128
|
|
|
137
129
|
if base_addr is not None and offset is not None and elem_size is not None:
|
|
138
130
|
return base_addr, offset, elem_size
|
|
@@ -152,7 +144,7 @@ class SimEngineVRBase(
|
|
|
152
144
|
# extract stack offset
|
|
153
145
|
stack_offset: int | None = self.state.get_stack_offset(data)
|
|
154
146
|
|
|
155
|
-
variable_manager = self.variable_manager[self.func_addr]
|
|
147
|
+
variable_manager = self.state.variable_manager[self.func_addr]
|
|
156
148
|
var_candidates: list[tuple[SimVariable, int]] = variable_manager.find_variables_by_stmt(
|
|
157
149
|
self.block.addr, self.stmt_idx, "memory"
|
|
158
150
|
)
|
|
@@ -190,10 +182,10 @@ class SimEngineVRBase(
|
|
|
190
182
|
stack_offset,
|
|
191
183
|
lea_size,
|
|
192
184
|
base="bp",
|
|
193
|
-
ident=self.variable_manager[self.func_addr].next_variable_ident("stack"),
|
|
185
|
+
ident=self.state.variable_manager[self.func_addr].next_variable_ident("stack"),
|
|
194
186
|
region=self.func_addr,
|
|
195
187
|
)
|
|
196
|
-
self.variable_manager[self.func_addr].add_variable("stack", stack_offset, variable)
|
|
188
|
+
self.state.variable_manager[self.func_addr].add_variable("stack", stack_offset, variable)
|
|
197
189
|
l.debug("Identified a new stack variable %s at %#x.", variable, self.ins_addr)
|
|
198
190
|
existing_vars.append((variable, 0))
|
|
199
191
|
|
|
@@ -212,7 +204,7 @@ class SimEngineVRBase(
|
|
|
212
204
|
# this is probably an address for a global variable
|
|
213
205
|
global_var_addr = data.concrete_value
|
|
214
206
|
|
|
215
|
-
variable_manager = self.variable_manager["global"]
|
|
207
|
+
variable_manager = self.state.variable_manager["global"]
|
|
216
208
|
|
|
217
209
|
# special case for global variables: find existing variable by base address
|
|
218
210
|
existing_vars = [(var, 0) for var in variable_manager.get_global_variables(global_var_addr)]
|
|
@@ -249,7 +241,7 @@ class SimEngineVRBase(
|
|
|
249
241
|
# extract stack offset
|
|
250
242
|
stack_offset: int | None = self.state.get_stack_offset(data)
|
|
251
243
|
|
|
252
|
-
variable_manager = self.variable_manager[self.func_addr]
|
|
244
|
+
variable_manager = self.state.variable_manager[self.func_addr]
|
|
253
245
|
var_candidates: list[tuple[SimVariable, int]] = variable_manager.find_variables_by_stmt(
|
|
254
246
|
self.block.addr,
|
|
255
247
|
self.stmt_idx,
|
|
@@ -265,7 +257,7 @@ class SimEngineVRBase(
|
|
|
265
257
|
elif self.state.is_global_variable_address(data):
|
|
266
258
|
# this is probably an address for a global variable
|
|
267
259
|
global_var_addr = data.concrete_value
|
|
268
|
-
variable_manager = self.variable_manager["global"]
|
|
260
|
+
variable_manager = self.state.variable_manager["global"]
|
|
269
261
|
# special case for global variables: find existing variable by base address
|
|
270
262
|
existing_vars = [(var, 0) for var in variable_manager.get_global_variables(global_var_addr)]
|
|
271
263
|
else:
|
|
@@ -319,9 +311,9 @@ class SimEngineVRBase(
|
|
|
319
311
|
# handle register writes
|
|
320
312
|
|
|
321
313
|
# first check if there is an existing variable for the atom at this location already
|
|
322
|
-
existing_vars: set[tuple[SimVariable, int]] = self.variable_manager[
|
|
323
|
-
self.
|
|
324
|
-
)
|
|
314
|
+
existing_vars: set[tuple[SimVariable, int]] = self.state.variable_manager[
|
|
315
|
+
self.func_addr
|
|
316
|
+
].find_variables_by_atom(self.block.addr, self.stmt_idx, dst)
|
|
325
317
|
if not existing_vars:
|
|
326
318
|
# next check if we are overwriting *part* of an existing variable that is not an input variable
|
|
327
319
|
addr_and_variables = set()
|
|
@@ -334,7 +326,7 @@ class SimEngineVRBase(
|
|
|
334
326
|
addr_and_variables.update(self.state.extract_variables(value))
|
|
335
327
|
except SimMemoryMissingError:
|
|
336
328
|
pass
|
|
337
|
-
input_vars = self.variable_manager[self.func_addr].input_variables()
|
|
329
|
+
input_vars = self.state.variable_manager[self.func_addr].input_variables()
|
|
338
330
|
existing_vars = {
|
|
339
331
|
(av[1], av[0]) for av in addr_and_variables if av[1] not in input_vars and av[1].size > size
|
|
340
332
|
}
|
|
@@ -343,10 +335,10 @@ class SimEngineVRBase(
|
|
|
343
335
|
variable = SimRegisterVariable(
|
|
344
336
|
offset,
|
|
345
337
|
size,
|
|
346
|
-
ident=self.variable_manager[self.func_addr].next_variable_ident("register"),
|
|
338
|
+
ident=self.state.variable_manager[self.func_addr].next_variable_ident("register"),
|
|
347
339
|
region=self.func_addr,
|
|
348
340
|
)
|
|
349
|
-
self.variable_manager[self.func_addr].add_variable("register", offset, variable)
|
|
341
|
+
self.state.variable_manager[self.func_addr].add_variable("register", offset, variable)
|
|
350
342
|
else:
|
|
351
343
|
variable, _ = next(iter(existing_vars))
|
|
352
344
|
|
|
@@ -355,7 +347,7 @@ class SimEngineVRBase(
|
|
|
355
347
|
v = MultiValues(annotated_data)
|
|
356
348
|
self.state.register_region.store(offset, v)
|
|
357
349
|
# register with the variable manager
|
|
358
|
-
self.variable_manager[self.func_addr].write_to(variable, None, codeloc, atom=dst, overwrite=False)
|
|
350
|
+
self.state.variable_manager[self.func_addr].write_to(variable, None, codeloc, atom=dst, overwrite=False)
|
|
359
351
|
|
|
360
352
|
if richr.typevar is not None:
|
|
361
353
|
if not self.state.typevars.has_type_variable_for(variable, codeloc):
|
|
@@ -397,9 +389,9 @@ class SimEngineVRBase(
|
|
|
397
389
|
self._reference(richr, codeloc)
|
|
398
390
|
|
|
399
391
|
# first check if there is an existing variable for the atom at this location already
|
|
400
|
-
existing_vars: set[tuple[SimVariable, int]] = self.variable_manager[
|
|
401
|
-
self.
|
|
402
|
-
)
|
|
392
|
+
existing_vars: set[tuple[SimVariable, int]] = self.state.variable_manager[
|
|
393
|
+
self.func_addr
|
|
394
|
+
].find_variables_by_atom(self.block.addr, self.stmt_idx, dst)
|
|
403
395
|
if not existing_vars:
|
|
404
396
|
# next check if there is already a variable for the vvar ID
|
|
405
397
|
addr_and_variables = set()
|
|
@@ -415,33 +407,33 @@ class SimEngineVRBase(
|
|
|
415
407
|
variable = SimRegisterVariable(
|
|
416
408
|
vvar.reg_offset,
|
|
417
409
|
vvar.size,
|
|
418
|
-
ident=self.variable_manager[self.func_addr].next_variable_ident("register"),
|
|
410
|
+
ident=self.state.variable_manager[self.func_addr].next_variable_ident("register"),
|
|
419
411
|
region=self.func_addr,
|
|
420
412
|
)
|
|
421
|
-
self.variable_manager[self.func_addr].add_variable("register", vvar.reg_offset, variable)
|
|
413
|
+
self.state.variable_manager[self.func_addr].add_variable("register", vvar.reg_offset, variable)
|
|
422
414
|
elif vvar.was_stack:
|
|
423
415
|
variable = SimStackVariable(
|
|
424
416
|
vvar.stack_offset,
|
|
425
417
|
vvar.size,
|
|
426
|
-
ident=self.variable_manager[self.func_addr].next_variable_ident("stack"),
|
|
418
|
+
ident=self.state.variable_manager[self.func_addr].next_variable_ident("stack"),
|
|
427
419
|
region=self.func_addr,
|
|
428
420
|
)
|
|
429
|
-
self.variable_manager[self.func_addr].add_variable("stack", vvar.stack_offset, variable)
|
|
421
|
+
self.state.variable_manager[self.func_addr].add_variable("stack", vvar.stack_offset, variable)
|
|
430
422
|
elif vvar.was_parameter:
|
|
431
423
|
# FIXME: we assume all parameter vvars were registers
|
|
432
424
|
variable = SimRegisterVariable(
|
|
433
425
|
vvar.reg_offset,
|
|
434
426
|
vvar.size,
|
|
435
|
-
ident=self.variable_manager[self.func_addr].next_variable_ident("register"),
|
|
427
|
+
ident=self.state.variable_manager[self.func_addr].next_variable_ident("register"),
|
|
436
428
|
region=self.func_addr,
|
|
437
429
|
)
|
|
438
|
-
self.variable_manager[self.func_addr].add_variable("register", vvar.oident, variable)
|
|
430
|
+
self.state.variable_manager[self.func_addr].add_variable("register", vvar.oident, variable)
|
|
439
431
|
elif vvar.was_tmp:
|
|
440
432
|
# FIXME: we treat all tmp vvars as registers
|
|
441
433
|
variable = SimRegisterVariable(
|
|
442
434
|
4096 + vvar.tmp_idx,
|
|
443
435
|
vvar.size,
|
|
444
|
-
ident=self.variable_manager[self.func_addr].next_variable_ident("register"),
|
|
436
|
+
ident=self.state.variable_manager[self.func_addr].next_variable_ident("register"),
|
|
445
437
|
region=self.func_addr,
|
|
446
438
|
)
|
|
447
439
|
else:
|
|
@@ -452,7 +444,7 @@ class SimEngineVRBase(
|
|
|
452
444
|
# FIXME: The offset does not have to be 0
|
|
453
445
|
annotated_data = self.state.annotate_with_variables(data, [(0, variable)])
|
|
454
446
|
self.vvar_region[vvar_id] = annotated_data
|
|
455
|
-
self.variable_manager[self.func_addr].write_to(variable, None, codeloc, atom=dst, overwrite=False)
|
|
447
|
+
self.state.variable_manager[self.func_addr].write_to(variable, None, codeloc, atom=dst, overwrite=False)
|
|
456
448
|
|
|
457
449
|
if richr.typevar is not None:
|
|
458
450
|
if not self.state.typevars.has_type_variable_for(variable, codeloc):
|
|
@@ -502,13 +494,13 @@ class SimEngineVRBase(
|
|
|
502
494
|
|
|
503
495
|
if not stored:
|
|
504
496
|
# remove existing variables linked to this statement
|
|
505
|
-
existing_vars = self.variable_manager[self.func_addr].find_variables_by_stmt(
|
|
497
|
+
existing_vars = self.state.variable_manager[self.func_addr].find_variables_by_stmt(
|
|
506
498
|
self.block.addr, self.stmt_idx, "memory"
|
|
507
499
|
)
|
|
508
500
|
codeloc = self._codeloc()
|
|
509
501
|
if existing_vars:
|
|
510
502
|
for existing_var, _ in list(existing_vars):
|
|
511
|
-
self.variable_manager[self.func_addr].remove_variable_by_atom(codeloc, existing_var, atom)
|
|
503
|
+
self.state.variable_manager[self.func_addr].remove_variable_by_atom(codeloc, existing_var, atom)
|
|
512
504
|
|
|
513
505
|
# storing to a location specified by a pointer whose value cannot be determined at this point
|
|
514
506
|
self._store_to_variable(richr_addr, size)
|
|
@@ -517,11 +509,11 @@ class SimEngineVRBase(
|
|
|
517
509
|
self, stack_offset, data: RichR[claripy.ast.BV | claripy.ast.FP], size, offset=0, atom=None, endness=None
|
|
518
510
|
):
|
|
519
511
|
if atom is None:
|
|
520
|
-
existing_vars = self.variable_manager[self.func_addr].find_variables_by_stmt(
|
|
512
|
+
existing_vars = self.state.variable_manager[self.func_addr].find_variables_by_stmt(
|
|
521
513
|
self.block.addr, self.stmt_idx, "memory"
|
|
522
514
|
)
|
|
523
515
|
else:
|
|
524
|
-
existing_vars = self.variable_manager[self.func_addr].find_variables_by_atom(
|
|
516
|
+
existing_vars = self.state.variable_manager[self.func_addr].find_variables_by_atom(
|
|
525
517
|
self.block.addr, self.stmt_idx, atom
|
|
526
518
|
)
|
|
527
519
|
if not existing_vars:
|
|
@@ -529,12 +521,12 @@ class SimEngineVRBase(
|
|
|
529
521
|
stack_offset,
|
|
530
522
|
size,
|
|
531
523
|
base="bp",
|
|
532
|
-
ident=self.variable_manager[self.func_addr].next_variable_ident("stack"),
|
|
524
|
+
ident=self.state.variable_manager[self.func_addr].next_variable_ident("stack"),
|
|
533
525
|
region=self.func_addr,
|
|
534
526
|
)
|
|
535
527
|
variable_offset = offset
|
|
536
528
|
if isinstance(stack_offset, int):
|
|
537
|
-
self.variable_manager[self.func_addr].set_variable("stack", stack_offset, variable)
|
|
529
|
+
self.state.variable_manager[self.func_addr].set_variable("stack", stack_offset, variable)
|
|
538
530
|
l.debug("Identified a new stack variable %s at %#x.", variable, self.ins_addr)
|
|
539
531
|
|
|
540
532
|
else:
|
|
@@ -562,7 +554,7 @@ class SimEngineVRBase(
|
|
|
562
554
|
offset_into_var = var_offset
|
|
563
555
|
if offset_into_var == 0:
|
|
564
556
|
offset_into_var = None
|
|
565
|
-
self.variable_manager[self.func_addr].write_to(
|
|
557
|
+
self.state.variable_manager[self.func_addr].write_to(
|
|
566
558
|
var,
|
|
567
559
|
offset_into_var,
|
|
568
560
|
codeloc,
|
|
@@ -589,7 +581,7 @@ class SimEngineVRBase(
|
|
|
589
581
|
offset: claripy.ast.BV | None = None,
|
|
590
582
|
elem_size: int | None = None,
|
|
591
583
|
):
|
|
592
|
-
variable_manager = self.variable_manager["global"]
|
|
584
|
+
variable_manager = self.state.variable_manager["global"]
|
|
593
585
|
if stmt is None:
|
|
594
586
|
existing_vars = variable_manager.find_variables_by_stmt(self.block.addr, self.stmt_idx, "memory")
|
|
595
587
|
else:
|
|
@@ -696,9 +688,6 @@ class SimEngineVRBase(
|
|
|
696
688
|
base_typevar = typevar
|
|
697
689
|
field_offset = 0
|
|
698
690
|
|
|
699
|
-
# if addr_variable is not None:
|
|
700
|
-
# self.variable_manager[self.func_addr].reference_at(addr_variable, field_offset, codeloc, atom=stmt)
|
|
701
|
-
|
|
702
691
|
store_typevar = self._create_access_typevar(base_typevar, True, size, field_offset)
|
|
703
692
|
if addr_variable is not None:
|
|
704
693
|
self.state.typevars.add_type_variable(addr_variable, codeloc, typevar)
|
|
@@ -766,16 +755,18 @@ class SimEngineVRBase(
|
|
|
766
755
|
all_vars.add((var_offset, var_))
|
|
767
756
|
|
|
768
757
|
if not all_vars and concrete_offset is not None:
|
|
769
|
-
variables = self.variable_manager[self.func_addr].find_variables_by_stack_offset(
|
|
758
|
+
variables = self.state.variable_manager[self.func_addr].find_variables_by_stack_offset(
|
|
759
|
+
concrete_offset
|
|
760
|
+
)
|
|
770
761
|
if not variables:
|
|
771
762
|
variable = SimStackVariable(
|
|
772
763
|
concrete_offset,
|
|
773
764
|
size,
|
|
774
765
|
base="bp",
|
|
775
|
-
ident=self.variable_manager[self.func_addr].next_variable_ident("stack"),
|
|
766
|
+
ident=self.state.variable_manager[self.func_addr].next_variable_ident("stack"),
|
|
776
767
|
region=self.func_addr,
|
|
777
768
|
)
|
|
778
|
-
self.variable_manager[self.func_addr].add_variable("stack", concrete_offset, variable)
|
|
769
|
+
self.state.variable_manager[self.func_addr].add_variable("stack", concrete_offset, variable)
|
|
779
770
|
variables = {variable}
|
|
780
771
|
l.debug("Identified a new stack variable %s at %#x.", variable, self.ins_addr)
|
|
781
772
|
for variable in variables:
|
|
@@ -814,7 +805,7 @@ class SimEngineVRBase(
|
|
|
814
805
|
var_offset,
|
|
815
806
|
),
|
|
816
807
|
)
|
|
817
|
-
self.variable_manager[self.func_addr].read_from(
|
|
808
|
+
self.state.variable_manager[self.func_addr].read_from(
|
|
818
809
|
var,
|
|
819
810
|
offset_into_variable,
|
|
820
811
|
codeloc,
|
|
@@ -864,12 +855,12 @@ class SimEngineVRBase(
|
|
|
864
855
|
if v is None and expr is not None:
|
|
865
856
|
# failed to map the address to a known variable
|
|
866
857
|
# remove existing variables linked to this variable
|
|
867
|
-
existing_vars = self.variable_manager[self.func_addr].find_variables_by_atom(
|
|
858
|
+
existing_vars = self.state.variable_manager[self.func_addr].find_variables_by_atom(
|
|
868
859
|
self.block.addr, self.stmt_idx, expr
|
|
869
860
|
)
|
|
870
861
|
if existing_vars:
|
|
871
862
|
for existing_var, _ in list(existing_vars):
|
|
872
|
-
self.variable_manager[self.func_addr].remove_variable_by_atom(codeloc, existing_var, expr)
|
|
863
|
+
self.state.variable_manager[self.func_addr].remove_variable_by_atom(codeloc, existing_var, expr)
|
|
873
864
|
|
|
874
865
|
# Loading data from a pointer
|
|
875
866
|
if richr_addr.type_constraints:
|
|
@@ -901,7 +892,7 @@ class SimEngineVRBase(
|
|
|
901
892
|
offset: claripy.ast.BV | None = None,
|
|
902
893
|
elem_size: int | None = None,
|
|
903
894
|
) -> RichR[claripy.ast.BV]:
|
|
904
|
-
variable_manager = self.variable_manager["global"]
|
|
895
|
+
variable_manager = self.state.variable_manager["global"]
|
|
905
896
|
if expr is None:
|
|
906
897
|
existing_vars = variable_manager.find_variables_by_stmt(self.block.addr, self.stmt_idx, "memory")
|
|
907
898
|
else:
|
|
@@ -992,11 +983,11 @@ class SimEngineVRBase(
|
|
|
992
983
|
variable = SimRegisterVariable(
|
|
993
984
|
offset,
|
|
994
985
|
size if force_variable_size is None else force_variable_size,
|
|
995
|
-
ident=self.variable_manager[self.func_addr].next_variable_ident("register"),
|
|
986
|
+
ident=self.state.variable_manager[self.func_addr].next_variable_ident("register"),
|
|
996
987
|
region=self.func_addr,
|
|
997
988
|
)
|
|
998
989
|
value = self.state.annotate_with_variables(value, [(0, variable)])
|
|
999
|
-
self.variable_manager[self.func_addr].add_variable("register", offset, variable)
|
|
990
|
+
self.state.variable_manager[self.func_addr].add_variable("register", offset, variable)
|
|
1000
991
|
self.state.register_region.store(offset, value)
|
|
1001
992
|
value_list = [{value}]
|
|
1002
993
|
else:
|
|
@@ -1006,7 +997,9 @@ class SimEngineVRBase(
|
|
|
1006
997
|
for value_set in value_list:
|
|
1007
998
|
for value in value_set:
|
|
1008
999
|
for _, var in self.state.extract_variables(value):
|
|
1009
|
-
self.variable_manager[self.func_addr].read_from(
|
|
1000
|
+
self.state.variable_manager[self.func_addr].read_from(
|
|
1001
|
+
var, None, codeloc, atom=expr, overwrite=False
|
|
1002
|
+
)
|
|
1010
1003
|
variable_set.add(var)
|
|
1011
1004
|
|
|
1012
1005
|
if offset == self.project.arch.sp_offset:
|
|
@@ -1078,20 +1071,20 @@ class SimEngineVRBase(
|
|
|
1078
1071
|
variable = SimRegisterVariable(
|
|
1079
1072
|
vvar.reg_offset,
|
|
1080
1073
|
vvar.size,
|
|
1081
|
-
ident=self.variable_manager[self.func_addr].next_variable_ident("register"),
|
|
1074
|
+
ident=self.state.variable_manager[self.func_addr].next_variable_ident("register"),
|
|
1082
1075
|
region=self.func_addr,
|
|
1083
1076
|
)
|
|
1084
1077
|
value = self.state.annotate_with_variables(value, [(0, variable)])
|
|
1085
|
-
self.variable_manager[self.func_addr].add_variable("register", vvar.reg_offset, variable)
|
|
1078
|
+
self.state.variable_manager[self.func_addr].add_variable("register", vvar.reg_offset, variable)
|
|
1086
1079
|
elif vvar.category == ailment.Expr.VirtualVariableCategory.STACK:
|
|
1087
1080
|
variable = SimStackVariable(
|
|
1088
1081
|
vvar.stack_offset,
|
|
1089
1082
|
vvar.size,
|
|
1090
|
-
ident=self.variable_manager[self.func_addr].next_variable_ident("stack"),
|
|
1083
|
+
ident=self.state.variable_manager[self.func_addr].next_variable_ident("stack"),
|
|
1091
1084
|
region=self.func_addr,
|
|
1092
1085
|
)
|
|
1093
1086
|
value = self.state.annotate_with_variables(value, [(0, variable)])
|
|
1094
|
-
self.variable_manager[self.func_addr].add_variable("stack", vvar.stack_offset, variable)
|
|
1087
|
+
self.state.variable_manager[self.func_addr].add_variable("stack", vvar.stack_offset, variable)
|
|
1095
1088
|
elif vvar.category == ailment.Expr.VirtualVariableCategory.PARAMETER:
|
|
1096
1089
|
raise KeyError(f"Missing virtual variable for parameter {vvar}")
|
|
1097
1090
|
elif vvar.category == ailment.Expr.VirtualVariableCategory.TMP:
|
|
@@ -1104,7 +1097,7 @@ class SimEngineVRBase(
|
|
|
1104
1097
|
|
|
1105
1098
|
variable_set = set()
|
|
1106
1099
|
for _, var in self.state.extract_variables(value):
|
|
1107
|
-
self.variable_manager[self.func_addr].read_from(var, None, codeloc, atom=expr, overwrite=False)
|
|
1100
|
+
self.state.variable_manager[self.func_addr].read_from(var, None, codeloc, atom=expr, overwrite=False)
|
|
1108
1101
|
variable_set.add(var)
|
|
1109
1102
|
|
|
1110
1103
|
if (
|
|
@@ -51,7 +51,7 @@ class SimEngineVRVEX(
|
|
|
51
51
|
|
|
52
52
|
def _process_block(self, whitelist=None):
|
|
53
53
|
scanner = VEXIRSBScanner(self.project, logger=self.l)
|
|
54
|
-
scanner.
|
|
54
|
+
scanner.process(None, block=self.block)
|
|
55
55
|
self.stmts_to_lower = scanner.stmts_to_lower
|
|
56
56
|
self.reg_read_stmts_to_ignore = scanner.reg_read_stmts_to_ignore
|
|
57
57
|
|
|
@@ -39,12 +39,12 @@ class VEXIRSBScanner(SimEngineLightVEX[None, None, None, None]):
|
|
|
39
39
|
def _is_top(self, expr) -> bool:
|
|
40
40
|
return True
|
|
41
41
|
|
|
42
|
-
def
|
|
42
|
+
def process(self, state, *, block=None, whitelist=None, **kwargs):
|
|
43
43
|
self.tmps_with_64bit_regs = set()
|
|
44
44
|
self.tmps_assignment_stmtidx = {}
|
|
45
45
|
self.tmps_converted_to_32bit = set()
|
|
46
46
|
|
|
47
|
-
super().
|
|
47
|
+
super().process(state, block=block, whitelist=whitelist, **kwargs)
|
|
48
48
|
|
|
49
49
|
self.stmts_to_lower = {self.tmps_assignment_stmtidx[i] for i in self.tmps_converted_to_32bit}
|
|
50
50
|
|
angr/calling_conventions.py
CHANGED
|
@@ -11,6 +11,7 @@ import archinfo
|
|
|
11
11
|
from archinfo import RegisterName
|
|
12
12
|
from unique_log_filter import UniqueLogFilter
|
|
13
13
|
|
|
14
|
+
import angr
|
|
14
15
|
from .errors import AngrTypeError
|
|
15
16
|
from .sim_type import (
|
|
16
17
|
SimType,
|
|
@@ -33,7 +34,6 @@ from .sim_type import (
|
|
|
33
34
|
SimTypeReference,
|
|
34
35
|
)
|
|
35
36
|
from .state_plugins.sim_action_object import SimActionObject
|
|
36
|
-
from .engines.soot.engine import SootMixin
|
|
37
37
|
|
|
38
38
|
l = logging.getLogger(name=__name__)
|
|
39
39
|
l.addFilter(UniqueLogFilter())
|
|
@@ -307,7 +307,7 @@ class SimRegArg(SimFunctionArgument):
|
|
|
307
307
|
def __hash__(self):
|
|
308
308
|
return hash((self.size, self.reg_name, self.reg_offset))
|
|
309
309
|
|
|
310
|
-
def check_offset(self, arch):
|
|
310
|
+
def check_offset(self, arch) -> int:
|
|
311
311
|
return arch.registers[self.reg_name][0] + self.reg_offset
|
|
312
312
|
|
|
313
313
|
def set_value(self, state, value, **kwargs): # pylint: disable=unused-argument,arguments-differ
|
|
@@ -582,7 +582,12 @@ class SimCC:
|
|
|
582
582
|
FP_RETURN_VAL: SimFunctionArgument | None = (
|
|
583
583
|
None # The location where floating-point argument return values are stored
|
|
584
584
|
)
|
|
585
|
-
ARCH
|
|
585
|
+
ARCH: type[archinfo.Arch] | None = (
|
|
586
|
+
None # The archinfo.Arch class for which this CC is most likely relevant, if related
|
|
587
|
+
)
|
|
588
|
+
# archinfo.Arch classes for which this CC is relevant, in addition to self.ARCH.
|
|
589
|
+
# you should access cls.arches() to get a list of all arches for which this CC is relevant
|
|
590
|
+
EXTRA_ARCHES: tuple[type[archinfo.Arch], ...] = ()
|
|
586
591
|
CALLEE_CLEANUP = False # Whether the callee has to deallocate the stack space for the arguments
|
|
587
592
|
|
|
588
593
|
STACK_ALIGNMENT = 1 # the alignment requirement of the stack pointer at function start BEFORE call
|
|
@@ -1082,8 +1087,8 @@ class SimCC:
|
|
|
1082
1087
|
|
|
1083
1088
|
@classmethod
|
|
1084
1089
|
def _match(cls, arch, args: list, sp_delta):
|
|
1085
|
-
if
|
|
1086
|
-
arch, cls.
|
|
1090
|
+
if (
|
|
1091
|
+
cls.arches() is not None and ":" not in arch.name and not isinstance(arch, cls.arches())
|
|
1087
1092
|
): # pylint:disable=isinstance-second-argument-not-valid-type
|
|
1088
1093
|
return False
|
|
1089
1094
|
if sp_delta != cls.STACKARG_SP_DIFF:
|
|
@@ -1149,6 +1154,12 @@ class SimCC:
|
|
|
1149
1154
|
return cc_cls(arch)
|
|
1150
1155
|
return None
|
|
1151
1156
|
|
|
1157
|
+
@classmethod
|
|
1158
|
+
def arches(cls) -> tuple[type[archinfo.Arch], ...]:
|
|
1159
|
+
if cls.ARCH is not None:
|
|
1160
|
+
return (cls.ARCH, *cls.EXTRA_ARCHES)
|
|
1161
|
+
return cls.EXTRA_ARCHES
|
|
1162
|
+
|
|
1152
1163
|
def get_arg_info(self, state, prototype):
|
|
1153
1164
|
"""
|
|
1154
1165
|
This is just a simple wrapper that collects the information from various locations
|
|
@@ -1444,7 +1455,7 @@ class SimCCSystemVAMD64(SimCC):
|
|
|
1444
1455
|
|
|
1445
1456
|
@classmethod
|
|
1446
1457
|
def _match(cls, arch, args, sp_delta):
|
|
1447
|
-
if cls.ARCH is not None and not isinstance(arch, cls.ARCH):
|
|
1458
|
+
if cls.ARCH is not None and ":" not in arch.name and not isinstance(arch, cls.ARCH):
|
|
1448
1459
|
return False
|
|
1449
1460
|
# if sp_delta != cls.STACKARG_SP_DIFF:
|
|
1450
1461
|
# return False
|
|
@@ -1789,8 +1800,54 @@ class SimCCARMHF(SimCCARM):
|
|
|
1789
1800
|
FP_RETURN_VAL = SimRegArg("s0", 32)
|
|
1790
1801
|
CALLER_SAVED_REGS = []
|
|
1791
1802
|
RETURN_ADDR = SimRegArg("lr", 4)
|
|
1792
|
-
RETURN_VAL = SimRegArg("r0", 4)
|
|
1803
|
+
RETURN_VAL = SimRegArg("r0", 4)
|
|
1804
|
+
OVERFLOW_RETURN_VAL = SimRegArg("r1", 4)
|
|
1793
1805
|
ARCH = archinfo.ArchARMHF
|
|
1806
|
+
EXTRA_ARCHES = (archinfo.ArchARMCortexM,)
|
|
1807
|
+
|
|
1808
|
+
def next_arg(self, session, arg_type):
|
|
1809
|
+
if isinstance(arg_type, (SimTypeArray, SimTypeFixedSizeArray)): # hack
|
|
1810
|
+
arg_type = SimTypePointer(arg_type.elem_type).with_arch(self.arch)
|
|
1811
|
+
state = session.getstate()
|
|
1812
|
+
classification = self._classify(arg_type)
|
|
1813
|
+
try:
|
|
1814
|
+
mapped_classes = []
|
|
1815
|
+
for cls in classification:
|
|
1816
|
+
if cls == "DOUBLEP":
|
|
1817
|
+
if session.getstate()[1] % 2 == 1: # doubles must start on an even register
|
|
1818
|
+
next(session.int_iter)
|
|
1819
|
+
|
|
1820
|
+
if session.getstate()[1] == len(self.ARG_REGS) - 2:
|
|
1821
|
+
mapped_classes.append(next(session.int_iter))
|
|
1822
|
+
mapped_classes.append(next(session.both_iter))
|
|
1823
|
+
else:
|
|
1824
|
+
try:
|
|
1825
|
+
mapped_classes.append(next(session.int_iter))
|
|
1826
|
+
mapped_classes.append(next(session.int_iter))
|
|
1827
|
+
except StopIteration:
|
|
1828
|
+
mapped_classes.append(next(session.both_iter))
|
|
1829
|
+
mapped_classes.append(next(session.both_iter))
|
|
1830
|
+
elif cls == "NO_CLASS":
|
|
1831
|
+
raise NotImplementedError("Bug. Report to @rhelmot")
|
|
1832
|
+
elif cls == "MEMORY":
|
|
1833
|
+
mapped_classes.append(next(session.both_iter))
|
|
1834
|
+
elif cls == "INTEGER":
|
|
1835
|
+
try:
|
|
1836
|
+
mapped_classes.append(next(session.int_iter))
|
|
1837
|
+
except StopIteration:
|
|
1838
|
+
mapped_classes.append(next(session.both_iter))
|
|
1839
|
+
elif cls == "SINGLEP":
|
|
1840
|
+
try:
|
|
1841
|
+
mapped_classes.append(next(session.fp_iter))
|
|
1842
|
+
except StopIteration:
|
|
1843
|
+
mapped_classes.append(next(session.both_iter))
|
|
1844
|
+
else:
|
|
1845
|
+
raise NotImplementedError("Bug. Report to @rhelmot")
|
|
1846
|
+
except StopIteration:
|
|
1847
|
+
session.setstate(state)
|
|
1848
|
+
mapped_classes = [next(session.both_iter) for _ in classification]
|
|
1849
|
+
|
|
1850
|
+
return refine_locs_with_struct_type(self.arch, mapped_classes, arg_type)
|
|
1794
1851
|
|
|
1795
1852
|
|
|
1796
1853
|
class SimCCARMLinuxSyscall(SimCCSyscall):
|
|
@@ -2122,7 +2179,7 @@ class SimCCSoot(SimCC):
|
|
|
2122
2179
|
ARG_REGS = []
|
|
2123
2180
|
|
|
2124
2181
|
def setup_callsite(self, state, ret_addr, args, prototype, stack_base=None, alloc_base=None, grow_like_stack=True):
|
|
2125
|
-
SootMixin.setup_callsite(state, args, ret_addr)
|
|
2182
|
+
angr.engines.SootMixin.setup_callsite(state, args, ret_addr)
|
|
2126
2183
|
|
|
2127
2184
|
@staticmethod
|
|
2128
2185
|
def guess_prototype(args, prototype=None):
|
|
@@ -2226,7 +2283,7 @@ DEFAULT_CC: dict[str, dict[str, type[SimCC]]] = {
|
|
|
2226
2283
|
"X86": {"Linux": SimCCCdecl, "CGC": SimCCCdecl, "Win32": SimCCMicrosoftCdecl},
|
|
2227
2284
|
"ARMEL": {"Linux": SimCCARM},
|
|
2228
2285
|
"ARMHF": {"Linux": SimCCARMHF},
|
|
2229
|
-
"ARMCortexM": {"Linux":
|
|
2286
|
+
"ARMCortexM": {"Linux": SimCCARMHF},
|
|
2230
2287
|
"MIPS32": {"Linux": SimCCO32},
|
|
2231
2288
|
"MIPS64": {"Linux": SimCCN64},
|
|
2232
2289
|
"PPC32": {"Linux": SimCCPowerPC},
|
angr/engines/engine.py
CHANGED
|
@@ -24,10 +24,9 @@ DataType_co = TypeVar("DataType_co", covariant=True)
|
|
|
24
24
|
HeavyState = SimState[int | SootAddressDescriptor, claripy.ast.BV | SootAddressDescriptor]
|
|
25
25
|
|
|
26
26
|
|
|
27
|
-
class
|
|
27
|
+
class SimEngine(Generic[StateType, ResultType], metaclass=abc.ABCMeta):
|
|
28
28
|
"""
|
|
29
|
-
|
|
30
|
-
which having method `process` (contained in `SimEngine`) doesn't make sense
|
|
29
|
+
A SimEngine is a type which understands how to perform execution on a state.
|
|
31
30
|
"""
|
|
32
31
|
|
|
33
32
|
state: StateType
|
|
@@ -43,21 +42,6 @@ class SimEngineBase(Generic[StateType]):
|
|
|
43
42
|
self.project = state[0]
|
|
44
43
|
|
|
45
44
|
|
|
46
|
-
class SimEngine(Generic[StateType, ResultType], SimEngineBase[StateType], metaclass=abc.ABCMeta):
|
|
47
|
-
"""
|
|
48
|
-
A SimEngine is a class which understands how to perform execution on a state. This is a base class.
|
|
49
|
-
"""
|
|
50
|
-
|
|
51
|
-
@abc.abstractmethod
|
|
52
|
-
def process(self, state: StateType, **kwargs) -> ResultType:
|
|
53
|
-
"""
|
|
54
|
-
The main entry point for an engine. Should take a state and return a result.
|
|
55
|
-
|
|
56
|
-
:param state: The state to proceed from
|
|
57
|
-
:return: The result. Whatever you want ;)
|
|
58
|
-
"""
|
|
59
|
-
|
|
60
|
-
|
|
61
45
|
class SuccessorsMixin(SimEngine[HeavyState, SimSuccessors]):
|
|
62
46
|
"""
|
|
63
47
|
A mixin for SimEngine which implements ``process`` to perform common operations related to symbolic execution
|
angr/engines/light/engine.py
CHANGED
|
@@ -64,13 +64,8 @@ class SimEngineLight(Generic[StateType, DataType_co, BlockType, ResultType], Sim
|
|
|
64
64
|
self.l = logger or logging.getLogger(self.__module__ + "." + self.__class__.__name__)
|
|
65
65
|
super().__init__(project)
|
|
66
66
|
|
|
67
|
-
# there's two of these to support the mixin pattern - mixins can override process while there must be some base
|
|
68
|
-
# class that provides _process
|
|
69
|
-
def process(self, state: StateType, *, block: BlockType | None = None, **kwargs) -> ResultType:
|
|
70
|
-
return self._process(state, block=block, **kwargs)
|
|
71
|
-
|
|
72
67
|
@abstractmethod
|
|
73
|
-
def
|
|
68
|
+
def process(self, state: StateType, *, block: BlockType | None = None, **kwargs) -> ResultType: ...
|
|
74
69
|
|
|
75
70
|
def lift(self, state: StateType) -> BlockType:
|
|
76
71
|
raise TypeError(f"{type(self)} requires `block` to be passed to `process`")
|
|
@@ -267,7 +262,7 @@ class SimEngineLightVEX(
|
|
|
267
262
|
if name.startswith("_handle_dirty_")
|
|
268
263
|
}
|
|
269
264
|
|
|
270
|
-
def
|
|
265
|
+
def process(
|
|
271
266
|
self, state: StateType, *, block: Block | None = None, whitelist: set[int] | None = None, **kwargs
|
|
272
267
|
) -> ResultType:
|
|
273
268
|
# initialize local variables
|
|
@@ -640,7 +635,7 @@ class SimEngineLightAIL(
|
|
|
640
635
|
}
|
|
641
636
|
super().__init__(*args, **kwargs)
|
|
642
637
|
|
|
643
|
-
def
|
|
638
|
+
def process(
|
|
644
639
|
self, state: StateType, *, block: ailment.Block | None = None, whitelist: set[int] | None = None, **kwargs
|
|
645
640
|
) -> ResultType:
|
|
646
641
|
self.tmps = {}
|
angr/engines/pcode/emulate.py
CHANGED
|
@@ -4,7 +4,7 @@ import logging
|
|
|
4
4
|
import claripy
|
|
5
5
|
from claripy.ast.bv import BV
|
|
6
6
|
|
|
7
|
-
from angr.engines.engine import
|
|
7
|
+
from angr.engines.engine import SimEngine
|
|
8
8
|
from angr.utils.constants import DEFAULT_STATEMENT
|
|
9
9
|
from .lifter import IRSB
|
|
10
10
|
from .behavior import OpBehavior
|
|
@@ -19,7 +19,7 @@ with contextlib.suppress(ImportError):
|
|
|
19
19
|
l = logging.getLogger(__name__)
|
|
20
20
|
|
|
21
21
|
|
|
22
|
-
class PcodeEmulatorMixin(
|
|
22
|
+
class PcodeEmulatorMixin(SimEngine):
|
|
23
23
|
"""
|
|
24
24
|
Mixin for p-code execution.
|
|
25
25
|
"""
|
angr/engines/pcode/lifter.py
CHANGED
|
@@ -20,7 +20,7 @@ from cachetools import LRUCache
|
|
|
20
20
|
from pyvex.errors import PyVEXError, SkipStatementsError, LiftingException
|
|
21
21
|
|
|
22
22
|
from .behavior import BehaviorFactory
|
|
23
|
-
from angr.engines.engine import
|
|
23
|
+
from angr.engines.engine import SimEngine
|
|
24
24
|
from angr.state_plugins.inspect import BP_AFTER, BP_BEFORE
|
|
25
25
|
from angr.sim_state import SimState
|
|
26
26
|
from angr.misc.ux import once
|
|
@@ -981,7 +981,7 @@ class PcodeLifter(Lifter):
|
|
|
981
981
|
raise LiftingException(f"pypcode: could not decode any instructions @ 0x{self.addr:x}")
|
|
982
982
|
|
|
983
983
|
|
|
984
|
-
class PcodeLifterEngineMixin(
|
|
984
|
+
class PcodeLifterEngineMixin(SimEngine):
|
|
985
985
|
"""
|
|
986
986
|
Lifter mixin to lift from machine code to P-Code.
|
|
987
987
|
"""
|