angr 9.2.140__py3-none-manylinux2014_x86_64.whl → 9.2.142__py3-none-manylinux2014_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 +1 -1
- angr/analyses/calling_convention/calling_convention.py +105 -35
- angr/analyses/calling_convention/fact_collector.py +44 -18
- angr/analyses/calling_convention/utils.py +3 -1
- angr/analyses/cfg/cfg_base.py +38 -4
- angr/analyses/cfg/cfg_fast.py +23 -7
- angr/analyses/cfg/indirect_jump_resolvers/jumptable.py +13 -8
- angr/analyses/class_identifier.py +8 -7
- angr/analyses/complete_calling_conventions.py +1 -1
- angr/analyses/decompiler/ail_simplifier.py +105 -62
- angr/analyses/decompiler/callsite_maker.py +24 -11
- angr/analyses/decompiler/clinic.py +83 -5
- angr/analyses/decompiler/condition_processor.py +7 -7
- angr/analyses/decompiler/decompilation_cache.py +2 -1
- angr/analyses/decompiler/decompiler.py +11 -2
- angr/analyses/decompiler/dephication/graph_vvar_mapping.py +4 -6
- angr/analyses/decompiler/optimization_passes/base_ptr_save_simplifier.py +8 -2
- angr/analyses/decompiler/optimization_passes/condition_constprop.py +63 -34
- angr/analyses/decompiler/optimization_passes/duplication_reverter/duplication_reverter.py +3 -1
- angr/analyses/decompiler/optimization_passes/flip_boolean_cmp.py +21 -2
- angr/analyses/decompiler/optimization_passes/lowered_switch_simplifier.py +85 -16
- angr/analyses/decompiler/optimization_passes/optimization_pass.py +78 -1
- angr/analyses/decompiler/optimization_passes/register_save_area_simplifier.py +29 -7
- angr/analyses/decompiler/optimization_passes/return_duplicator_base.py +51 -7
- angr/analyses/decompiler/optimization_passes/stack_canary_simplifier.py +6 -0
- angr/analyses/decompiler/optimization_passes/win_stack_canary_simplifier.py +9 -1
- angr/analyses/decompiler/peephole_optimizations/eager_eval.py +44 -7
- angr/analyses/decompiler/region_identifier.py +76 -51
- angr/analyses/decompiler/region_simplifiers/expr_folding.py +32 -18
- angr/analyses/decompiler/region_simplifiers/region_simplifier.py +4 -1
- angr/analyses/decompiler/ssailification/rewriting.py +70 -32
- angr/analyses/decompiler/ssailification/rewriting_engine.py +118 -24
- angr/analyses/decompiler/ssailification/ssailification.py +22 -14
- angr/analyses/decompiler/stack_item.py +36 -0
- angr/analyses/decompiler/structured_codegen/c.py +86 -145
- angr/analyses/decompiler/structuring/dream.py +1 -1
- angr/analyses/decompiler/structuring/phoenix.py +9 -4
- angr/analyses/decompiler/structuring/structurer_base.py +2 -1
- angr/analyses/decompiler/utils.py +46 -20
- angr/analyses/find_objects_static.py +2 -1
- angr/analyses/reaching_definitions/engine_vex.py +13 -0
- angr/analyses/reaching_definitions/function_handler.py +24 -10
- angr/analyses/reaching_definitions/function_handler_library/stdio.py +1 -0
- angr/analyses/reaching_definitions/function_handler_library/stdlib.py +45 -12
- angr/analyses/reaching_definitions/function_handler_library/string.py +77 -21
- angr/analyses/reaching_definitions/function_handler_library/unistd.py +21 -1
- angr/analyses/reaching_definitions/rd_state.py +11 -7
- angr/analyses/s_liveness.py +44 -6
- angr/analyses/s_reaching_definitions/s_rda_model.py +4 -2
- angr/analyses/s_reaching_definitions/s_rda_view.py +43 -25
- angr/analyses/typehoon/simple_solver.py +35 -8
- angr/analyses/typehoon/typehoon.py +3 -1
- angr/analyses/variable_recovery/engine_ail.py +1 -1
- angr/analyses/variable_recovery/engine_vex.py +20 -4
- angr/calling_conventions.py +17 -12
- angr/factory.py +8 -3
- angr/knowledge_plugins/functions/function.py +5 -10
- angr/knowledge_plugins/variables/variable_manager.py +34 -5
- angr/procedures/definitions/__init__.py +3 -10
- angr/procedures/definitions/wdk_ntoskrnl.py +2 -0
- angr/procedures/win32_kernel/__fastfail.py +15 -0
- angr/sim_procedure.py +2 -2
- angr/simos/simos.py +17 -11
- angr/simos/windows.py +42 -1
- angr/utils/ail.py +41 -1
- angr/utils/cpp.py +17 -0
- angr/utils/doms.py +142 -0
- angr/utils/library.py +1 -1
- angr/utils/types.py +59 -0
- {angr-9.2.140.dist-info → angr-9.2.142.dist-info}/METADATA +7 -7
- {angr-9.2.140.dist-info → angr-9.2.142.dist-info}/RECORD +75 -70
- {angr-9.2.140.dist-info → angr-9.2.142.dist-info}/LICENSE +0 -0
- {angr-9.2.140.dist-info → angr-9.2.142.dist-info}/WHEEL +0 -0
- {angr-9.2.140.dist-info → angr-9.2.142.dist-info}/entry_points.txt +0 -0
- {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(),
|
|
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
|
-
|
|
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,
|
|
658
|
-
super().__init__(
|
|
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,
|
|
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,
|
|
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__ = (
|
|
811
|
+
__slots__ = (
|
|
812
|
+
"body",
|
|
813
|
+
"condition",
|
|
814
|
+
"initializer",
|
|
815
|
+
"iterator",
|
|
816
|
+
)
|
|
839
817
|
|
|
840
|
-
def __init__(self, initializer, condition, iterator, body,
|
|
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__ = (
|
|
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,
|
|
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__ = (
|
|
1038
|
+
__slots__ = ()
|
|
1062
1039
|
|
|
1063
|
-
def __init__(self,
|
|
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__ = (
|
|
1055
|
+
__slots__ = ()
|
|
1080
1056
|
|
|
1081
|
-
def __init__(self,
|
|
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"
|
|
1072
|
+
__slots__ = ("cases", "default", "switch")
|
|
1098
1073
|
|
|
1099
|
-
def __init__(self, switch, cases, default,
|
|
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"
|
|
1130
|
+
__slots__ = ("cases", "head")
|
|
1157
1131
|
|
|
1158
|
-
def __init__(self, head, cases,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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",
|
|
1514
|
+
__slots__ = ("name",)
|
|
1557
1515
|
|
|
1558
|
-
def __init__(self, name: str, ty: SimType,
|
|
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,
|
|
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,
|
|
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,
|
|
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"
|
|
1743
|
+
__slots__ = ("_cstyle_null_cmp", "common_type", "lhs", "op", "rhs")
|
|
1795
1744
|
|
|
1796
|
-
def __init__(self, op, lhs, rhs,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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__ = (
|
|
2303
|
+
__slots__ = (
|
|
2304
|
+
"expr",
|
|
2305
|
+
"stmts",
|
|
2306
|
+
)
|
|
2366
2307
|
|
|
2367
|
-
def __init__(self, stmts: CStatements, expr: CExpression,
|
|
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],
|
|
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(
|
|
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
|
-
|
|
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(
|
|
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 =
|
|
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(
|
|
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(
|
|
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
|
|