angr 9.2.164__cp310-abi3-win_amd64.whl → 9.2.165__cp310-abi3-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 CHANGED
@@ -2,7 +2,7 @@
2
2
  # pylint: disable=wrong-import-position
3
3
  from __future__ import annotations
4
4
 
5
- __version__ = "9.2.164"
5
+ __version__ = "9.2.165"
6
6
 
7
7
  if bytes is str:
8
8
  raise Exception(
angr/analyses/analysis.py CHANGED
@@ -1,5 +1,6 @@
1
1
  from __future__ import annotations
2
2
  import functools
3
+ import os
3
4
  import sys
4
5
  import contextlib
5
6
  from collections import defaultdict
@@ -14,6 +15,8 @@ import logging
14
15
  import time
15
16
  import typing
16
17
 
18
+ import psutil
19
+
17
20
  from rich import progress
18
21
 
19
22
  from angr.misc.plugins import PluginVendor, VendorPreset
@@ -287,6 +290,8 @@ class Analysis:
287
290
  _name: str
288
291
  errors: list[AnalysisLogEntry] = []
289
292
  named_errors: defaultdict[str, list[AnalysisLogEntry]] = defaultdict(list)
293
+ _ram_usage: float | None = None
294
+ _last_ramusage_update: float = 0.0
290
295
  _progress_callback = None
291
296
  _show_progressbar = False
292
297
  _progressbar = None
@@ -295,7 +300,7 @@ class Analysis:
295
300
  _PROGRESS_WIDGETS = [
296
301
  progress.TaskProgressColumn(),
297
302
  progress.BarColumn(),
298
- progress.TextColumn("Elapsed Time:"),
303
+ progress.TextColumn("Elapsed:"),
299
304
  progress.TimeElapsedColumn(),
300
305
  progress.TextColumn("Time:"),
301
306
  progress.TimeRemainingColumn(),
@@ -311,7 +316,9 @@ class Analysis:
311
316
  raise
312
317
  else:
313
318
  error = AnalysisLogEntry("exception occurred", exc_info=True)
314
- l.error("Caught and logged %s with resilience: %s", error.exc_type.__name__, error.exc_value)
319
+ l.error(
320
+ "Caught and logged %s with resilience: %s", error.exc_type.__name__, error.exc_value # type:ignore
321
+ )
315
322
  if name is None:
316
323
  self.errors.append(error)
317
324
  else:
@@ -342,10 +349,12 @@ class Analysis:
342
349
  if self._progressbar is None:
343
350
  self._initialize_progressbar()
344
351
 
352
+ assert self._task is not None
353
+ assert self._progressbar is not None
345
354
  self._progressbar.update(self._task, completed=percentage)
346
355
 
347
- if text is not None and self._progressbar:
348
- self._progressbar.update(self._task, description=text)
356
+ if text is not None and self._progressbar:
357
+ self._progressbar.update(self._task, description=text)
349
358
 
350
359
  if self._progress_callback is not None:
351
360
  self._progress_callback(percentage, text=text, **kwargs) # pylint:disable=not-callable
@@ -360,6 +369,7 @@ class Analysis:
360
369
  if self._progressbar is None:
361
370
  self._initialize_progressbar()
362
371
  if self._progressbar is not None:
372
+ assert self._task is not None
363
373
  self._progressbar.update(self._task, completed=100)
364
374
  self._progressbar.stop()
365
375
  self._progressbar = None
@@ -384,6 +394,19 @@ class Analysis:
384
394
  if ctr != 0 and ctr % freq == 0:
385
395
  time.sleep(sleep_time)
386
396
 
397
+ @property
398
+ def ram_usage(self) -> float:
399
+ """
400
+ Return the current RAM usage of the Python process, in bytes. The value is updated at most once per second.
401
+ """
402
+
403
+ if time.time() - self._last_ramusage_update > 1:
404
+ self._last_ramusage_update = time.time()
405
+ proc = psutil.Process(os.getpid())
406
+ meminfo = proc.memory_info()
407
+ self._ram_usage = meminfo.rss
408
+ return self._ram_usage if self._ram_usage is not None else -0.1
409
+
387
410
  def __getstate__(self):
388
411
  d = dict(self.__dict__)
389
412
  d.pop("_progressbar", None)
@@ -846,6 +846,8 @@ class CFGFast(ForwardAnalysis[CFGNode, CFGNode, CFGJob, int], CFGBase): # pylin
846
846
  # exception handling
847
847
  self._exception_handling_by_endaddr = SortedDict()
848
848
 
849
+ self.stage: str = ""
850
+
849
851
  #
850
852
  # Variables used during analysis
851
853
  #
@@ -1361,6 +1363,8 @@ class CFGFast(ForwardAnalysis[CFGNode, CFGNode, CFGJob, int], CFGBase): # pylin
1361
1363
  return job.addr
1362
1364
 
1363
1365
  def _pre_analysis(self):
1366
+ self.stage = "Pre-analysis"
1367
+
1364
1368
  # Create a read-only memory view in loader for faster data loading
1365
1369
  self.project.loader.gen_ro_memview()
1366
1370
 
@@ -1446,6 +1450,8 @@ class CFGFast(ForwardAnalysis[CFGNode, CFGNode, CFGJob, int], CFGBase): # pylin
1446
1450
 
1447
1451
  self._job_ctr = 0
1448
1452
 
1453
+ self.stage = "Analysis (Stage 1)"
1454
+
1449
1455
  def _pre_job_handling(self, job: CFGJob): # pylint:disable=arguments-differ
1450
1456
  """
1451
1457
  Some pre job-processing tasks, like update progress bar.
@@ -1481,7 +1487,13 @@ class CFGFast(ForwardAnalysis[CFGNode, CFGNode, CFGJob, int], CFGBase): # pylin
1481
1487
  percentage = min(
1482
1488
  self._seg_list.occupied_size * max_percentage_stage_1 / self._regions_size, max_percentage_stage_1
1483
1489
  )
1484
- self._update_progress(percentage, cfg=self)
1490
+ ram_usage = self.ram_usage / (1024 * 1024)
1491
+ text = (
1492
+ f"{self.stage} | {len(self.functions)} funcs, {len(self.graph)} blocks | "
1493
+ f"{len(self._indirect_jumps_to_resolve)}/{len(self.indirect_jumps)} IJs | "
1494
+ f"{ram_usage:0.2f} MB RAM"
1495
+ )
1496
+ self._update_progress(percentage, text=text, cfg=self)
1485
1497
 
1486
1498
  def _intra_analysis(self):
1487
1499
  pass
@@ -1780,6 +1792,9 @@ class CFGFast(ForwardAnalysis[CFGNode, CFGNode, CFGJob, int], CFGBase): # pylin
1780
1792
  self._model.edges_to_repair = remaining_edges_to_repair
1781
1793
 
1782
1794
  def _post_analysis(self):
1795
+
1796
+ self.stage = "Analysis (Stage 2)"
1797
+
1783
1798
  self._repair_edges()
1784
1799
 
1785
1800
  self._make_completed_functions()
@@ -13,8 +13,6 @@ from unique_log_filter import UniqueLogFilter
13
13
 
14
14
 
15
15
  from angr.utils.graph import GraphUtils
16
- from angr.utils.lazy_import import lazy_import
17
- from angr.utils import is_pyinstaller
18
16
  from angr.utils.graph import dominates, inverted_idoms
19
17
  from angr.utils.ail import is_head_controlled_loop_block
20
18
  from angr.block import Block, BlockNode
@@ -37,12 +35,6 @@ from .structuring.structurer_nodes import (
37
35
  from .graph_region import GraphRegion
38
36
  from .utils import peephole_optimize_expr
39
37
 
40
- if is_pyinstaller():
41
- # PyInstaller is not happy with lazy import
42
- import sympy
43
- else:
44
- sympy = lazy_import("sympy")
45
-
46
38
 
47
39
  l = logging.getLogger(__name__)
48
40
  l.addFilter(UniqueLogFilter())
@@ -953,6 +945,9 @@ class ConditionProcessor:
953
945
 
954
946
  @staticmethod
955
947
  def claripy_ast_to_sympy_expr(ast, memo=None):
948
+
949
+ import sympy # pylint:disable=import-outside-toplevel
950
+
956
951
  if ast.op == "And":
957
952
  return sympy.And(*(ConditionProcessor.claripy_ast_to_sympy_expr(arg, memo=memo) for arg in ast.args))
958
953
  if ast.op == "Or":
@@ -974,6 +969,9 @@ class ConditionProcessor:
974
969
 
975
970
  @staticmethod
976
971
  def sympy_expr_to_claripy_ast(expr, memo: dict):
972
+
973
+ import sympy # pylint:disable=import-outside-toplevel
974
+
977
975
  if expr.is_Symbol:
978
976
  return memo[expr]
979
977
  if isinstance(expr, sympy.Or):
@@ -990,6 +988,9 @@ class ConditionProcessor:
990
988
 
991
989
  @staticmethod
992
990
  def simplify_condition(cond, depth_limit=8, variables_limit=8):
991
+
992
+ import sympy # pylint:disable=import-outside-toplevel
993
+
993
994
  memo = {}
994
995
  if cond.depth > depth_limit or len(cond.variables) > variables_limit:
995
996
  return cond
@@ -43,6 +43,7 @@ from .sar_to_signed_div import SarToSignedDiv
43
43
  from .tidy_stack_addr import TidyStackAddr
44
44
  from .invert_negated_logical_conjuction_disjunction import InvertNegatedLogicalConjunctionsAndDisjunctions
45
45
  from .rol_ror import RolRorRewriter
46
+ from .inlined_memcpy import InlinedMemcpy
46
47
  from .inlined_strcpy import InlinedStrcpy
47
48
  from .inlined_strcpy_consolidation import InlinedStrcpyConsolidation
48
49
  from .inlined_wstrcpy import InlinedWstrcpy
@@ -99,6 +100,7 @@ ALL_PEEPHOLE_OPTS: list[type[PeepholeOptimizationExprBase]] = [
99
100
  TidyStackAddr,
100
101
  InvertNegatedLogicalConjunctionsAndDisjunctions,
101
102
  RolRorRewriter,
103
+ InlinedMemcpy,
102
104
  InlinedStrcpy,
103
105
  InlinedStrcpyConsolidation,
104
106
  InlinedWstrcpy,
@@ -0,0 +1,78 @@
1
+ # pylint:disable=arguments-differ
2
+ from __future__ import annotations
3
+
4
+ from angr.ailment.expression import Const, StackBaseOffset, VirtualVariable, Load, UnaryOp
5
+ from angr.ailment.statement import Call, Assignment, Store
6
+ from angr import SIM_LIBRARIES
7
+ from .base import PeepholeOptimizationStmtBase
8
+
9
+
10
+ class InlinedMemcpy(PeepholeOptimizationStmtBase):
11
+ """
12
+ Simplifies inlined data copying logic into calls to memcpy.
13
+ """
14
+
15
+ __slots__ = ()
16
+
17
+ NAME = "Simplifying inlined strcpy"
18
+ stmt_classes = (Assignment, Store)
19
+
20
+ def optimize(self, stmt: Assignment | Store, stmt_idx: int | None = None, block=None, **kwargs):
21
+ should_replace = False
22
+ dst_offset, src_offset, store_size = None, None, None
23
+ if (
24
+ isinstance(stmt, Assignment)
25
+ and isinstance(stmt.dst, VirtualVariable)
26
+ and stmt.dst.was_stack
27
+ and stmt.dst.size == 16
28
+ and isinstance(stmt.src, Load)
29
+ ):
30
+ dst_offset = stmt.dst.stack_offset
31
+ store_size = stmt.dst.size
32
+ if (
33
+ isinstance(stmt.src.addr, UnaryOp)
34
+ and stmt.src.addr.op == "Reference"
35
+ and isinstance(stmt.src.addr.operand, VirtualVariable)
36
+ ):
37
+ should_replace = True
38
+ src_offset = stmt.src.addr.operand.stack_offset
39
+ elif isinstance(stmt.src.addr, StackBaseOffset):
40
+ should_replace = True
41
+ src_offset = stmt.src.addr.offset
42
+
43
+ if (
44
+ isinstance(stmt, Store)
45
+ and isinstance(stmt.addr, StackBaseOffset)
46
+ and stmt.size == 16
47
+ and isinstance(stmt.data, Load)
48
+ ):
49
+ dst_offset = stmt.addr.offset
50
+ store_size = stmt.size
51
+ if (
52
+ isinstance(stmt.data.addr, UnaryOp)
53
+ and stmt.data.addr.op == "Reference"
54
+ and isinstance(stmt.data.addr.operand, VirtualVariable)
55
+ ):
56
+ should_replace = True
57
+ src_offset = stmt.data.addr.operand.stack_offset
58
+ elif isinstance(stmt.data.addr, StackBaseOffset):
59
+ should_replace = True
60
+ src_offset = stmt.data.addr.offset
61
+
62
+ if should_replace:
63
+ assert dst_offset is not None and src_offset is not None and store_size is not None
64
+ # replace it with a call to memcpy
65
+ assert self.project is not None
66
+ return Call(
67
+ stmt.idx,
68
+ "memcpy",
69
+ args=[
70
+ StackBaseOffset(None, self.project.arch.bits, dst_offset),
71
+ StackBaseOffset(None, self.project.arch.bits, src_offset),
72
+ Const(None, None, store_size, self.project.arch.bits),
73
+ ],
74
+ prototype=SIM_LIBRARIES["libc.so"][0].get_prototype("memcpy"),
75
+ **stmt.tags,
76
+ )
77
+
78
+ return None
@@ -1,11 +1,11 @@
1
- # pylint:disable=arguments-differ
1
+ # pylint:disable=arguments-differ,too-many-boolean-expressions
2
2
  from __future__ import annotations
3
3
  import string
4
4
 
5
5
  from archinfo import Endness
6
6
 
7
- from angr.ailment.expression import Const, StackBaseOffset, VirtualVariable
8
- from angr.ailment.statement import Call, Assignment
7
+ from angr.ailment.expression import Const, StackBaseOffset, VirtualVariable, UnaryOp
8
+ from angr.ailment.statement import Call, Assignment, Store, Statement
9
9
 
10
10
  from angr import SIM_LIBRARIES
11
11
  from angr.utils.endness import ail_const_to_be
@@ -24,24 +24,54 @@ class InlinedStrcpy(PeepholeOptimizationStmtBase):
24
24
  __slots__ = ()
25
25
 
26
26
  NAME = "Simplifying inlined strcpy"
27
- stmt_classes = (Assignment,)
27
+ stmt_classes = (Assignment, Store)
28
+
29
+ def optimize(self, stmt: Assignment | Store, stmt_idx: int | None = None, block=None, **kwargs):
30
+ inlined_strcpy_candidate = False
31
+ src: Const | None = None
32
+ strcpy_dst: StackBaseOffset | UnaryOp | None = None
33
+
34
+ assert self.project is not None
28
35
 
29
- def optimize(self, stmt: Assignment, stmt_idx: int | None = None, block=None, **kwargs):
30
36
  if (
31
- isinstance(stmt.dst, VirtualVariable)
37
+ isinstance(stmt, Assignment)
38
+ and isinstance(stmt.dst, VirtualVariable)
32
39
  and stmt.dst.was_stack
33
40
  and isinstance(stmt.src, Const)
34
41
  and isinstance(stmt.src.value, int)
35
42
  ):
36
- r, s = self.is_integer_likely_a_string(stmt.src.value, stmt.src.size, self.project.arch.memory_endness)
43
+ inlined_strcpy_candidate = True
44
+ src = stmt.src
45
+ strcpy_dst = StackBaseOffset(None, self.project.arch.bits, stmt.dst.stack_offset)
46
+ elif (
47
+ isinstance(stmt, Store)
48
+ and isinstance(stmt.addr, UnaryOp)
49
+ and stmt.addr.op == "Reference"
50
+ and isinstance(stmt.addr.operand, VirtualVariable)
51
+ and stmt.addr.operand.was_stack
52
+ and isinstance(stmt.data, Const)
53
+ and isinstance(stmt.data.value, int)
54
+ ):
55
+ inlined_strcpy_candidate = True
56
+ src = stmt.data
57
+ strcpy_dst = stmt.addr
58
+
59
+ if inlined_strcpy_candidate:
60
+ assert src is not None and strcpy_dst is not None
61
+ assert isinstance(src.value, int)
62
+ assert self.kb is not None
63
+
64
+ r, s = self.is_integer_likely_a_string(src.value, src.size, self.project.arch.memory_endness)
37
65
  if r:
66
+ assert s is not None
67
+
38
68
  # replace it with a call to strncpy
39
69
  str_id = self.kb.custom_strings.allocate(s.encode("ascii"))
40
70
  return Call(
41
71
  stmt.idx,
42
72
  "strncpy",
43
73
  args=[
44
- StackBaseOffset(None, self.project.arch.bits, stmt.dst.stack_offset),
74
+ strcpy_dst,
45
75
  Const(None, None, str_id, self.project.arch.bits, custom_string=True),
46
76
  Const(None, None, len(s), self.project.arch.bits),
47
77
  ],
@@ -68,9 +98,21 @@ class InlinedStrcpy(PeepholeOptimizationStmtBase):
68
98
  next_offset = None
69
99
  stride = []
70
100
 
101
+ if not stride:
102
+ return None
103
+ min_stride_stmt_idx = min(stmt_idx_ for _, stmt_idx_, _ in stride)
104
+ if min_stride_stmt_idx > stmt_idx:
105
+ # the current statement is not involved in the stride. we can't simplify here, otherwise we
106
+ # will incorrectly remove the current statement
107
+ return None
108
+
71
109
  integer, size = self.stride_to_int(stride)
72
- r, s = self.is_integer_likely_a_string(integer, size, Endness.BE)
110
+ prev_stmt = None if stmt_idx == 0 else block.statements[stmt_idx - 1]
111
+ min_str_length = 1 if prev_stmt is not None and self.is_inlined_strcpy(prev_stmt) else 4
112
+ r, s = self.is_integer_likely_a_string(integer, size, Endness.BE, min_length=min_str_length)
73
113
  if r:
114
+ assert s is not None
115
+
74
116
  # we remove all involved statements whose statement IDs are greater than the current one
75
117
  for _, stmt_idx_, _ in reversed(stride):
76
118
  if stmt_idx_ <= stmt_idx:
@@ -83,7 +125,7 @@ class InlinedStrcpy(PeepholeOptimizationStmtBase):
83
125
  stmt.idx,
84
126
  "strncpy",
85
127
  args=[
86
- StackBaseOffset(None, self.project.arch.bits, stmt.dst.stack_offset),
128
+ strcpy_dst,
87
129
  Const(None, None, str_id, self.project.arch.bits, custom_string=True),
88
130
  Const(None, None, len(s), self.project.arch.bits),
89
131
  ],
@@ -101,10 +143,13 @@ class InlinedStrcpy(PeepholeOptimizationStmtBase):
101
143
  for _, _, v in stride:
102
144
  size += v.size
103
145
  n <<= v.bits
146
+ assert isinstance(v.value, int)
104
147
  n |= v.value
105
148
  return n, size
106
149
 
107
150
  def collect_constant_stores(self, block, starting_stmt_idx: int) -> dict[int, tuple[int, Const | None]]:
151
+ assert self.project is not None
152
+
108
153
  r = {}
109
154
  for idx, stmt in enumerate(block.statements):
110
155
  if idx < starting_stmt_idx:
@@ -158,3 +203,15 @@ class InlinedStrcpy(PeepholeOptimizationStmtBase):
158
203
  return False, None
159
204
  return True, "".join(chars)
160
205
  return False, None
206
+
207
+ @staticmethod
208
+ def is_inlined_strcpy(stmt: Statement) -> bool:
209
+ return (
210
+ isinstance(stmt, Call)
211
+ and isinstance(stmt.target, str)
212
+ and stmt.target == "strncpy"
213
+ and stmt.args is not None
214
+ and len(stmt.args) == 3
215
+ and isinstance(stmt.args[1], Const)
216
+ and hasattr(stmt.args[1], "custom_string")
217
+ )
@@ -1,7 +1,7 @@
1
1
  # pylint:disable=arguments-differ
2
2
  from __future__ import annotations
3
3
 
4
- from angr.ailment.expression import Expression, BinaryOp, Const, Register, StackBaseOffset
4
+ from angr.ailment.expression import Expression, BinaryOp, Const, Register, StackBaseOffset, UnaryOp, VirtualVariable
5
5
  from angr.ailment.statement import Call, Store
6
6
 
7
7
  from angr import SIM_LIBRARIES
@@ -21,12 +21,12 @@ class InlinedStrcpyConsolidation(PeepholeOptimizationMultiStmtBase):
21
21
 
22
22
  def optimize(self, stmts: list[Call], **kwargs):
23
23
  last_stmt, stmt = stmts
24
- if InlinedStrcpyConsolidation._is_inlined_strcpy(last_stmt):
24
+ if InlinedStrcpy.is_inlined_strcpy(last_stmt):
25
25
  s_last: bytes = self.kb.custom_strings[last_stmt.args[1].value]
26
26
  addr_last = last_stmt.args[0]
27
27
  new_str = None # will be set if consolidation should happen
28
28
 
29
- if isinstance(stmt, Call) and InlinedStrcpyConsolidation._is_inlined_strcpy(stmt):
29
+ if isinstance(stmt, Call) and InlinedStrcpy.is_inlined_strcpy(stmt):
30
30
  # consolidating two calls
31
31
  s_curr: bytes = self.kb.custom_strings[stmt.args[1].value]
32
32
  addr_curr = stmt.args[0]
@@ -74,22 +74,19 @@ class InlinedStrcpyConsolidation(PeepholeOptimizationMultiStmtBase):
74
74
 
75
75
  return None
76
76
 
77
- @staticmethod
78
- def _is_inlined_strcpy(stmt: Call):
79
- return (
80
- isinstance(stmt.target, str)
81
- and stmt.target == "strncpy"
82
- and len(stmt.args) == 3
83
- and isinstance(stmt.args[1], Const)
84
- and hasattr(stmt.args[1], "custom_string")
85
- )
86
-
87
77
  @staticmethod
88
78
  def _parse_addr(addr: Expression) -> tuple[Expression, int]:
89
79
  if isinstance(addr, Register):
90
80
  return addr, 0
91
81
  if isinstance(addr, StackBaseOffset):
92
82
  return StackBaseOffset(None, addr.bits, 0), addr.offset
83
+ if (
84
+ isinstance(addr, UnaryOp)
85
+ and addr.op == "Reference"
86
+ and isinstance(addr.operand, VirtualVariable)
87
+ and addr.operand.was_stack
88
+ ):
89
+ return StackBaseOffset(None, addr.bits, 0), addr.operand.stack_offset
93
90
  if isinstance(addr, BinaryOp):
94
91
  if addr.op == "Add" and isinstance(addr.operands[1], Const):
95
92
  base_0, offset_0 = InlinedStrcpyConsolidation._parse_addr(addr.operands[0])
@@ -27,6 +27,42 @@ STEP_LIMIT_FIND = 500
27
27
  STEP_LIMIT_ANALYSIS = 5000
28
28
 
29
29
 
30
+ ALL_X64_XMM_REGS = {
31
+ capstone.x86.X86_REG_XMM0,
32
+ capstone.x86.X86_REG_XMM1,
33
+ capstone.x86.X86_REG_XMM2,
34
+ capstone.x86.X86_REG_XMM3,
35
+ capstone.x86.X86_REG_XMM4,
36
+ capstone.x86.X86_REG_XMM5,
37
+ capstone.x86.X86_REG_XMM6,
38
+ capstone.x86.X86_REG_XMM7,
39
+ capstone.x86.X86_REG_XMM8,
40
+ capstone.x86.X86_REG_XMM9,
41
+ capstone.x86.X86_REG_XMM10,
42
+ capstone.x86.X86_REG_XMM11,
43
+ capstone.x86.X86_REG_XMM12,
44
+ capstone.x86.X86_REG_XMM13,
45
+ capstone.x86.X86_REG_XMM14,
46
+ capstone.x86.X86_REG_XMM15,
47
+ capstone.x86.X86_REG_XMM16,
48
+ capstone.x86.X86_REG_XMM17,
49
+ capstone.x86.X86_REG_XMM18,
50
+ capstone.x86.X86_REG_XMM19,
51
+ capstone.x86.X86_REG_XMM20,
52
+ capstone.x86.X86_REG_XMM21,
53
+ capstone.x86.X86_REG_XMM22,
54
+ capstone.x86.X86_REG_XMM23,
55
+ capstone.x86.X86_REG_XMM24,
56
+ capstone.x86.X86_REG_XMM25,
57
+ capstone.x86.X86_REG_XMM26,
58
+ capstone.x86.X86_REG_XMM27,
59
+ capstone.x86.X86_REG_XMM28,
60
+ capstone.x86.X86_REG_XMM29,
61
+ capstone.x86.X86_REG_XMM30,
62
+ capstone.x86.X86_REG_XMM31,
63
+ }
64
+
65
+
30
66
  class StringDeobFuncDescriptor:
31
67
  """
32
68
  Describes a string deobfuscation function.
@@ -478,10 +514,12 @@ class StringObfuscationFinder(Analysis):
478
514
  actual_addrs = action.actual_addrs
479
515
  if action.type == "mem":
480
516
  if action.action == "read":
517
+ assert action.size is not None
481
518
  for a in actual_addrs:
482
519
  for size in range(action.size.ast // 8):
483
520
  all_global_reads.append(a + size)
484
521
  elif action.action == "write":
522
+ assert action.size is not None
485
523
  for a in actual_addrs:
486
524
  for size in range(action.size.ast // 8):
487
525
  all_global_writes.append(a + size)
@@ -598,16 +636,16 @@ class StringObfuscationFinder(Analysis):
598
636
  type3_functions = []
599
637
 
600
638
  for func in function_candidates:
601
- if not 8 <= len(func.block_addrs_set) < 14:
639
+ if not 1 <= len(func.block_addrs_set) < 14:
602
640
  continue
603
641
 
604
642
  # if it has a prototype recovered, it must have four arguments
605
- if func.prototype is not None and len(func.prototype.args) != 4:
643
+ if func.prototype is not None and len(func.prototype.args) not in {3, 4}:
606
644
  continue
607
645
 
608
646
  # the function must call some other functions
609
- if callgraph_digraph.out_degree[func.addr] == 0:
610
- continue
647
+ # if callgraph_digraph.out_degree[func.addr] == 0:
648
+ # continue
611
649
 
612
650
  # take a look at its call sites
613
651
  func_node = cfg.get_any_node(func.addr)
@@ -635,30 +673,34 @@ class StringObfuscationFinder(Analysis):
635
673
  continue
636
674
  if dec.codegen is None or not dec.codegen.text:
637
675
  continue
676
+
638
677
  if not self._like_type3_deobfuscation_function(dec.codegen.text):
639
678
  continue
640
679
 
641
680
  # examine the first 100 call sites and see if any of them returns a valid string
642
681
  valid = False
682
+ guessed_size = False
643
683
  for i in range(min(100, len(call_sites))):
644
684
  call_site_block = self.project.factory.block(call_sites[i].addr)
645
685
  if not self._is_block_setting_constants_to_stack(call_site_block):
646
686
  continue
647
687
 
648
688
  # simulate an execution to see if it really works
649
- data = self._type3_prepare_and_execute(
650
- func.addr, call_sites[i].addr, call_sites[i].function_address, cfg
689
+ data, guessed_size = self._type3_prepare_and_execute(
690
+ func.addr, call_sites[i].addr, call_sites[i].function_address, cfg # type:ignore
651
691
  )
652
692
  if data is None:
653
693
  continue
654
- if len(data) > 3 and all(chr(x) in string.printable for x in data):
655
- valid = True
656
- break
694
+ if len(data) > 3:
695
+ consecutive_printable_strs = self._consecutive_printable_substrings(data, min_length=4)
696
+ if consecutive_printable_strs:
697
+ valid = True
698
+ break
657
699
 
658
700
  if valid:
659
701
  desc = StringDeobFuncDescriptor()
660
702
  desc.string_output_arg_idx = 0
661
- desc.string_length_arg_idx = 1
703
+ desc.string_length_arg_idx = 1 if not guessed_size else None
662
704
  desc.string_null_terminating = False
663
705
  type3_functions.append((func.addr, desc))
664
706
 
@@ -687,11 +729,15 @@ class StringObfuscationFinder(Analysis):
687
729
  if cfg is None:
688
730
  raise AngrAnalysisError("StringObfuscationFinder needs a CFG for the analysis")
689
731
 
690
- call_sites = cfg.get_predecessors(cfg.get_any_node(func_addr))
732
+ cfg_node = cfg.get_any_node(func_addr)
733
+ if cfg_node is None:
734
+ raise AngrAnalysisError(f"Cannot find the CFG node for function {func_addr:#x}")
735
+ call_sites = cfg.get_predecessors(cfg_node)
691
736
  callinsn2content = {}
692
737
  for idx, call_site in enumerate(call_sites):
693
738
  _l.debug("Analyzing type 3 candidate call site %#x (%d/%d)...", call_site.addr, idx + 1, len(call_sites))
694
- data = self._type3_prepare_and_execute(func_addr, call_site.addr, call_site.function_address, cfg)
739
+ assert call_site.function_address is not None
740
+ data, _ = self._type3_prepare_and_execute(func_addr, call_site.addr, call_site.function_address, cfg)
695
741
  if data:
696
742
  callinsn2content[call_site.instruction_addrs[-1]] = data
697
743
  # print(hex(call_site.addr), data)
@@ -722,12 +768,14 @@ class StringObfuscationFinder(Analysis):
722
768
 
723
769
  @staticmethod
724
770
  def _like_type3_deobfuscation_function(code: str) -> bool:
725
- return bool(
726
- ("^" in code or ">>" in code or "<<" in code or "~" in code)
727
- and ("do" in code or "while" in code or "for" in code)
728
- )
729
-
730
- def _type3_prepare_and_execute(self, func_addr: int, call_site_addr: int, call_site_func_addr: int, cfg):
771
+ has_bitwise_ops = "^" in code or ">>" in code or "<<" in code or "~" in code
772
+ has_loops = "do" in code or "while" in code or "for" in code
773
+ has_many_bitwise_ops = code.count("^") + code.count(">>") + code.count("<<") + code.count("~") > 5
774
+ return has_bitwise_ops and (has_loops or has_many_bitwise_ops)
775
+
776
+ def _type3_prepare_and_execute(
777
+ self, func_addr: int, call_site_addr: int, call_site_func_addr: int, cfg
778
+ ) -> tuple[bytes | None, bool]:
731
779
  blocks_at_callsite = [call_site_addr]
732
780
 
733
781
  # backtrack from call site to include all previous consecutive blocks
@@ -773,6 +821,7 @@ class StringObfuscationFinder(Analysis):
773
821
  # setup sp and bp, just in case
774
822
  state.regs._sp = 0x7FFF0000
775
823
  bp_set = False
824
+ assert prop.model.input_states is not None
776
825
  prop_state = prop.model.input_states.get(call_site_addr, None)
777
826
  if prop_state is not None:
778
827
  for reg_offset, reg_width in reg_reads:
@@ -798,7 +847,7 @@ class StringObfuscationFinder(Analysis):
798
847
  else:
799
848
  simgr.step()
800
849
  if not simgr.active:
801
- return None
850
+ return None, False
802
851
 
803
852
  in_state = simgr.active[0]
804
853
 
@@ -821,33 +870,63 @@ class StringObfuscationFinder(Analysis):
821
870
  try:
822
871
  ret_value = callable_0()
823
872
  except (AngrCallableMultistateError, AngrCallableError):
824
- return None
873
+ return None, False
825
874
 
826
875
  out_state = callable_0.result_state
827
876
 
828
877
  # figure out what was written
878
+ assert out_state is not None
829
879
  ptr = out_state.memory.load(ret_value, size=self.project.arch.bytes, endness=self.project.arch.memory_endness)
880
+ if out_state.memory.load(ptr, size=4).concrete_value == 0:
881
+ # fall back to using the return value as the pointer
882
+ ptr = ret_value
883
+ if out_state.memory.load(ptr, size=4).concrete_value == 0:
884
+ # can't find a valid pointer
885
+ return None, False
886
+
830
887
  size = out_state.memory.load(ret_value + 8, size=4, endness=self.project.arch.memory_endness)
888
+ guessed_size = False
889
+ if size.symbolic or size.concrete_value == 0 or size.concrete_value >= 1024:
890
+ size = 64
891
+ guessed_size = True
831
892
  # TODO: Support lists with varied-length elements
832
893
  data = out_state.memory.load(ptr, size=size, endness="Iend_BE")
833
894
  if data.symbolic:
834
- return None
895
+ return None, False
835
896
 
836
- return out_state.solver.eval(data, cast_to=bytes)
897
+ return out_state.solver.eval(data, cast_to=bytes), guessed_size
837
898
 
838
899
  @staticmethod
839
900
  def _is_block_setting_constants_to_stack(block, threshold: int = 5) -> bool:
840
- insn_setting_consts = 0
901
+ insn_setting_const_bytes = 0
902
+ xmm_has_const = False
841
903
  for insn in block.capstone.insns:
842
- if (
843
- insn.mnemonic.startswith("mov")
844
- and len(insn.operands) == 2
845
- and insn.operands[0].type == capstone.x86.X86_OP_MEM
846
- and insn.operands[0].mem.base in {capstone.x86.X86_REG_RSP, capstone.x86.X86_REG_RBP}
847
- and insn.operands[1].type == capstone.x86.X86_OP_IMM
848
- ):
849
- insn_setting_consts += 1
850
- return insn_setting_consts >= threshold
904
+ if insn.mnemonic.startswith("mov") and len(insn.operands) == 2:
905
+ if (
906
+ insn.operands[0].type == capstone.x86.X86_OP_MEM
907
+ and insn.operands[0].mem.base in {capstone.x86.X86_REG_RSP, capstone.x86.X86_REG_RBP}
908
+ and insn.operands[1].type == capstone.x86.X86_OP_IMM
909
+ ):
910
+ # mov [rsp|rbp + offset], imm
911
+ insn_setting_const_bytes += 1 # FIXME: How to get the size of the mov in capstone?
912
+ if (
913
+ insn.operands[0].type == capstone.x86.X86_OP_REG
914
+ and insn.operands[0].reg in ALL_X64_XMM_REGS
915
+ and insn.operands[1].type == capstone.x86.X86_OP_MEM
916
+ and insn.operands[1].mem.base == capstone.x86.X86_REG_RIP
917
+ ):
918
+ xmm_has_const = True
919
+ if (
920
+ xmm_has_const
921
+ and insn.operands[0].type == capstone.x86.X86_OP_MEM
922
+ and insn.operands[0].mem.base in {capstone.x86.X86_REG_RSP, capstone.x86.X86_REG_RBP}
923
+ and insn.operands[1].type == capstone.x86.X86_OP_REG
924
+ and insn.operands[1].reg in ALL_X64_XMM_REGS
925
+ ):
926
+ # mov [rsp|rbp + offset], xmm0 - 31
927
+ insn_setting_const_bytes += 16
928
+
929
+ return insn_setting_const_bytes >= threshold
851
930
 
852
931
  @staticmethod
853
932
  def _is_string_reasonable(s: bytes) -> bool:
@@ -857,5 +936,24 @@ class StringObfuscationFinder(Analysis):
857
936
  s = s.replace(b"\x00", b"")
858
937
  return all(chr(ch) in string.printable for ch in s)
859
938
 
939
+ @staticmethod
940
+ def _consecutive_printable_substrings(s: bytes, min_length: int = 3) -> list[bytes]:
941
+ """
942
+ Find all consecutive printable substrings in a string.
943
+ """
944
+ substrings = []
945
+ current_substring = b""
946
+ for ch in s:
947
+ if chr(ch) in string.printable:
948
+ current_substring += bytes([ch])
949
+ else:
950
+ if current_substring:
951
+ if len(current_substring) >= min_length:
952
+ substrings.append(current_substring)
953
+ current_substring = b""
954
+ if current_substring:
955
+ substrings.append(current_substring)
956
+ return substrings
957
+
860
958
 
861
959
  AnalysesHub.register_default("StringObfuscationFinder", StringObfuscationFinder)
angr/engines/icicle.py CHANGED
@@ -123,7 +123,7 @@ class IcicleEngine(ConcreteEngine):
123
123
  if proj is None:
124
124
  raise ValueError("IcicleEngine requires a project to be set")
125
125
 
126
- emu = Icicle(icicle_arch, PROCESSORS_DIR, True)
126
+ emu = Icicle(icicle_arch, PROCESSORS_DIR, True, True)
127
127
 
128
128
  copied_registers = set()
129
129
 
@@ -174,6 +174,11 @@ class IcicleEngine(ConcreteEngine):
174
174
  initial_cpu_icount=emu.cpu_icount,
175
175
  )
176
176
 
177
+ # 3. Copy edge hitmap
178
+ edge_hitmap = state.history.last_edge_hitmap
179
+ if edge_hitmap is not None:
180
+ emu.edge_hitmap = edge_hitmap
181
+
177
182
  return (emu, translation_data)
178
183
 
179
184
  @staticmethod
@@ -221,9 +226,12 @@ class IcicleEngine(ConcreteEngine):
221
226
  # Skip the last block, because it will be added by Successors
222
227
  state.history.recent_bbl_addrs.extend([b[0] for b in emu.recent_blocks][:-1])
223
228
 
224
- # 4. Set history.recent_instruction_count
229
+ # 3.3. Set history.recent_instruction_count
225
230
  state.history.recent_instruction_count = emu.cpu_icount - translation_data.initial_cpu_icount
226
231
 
232
+ # 3.4. Set edge hitmap
233
+ state.history.edge_hitmap = emu.edge_hitmap
234
+
227
235
  return state
228
236
 
229
237
  @override
angr/rustylib.pyd CHANGED
Binary file
@@ -59,6 +59,9 @@ class SimStateHistory(SimStatePlugin):
59
59
  self.recent_syscall_count = 0 if clone is None else clone.recent_syscall_count
60
60
  self.recent_instruction_count = -1 if clone is None else clone.recent_instruction_count
61
61
 
62
+ # afl-style hitmap
63
+ self.edge_hitmap: bytes | None = None if clone is None else clone.edge_hitmap
64
+
62
65
  # satness stuff
63
66
  self._all_constraints = ()
64
67
  self._satisfiable = None
@@ -402,6 +405,19 @@ class SimStateHistory(SimStatePlugin):
402
405
  def stack_actions(self):
403
406
  return LambdaIterIter(self, operator.attrgetter("recent_stack_actions"))
404
407
 
408
+ @property
409
+ def last_edge_hitmap(self) -> bytes | None:
410
+ """
411
+ Returns the last edge hitmap in the history chain, or None if there is no edge hitmap.
412
+ """
413
+ history = self
414
+ while history is not None:
415
+ if history.edge_hitmap is not None:
416
+ return history.edge_hitmap
417
+ # Traverse to the previous state in the history chain
418
+ history = history.parent
419
+ return None
420
+
405
421
  #
406
422
  # Merging support
407
423
  #
angr/unicornlib.dll CHANGED
Binary file
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: angr
3
- Version: 9.2.164
3
+ Version: 9.2.165
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
  License: BSD-2-Clause
6
6
  Project-URL: Homepage, https://angr.io/
@@ -16,12 +16,12 @@ Description-Content-Type: text/markdown
16
16
  License-File: LICENSE
17
17
  Requires-Dist: cxxheaderparser
18
18
  Requires-Dist: GitPython
19
- Requires-Dist: archinfo==9.2.164
19
+ Requires-Dist: archinfo==9.2.165
20
20
  Requires-Dist: cachetools
21
21
  Requires-Dist: capstone==5.0.3
22
22
  Requires-Dist: cffi>=1.14.0
23
- Requires-Dist: claripy==9.2.164
24
- Requires-Dist: cle==9.2.164
23
+ Requires-Dist: claripy==9.2.165
24
+ Requires-Dist: cle==9.2.165
25
25
  Requires-Dist: mulpyplexer
26
26
  Requires-Dist: networkx!=2.8.1,>=2.0
27
27
  Requires-Dist: protobuf>=5.28.2
@@ -30,7 +30,7 @@ Requires-Dist: pycparser>=2.18
30
30
  Requires-Dist: pydemumble
31
31
  Requires-Dist: pyformlang
32
32
  Requires-Dist: pypcode<4.0,>=3.2.1
33
- Requires-Dist: pyvex==9.2.164
33
+ Requires-Dist: pyvex==9.2.165
34
34
  Requires-Dist: rich>=13.1.0
35
35
  Requires-Dist: sortedcontainers
36
36
  Requires-Dist: sympy
@@ -1,4 +1,4 @@
1
- angr/__init__.py,sha256=CH6F91EXwthOZbyupfpEWLQ6AuJ8SZ290aETtucu03k,9246
1
+ angr/__init__.py,sha256=Jzf5SkZpGKPPRzfua6STXqvMfUyT2S0lcUDuVZKeRGk,9246
2
2
  angr/__main__.py,sha256=AK9V6uPZ58UuTKmmiH_Kgn5pG9AvjnmJCPOku69A-WU,4993
3
3
  angr/annocfg.py,sha256=0NIvcuCskwz45hbBzigUTAuCrYutjDMwEXtMJf0y0S0,10742
4
4
  angr/blade.py,sha256=OGGW-oggqI9_LvgZhiQuh9Ktkvf3vhRBmH0XviNyZ6o,15801
@@ -15,7 +15,7 @@ angr/keyed_region.py,sha256=Cx6dadqFgEvRmEHTbCJpg9mXkBtKGc_BKckHc6bk1IU,17992
15
15
  angr/knowledge_base.py,sha256=hRoSLuLaOXmddTSF9FN5TVs7liftpBGq_IICz5AaYBk,4533
16
16
  angr/project.py,sha256=AJmBgv3U8iv-hGEfnpmESVVjK16NiBAemmahLuqz7yk,38096
17
17
  angr/py.typed,sha256=la67KBlbjXN-_-DfGNcdOcjYumVpKG_Tkw-8n5dnGB4,8
18
- angr/rustylib.pyd,sha256=Q0rywAE67yvPoRHTaylffp24v-IsXCcmNGM5MWcCd6U,4441088
18
+ angr/rustylib.pyd,sha256=IRycDjBKxFY8O2UK9VnuWqDhf16cNEPcgwyvGWQxGWM,4456960
19
19
  angr/serializable.py,sha256=l908phj_KcqopEEL_oCufbP_H6cm3Wc9v-5xdux1-6g,1533
20
20
  angr/sim_manager.py,sha256=w7yTfWR-P9yoN5x85eeiNpj9dTrnjpJ3o5aoFpDAPnc,39396
21
21
  angr/sim_options.py,sha256=tfl57MFECmA7uvMMtQrRRbpG8g_A9jKOzwY6nApTW6Y,17782
@@ -27,7 +27,7 @@ angr/sim_variable.py,sha256=3DssmMw5G7m_-MYToJ3LBP-ooy2UQEuI2YgxIuX3d4Y,13177
27
27
  angr/slicer.py,sha256=DND0BERanYKafasRH9MDFAng0rSjdjmzXj2-phCD6CQ,10634
28
28
  angr/state_hierarchy.py,sha256=qDQCUGXmQm3vOxE3CSoiqTH4OAFFOWZZt9BLhNpeOhA,8484
29
29
  angr/tablespecs.py,sha256=Kx1e87FxTx3_ZN7cAHWZSRpdInT4Vfj5gExAWtLkLTw,3259
30
- angr/unicornlib.dll,sha256=2mVrMM8WfkFzi0IyfxPXZLjNBOFqUN3Q3OUTBiQ2Z4g,813568
30
+ angr/unicornlib.dll,sha256=x615-V8z6ATaO7xNGK-H1OYtFJxBJnueHMd0UfA3PNQ,813568
31
31
  angr/vaults.py,sha256=D_gkDegCyPlZMKGC5E8zINYAaZfSXNWbmhX0rXCYpvM,9718
32
32
  angr/ailment/__init__.py,sha256=X1LTS6MuTovGtbXBjZendUVOzRk-ib-bP0imuqJDOYI,2039
33
33
  angr/ailment/block.py,sha256=rkmimsNPhrUabVVbRd2IgCaW0hA2_isvAsKlYtHZhgY,2428
@@ -42,7 +42,7 @@ angr/ailment/statement.py,sha256=3JEhg-JDRrNjaeHFgO-liEIrZRW6v5sIsOqcGHiuM3A,304
42
42
  angr/ailment/tagged_object.py,sha256=48xIMC5WKebEpA12Zq6dQz3evvKxT3ULEu2cPdw9w-Y,1566
43
43
  angr/ailment/utils.py,sha256=YprhO7yJcd5jUKDbCXFMmPdCd8BIOhqXti-zb3mtxRQ,2830
44
44
  angr/analyses/__init__.py,sha256=KFu0Otm7bqAcjX8dsnQzphJmkUVxMLssjFIJJOci32U,3479
45
- angr/analyses/analysis.py,sha256=9FRa8ojMPhfzfLm7qsuBrrJeMKq2gTXF6pGfdA8o4yQ,14890
45
+ angr/analyses/analysis.py,sha256=2ABUppMZr97ZEAmxOQuXo-eyw5aF0ZASAii8SuuncNo,15685
46
46
  angr/analyses/backward_slice.py,sha256=fdE1GbppXjGufLzfOQkeuIzGX0yx9ISHJlOGqS6m1lg,27218
47
47
  angr/analyses/binary_optimizer.py,sha256=xFDv8c1s5nQUKY_EWYRCuVroSXFkMiSLl5LngPiysDA,26145
48
48
  angr/analyses/bindiff.py,sha256=ysphJ9cg7yxnW7HxOSLYEohrTdq9ZK-8cVvKQ0U9u9M,64020
@@ -88,7 +88,7 @@ angr/analyses/cfg/cfg.py,sha256=dc9M91CaLeEKduYfMwpsT_01x6XyYuoNvgvcDKtbN-I,3177
88
88
  angr/analyses/cfg/cfg_arch_options.py,sha256=_XRewFZ51SeNaxChadb6_ER7-8LW8KXeTIpoP8_iRj0,3506
89
89
  angr/analyses/cfg/cfg_base.py,sha256=eleUmM_znfsl6KV7T2tUmSEy2iLmPsrT3dNB2BYudd4,124964
90
90
  angr/analyses/cfg/cfg_emulated.py,sha256=4lKrmGVfCGt8l3Nz9zH6EcUcAVLwyOM7p81DlxUVNGA,148351
91
- angr/analyses/cfg/cfg_fast.py,sha256=J1nhaV9yC6SjQ_TWOJ7e0wfiCPa11pfxjTlns9IErlg,232462
91
+ angr/analyses/cfg/cfg_fast.py,sha256=e0rl_AIM1ne-GZK7yuDPNkceyNSZIYY77sg0-jvjsyo,232943
92
92
  angr/analyses/cfg/cfg_fast_soot.py,sha256=8YgMtY_8w4nAMcHR6n-q_eFvKwsvNz0anUH7EzIL1B4,25924
93
93
  angr/analyses/cfg/cfg_job_base.py,sha256=Zshze972MakTsd-licQz77lac17igQaaTsAteHeHhYQ,5974
94
94
  angr/analyses/cfg/indirect_jump_resolvers/__init__.py,sha256=qWiTSIAQgXWmaYa9YYaiKsSTwUVClymaXv9sCX-bY-k,835
@@ -123,7 +123,7 @@ angr/analyses/decompiler/block_similarity.py,sha256=S1lTlXFyOmJlQa7I3y7xgLsENLS4
123
123
  angr/analyses/decompiler/block_simplifier.py,sha256=XcX9wsBM4AL_WWqmFrtSUDeSv0a125cC1-Q1NhmTrNE,14777
124
124
  angr/analyses/decompiler/callsite_maker.py,sha256=O7vjwNTmCLijzjKgSCaoX3IX4_sC-u-OqoKhE7lahlc,23427
125
125
  angr/analyses/decompiler/clinic.py,sha256=1TnX_kIvZ4kFoK818Tyq98ONATP82T9n7fB4akx9yHg,150921
126
- angr/analyses/decompiler/condition_processor.py,sha256=g8sknCiCoBx3rXsHy2nx0VKDymSoSyLpq5zMpvFUhWg,54441
126
+ angr/analyses/decompiler/condition_processor.py,sha256=ECv0HHJt48tOGjzKUQezZ1lUS3_Qqu2a8E-6W5SMerI,54425
127
127
  angr/analyses/decompiler/decompilation_cache.py,sha256=gAZtyXs-eoFj3680bTrJVAZcIoaPsFK0kayu30NYLb4,1509
128
128
  angr/analyses/decompiler/decompilation_options.py,sha256=NDB67DI1L-stvJ4b1eQkfV26HgDJ_rG9-6PEv08G9-8,8195
129
129
  angr/analyses/decompiler/decompiler.py,sha256=3TsG9Tz4OQInSXcHhoASqxY7VhRsaK8xw-ZV9-Y-zhc,30533
@@ -197,7 +197,7 @@ angr/analyses/decompiler/optimization_passes/duplication_reverter/duplication_re
197
197
  angr/analyses/decompiler/optimization_passes/duplication_reverter/errors.py,sha256=dJq1F3jbGBFWi0zIUmDu8bwUAKPt-JyAh5iegY9rYuU,527
198
198
  angr/analyses/decompiler/optimization_passes/duplication_reverter/similarity.py,sha256=H9FGTyxHm-KbqgxuTe2qjMotboRbUyOTeiPVcD_8DSk,4411
199
199
  angr/analyses/decompiler/optimization_passes/duplication_reverter/utils.py,sha256=_WiRuxiMaxRAYtU5LiHGQ383PiI0sCt-KgG2QFG0KX4,5176
200
- angr/analyses/decompiler/peephole_optimizations/__init__.py,sha256=pqd1vDt1GO_6n1wbRtis0iq0nTkMh3bwwA17MaiUuIs,4869
200
+ angr/analyses/decompiler/peephole_optimizations/__init__.py,sha256=TSpLThx8U5YK05r779be8SozeTya0zbziPOZDKCGa6M,4930
201
201
  angr/analyses/decompiler/peephole_optimizations/a_div_const_add_a_mul_n_div_const.py,sha256=HY6EQkThiyMaahz3bodJUqLBKWY2n4aKGbKyspMXN50,1641
202
202
  angr/analyses/decompiler/peephole_optimizations/a_mul_const_div_shr_const.py,sha256=-V60wMaBKz1Ld1NcaQ8Dl0T4Xo9Qq6nfAQpXJ-MNsDI,1379
203
203
  angr/analyses/decompiler/peephole_optimizations/a_mul_const_sub_a.py,sha256=5Gsq3DSQEWt3tZSkrxnbAEePkKC_dmpoQHZ2PVNlSfs,1158
@@ -221,8 +221,9 @@ angr/analyses/decompiler/peephole_optimizations/conv_a_sub0_shr_and.py,sha256=4f
221
221
  angr/analyses/decompiler/peephole_optimizations/conv_shl_shr.py,sha256=STmu5FE0EHOkCdxFJt44DhMAjbAagnuics5VV6aNmnM,2110
222
222
  angr/analyses/decompiler/peephole_optimizations/eager_eval.py,sha256=t1Kn5ffzwio7AUO3EDtAbGvBFiR2gaRLIXBpOZ9LSIU,20612
223
223
  angr/analyses/decompiler/peephole_optimizations/extended_byte_and_mask.py,sha256=NU1D1xqyQi4SaCUrJ9bk51-hjcFNseQgqD0wgQkh558,2049
224
- angr/analyses/decompiler/peephole_optimizations/inlined_strcpy.py,sha256=HPXGn8PWsMGyi4EfgMIwho82H_RthwPKvlq2cdxFF2I,6462
225
- angr/analyses/decompiler/peephole_optimizations/inlined_strcpy_consolidation.py,sha256=1s7_nlpyJKuJGwCrZESlYw2dPL49VgKPQT8wVbmCeYs,4912
224
+ angr/analyses/decompiler/peephole_optimizations/inlined_memcpy.py,sha256=5OAgdFMTRlTggLQSUbVcUdgUmkJN7_p4wYkqt1A4AYQ,2944
225
+ angr/analyses/decompiler/peephole_optimizations/inlined_strcpy.py,sha256=q2IVsIFhfo0TGY3PfeOmCZqdpzUI2B3Tjv_p3_jpwl4,8668
226
+ angr/analyses/decompiler/peephole_optimizations/inlined_strcpy_consolidation.py,sha256=d-O_rIm0OrwK88P0zYBZcOY0ewTdCp4bnkJZDdWUUVw,4883
226
227
  angr/analyses/decompiler/peephole_optimizations/inlined_wstrcpy.py,sha256=irbBK2HB75f27L2EnHPuwDHumz1GBYqVwB96zoe-SFM,6787
227
228
  angr/analyses/decompiler/peephole_optimizations/invert_negated_logical_conjuction_disjunction.py,sha256=hRx0tuK_s47AEgPfaWYbzh5lPfBhx_anGDTVoIxHYkg,1990
228
229
  angr/analyses/decompiler/peephole_optimizations/modulo_simplifier.py,sha256=M09Whprj6tOJdFI5n9a7b-82YZOgnm3QvIbISJ9Lvaw,3724
@@ -294,7 +295,7 @@ angr/analyses/deobfuscator/api_obf_finder.py,sha256=044ZCXK6D5BZjVyPfe0isAFDzDDD
294
295
  angr/analyses/deobfuscator/api_obf_peephole_optimizer.py,sha256=jtUxKYTdmGu0c_8zmP8V3JUYzTcac0j1CNctic3e7QA,2215
295
296
  angr/analyses/deobfuscator/api_obf_type2_finder.py,sha256=tPUfe_2jJV1uZB5cetgglf3T75E_UQZYVUFAfMACV9g,6389
296
297
  angr/analyses/deobfuscator/irsb_reg_collector.py,sha256=q91IYpepptTQWcF0MJLHVCuvUsUuzPcL2XbbcIDV4eo,1290
297
- angr/analyses/deobfuscator/string_obf_finder.py,sha256=bCd5Weos3Xn5nQUdoQfq2MioouTP-DdN0LUmxxmMK3s,36440
298
+ angr/analyses/deobfuscator/string_obf_finder.py,sha256=cbwako92izix5V6tct95PpqK6nUE7YEUyNU8EAcyTes,40528
298
299
  angr/analyses/deobfuscator/string_obf_opt_passes.py,sha256=YzrsEKsUaUPshB8LqfwDso8aK7m0ySmR3i50T5ZiwNo,5360
299
300
  angr/analyses/deobfuscator/string_obf_peephole_optimizer.py,sha256=_VQv2E2yOAZDAi53smQL5KcSLNe5FMqNUYC8jNSYXGs,1957
300
301
  angr/analyses/fcp/__init__.py,sha256=E9dxFckDM9DijfU4RRg9SGL6xDKCz7yBBP-XSkS-S9U,115
@@ -434,7 +435,7 @@ angr/engines/concrete.py,sha256=kEt6Dyp8QAIaOP3oW5lRcDs_2UMP2vbiNzylGiqvf7g,2143
434
435
  angr/engines/engine.py,sha256=2kwOT-sbxKXAVX2PmsPTr8Ax36Vxq6hkRdDKaITBQNc,657
435
436
  angr/engines/failure.py,sha256=redqmkSuJoIc828hpmX3CTk4EqQ-PeEn7MK2uIqSAc0,1040
436
437
  angr/engines/hook.py,sha256=lAEYYAXQY_GDOpsz3JZ7IswxrBccZnZ6EaQwyNBb4W8,2590
437
- angr/engines/icicle.py,sha256=SzqHmA0bo4ThrfR1k5FNpYwmLg07LW8kUMu2ZaHQgkc,10079
438
+ angr/engines/icicle.py,sha256=8mAL_YEumoP95C3p0r7yoGdi68Xq2sz9-qpGjAu5ffE,10333
438
439
  angr/engines/procedure.py,sha256=8kgFH56nkqSWm0p1apuGBaFngl-4BnAzE0bXhq9mc6Y,2561
439
440
  angr/engines/successors.py,sha256=oQCW7Knxb4zz7EP6Mi6RrRNrwuhbv5fnX8UL76nn0sY,29501
440
441
  angr/engines/syscall.py,sha256=7wYTriURsDTTi3PEBj4u3ZWDi7RHBV-gRrxTRxwMAVk,2166
@@ -1291,7 +1292,7 @@ angr/state_plugins/debug_variables.py,sha256=LR-lsjnn6FVrEr8RCVkhA_gyeeh1jiHC92u
1291
1292
  angr/state_plugins/filesystem.py,sha256=qkM2zCfcrSBjt-g3RO1VYbjHPNRSdvsNRQR_M47pqFU,15765
1292
1293
  angr/state_plugins/gdb.py,sha256=CrilA-FPDNm7Fk5fWx9wOn_gVb4SRJyFyNPcef7oOr0,5175
1293
1294
  angr/state_plugins/globals.py,sha256=pU8_VPSjLLsW2x7vr_f2uFRMEIobqDjXQJUp5YDbkNU,1593
1294
- angr/state_plugins/history.py,sha256=TY266XyRZA8LkSXf5TX3yfGTRJnvVByySZcCsDTkG2A,19214
1295
+ angr/state_plugins/history.py,sha256=f_d3QxcN0TYe2tZxCz1ojBKmb2oNjIAuKWYNZFEfL8I,19782
1295
1296
  angr/state_plugins/inspect.py,sha256=9hXBRAL9C8rGqGdS9joydSsBsIrgu_pVLNmZeO_fqFs,11350
1296
1297
  angr/state_plugins/javavm_classloader.py,sha256=QOkvHSVnoiaEKX6HK520viBemFpxXBcaXeC_csLSmhY,5589
1297
1298
  angr/state_plugins/jni_references.py,sha256=ufNi66U9-O2c7bzOv1cAxykcEu3uj6PvbIOy_CV2Z2I,3451
@@ -1400,9 +1401,9 @@ angr/utils/vex.py,sha256=epcrCexi_NjKnPGM2gfpiRsUea_Scd-71UMuF32ZAQo,306
1400
1401
  angr/utils/ssa/__init__.py,sha256=xbuVllFoPane9lHACdRQP5OO99Mca-4sqpFrtoAvnxo,17464
1401
1402
  angr/utils/ssa/tmp_uses_collector.py,sha256=digAUQpYoFR1VYfwoXlF3T1pYdDi6Pdq_ck54SjMabQ,813
1402
1403
  angr/utils/ssa/vvar_uses_collector.py,sha256=HewqUQluNE9EsaiLeFo7LaBvws_DDBDYNt9RBExy464,1367
1403
- angr-9.2.164.dist-info/licenses/LICENSE,sha256=PmWf0IlSz6Jjp9n7nyyBQA79Q5C2ma68LRykY1V3GF0,1456
1404
- angr-9.2.164.dist-info/METADATA,sha256=abdzxTnPw1r7XfknxLeYnLHgglSPpltkv6xbkHw3pxg,4453
1405
- angr-9.2.164.dist-info/WHEEL,sha256=OJ2zpOfp3Fst0GC5jHtFuY8tAf46LLgZ9O920dE4b3c,100
1406
- angr-9.2.164.dist-info/entry_points.txt,sha256=Vjh1C8PMyr5dZFMnik5WkEP01Uwr2T73I3a6N32sgQU,44
1407
- angr-9.2.164.dist-info/top_level.txt,sha256=dKw0KWTbwLXytFvv15oAAG4sUs3ey47tt6DorJG9-hw,5
1408
- angr-9.2.164.dist-info/RECORD,,
1404
+ angr-9.2.165.dist-info/licenses/LICENSE,sha256=PmWf0IlSz6Jjp9n7nyyBQA79Q5C2ma68LRykY1V3GF0,1456
1405
+ angr-9.2.165.dist-info/METADATA,sha256=RgxSY1QhXwxPTOYdu6EUkhQuZyh3g5HvWk15uifPayU,4453
1406
+ angr-9.2.165.dist-info/WHEEL,sha256=OJ2zpOfp3Fst0GC5jHtFuY8tAf46LLgZ9O920dE4b3c,100
1407
+ angr-9.2.165.dist-info/entry_points.txt,sha256=Vjh1C8PMyr5dZFMnik5WkEP01Uwr2T73I3a6N32sgQU,44
1408
+ angr-9.2.165.dist-info/top_level.txt,sha256=dKw0KWTbwLXytFvv15oAAG4sUs3ey47tt6DorJG9-hw,5
1409
+ angr-9.2.165.dist-info/RECORD,,
File without changes