angr 9.2.140__py3-none-win_amd64.whl → 9.2.142__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 (76) hide show
  1. angr/__init__.py +1 -1
  2. angr/analyses/calling_convention/calling_convention.py +105 -35
  3. angr/analyses/calling_convention/fact_collector.py +44 -18
  4. angr/analyses/calling_convention/utils.py +3 -1
  5. angr/analyses/cfg/cfg_base.py +38 -4
  6. angr/analyses/cfg/cfg_fast.py +23 -7
  7. angr/analyses/cfg/indirect_jump_resolvers/jumptable.py +13 -8
  8. angr/analyses/class_identifier.py +8 -7
  9. angr/analyses/complete_calling_conventions.py +1 -1
  10. angr/analyses/decompiler/ail_simplifier.py +105 -62
  11. angr/analyses/decompiler/callsite_maker.py +24 -11
  12. angr/analyses/decompiler/clinic.py +83 -5
  13. angr/analyses/decompiler/condition_processor.py +7 -7
  14. angr/analyses/decompiler/decompilation_cache.py +2 -1
  15. angr/analyses/decompiler/decompiler.py +11 -2
  16. angr/analyses/decompiler/dephication/graph_vvar_mapping.py +4 -6
  17. angr/analyses/decompiler/optimization_passes/base_ptr_save_simplifier.py +8 -2
  18. angr/analyses/decompiler/optimization_passes/condition_constprop.py +63 -34
  19. angr/analyses/decompiler/optimization_passes/duplication_reverter/duplication_reverter.py +3 -1
  20. angr/analyses/decompiler/optimization_passes/flip_boolean_cmp.py +21 -2
  21. angr/analyses/decompiler/optimization_passes/lowered_switch_simplifier.py +85 -16
  22. angr/analyses/decompiler/optimization_passes/optimization_pass.py +78 -1
  23. angr/analyses/decompiler/optimization_passes/register_save_area_simplifier.py +29 -7
  24. angr/analyses/decompiler/optimization_passes/return_duplicator_base.py +51 -7
  25. angr/analyses/decompiler/optimization_passes/stack_canary_simplifier.py +6 -0
  26. angr/analyses/decompiler/optimization_passes/win_stack_canary_simplifier.py +9 -1
  27. angr/analyses/decompiler/peephole_optimizations/eager_eval.py +44 -7
  28. angr/analyses/decompiler/region_identifier.py +76 -51
  29. angr/analyses/decompiler/region_simplifiers/expr_folding.py +32 -18
  30. angr/analyses/decompiler/region_simplifiers/region_simplifier.py +4 -1
  31. angr/analyses/decompiler/ssailification/rewriting.py +70 -32
  32. angr/analyses/decompiler/ssailification/rewriting_engine.py +118 -24
  33. angr/analyses/decompiler/ssailification/ssailification.py +22 -14
  34. angr/analyses/decompiler/stack_item.py +36 -0
  35. angr/analyses/decompiler/structured_codegen/c.py +86 -145
  36. angr/analyses/decompiler/structuring/dream.py +1 -1
  37. angr/analyses/decompiler/structuring/phoenix.py +9 -4
  38. angr/analyses/decompiler/structuring/structurer_base.py +2 -1
  39. angr/analyses/decompiler/utils.py +46 -20
  40. angr/analyses/find_objects_static.py +2 -1
  41. angr/analyses/reaching_definitions/engine_vex.py +13 -0
  42. angr/analyses/reaching_definitions/function_handler.py +24 -10
  43. angr/analyses/reaching_definitions/function_handler_library/stdio.py +1 -0
  44. angr/analyses/reaching_definitions/function_handler_library/stdlib.py +45 -12
  45. angr/analyses/reaching_definitions/function_handler_library/string.py +77 -21
  46. angr/analyses/reaching_definitions/function_handler_library/unistd.py +21 -1
  47. angr/analyses/reaching_definitions/rd_state.py +11 -7
  48. angr/analyses/s_liveness.py +44 -6
  49. angr/analyses/s_reaching_definitions/s_rda_model.py +4 -2
  50. angr/analyses/s_reaching_definitions/s_rda_view.py +43 -25
  51. angr/analyses/typehoon/simple_solver.py +35 -8
  52. angr/analyses/typehoon/typehoon.py +3 -1
  53. angr/analyses/variable_recovery/engine_ail.py +1 -1
  54. angr/analyses/variable_recovery/engine_vex.py +20 -4
  55. angr/calling_conventions.py +17 -12
  56. angr/factory.py +8 -3
  57. angr/knowledge_plugins/functions/function.py +5 -10
  58. angr/knowledge_plugins/variables/variable_manager.py +34 -5
  59. angr/lib/angr_native.dll +0 -0
  60. angr/procedures/definitions/__init__.py +3 -10
  61. angr/procedures/definitions/wdk_ntoskrnl.py +2 -0
  62. angr/procedures/win32_kernel/__fastfail.py +15 -0
  63. angr/sim_procedure.py +2 -2
  64. angr/simos/simos.py +17 -11
  65. angr/simos/windows.py +42 -1
  66. angr/utils/ail.py +41 -1
  67. angr/utils/cpp.py +17 -0
  68. angr/utils/doms.py +142 -0
  69. angr/utils/library.py +1 -1
  70. angr/utils/types.py +59 -0
  71. {angr-9.2.140.dist-info → angr-9.2.142.dist-info}/METADATA +7 -7
  72. {angr-9.2.140.dist-info → angr-9.2.142.dist-info}/RECORD +76 -71
  73. {angr-9.2.140.dist-info → angr-9.2.142.dist-info}/LICENSE +0 -0
  74. {angr-9.2.140.dist-info → angr-9.2.142.dist-info}/WHEEL +0 -0
  75. {angr-9.2.140.dist-info → angr-9.2.142.dist-info}/entry_points.txt +0 -0
  76. {angr-9.2.140.dist-info → angr-9.2.142.dist-info}/top_level.txt +0 -0
