angr 9.2.167__cp310-abi3-manylinux_2_28_x86_64.whl → 9.2.168__cp310-abi3-manylinux_2_28_x86_64.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.167"
5
+ __version__ = "9.2.168"
6
6
 
7
7
  if bytes is str:
8
8
  raise Exception(
angr/analyses/cfg/cfb.py CHANGED
@@ -119,19 +119,19 @@ class CFBlanket(Analysis):
119
119
  def _init_regions(self):
120
120
  for obj in self.project.loader.all_objects:
121
121
  if isinstance(obj, cle.MetaELF):
122
- if obj.sections:
122
+ if obj.segments:
123
+ if "segment" not in self._exclude_region_types:
124
+ for segment in obj.segments:
125
+ if segment.memsize > 0:
126
+ mr = MemoryRegion(segment.vaddr, segment.memsize, "segment", obj, segment)
127
+ self._regions.append(mr)
128
+ elif obj.sections:
123
129
  if "section" not in self._exclude_region_types:
124
130
  # Enumerate sections in an ELF file
125
131
  for section in obj.sections:
126
132
  if section.occupies_memory:
127
133
  mr = MemoryRegion(section.vaddr, section.memsize, "section", obj, section)
128
134
  self._regions.append(mr)
129
- elif obj.segments:
130
- if "segment" not in self._exclude_region_types:
131
- for segment in obj.segments:
132
- if segment.memsize > 0:
133
- mr = MemoryRegion(segment.vaddr, segment.memsize, "segment", obj, segment)
134
- self._regions.append(mr)
135
135
  else:
136
136
  raise NotImplementedError(
137
137
  "Currently ELFs without sections or segments are not supported. Please "
@@ -55,6 +55,7 @@ from .optimization_passes import (
55
55
 
56
56
  if TYPE_CHECKING:
57
57
  from angr.knowledge_plugins.cfg import CFGModel
58
+ from .notes import DecompilationNote
58
59
  from .decompilation_cache import DecompilationCache
59
60
  from .peephole_optimizations import PeepholeOptimizationStmtBase, PeepholeOptimizationExprBase
60
61
 
@@ -149,6 +150,7 @@ class Clinic(Analysis):
149
150
  ail_graph: networkx.DiGraph | None = None,
150
151
  arg_vvars: dict[int, tuple[ailment.Expr.VirtualVariable, SimVariable]] | None = None,
151
152
  start_stage: ClinicStage | None = ClinicStage.INITIALIZATION,
153
+ notes: dict[str, DecompilationNote] | None = None,
152
154
  ):
153
155
  if not func.normalized and mode == ClinicMode.DECOMPILE:
154
156
  raise ValueError("Decompilation must work on normalized function graphs.")
@@ -194,6 +196,8 @@ class Clinic(Analysis):
194
196
  # actual stack variables. these secondary stack variables can be safely eliminated if not used by anything.
195
197
  self.secondary_stackvars: set[int] = set()
196
198
 
199
+ self.notes = notes if notes is not None else {}
200
+
197
201
  #
198
202
  # intermediate variables used during decompilation
199
203
  #
@@ -1555,6 +1559,7 @@ class Clinic(Analysis):
1555
1559
  refine_loops_with_single_successor=self._refine_loops_with_single_successor,
1556
1560
  complete_successors=self._complete_successors,
1557
1561
  stack_pointer_tracker=stack_pointer_tracker,
1562
+ notes=self.notes,
1558
1563
  **kwargs,
1559
1564
  )
1560
1565
  if a.out_graph:
@@ -22,6 +22,7 @@ class DecompilationCache:
22
22
  "errors",
23
23
  "func_typevar",
24
24
  "ite_exprs",
25
+ "notes",
25
26
  "parameters",
26
27
  "type_constraints",
27
28
  "var_to_typevar",
@@ -38,6 +39,7 @@ class DecompilationCache:
38
39
  self.ite_exprs: set[tuple[int, Any]] | None = None
39
40
  self.binop_operators: dict[OpDescriptor, str] | None = None
40
41
  self.errors: list[str] = []
42
+ self.notes: dict[str, str] = {}
41
43
 
42
44
  @property
43
45
  def local_types(self):
@@ -239,6 +239,16 @@ options = [
239
239
  default_value=False,
240
240
  clears_cache=True,
241
241
  ),
242
+ O(
243
+ "Display decompilation notes as comments",
244
+ "Display decompilation notes in the outpu as function comments.",
245
+ bool,
246
+ "codegen",
247
+ "display_notes",
248
+ category="Display",
249
+ default_value=False,
250
+ clears_cache=False,
251
+ ),
242
252
  O(
243
253
  "Multi-expression statements generation",
244
254
  "Should the structuring algorithm generate multi-expression statements? If so, under what conditions?",
@@ -21,12 +21,13 @@ from .region_identifier import RegionIdentifier
21
21
  from .optimization_passes.optimization_pass import OptimizationPassStage
22
22
  from .ailgraph_walker import AILGraphWalker
23
23
  from .condition_processor import ConditionProcessor
24
- from .decompilation_options import DecompilationOption
24
+ from .decompilation_options import DecompilationOption, PARAM_TO_OPTION
25
25
  from .decompilation_cache import DecompilationCache
26
26
  from .utils import remove_edges_in_ailgraph
27
27
  from .sequence_walker import SequenceWalker
28
28
  from .structuring.structurer_nodes import SequenceNode
29
29
  from .presets import DECOMPILATION_PRESETS, DecompilationPreset
30
+ from .notes import DecompilationNote
30
31
 
31
32
  if TYPE_CHECKING:
32
33
  from angr.knowledge_plugins.cfg.cfg_model import CFGModel
@@ -80,7 +81,7 @@ class Decompiler(Analysis):
80
81
  func = self.kb.functions[func]
81
82
  self.func: Function = func
82
83
  self._cfg = cfg.model if isinstance(cfg, CFGFast) else cfg
83
- self._options = options or []
84
+ self._options = self._parse_options(options) if options else []
84
85
 
85
86
  if preset is None and optimization_passes:
86
87
  self._optimization_passes = optimization_passes
@@ -145,6 +146,7 @@ class Decompiler(Analysis):
145
146
  self._copied_var_ids: set[int] = set()
146
147
  self._optimization_scratch: dict[str, Any] = {}
147
148
  self.expr_collapse_depth = expr_collapse_depth
149
+ self.notes: dict[str, DecompilationNote] = {}
148
150
 
149
151
  if decompile:
150
152
  with self._resilience():
@@ -171,6 +173,20 @@ class Decompiler(Analysis):
171
173
  id_checks = {"cfg", "variable_kb"}
172
174
  return all(a[k] is b[k] if k in id_checks else a[k] == b[k] for k in self._cache_parameters)
173
175
 
176
+ @staticmethod
177
+ def _parse_options(options: list[tuple[DecompilationOption | str, Any]]) -> list[tuple[DecompilationOption, Any]]:
178
+ """
179
+ Parse the options and return a list of option tuples.
180
+ """
181
+
182
+ converted_options = []
183
+ for o, v in options:
184
+ if isinstance(o, str):
185
+ # convert to DecompilationOption
186
+ o = PARAM_TO_OPTION[o]
187
+ converted_options.append((o, v))
188
+ return converted_options
189
+
174
190
  @timethis
175
191
  def _decompile(self):
176
192
  if self.func.is_simprocedure:
@@ -268,6 +284,7 @@ class Decompiler(Analysis):
268
284
  ail_graph=self._clinic_graph,
269
285
  arg_vvars=self._clinic_arg_vvars,
270
286
  start_stage=self._clinic_start_stage,
287
+ notes=self.notes,
271
288
  **self.options_to_params(self.options_by_class["clinic"]),
272
289
  )
273
290
  else:
@@ -378,6 +395,7 @@ class Decompiler(Analysis):
378
395
  const_formats=old_codegen.const_formats if old_codegen is not None else None,
379
396
  externs=clinic.externs,
380
397
  binop_depth_cutoff=self.expr_collapse_depth,
398
+ notes=self.notes,
381
399
  **self.options_to_params(self.options_by_class["codegen"]),
382
400
  )
