angr 9.2.175__cp310-abi3-win_amd64.whl → 9.2.176__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.

Files changed (42) hide show
  1. angr/__init__.py +1 -1
  2. angr/analyses/calling_convention/calling_convention.py +12 -0
  3. angr/analyses/complete_calling_conventions.py +39 -26
  4. angr/analyses/decompiler/ail_simplifier.py +13 -11
  5. angr/analyses/decompiler/ccall_rewriters/rewriter_base.py +5 -1
  6. angr/analyses/decompiler/clinic.py +54 -40
  7. angr/analyses/decompiler/optimization_passes/ite_region_converter.py +3 -3
  8. angr/analyses/decompiler/optimization_passes/lowered_switch_simplifier.py +2 -2
  9. angr/analyses/decompiler/peephole_optimizations/__init__.py +4 -4
  10. angr/analyses/decompiler/peephole_optimizations/{inlined_wstrcpy.py → inlined_wcscpy.py} +16 -8
  11. angr/analyses/decompiler/peephole_optimizations/{inlined_wstrcpy_consolidation.py → inlined_wcscpy_consolidation.py} +13 -13
  12. angr/analyses/decompiler/ssailification/rewriting_engine.py +14 -1
  13. angr/analyses/decompiler/structured_codegen/c.py +6 -5
  14. angr/analyses/decompiler/structuring/dream.py +2 -2
  15. angr/analyses/decompiler/structuring/phoenix.py +101 -23
  16. angr/analyses/stack_pointer_tracker.py +4 -3
  17. angr/analyses/typehoon/lifter.py +29 -18
  18. angr/analyses/typehoon/simple_solver.py +157 -50
  19. angr/analyses/typehoon/translator.py +34 -34
  20. angr/analyses/typehoon/typeconsts.py +33 -15
  21. angr/analyses/typehoon/typevars.py +9 -2
  22. angr/analyses/variable_recovery/engine_ail.py +4 -2
  23. angr/analyses/variable_recovery/engine_base.py +4 -1
  24. angr/analyses/variable_recovery/variable_recovery_fast.py +3 -1
  25. angr/engines/icicle.py +4 -4
  26. angr/engines/vex/claripy/ccall.py +3 -3
  27. angr/knowledge_plugins/functions/function.py +17 -0
  28. angr/procedures/posix/pthread.py +4 -4
  29. angr/procedures/stubs/format_parser.py +3 -3
  30. angr/rustylib.pyd +0 -0
  31. angr/sim_type.py +11 -6
  32. angr/simos/windows.py +1 -1
  33. angr/storage/memory_mixins/paged_memory/page_backer_mixins.py +1 -1
  34. angr/unicornlib.dll +0 -0
  35. angr/utils/constants.py +1 -1
  36. angr/utils/strings.py +20 -0
  37. {angr-9.2.175.dist-info → angr-9.2.176.dist-info}/METADATA +5 -5
  38. {angr-9.2.175.dist-info → angr-9.2.176.dist-info}/RECORD +42 -41
  39. {angr-9.2.175.dist-info → angr-9.2.176.dist-info}/WHEEL +0 -0
  40. {angr-9.2.175.dist-info → angr-9.2.176.dist-info}/entry_points.txt +0 -0
  41. {angr-9.2.175.dist-info → angr-9.2.176.dist-info}/licenses/LICENSE +0 -0
  42. {angr-9.2.175.dist-info → angr-9.2.176.dist-info}/top_level.txt +0 -0
@@ -5,6 +5,7 @@ All type constants used in type inference. They can be mapped, translated, or re
5
5
  from __future__ import annotations
6
6
 
7
7
  import functools
8
+ import itertools
8
9
 
9
10
 
10
11
  def memoize(f):
@@ -24,6 +25,9 @@ def memoize(f):
24
25
  class TypeConstant:
25
26
  SIZE = None
26
27
 
28
+ def __init__(self, name: str | None = None):
29
+ self.name = name
30
+
27
31
  def pp_str(self, mapping) -> str: # pylint:disable=unused-argument
28
32
  return repr(self)
29
33
 