@@ -40,6 +40,7 @@ from angr.sim_variable import SimVariable, SimTemporaryVariable, SimStackVariabl
40
40
  from angr.utils.constants import is_alignment_mask
41
41
  from angr.utils.library import get_cpp_function_name
42
42
  from angr.utils.loader import is_in_readonly_segment, is_in_readonly_section
43
+ from angr.utils.types import unpack_typeref, unpack_pointer_and_array
43
44
  from angr.analyses.decompiler.utils import structured_node_is_simple_return
44
45
  from angr.errors import UnsupportedNodeTypeError, AngrRuntimeError
45
46
  from angr.knowledge_plugins.cfg.memory_data import MemoryData, MemoryDataSort
@@ -72,35 +73,6 @@ l.addFilter(UniqueLogFilter())
72
73
  INDENT_DELTA = 4
73
74
 
74
75
 
75
- def unpack_typeref(ty):
76
- if isinstance(ty, TypeRef):
77
- return ty.type
78
- return ty
79
-
80
-
81
- def unpack_pointer(ty) -> SimType | None:
82
- if isinstance(ty, SimTypePointer):
83
- return ty.pts_to
84
- return None
85
-
86
-
87
- def unpack_array(ty) -> SimType | None:
88
- if isinstance(ty, SimTypeArray):
89
- return ty.elem_type
90
- if isinstance(ty, SimTypeFixedSizeArray):
91
- return ty.elem_type
92
- return None
93
-
94
-
95
- def squash_array_reference(ty):
96
- pointed_to = unpack_pointer(ty)
97
- if pointed_to:
98
- array_of = unpack_array(pointed_to)
99
- if array_of:
100
- return SimTypePointer(array_of)
101
- return ty
102
-
103
-
104
76
  def qualifies_for_simple_cast(ty1, ty2):
105
77
  # converting ty1 to ty2 - can this happen precisely?
106
78
  # used to decide whether to add explicit typecasts instead of doing *(int*)&v1
@@ -122,7 +94,7 @@ def qualifies_for_implicit_cast(ty1, ty2):
122
94
  ):
123
95
  return False
124
96
 
125
- return ty1.size <= ty2.size
97
+ return ty1.size <= ty2.size if ty1.size is not None and ty2.size is not None else False
126
98
 
127
99
 
128
100
  def extract_terms(expr: CExpression) -> tuple[int, list[tuple[int, CExpression]]]:
@@ -260,9 +232,10 @@ class CConstruct:
260
232
  Acts as the base class for all other representation constructions.