383
401
 
@@ -0,0 +1,9 @@
1
+ from __future__ import annotations
2
+
3
+ from .decompilation_note import DecompilationNote, DecompilationNoteLevel
4
+
5
+
6
+ __all__ = (
7
+ "DecompilationNote",
8
+ "DecompilationNoteLevel",
9
+ )
@@ -0,0 +1,48 @@
1
+ from __future__ import annotations
2
+ from typing import Any
3
+
4
+ from enum import Enum
5
+
6
+
7
+ class DecompilationNoteLevel(Enum):
8
+ """
9
+ Enum class describing the level of each decompilation note.
10
+ """
11
+
12
+ DEBUG = 0
13
+ INFO = 1
14
+ WARNING = 2
15
+ CRITICAL = 3
16
+
17
+
18
+ class DecompilationNote:
19
+ """
20
+ Describes a note that is generated during decompilation.
21
+
22
+ Key is a unique string for the decompilation note. It is used as an index in the decompilation notes dictionary in
23
+ the Decompiler class.
24
+ Name is string for display by default.
25
+ Content is the actual content of the note. It can be of any time, but for custom types, you must override `__str__`
26
+ so that it can be displayed.
27
+ Level is the level of the note. The following values are available: DecompilationNoteLevel.DEBUG,
28
+ DecompilationNoteLevel.INFO, DecompilationNoteLevel.WARNING, and DecompilationNoteLevel.CRITICAL.
29
+ """
30
+
31
+ __slots__ = (
32
+ "content",
33
+ "key",
34
+ "level",
35
+ "name",
36
+ )
37
+
38
+ def __init__(self, key: str, name: str, content: Any, *, level=DecompilationNoteLevel.INFO):
39
+ self.key = key
40
+ self.name = name
41
+ self.content = content
42
+ self.level = level
43
+
44
+ def __repr__(self):
45
+ return f"<DecompilationNote: {self.name}>"
46
+
47
+ def __str__(self):
48
+ return f"{self.name}: {self.content}"
@@ -0,0 +1,56 @@
1
+ from __future__ import annotations
2
+
3
+ from .decompilation_note import DecompilationNote
4
+
5
+
6
+ class DeobfuscatedString:
7
+ """
8
+ Represents a deobfuscated string.
9
+ """
10
+
11
+ __slots__ = ("ref_addr", "type", "value")
12
+
13
+ def __init__(self, value: bytes, obf_type: str, ref_addr: int | None = None):
14
+ self.value = value
15
+ self.type = obf_type
16
+ self.ref_addr = ref_addr
17
+
18
+ def __repr__(self):
19
+ return (
20
+ f"<DeobfuscatedString Type{self.type} value={self.value!r} ref={self.ref_addr:#x}>"
21
+ if self.ref_addr is not None
22
+ else f"<DeobfuscatedString Type{self.type} value={self.value!r}>"
23
+ )
24
+
25
+ def __str__(self):
26
+ return repr(self.value)
27
+
28
+
29
+ class DeobfuscatedStringsNote(DecompilationNote):
30
+ """
31
+ Represents a decompilation note that describes obfuscated strings found during decompilation.
32
+ """
33
+
34
+ def __init__(self, key: str = "deobfuscated_strings", name: str = "Deobfuscated Strings"):
35
+ super().__init__(key, name, None)
36
+
37
+ self.strings: dict[int, DeobfuscatedString] = {}
38
+
39
+ def add_string(self, obf_type: str, value: bytes, *, ref_addr: int):
40
+ """
41
+ Add a deobfuscated string to the note.
42
+
43
+ :param obf_type: The type of obfuscation (e.g., "1", "2").
44
+ :param value: The deobfuscated string value.
45
+ :param ref_addr: The address where this string is referenced, if applicable.
46
+ """
47
+ deobf_str = DeobfuscatedString(value, obf_type, ref_addr=ref_addr)
48
+ self.strings[ref_addr] = deobf_str
49
+
50
+ def __str__(self):
51
+ lines = ["Obfuscated strings are found in decompilation and have been deobfuscated:"]
52
+ for addr in sorted(self.strings):
53
+ deobf_str = self.strings[addr]
54
+ lines.append(f" Type {deobf_str.type} @ {deobf_str.ref_addr:#x}: {deobf_str.value!r}")
55
+
56
+ return "\n".join(lines)
@@ -141,6 +141,7 @@ class OptimizationPass(BaseOptimizationPass):
141
141
  arg_vvars: set[int] | None = None,