@@ -115,7 +119,8 @@ class Int512(Int):
115
119
 
116
120
 
117
121
  class IntVar(Int):
118
- def __init__(self, size):
122
+ def __init__(self, size, name: str | None = None):
123
+ super().__init__(name)
119
124
  self._size = size
120
125
 
121
126
  @property
@@ -146,7 +151,8 @@ class Float64(Float):
146
151
 
147
152
 
148
153
  class Pointer(TypeConstant):
149
- def __init__(self, basetype: TypeConstant | None):
154
+ def __init__(self, basetype: TypeConstant | None, name: str | None = None):
155
+ super().__init__(name=name)
150
156
  self.basetype: TypeConstant | None = basetype
151
157
 
152
158
  def __eq__(self, other):
@@ -169,13 +175,15 @@ class Pointer32(Pointer, Int32):
169
175
  32-bit pointers.
170
176
  """
171
177
 
172
- def __init__(self, basetype=None):
173
- Pointer.__init__(self, basetype)
178
+ def __init__(self, basetype=None, name: str | None = None):
179
+ Pointer.__init__(self, basetype, name=name)
180
+ Int32.__init__(self, name=name)
174
181
 
175
182
  @memoize
176
183
  def __repr__(self, memo=None):
177
184
  bt = self.basetype.__repr__(memo=memo) if isinstance(self.basetype, TypeConstant) else repr(self.basetype)
178
- return f"ptr32({bt})"
185
+ name_str = f"{self.name}#" if self.name else ""
186
+ return f"{name_str}ptr32({bt})"
179
187
 
180
188
 
181
189
  class Pointer64(Pointer, Int64):
@@ -183,17 +191,20 @@ class Pointer64(Pointer, Int64):
183
191
  64-bit pointers.
184
192
  """
185
193
 
186
- def __init__(self, basetype=None):
187
- Pointer.__init__(self, basetype)
194
+ def __init__(self, basetype=None, name: str | None = None):
195
+ Pointer.__init__(self, basetype, name=name)
196
+ Int64.__init__(self, name=name)
188
197
 
189
198
  @memoize
190
199
  def __repr__(self, memo=None):
191
200
  bt = self.basetype.__repr__(memo=memo) if isinstance(self.basetype, TypeConstant) else repr(self.basetype)
192
- return f"ptr64({bt})"
201
+ name_str = f"{self.name}#" if self.name else ""
202
+ return f"{name_str}ptr64({bt})"
193
203
 
194
204
 
195
205
  class Array(TypeConstant):
196
- def __init__(self, element=None, count=None):
206
+ def __init__(self, element=None, count=None, name: str | None = None):
207
+ super().__init__(name=name)
197
208
  self.element: TypeConstant | None = element
198
209
  self.count: int | None = count
199
210
 
@@ -222,18 +233,22 @@ class Array(TypeConstant):
222
233
  return self._hash(set())
223
234
 
224
235
 
236
+ _STRUCT_ID = itertools.count()
237
+
238
+
225
239
  class Struct(TypeConstant):
226
- def __init__(self, fields=None, name=None, field_names=None, is_cppclass: bool = False):
240
+ def __init__(self, fields=None, name=None, field_names=None, is_cppclass: bool = False, idx: int = -1):
241
+ super().__init__(name=name)
227
242
  self.fields = {} if fields is None else fields # offset to type
228
- self.name = name
229
243
  self.field_names = field_names
230
244
  self.is_cppclass = is_cppclass
245
+ self.idx = idx if idx != -1 else next(_STRUCT_ID)
231
246
 
232
247
  def _hash(self, visited: set[int]):
233
248
  if id(self) in visited:
234
249
  return 0
235
250
  visited.add(id(self))
236
- return hash((type(self), self._hash_fields(visited)))
251
+ return hash((type(self), self.idx, self._hash_fields(visited)))
237
252
 
238
253
  def _hash_fields(self, visited: set[int]):
239
254
  keys = sorted(self.fields.keys())
@@ -252,6 +267,7 @@ class Struct(TypeConstant):
252
267
  @memoize
253
268
  def __repr__(self, memo=None):
