angr 9.2.136__py3-none-win_amd64.whl → 9.2.137__py3-none-win_amd64.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/calling_convention.py +2 -1
- angr/analyses/calling_convention/fact_collector.py +10 -2
- angr/analyses/cfg/cfg_base.py +3 -33
- angr/analyses/cfg/cfg_emulated.py +0 -103
- angr/analyses/cfg/cfg_fast.py +28 -12
- angr/analyses/cfg/indirect_jump_resolvers/jumptable.py +15 -0
- angr/analyses/class_identifier.py +1 -2
- angr/analyses/complete_calling_conventions.py +3 -0
- angr/analyses/decompiler/ail_simplifier.py +12 -1
- angr/analyses/decompiler/block_simplifier.py +2 -2
- angr/analyses/decompiler/ccall_rewriters/__init__.py +2 -0
- angr/analyses/decompiler/ccall_rewriters/amd64_ccalls.py +1 -1
- angr/analyses/decompiler/ccall_rewriters/x86_ccalls.py +69 -0
- angr/analyses/decompiler/clinic.py +77 -65
- angr/analyses/decompiler/condition_processor.py +2 -0
- angr/analyses/decompiler/decompiler.py +1 -0
- angr/analyses/decompiler/dephication/dephication_base.py +2 -0
- angr/analyses/decompiler/dephication/rewriting_engine.py +8 -6
- angr/analyses/decompiler/dephication/seqnode_dephication.py +10 -1
- angr/analyses/decompiler/optimization_passes/return_duplicator_base.py +1 -2
- angr/analyses/decompiler/sequence_walker.py +6 -2
- angr/analyses/decompiler/ssailification/rewriting.py +11 -1
- angr/analyses/decompiler/ssailification/rewriting_engine.py +56 -19
- angr/analyses/decompiler/ssailification/ssailification.py +13 -3
- angr/analyses/decompiler/ssailification/traversal.py +28 -2
- angr/analyses/decompiler/ssailification/traversal_state.py +6 -1
- angr/analyses/decompiler/structured_codegen/c.py +44 -21
- angr/analyses/decompiler/structuring/phoenix.py +117 -14
- angr/analyses/decompiler/utils.py +113 -8
- angr/analyses/reaching_definitions/function_handler.py +1 -1
- angr/analyses/s_liveness.py +5 -1
- angr/analyses/s_propagator.py +25 -4
- angr/analyses/s_reaching_definitions/s_rda_model.py +2 -1
- angr/analyses/s_reaching_definitions/s_rda_view.py +20 -1
- angr/analyses/s_reaching_definitions/s_reaching_definitions.py +11 -1
- angr/analyses/stack_pointer_tracker.py +26 -16
- angr/analyses/variable_recovery/engine_ail.py +19 -7
- angr/analyses/variable_recovery/engine_base.py +16 -14
- angr/analyses/variable_recovery/engine_vex.py +2 -2
- angr/analyses/variable_recovery/variable_recovery_fast.py +22 -1
- angr/block.py +59 -20
- angr/engines/pcode/emulate.py +1 -1
- angr/engines/pcode/lifter.py +31 -18
- angr/engines/soot/expressions/__init__.py +2 -4
- angr/engines/soot/statements/__init__.py +1 -2
- angr/engines/soot/values/__init__.py +1 -2
- angr/engines/successors.py +11 -6
- angr/engines/vex/lifter.py +9 -6
- angr/flirt/build_sig.py +8 -15
- angr/knowledge_plugins/functions/function.py +0 -6
- angr/knowledge_plugins/functions/soot_function.py +5 -8
- angr/knowledge_plugins/variables/variable_manager.py +16 -10
- angr/lib/angr_native.dll +0 -0
- {angr-9.2.136.dist-info → angr-9.2.137.dist-info}/METADATA +7 -7
- {angr-9.2.136.dist-info → angr-9.2.137.dist-info}/RECORD +60 -59
- {angr-9.2.136.dist-info → angr-9.2.137.dist-info}/WHEEL +1 -1
- {angr-9.2.136.dist-info → angr-9.2.137.dist-info}/LICENSE +0 -0
- {angr-9.2.136.dist-info → angr-9.2.137.dist-info}/entry_points.txt +0 -0
- {angr-9.2.136.dist-info → angr-9.2.137.dist-info}/top_level.txt +0 -0
angr/engines/pcode/lifter.py
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
from __future__ import annotations
|
|
8
8
|
|
|
9
9
|
import logging
|
|
10
|
-
from typing import
|
|
10
|
+
from typing import Any, TYPE_CHECKING
|
|
11
11
|
from collections.abc import Iterable, Sequence
|
|
12
12
|
|
|
13
13
|
import archinfo
|
|
@@ -35,6 +35,12 @@ except ImportError:
|
|
|
35
35
|
pypcode = None
|
|
36
36
|
|
|
37
37
|
|
|
38
|
+
if TYPE_CHECKING:
|
|
39
|
+
# this is to make pyright happy; otherwise it believes pypcode is None
|
|
40
|
+
import pypcode
|
|
41
|
+
from pypcode import PcodeOp, Context
|
|
42
|
+
|
|
43
|
+
|
|
38
44
|
l = logging.getLogger(__name__)
|
|
39
45
|
|
|
40
46
|
IRSB_MAX_SIZE = 400
|
|
@@ -130,8 +136,8 @@ class IRSB:
|
|
|
130
136
|
|
|
131
137
|
_direct_next: bool | None
|
|
132
138
|
_exit_statements: Sequence[tuple[int, int, ExitStatement]]
|
|
133
|
-
_instruction_addresses:
|
|
134
|
-
_ops:
|
|
139
|
+
_instruction_addresses: list[int] | None
|
|
140
|
+
_ops: list[PcodeOp] # FIXME: Merge into _statements
|
|
135
141
|
_size: int | None
|
|
136
142
|
_statements: Iterable # Note: currently unused
|
|
137
143
|
_disassembly: PcodeDisassemblerBlock | None
|
|
@@ -140,7 +146,7 @@ class IRSB:
|
|
|
140
146
|
behaviors: BehaviorFactory | None
|
|
141
147
|
data_refs: Sequence # Note: currently unused
|
|
142
148
|
const_vals: Sequence # Note: currently unused
|
|
143
|
-
default_exit_target:
|
|
149
|
+
default_exit_target: Any # Note: currently used
|
|
144
150
|
jumpkind: str | None
|
|
145
151
|
next: int | None
|
|
146
152
|
|
|
@@ -199,7 +205,7 @@ class IRSB:
|
|
|
199
205
|
self._direct_next = None
|
|
200
206
|
self._exit_statements = []
|
|
201
207
|
self._instruction_addresses = None
|
|
202
|
-
self._ops = []
|
|
208
|
+
self._ops: list[PcodeOp] = []
|
|
203
209
|
self._size = None
|
|
204
210
|
self._statements = []
|
|
205
211
|
self.addr = mem_addr
|
|
@@ -248,7 +254,7 @@ class IRSB:
|
|
|
248
254
|
|
|
249
255
|
@property
|
|
250
256
|
def has_statements(self) -> bool:
|
|
251
|
-
return self.statements is not None and self.statements
|
|
257
|
+
return bool(self.statements is not None and self.statements)
|
|
252
258
|
|
|
253
259
|
@property
|
|
254
260
|
def exit_statements(self) -> Sequence[tuple[int, int, ExitStatement]]:
|
|
@@ -320,7 +326,7 @@ class IRSB:
|
|
|
320
326
|
return len(self.statements)
|
|
321
327
|
|
|
322
328
|
@property
|
|
323
|
-
def offsIP(self) -> int:
|
|
329
|
+
def offsIP(self) -> int | None:
|
|
324
330
|
return self.arch.ip_offset
|
|
325
331
|
|
|
326
332
|
@property
|
|
@@ -459,10 +465,10 @@ class IRSB:
|
|
|
459
465
|
jumpkind: str | None = None,
|
|
460
466
|
direct_next: bool | None = None,
|
|
461
467
|
size: int | None = None,
|
|
462
|
-
ops:
|
|
463
|
-
instruction_addresses:
|
|
468
|
+
ops: list[PcodeOp] | None = None,
|
|
469
|
+
instruction_addresses: list[int] | None = None,
|
|
464
470
|
exit_statements: Sequence[tuple[int, int, ExitStatement]] | None = None,
|
|
465
|
-
default_exit_target:
|
|
471
|
+
default_exit_target: Any = None,
|
|
466
472
|
) -> None:
|
|
467
473
|
# pylint: disable=unused-argument
|
|
468
474
|
self._statements = statements if statements is not None else []
|
|
@@ -490,7 +496,7 @@ class IRSB:
|
|
|
490
496
|
)
|
|
491
497
|
|
|
492
498
|
@property
|
|
493
|
-
def statements(self) ->
|
|
499
|
+
def statements(self) -> list:
|
|
494
500
|
# FIXME: For compatibility, may want to implement Ist_IMark and
|
|
495
501
|
# pyvex.IRStmt.Exit to ease analyses.
|
|
496
502
|
l.debug("Returning empty statements list!")
|
|
@@ -807,7 +813,7 @@ class PcodeBasicBlockLifter:
|
|
|
807
813
|
Lifts basic blocks to P-code
|
|
808
814
|
"""
|
|
809
815
|
|
|
810
|
-
context:
|
|
816
|
+
context: Context
|
|
811
817
|
behaviors: BehaviorFactory
|
|
812
818
|
|
|
813
819
|
def __init__(self, arch: archinfo.Arch):
|
|
@@ -1032,7 +1038,7 @@ class PcodeLifterEngineMixin(SimEngineBase):
|
|
|
1032
1038
|
self,
|
|
1033
1039
|
addr: int | None = None,
|
|
1034
1040
|
state: SimState | None = None,
|
|
1035
|
-
clemory: cle.Clemory | None = None,
|
|
1041
|
+
clemory: cle.Clemory | cle.ClemoryReadOnlyView | None = None,
|
|
1036
1042
|
insn_bytes: bytes | None = None,
|
|
1037
1043
|
arch: archinfo.Arch | None = None,
|
|
1038
1044
|
size: int | None = None,
|
|
@@ -1047,7 +1053,7 @@ class PcodeLifterEngineMixin(SimEngineBase):
|
|
|
1047
1053
|
load_from_ro_regions: bool = False,
|
|
1048
1054
|
cross_insn_opt: bool | None = None,
|
|
1049
1055
|
const_prop: bool | None = None,
|
|
1050
|
-
):
|
|
1056
|
+
) -> IRSB:
|
|
1051
1057
|
"""
|
|
1052
1058
|
Temporary compatibility interface for integration with block code.
|
|
1053
1059
|
"""
|
|
@@ -1075,7 +1081,7 @@ class PcodeLifterEngineMixin(SimEngineBase):
|
|
|
1075
1081
|
self,
|
|
1076
1082
|
addr: int | None = None,
|
|
1077
1083
|
state: SimState | None = None,
|
|
1078
|
-
clemory: cle.Clemory | None = None,
|
|
1084
|
+
clemory: cle.Clemory | cle.ClemoryReadOnlyView | None = None,
|
|
1079
1085
|
insn_bytes: bytes | None = None,
|
|
1080
1086
|
arch: archinfo.Arch | None = None,
|
|
1081
1087
|
size: int | None = None,
|
|
@@ -1090,7 +1096,7 @@ class PcodeLifterEngineMixin(SimEngineBase):
|
|
|
1090
1096
|
load_from_ro_regions: bool = False,
|
|
1091
1097
|
cross_insn_opt: bool | None = None,
|
|
1092
1098
|
const_prop: bool | None = None,
|
|
1093
|
-
):
|
|
1099
|
+
) -> IRSB:
|
|
1094
1100
|
"""
|
|
1095
1101
|
Lift an IRSB.
|
|
1096
1102
|
|
|
@@ -1137,6 +1143,7 @@ class PcodeLifterEngineMixin(SimEngineBase):
|
|
|
1137
1143
|
|
|
1138
1144
|
# phase 1: parameter defaults
|
|
1139
1145
|
if addr is None:
|
|
1146
|
+
assert state is not None
|
|
1140
1147
|
addr = state.solver.eval(state._ip)
|
|
1141
1148
|
if size is not None:
|
|
1142
1149
|
size = min(size, IRSB_MAX_SIZE)
|
|
@@ -1158,6 +1165,7 @@ class PcodeLifterEngineMixin(SimEngineBase):
|
|
|
1158
1165
|
" disabled."
|
|
1159
1166
|
)
|
|
1160
1167
|
opt_level = 0
|
|
1168
|
+
assert state is not None
|
|
1161
1169
|
if state and o.OPTIMIZE_IR in state.options:
|
|
1162
1170
|
state.options.remove(o.OPTIMIZE_IR)
|
|
1163
1171
|
if skip_stmts is not True:
|
|
@@ -1278,13 +1286,18 @@ class PcodeLifterEngineMixin(SimEngineBase):
|
|
|
1278
1286
|
)
|
|
1279
1287
|
return irsb
|
|
1280
1288
|
|
|
1289
|
+
raise SimEngineError("Unreachable code reached")
|
|
1281
1290
|
# phase x: error handling
|
|
1282
1291
|
except PyVEXError as e:
|
|
1283
1292
|
l.debug("Translation error at %#x", addr)
|
|
1284
1293
|
raise SimTranslationError("Unable to translate bytecode") from e
|
|
1285
1294
|
|
|
1286
1295
|
def _load_bytes(
|
|
1287
|
-
self,
|
|
1296
|
+
self,
|
|
1297
|
+
addr: int,
|
|
1298
|
+
max_size: int,
|
|
1299
|
+
state: SimState | None = None,
|
|
1300
|
+
clemory: cle.Clemory | cle.ClemoryReadOnlyView | None = None,
|
|
1288
1301
|
) -> tuple[bytes, int, int]:
|
|
1289
1302
|
if clemory is None and state is None:
|
|
1290
1303
|
raise SimEngineError("state and clemory cannot both be None in _load_bytes().")
|
|
@@ -1306,7 +1319,7 @@ class PcodeLifterEngineMixin(SimEngineBase):
|
|
|
1306
1319
|
|
|
1307
1320
|
# Load from the clemory if we can
|
|
1308
1321
|
if not load_from_state or not state:
|
|
1309
|
-
if isinstance(clemory, cle.Clemory):
|
|
1322
|
+
if isinstance(clemory, (cle.Clemory, cle.ClemoryReadOnlyView)):
|
|
1310
1323
|
try:
|
|
1311
1324
|
start, backer = next(clemory.backers(addr))
|
|
1312
1325
|
except StopIteration:
|
|
@@ -39,10 +39,8 @@ l = logging.getLogger("angr.engines.soot.expressions")
|
|
|
39
39
|
|
|
40
40
|
def translate_expr(expr, state):
|
|
41
41
|
expr_name = expr.__class__.__name__.split(".")[-1]
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
if expr_name.endswith("Expr"):
|
|
45
|
-
expr_name = expr_name[:-4]
|
|
42
|
+
expr_name = expr_name.removeprefix("Soot")
|
|
43
|
+
expr_name = expr_name.removesuffix("Expr")
|
|
46
44
|
expr_cls_name = "SimSootExpr_" + expr_name
|
|
47
45
|
|
|
48
46
|
g = globals()
|
|
@@ -16,8 +16,7 @@ l = logging.getLogger("angr.engines.soot.statements")
|
|
|
16
16
|
|
|
17
17
|
def translate_stmt(stmt, state):
|
|
18
18
|
stmt_name = stmt.__class__.__name__.split(".")[-1]
|
|
19
|
-
|
|
20
|
-
stmt_name = stmt_name[:-4]
|
|
19
|
+
stmt_name = stmt_name.removesuffix("Stmt")
|
|
21
20
|
|
|
22
21
|
stmt_cls_name = f"SimSootStmt_{stmt_name}"
|
|
23
22
|
if stmt_cls_name in globals():
|
|
@@ -12,8 +12,7 @@ from .strref import SimSootValue_StringRef
|
|
|
12
12
|
|
|
13
13
|
def translate_value(value, state):
|
|
14
14
|
value_name = value.__class__.__name__
|
|
15
|
-
|
|
16
|
-
value_name = value_name[4:]
|
|
15
|
+
value_name = value_name.removeprefix("Soot")
|
|
17
16
|
value_cls_name = "SimSootValue_" + value_name
|
|
18
17
|
|
|
19
18
|
g = globals()
|
angr/engines/successors.py
CHANGED
|
@@ -269,11 +269,11 @@ class SimSuccessors:
|
|
|
269
269
|
# categorize the state
|
|
270
270
|
if o.APPROXIMATE_GUARDS in state.options and state.solver.is_false(state.scratch.guard, exact=False):
|
|
271
271
|
if o.VALIDATE_APPROXIMATIONS in state.options and state.satisfiable():
|
|
272
|
-
raise
|
|
272
|
+
raise AssertionError("WTF")
|
|
273
273
|
self.unsat_successors.append(state)
|
|
274
274
|
elif o.APPROXIMATE_SATISFIABILITY in state.options and not state.solver.satisfiable(exact=False):
|
|
275
275
|
if o.VALIDATE_APPROXIMATIONS in state.options and state.solver.satisfiable():
|
|
276
|
-
raise
|
|
276
|
+
raise AssertionError("WTF")
|
|
277
277
|
self.unsat_successors.append(state)
|
|
278
278
|
elif (not state.scratch.guard.symbolic and state.solver.is_false(state.scratch.guard)) or (
|
|
279
279
|
o.LAZY_SOLVES not in state.options and not state.satisfiable()
|
|
@@ -295,10 +295,15 @@ class SimSuccessors:
|
|
|
295
295
|
# syscall
|
|
296
296
|
self.successors.append(state)
|
|
297
297
|
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
298
|
+
if "ip_at_syscall" in state.arch.registers:
|
|
299
|
+
# Misuse the ip_at_syscall register to save the return address for this syscall
|
|
300
|
+
# state.ip *might be* changed to be the real address
|
|
301
|
+
# of syscall SimProcedures by syscall handling code in angr
|
|
302
|
+
state.regs.ip_at_syscall = state.ip
|
|
303
|
+
else:
|
|
304
|
+
# The architecture doesn't have an ip_at_syscall register.
|
|
305
|
+
# Nothing to do but hope vigorously.
|
|
306
|
+
l.warning(f"Handling syscall on arch {state.arch.name:s} without ip_at_syscall register")
|
|
302
307
|
|
|
303
308
|
try:
|
|
304
309
|
symbolic_syscall_num, concrete_syscall_nums = self._resolve_syscall(state)
|
angr/engines/vex/lifter.py
CHANGED
|
@@ -57,7 +57,7 @@ class VEXLifter(SimEngineBase):
|
|
|
57
57
|
self.selfmodifying_code = False
|
|
58
58
|
|
|
59
59
|
# block cache
|
|
60
|
-
self._block_cache = None
|
|
60
|
+
self._block_cache: LRUCache = None
|
|
61
61
|
self._block_cache_hits = 0
|
|
62
62
|
self._block_cache_misses = 0
|
|
63
63
|
|
|
@@ -78,8 +78,8 @@ class VEXLifter(SimEngineBase):
|
|
|
78
78
|
self,
|
|
79
79
|
addr=None,
|
|
80
80
|
state=None,
|
|
81
|
-
clemory=None,
|
|
82
|
-
insn_bytes=None,
|
|
81
|
+
clemory: cle.Clemory | cle.ClemoryReadOnlyView | None = None,
|
|
82
|
+
insn_bytes: bytes | None = None,
|
|
83
83
|
offset=None,
|
|
84
84
|
arch=None,
|
|
85
85
|
size=None,
|
|
@@ -94,7 +94,7 @@ class VEXLifter(SimEngineBase):
|
|
|
94
94
|
cross_insn_opt=None,
|
|
95
95
|
load_from_ro_regions=False,
|
|
96
96
|
const_prop=False,
|
|
97
|
-
):
|
|
97
|
+
) -> pyvex.IRSB:
|
|
98
98
|
"""
|
|
99
99
|
Lift an IRSB.
|
|
100
100
|
|
|
@@ -245,6 +245,7 @@ class VEXLifter(SimEngineBase):
|
|
|
245
245
|
raise SimEngineError(f"No bytes in memory for block starting at {addr:#x}.")
|
|
246
246
|
|
|
247
247
|
# phase 5: call into pyvex
|
|
248
|
+
buff: bytes | claripy.ast.BV
|
|
248
249
|
l.debug("Creating IRSB of %s at %#x", arch, addr)
|
|
249
250
|
try:
|
|
250
251
|
for subphase in range(2):
|
|
@@ -287,7 +288,9 @@ class VEXLifter(SimEngineBase):
|
|
|
287
288
|
l.debug("Using bytes: %r", pyvex.ffi.buffer(buff, size))
|
|
288
289
|
raise SimTranslationError("Unable to translate bytecode") from e
|
|
289
290
|
|
|
290
|
-
def _load_bytes(
|
|
291
|
+
def _load_bytes(
|
|
292
|
+
self, addr, max_size, state=None, clemory: cle.Clemory | cle.ClemoryReadOnlyView | None = None
|
|
293
|
+
) -> tuple[bytes, int, int]:
|
|
291
294
|
if clemory is None and state is None:
|
|
292
295
|
raise SimEngineError("state and clemory cannot both be None in _load_bytes().")
|
|
293
296
|
|
|
@@ -308,7 +311,7 @@ class VEXLifter(SimEngineBase):
|
|
|
308
311
|
|
|
309
312
|
# Load from the clemory if we can
|
|
310
313
|
if not load_from_state or not state:
|
|
311
|
-
if isinstance(clemory, cle.Clemory):
|
|
314
|
+
if isinstance(clemory, (cle.Clemory, cle.ClemoryReadOnlyView)):
|
|
312
315
|
try:
|
|
313
316
|
start, backer = next(clemory.backers(addr))
|
|
314
317
|
except StopIteration:
|
angr/flirt/build_sig.py
CHANGED
|
@@ -22,9 +22,7 @@ def get_basic_info(ar_path: str) -> dict[str, str]:
|
|
|
22
22
|
"""
|
|
23
23
|
|
|
24
24
|
with tempfile.TemporaryDirectory() as tempdirname:
|
|
25
|
-
cwd
|
|
26
|
-
os.chdir(tempdirname)
|
|
27
|
-
subprocess.call(["ar", "x", ar_path])
|
|
25
|
+
subprocess.call(["ar", "x", ar_path], cwd=tempdirname)
|
|
28
26
|
|
|
29
27
|
# Load arch and OS information from the first .o file
|
|
30
28
|
o_files = [f for f in os.listdir(".") if f.endswith(".o")]
|
|
@@ -32,8 +30,8 @@ def get_basic_info(ar_path: str) -> dict[str, str]:
|
|
|
32
30
|
proj = angr.Project(o_files[0], auto_load_libs=False)
|
|
33
31
|
arch_name = proj.arch.name.lower()
|
|
34
32
|
os_name = proj.simos.name.lower()
|
|
35
|
-
|
|
36
|
-
|
|
33
|
+
else:
|
|
34
|
+
raise ValueError("No .o files found in the archive.")
|
|
37
35
|
|
|
38
36
|
return {
|
|
39
37
|
"arch": arch_name,
|
|
@@ -64,9 +62,7 @@ def get_unique_strings(ar_path: str) -> list[str]:
|
|
|
64
62
|
# extract the archive file into a temporary directory
|
|
65
63
|
all_strings = set()
|
|
66
64
|
with tempfile.TemporaryDirectory() as tempdirname:
|
|
67
|
-
cwd
|
|
68
|
-
os.chdir(tempdirname)
|
|
69
|
-
subprocess.call(["ar", "x", ar_path])
|
|
65
|
+
subprocess.call(["ar", "x", ar_path], cwd=tempdirname)
|
|
70
66
|
|
|
71
67
|
for filename in os.listdir("."):
|
|
72
68
|
if filename.endswith(".o"):
|
|
@@ -93,8 +89,6 @@ def get_unique_strings(ar_path: str) -> list[str]:
|
|
|
93
89
|
non_symbol_strings.add(s)
|
|
94
90
|
all_strings |= non_symbol_strings
|
|
95
91
|
|
|
96
|
-
os.chdir(cwd)
|
|
97
|
-
|
|
98
92
|
grouped_strings = defaultdict(set)
|
|
99
93
|
for s in all_strings:
|
|
100
94
|
grouped_strings[s[:5]].add(s)
|
|
@@ -138,7 +132,7 @@ def process_exc_file(exc_path: str):
|
|
|
138
132
|
|
|
139
133
|
TODO: Add caller-callee-based de-duplication.
|
|
140
134
|
"""
|
|
141
|
-
with open(exc_path) as f:
|
|
135
|
+
with open(exc_path, encoding="utf-8") as f:
|
|
142
136
|
data = f.read()
|
|
143
137
|
lines = data.split("\n")
|
|
144
138
|
|
|
@@ -184,7 +178,7 @@ def process_exc_file(exc_path: str):
|
|
|
184
178
|
g[the_chosen_one] = "+" + line
|
|
185
179
|
|
|
186
180
|
# output
|
|
187
|
-
with open(exc_path, "w") as f:
|
|
181
|
+
with open(exc_path, "w", encoding="utf-8") as f:
|
|
188
182
|
for g in groups.values():
|
|
189
183
|
for line in g.values():
|
|
190
184
|
f.write(line + "\n")
|
|
@@ -273,8 +267,7 @@ def main():
|
|
|
273
267
|
basename = os.path.basename(ar_path)
|
|
274
268
|
|
|
275
269
|
# sanitize basename since otherwise sigmake is not happy with it
|
|
276
|
-
|
|
277
|
-
basename = basename[:-2]
|
|
270
|
+
basename = basename.removesuffix(".a")
|
|
278
271
|
basename = basename.replace("+", "plus")
|
|
279
272
|
|
|
280
273
|
# sanitize signame as well
|
|
@@ -292,7 +285,7 @@ def main():
|
|
|
292
285
|
|
|
293
286
|
assert not has_collision
|
|
294
287
|
|
|
295
|
-
with open(meta_path, "w") as f:
|
|
288
|
+
with open(meta_path, "w", encoding="utf-8") as f:
|
|
296
289
|
metadata = {
|
|
297
290
|
"unique_strings": unique_strings,
|
|
298
291
|
}
|
|
@@ -70,13 +70,10 @@ class Function(Serializable):
|
|
|
70
70
|
"is_simprocedure",
|
|
71
71
|
"is_syscall",
|
|
72
72
|
"normalized",
|
|
73
|
-
"prepared_registers",
|
|
74
|
-
"prepared_stack_variables",
|
|
75
73
|
"previous_names",
|
|
76
74
|
"prototype",
|
|
77
75
|
"prototype_libname",
|
|
78
76
|
"ran_cca",
|
|
79
|
-
"registers_read_afterwards",
|
|
80
77
|
"retaddr_on_stack",
|
|
81
78
|
"sp_delta",
|
|
82
79
|
"startpoint",
|
|
@@ -149,9 +146,6 @@ class Function(Serializable):
|
|
|
149
146
|
self.is_prototype_guessed: bool = True
|
|
150
147
|
# Whether this function returns or not. `None` means it's not determined yet
|
|
151
148
|
self._returning = None
|
|
152
|
-
self.prepared_registers = set()
|
|
153
|
-
self.prepared_stack_variables = set()
|
|
154
|
-
self.registers_read_afterwards = set()
|
|
155
149
|
|
|
156
150
|
self._addr_to_block_node = {} # map addresses to nodes. it's a cache of blocks. if a block is removed from the
|
|
157
151
|
# function, it may not be removed from _addr_to_block_node. if you want to list
|
|
@@ -1,7 +1,11 @@
|
|
|
1
|
+
# pylint:disable=super-init-not-called
|
|
1
2
|
from __future__ import annotations
|
|
2
3
|
import os
|
|
3
|
-
import networkx
|
|
4
4
|
from collections import defaultdict
|
|
5
|
+
|
|
6
|
+
import networkx
|
|
7
|
+
|
|
8
|
+
from angr.codenode import BlockNode
|
|
5
9
|
from .function import Function
|
|
6
10
|
|
|
7
11
|
|
|
@@ -88,10 +92,6 @@ class SootFunction(Function):
|
|
|
88
92
|
if hooker and hasattr(hooker, "NO_RET"):
|
|
89
93
|
self.returning = not hooker.NO_RET
|
|
90
94
|
|
|
91
|
-
self.prepared_registers = set()
|
|
92
|
-
self.prepared_stack_variables = set()
|
|
93
|
-
self.registers_read_afterwards = set()
|
|
94
|
-
|
|
95
95
|
# startpoint can always be None if this CFGNode is a syscall node
|
|
96
96
|
self.startpoint = None
|
|
97
97
|
|
|
@@ -126,6 +126,3 @@ class SootFunction(Function):
|
|
|
126
126
|
if isinstance(node, BlockNode) and node.addr not in self._addr_to_block_node:
|
|
127
127
|
self._addr_to_block_node[node.addr] = node
|
|
128
128
|
return node
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
from angr.codenode import BlockNode
|
|
@@ -915,7 +915,7 @@ class VariableManagerInternal(Serializable):
|
|
|
915
915
|
# rename variables in a fixed order
|
|
916
916
|
var_ctr = count(0)
|
|
917
917
|
|
|
918
|
-
sorted_stack_variables = sorted(sorted_stack_variables, key=lambda v: v.offset)
|
|
918
|
+
sorted_stack_variables = sorted(sorted_stack_variables, key=lambda v: (v.offset, v.ident))
|
|
919
919
|
sorted_reg_variables = sorted(sorted_reg_variables, key=lambda v: _id_from_varident(v.ident))
|
|
920
920
|
|
|
921
921
|
# find variables that are likely only used by phi assignments
|
|
@@ -1033,7 +1033,7 @@ class VariableManagerInternal(Serializable):
|
|
|
1033
1033
|
Map SSA variables to a unified variable. Fill in self._unified_variables.
|
|
1034
1034
|
"""
|
|
1035
1035
|
|
|
1036
|
-
stack_vars:
|
|
1036
|
+
stack_vars: set[SimStackVariable] = set()
|
|
1037
1037
|
reg_vars: set[SimRegisterVariable] = set()
|
|
1038
1038
|
|
|
1039
1039
|
# unify stack variables based on their locations
|
|
@@ -1042,19 +1042,14 @@ class VariableManagerInternal(Serializable):
|
|
|
1042
1042
|
# do not unify twice
|
|
1043
1043
|
continue
|
|
1044
1044
|
if isinstance(v, SimStackVariable):
|
|
1045
|
-
stack_vars
|
|
1045
|
+
stack_vars.add(v)
|
|
1046
1046
|
elif isinstance(v, SimRegisterVariable):
|
|
1047
1047
|
reg_vars.add(v)
|
|
1048
1048
|
|
|
1049
|
-
for _, vs in stack_vars.items():
|
|
1050
|
-
unified = vs[0].copy()
|
|
1051
|
-
for v in vs:
|
|
1052
|
-
self.set_unified_variable(v, unified)
|
|
1053
|
-
|
|
1054
1049
|
# unify register variables based on phi nodes
|
|
1055
1050
|
graph = networkx.DiGraph() # an edge v1 -> v2 means v2 is the phi variable for v1
|
|
1056
1051
|
for v, subvs in self._phi_variables.items():
|
|
1057
|
-
if not isinstance(v, SimRegisterVariable):
|
|
1052
|
+
if not isinstance(v, (SimRegisterVariable, SimStackVariable)):
|
|
1058
1053
|
continue
|
|
1059
1054
|
for subv in subvs:
|
|
1060
1055
|
graph.add_edge(subv, v)
|
|
@@ -1086,10 +1081,21 @@ class VariableManagerInternal(Serializable):
|
|
|
1086
1081
|
self.set_unified_variable(v, unified)
|
|
1087
1082
|
for v in nodes:
|
|
1088
1083
|
reg_vars.discard(v)
|
|
1084
|
+
stack_vars.discard(v)
|
|
1089
1085
|
|
|
1090
|
-
|
|
1086
|
+
# deal with remaining variables
|
|
1087
|
+
for v in sorted(reg_vars, key=lambda v: v.ident):
|
|
1091
1088
|
self.set_unified_variable(v, v)
|
|
1092
1089
|
|
|
1090
|
+
stack_vars_by_offset: dict[int, list[SimStackVariable]] = defaultdict(list)
|
|
1091
|
+
for v in stack_vars:
|
|
1092
|
+
stack_vars_by_offset[v.offset].append(v)
|
|
1093
|
+
for vs in stack_vars_by_offset.values():
|
|
1094
|
+
vs = sorted(vs, key=lambda v: v.ident)
|
|
1095
|
+
unified = vs[0].copy()
|
|
1096
|
+
for v in vs:
|
|
1097
|
+
self.set_unified_variable(v, unified)
|
|
1098
|
+
|
|
1093
1099
|
def set_unified_variable(self, variable: SimVariable, unified: SimVariable) -> None:
|
|
1094
1100
|
"""
|
|
1095
1101
|
Set the unified variable for a given SSA variable.
|
angr/lib/angr_native.dll
CHANGED
|
Binary file
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.2
|
|
2
2
|
Name: angr
|
|
3
|
-
Version: 9.2.
|
|
3
|
+
Version: 9.2.137
|
|
4
4
|
Summary: A multi-architecture binary analysis toolkit, with the ability to perform dynamic symbolic execution and various static analyses on binaries
|
|
5
5
|
Home-page: https://github.com/angr/angr
|
|
6
6
|
License: BSD-2-Clause
|
|
@@ -16,13 +16,13 @@ Description-Content-Type: text/markdown
|
|
|
16
16
|
License-File: LICENSE
|
|
17
17
|
Requires-Dist: CppHeaderParser
|
|
18
18
|
Requires-Dist: GitPython
|
|
19
|
-
Requires-Dist: ailment==9.2.
|
|
20
|
-
Requires-Dist: archinfo==9.2.
|
|
19
|
+
Requires-Dist: ailment==9.2.137
|
|
20
|
+
Requires-Dist: archinfo==9.2.137
|
|
21
21
|
Requires-Dist: cachetools
|
|
22
22
|
Requires-Dist: capstone==5.0.3
|
|
23
23
|
Requires-Dist: cffi>=1.14.0
|
|
24
|
-
Requires-Dist: claripy==9.2.
|
|
25
|
-
Requires-Dist: cle==9.2.
|
|
24
|
+
Requires-Dist: claripy==9.2.137
|
|
25
|
+
Requires-Dist: cle==9.2.137
|
|
26
26
|
Requires-Dist: itanium-demangler
|
|
27
27
|
Requires-Dist: mulpyplexer
|
|
28
28
|
Requires-Dist: nampa
|
|
@@ -31,7 +31,7 @@ Requires-Dist: protobuf>=5.28.2
|
|
|
31
31
|
Requires-Dist: psutil
|
|
32
32
|
Requires-Dist: pycparser>=2.18
|
|
33
33
|
Requires-Dist: pyformlang
|
|
34
|
-
Requires-Dist: pyvex==9.2.
|
|
34
|
+
Requires-Dist: pyvex==9.2.137
|
|
35
35
|
Requires-Dist: rich>=13.1.0
|
|
36
36
|
Requires-Dist: sortedcontainers
|
|
37
37
|
Requires-Dist: sympy
|