142
142
  peephole_optimizations=None,
143
143
  stack_pointer_tracker=None,
144
+ notes: dict | None = None,
144
145
  **kwargs,
145
146
  ):
146
147
  super().__init__(func)
@@ -164,6 +165,7 @@ class OptimizationPass(BaseOptimizationPass):
164
165
  self._avoid_vvar_ids = avoid_vvar_ids or set()
165
166
  self._peephole_optimizations = peephole_optimizations
166
167
  self._stack_pointer_tracker = stack_pointer_tracker
168
+ self.notes = notes if notes is not None else {}
167
169
 
168
170
  # output
169
171
  self.out_graph: networkx.DiGraph | None = None
@@ -1,3 +1,4 @@
1
+ # pylint:disable=missing-class-docstring
1
2
  from __future__ import annotations
2
3
  from sortedcontainers import SortedDict
3
4
 
@@ -114,13 +115,45 @@ class InstructionMapping:
114
115
 
115
116
 
116
117
  class BaseStructuredCodeGenerator:
117
- def __init__(self, flavor=None):
118
+ def __init__(self, flavor=None, notes=None):
118
119
  self.flavor = flavor
119
120
  self.text = None
120
121
  self.map_pos_to_node = None
121
122
  self.map_pos_to_addr = None
122
123
  self.map_addr_to_pos = None
123
124
  self.map_ast_to_pos: dict[SimVariable, set[PositionMappingElement]] | None = None
125
+ self.notes = notes if notes is not None else {}
126
+
127
+ def adjust_mapping_positions(
128
+ self,
129
+ offset: int,
130
+ pos_to_node: PositionMapping,
131
+ pos_to_addr: PositionMapping,
132
+ addr_to_pos: InstructionMapping,
133
+ ) -> tuple[PositionMapping, PositionMapping, InstructionMapping]:
134
+ """
135
+ Adjust positions in the mappings to account for the notes that are prepended to the text.
136
+
137
+ :param offset: The length of the notes to prepend.
138
+ :param pos_to_node: The position to node mapping.
139
+ :param pos_to_addr: The position to address mapping.
140
+ :param addr_to_pos: The address to position mapping.
141
+ :return: Adjusted mappings.
142
+ """
143
+ new_pos_to_node = PositionMapping()
144
+ new_pos_to_addr = PositionMapping()
145
+ new_addr_to_pos = InstructionMapping()
146
+
147
+ for pos, node in pos_to_node.items():
148
+ new_pos_to_node.add_mapping(pos + offset, node.length, node.obj)
149
+
150
+ for pos, node in pos_to_addr.items():
151
+ new_pos_to_addr.add_mapping(pos + offset, node.length, node.obj)
152
+
153
+ for addr, pos in addr_to_pos.items():
154
+ new_addr_to_pos.add_mapping(addr, pos.posmap_pos + offset)
155
+
156
+ return new_pos_to_node, new_pos_to_addr, new_addr_to_pos
124
157
 
125
158
  def reapply_options(self, options):
126
159
  pass
@@ -43,6 +43,7 @@ from angr.utils.library import get_cpp_function_name
43
43
  from angr.utils.loader import is_in_readonly_segment, is_in_readonly_section
44
44
  from angr.utils.types import unpack_typeref, unpack_pointer_and_array, dereference_simtype_by_lib
45
45
  from angr.analyses.decompiler.utils import structured_node_is_simple_return
46
+ from angr.analyses.decompiler.notes.deobfuscated_strings import DeobfuscatedStringsNote
46
47
  from angr.errors import UnsupportedNodeTypeError, AngrRuntimeError
47
48
  from angr.knowledge_plugins.cfg.memory_data import MemoryData, MemoryDataSort
48
49
  from angr.analyses import Analysis, register_analysis
@@ -254,7 +255,7 @@ class CConstruct:
254
255
  self.tags = tags or {}