254
269
  prefix = "CppClass" if self.is_cppclass else "struct"
270
+ prefix += f"#{self.idx}"
255
271
  if self.name:
256
272
  prefix = f"{prefix} {self.name}"
257
273
  return (
@@ -262,14 +278,15 @@ class Struct(TypeConstant):
262
278
  )
263
279
 
264
280
  def __eq__(self, other):
265
- return type(other) is type(self) and hash(self) == hash(other)
281
+ return type(other) is type(self) and self.idx == other.idx and hash(self) == hash(other)
266
282
 
267
283
  def __hash__(self):
268
284
  return self._hash(set())
269
285
 
270
286
 
271
287
  class Function(TypeConstant):
272
- def __init__(self, params: list, outputs: list):
288
+ def __init__(self, params: list, outputs: list, name: str | None = None):
289
+ super().__init__(name=name)
273
290
  self.params = params
274
291
  self.outputs = outputs
275
292
 
@@ -298,7 +315,8 @@ class Function(TypeConstant):
298
315
 
299
316
 
300
317
  class TypeVariableReference(TypeConstant):
301
- def __init__(self, typevar):
318
+ def __init__(self, typevar, name: str | None = None):
319
+ super().__init__(name=name)
302
320
  self.typevar = typevar
303
321
 
304
322
  def __repr__(self, memo=None):
@@ -559,20 +559,27 @@ class ReinterpretAs(BaseLabel):
559
559
 
560
560
 
561
561
  class HasField(BaseLabel):
562
+ """
563
+ Has a field of the given bit size * elem_count at the given offset.
564
+ """
565
+
562
566
  __slots__ = (
563
567
  "bits",
568
+ "elem_count",
564
569
  "offset",
565
570
  )
566
571
 
567
- def __init__(self, bits, offset):
572
+ def __init__(self, bits, offset, elem_count: int = 1):
568
573
  self.bits = bits
569
574
  self.offset = offset
575
+ self.elem_count = elem_count
570
576
  super().__init__()
571
577
 
572
578
  def __repr__(self):
573
579
  if self.bits == MAX_POINTSTO_BITS:
574
580
  return f"<MAX_POINTSTO_BITS>@{self.offset}"
575
- return f"<{self.bits} bits>@{self.offset}"
581
+ elem_str = str(self.elem_count) if self.elem_count != 1 else ""
582
+ return f"<{self.bits} bits>@{self.offset}{elem_str}"
576
583
 
577
584
 
578
585
  class IsArray(BaseLabel):