261
233
  """
262
234
 
263
- __slots__ = ("codegen",)
235
+ __slots__ = ("codegen", "tags")
264
236
 
265
- def __init__(self, codegen):
237
+ def __init__(self, codegen, tags=None):
238
+ self.tags = tags or {}
266
239
  self.codegen: StructuredCodeGenerator = codegen
267
240
 
268
241
  def c_repr(self, indent=0, pos_to_node=None, pos_to_addr=None, addr_to_pos=None):
@@ -319,6 +292,7 @@ class CConstruct:
319
292
  CUnaryOp,
320
293
  CAssignment,
321
294
  CFunctionCall,
295
+ CLabel,
322
296
  ),
323
297
  )
324
298
  and pos_to_node is not None
@@ -341,7 +315,7 @@ class CConstruct:
341
315
  pos_to_node.add_mapping(pos, len(s), obj)
342
316
 
343
317
  if s.endswith("\n"):
344
- text = pending_stmt_comments.pop(last_insn_addr, None)
318
+ text = pending_stmt_comments.pop(last_insn_addr, None) if isinstance(last_insn_addr, int) else None
345
319
  if text is not None:
346
320
  todo = " // " + text
347
321
  pos += len(s) - 1
@@ -354,7 +328,7 @@ class CConstruct:
354
328
  yield s
355
329
 
356
330
  if isinstance(obj, CExpression):
357
- text = pending_expr_comments.pop(last_insn_addr, None)
331
+ text = pending_expr_comments.pop(last_insn_addr, None) if isinstance(last_insn_addr, int) else None
358
332
  if text is not None:
359
333
  todo = " /*" + text + "*/ "
360
334
  pos += len(todo)
@@ -504,7 +478,8 @@ class CFunction(CConstruct): # pylint:disable=abstract-method
504
478
  vartypes = [x[1] for x in cvar_and_vartypes]
505
479
  count = Counter(vartypes)
506
480
  vartypes = sorted(
507
- count.copy(), key=lambda x: (isinstance(x, (SimTypeChar, SimTypeInt, SimTypeFloat)), count[x], repr(x))
481
+ count.copy(),
482
+ key=lambda x, ct=count: (isinstance(x, (SimTypeChar, SimTypeInt, SimTypeFloat)), ct[x], repr(x)),
508
483
  )
509
484
 
510
485
  for i, var_type in enumerate(vartypes):
@@ -563,7 +538,9 @@ class CFunction(CConstruct): # pylint:disable=abstract-method
563
538
  yield from type_to_c_repr_chunks(ty, full=True, indent_str=indent_str)
564
539
 
565
540
  if self.codegen.show_externs and self.codegen.cexterns:
566
- for v in sorted(self.codegen.cexterns, key=lambda v: v.variable.name):
541
+ for v in sorted(self.codegen.cexterns, key=lambda v: str(v.variable.name)):
542
+ if v.variable not in self.variables_in_use:
543
+ continue
567
544
  varname = v.c_repr() if v.type is None else v.variable.name
568
545
  yield "extern ", None
569
546
  yield from type_to_c_repr_chunks(v.type, name=varname, name_type=v, full=False)
@@ -573,6 +550,7 @@ class CFunction(CConstruct): # pylint:disable=abstract-method
573
550
  yield indent_str, None
574
551
 
575
552
  # header comments (if they exist)
553
+ assert self.codegen.cfunc is not None and self.codegen.cfunc.addr is not None
576
554
  header_comments = self.codegen.kb.comments.get(self.codegen.cfunc.addr, [])
577
555
  if header_comments:
578
556
  header_cmt = self._line_wrap_comment("".join(header_comments))
@@ -582,6 +560,7 @@ class CFunction(CConstruct): # pylint:disable=abstract-method
582
560
  yield "// attributes: PLT stub\n", None
583
561
 
584
562
  # return type
563
+ assert self.functy.returnty is not None
585
564
  yield self.functy.returnty.c_repr(name="").strip(" "), self.functy.returnty
586
565
  yield " ", None
587
566
  # function name
@@ -641,7 +620,8 @@ class CStatement(CConstruct): # pylint:disable=abstract-method
641
620
  Represents a statement in C.
642
621
  """
643
622
 
644
- __slots__ = ()
623
+ def __init__(self, tags=None, codegen=None):
624
+ super().__init__(codegen=codegen, tags=tags)
645
625
 
646
626
 
647
627
  class CExpression(CConstruct):
@@ -649,13 +629,10 @@ class CExpression(CConstruct):
649
629
  Base class for C expressions.
650
630
  """
651
631
 
652
- __slots__ = (
653
- "_type",
654
- "collapsed",
655
- )
632
+ __slots__ = ("_type", "collapsed")
656
633
 
657
- def __init__(self, collapsed=False, **kwargs):
658
- super().__init__(**kwargs)
634
+ def __init__(self, collapsed=False, tags=None, codegen=None):
635
+ super().__init__(codegen=codegen, tags=tags)
659
636
  self._type = None
660
637
  self.collapsed = collapsed
661
638
 
@@ -739,15 +716,13 @@ class CWhileLoop(CLoop):
739
716
  __slots__ = (
740
717
  "body",
741
718
  "condition",
742
- "tags",
743
719
  )
744
720
 
745
- def __init__(self, condition, body, tags=None, **kwargs):
721
+ def __init__(self, condition, body, **kwargs):
746
722
  super().__init__(**kwargs)
747
723
 
748
724
  self.condition = condition
749
725
  self.body = body
750
- self.tags = tags
751
726
 
752
727
  def c_repr_chunks(self, indent=0, asexpr=False):
753
728
  indent_str = self.indent_str(indent=indent)
@@ -787,15 +762,13 @@ class CDoWhileLoop(CLoop):
787
762
  __slots__ = (
788
763
  "body",
789
764
  "condition",
790
- "tags",
791
765
  )
792
766
 
793
- def __init__(self, condition, body, tags=None, **kwargs):
767
+ def __init__(self, condition, body, **kwargs):
794
768
  super().__init__(**kwargs)
795
769
 
796
770
  self.condition = condition
797
771
  self.body = body
798
- self.tags = tags
799
772
 
800
773
  def c_repr_chunks(self, indent=0, asexpr=False):
801
774
  indent_str = self.indent_str(indent=indent)
@@ -835,9 +808,14 @@ class CForLoop(CStatement):
835
808
  Represents a for-loop in C.
836
809
  """
837
810
 
838
- __slots__ = ("body", "condition", "initializer", "iterator", "tags")
811
+ __slots__ = (
812
+ "body",
813
+ "condition",
814
+ "initializer",
815
+ "iterator",
816
+ )
839
817
 
840
- def __init__(self, initializer, condition, iterator, body, tags=None, **kwargs):
818
+ def __init__(self, initializer, condition, iterator, body, **kwargs):
841
819
  super().__init__(**kwargs)
842
820
 
843
821
  self.initializer = initializer
@@ -845,8 +823,6 @@ class CForLoop(CStatement):
845
823
  self.iterator = iterator
