angr 9.2.138__py3-none-macosx_11_0_arm64.whl → 9.2.139__py3-none-macosx_11_0_arm64.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/fact_collector.py +59 -12
- angr/analyses/calling_convention/utils.py +2 -2
- angr/analyses/cfg/cfg_fast.py +12 -4
- angr/analyses/decompiler/ail_simplifier.py +14 -3
- angr/analyses/decompiler/block_simplifier.py +0 -2
- angr/analyses/decompiler/callsite_maker.py +80 -14
- angr/analyses/decompiler/clinic.py +31 -37
- angr/analyses/decompiler/condition_processor.py +2 -2
- angr/analyses/decompiler/decompiler.py +2 -0
- angr/analyses/decompiler/dephication/rewriting_engine.py +16 -7
- angr/analyses/decompiler/optimization_passes/__init__.py +3 -0
- angr/analyses/decompiler/optimization_passes/condition_constprop.py +149 -0
- angr/analyses/decompiler/optimization_passes/deadblock_remover.py +12 -3
- angr/analyses/decompiler/optimization_passes/inlined_string_transformation_simplifier.py +1 -1
- angr/analyses/decompiler/optimization_passes/optimization_pass.py +5 -2
- angr/analyses/decompiler/optimization_passes/return_duplicator_base.py +15 -7
- angr/analyses/decompiler/optimization_passes/return_duplicator_high.py +7 -10
- angr/analyses/decompiler/peephole_optimizations/eager_eval.py +12 -1
- angr/analyses/decompiler/peephole_optimizations/remove_redundant_conversions.py +61 -25
- angr/analyses/decompiler/peephole_optimizations/remove_redundant_shifts.py +50 -1
- angr/analyses/decompiler/presets/fast.py +2 -0
- angr/analyses/decompiler/presets/full.py +2 -0
- angr/analyses/decompiler/region_simplifiers/region_simplifier.py +4 -0
- angr/analyses/decompiler/ssailification/rewriting_engine.py +20 -2
- angr/analyses/decompiler/ssailification/traversal_engine.py +4 -3
- angr/analyses/decompiler/structured_codegen/c.py +10 -3
- angr/analyses/decompiler/structuring/dream.py +7 -2
- angr/analyses/decompiler/structuring/phoenix.py +101 -49
- angr/analyses/decompiler/structuring/structurer_base.py +85 -36
- angr/analyses/decompiler/structuring/structurer_nodes.py +3 -1
- angr/analyses/deobfuscator/api_obf_finder.py +6 -1
- angr/analyses/deobfuscator/api_obf_type2_finder.py +158 -0
- angr/analyses/s_propagator.py +127 -50
- angr/analyses/s_reaching_definitions/s_rda_view.py +2 -2
- angr/analyses/s_reaching_definitions/s_reaching_definitions.py +3 -1
- angr/analyses/variable_recovery/engine_ail.py +1 -1
- angr/analyses/variable_recovery/engine_base.py +55 -62
- angr/analyses/variable_recovery/engine_vex.py +1 -1
- angr/analyses/variable_recovery/irsb_scanner.py +2 -2
- angr/calling_conventions.py +66 -9
- angr/engines/engine.py +2 -18
- angr/engines/light/engine.py +3 -8
- angr/engines/pcode/emulate.py +2 -2
- angr/engines/pcode/lifter.py +2 -2
- angr/engines/successors.py +1 -8
- angr/engines/vex/lifter.py +2 -2
- angr/engines/vex/light/light.py +2 -2
- angr/knowledge_plugins/cfg/cfg_model.py +3 -2
- angr/knowledge_plugins/labels.py +2 -2
- angr/knowledge_plugins/obfuscations.py +1 -0
- angr/knowledge_plugins/xrefs/xref_manager.py +4 -0
- angr/lib/angr_native.dylib +0 -0
- {angr-9.2.138.dist-info → angr-9.2.139.dist-info}/METADATA +6 -6
- {angr-9.2.138.dist-info → angr-9.2.139.dist-info}/RECORD +59 -57
- {angr-9.2.138.dist-info → angr-9.2.139.dist-info}/LICENSE +0 -0
- {angr-9.2.138.dist-info → angr-9.2.139.dist-info}/WHEEL +0 -0
- {angr-9.2.138.dist-info → angr-9.2.139.dist-info}/entry_points.txt +0 -0
- {angr-9.2.138.dist-info → angr-9.2.139.dist-info}/top_level.txt +0 -0
|
@@ -4,9 +4,9 @@ from typing import Any
|
|
|
4
4
|
|
|
5
5
|
import networkx
|
|
6
6
|
|
|
7
|
+
from angr.analyses.decompiler.structuring import SAILRStructurer, DreamStructurer
|
|
7
8
|
from .return_duplicator_base import ReturnDuplicatorBase
|
|
8
9
|
from .optimization_pass import OptimizationPass, OptimizationPassStage
|
|
9
|
-
from angr.analyses.decompiler.structuring import SAILRStructurer, DreamStructurer
|
|
10
10
|
|
|
11
11
|
_l = logging.getLogger(name=__name__)
|
|
12
12
|
|
|
@@ -19,7 +19,7 @@ class ReturnDuplicatorHigh(OptimizationPass, ReturnDuplicatorBase):
|
|
|
19
19
|
|
|
20
20
|
ARCHES = None
|
|
21
21
|
PLATFORMS = None
|
|
22
|
-
STAGE = OptimizationPassStage.
|
|
22
|
+
STAGE = OptimizationPassStage.AFTER_GLOBAL_SIMPLIFICATION
|
|
23
23
|
NAME = "Duplicate return-only blocks (high)"
|
|
24
24
|
DESCRIPTION = __doc__
|
|
25
25
|
STRUCTURING = [SAILRStructurer.NAME, DreamStructurer.NAME]
|
|
@@ -28,27 +28,22 @@ class ReturnDuplicatorHigh(OptimizationPass, ReturnDuplicatorBase):
|
|
|
28
28
|
self,
|
|
29
29
|
func,
|
|
30
30
|
# settings
|
|
31
|
+
*,
|
|
32
|
+
vvar_id_start: int,
|
|
31
33
|
max_calls_in_regions: int = 2,
|
|
32
34
|
minimize_copies_for_regions: bool = True,
|
|
33
|
-
region_identifier=None,
|
|
34
|
-
vvar_id_start: int | None = None,
|
|
35
35
|
scratch: dict[str, Any] | None = None,
|
|
36
36
|
**kwargs,
|
|
37
37
|
):
|
|
38
|
-
OptimizationPass.__init__(
|
|
39
|
-
self, func, vvar_id_start=vvar_id_start, scratch=scratch, region_identifier=region_identifier, **kwargs
|
|
40
|
-
)
|
|
38
|
+
OptimizationPass.__init__(self, func, vvar_id_start=vvar_id_start, scratch=scratch, **kwargs)
|
|
41
39
|
ReturnDuplicatorBase.__init__(
|
|
42
40
|
self,
|
|
43
41
|
func,
|
|
44
42
|
max_calls_in_regions=max_calls_in_regions,
|
|
45
43
|
minimize_copies_for_regions=minimize_copies_for_regions,
|
|
46
|
-
ri=region_identifier,
|
|
47
44
|
vvar_id_start=vvar_id_start,
|
|
48
45
|
scratch=scratch,
|
|
49
46
|
)
|
|
50
|
-
# since we run before the RegionIdentification pass in the decompiler, we need to collect it early here
|
|
51
|
-
self._ri = self._recover_regions(self._graph)
|
|
52
47
|
|
|
53
48
|
self.analyze()
|
|
54
49
|
|
|
@@ -60,6 +55,8 @@ class ReturnDuplicatorHigh(OptimizationPass, ReturnDuplicatorBase):
|
|
|
60
55
|
return dst_is_const_ret
|
|
61
56
|
|
|
62
57
|
def _analyze(self, cache=None):
|
|
58
|
+
# since we run before the RegionIdentification pass in the decompiler, we need to collect it early here
|
|
59
|
+
self._ri = self._recover_regions(self._graph)
|
|
63
60
|
copy_graph = networkx.DiGraph(self._graph)
|
|
64
61
|
if self._analyze_core(copy_graph):
|
|
65
62
|
self.out_graph = self._simplify_graph(copy_graph)
|
|
@@ -150,7 +150,12 @@ class EagerEvaluation(PeepholeOptimizationExprBase):
|
|
|
150
150
|
if isinstance(expr.operands[1], Const) and expr.operands[1].value == 1:
|
|
151
151
|
# x * 1 => x
|
|
152
152
|
return expr.operands[0]
|
|
153
|
-
if
|
|
153
|
+
if (
|
|
154
|
+
isinstance(expr.operands[0], Const)
|
|
155
|
+
and expr.operands[0].is_int
|
|
156
|
+
and isinstance(expr.operands[1], Const)
|
|
157
|
+
and expr.operands[1].is_int
|
|
158
|
+
):
|
|
154
159
|
# constant multiplication
|
|
155
160
|
mask = (1 << expr.bits) - 1
|
|
156
161
|
return Const(
|
|
@@ -236,6 +241,10 @@ class EagerEvaluation(PeepholeOptimizationExprBase):
|
|
|
236
241
|
return expr.operands[1]
|
|
237
242
|
if isinstance(expr.operands[1], Const) and expr.operands[1].value == 0:
|
|
238
243
|
return expr.operands[0]
|
|
244
|
+
if isinstance(expr.operands[0], Const) and expr.operands[0].value == (1 << expr.operands[0].bits) - 1:
|
|
245
|
+
return expr.operands[0]
|
|
246
|
+
if isinstance(expr.operands[1], Const) and expr.operands[1].value == (1 << expr.operands[1].bits) - 1:
|
|
247
|
+
return expr.operands[1]
|
|
239
248
|
if expr.operands[0].likes(expr.operands[1]):
|
|
240
249
|
return expr.operands[0]
|
|
241
250
|
|
|
@@ -290,6 +299,7 @@ class EagerEvaluation(PeepholeOptimizationExprBase):
|
|
|
290
299
|
def _optimize_convert(expr: Convert):
|
|
291
300
|
if (
|
|
292
301
|
isinstance(expr.operand, Const)
|
|
302
|
+
and expr.operand.is_int
|
|
293
303
|
and expr.from_type == Convert.TYPE_INT
|
|
294
304
|
and expr.to_type == Convert.TYPE_INT
|
|
295
305
|
and expr.from_bits > expr.to_bits
|
|
@@ -300,6 +310,7 @@ class EagerEvaluation(PeepholeOptimizationExprBase):
|
|
|
300
310
|
return Const(expr.idx, expr.operand.variable, v, expr.to_bits, **expr.operand.tags)
|
|
301
311
|
if (
|
|
302
312
|
isinstance(expr.operand, Const)
|
|
313
|
+
and expr.operand.is_int
|
|
303
314
|
and expr.from_type == Convert.TYPE_INT
|
|
304
315
|
and expr.to_type == Convert.TYPE_INT
|
|
305
316
|
and expr.from_bits <= expr.to_bits
|
|
@@ -169,29 +169,65 @@ class RemoveRedundantConversions(PeepholeOptimizationExprBase):
|
|
|
169
169
|
@staticmethod
|
|
170
170
|
def _optimize_Convert(expr: Convert):
|
|
171
171
|
operand_expr = expr.operand
|
|
172
|
-
if isinstance(operand_expr, BinaryOp)
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
172
|
+
if isinstance(operand_expr, BinaryOp):
|
|
173
|
+
if operand_expr.op in {
|
|
174
|
+
"Mul",
|
|
175
|
+
"Shl",
|
|
176
|
+
"Div",
|
|
177
|
+
"DivMod",
|
|
178
|
+
"Mod",
|
|
179
|
+
"Add",
|
|
180
|
+
"Sub",
|
|
181
|
+
}:
|
|
182
|
+
op0, op1 = operand_expr.operands
|
|
183
|
+
if (
|
|
184
|
+
isinstance(op0, Convert)
|
|
185
|
+
and isinstance(op1, Convert)
|
|
186
|
+
and op0.from_bits == op1.from_bits
|
|
187
|
+
and op0.to_bits == op1.to_bits
|
|
188
|
+
and expr.from_bits == op0.to_bits
|
|
189
|
+
and expr.to_bits == op1.from_bits
|
|
190
|
+
):
|
|
191
|
+
return BinaryOp(
|
|
192
|
+
operand_expr.idx,
|
|
193
|
+
operand_expr.op,
|
|
194
|
+
[op0.operand, op1.operand],
|
|
195
|
+
expr.is_signed,
|
|
196
|
+
**operand_expr.tags,
|
|
197
|
+
)
|
|
198
|
+
elif operand_expr.op == "Or" and expr.from_bits > expr.to_bits:
|
|
199
|
+
# Conv(64->32,((vvar_183{reg 128} & 0xffffffff00000000<64>)
|
|
200
|
+
# | Conv(32->64, Load(addr=0x200002dc<32>, size=4, endness=Iend_LE))))
|
|
201
|
+
# =>
|
|
202
|
+
# Conv(64->32, Load(addr=0x200002dc<32>, size=4, endness=Iend_LE))
|
|
203
|
+
high_mask = ((1 << expr.from_bits) - 1) - ((1 << expr.to_bits) - 1)
|
|
204
|
+
op0, op1 = operand_expr.operands
|
|
205
|
+
if (
|
|
206
|
+
isinstance(op0, BinaryOp)
|
|
207
|
+
and op0.op == "And"
|
|
208
|
+
and isinstance(op0.operands[1], Const)
|
|
209
|
+
and op0.operands[1].value == high_mask
|
|
210
|
+
):
|
|
211
|
+
return Convert(
|
|
212
|
+
expr.idx,
|
|
213
|
+
expr.from_bits,
|
|
214
|
+
expr.to_bits,
|
|
215
|
+
expr.is_signed,
|
|
216
|
+
op1,
|
|
217
|
+
**expr.tags,
|
|
218
|
+
)
|
|
219
|
+
if (
|
|
220
|
+
isinstance(op1, BinaryOp)
|
|
221
|
+
and op1.op == "And"
|
|
222
|
+
and isinstance(op1.operands[1], Const)
|
|
223
|
+
and op1.operands[1].value == high_mask
|
|
224
|
+
):
|
|
225
|
+
return Convert(
|
|
226
|
+
expr.idx,
|
|
227
|
+
expr.from_bits,
|
|
228
|
+
expr.to_bits,
|
|
229
|
+
expr.is_signed,
|
|
230
|
+
op0,
|
|
231
|
+
**expr.tags,
|
|
232
|
+
)
|
|
197
233
|
return None
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# pylint:disable=no-self-use,
|
|
1
|
+
# pylint:disable=no-self-use,too-many-boolean-expressions
|
|
2
2
|
from __future__ import annotations
|
|
3
3
|
from ailment.expression import BinaryOp, Const, Convert
|
|
4
4
|
|
|
@@ -7,6 +7,10 @@ from .utils import get_expr_shift_left_amount
|
|
|
7
7
|
|
|
8
8
|
|
|
9
9
|
class RemoveRedundantShifts(PeepholeOptimizationExprBase):
|
|
10
|
+
"""
|
|
11
|
+
Remove redundant bitshift operations.
|
|
12
|
+
"""
|
|
13
|
+
|
|
10
14
|
__slots__ = ()
|
|
11
15
|
|
|
12
16
|
NAME = "Remove redundant bitshifts"
|
|
@@ -43,4 +47,49 @@ class RemoveRedundantShifts(PeepholeOptimizationExprBase):
|
|
|
43
47
|
if expr.op in {"Shl", "Shr", "Sar"} and isinstance(expr.operands[1], Const) and expr.operands[1].value == 0:
|
|
44
48
|
return expr.operands[0]
|
|
45
49
|
|
|
50
|
+
mask_hi32bits = 0xFFFFFFFF_00000000
|
|
51
|
+
exp_32bits = 0x1_00000000
|
|
52
|
+
if (
|
|
53
|
+
expr.op == "Shr"
|
|
54
|
+
and isinstance(expr.operands[1], Const)
|
|
55
|
+
and expr.operands[1].value == 32
|
|
56
|
+
and isinstance(expr.operands[0], BinaryOp)
|
|
57
|
+
and expr.operands[0].op == "Or"
|
|
58
|
+
):
|
|
59
|
+
op0, op1 = expr.operands[0].operands
|
|
60
|
+
if (
|
|
61
|
+
isinstance(op1, Convert)
|
|
62
|
+
and op1.from_bits == 32
|
|
63
|
+
and op1.to_bits == 64
|
|
64
|
+
and op1.from_type == Convert.TYPE_INT
|
|
65
|
+
and op1.to_type == Convert.TYPE_INT
|
|
66
|
+
and isinstance(op0, BinaryOp)
|
|
67
|
+
and op0.op == "And"
|
|
68
|
+
):
|
|
69
|
+
# (expr<64-bits> & 0xffffffff_00000000) | Conv(32->64, expr<32-bits>)) >> 32 ==> expr<64-bits> >> 32
|
|
70
|
+
inner_op0, inner_op1 = op0.operands
|
|
71
|
+
if isinstance(inner_op1, Const) and inner_op1.value == mask_hi32bits:
|
|
72
|
+
if (
|
|
73
|
+
isinstance(inner_op0, BinaryOp)
|
|
74
|
+
and isinstance(inner_op0.operands[1], Const)
|
|
75
|
+
and inner_op0.operands[1].value == exp_32bits
|
|
76
|
+
):
|
|
77
|
+
return inner_op0.operands[0]
|
|
78
|
+
return BinaryOp(expr.idx, "Shr", [inner_op0, expr.operands[1]], expr.signed, **expr.tags)
|
|
79
|
+
return BinaryOp(expr.idx, "Shr", [op0, expr.operands[1]], expr.signed, **expr.tags)
|
|
80
|
+
|
|
81
|
+
for op0, op1 in [expr.operands[0].operands, expr.operands[0].operands[::-1]]:
|
|
82
|
+
# ((v11 & 0xffff_ffff | 10.0 * 0x1_00000000) >> 32) ==> 10.0
|
|
83
|
+
if (
|
|
84
|
+
isinstance(op0, BinaryOp)
|
|
85
|
+
and op0.op == "And"
|
|
86
|
+
and isinstance(op0.operands[1], Const)
|
|
87
|
+
and op0.operands[1].value == 0xFFFF_FFFF
|
|
88
|
+
and isinstance(op1, BinaryOp)
|
|
89
|
+
and op1.op == "Mul"
|
|
90
|
+
and isinstance(op1.operands[1], Const)
|
|
91
|
+
and op1.operands[1].value == 0x1_0000_0000
|
|
92
|
+
):
|
|
93
|
+
return op1.operands[0]
|
|
94
|
+
|
|
46
95
|
return None
|
|
@@ -21,6 +21,7 @@ from angr.analyses.decompiler.optimization_passes import (
|
|
|
21
21
|
CallStatementRewriter,
|
|
22
22
|
DeadblockRemover,
|
|
23
23
|
SwitchReusedEntryRewriter,
|
|
24
|
+
ConditionConstantPropagation,
|
|
24
25
|
)
|
|
25
26
|
|
|
26
27
|
|
|
@@ -47,6 +48,7 @@ preset_fast = DecompilationPreset(
|
|
|
47
48
|
FlipBooleanCmp,
|
|
48
49
|
InlinedStringTransformationSimplifier,
|
|
49
50
|
CallStatementRewriter,
|
|
51
|
+
ConditionConstantPropagation,
|
|
50
52
|
],
|
|
51
53
|
)
|
|
52
54
|
|
|
@@ -26,6 +26,7 @@ from angr.analyses.decompiler.optimization_passes import (
|
|
|
26
26
|
InlinedStringTransformationSimplifier,
|
|
27
27
|
CallStatementRewriter,
|
|
28
28
|
SwitchReusedEntryRewriter,
|
|
29
|
+
ConditionConstantPropagation,
|
|
29
30
|
)
|
|
30
31
|
|
|
31
32
|
|
|
@@ -57,6 +58,7 @@ preset_full = DecompilationPreset(
|
|
|
57
58
|
InlinedStringTransformationSimplifier,
|
|
58
59
|
CallStatementRewriter,
|
|
59
60
|
SwitchReusedEntryRewriter,
|
|
61
|
+
ConditionConstantPropagation,
|
|
60
62
|
],
|
|
61
63
|
)
|
|
62
64
|
|
|
@@ -88,6 +88,10 @@ class RegionSimplifier(Analysis):
|
|
|
88
88
|
#
|
|
89
89
|
|
|
90
90
|
def _fold_oneuse_expressions(self, region):
|
|
91
|
+
# Disabled until https://github.com/angr/angr/issues/5110 and related folding issues fixed
|
|
92
|
+
return region
|
|
93
|
+
|
|
94
|
+
# pylint:disable=unreachable
|
|
91
95
|
variable_manager = self.variable_kb.variables[self.func.addr]
|
|
92
96
|
expr_counter = ExpressionCounter(region, variable_manager)
|
|
93
97
|
|
|
@@ -3,7 +3,7 @@ from __future__ import annotations
|
|
|
3
3
|
import logging
|
|
4
4
|
|
|
5
5
|
from ailment.manager import Manager
|
|
6
|
-
from ailment.statement import Statement, Assignment, Store, Call, Return, ConditionalJump, DirtyStatement
|
|
6
|
+
from ailment.statement import Statement, Assignment, Store, Call, Return, ConditionalJump, DirtyStatement, Jump
|
|
7
7
|
from ailment.expression import (
|
|
8
8
|
Expression,
|
|
9
9
|
Register,
|
|
@@ -19,6 +19,7 @@ from ailment.expression import (
|
|
|
19
19
|
ITE,
|
|
20
20
|
Tmp,
|
|
21
21
|
DirtyExpression,
|
|
22
|
+
Reinterpret,
|
|
22
23
|
)
|
|
23
24
|
|
|
24
25
|
from angr.engines.light.engine import SimEngineNostmtAIL
|
|
@@ -183,6 +184,12 @@ class SimEngineSSARewriting(
|
|
|
183
184
|
|
|
184
185
|
return None
|
|
185
186
|
|
|
187
|
+
def _handle_stmt_Jump(self, stmt: Jump) -> Jump | None:
|
|
188
|
+
new_target = self._expr(stmt.target)
|
|
189
|
+
if new_target is not None:
|
|
190
|
+
return Jump(stmt.idx, new_target, stmt.target_idx, **stmt.tags)
|
|
191
|
+
return None
|
|
192
|
+
|
|
186
193
|
def _handle_stmt_ConditionalJump(self, stmt: ConditionalJump) -> ConditionalJump | None:
|
|
187
194
|
new_cond = self._expr(stmt.condition)
|
|
188
195
|
new_true_target = self._expr(stmt.true_target) if stmt.true_target is not None else None
|
|
@@ -429,7 +436,18 @@ class SimEngineSSARewriting(
|
|
|
429
436
|
def _handle_expr_Phi(self, expr):
|
|
430
437
|
return None
|
|
431
438
|
|
|
432
|
-
def _handle_expr_Reinterpret(self, expr):
|
|
439
|
+
def _handle_expr_Reinterpret(self, expr: Reinterpret) -> Reinterpret | None:
|
|
440
|
+
new_operand = self._expr(expr.operand)
|
|
441
|
+
if new_operand is not None:
|
|
442
|
+
return Reinterpret(
|
|
443
|
+
expr.idx,
|
|
444
|
+
expr.from_bits,
|
|
445
|
+
expr.from_type,
|
|
446
|
+
expr.to_bits,
|
|
447
|
+
expr.to_type,
|
|
448
|
+
new_operand,
|
|
449
|
+
**expr.tags,
|
|
450
|
+
)
|
|
433
451
|
return None
|
|
434
452
|
|
|
435
453
|
def _handle_expr_StackBaseOffset(self, expr):
|
|
@@ -205,7 +205,7 @@ class SimEngineSSATraversal(SimEngineLightAIL[TraversalState, None, None, None])
|
|
|
205
205
|
_handle_binop_Set = _handle_binop_Default
|
|
206
206
|
|
|
207
207
|
def _handle_unop_Default(self, expr):
|
|
208
|
-
self._expr(expr.
|
|
208
|
+
self._expr(expr.operand)
|
|
209
209
|
|
|
210
210
|
_handle_unop_BitwiseNeg = _handle_unop_Default
|
|
211
211
|
_handle_unop_Dereference = _handle_unop_Default
|
|
@@ -243,16 +243,17 @@ class SimEngineSSATraversal(SimEngineLightAIL[TraversalState, None, None, None])
|
|
|
243
243
|
if expr.maddr is not None:
|
|
244
244
|
self._expr(expr.maddr)
|
|
245
245
|
|
|
246
|
+
_handle_expr_Convert = _handle_unop_Default
|
|
247
|
+
_handle_expr_Reinterpret = _handle_unop_Default
|
|
248
|
+
|
|
246
249
|
def _handle_Dummy(self, expr):
|
|
247
250
|
pass
|
|
248
251
|
|
|
249
252
|
_handle_expr_VirtualVariable = _handle_Dummy
|
|
250
253
|
_handle_expr_Phi = _handle_Dummy
|
|
251
254
|
_handle_expr_Load = _handle_Dummy
|
|
252
|
-
_handle_expr_Convert = _handle_Dummy
|
|
253
255
|
_handle_expr_Const = _handle_Dummy
|
|
254
256
|
_handle_expr_MultiStatementExpression = _handle_Dummy
|
|
255
|
-
_handle_expr_Reinterpret = _handle_Dummy
|
|
256
257
|
_handle_expr_StackBaseOffset = _handle_Dummy
|
|
257
258
|
_handle_expr_BasePointerOffset = _handle_Dummy
|
|
258
259
|
_handle_expr_Call = _handle_Dummy
|
|
@@ -2504,6 +2504,7 @@ class CStructuredCodeGenerator(BaseStructuredCodeGenerator, Analysis):
|
|
|
2504
2504
|
omit_func_header=False,
|
|
2505
2505
|
display_block_addrs=False,
|
|
2506
2506
|
display_vvar_ids=False,
|
|
2507
|
+
min_data_addr: int = 0x400_000,
|
|
2507
2508
|
):
|
|
2508
2509
|
super().__init__(flavor=flavor)
|
|
2509
2510
|
|
|
@@ -2578,6 +2579,7 @@ class CStructuredCodeGenerator(BaseStructuredCodeGenerator, Analysis):
|
|
|
2578
2579
|
self.omit_func_header = omit_func_header
|
|
2579
2580
|
self.display_block_addrs = display_block_addrs
|
|
2580
2581
|
self.display_vvar_ids = display_vvar_ids
|
|
2582
|
+
self.min_data_addr = min_data_addr
|
|
2581
2583
|
self.text = None
|
|
2582
2584
|
self.map_pos_to_node = None
|
|
2583
2585
|
self.map_pos_to_addr = None
|
|
@@ -3519,8 +3521,8 @@ class CStructuredCodeGenerator(BaseStructuredCodeGenerator, Analysis):
|
|
|
3519
3521
|
expr.value
|
|
3520
3522
|
]
|
|
3521
3523
|
inline_string = True
|
|
3522
|
-
elif isinstance(type_, SimTypePointer) and isinstance(type_.pts_to, SimTypeChar):
|
|
3523
|
-
# char*
|
|
3524
|
+
elif isinstance(type_, SimTypePointer) and isinstance(type_.pts_to, (SimTypeChar, SimTypeBottom)):
|
|
3525
|
+
# char* or void*
|
|
3524
3526
|
# Try to get a string
|
|
3525
3527
|
if (
|
|
3526
3528
|
self._cfg is not None
|
|
@@ -3583,11 +3585,16 @@ class CStructuredCodeGenerator(BaseStructuredCodeGenerator, Analysis):
|
|
|
3583
3585
|
elif function_pointer:
|
|
3584
3586
|
self._function_pointers.add(expr.reference_variable)
|
|
3585
3587
|
|
|
3588
|
+
var_access = None
|
|
3586
3589
|
if variable is not None and not reference_values:
|
|
3587
3590
|
cvar = self._variable(variable, None)
|
|
3588
3591
|
offset = getattr(expr, "reference_variable_offset", 0)
|
|
3589
|
-
|
|
3592
|
+
var_access = self._access_constant_offset_reference(self._get_variable_reference(cvar), offset, None)
|
|
3590
3593
|
|
|
3594
|
+
if var_access is not None and expr.value >= self.min_data_addr:
|
|
3595
|
+
return var_access
|
|
3596
|
+
|
|
3597
|
+
reference_values["offset"] = var_access
|
|
3591
3598
|
return CConstant(expr.value, type_, reference_values=reference_values, tags=expr.tags, codegen=self)
|
|
3592
3599
|
|
|
3593
3600
|
def _handle_Expr_UnaryOp(self, expr, **kwargs):
|
|
@@ -567,8 +567,13 @@ class DreamStructurer(StructurerBase):
|
|
|
567
567
|
seq, cmp_lb, jump_table.jumptable_entries, i, node_b_addr, addr2nodes
|
|
568
568
|
)
|
|
569
569
|
# if we don't know what the end address of this switch-case structure is, let's figure it out
|
|
570
|
-
switch_end_addr =
|
|
571
|
-
|
|
570
|
+
switch_end_addr = (
|
|
571
|
+
node_b_addr
|
|
572
|
+
if node_default is None
|
|
573
|
+
else self._switch_find_switch_end_addr(cases, node_default, {nn.addr for nn in self._region.graph})
|
|
574
|
+
)
|
|
575
|
+
if switch_end_addr is not None:
|
|
576
|
+
self._switch_handle_gotos(cases, node_default, switch_end_addr)
|
|
572
577
|
|
|
573
578
|
self._make_switch_cases_core(
|
|
574
579
|
seq,
|