angr 9.2.97__py3-none-win_amd64.whl → 9.2.99__py3-none-win_amd64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of angr might be problematic. Click here for more details.

Files changed (33) hide show
  1. angr/__init__.py +1 -1
  2. angr/analyses/cfg/cfg_base.py +14 -1
  3. angr/analyses/cfg/cfg_fast.py +3 -3
  4. angr/analyses/cfg/indirect_jump_resolvers/propagator_utils.py +10 -6
  5. angr/analyses/decompiler/clinic.py +2 -40
  6. angr/analyses/decompiler/optimization_passes/__init__.py +2 -0
  7. angr/analyses/decompiler/optimization_passes/inlined_string_transformation_simplifier.py +380 -0
  8. angr/analyses/decompiler/optimization_passes/ite_region_converter.py +10 -2
  9. angr/analyses/decompiler/optimization_passes/x86_gcc_getpc_simplifier.py +4 -1
  10. angr/analyses/decompiler/peephole_optimizations/__init__.py +1 -0
  11. angr/analyses/decompiler/peephole_optimizations/inlined_strcpy.py +71 -3
  12. angr/analyses/decompiler/peephole_optimizations/inlined_wstrcpy.py +162 -0
  13. angr/analyses/decompiler/region_simplifiers/expr_folding.py +5 -3
  14. angr/analyses/decompiler/return_maker.py +71 -0
  15. angr/analyses/decompiler/structured_codegen/__init__.py +1 -1
  16. angr/analyses/decompiler/structured_codegen/c.py +72 -99
  17. angr/analyses/decompiler/utils.py +5 -1
  18. angr/analyses/propagator/engine_vex.py +15 -0
  19. angr/analyses/reaching_definitions/engine_vex.py +6 -0
  20. angr/analyses/variable_recovery/engine_vex.py +6 -0
  21. angr/analyses/variable_recovery/irsb_scanner.py +12 -0
  22. angr/engines/light/engine.py +126 -15
  23. angr/knowledge_plugins/functions/function.py +4 -0
  24. angr/lib/angr_native.dll +0 -0
  25. angr/storage/memory_mixins/paged_memory/pages/list_page.py +20 -5
  26. angr/storage/memory_mixins/paged_memory/pages/mv_list_page.py +2 -1
  27. angr/storage/memory_mixins/simple_interface_mixin.py +4 -0
  28. {angr-9.2.97.dist-info → angr-9.2.99.dist-info}/METADATA +6 -6
  29. {angr-9.2.97.dist-info → angr-9.2.99.dist-info}/RECORD +33 -30
  30. {angr-9.2.97.dist-info → angr-9.2.99.dist-info}/LICENSE +0 -0
  31. {angr-9.2.97.dist-info → angr-9.2.99.dist-info}/WHEEL +0 -0
  32. {angr-9.2.97.dist-info → angr-9.2.99.dist-info}/entry_points.txt +0 -0
  33. {angr-9.2.97.dist-info → angr-9.2.99.dist-info}/top_level.txt +0 -0