846
824
  self.body = body
847
825
 
848
- self.tags = tags
849
-
850
826
  def c_repr_chunks(self, indent=0, asexpr=False):
851
827
  indent_str = self.indent_str(indent=indent)
852
828
  brace = CClosingObject("{")
@@ -887,7 +863,12 @@ class CIfElse(CStatement):
887
863
  Represents an if-else construct in C.
888
864
  """
889
865
 
890
- __slots__ = ("condition_and_nodes", "cstyle_ifs", "else_node", "simplify_else_scope", "tags")
866
+ __slots__ = (
867
+ "condition_and_nodes",
868
+ "cstyle_ifs",
869
+ "else_node",
870
+ "simplify_else_scope",
871
+ )
891
872
 
892
873
  def __init__(
893
874
  self,
@@ -895,7 +876,6 @@ class CIfElse(CStatement):
895
876
  else_node=None,
896
877
  simplify_else_scope=False,
897
878
  cstyle_ifs=True,
898
- tags=None,
899
879
  **kwargs,
900
880
  ):
901
881
  super().__init__(**kwargs)
@@ -904,7 +884,6 @@ class CIfElse(CStatement):
904
884
  self.else_node = else_node
905
885
  self.simplify_else_scope = simplify_else_scope
906
886
  self.cstyle_ifs = cstyle_ifs
907
- self.tags = tags
908
887
 
909
888
  if not self.condition_and_nodes:
910
889
  raise ValueError("You must specify at least one condition")
@@ -1014,15 +993,13 @@ class CIfBreak(CStatement):
1014
993
  __slots__ = (
1015
994
  "condition",
1016
995
  "cstyle_ifs",
1017
- "tags",
1018
996
  )
1019
997
 
1020
- def __init__(self, condition, cstyle_ifs=True, tags=None, **kwargs):
998
+ def __init__(self, condition, cstyle_ifs=True, **kwargs):
1021
999
  super().__init__(**kwargs)
1022
1000
 
1023
1001
  self.condition = condition
1024
1002
  self.cstyle_ifs = cstyle_ifs
1025
- self.tags = tags
1026
1003
 
1027
1004
  def c_repr_chunks(self, indent=0, asexpr=False):
1028
1005
  indent_str = self.indent_str(indent=indent)
@@ -1058,11 +1035,10 @@ class CBreak(CStatement):
1058
1035
  Represents a break statement in C.
1059
1036
  """
1060
1037
 
1061
- __slots__ = ("tags",)
1038
+ __slots__ = ()
1062
1039
 
1063
- def __init__(self, tags=None, **kwargs):
1040
+ def __init__(self, **kwargs):
1064
1041
  super().__init__(**kwargs)
1065
- self.tags = tags
1066
1042
 
1067
1043
  def c_repr_chunks(self, indent=0, asexpr=False):
1068
1044
  indent_str = self.indent_str(indent=indent)
@@ -1076,11 +1052,10 @@ class CContinue(CStatement):
1076
1052
  Represents a continue statement in C.
1077
1053
  """
1078
1054
 
1079
- __slots__ = ("tags",)
1055
+ __slots__ = ()
1080
1056
 
1081
- def __init__(self, tags=None, **kwargs):
1057
+ def __init__(self, **kwargs):
1082
1058
  super().__init__(**kwargs)
1083
- self.tags = tags
1084
1059
 
1085
1060
  def c_repr_chunks(self, indent=0, asexpr=False):
1086
1061
  indent_str = self.indent_str(indent=indent)
@@ -1094,15 +1069,14 @@ class CSwitchCase(CStatement):
1094
1069
  Represents a switch-case statement in C.
1095
1070
  """
1096
1071
 
1097
- __slots__ = ("cases", "default", "switch", "tags")
1072
+ __slots__ = ("cases", "default", "switch")
1098
1073
 
1099
- def __init__(self, switch, cases, default, tags=None, **kwargs):
1074
+ def __init__(self, switch, cases, default, **kwargs):
1100
1075
  super().__init__(**kwargs)
1101
1076
 
1102
1077
  self.switch = switch
1103
1078
  self.cases: list[tuple[int | tuple[int], CStatements]] = cases
1104
1079
  self.default = default
1105
- self.tags = tags
1106
1080
 
1107
1081
  def c_repr_chunks(self, indent=0, asexpr=False):
1108
1082
  indent_str = self.indent_str(indent=indent)
@@ -1153,14 +1127,13 @@ class CIncompleteSwitchCase(CStatement):
1153
1127
  structuring fails (for whatever reason).
1154
1128
  """
1155
1129
 
1156
- __slots__ = ("cases", "head", "tags")
1130
+ __slots__ = ("cases", "head")
1157
1131
 
1158
- def __init__(self, head, cases, tags=None, **kwargs):
1132
+ def __init__(self, head, cases, **kwargs):
1159
1133
  super().__init__(**kwargs)
1160
1134
 
1161
1135
  self.head = head
1162
1136
  self.cases: list[tuple[int, CStatements]] = cases
1163
- self.tags = tags
1164
1137
 
1165
1138
  def c_repr_chunks(self, indent=0, asexpr=False):
1166
1139
  indent_str = self.indent_str(indent=indent)
@@ -1199,18 +1172,13 @@ class CAssignment(CStatement):
1199
1172
  a = b
1200
1173
  """