@@ -34,6 +34,7 @@ class SimEngineVRAIL(
34
34
  def __init__(
35
35
  self,
36
36
  *args,
37
+ type_lifter: TypeLifter,
37
38
  call_info=None,
38
39
  vvar_to_vvar: dict[int, int] | None,
39
40
  vvar_type_hints: dict[int, typeconsts.TypeConstant] | None = None,
@@ -44,6 +45,7 @@ class SimEngineVRAIL(
44
45
  self._reference_spoffset: bool = False
45
46
  self.call_info = call_info or {}
46
47
  self.vvar_to_vvar = vvar_to_vvar
48
+ self.type_lifter = type_lifter
47
49
 
48
50
  def _mapped_vvarid(self, vvar_id: int) -> int | None:
49
51
  if self.vvar_to_vvar is not None and vvar_id in self.vvar_to_vvar:
@@ -195,7 +197,7 @@ class SimEngineVRAIL(
195
197
  arg_type = (
196
198
  dereference_simtype_by_lib(arg_type, prototype_libname) if prototype_libname else arg_type
197
199
  )
198
- arg_ty = TypeLifter(self.arch.bits).lift(arg_type)
200
+ arg_ty = self.type_lifter.lift(arg_type)
199
201
  type_constraint = typevars.Subtype(arg.typevar, arg_ty)
200
202
  self.state.add_type_constraint(type_constraint)
201
203
 
@@ -282,7 +284,7 @@ class SimEngineVRAIL(
282
284
  arg_type = (
283
285
  dereference_simtype_by_lib(arg_type, prototype_libname) if prototype_libname else arg_type
284
286
  )
285
- arg_ty = TypeLifter(self.arch.bits).lift(arg_type)
287
+ arg_ty = self.type_lifter.lift(arg_type)
286
288
  if arg.typevar is not None and isinstance(
287
289
  arg_ty, (typeconsts.TypeConstant, typevars.TypeVariable, typevars.DerivedTypeVariable)
288
290
  ):
@@ -277,7 +277,10 @@ class SimEngineVRBase(
277
277
  variable, _ = existing_vars[0]
278
278
 
279
279
  if not self.state.typevars.has_type_variable_for(variable):
280
- variable_typevar = typevars.TypeVariable()
280
+ if isinstance(variable, SimStackVariable) and variable.offset in self.state.stack_offset_typevars:
281
+ variable_typevar = self.state.stack_offset_typevars[variable.offset]
282
+ else:
283
+ variable_typevar = typevars.TypeVariable()
281
284
  self.state.typevars.add_type_variable(variable, variable_typevar)
282
285
  # we do not add any type constraint here because we are not sure if the given memory address will ever be
283
286
  # accessed or not
@@ -284,6 +284,7 @@ class VariableRecoveryFast(ForwardAnalysis, VariableRecoveryBase): # pylint:dis
284
284
  self._unify_variables = unify_variables
285
285
 
286
286
  # handle type hints
287
+ self.type_lifter = TypeLifter(self.project.arch.bits)
287
288
  self.vvar_type_hints = {}
288
289
  if type_hints:
289
290
  self._parse_type_hints(type_hints)
@@ -294,6 +295,7 @@ class VariableRecoveryFast(ForwardAnalysis, VariableRecoveryBase): # pylint:dis
294
295
  call_info=call_info,
295
296
  vvar_to_vvar=self.vvar_to_vvar,
296
297
  vvar_type_hints=self.vvar_type_hints,
298
+ type_lifter=self.type_lifter,
297
299
  )
298
300
  self._vex_engine: SimEngineVRVEX = SimEngineVRVEX(self.project, self.kb, call_info=call_info)
299
301
 
@@ -654,7 +656,7 @@ class VariableRecoveryFast(ForwardAnalysis, VariableRecoveryBase): # pylint:dis
654
656
  if ty is None:
655
657
  return None
656
658
  ty = ty.with_arch(self.project.arch)
657
- lifted = TypeLifter(self.project.arch.bits).lift(ty)
659
+ lifted = self.type_lifter.lift(ty)
658
660
  return None if isinstance(lifted, (BottomType, TopType)) else lifted
659
661
 
660
662
 
angr/engines/icicle.py CHANGED
@@ -8,7 +8,7 @@ from dataclasses import dataclass
8
8
  from typing_extensions import override
9
9
 
10
10
  import pypcode
11
- from archinfo import Arch, Endness
11
+ from archinfo import Arch, Endness, ArchARMCortexM
12
12
 
13
13
  from angr.engines.concrete import ConcreteEngine, HeavyConcreteState
14
14
  from angr.engines.failure import SimEngineFailure
@@ -84,11 +84,11 @@ class IcicleEngine(ConcreteEngine):
84
84
  return icicle_arch.startswith(("arm", "thumb"))
85
85
 
86
86
  @staticmethod
87
- def __is_thumb(icicle_arch: str, addr: int) -> bool:
87
+ def __is_thumb(angr_arch: Arch, icicle_arch: str, addr: int) -> bool:
88
88
  """
89
89
  Check if the architecture is thumb based on the address.
90
90
  """
91
- return IcicleEngine.__is_arm(icicle_arch) and addr & 1 == 1
91
+ return isinstance(angr_arch, ArchARMCortexM) or (IcicleEngine.__is_arm(icicle_arch) and addr & 1 == 1)
92
92
 
93
93
  @staticmethod
94
94
  def __get_pages(state: HeavyConcreteState) -> set[int]:
@@ -138,7 +138,7 @@ class IcicleEngine(ConcreteEngine):
138
138
  log.debug("Register %s not found in icicle", register)
139
139
 
140
140
  # Unset the thumb bit if necessary
141
- if IcicleEngine.__is_thumb(icicle_arch, state.addr):
141
+ if IcicleEngine.__is_thumb(state.arch, icicle_arch, state.addr):
142
142
  emu.pc = state.addr & ~1
143
143
  emu.isa_mode = 1
144
144
  elif "arm" in icicle_arch: # Hack to work around us calling it r15t
@@ -343,7 +343,7 @@ def pc_make_rdata_if_necessary(nbits, cf, pf, af, zf, sf, of, platform=None):
343
343
 
344
344
 
345
345
  def pc_actions_ADD(state, nbits, arg_l, arg_r, cc_ndep, platform=None):
346
- data_mask, sign_mask = pc_preamble(nbits)
346
+ data_mask, _sign_mask = pc_preamble(nbits)
347
347
  res = arg_l + arg_r
348
348
 
349
349
  cf = claripy.If(claripy.ULT(res, arg_l), claripy.BVV(1, 1), claripy.BVV(0, 1))
@@ -701,7 +701,7 @@ def pc_calculate_rdata_all(state, cc_op, cc_dep1, cc_dep2, cc_ndep, platform=Non
701
701
  def pc_calculate_condition(state, cond, cc_op, cc_dep1, cc_dep2, cc_ndep, platform=None):
702
702
  rdata_all = pc_calculate_rdata_all_WRK(state, cc_op, cc_dep1, cc_dep2, cc_ndep, platform=platform)
703
703
  if isinstance(rdata_all, tuple):
704
- cf, pf, af, zf, sf, of = rdata_all
704
+ cf, pf, _af, zf, sf, of = rdata_all
705
705
  v = op_concretize(cond)
706
706
 
707
707
  inv = v & 1
@@ -993,7 +993,7 @@ def pc_calculate_rdata_c(state, cc_op, cc_dep1, cc_dep2, cc_ndep, platform=None)
993
993
  rdata_all = pc_calculate_rdata_all_WRK(state, cc_op, cc_dep1, cc_dep2, cc_ndep, platform=platform)
994
994
 
995
995
  if isinstance(rdata_all, tuple):
996
- cf, pf, af, zf, sf, of = rdata_all
996
+ cf, _pf, _af, _zf, _sf, _of = rdata_all
997
997
  return claripy.Concat(claripy.BVV(0, data[platform]["size"] - 1), cf & 1)
998
998
  return claripy.LShR(rdata_all, data[platform]["CondBitOffsets"]["G_CC_SHIFT_C"]) & 1
999
999
 
@@ -1750,6 +1750,23 @@ class Function(Serializable):
1750
1750
  _find_called(self.addr)
1751
1751
  return {self._function_manager.function(a) for a in called}
1752
1752
 
1753
+ def holes(self, min_size: int = 8) -> int:
1754
+ """
1755
+ Find the number of non-consecutive areas in the function that are at least `min_size` bytes large.
1756
+ """
1757
+
1758
+ block_addrs = sorted(self._local_block_addrs)
1759
+ if not block_addrs:
1760
+ return 0
1761
+ holes = 0
1762
+ for i, addr in enumerate(block_addrs):
1763
+ if i == len(block_addrs) - 1:
1764
+ break
1765
+ next_addr = block_addrs[i + 1]
1766
+ if next_addr > addr + self._block_sizes[addr] and next_addr - (addr + self._block_sizes[addr]) >= min_size:
1767
+ holes += 1
1768
+ return holes
1769
+
1753
1770
  def copy(self):
1754
1771
  func = Function(self._function_manager, self.addr, name=self.name, syscall=self.is_syscall)
1755
1772
  func.transition_graph = networkx.DiGraph(self.transition_graph)
@@ -52,20 +52,20 @@ class pthread_cond_signal(angr.SimProcedure):
52
52
 
53
53
  class pthread_mutex_lock(angr.SimProcedure):
54
54
  """
55
- A no-op.
55
+ Always returns 0 (SUCCESS).
56
56
  """
57
57
 
58
58
  def run(self, arg):
59
- pass
59
+ return 0
60
60
 
61
61
 
62
62
  class pthread_mutex_unlock(angr.SimProcedure):
63
63
  """
64
- A no-op.
64
+ Always returns 0 (SUCCESS).
65
65
  """
66
66
 
67
67
  def run(self, arg):
68
- pass
68
+ return 0
69
69
 
70
70
 
71
71
  class pthread_once(angr.SimProcedure):
@@ -99,11 +99,11 @@ class FormatString:
99
99
  elif fmt_spec.spec_type == b"c":
100
100
  s_val = chr(c_val & 0xFF)
101
101
  elif fmt_spec.spec_type == b"x":
102
- s_val = hex(c_val)[2:]
102
+ s_val = f"{c_val:x}"[2:]
103
103
  elif fmt_spec.spec_type == b"o":
104
- s_val = oct(c_val)[2:]
104
+ s_val = f"{c_val:o}"[2:]
105
105
  elif fmt_spec.spec_type == b"p":
106
- s_val = hex(c_val)
106
+ s_val = f"{c_val:x}"
107
107
  else:
108
108
  raise SimProcedureError(f"Unimplemented format specifier '{fmt_spec.spec_type}'")
109
109
 
angr/rustylib.pyd CHANGED
Binary file
angr/sim_type.py CHANGED
@@ -872,6 +872,8 @@ class SimTypePointer(SimTypeReg):
872
872
  self, name=None, full=0, memo=None, indent=0, name_parens: bool = True
873
873
  ): # pylint: disable=unused-argument
874
874
  # if pts_to is SimTypeBottom, we return a void*
875
+ if self.label is not None and name is not None:
876
+ return super().c_repr(name=name, full=full, memo=memo, indent=indent, name_parens=name_parens)
875
877
  if isinstance(self.pts_to, SimTypeBottom):
876
878
  out = "void*"
877
879
  if name is None:
@@ -2192,10 +2194,10 @@ class SimTypeRef(SimType):
2192
2194
  ) -> str: # pylint: disable=unused-argument
2193
2195
  prefix = "unknown"
2194
2196
  if self.original_type is SimStruct:
2195
- prefix = "struct"
2197
+ prefix = "struct "
2196
2198
  if name is None:
2197
2199
  name = ""
2198
- return f"{prefix}{name} {self.name}"
2200
+ return f"{prefix}{self.label} {name}"
2199
2201
 
2200
2202
  def _init_str(self) -> str:
2201
2203
  original_type_name = self.original_type.__name__.split(".")[-1]
@@ -3752,7 +3754,7 @@ def _cpp_decl_to_type(
3752
3754
  for idx, param in enumerate(the_func.parameters):
3753
3755
  arg_type = param.type
3754
3756
  args.append(_cpp_decl_to_type(arg_type, extra_types, opaque_classes=opaque_classes))
3755
- arg_name = param.name if param.name is not None else f"unknown_{idx}"
3757
+ arg_name = param.name if param.name is not None else f"arg_{idx}"
3756
3758
  arg_names.append(arg_name)
3757
3759
 
3758
3760
  args = tuple(args)
@@ -3799,7 +3801,7 @@ def _cpp_decl_to_type(
3799
3801
  for idx, param in enumerate(the_func.parameters):
3800
3802
  arg_type = param.type
3801
3803
  args.append(_cpp_decl_to_type(arg_type, extra_types, opaque_classes=opaque_classes))
3802
- arg_name = param.name if param.name is not None else f"unknown_{idx}"
3804
+ arg_name = param.name if param.name is not None else f"arg_{idx}"
3803
3805
  arg_names.append(arg_name)
3804
3806
 
3805
3807
  args = tuple(args)
@@ -3821,8 +3823,11 @@ def _cpp_decl_to_type(
3821
3823
  elif lbl in ALL_TYPES:
3822
3824
  t = ALL_TYPES[lbl]
3823
3825
  elif opaque_classes is True:
3824
- # create a class without knowing the internal members
3825
- t = SimCppClass(unique_name=lbl, name=lbl, members={}, size=32)
3826
+ # create a struct or a class without knowing the internal members
3827
+ if decl.typename.classkey == "struct":
3828
+ t = SimTypeRef(lbl.removeprefix("struct "), SimStruct)
3829
+ else:
3830
+ t = SimCppClass(unique_name=lbl, name=lbl, members={}, size=32)
3826
3831
  else:
3827
3832
  raise TypeError(f'Unknown type "{lbl}"')
3828
3833
 
angr/simos/windows.py CHANGED
@@ -440,7 +440,7 @@ class SimWindows(SimOS):
440
440
  :param state: The state to get the syscall number from
441
441
  :param allow_unsupported: Whether to return a "dummy" sycall instead of raising an unsupported exception
442
442
  """
443
- if state.block(state.history.jump_source).bytes.hex() == "cd29": # int 29h
443
+ if state.history.jump_source and state.block(state.history.jump_source).bytes.hex() == "cd29": # int 29h
444
444
  return self.fastfail
445
445
  return None
446
446
 
@@ -192,7 +192,7 @@ class ConcreteBackerMixin(ClemoryBackerMixin):
192
192
 
193
193
  try:
194
194
  backer_iter = self._clemory_backer.backers(addr)
195
- backer_start, backer = next(backer_iter)
195
+ backer_start, _backer = next(backer_iter)
196
196
  except StopIteration:
197
197
  return super()._initialize_page(pageno, permissions=permissions, **kwargs)
198
198
 
angr/unicornlib.dll CHANGED
Binary file
angr/utils/constants.py CHANGED
@@ -6,4 +6,4 @@ MAX_POINTSTO_BITS = -1330 * 8
6
6
 
7
7
 
8
8
  def is_alignment_mask(n):
9
- return n in {0xFFFFFFFFFFFFFFE0, 0xFFFFFFFFFFFFFFF0, 0xFFFFFFE0, 0xFFFFFFF0, 0xFFFFFFFC, 0xFFFFFFF8}
9
+ return n in {0xFFFFFFFFFFFFFFE0, 0xFFFFFFFFFFFFFFF0, 0xFFFFFFC0, 0xFFFFFFE0, 0xFFFFFFF0, 0xFFFFFFFC, 0xFFFFFFF8}
angr/utils/strings.py ADDED
@@ -0,0 +1,20 @@
1
+ from __future__ import annotations
2
+
3
+
4
+ def decode_utf16_string(data: bytes) -> str:
5
+ """
6
+ Decode a UTF-16 encoded string from a bytes object in a resilient manner.
7
+
8
+ :param data: The bytes object containing the UTF-16 encoded string.
9
+ :param errors: The error handling scheme. Default is 'strict'.
10
+ Other options include 'ignore', 'replace', etc.
11
+ :return: The decoded string.
12
+ """
13
+ if len(data) % 2 == 1:
14
+ data = data[:-1] # Trim off the last byte if the length is odd
15
+
16
+ # If no BOM, try to decode as little-endian first
17
+ try:
18
+ return data.decode("utf-16-le")
19
+ except UnicodeDecodeError:
20
+ return "<utf16-decode-error>"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: angr
3
- Version: 9.2.175
3
+ Version: 9.2.176
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.175
19
+ Requires-Dist: archinfo==9.2.176
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.175
24
- Requires-Dist: cle==9.2.175
23
+ Requires-Dist: claripy==9.2.176
24
+ Requires-Dist: cle==9.2.176
25
25
  Requires-Dist: msgspec
26
26
  Requires-Dist: mulpyplexer
27
27
  Requires-Dist: networkx!=2.8.1,>=2.0
@@ -31,7 +31,7 @@ Requires-Dist: pycparser>=2.18
31
31
  Requires-Dist: pydemumble
32
32
  Requires-Dist: pyformlang
33
33
  Requires-Dist: pypcode<4.0,>=3.2.1
34
- Requires-Dist: pyvex==9.2.175
34
+ Requires-Dist: pyvex==9.2.176
35
35
  Requires-Dist: rich>=13.1.0
36
36
  Requires-Dist: sortedcontainers
37
37
  Requires-Dist: sympy