255
256
  self.codegen: StructuredCodeGenerator = codegen
256
257
 
257
- def c_repr(self, indent=0, pos_to_node=None, pos_to_addr=None, addr_to_pos=None):
258
+ def c_repr(self, initial_pos=0, indent=0, pos_to_node=None, pos_to_addr=None, addr_to_pos=None):
258
259
  """
259
260
  Creates the C representation of the code and displays it by
260
261
  constructing a large string. This function is called by each program function that needs to be decompiled.
@@ -268,7 +269,7 @@ class CConstruct:
268
269
 
269
270
  def mapper(chunks):
270
271
  # start all positions at beginning of document
271
- pos = 0
272
+ pos = initial_pos
272
273
 
273
274
  last_insn_addr = None
274
275
 
@@ -2520,8 +2521,10 @@ class CStructuredCodeGenerator(BaseStructuredCodeGenerator, Analysis):
2520
2521
  display_block_addrs=False,
2521
2522
  display_vvar_ids=False,
2522
2523
  min_data_addr: int = 0x400_000,
2524
+ notes=None,
2525
+ display_notes: bool = True,
2523
2526
  ):
2524
- super().__init__(flavor=flavor)
2527
+ super().__init__(flavor=flavor, notes=notes)
2525
2528
 
2526
2529
  self._handlers = {
2527
2530
  CodeNode: self._handle_Code,
@@ -2604,6 +2607,7 @@ class CStructuredCodeGenerator(BaseStructuredCodeGenerator, Analysis):
2604
2607
  self.map_addr_to_label: dict[tuple[int, int | None], CLabel] = {}
2605
2608
  self.cfunc: CFunction | None = None
2606
2609
  self.cexterns: set[CVariable] | None = None
2610
+ self.display_notes = display_notes
2607
2611
 
2608
2612
  self._analyze()
2609
2613
 
@@ -2700,9 +2704,20 @@ class CStructuredCodeGenerator(BaseStructuredCodeGenerator, Analysis):
2700
2704
  ast_to_pos = defaultdict(set)
2701
2705
 
2702
2706
  text = cfunc.c_repr(
2703
- indent=self._indent, pos_to_node=pos_to_node, pos_to_addr=pos_to_addr, addr_to_pos=addr_to_pos
2707
+ initial_pos=0,
2708
+ indent=self._indent,
2709
+ pos_to_node=pos_to_node,
2710
+ pos_to_addr=pos_to_addr,
2711
+ addr_to_pos=addr_to_pos,
2704
2712
  )
2705
2713
 
2714
+ if self.display_notes:
2715
+ notes = self.render_notes()
2716
+ pos_to_node, pos_to_addr, addr_to_pos = self.adjust_mapping_positions(
2717
+ len(notes), pos_to_node, pos_to_addr, addr_to_pos
2718
+ )
2719
+ text = notes + text
2720
+
2706
2721
  for elem, node in pos_to_node.items():
2707
2722
  if isinstance(node.obj, CConstant):
2708
2723
  ast_to_pos[node.obj.value].add(elem)
@@ -2726,6 +2741,21 @@ class CStructuredCodeGenerator(BaseStructuredCodeGenerator, Analysis):
2726
2741
 
2727
2742
  return text, pos_to_node, pos_to_addr, addr_to_pos, ast_to_pos
2728
2743
 
2744
+ def render_notes(self) -> str:
2745
+ """
2746
+ Render decompilation notes.
2747
+
2748
+ :return: A string containing all notes.
2749
+ """
2750
+ if not self.notes:
2751
+ return ""
2752
+
2753
+ lines = []
2754
+ for note in self.notes.values():
2755
+ note_lines = str(note).split("\n")
2756
+ lines += [f"// {line}" for line in note_lines]
2757
+ return "\n".join(lines) + "\n\n"
2758
+
2729
2759
  def _get_variable_type(self, var, is_global=False):
2730
2760
  if is_global:
2731
2761
  return self._variable_kb.variables["global"].get_variable_type(var)
@@ -3601,14 +3631,18 @@ class CStructuredCodeGenerator(BaseStructuredCodeGenerator, Analysis):
3601
3631
  reference_values = {}
3602
3632
  type_ = unpack_typeref(type_)
3603
3633
  if expr.value in self.kb.obfuscations.type1_deobfuscated_strings:
3604
- reference_values[SimTypePointer(SimTypeChar())] = self.kb.obfuscations.type1_deobfuscated_strings[
3605
- expr.value
3606
- ]
3634
+ deobf_str = self.kb.obfuscations.type1_deobfuscated_strings[expr.value]
3635
+ reference_values[SimTypePointer(SimTypeChar())] = deobf_str
3636
+ if "deobfuscated_strings" not in self.notes:
3637
+ self.notes["deobfuscated_strings"] = DeobfuscatedStringsNote()
3638
+ self.notes["deobfuscated_strings"].add_string("1", deobf_str, ref_addr=expr.value)
3607
3639
  inline_string = True
3608
3640
  elif expr.value in self.kb.obfuscations.type2_deobfuscated_strings:
3609
- reference_values[SimTypePointer(SimTypeChar())] = self.kb.obfuscations.type2_deobfuscated_strings[
3610
- expr.value
3611
- ]
3641
+ deobf_str = self.kb.obfuscations.type2_deobfuscated_strings[expr.value]
3642
+ reference_values[SimTypePointer(SimTypeChar())] = deobf_str
3643
+ if "deobfuscated_strings" not in self.notes:
3644
+ self.notes["deobfuscated_strings"] = DeobfuscatedStringsNote()
3645
+ self.notes["deobfuscated_strings"].add_string("2", deobf_str, ref_addr=expr.value)
3612
3646
  inline_string = True
3613
3647
  elif isinstance(type_, SimTypePointer) and isinstance(type_.pts_to, (SimTypeChar, SimTypeBottom)):
3614
3648
  # char* or void*
@@ -173,10 +173,8 @@ class StringObfuscationFinder(Analysis):
173
173
  continue
174
174
 
175
175
  # decompile this function and see if it "looks like" a deobfuscation function
176
- try:
177
- dec = self.project.analyses.Decompiler(func, cfg=cfg)
178
- except Exception: # pylint:disable=broad-exception-caught
179
- continue
176
+ with self._resilience():
177
+ dec = self.project.analyses.Decompiler(func, cfg=cfg, fail_fast=self._fail_fast) # type:ignore
180
178
  if (
181
179
  dec.codegen is None
182
180
  or not dec.codegen.text
@@ -470,10 +468,13 @@ class StringObfuscationFinder(Analysis):
470
468
  continue
471
469
 
472
470
  # decompile this function and see if it "looks like" a deobfuscation function
473
- try:
474
- dec = self.project.analyses.Decompiler(func, cfg=cfg, expr_collapse_depth=64)
475
- except Exception: # pylint:disable=broad-exception-caught
476
- continue
471
+ with self._resilience():
472
+ dec = self.project.analyses.Decompiler(
473
+ func,
474
+ cfg=cfg,
475
+ expr_collapse_depth=64,
476
+ fail_fast=self._fail_fast, # type:ignore
477
+ )
477
478
  if (
478
479
  dec.codegen is None
479
480
  or not dec.codegen.text
@@ -666,11 +667,9 @@ class StringObfuscationFinder(Analysis):
666
667
  continue
667
668
 
668
669
  # take a look at the content
669
- try:
670
- dec = self.project.analyses.Decompiler(func, cfg=cfg)
671
- except Exception: # pylint:disable=broad-exception-caught
670
+ with self._resilience():
672
671
  # catch all exceptions
673
- continue
672
+ dec = self.project.analyses.Decompiler(func, cfg=cfg, fail_fast=self._fail_fast) # type:ignore
674
673
  if dec.codegen is None or not dec.codegen.text:
675
674
  continue
676
675
 
@@ -736,7 +735,7 @@ class StringObfuscationFinder(Analysis):
736
735
  callinsn2content = {}
737
736
  for idx, call_site in enumerate(call_sites):
738
737
  _l.debug("Analyzing type 3 candidate call site %#x (%d/%d)...", call_site.addr, idx + 1, len(call_sites))
739
- assert call_site.function_address is not None
738
+ assert call_site.function_address is not None and isinstance(call_site.function_address, int)
740
739
  data, _ = self._type3_prepare_and_execute(func_addr, call_site.addr, call_site.function_address, cfg)
741
740
  if data:
742
741
  callinsn2content[call_site.instruction_addrs[-1]] = data
@@ -831,7 +830,7 @@ class StringObfuscationFinder(Analysis):
831
830
  # at least a byte
832
831
  continue
833
832
  con = prop_state.load_register(reg_offset, reg_width // 8)
834
- if isinstance(con, claripy.ast.Base) and con.op == "BVV":
833
+ if isinstance(con, claripy.ast.Base) and con.op == "BVV" and isinstance(con.concrete_value, int):
835
834
  state.registers.store(reg_offset, claripy.BVV(con.concrete_value, reg_width))
836
835
  if reg_offset == state.arch.bp_offset:
837
836
  bp_set = True
@@ -851,7 +850,11 @@ class StringObfuscationFinder(Analysis):
851
850
 
852
851
  in_state = simgr.active[0]
853
852
 
854
- cc = default_cc(self.project.arch.name, self.project.simos.name)(self.project.arch)
853
+ cc_cls = default_cc(self.project.arch.name, self.project.simos.name)
854
+ assert (
855
+ cc_cls is not None
856
+ ), f"Failed to obtain the default calling convention for {self.project.arch.name}-{self.project.simos.name}."
857
+ cc = cc_cls(self.project.arch)
855
858
  cc.STACKARG_SP_BUFF = 0 # disable shadow stack space because the binary code already sets it if needed
856
859
  cc.STACK_ALIGNMENT = 1 # disable stack address aligning because the binary code already sets it if needed
857
860
  prototype_0 = SimTypeFunction([], SimTypePointer(pts_to=SimTypeBottom(label="void"))).with_arch(
@@ -875,7 +878,7 @@ class StringObfuscationFinder(Analysis):
875
878
  out_state = callable_0.result_state
876
879
 
877
880
  # figure out what was written
878
- assert out_state is not None
881
+ assert out_state is not None and ret_value is not None
879
882
  ptr = out_state.memory.load(ret_value, size=self.project.arch.bytes, endness=self.project.arch.memory_endness)
880
883
  if out_state.memory.load(ptr, size=4).concrete_value == 0:
881
884
  # fall back to using the return value as the pointer
@@ -7,6 +7,7 @@ from angr.ailment import Block
7
7
  from angr.ailment.statement import Statement, Call, Assignment
8
8
  from angr.ailment.expression import Const, Register, VirtualVariable
9
9
 
10
+ from angr.analyses.decompiler.notes.deobfuscated_strings import DeobfuscatedStringsNote
10
11
  from angr.analyses.decompiler.optimization_passes.optimization_pass import OptimizationPass, OptimizationPassStage
11
12
  from angr.analyses.decompiler.optimization_passes import register_optimization_pass
12
13
 
@@ -57,9 +58,11 @@ class StringObfType3Rewriter(OptimizationPass):
57
58
  self.is_call_or_call_assignment(last_stmt)
58
59
  and last_stmt.ins_addr in self.kb.obfuscations.type3_deobfuscated_strings
59
60
  ):
60
- new_block = self._process_block(
61
- block, self.kb.obfuscations.type3_deobfuscated_strings[block.statements[-1].ins_addr]
62
- )
61
+ the_str = self.kb.obfuscations.type3_deobfuscated_strings[block.statements[-1].ins_addr]
62
+ if "deobfuscated_strings" not in self.kb.notes:
63
+ self.kb.notes["deobfuscated_strings"] = DeobfuscatedStringsNote("deobfuscated_strings")
64
+ self.kb.notes["deobfuscated_strings"].add_string("3", the_str, ref_addr=last_stmt.ins_addr)
65
+ new_block = self._process_block(block, the_str)
63
66
  if new_block is not None:
64
67
  self._update_block(block, new_block)
65
68
 
angr/rustylib.abi3.so CHANGED
Binary file
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: angr
3
- Version: 9.2.167
3
+ Version: 9.2.168
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.167
19
+ Requires-Dist: archinfo==9.2.168
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.167
24
- Requires-Dist: cle==9.2.167
23
+ Requires-Dist: claripy==9.2.168
24
+ Requires-Dist: cle==9.2.168
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.167
33
+ Requires-Dist: pyvex==9.2.168
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=l2XMymhaDdbXPxobunMDaeunXuyotEqHq1WF8Fc0pK4,9246
1
+ angr/__init__.py,sha256=8sb0b7E65y73bsJbTKbs7bOQI7L7L1bYJthAqzkYPJo,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.abi3.so,sha256=xy5ObAx1TjJWIrACfO9zBNm_rZdqhTesDcLbiuxJkuw,5837576
18
+ angr/rustylib.abi3.so,sha256=8oUYrTHXPGS_zlBI-0QbBY3SV3YQmbyNindzEjLQTJE,5837360
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
@@ -83,7 +83,7 @@ angr/analyses/calling_convention/calling_convention.py,sha256=vdGqrv7SQDnO6Rg9rg
83
83
  angr/analyses/calling_convention/fact_collector.py,sha256=SCdNm-6qfgj-SRnbtPpzzkZBS0nH0Ik3zPn5wLG6-7Y,28480
84
84
  angr/analyses/calling_convention/utils.py,sha256=twkO073RvkkFXnOTc-KYQT1GKUtz0OPjxh0N6AWIriQ,2110
85
85
  angr/analyses/cfg/__init__.py,sha256=-w8Vd6FD6rtjlQaQ7MxwmliFgS2zt-kZepAY4gHas04,446
86
- angr/analyses/cfg/cfb.py,sha256=scykl1FJvqcTe2x69zreWi0PG_zYMbka3k6tlRwaD_g,15367
86
+ angr/analyses/cfg/cfb.py,sha256=7JibFw5NyGWIbZnWMn7NS0zOqpB5s3KvxRoK8bEJOOs,15367
87
87
  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
@@ -122,11 +122,11 @@ angr/analyses/decompiler/block_io_finder.py,sha256=9J56W0_SQPczZ2-VoxqSv61T57foH
122
122
  angr/analyses/decompiler/block_similarity.py,sha256=S1lTlXFyOmJlQa7I3y7xgLsENLS4XGET7tdD55k_6Vg,6859
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
- angr/analyses/decompiler/clinic.py,sha256=XfPjnSpu4PqVoEzIxGrTRwnoWLR5ioUu-fND2xaxWdo,151158
125
+ angr/analyses/decompiler/clinic.py,sha256=rGR5ODSEZyHX1cmEuUNPKxK3BNcVAg-97TlppxhdtDs,151349
126
126
  angr/analyses/decompiler/condition_processor.py,sha256=ALx1EO82EWOfj1mjWhS_8GNMLdEO98jqnIqB-CtfELg,56692
127
- angr/analyses/decompiler/decompilation_cache.py,sha256=gAZtyXs-eoFj3680bTrJVAZcIoaPsFK0kayu30NYLb4,1509
128
- angr/analyses/decompiler/decompilation_options.py,sha256=NDB67DI1L-stvJ4b1eQkfV26HgDJ_rG9-6PEv08G9-8,8195
129
- angr/analyses/decompiler/decompiler.py,sha256=_0C5z_xd635inlB9sL7syV6U9Z0aTortlL05TNclF40,31020
127
+ angr/analyses/decompiler/decompilation_cache.py,sha256=06oiG299mVpGOTL54Xy1CUxz5s8QLgYJn5XIvKFLYkU,1566
128
+ angr/analyses/decompiler/decompilation_options.py,sha256=bs6CNpU3UxepgBB_9eUH4jriNpGoryyPP0sR1hDWpTk,8477
129
+ angr/analyses/decompiler/decompiler.py,sha256=Mw1C-VPO283ghNS6P5KscjQLhH7Yj19SDCiSDzwU7ME,31716
130
130
  angr/analyses/decompiler/empty_node_remover.py,sha256=4CdxTM1AVmRoEdRIwJg1YEy10AgkEoRmJ8SU7xGbKnM,7424
131
131
  angr/analyses/decompiler/expression_narrower.py,sha256=lBtcsPu4V5JJ_u25GF-BJ3vaybu8TRr9XxmnjOrA4J8,10367
132
132
  angr/analyses/decompiler/goto_manager.py,sha256=wVoeXJcadIda84LloGgqW-rL0QHLv3fx4vZHLhmz-_o,4027
@@ -159,6 +159,9 @@ angr/analyses/decompiler/dephication/graph_rewriting.py,sha256=cRMrYJgGV57H5TzWY
159
159
  angr/analyses/decompiler/dephication/graph_vvar_mapping.py,sha256=wvGWiSOa-2PnHpsLn3UkYwOYnFGJtFj0SpCn0bWl6k8,16224
160
160
  angr/analyses/decompiler/dephication/rewriting_engine.py,sha256=qBX6yrtJQhjiSRBz0mBjafF1lTrl22oToOErxIFSr4w,18623
161
161
  angr/analyses/decompiler/dephication/seqnode_dephication.py,sha256=kigkzU78eNe-zD16hUI2YMNt_jHvixpohHpnLhAHMlw,5437
162
+ angr/analyses/decompiler/notes/__init__.py,sha256=4e5yTEQr5tnTQt8BfsMXqRUUpWPaQIFLzsgNVx55VJw,181
163
+ angr/analyses/decompiler/notes/decompilation_note.py,sha256=MTFHVMlfmJGrKGuvlHppcIEFR1FWF9xW8_0U0xoFOUo,1352
164
+ angr/analyses/decompiler/notes/deobfuscated_strings.py,sha256=f9AtSSVIB7kAlPUlkLxqNodco4KWbYivPV3Yh8KjVTo,1877
162
165
  angr/analyses/decompiler/optimization_passes/__init__.py,sha256=y7ND9Wg98M5SoMGuOespoLeh1s-wFqKyeW2_4esDsiw,5236
163
166
  angr/analyses/decompiler/optimization_passes/base_ptr_save_simplifier.py,sha256=-kuCQk0ALYM1rmr6VaijrZYgHseeXqlWECaekKfI6hE,6120
164
167
  angr/analyses/decompiler/optimization_passes/call_stmt_rewriter.py,sha256=INLmzfGDMsVzyQF2S6uwiQSoNcxM7DUBJrdWlL2gqlY,1325
@@ -179,7 +182,7 @@ angr/analyses/decompiler/optimization_passes/ite_expr_converter.py,sha256=DA2H1U
179
182
  angr/analyses/decompiler/optimization_passes/ite_region_converter.py,sha256=8Q2Yh7QcKuoO51zfEa0abnTPES_QQRWbjiu3ZUntwvQ,13792
180
183
  angr/analyses/decompiler/optimization_passes/lowered_switch_simplifier.py,sha256=_p9puK2bvp055mqSW28QIqXWpZD-OpsunWPQrOWmT9Q,42130
181
184
  angr/analyses/decompiler/optimization_passes/mod_simplifier.py,sha256=9ekxyvxF8g3tN5oanUg96HaYiyYVbj5Nf-vSeeq86kI,3384
182
- angr/analyses/decompiler/optimization_passes/optimization_pass.py,sha256=5MbM2DcGAKRTyydge7_ZkOkj-bswmK-qW5Ozk5cmZA8,28078
185
+ angr/analyses/decompiler/optimization_passes/optimization_pass.py,sha256=VGpCQmx8H2w3HoVFGdqwYYZ0z_IdHrFjOhz37yvxxTQ,28169
183
186
  angr/analyses/decompiler/optimization_passes/register_save_area_simplifier.py,sha256=-MoVamrPN9fMakQMZPwRYQ5rbeuQURXvyELuUhPVXKI,9088
184
187
  angr/analyses/decompiler/optimization_passes/ret_addr_save_simplifier.py,sha256=A7azHMeTQDXPFj44lI-mK7wnbJZ6cdSL-lwwqxiBTk0,6420
185
188
  angr/analyses/decompiler/optimization_passes/ret_deduplicator.py,sha256=hqOBkbiyQwGDoPdkMLwJjJOI_90QQ2R6ESs2HQ4z0iw,8005
@@ -280,8 +283,8 @@ angr/analyses/decompiler/ssailification/traversal.py,sha256=rvFatMUpQQMbENCsPoPo
280
283
  angr/analyses/decompiler/ssailification/traversal_engine.py,sha256=MdmNKWN2LVQ9fH7O-E4yNn5oXUS2p2u1qHM_OayPJ-k,11466
281
284
  angr/analyses/decompiler/ssailification/traversal_state.py,sha256=RDs2mTc6GYnbMom2gBfNfNMcazKMSkhemEmse8uELTY,1558
282
285
  angr/analyses/decompiler/structured_codegen/__init__.py,sha256=mxG4yruPAab8735wVgXZ1zu8qFPz-njKe0m5UcywE3o,633
283
- angr/analyses/decompiler/structured_codegen/base.py,sha256=DEeNrBOC8AAJb-qFyUoYeX8fpHSPmAsutCDF-0UhaQ4,3782
284
- angr/analyses/decompiler/structured_codegen/c.py,sha256=MvVnWYmvV5KhcQY9bg8X56z45HnRkSwM0XKKXvhuz0g,148169
286
+ angr/analyses/decompiler/structured_codegen/base.py,sha256=mb5d5iQO1N2wMl7QySvfHemXM-e0yQBhjtlmnLsVSgE,5134
287
+ angr/analyses/decompiler/structured_codegen/c.py,sha256=ebZzyHrh0Jt6fPL6gi-MDgRoA4OeXtb_NVePMLe2h4A,149613
285
288
  angr/analyses/decompiler/structured_codegen/dummy.py,sha256=JZLeovXE-8C-unp2hbejxCG30l-yCx4sWFh7JMF_iRM,570
286
289
  angr/analyses/decompiler/structured_codegen/dwarf_import.py,sha256=J6V40RuIyKXN7r6ESftIYfoREgmgFavnUL5m3lyTzlM,7072
287
290
  angr/analyses/decompiler/structuring/__init__.py,sha256=kEFP-zv9CZrhJtLTKwT9-9cGVTls71wLYaLDUuYorBU,711
@@ -296,8 +299,8 @@ angr/analyses/deobfuscator/api_obf_finder.py,sha256=044ZCXK6D5BZjVyPfe0isAFDzDDD
296
299
  angr/analyses/deobfuscator/api_obf_peephole_optimizer.py,sha256=jtUxKYTdmGu0c_8zmP8V3JUYzTcac0j1CNctic3e7QA,2215
297
300
  angr/analyses/deobfuscator/api_obf_type2_finder.py,sha256=tPUfe_2jJV1uZB5cetgglf3T75E_UQZYVUFAfMACV9g,6389
298
301
  angr/analyses/deobfuscator/irsb_reg_collector.py,sha256=q91IYpepptTQWcF0MJLHVCuvUsUuzPcL2XbbcIDV4eo,1290
299
- angr/analyses/deobfuscator/string_obf_finder.py,sha256=cbwako92izix5V6tct95PpqK6nUE7YEUyNU8EAcyTes,40528
300
- angr/analyses/deobfuscator/string_obf_opt_passes.py,sha256=YzrsEKsUaUPshB8LqfwDso8aK7m0ySmR3i50T5ZiwNo,5360
302
+ angr/analyses/deobfuscator/string_obf_finder.py,sha256=uJRQhpDj_QhcKLmKtiskx_DjcTWYn4oDUeQJfEQgOqQ,40829
303
+ angr/analyses/deobfuscator/string_obf_opt_passes.py,sha256=WsITtz2oskY9loF8dnkyoTlKHnurQo61qK7A8XEcFAU,5724
301
304
  angr/analyses/deobfuscator/string_obf_peephole_optimizer.py,sha256=_VQv2E2yOAZDAi53smQL5KcSLNe5FMqNUYC8jNSYXGs,1957
302
305
  angr/analyses/fcp/__init__.py,sha256=E9dxFckDM9DijfU4RRg9SGL6xDKCz7yBBP-XSkS-S9U,115
303
306
  angr/analyses/fcp/fcp.py,sha256=djkJsvSja_De7ptNwllmTHjvVl62BFcH_haBhwhzFtw,16373
@@ -1402,9 +1405,9 @@ angr/utils/vex.py,sha256=epcrCexi_NjKnPGM2gfpiRsUea_Scd-71UMuF32ZAQo,306
1402
1405
  angr/utils/ssa/__init__.py,sha256=xbuVllFoPane9lHACdRQP5OO99Mca-4sqpFrtoAvnxo,17464
1403
1406
  angr/utils/ssa/tmp_uses_collector.py,sha256=digAUQpYoFR1VYfwoXlF3T1pYdDi6Pdq_ck54SjMabQ,813
1404
1407
  angr/utils/ssa/vvar_uses_collector.py,sha256=HewqUQluNE9EsaiLeFo7LaBvws_DDBDYNt9RBExy464,1367
1405
- angr-9.2.167.dist-info/METADATA,sha256=4jaQlt9lgWILUCU3BXhhfePpxcqNESYYCNOellm0ztI,4343
1406
- angr-9.2.167.dist-info/WHEEL,sha256=LqR_W0RRJW31YMkRS3Dv-iW-Y--YJhfEgOaHweTHgb8,112
1407
- angr-9.2.167.dist-info/entry_points.txt,sha256=Vjh1C8PMyr5dZFMnik5WkEP01Uwr2T73I3a6N32sgQU,44
1408
- angr-9.2.167.dist-info/top_level.txt,sha256=dKw0KWTbwLXytFvv15oAAG4sUs3ey47tt6DorJG9-hw,5
1409
- angr-9.2.167.dist-info/RECORD,,
1410
- angr-9.2.167.dist-info/licenses/LICENSE,sha256=PmWf0IlSz6Jjp9n7nyyBQA79Q5C2ma68LRykY1V3GF0,1456
1408
+ angr-9.2.168.dist-info/METADATA,sha256=pU3aYBKHP3DeKRFpanh2HUXro-BaoZMy388FpSrCzHA,4343
1409
+ angr-9.2.168.dist-info/WHEEL,sha256=LqR_W0RRJW31YMkRS3Dv-iW-Y--YJhfEgOaHweTHgb8,112
1410
+ angr-9.2.168.dist-info/entry_points.txt,sha256=Vjh1C8PMyr5dZFMnik5WkEP01Uwr2T73I3a6N32sgQU,44
1411
+ angr-9.2.168.dist-info/top_level.txt,sha256=dKw0KWTbwLXytFvv15oAAG4sUs3ey47tt6DorJG9-hw,5
1412
+ angr-9.2.168.dist-info/RECORD,,
1413
+ angr-9.2.168.dist-info/licenses/LICENSE,sha256=PmWf0IlSz6Jjp9n7nyyBQA79Q5C2ma68LRykY1V3GF0,1456
File without changes