1201
1174
 
1202
- __slots__ = (
1203
- "lhs",
1204
- "rhs",
1205
- "tags",
1206
- )
1175
+ __slots__ = ("lhs", "rhs")
1207
1176
 
1208
- def __init__(self, lhs, rhs, tags=None, **kwargs):
1177
+ def __init__(self, lhs, rhs, **kwargs):
1209
1178
  super().__init__(**kwargs)
1210
1179
 
1211
1180
  self.lhs = lhs
1212
1181
  self.rhs = rhs
1213
- self.tags = tags
1214
1182
 
1215
1183
  def c_repr_chunks(self, indent=0, asexpr=False):
1216
1184
  indent_str = self.indent_str(indent=indent)
@@ -1278,7 +1246,6 @@ class CFunctionCall(CStatement, CExpression):
1278
1246
  "returning",
1279
1247
  "show_demangled_name",
1280
1248
  "show_disambiguated_name",
1281
- "tags",
1282
1249
  )
1283
1250
 
1284
1251
  def __init__(
@@ -1288,20 +1255,21 @@ class CFunctionCall(CStatement, CExpression):
1288
1255
  args,
1289
1256
  returning=True,
1290
1257
  ret_expr=None,
1291
- tags=None,
1292
1258
  is_expr: bool = False,
1293
1259
  show_demangled_name=True,
1294
1260
  show_disambiguated_name: bool = True,
1261
+ tags=None,
1262
+ codegen=None,
1295
1263
  **kwargs,
1296
1264
  ):
1297
- super().__init__(**kwargs)
1265
+ super().__init__(tags=tags, codegen=codegen, **kwargs)
1266
+ CConstruct.__init__(self, tags=tags, codegen=codegen)
1298
1267
 
1299
1268
  self.callee_target = callee_target
1300
1269
  self.callee_func: Function | None = callee_func
1301
1270
  self.args = args if args is not None else []
1302
1271
  self.returning = returning
1303
1272
  self.ret_expr = ret_expr
1304
- self.tags = tags
1305
1273
  self.is_expr = is_expr
1306
1274
  self.show_demangled_name = show_demangled_name
1307
1275
  self.show_disambiguated_name = show_disambiguated_name
@@ -1390,16 +1358,12 @@ class CFunctionCall(CStatement, CExpression):
1390
1358
 
1391
1359
 
1392
1360
  class CReturn(CStatement):
1393
- __slots__ = (
1394
- "retval",
1395
- "tags",
1396
- )
1361
+ __slots__ = ("retval",)
1397
1362
 
1398
- def __init__(self, retval, tags=None, **kwargs):
1363
+ def __init__(self, retval, **kwargs):
1399
1364
  super().__init__(**kwargs)
1400
1365
 
1401
1366
  self.retval = retval
1402
- self.tags = tags
1403
1367
 
1404
1368
  def c_repr_chunks(self, indent=0, asexpr=False):
1405
1369
  indent_str = self.indent_str(indent=indent)
@@ -1416,12 +1380,11 @@ class CReturn(CStatement):
1416
1380
 
1417
1381
  class CGoto(CStatement):
1418
1382
  __slots__ = (
1419
- "tags",
1420
1383
  "target",
1421
1384
  "target_idx",
1422
1385
  )
1423
1386
 
1424
- def __init__(self, target, target_idx, tags=None, **kwargs):
1387
+ def __init__(self, target, target_idx, **kwargs):
1425
1388
  super().__init__(**kwargs)
1426
1389
 
1427
1390
  if isinstance(target, CConstant):
@@ -1430,7 +1393,6 @@ class CGoto(CStatement):
1430
1393
 
1431
1394
  self.target: int | CExpression = target
1432
1395
  self.target_idx = target_idx
1433
- self.tags = tags
1434
1396
 
1435
1397
  def c_repr_chunks(self, indent=0, asexpr=False):
1436
1398
  indent_str = self.indent_str(indent=indent)
@@ -1503,15 +1465,13 @@ class CLabel(CStatement):
1503
1465
  "block_idx",
1504
1466
  "ins_addr",
1505
1467
  "name",
1506
- "tags",
1507
1468
  )
1508
1469
 
1509
- def __init__(self, name: str, ins_addr: int, block_idx: int | None, tags=None, **kwargs):
1470
+ def __init__(self, name: str, ins_addr: int, block_idx: int | None, **kwargs):
1510
1471
  super().__init__(**kwargs)
1511
1472
  self.name = name
1512
1473
  self.ins_addr = ins_addr
1513
1474
  self.block_idx = block_idx
1514
- self.tags = tags
1515
1475
 
1516
1476
  def c_repr_chunks(self, indent=0, asexpr=False):
1517
1477
  # indent-_str = self.indent_str(indent=indent)
@@ -1526,16 +1486,14 @@ class CStructField(CExpression):
1526
1486
  "field",
1527
1487
  "offset",
1528
1488
  "struct_type",
1529
- "tags",
1530
1489
  )
1531
1490
 