@@ -163,6 +163,9 @@ class SimEnginePropagatorVEX(
163
163
  self.state.store_register(stmt.offset, size, data)
164
164
  self.state.add_replacement(self._codeloc(block_only=False), VEXReg(stmt.offset, size), data)
165
165
 
166
+ def _handle_PutI(self, stmt):
167
+ self._expr(stmt.data)
168
+
166
169
  def _store_data(self, addr, data, size, endness):
167
170
  # pylint: disable=unused-argument,no-self-use
168
171
  if isinstance(addr, claripy.ast.Base):
@@ -260,6 +263,9 @@ class SimEnginePropagatorVEX(
260
263
  size = expr.result_size(self.tyenv) // self.arch.byte_width
261
264
  return self.state.load_register(expr.offset, size)
262
265
 
266
+ def _handle_GetI(self, expr):
267
+ return self.state.top(expr.result_size(self.tyenv))
268
+
263
269
  def _handle_Load(self, expr):
264
270
  addr = self._expr(expr.addr)
265
271
  if addr is None or type(addr) in (Top, Bottom):
@@ -278,6 +284,13 @@ class SimEnginePropagatorVEX(
278
284
  # print(expr.op, r)
279
285
  return r
280
286
 
287
+ def _handle_Triop(self, expr: pyvex.IRExpr.Triop):
288
+ if not self.state.do_binops:
289
+ return self.state.top(expr.result_size(self.tyenv))
290
+
291
+ r = super()._handle_Triop(expr)
292
+ return r
293
+
281
294
  def _handle_Conversion(self, expr):
282
295
  expr_ = self._expr(expr.args[0])
283
296
  to_size = expr.result_size(self.tyenv)
@@ -311,3 +324,5 @@ class SimEnginePropagatorVEX(
311
324
  self.state.block_initial_reg_values[self.block.addr, dst.concrete_value].append(v)
312
325
 
313
326
  super()._handle_Exit(stmt)
327
+
328
+ _handle_CmpF = _handle_CmpEQ
@@ -176,6 +176,9 @@ class SimEngineRDVEX(
176
176
  return
177
177
  self.state.kill_and_add_definition(reg, data)
178
178
 
179
+ def _handle_PutI(self, stmt):
180
+ pass
181
+
179
182
  # e.g. STle(t6) = t21, t6 and/or t21 might include multiple values
180
183
  def _handle_Store(self, stmt):
181
184
  addr = self._expr(stmt.addr)
@@ -404,6 +407,9 @@ class SimEngineRDVEX(
404
407
 
405
408
  return values
406
409
 
410
+ def _handle_GetI(self, expr: pyvex.IRExpr.GetI) -> MultiValues:
411
+ return MultiValues(self.state.top(expr.result_size(self.tyenv)))
412
+
407
413
  # e.g. t27 = LDle:I64(t9), t9 might include multiple values
408
414
  # caution: Is also called from StoreG
409
415
  def _handle_Load(self, expr) -> MultiValues:
@@ -61,6 +61,9 @@ class SimEngineVRVEX(
61
61
  return
62
62
  self._assign_to_register(offset, r, size)
63
63
 
64
+ def _handle_PutI(self, stmt):
65
+ pass
66
+
64
67
  def _handle_Store(self, stmt):
65
68
  addr_r = self._expr(stmt.addr)
66
69
  size = stmt.data.result_size(self.tyenv) // 8
@@ -159,6 +162,9 @@ class SimEngineVRVEX(
159
162
  create_variable=self.stmt_idx not in self.reg_read_stmts_to_ignore,
160
163
  )
161
164
 
165
+ def _handle_GetI(self, expr: pyvex.IRExpr.GetI):
166
+ return RichR(self.state.top(expr.result_size(self.tyenv)))
167
+
162
168
  def _handle_Load(self, expr: pyvex.IRExpr.Load) -> RichR:
163
169
  addr = self._expr(expr.addr)
164
170
  size = expr.result_size(self.tyenv) // 8
@@ -33,6 +33,12 @@ class VEXIRSBScanner(SimEngineLightVEXMixin):
33
33
  self.reg_read_stmt_id: Dict[int, int] = {}
34
34
  self.reg_read_stmts_to_ignore: Set[int] = set()
35
35
 
36
+ def _top(self, size: int):
37
+ return None
38
+
39
+ def _is_top(self, expr) -> bool:
40
+ return True
41
+
36
42
  def _process_Stmt(self, whitelist=None):
37
43
  self.tmps_with_64bit_regs = set()
38
44
  self.tmps_assignment_stmtidx = {}
@@ -55,6 +61,9 @@ class VEXIRSBScanner(SimEngineLightVEXMixin):
55
61
  self.reg_read_stmts_to_ignore.add(self.reg_read_stmt_id[old_reg_offset])
56
62
  self.reg_with_reg_as_value[stmt.offset] = self.tmp_with_reg_as_value[stmt.data.tmp]
57
63
 
64
+ def _handle_PutI(self, stmt):
65
+ pass
66
+
58
67
  def _handle_Load(self, expr):
59
68
  pass
60
69
 
@@ -85,6 +94,9 @@ class VEXIRSBScanner(SimEngineLightVEXMixin):
85
94
  if expr.offset in self.reg_with_reg_as_value:
86
95
  del self.reg_with_reg_as_value[expr.offset]
87
96
 
97
+ def _handle_GetI(self, expr):
98
+ pass
99
+
88
100
  def _handle_RdTmp(self, expr):
89
101
  if expr.tmp in self.tmps_converted_to_32bit:
90
102
  self.tmps_converted_to_32bit.remove(expr.tmp)
@@ -239,10 +239,55 @@ class SimEngineLightVEXMixin(SimEngineLightMixin):
239
239
  return None
240
240
 
241
241
  def _handle_Triop(self, expr: pyvex.IRExpr.Triop): # pylint: disable=useless-return
242
- if self.l is not None:
242
+ handler = None
243
+ if expr.op.startswith("Iop_AddF"):
244
+ handler = "_handle_AddF"
245
+ elif expr.op.startswith("Iop_SubF"):
246
+ handler = "_handle_AddF"
247
+ elif expr.op.startswith("Iop_MulF"):
248
+ handler = "_handle_MulF"
249
+ elif expr.op.startswith("Iop_DivF"):
250
+ handler = "_handle_DivF"
251
+ elif expr.op.startswith("Iop_SinF"):
252
+ handler = "_handle_SinF"
253
+ elif expr.op.startswith("Iop_ScaleF"):
254
+ handler = "_handle_ScaleF"
255
+
256
+ if handler is not None and hasattr(self, handler):
257
+ return getattr(self, handler)(expr)
258
+
259
+ if once(expr.op) and self.l is not None:
243
260
  self.l.error("Unsupported Triop %s.", expr.op)
261
+
244
262
  return None
245
263
 
264
+ def _handle_AddF(self, expr):
265
+ return self._top(expr.result_size(self.tyenv))
266
+
267
+ def _handle_SubF(self, expr):
268
+ return self._top(expr.result_size(self.tyenv))
269
+
270
+ def _handle_MulF(self, expr):
271
+ return self._top(expr.result_size(self.tyenv))
272
+
273
+ def _handle_DivF(self, expr):
274
+ return self._top(expr.result_size(self.tyenv))
275
+
276
+ def _handle_NegF(self, expr):
277
+ return self._top(expr.result_size(self.tyenv))
278
+
279
+ def _handle_AbsF(self, expr):
280
+ return self._top(expr.result_size(self.tyenv))
281
+
282
+ def _handle_SinF(self, expr):
283
+ return self._top(expr.result_size(self.tyenv))
284
+
285
+ def _handle_CosF(self, expr):
286
+ return self._top(expr.result_size(self.tyenv))
287
+
288
+ def _handle_ScaleF(self, expr):
289
+ return self._top(expr.result_size(self.tyenv))
290
+
246
291
  def _handle_RdTmp(self, expr):
247
292
  tmp = expr.tmp
248
293
 
@@ -294,6 +339,10 @@ class SimEngineLightVEXMixin(SimEngineLightMixin):
294
339
  handler = "_handle_Clz"
295
340
  elif expr.op.startswith("Iop_Ctz"):
296
341
  handler = "_handle_Ctz"
342
+ elif expr.op.startswith("Iop_NegF"):
343
+ handler = "_handle_NegF"
344
+ elif expr.op.startswith("Iop_AbsF"):
345
+ handler = "_handle_AbsF"
297
346
 
298
347
  if handler is not None and hasattr(self, handler):
299
348
  return getattr(self, handler)(expr)
@@ -361,6 +410,10 @@ class SimEngineLightVEXMixin(SimEngineLightMixin):
361
410
  handler = "_handle_16HLto32"
362
411
  elif expr.op.startswith("Iop_ExpCmpNE64"):
363
412
  handler = "_handle_ExpCmpNE64"
413
+ elif expr.op.startswith("Iop_SinF"):
414
+ handler = "_handle_SinF"
415
+ elif expr.op.startswith("Iop_CosF"):
416
+ handler = "_handle_CosF"
364
417
 
365
418
  vector_size, vector_count = None, None
366
419
  if handler is not None:
@@ -539,6 +592,10 @@ class SimEngineLightVEXMixin(SimEngineLightMixin):
539
592
 
540
593
  return expr_0 * expr_1
541
594
 
595
+ def _handle_Mull(self, expr):
596
+ self._binop_get_args(expr)
597
+ return self._top(expr.result_size(self.tyenv))
598
+
542
599
  def _handle_DivMod(self, expr):
543
600
  args, r = self._binop_get_args(expr)
544
601
  if args is None:
@@ -938,35 +995,47 @@ class SimEngineLightAILMixin(SimEngineLightMixin):
938
995
  return expr
939
996
 
940
997
  def _ail_handle_UnaryOp(self, expr):
941
- handler_name = "_ail_handle_%s" % expr.op
998
+ handler_name = f"_handle_{expr.op}"
942
999
  try:
943
1000
  handler = getattr(self, handler_name)
944
1001
  except AttributeError:
945
- if self.l is not None:
946
- self.l.warning("Unsupported UnaryOp %s.", expr.op)
947
- return None
1002
+ handler_name = "_ail_handle_%s" % expr.op
1003
+ try:
1004
+ handler = getattr(self, handler_name)
1005
+ except AttributeError:
1006
+ if self.l is not None:
1007
+ self.l.warning("Unsupported UnaryOp %s.", expr.op)
1008
+ return None
948
1009
 
949
1010
  return handler(expr)
950
1011
 
951
1012
  def _ail_handle_BinaryOp(self, expr):
952
- handler_name = "_ail_handle_%s" % expr.op
1013
+ handler_name = f"_handle_{expr.op}"
953
1014
  try:
954
1015
  handler = getattr(self, handler_name)
955
1016
  except AttributeError:
956
- if self.l is not None:
957
- self.l.warning("Unsupported BinaryOp %s.", expr.op)
958
- return None
1017
+ handler_name = "_ail_handle_%s" % expr.op
1018
+ try:
1019
+ handler = getattr(self, handler_name)
1020
+ except AttributeError:
1021
+ if self.l is not None:
1022
+ self.l.warning("Unsupported BinaryOp %s.", expr.op)
1023
+ return None
959
1024
 
960
1025
  return handler(expr)
961
1026
 
962
1027
  def _ail_handle_TernaryOp(self, expr):
963
- handler_name = "_ail_handle_%s" % expr.op
1028
+ handler_name = f"_handle_{expr.op}"
964
1029
  try:
965
1030
  handler = getattr(self, handler_name)
966
1031
  except AttributeError:
967
- if self.l is not None:
968
- self.l.warning("Unsupported Ternary %s.", expr.op)
969
- return None
1032
+ handler_name = "_ail_handle_%s" % expr.op
1033
+ try:
1034
+ handler = getattr(self, handler_name)
1035
+ except AttributeError:
1036
+ if self.l is not None:
1037
+ self.l.warning("Unsupported Ternary %s.", expr.op)
1038
+ return None
970
1039
 
971
1040
  return handler(expr)
972
1041
 
@@ -974,6 +1043,44 @@ class SimEngineLightAILMixin(SimEngineLightMixin):
974
1043
  # Binary operation handlers
975
1044
  #
976
1045
 
1046
+ def _ail_handle_CmpEQ(self, expr):
1047
+ arg0, arg1 = expr.operands
1048
+
1049
+ expr_0 = self._expr(arg0)
1050
+ expr_1 = self._expr(arg1)
1051
+ if expr_0 is None:
1052
+ expr_0 = arg0
1053
+ if expr_1 is None:
1054
+ expr_1 = arg1
1055
+
1056
+ try:
1057
+ if isinstance(expr_0, ailment.Expr.Const) and isinstance(expr_1, ailment.Expr.Const):
1058
+ if expr_0.value == expr_1.value:
1059
+ return ailment.Expr.Const(None, None, 1, 1)
1060
+ return ailment.Expr.Const(None, None, 0, 1)
1061
+ except TypeError:
1062
+ pass
1063
+ return ailment.Expr.BinaryOp(expr.idx, "CmpEQ", [expr_0, expr_1], expr.signed, **expr.tags)
1064
+
1065
+ def _ail_handle_CmpNE(self, expr):
1066
+ arg0, arg1 = expr.operands
1067
+
1068
+ expr_0 = self._expr(arg0)
1069
+ expr_1 = self._expr(arg1)
1070
+ if expr_0 is None:
1071
+ expr_0 = arg0
1072
+ if expr_1 is None:
1073
+ expr_1 = arg1
1074
+
1075
+ try:
1076
+ if isinstance(expr_0, ailment.Expr.Const) and isinstance(expr_1, ailment.Expr.Const):
1077
+ if expr_0.value != expr_1.value:
1078
+ return ailment.Expr.Const(None, None, 1, 1)
1079
+ return ailment.Expr.Const(None, None, 0, 1)
1080
+ except TypeError:
1081
+ pass
1082
+ return ailment.Expr.BinaryOp(expr.idx, "CmpNE", [expr_0, expr_1], expr.signed, **expr.tags)
1083
+
977
1084
  def _ail_handle_CmpLT(self, expr):
978
1085
  arg0, arg1 = expr.operands
979
1086
 
@@ -985,9 +1092,13 @@ class SimEngineLightAILMixin(SimEngineLightMixin):
985
1092
  expr_1 = arg1
986
1093
 
987
1094
  try:
988
- return expr_0 <= expr_1
1095
+ if isinstance(expr_0, ailment.Expr.Const) and isinstance(expr_1, ailment.Expr.Const):
1096
+ if expr_0.value < expr_1.value:
1097
+ return ailment.Expr.Const(None, None, 1, 1)
1098
+ return ailment.Expr.Const(None, None, 0, 1)
989
1099
  except TypeError:
990
- return ailment.Expr.BinaryOp(expr.idx, "CmpLT", [expr_0, expr_1], expr.signed, **expr.tags)
1100
+ pass
1101
+ return ailment.Expr.BinaryOp(expr.idx, "CmpLT", [expr_0, expr_1], expr.signed, **expr.tags)
991
1102
 
992
1103
  def _ail_handle_Add(self, expr):
993
1104
  arg0, arg1 = expr.operands
@@ -1535,6 +1535,10 @@ class Function(Serializable):
1535
1535
 
1536
1536
  for library in libraries:
1537
1537
  for name in name_variants:
1538
+ if isinstance(library, SimSyscallLibrary):
1539
+ # FIXME: we don't support getting declaration from a syscall library yet. we don't have the concept
1540
+ # of abi at this point.
1541
+ continue
1538
1542
  if not library.has_prototype(name):
1539
1543
  continue
1540
1544
 
angr/lib/angr_native.dll CHANGED
Binary file
@@ -2,6 +2,8 @@
2
2
  import logging
3
3
  from typing import Optional, List, Set, Tuple
4
4
 
5
+ import claripy
6
+
5
7
  from angr.utils.dynamic_dictlist import DynamicDictList
6
8
  from angr.storage.memory_object import SimMemoryObject, SimLabeledMemoryObject
7
9
  from . import PageBase
@@ -192,9 +194,14 @@ class ListPage(MemoryObjectMixin, PageBase):
192
194
  merged_offsets.add(b)
193
195
 
194
196
  else:
195
- # get the size that we can merge easily. This is the minimum of
196
- # the size of all memory objects and unallocated spaces.
197
- min_size = min([mo.length - (b + page_addr - mo.base) for mo, _ in memory_objects])
197
+ # get the size that we can merge easily. This is the minimum of the size of all memory objects and
198
+ # unallocated spaces.
199
+ min_size = None
200
+ mask = (1 << memory.state.arch.bits) - 1
201
+ for mo, _ in memory_objects:
202
+ mo_size = mo.length - ((b + page_addr - mo.base) & mask)
203
+ if min_size is None or mo_size < min_size:
204
+ min_size = mo_size
198
205
  for um, _ in unconstrained_in:
199
206
  for i in range(0, min_size):
200
207
  if um._contains(b + i, page_addr):
@@ -263,15 +270,23 @@ class ListPage(MemoryObjectMixin, PageBase):
263
270
  differences.add(c)
264
271
  else:
265
272
  if self.content[c] is None:
273
+ if self.sinkhole is None:
274
+ v = claripy.BVV(0, 8)
275
+ else:
276
+ v = (self.sinkhole.bytes_at(page_addr + c, 1),)
266
277
  self.content[c] = SimMemoryObject(
267
- self.sinkhole.bytes_at(page_addr + c, 1),
278
+ v,
268
279
  page_addr + c,
269
280
  byte_width=byte_width,
270
281
  endness="Iend_BE",
271
282
  )
272
283
  if other.content[c] is None:
284
+ if other.sinkhole is None:
285
+ v = claripy.BVV(0, 8)
286
+ else:
287
+ v = (other.sinkhole.bytes_at(page_addr + c, 1),)
273
288
  other.content[c] = SimMemoryObject(
274
- other.sinkhole.bytes_at(page_addr + c, 1),
289
+ v,
275
290
  page_addr + c,
276
291
  byte_width=byte_width,
277
292
  endness="Iend_BE",
@@ -239,9 +239,10 @@ class MVListPage(
239
239
  # get the size that we can merge easily. This is the minimum of the size of all memory objects and
240
240
  # unallocated spaces.
241
241
  min_size = len(self.content) - b
242
+ mask = (1 << memory.state.arch.bits) - 1
242
243
  for mo_set in mo_sets:
243
244
  for mo in mo_set:
244
- min_size = min(min_size, mo.length - (b + page_addr - mo.base))
245
+ min_size = min(min_size, mo.length - ((b + page_addr - mo.base) & mask))
245
246
  for um, _ in unconstrained_in:
246
247
  for i in range(0, min_size):
247
248
  if um._contains(b + i, page_addr):
@@ -28,6 +28,8 @@ class SimpleInterfaceMixin(MemoryMixin):
28
28
  )
29
29
 
30
30
  def _translate_addr(self, a):
31
+ if isinstance(a, int):
32
+ return a
31
33
  if isinstance(a, claripy.ast.Base) and not a.singlevalued:
32
34
  raise SimMemoryError("address not supported")
33
35
  return self.state.solver.eval(a)
@@ -43,6 +45,8 @@ class SimpleInterfaceMixin(MemoryMixin):
43
45
  raise SimMemoryError("data not supported")
44
46
 
45
47
  def _translate_size(self, s, data):
48
+ if isinstance(s, int):
49
+ return s
46
50
  if isinstance(s, claripy.ast.Base) and not s.singlevalued:
47
51
  raise SimMemoryError("size not supported")
48
52
  if s is None:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: angr
3
- Version: 9.2.97
3
+ Version: 9.2.99
4
4
  Summary: A multi-architecture binary analysis toolkit, with the ability to perform dynamic symbolic execution and various static analyses on binaries
5
5
  Home-page: https://github.com/angr/angr
6
6
  License: BSD-2-Clause
@@ -17,13 +17,13 @@ Description-Content-Type: text/markdown
17
17
  License-File: LICENSE
18
18
  Requires-Dist: CppHeaderParser
19
19
  Requires-Dist: GitPython
20
- Requires-Dist: ailment ==9.2.97
21
- Requires-Dist: archinfo ==9.2.97
20
+ Requires-Dist: ailment ==9.2.99
21
+ Requires-Dist: archinfo ==9.2.99
22
22
  Requires-Dist: cachetools
23
23
  Requires-Dist: capstone ==5.0.0.post1
24
24
  Requires-Dist: cffi >=1.14.0
25
- Requires-Dist: claripy ==9.2.97
26
- Requires-Dist: cle ==9.2.97
25
+ Requires-Dist: claripy ==9.2.99
26
+ Requires-Dist: cle ==9.2.99
27
27
  Requires-Dist: dpkt
28
28
  Requires-Dist: itanium-demangler
29
29
  Requires-Dist: mulpyplexer
@@ -33,7 +33,7 @@ Requires-Dist: protobuf >=3.19.0
33
33
  Requires-Dist: psutil
34
34
  Requires-Dist: pycparser >=2.18
35
35
  Requires-Dist: pyformlang
36
- Requires-Dist: pyvex ==9.2.97
36
+ Requires-Dist: pyvex ==9.2.99
37
37
  Requires-Dist: rich >=13.1.0
38
38
  Requires-Dist: rpyc
39
39
  Requires-Dist: sortedcontainers