angr 9.2.131__py3-none-manylinux2014_aarch64.whl → 9.2.132__py3-none-manylinux2014_aarch64.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/analysis.py +6 -2
- angr/analyses/cfg/cfg_emulated.py +5 -5
- angr/analyses/cfg/cfg_fast.py +2 -2
- angr/analyses/cfg/indirect_jump_resolvers/jumptable.py +139 -94
- angr/analyses/cfg/indirect_jump_resolvers/x86_elf_pic_plt.py +1 -1
- angr/analyses/ddg.py +14 -11
- angr/analyses/decompiler/ail_simplifier.py +3 -2
- angr/analyses/decompiler/block_simplifier.py +10 -21
- angr/analyses/decompiler/clinic.py +108 -34
- angr/analyses/decompiler/condition_processor.py +12 -10
- angr/analyses/decompiler/dephication/graph_rewriting.py +1 -1
- angr/analyses/decompiler/dephication/rewriting_engine.py +169 -45
- angr/analyses/decompiler/dephication/seqnode_dephication.py +5 -4
- angr/analyses/decompiler/optimization_passes/const_derefs.py +1 -0
- angr/analyses/decompiler/optimization_passes/div_simplifier.py +41 -16
- angr/analyses/decompiler/optimization_passes/engine_base.py +261 -83
- angr/analyses/decompiler/optimization_passes/inlined_string_transformation_simplifier.py +173 -35
- angr/analyses/decompiler/optimization_passes/mod_simplifier.py +5 -2
- angr/analyses/decompiler/optimization_passes/optimization_pass.py +39 -19
- angr/analyses/decompiler/peephole_optimizations/remove_noop_conversions.py +2 -0
- angr/analyses/decompiler/ssailification/rewriting.py +1 -2
- angr/analyses/decompiler/ssailification/rewriting_engine.py +138 -55
- angr/analyses/decompiler/ssailification/ssailification.py +2 -1
- angr/analyses/decompiler/ssailification/traversal.py +4 -6
- angr/analyses/decompiler/ssailification/traversal_engine.py +125 -42
- angr/analyses/decompiler/structured_codegen/c.py +5 -3
- angr/analyses/decompiler/structuring/phoenix.py +26 -9
- angr/analyses/decompiler/structuring/structurer_nodes.py +9 -0
- angr/analyses/deobfuscator/irsb_reg_collector.py +29 -60
- angr/analyses/deobfuscator/string_obf_finder.py +2 -2
- angr/analyses/init_finder.py +47 -22
- angr/analyses/propagator/engine_base.py +21 -14
- angr/analyses/propagator/engine_vex.py +149 -179
- angr/analyses/propagator/propagator.py +10 -28
- angr/analyses/propagator/top_checker_mixin.py +211 -5
- angr/analyses/propagator/vex_vars.py +1 -1
- angr/analyses/reaching_definitions/dep_graph.py +1 -1
- angr/analyses/reaching_definitions/engine_ail.py +304 -329
- angr/analyses/reaching_definitions/engine_vex.py +243 -229
- angr/analyses/reaching_definitions/function_handler.py +3 -3
- angr/analyses/reaching_definitions/rd_state.py +37 -32
- angr/analyses/s_propagator.py +18 -3
- angr/analyses/s_reaching_definitions/s_reaching_definitions.py +9 -5
- angr/analyses/typehoon/simple_solver.py +7 -5
- angr/analyses/typehoon/translator.py +8 -0
- angr/analyses/typehoon/typeconsts.py +10 -2
- angr/analyses/typehoon/typevars.py +9 -7
- angr/analyses/variable_recovery/engine_ail.py +299 -259
- angr/analyses/variable_recovery/engine_base.py +135 -117
- angr/analyses/variable_recovery/engine_vex.py +175 -185
- angr/analyses/variable_recovery/irsb_scanner.py +49 -38
- angr/analyses/variable_recovery/variable_recovery.py +28 -5
- angr/analyses/variable_recovery/variable_recovery_base.py +32 -33
- angr/analyses/variable_recovery/variable_recovery_fast.py +2 -2
- angr/analyses/xrefs.py +46 -19
- angr/annocfg.py +19 -14
- angr/block.py +4 -9
- angr/calling_conventions.py +1 -1
- angr/engines/engine.py +30 -14
- angr/engines/light/__init__.py +11 -3
- angr/engines/light/engine.py +1003 -1185
- angr/engines/pcode/cc.py +2 -0
- angr/engines/successors.py +13 -9
- angr/engines/vex/claripy/datalayer.py +1 -1
- angr/engines/vex/claripy/irop.py +1 -1
- angr/engines/vex/light/slicing.py +2 -2
- angr/exploration_techniques/__init__.py +1 -124
- angr/exploration_techniques/base.py +126 -0
- angr/exploration_techniques/bucketizer.py +1 -1
- angr/exploration_techniques/dfs.py +3 -1
- angr/exploration_techniques/director.py +2 -3
- angr/exploration_techniques/driller_core.py +1 -1
- angr/exploration_techniques/explorer.py +4 -2
- angr/exploration_techniques/lengthlimiter.py +2 -1
- angr/exploration_techniques/local_loop_seer.py +2 -1
- angr/exploration_techniques/loop_seer.py +5 -5
- angr/exploration_techniques/manual_mergepoint.py +2 -1
- angr/exploration_techniques/memory_watcher.py +3 -1
- angr/exploration_techniques/oppologist.py +4 -5
- angr/exploration_techniques/slicecutor.py +4 -2
- angr/exploration_techniques/spiller.py +1 -1
- angr/exploration_techniques/stochastic.py +2 -1
- angr/exploration_techniques/stub_stasher.py +2 -1
- angr/exploration_techniques/suggestions.py +3 -1
- angr/exploration_techniques/symbion.py +3 -1
- angr/exploration_techniques/tech_builder.py +2 -1
- angr/exploration_techniques/threading.py +4 -7
- angr/exploration_techniques/timeout.py +4 -2
- angr/exploration_techniques/tracer.py +4 -3
- angr/exploration_techniques/unique.py +3 -2
- angr/exploration_techniques/veritesting.py +1 -1
- angr/knowledge_plugins/key_definitions/atoms.py +2 -2
- angr/knowledge_plugins/key_definitions/live_definitions.py +16 -13
- angr/knowledge_plugins/propagations/states.py +13 -8
- angr/knowledge_plugins/variables/variable_manager.py +23 -9
- angr/sim_manager.py +1 -3
- angr/sim_state.py +39 -41
- angr/sim_type.py +5 -0
- angr/sim_variable.py +29 -28
- angr/utils/bits.py +12 -0
- angr/utils/orderedset.py +4 -1
- angr/utils/ssa/__init__.py +21 -3
- {angr-9.2.131.dist-info → angr-9.2.132.dist-info}/METADATA +6 -6
- {angr-9.2.131.dist-info → angr-9.2.132.dist-info}/RECORD +109 -110
- angr/analyses/propagator/engine_ail.py +0 -1562
- angr/storage/memory_mixins/__init__.pyi +0 -48
- {angr-9.2.131.dist-info → angr-9.2.132.dist-info}/LICENSE +0 -0
- {angr-9.2.131.dist-info → angr-9.2.132.dist-info}/WHEEL +0 -0
- {angr-9.2.131.dist-info → angr-9.2.132.dist-info}/entry_points.txt +0 -0
- {angr-9.2.131.dist-info → angr-9.2.132.dist-info}/top_level.txt +0 -0
|
@@ -33,6 +33,7 @@ from angr.sim_type import (
|
|
|
33
33
|
dereference_simtype,
|
|
34
34
|
SimTypeInt128,
|
|
35
35
|
SimTypeInt256,
|
|
36
|
+
SimTypeInt512,
|
|
36
37
|
)
|
|
37
38
|
from angr.knowledge_plugins.functions import Function
|
|
38
39
|
from angr.sim_variable import SimVariable, SimTemporaryVariable, SimStackVariable, SimMemoryVariable
|
|
@@ -1869,7 +1870,6 @@ class CBinaryOp(CExpression):
|
|
|
1869
1870
|
"Mul": self._c_repr_chunks_mul,
|
|
1870
1871
|
"Mull": self._c_repr_chunks_mull,
|
|
1871
1872
|
"Div": self._c_repr_chunks_div,
|
|
1872
|
-
"DivMod": self._c_repr_chunks_divmod,
|
|
1873
1873
|
"Mod": self._c_repr_chunks_mod,
|
|
1874
1874
|
"And": self._c_repr_chunks_and,
|
|
1875
1875
|
"Xor": self._c_repr_chunks_xor,
|
|
@@ -3465,7 +3465,7 @@ class CStructuredCodeGenerator(BaseStructuredCodeGenerator, Analysis):
|
|
|
3465
3465
|
|
|
3466
3466
|
def _handle_Expr_Tmp(self, expr: Tmp, **kwargs):
|
|
3467
3467
|
l.warning("FIXME: Leftover Tmp expressions are found.")
|
|
3468
|
-
return self._variable(SimTemporaryVariable(expr.tmp_idx), expr.size)
|
|
3468
|
+
return self._variable(SimTemporaryVariable(expr.tmp_idx, expr.bits), expr.size)
|
|
3469
3469
|
|
|
3470
3470
|
def _handle_Expr_Const(self, expr: Expr.Const, type_=None, reference_values=None, variable=None, **kwargs):
|
|
3471
3471
|
inline_string = False
|
|
@@ -3590,7 +3590,9 @@ class CStructuredCodeGenerator(BaseStructuredCodeGenerator, Analysis):
|
|
|
3590
3590
|
def _handle_Expr_Convert(self, expr: Expr.Convert, **kwargs):
|
|
3591
3591
|
# width of converted type is easy
|
|
3592
3592
|
dst_type: SimTypeInt | SimTypeChar
|
|
3593
|
-
if
|
|
3593
|
+
if 512 >= expr.to_bits > 256:
|
|
3594
|
+
dst_type = SimTypeInt512()
|
|
3595
|
+
elif 256 >= expr.to_bits > 128:
|
|
3594
3596
|
dst_type = SimTypeInt256()
|
|
3595
3597
|
elif 128 >= expr.to_bits > 64:
|
|
3596
3598
|
dst_type = SimTypeInt128()
|
|
@@ -1569,6 +1569,15 @@ class PhoenixStructurer(StructurerBase):
|
|
|
1569
1569
|
|
|
1570
1570
|
return case_and_entry_addrs
|
|
1571
1571
|
|
|
1572
|
+
def _is_switch_cases_address_loaded_from_memory_head_or_jumpnode(self, graph, node) -> bool:
|
|
1573
|
+
jump_tables = self.kb.cfgs["CFGFast"].jump_tables
|
|
1574
|
+
if node.addr in jump_tables:
|
|
1575
|
+
return True
|
|
1576
|
+
for succ in graph.successors(node):
|
|
1577
|
+
if succ.addr in jump_tables:
|
|
1578
|
+
return True
|
|
1579
|
+
return node in self.switch_case_known_heads
|
|
1580
|
+
|
|
1572
1581
|
# other acyclic schemas
|
|
1573
1582
|
|
|
1574
1583
|
def _match_acyclic_sequence(self, graph, full_graph, start_node) -> bool:
|
|
@@ -1578,14 +1587,12 @@ class PhoenixStructurer(StructurerBase):
|
|
|
1578
1587
|
succs = list(graph.successors(start_node))
|
|
1579
1588
|
if len(succs) == 1:
|
|
1580
1589
|
end_node = succs[0]
|
|
1581
|
-
jump_tables = self.kb.cfgs["CFGFast"].jump_tables
|
|
1582
1590
|
if (
|
|
1583
1591
|
full_graph.out_degree[start_node] == 1
|
|
1584
1592
|
and full_graph.in_degree[end_node] == 1
|
|
1585
1593
|
and not full_graph.has_edge(end_node, start_node)
|
|
1586
|
-
and
|
|
1587
|
-
and
|
|
1588
|
-
and start_node not in self.switch_case_known_heads
|
|
1594
|
+
and not self._is_switch_cases_address_loaded_from_memory_head_or_jumpnode(full_graph, end_node)
|
|
1595
|
+
and not self._is_switch_cases_address_loaded_from_memory_head_or_jumpnode(full_graph, start_node)
|
|
1589
1596
|
and end_node not in self.dowhile_known_tail_nodes
|
|
1590
1597
|
):
|
|
1591
1598
|
# merge two blocks
|
|
@@ -1606,7 +1613,9 @@ class PhoenixStructurer(StructurerBase):
|
|
|
1606
1613
|
succs = list(full_graph.successors(start_node))
|
|
1607
1614
|
if len(succs) == 2:
|
|
1608
1615
|
left, right = succs
|
|
1609
|
-
if
|
|
1616
|
+
if self._is_switch_cases_address_loaded_from_memory_head_or_jumpnode(
|
|
1617
|
+
full_graph, left
|
|
1618
|
+
) or self._is_switch_cases_address_loaded_from_memory_head_or_jumpnode(full_graph, right):
|
|
1610
1619
|
# structure the switch-case first before we wrap them into an ITE. give up
|
|
1611
1620
|
return False
|
|
1612
1621
|
|
|
@@ -2039,7 +2048,9 @@ class PhoenixStructurer(StructurerBase):
|
|
|
2039
2048
|
left, right = right, left
|
|
2040
2049
|
|
|
2041
2050
|
# ensure left and right nodes are not the head of a switch-case construct
|
|
2042
|
-
if
|
|
2051
|
+
if self._is_switch_cases_address_loaded_from_memory_head_or_jumpnode(
|
|
2052
|
+
full_graph, left
|
|
2053
|
+
) or self._is_switch_cases_address_loaded_from_memory_head_or_jumpnode(full_graph, right):
|
|
2043
2054
|
return None
|
|
2044
2055
|
|
|
2045
2056
|
if (
|
|
@@ -2086,7 +2097,9 @@ class PhoenixStructurer(StructurerBase):
|
|
|
2086
2097
|
left, right = right, left
|
|
2087
2098
|
|
|
2088
2099
|
# ensure left and right nodes are not the head of a switch-case construct
|
|
2089
|
-
if
|
|
2100
|
+
if self._is_switch_cases_address_loaded_from_memory_head_or_jumpnode(
|
|
2101
|
+
full_graph, left
|
|
2102
|
+
) or self._is_switch_cases_address_loaded_from_memory_head_or_jumpnode(full_graph, right):
|
|
2090
2103
|
return None
|
|
2091
2104
|
|
|
2092
2105
|
if (
|
|
@@ -2127,7 +2140,9 @@ class PhoenixStructurer(StructurerBase):
|
|
|
2127
2140
|
left, successor = successor, left
|
|
2128
2141
|
|
|
2129
2142
|
# ensure left and successor nodes are not the head of a switch-case construct
|
|
2130
|
-
if
|
|
2143
|
+
if self._is_switch_cases_address_loaded_from_memory_head_or_jumpnode(
|
|
2144
|
+
full_graph, left
|
|
2145
|
+
) or self._is_switch_cases_address_loaded_from_memory_head_or_jumpnode(full_graph, successor):
|
|
2131
2146
|
return None
|
|
2132
2147
|
|
|
2133
2148
|
if (
|
|
@@ -2175,7 +2190,9 @@ class PhoenixStructurer(StructurerBase):
|
|
|
2175
2190
|
left, else_node = else_node, left
|
|
2176
2191
|
|
|
2177
2192
|
# ensure left and else nodes are not the head of a switch-case construct
|
|
2178
|
-
if
|
|
2193
|
+
if self._is_switch_cases_address_loaded_from_memory_head_or_jumpnode(
|
|
2194
|
+
full_graph, left
|
|
2195
|
+
) or self._is_switch_cases_address_loaded_from_memory_head_or_jumpnode(full_graph, else_node):
|
|
2179
2196
|
return None
|
|
2180
2197
|
|
|
2181
2198
|
if (
|
|
@@ -411,3 +411,12 @@ class IncompleteSwitchCaseHeadStatement(ailment.statement.Statement):
|
|
|
411
411
|
return ailment.utils.stable_hash(
|
|
412
412
|
(IncompleteSwitchCaseHeadStatement, self.idx, self.switch_variable, self._case_addrs_str)
|
|
413
413
|
)
|
|
414
|
+
|
|
415
|
+
def replace(self, old_expr, new_expr):
|
|
416
|
+
return self
|
|
417
|
+
|
|
418
|
+
def likes(self, other):
|
|
419
|
+
return self == other
|
|
420
|
+
|
|
421
|
+
def matches(self, other):
|
|
422
|
+
return self == other
|
|
@@ -1,85 +1,54 @@
|
|
|
1
|
-
# pylint:disable=no-self-use,unused-argument
|
|
1
|
+
# pylint:disable=no-self-use,unused-argument
|
|
2
2
|
from __future__ import annotations
|
|
3
3
|
|
|
4
|
-
import
|
|
4
|
+
from angr.engines.light import SimEngineNostmtVEX
|
|
5
5
|
|
|
6
|
-
from angr.engines.light import SimEngineLightVEXMixin
|
|
7
6
|
|
|
8
|
-
|
|
9
|
-
class IRSBRegisterCollector(SimEngineLightVEXMixin):
|
|
7
|
+
class IRSBRegisterCollector(SimEngineNostmtVEX[None, None, None]):
|
|
10
8
|
"""
|
|
11
9
|
Scan the VEX IRSB to collect all registers that are read.
|
|
12
10
|
"""
|
|
13
11
|
|
|
14
|
-
def __init__(self,
|
|
12
|
+
def __init__(self, *args, **kwargs):
|
|
15
13
|
super().__init__(*args, **kwargs)
|
|
16
14
|
|
|
17
|
-
self.block = block
|
|
18
15
|
self.reg_reads: set[tuple[int, int]] = set()
|
|
19
16
|
|
|
20
|
-
def
|
|
21
|
-
|
|
22
|
-
self.tyenv = self.block.vex.tyenv
|
|
23
|
-
|
|
24
|
-
self._process_Stmt()
|
|
25
|
-
|
|
26
|
-
self.stmt_idx = None
|
|
27
|
-
self.ins_addr = None
|
|
28
|
-
|
|
29
|
-
def _handle_Put(self, stmt):
|
|
30
|
-
pass
|
|
31
|
-
|
|
32
|
-
def _handle_Load(self, expr):
|
|
33
|
-
pass
|
|
17
|
+
def _top(self, bits):
|
|
18
|
+
return None
|
|
34
19
|
|
|
35
|
-
def
|
|
36
|
-
|
|
20
|
+
def _is_top(self, expr):
|
|
21
|
+
return True
|
|
37
22
|
|
|
38
|
-
def
|
|
39
|
-
pass
|
|
40
|
-
|
|
41
|
-
def _handle_LLSC(self, stmt: pyvex.IRStmt.LLSC):
|
|
42
|
-
pass
|
|
43
|
-
|
|
44
|
-
def _handle_StoreG(self, stmt):
|
|
45
|
-
pass
|
|
46
|
-
|
|
47
|
-
def _handle_Get(self, expr: pyvex.IRExpr.Get):
|
|
23
|
+
def _handle_expr_Get(self, expr):
|
|
48
24
|
self.reg_reads.add((expr.offset, expr.result_size(self.tyenv)))
|
|
49
25
|
|
|
50
|
-
def
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
def _handle_Conversion(self, expr: pyvex.IRExpr.Unop):
|
|
54
|
-
pass
|
|
26
|
+
def _handle_stmt_WrTmp(self, stmt):
|
|
27
|
+
self._expr(stmt.data)
|
|
55
28
|
|
|
56
|
-
def
|
|
57
|
-
|
|
29
|
+
def _handle_conversion(self, from_size, to_size, signed, operand):
|
|
30
|
+
return None
|
|
58
31
|
|
|
59
|
-
def
|
|
60
|
-
|
|
32
|
+
def _process_block_end(self, stmt_result, whitelist):
|
|
33
|
+
return None
|
|
61
34
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
_handle_CmpLE_v = _handle_Cmp_v
|
|
65
|
-
_handle_CmpLT_v = _handle_Cmp_v
|
|
66
|
-
_handle_CmpGE_v = _handle_Cmp_v
|
|
67
|
-
_handle_CmpGT_v = _handle_Cmp_v
|
|
35
|
+
def _handle_expr_VECRET(self, expr):
|
|
36
|
+
return None
|
|
68
37
|
|
|
69
|
-
def
|
|
70
|
-
|
|
38
|
+
def _handle_expr_GSPTR(self, expr):
|
|
39
|
+
return None
|
|
71
40
|
|
|
72
|
-
def
|
|
73
|
-
|
|
41
|
+
def _handle_expr_RdTmp(self, expr):
|
|
42
|
+
return None
|
|
74
43
|
|
|
75
|
-
def
|
|
76
|
-
|
|
44
|
+
def _handle_expr_GetI(self, expr):
|
|
45
|
+
return None
|
|
77
46
|
|
|
78
|
-
def
|
|
79
|
-
|
|
47
|
+
def _handle_expr_Load(self, expr):
|
|
48
|
+
return None
|
|
80
49
|
|
|
81
|
-
def
|
|
82
|
-
|
|
50
|
+
def _handle_expr_ITE(self, expr):
|
|
51
|
+
return None
|
|
83
52
|
|
|
84
|
-
def
|
|
85
|
-
|
|
53
|
+
def _handle_expr_Const(self, expr):
|
|
54
|
+
return None
|
|
@@ -669,8 +669,8 @@ class StringObfuscationFinder(Analysis):
|
|
|
669
669
|
# take a look at the call-site block to see what registers are used
|
|
670
670
|
reg_reads = set()
|
|
671
671
|
for block_addr in blocks_at_callsite:
|
|
672
|
-
reg_collector = IRSBRegisterCollector(self.project
|
|
673
|
-
reg_collector.process()
|
|
672
|
+
reg_collector = IRSBRegisterCollector(self.project)
|
|
673
|
+
reg_collector.process(state=None, block=self.project.factory.block(block_addr))
|
|
674
674
|
reg_reads |= set(reg_collector.reg_reads)
|
|
675
675
|
|
|
676
676
|
# run constant propagation to track constant registers
|
angr/analyses/init_finder.py
CHANGED
|
@@ -1,33 +1,36 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
from collections import defaultdict
|
|
3
|
+
from typing import cast
|
|
3
4
|
|
|
4
5
|
from cle.loader import MetaELF
|
|
5
|
-
from cle.backends import Section, Segment
|
|
6
6
|
import pyvex
|
|
7
7
|
import claripy
|
|
8
8
|
|
|
9
9
|
from angr.analyses import visitors, ForwardAnalysis
|
|
10
|
-
from angr.
|
|
10
|
+
from angr.code_location import CodeLocation
|
|
11
|
+
from angr.engines.light import SimEngineNostmtVEX
|
|
11
12
|
from . import register_analysis, PropagatorAnalysis
|
|
12
13
|
from .analysis import Analysis
|
|
13
14
|
from .propagator.vex_vars import VEXTmp
|
|
14
15
|
|
|
15
16
|
|
|
16
|
-
class SimEngineInitFinderVEX(
|
|
17
|
-
SimEngineLightVEXMixin,
|
|
18
|
-
SimEngineLight,
|
|
19
|
-
):
|
|
17
|
+
class SimEngineInitFinderVEX(SimEngineNostmtVEX[None, claripy.ast.Base | int | None, None]):
|
|
20
18
|
"""
|
|
21
19
|
The VEX engine class for InitFinder.
|
|
22
20
|
"""
|
|
23
21
|
|
|
24
22
|
def __init__(self, project, replacements, overlay, pointers_only=False):
|
|
25
|
-
super().__init__()
|
|
26
|
-
self.
|
|
27
|
-
self.replacements = replacements
|
|
23
|
+
super().__init__(project)
|
|
24
|
+
self.replacements: dict[CodeLocation, dict[int, claripy.ast.Base | int]] = replacements
|
|
28
25
|
self.overlay = overlay
|
|
29
26
|
self.pointers_only = pointers_only
|
|
30
27
|
|
|
28
|
+
def _top(self, bits):
|
|
29
|
+
return None
|
|
30
|
+
|
|
31
|
+
def _is_top(self, expr):
|
|
32
|
+
return expr is None
|
|
33
|
+
|
|
31
34
|
#
|
|
32
35
|
# Utils
|
|
33
36
|
#
|
|
@@ -38,18 +41,19 @@ class SimEngineInitFinderVEX(
|
|
|
38
41
|
return True
|
|
39
42
|
return bool(isinstance(expr, int))
|
|
40
43
|
|
|
41
|
-
def _is_addr_uninitialized(self, addr):
|
|
44
|
+
def _is_addr_uninitialized(self, addr: int | claripy.ast.Base):
|
|
42
45
|
# is it writing to a global, uninitialized region?
|
|
43
46
|
|
|
44
47
|
if isinstance(addr, claripy.ast.Base):
|
|
45
|
-
addr
|
|
48
|
+
assert addr.op == "BVV"
|
|
49
|
+
addr = cast(int, addr.args[0])
|
|
46
50
|
|
|
47
51
|
obj = self.project.loader.find_object_containing(addr)
|
|
48
52
|
if obj is not None:
|
|
49
53
|
if not obj.has_memory:
|
|
50
54
|
# Objects without memory are definitely uninitialized
|
|
51
55
|
return True
|
|
52
|
-
section
|
|
56
|
+
section = obj.find_section_containing(addr)
|
|
53
57
|
if section is not None:
|
|
54
58
|
return section.name in {
|
|
55
59
|
".bss",
|
|
@@ -58,7 +62,7 @@ class SimEngineInitFinderVEX(
|
|
|
58
62
|
if isinstance(obj, MetaELF):
|
|
59
63
|
# for ELFs, if p_memsz >= p_filesz, the extra bytes are considered NOBITS
|
|
60
64
|
# https://docs.oracle.com/cd/E19120-01/open.solaris/819-0690/gjpww/index.html
|
|
61
|
-
segment
|
|
65
|
+
segment = obj.find_segment_containing(addr)
|
|
62
66
|
if segment is not None and segment.memsize > segment.filesize:
|
|
63
67
|
return segment.vaddr + segment.filesize <= addr < segment.vaddr + segment.memsize
|
|
64
68
|
return False
|
|
@@ -71,6 +75,9 @@ class SimEngineInitFinderVEX(
|
|
|
71
75
|
return self.project.loader.find_object_containing(addr) is not None
|
|
72
76
|
return False
|
|
73
77
|
|
|
78
|
+
def _process_block_end(self, stmt_result, whitelist):
|
|
79
|
+
return None
|
|
80
|
+
|
|
74
81
|
#
|
|
75
82
|
# Statement handlers
|
|
76
83
|
#
|
|
@@ -78,15 +85,15 @@ class SimEngineInitFinderVEX(
|
|
|
78
85
|
def _handle_function(self, *args, **kwargs):
|
|
79
86
|
pass
|
|
80
87
|
|
|
81
|
-
def
|
|
88
|
+
def _handle_stmt_WrTmp(self, stmt):
|
|
82
89
|
# Don't do anything since constant propagation has already processed it
|
|
83
90
|
return
|
|
84
91
|
|
|
85
|
-
def
|
|
92
|
+
def _handle_stmt_Put(self, stmt):
|
|
86
93
|
# Don't do anything since constant propagation has already processed it
|
|
87
94
|
return
|
|
88
95
|
|
|
89
|
-
def
|
|
96
|
+
def _handle_stmt_Store(self, stmt):
|
|
90
97
|
blockloc = self._codeloc(block_only=True)
|
|
91
98
|
|
|
92
99
|
if type(stmt.addr) is pyvex.IRExpr.RdTmp:
|
|
@@ -107,7 +114,7 @@ class SimEngineInitFinderVEX(
|
|
|
107
114
|
if not self.pointers_only or self._is_pointer(data_v):
|
|
108
115
|
self.overlay.store(addr_v, data_v, endness=self.project.arch.memory_endness)
|
|
109
116
|
|
|
110
|
-
def
|
|
117
|
+
def _handle_stmt_StoreG(self, stmt):
|
|
111
118
|
blockloc = self._codeloc(block_only=True)
|
|
112
119
|
repl = self.replacements[blockloc]
|
|
113
120
|
|
|
@@ -144,16 +151,16 @@ class SimEngineInitFinderVEX(
|
|
|
144
151
|
# Expression handlers
|
|
145
152
|
#
|
|
146
153
|
|
|
147
|
-
def
|
|
154
|
+
def _handle_expr_Get(self, expr):
|
|
148
155
|
return None
|
|
149
156
|
|
|
150
|
-
def
|
|
157
|
+
def _handle_expr_Load(self, expr):
|
|
151
158
|
return None
|
|
152
159
|
|
|
153
|
-
def
|
|
160
|
+
def _handle_stmt_LoadG(self, stmt):
|
|
154
161
|
return None
|
|
155
162
|
|
|
156
|
-
def
|
|
163
|
+
def _handle_expr_RdTmp(self, expr):
|
|
157
164
|
blockloc = self._codeloc(block_only=True)
|
|
158
165
|
|
|
159
166
|
tmp = VEXTmp(expr.tmp)
|
|
@@ -161,6 +168,24 @@ class SimEngineInitFinderVEX(
|
|
|
161
168
|
return self.replacements[blockloc][tmp]
|
|
162
169
|
return None
|
|
163
170
|
|
|
171
|
+
def _handle_expr_VECRET(self, expr):
|
|
172
|
+
return None
|
|
173
|
+
|
|
174
|
+
def _handle_expr_GSPTR(self, expr):
|
|
175
|
+
return None
|
|
176
|
+
|
|
177
|
+
def _handle_expr_GetI(self, expr):
|
|
178
|
+
return None
|
|
179
|
+
|
|
180
|
+
def _handle_expr_ITE(self, expr):
|
|
181
|
+
return None
|
|
182
|
+
|
|
183
|
+
def _handle_conversion(self, from_size, to_size, signed, operand):
|
|
184
|
+
return None
|
|
185
|
+
|
|
186
|
+
def _handle_expr_Const(self, expr):
|
|
187
|
+
return None
|
|
188
|
+
|
|
164
189
|
|
|
165
190
|
class InitializationFinder(ForwardAnalysis, Analysis): # pylint:disable=abstract-method
|
|
166
191
|
"""
|
|
@@ -238,7 +263,7 @@ class InitializationFinder(ForwardAnalysis, Analysis): # pylint:disable=abstrac
|
|
|
238
263
|
return None
|
|
239
264
|
|
|
240
265
|
def _merge_states(self, node, *states):
|
|
241
|
-
return None
|
|
266
|
+
return None, False
|
|
242
267
|
|
|
243
268
|
def _run_on_node(self, node, state):
|
|
244
269
|
block = self.project.factory.block(node.addr, node.size, opt_level=1, cross_insn_opt=False)
|
|
@@ -1,9 +1,14 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
|
-
from typing import TYPE_CHECKING
|
|
2
|
+
from typing import TYPE_CHECKING, Generic
|
|
3
3
|
import logging
|
|
4
4
|
|
|
5
|
+
|
|
6
|
+
from angr.engines.light.engine import BlockType, DataType_co, StateType
|
|
7
|
+
|
|
5
8
|
from angr.engines.light import SimEngineLight
|
|
6
9
|
from angr.errors import SimEngineError
|
|
10
|
+
from angr.project import Project
|
|
11
|
+
from angr.misc.testing import is_testing
|
|
7
12
|
|
|
8
13
|
if TYPE_CHECKING:
|
|
9
14
|
from angr.analyses.reaching_definitions.reaching_definitions import ReachingDefinitionsModel
|
|
@@ -11,22 +16,22 @@ if TYPE_CHECKING:
|
|
|
11
16
|
l = logging.getLogger(name=__name__)
|
|
12
17
|
|
|
13
18
|
|
|
14
|
-
class
|
|
19
|
+
class SimEnginePropagatorBaseMixin(
|
|
20
|
+
Generic[StateType, DataType_co, BlockType], SimEngineLight[StateType, DataType_co, BlockType, StateType]
|
|
21
|
+
): # pylint:disable=abstract-method
|
|
15
22
|
def __init__(
|
|
16
23
|
self,
|
|
24
|
+
project: Project,
|
|
17
25
|
stack_pointer_tracker=None,
|
|
18
|
-
project=None,
|
|
19
26
|
propagate_tmps=True,
|
|
20
|
-
arch=None,
|
|
21
27
|
reaching_definitions: ReachingDefinitionsModel | None = None,
|
|
22
28
|
immediate_stmt_removal: bool = False,
|
|
23
29
|
bp_as_gpr: bool = False,
|
|
24
30
|
):
|
|
25
|
-
super().__init__()
|
|
31
|
+
super().__init__(project)
|
|
26
32
|
|
|
27
33
|
# Used in the VEX engine
|
|
28
|
-
self.
|
|
29
|
-
self.arch = arch
|
|
34
|
+
self.arch = project.arch
|
|
30
35
|
self.base_state = None
|
|
31
36
|
self._load_callback = None
|
|
32
37
|
self._propagate_tmps: bool = propagate_tmps
|
|
@@ -40,15 +45,17 @@ class SimEnginePropagatorBase(SimEngineLight): # pylint:disable=abstract-method
|
|
|
40
45
|
|
|
41
46
|
self._multi_occurrence_registers = None
|
|
42
47
|
|
|
43
|
-
def process(
|
|
44
|
-
self
|
|
45
|
-
|
|
46
|
-
self.
|
|
48
|
+
def process(
|
|
49
|
+
self, state: StateType, *, block: BlockType | None = None, base_state=None, load_callback=None, **kwargs
|
|
50
|
+
) -> StateType:
|
|
51
|
+
self.base_state = base_state
|
|
52
|
+
self._load_callback = load_callback
|
|
47
53
|
try:
|
|
48
|
-
|
|
54
|
+
result_state = super().process(state, block=block, **kwargs)
|
|
49
55
|
except SimEngineError as ex:
|
|
50
|
-
if kwargs.pop("fail_fast",
|
|
56
|
+
if kwargs.pop("fail_fast", is_testing) is True:
|
|
51
57
|
raise ex
|
|
52
58
|
l.error(ex, exc_info=True)
|
|
59
|
+
result_state = state
|
|
53
60
|
|
|
54
|
-
return
|
|
61
|
+
return result_state
|