1532
- def __init__(self, struct_type: SimStruct, offset, field, tags=None, **kwargs):
1491
+ def __init__(self, struct_type: SimStruct, offset, field, **kwargs):
1533
1492
  super().__init__(**kwargs)
1534
1493
 
1535
1494
  self.struct_type = struct_type
1536
1495
  self.offset = offset
1537
1496
  self.field = field
1538
- self.tags = tags
1539
1497
 
1540
1498
  @property
1541
1499
  def type(self):
@@ -1553,13 +1511,12 @@ class CFakeVariable(CExpression):
1553
1511
  An uninterpreted name to display in the decompilation output. Pretty much always represents an error?
1554
1512
  """
1555
1513
 
1556
- __slots__ = ("name", "tags")
1514
+ __slots__ = ("name",)
1557
1515
 
1558
- def __init__(self, name: str, ty: SimType, tags=None, **kwargs):
1516
+ def __init__(self, name: str, ty: SimType, **kwargs):
1559
1517
  super().__init__(**kwargs)
1560
1518
  self.name = name
1561
1519
  self._type = ty.with_arch(self.codegen.project.arch)
1562
- self.tags = tags
1563
1520
 
1564
1521
  @property
1565
1522
  def type(self):
@@ -1577,22 +1534,18 @@ class CVariable(CExpression):
1577
1534
  """
1578
1535
 
1579
1536
  __slots__ = (
1580
- "tags",
1581
1537
  "unified_variable",
1582
1538
  "variable",
1583
1539
  "variable_type",
1584
1540
  "vvar_id",
1585
1541
  )
1586
1542
 
1587
- def __init__(
1588
- self, variable: SimVariable, unified_variable=None, variable_type=None, tags=None, vvar_id=None, **kwargs
1589
- ):
1543
+ def __init__(self, variable: SimVariable, unified_variable=None, variable_type=None, vvar_id=None, **kwargs):
1590
1544
  super().__init__(**kwargs)
1591
1545
 
1592
1546
  self.variable: SimVariable = variable
1593
1547
  self.unified_variable: SimVariable | None = unified_variable
1594
1548
  self.variable_type: SimType = variable_type.with_arch(self.codegen.project.arch)
1595
- self.tags = tags
1596
1549
  self.vvar_id = vvar_id
1597
1550
 
1598
1551
  @property
@@ -1620,12 +1573,11 @@ class CIndexedVariable(CExpression):
1620
1573
  Represent a variable (an array) that is indexed.
1621
1574
  """
1622
1575
 
1623
- def __init__(self, variable: CExpression, index: CExpression, variable_type=None, tags=None, **kwargs):
1576
+ def __init__(self, variable: CExpression, index: CExpression, variable_type=None, **kwargs):
1624
1577
  super().__init__(**kwargs)
1625
1578
  self.variable = variable
1626
1579
  self.index: CExpression = index
1627
1580
  self._type = variable_type
1628
- self.tags = tags
1629
1581
 
1630
1582
  if self._type is None and self.variable.type is not None:
1631
1583
  u = unpack_typeref(self.variable.type)
@@ -1665,12 +1617,11 @@ class CVariableField(CExpression):
1665
1617
  Represent a field of a variable.
1666
1618
  """
1667
1619
 
1668
- def __init__(self, variable: CExpression, field: CStructField, var_is_ptr: bool = False, tags=None, **kwargs):
1620
+ def __init__(self, variable: CExpression, field: CStructField, var_is_ptr: bool = False, **kwargs):
1669
1621
  super().__init__(**kwargs)
1670
1622
  self.variable = variable
1671
1623
  self.field = field
1672
1624
  self.var_is_ptr = var_is_ptr
1673
- self.tags = tags
1674
1625
 
1675
1626
  @property
1676
1627
  def type(self):
@@ -1696,15 +1647,13 @@ class CUnaryOp(CExpression):
1696
1647
  __slots__ = (
1697
1648
  "op",
1698
1649
  "operand",
1699
- "tags",
1700
1650
  )
1701
1651
 
1702
- def __init__(self, op, operand: CExpression, tags=None, **kwargs):
1652
+ def __init__(self, op, operand: CExpression, **kwargs):
1703
1653
  super().__init__(**kwargs)
1704
1654
 
1705
1655
  self.op = op
1706
1656
  self.operand = operand
1707
- self.tags = tags
1708
1657
 
1709
1658
  if operand.type is not None:
1710
1659
  var_type = unpack_typeref(operand.type)
@@ -1791,15 +1740,14 @@ class CBinaryOp(CExpression):
1791
1740
  Binary operations.
1792
1741
  """
1793
1742
 
1794
- __slots__ = ("_cstyle_null_cmp", "common_type", "lhs", "op", "rhs", "tags")
1743
+ __slots__ = ("_cstyle_null_cmp", "common_type", "lhs", "op", "rhs")
1795
1744
 
1796
- def __init__(self, op, lhs, rhs, tags: dict | None = None, **kwargs):
1745
+ def __init__(self, op, lhs, rhs, **kwargs):
1797
1746
  super().__init__(**kwargs)
1798
1747
 
1799
1748
  self.op = op
1800
1749
  self.lhs = lhs
1801
1750
  self.rhs = rhs
1802
- self.tags = tags
1803
1751
  self._cstyle_null_cmp = self.codegen.cstyle_null_cmp
1804
1752
 
1805
1753
  self.common_type = self.compute_common_type(self.op, self.lhs.type, self.rhs.type)
@@ -2066,16 +2014,14 @@ class CTypeCast(CExpression):
2066
2014
  "dst_type",
2067
2015
  "expr",
2068
2016
  "src_type",
2069
- "tags",
2070
2017
  )
2071
2018
 
2072
- def __init__(self, src_type: SimType | None, dst_type: SimType, expr: CExpression, tags=None, **kwargs):
2019
+ def __init__(self, src_type: SimType | None, dst_type: SimType, expr: CExpression, **kwargs):
2073
2020
  super().__init__(**kwargs)
2074
2021
 
2075
2022
  self.src_type = (src_type or expr.type).with_arch(self.codegen.project.arch)
2076
2023
  self.dst_type = dst_type.with_arch(self.codegen.project.arch)
2077
2024
  self.expr = expr
2078
- self.tags = tags
2079
2025
 
2080
2026
  @property
2081
2027
  def type(self):
@@ -2106,17 +2052,15 @@ class CTypeCast(CExpression):
2106
2052
  class CConstant(CExpression):
2107
2053
  __slots__ = (
2108
2054
  "reference_values",
2109
- "tags",
2110
2055
  "value",
2111
2056
  )
2112
2057
 
2113
- def __init__(self, value, type_: SimType, reference_values=None, tags: dict | None = None, **kwargs):
2058
+ def __init__(self, value, type_: SimType, reference_values=None, **kwargs):
2114
2059
  super().__init__(**kwargs)
2115
2060
 
2116
2061
  self.value = value
2117
2062
  self._type = type_.with_arch(self.codegen.project.arch)
2118
2063
  self.reference_values = reference_values
2119
- self.tags = tags
2120
2064
 
2121
2065
  @property
2122
2066
  def _ident(self):
@@ -2304,16 +2248,12 @@ class CConstant(CExpression):
2304
2248
 
2305
2249
 
2306
2250
  class CRegister(CExpression):
2307
- __slots__ = (
2308
- "reg",
2309
- "tags",
2310
- )
2251
+ __slots__ = ("reg",)
2311
2252
 
2312
- def __init__(self, reg, tags=None, **kwargs):
2253
+ def __init__(self, reg, **kwargs):
2313
2254
  super().__init__(**kwargs)
2314
2255
 
2315
2256
  self.reg = reg
2316
- self.tags = tags
2317
2257
 
2318
2258
  @property
2319
2259
  def type(self):
@@ -2329,15 +2269,13 @@ class CITE(CExpression):
2329
2269
  "cond",
2330
2270
  "iffalse",
2331
2271
  "iftrue",
2332
- "tags",
2333
2272
  )
2334
2273
 
2335
- def __init__(self, cond, iftrue, iffalse, tags=None, **kwargs):
2274
+ def __init__(self, cond, iftrue, iffalse, **kwargs):
2336
2275
  super().__init__(**kwargs)
2337
2276
  self.cond = cond
2338
2277
  self.iftrue = iftrue
2339
2278
  self.iffalse = iffalse
2340
- self.tags = tags
2341
2279
 
2342
2280
  @property
2343
2281
  def type(self):
@@ -2362,13 +2300,15 @@ class CMultiStatementExpression(CExpression):
2362
2300
  (stmt0, stmt1, stmt2, expr)
2363
2301
  """
2364
2302
 
2365
- __slots__ = ("expr", "stmts", "tags")
2303
+ __slots__ = (
2304
+ "expr",
2305
+ "stmts",
2306
+ )
2366
2307
 
2367
- def __init__(self, stmts: CStatements, expr: CExpression, tags=None, **kwargs):
2308
+ def __init__(self, stmts: CStatements, expr: CExpression, **kwargs):
2368
2309
  super().__init__(**kwargs)
2369
2310
  self.stmts = stmts
2370
2311
  self.expr = expr
2371
- self.tags = tags
2372
2312
 
2373
2313
  @property
2374
2314
  def type(self):
@@ -2390,14 +2330,12 @@ class CVEXCCallExpression(CExpression):
2390
2330
  __slots__ = (
2391
2331
  "callee",
2392
2332
  "operands",
2393
- "tags",
2394
2333
  )
2395
2334
 
2396
- def __init__(self, callee: str, operands: list[CExpression], tags=None, **kwargs):
2335
+ def __init__(self, callee: str, operands: list[CExpression], **kwargs):
2397
2336
  super().__init__(**kwargs)
2398
2337
  self.callee = callee
2399
2338
  self.operands = operands
2400
- self.tags = tags
2401
2339
 
2402
2340
  @property
2403
2341
  def type(self):
@@ -2645,7 +2583,7 @@ class CStructuredCodeGenerator(BaseStructuredCodeGenerator, Analysis):
2645
2583
 
2646
2584
  # TODO store extern fallback size somewhere lol
2647
2585
  self.cexterns = {
2648
- self._variable(v, 1)
2586
+ self._variable(v, 1, mark_used=False)
2649
2587
  for v in self.externs
2650
2588
  if v not in self._inlined_strings and v not in self._function_pointers
2651
2589
  }
@@ -2762,7 +2700,9 @@ class CStructuredCodeGenerator(BaseStructuredCodeGenerator, Analysis):
2762
2700
  return _mapping.get(n)(signed=signed).with_arch(self.project.arch)
2763
2701
  return SimTypeNum(n, signed=signed).with_arch(self.project.arch)
2764
2702
 
2765
- def _variable(self, variable: SimVariable, fallback_type_size: int | None, vvar_id: int | None = None) -> CVariable:
2703
+ def _variable(
2704
+ self, variable: SimVariable, fallback_type_size: int | None, vvar_id: int | None = None, mark_used: bool = True
2705
+ ) -> CVariable:
2766
2706
  # TODO: we need to fucking make sure that variable recovery and type inference actually generates a size
2767
2707
  # TODO: for each variable it links into the fucking ail. then we can remove fallback_type_size.
2768
2708
  unified = self._variable_kb.variables[self._func.addr].unified_variable(variable)
@@ -2774,7 +2714,8 @@ class CStructuredCodeGenerator(BaseStructuredCodeGenerator, Analysis):
2774
2714
  (fallback_type_size or self.project.arch.bytes) * self.project.arch.byte_width
2775
2715
  )
2776
2716
  cvar = CVariable(variable, unified_variable=unified, variable_type=variable_type, codegen=self, vvar_id=vvar_id)
2777
- self._variables_in_use[variable] = cvar
2717
+ if mark_used:
2718
+ self._variables_in_use[variable] = cvar
2778
2719
  return cvar
2779
2720
 
2780
2721
  def _get_variable_reference(self, cvar: CVariable) -> CExpression:
@@ -2840,7 +2781,7 @@ class CStructuredCodeGenerator(BaseStructuredCodeGenerator, Analysis):
2840
2781
  # expr must express a POINTER to the base
2841
2782
  # returns a value which has a simtype of data_type as if it were dereferenced out of expr
2842
2783
  data_type = unpack_typeref(data_type)
2843
- base_type = unpack_typeref(unpack_pointer(expr.type))
2784
+ base_type = unpack_typeref(unpack_pointer_and_array(expr.type))
2844
2785
  if base_type is None:
2845
2786
  # well, not much we can do
2846
2787
  if data_type is None:
@@ -2963,7 +2904,7 @@ class CStructuredCodeGenerator(BaseStructuredCodeGenerator, Analysis):
2963
2904
  ) -> CExpression:
2964
2905
  # same rule as _access_constant_offset wrt pointer expressions
2965
2906
  data_type = unpack_typeref(data_type)
2966
- base_type = unpack_pointer(expr.type)
2907
+ base_type = unpack_pointer_and_array(expr.type)
2967
2908
  if base_type is None:
2968
2909
  # use the fallback from above
2969
2910
  return self._access_constant_offset(expr, 0, data_type, lvalue, renegotiate_type)
@@ -3023,7 +2964,7 @@ class CStructuredCodeGenerator(BaseStructuredCodeGenerator, Analysis):
3023
2964
  kernel = None
3024
2965
  while i < len(terms):
3025
2966
  c, t = terms[i]
3026
- if isinstance(unpack_typeref(t.type), SimTypePointer):
2967
+ if isinstance(unpack_typeref(t.type), (SimTypePointer, SimTypeArray)):
3027
2968
  if kernel is not None:
3028
2969
  l.warning("Summing two different pointers together. Uh oh!")
3029
2970
  return bail_out()
@@ -3046,7 +2987,7 @@ class CStructuredCodeGenerator(BaseStructuredCodeGenerator, Analysis):
3046
2987
 
3047
2988
  # suffering.
3048
2989
  while terms:
3049
- kernel_type = unpack_typeref(unpack_pointer(kernel.type))
2990
+ kernel_type = unpack_typeref(unpack_pointer_and_array(kernel.type))
3050
2991
  assert kernel_type
3051
2992
 
3052
2993
  if kernel_type.size is None:
@@ -3113,7 +3054,7 @@ class CStructuredCodeGenerator(BaseStructuredCodeGenerator, Analysis):
3113
3054
  kernel = inner.operand
3114
3055
  else:
3115
3056
  kernel = CUnaryOp("Reference", inner, codegen=self)
3116
- if unpack_typeref(unpack_pointer(kernel.type)) == kernel_type:
3057
+ if unpack_typeref(unpack_pointer_and_array(kernel.type)) == kernel_type:
3117
3058
  # we are not making progress
3118
3059
  pass
3119
3060
  else:
@@ -3967,7 +3908,7 @@ class PointerArithmeticFixer(CStructuredCodeWalker):
3967
3908
  )
3968
3909
  else:
3969
3910
  op = "Add"
3970
- return CBinaryOp(op, out.operand.variable, const, out.operand.tags, codegen=out.codegen)
3911
+ return CBinaryOp(op, out.operand.variable, const, tags=out.operand.tags, codegen=out.codegen)
3971
3912
  return out
3972
3913
  return obj
3973
3914