angr 9.2.158__cp310-abi3-manylinux2014_x86_64.whl → 9.2.160__cp310-abi3-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/ailment/__init__.py +81 -0
- angr/ailment/block.py +81 -0
- angr/ailment/block_walker.py +845 -0
- angr/ailment/constant.py +3 -0
- angr/ailment/converter_common.py +11 -0
- angr/ailment/converter_pcode.py +623 -0
- angr/ailment/converter_vex.py +798 -0
- angr/ailment/expression.py +1639 -0
- angr/ailment/manager.py +33 -0
- angr/ailment/statement.py +978 -0
- angr/ailment/tagged_object.py +61 -0
- angr/ailment/utils.py +114 -0
- angr/analyses/calling_convention/calling_convention.py +6 -2
- angr/analyses/decompiler/ail_simplifier.py +5 -5
- angr/analyses/decompiler/block_io_finder.py +4 -4
- angr/analyses/decompiler/block_similarity.py +2 -2
- angr/analyses/decompiler/block_simplifier.py +4 -4
- angr/analyses/decompiler/callsite_maker.py +2 -2
- angr/analyses/decompiler/ccall_rewriters/amd64_ccalls.py +1 -1
- angr/analyses/decompiler/ccall_rewriters/rewriter_base.py +1 -1
- angr/analyses/decompiler/ccall_rewriters/x86_ccalls.py +1 -1
- angr/analyses/decompiler/clinic.py +5 -2
- angr/analyses/decompiler/condition_processor.py +1 -1
- angr/analyses/decompiler/counters/boolean_counter.py +4 -4
- angr/analyses/decompiler/counters/call_counter.py +4 -4
- angr/analyses/decompiler/counters/expression_counters.py +5 -5
- angr/analyses/decompiler/counters/seq_cf_structure_counter.py +1 -1
- angr/analyses/decompiler/decompiler.py +17 -12
- angr/analyses/decompiler/dephication/dephication_base.py +12 -1
- angr/analyses/decompiler/dephication/graph_dephication.py +12 -5
- angr/analyses/decompiler/dephication/graph_rewriting.py +6 -10
- angr/analyses/decompiler/dephication/graph_vvar_mapping.py +109 -72
- angr/analyses/decompiler/dephication/rewriting_engine.py +32 -9
- angr/analyses/decompiler/dephication/seqnode_dephication.py +32 -10
- angr/analyses/decompiler/empty_node_remover.py +2 -2
- angr/analyses/decompiler/expression_narrower.py +6 -6
- angr/analyses/decompiler/goto_manager.py +2 -2
- angr/analyses/decompiler/jump_target_collector.py +1 -1
- angr/analyses/decompiler/label_collector.py +1 -1
- angr/analyses/decompiler/optimization_passes/base_ptr_save_simplifier.py +25 -25
- angr/analyses/decompiler/optimization_passes/call_stmt_rewriter.py +1 -1
- angr/analyses/decompiler/optimization_passes/code_motion.py +2 -2
- angr/analyses/decompiler/optimization_passes/condition_constprop.py +3 -3
- angr/analyses/decompiler/optimization_passes/const_derefs.py +3 -3
- angr/analyses/decompiler/optimization_passes/const_prop_reverter.py +4 -4
- angr/analyses/decompiler/optimization_passes/deadblock_remover.py +2 -2
- angr/analyses/decompiler/optimization_passes/determine_load_sizes.py +3 -3
- angr/analyses/decompiler/optimization_passes/div_simplifier.py +1 -1
- angr/analyses/decompiler/optimization_passes/duplication_reverter/ail_merge_graph.py +2 -2
- angr/analyses/decompiler/optimization_passes/duplication_reverter/duplication_reverter.py +4 -4
- angr/analyses/decompiler/optimization_passes/duplication_reverter/similarity.py +1 -1
- angr/analyses/decompiler/optimization_passes/duplication_reverter/utils.py +4 -4
- angr/analyses/decompiler/optimization_passes/eager_std_string_concatenation.py +3 -3
- angr/analyses/decompiler/optimization_passes/engine_base.py +1 -1
- angr/analyses/decompiler/optimization_passes/expr_op_swapper.py +3 -3
- angr/analyses/decompiler/optimization_passes/flip_boolean_cmp.py +2 -2
- angr/analyses/decompiler/optimization_passes/inlined_string_transformation_simplifier.py +2 -2
- angr/analyses/decompiler/optimization_passes/ite_expr_converter.py +3 -3
- angr/analyses/decompiler/optimization_passes/ite_region_converter.py +3 -3
- angr/analyses/decompiler/optimization_passes/lowered_switch_simplifier.py +4 -4
- angr/analyses/decompiler/optimization_passes/mod_simplifier.py +1 -1
- angr/analyses/decompiler/optimization_passes/optimization_pass.py +25 -1
- angr/analyses/decompiler/optimization_passes/register_save_area_simplifier.py +1 -1
- angr/analyses/decompiler/optimization_passes/ret_addr_save_simplifier.py +1 -1
- angr/analyses/decompiler/optimization_passes/ret_deduplicator.py +2 -2
- angr/analyses/decompiler/optimization_passes/return_duplicator_base.py +4 -4
- angr/analyses/decompiler/optimization_passes/return_duplicator_low.py +2 -2
- angr/analyses/decompiler/optimization_passes/stack_canary_simplifier.py +1 -1
- angr/analyses/decompiler/optimization_passes/switch_default_case_duplicator.py +3 -3
- angr/analyses/decompiler/optimization_passes/switch_reused_entry_rewriter.py +3 -3
- angr/analyses/decompiler/optimization_passes/tag_slicer.py +1 -1
- angr/analyses/decompiler/optimization_passes/win_stack_canary_simplifier.py +1 -1
- angr/analyses/decompiler/optimization_passes/x86_gcc_getpc_simplifier.py +1 -1
- angr/analyses/decompiler/peephole_optimizations/a_div_const_add_a_mul_n_div_const.py +1 -1
- angr/analyses/decompiler/peephole_optimizations/a_mul_const_div_shr_const.py +1 -1
- angr/analyses/decompiler/peephole_optimizations/a_mul_const_sub_a.py +1 -1
- angr/analyses/decompiler/peephole_optimizations/a_shl_const_sub_a.py +1 -1
- angr/analyses/decompiler/peephole_optimizations/a_sub_a_div.py +1 -1
- angr/analyses/decompiler/peephole_optimizations/a_sub_a_div_const_mul_const.py +1 -1
- angr/analyses/decompiler/peephole_optimizations/a_sub_a_shr_const_shr_const.py +1 -1
- angr/analyses/decompiler/peephole_optimizations/a_sub_a_sub_n.py +1 -1
- angr/analyses/decompiler/peephole_optimizations/arm_cmpf.py +1 -1
- angr/analyses/decompiler/peephole_optimizations/base.py +3 -3
- angr/analyses/decompiler/peephole_optimizations/basepointeroffset_add_n.py +1 -1
- angr/analyses/decompiler/peephole_optimizations/basepointeroffset_and_mask.py +1 -1
- angr/analyses/decompiler/peephole_optimizations/bitwise_or_to_logical_or.py +1 -1
- angr/analyses/decompiler/peephole_optimizations/bool_expr_xor_1.py +1 -1
- angr/analyses/decompiler/peephole_optimizations/bswap.py +2 -2
- angr/analyses/decompiler/peephole_optimizations/cas_intrinsics.py +2 -2
- angr/analyses/decompiler/peephole_optimizations/cmpord_rewriter.py +2 -2
- angr/analyses/decompiler/peephole_optimizations/coalesce_adjacent_shrs.py +1 -1
- angr/analyses/decompiler/peephole_optimizations/coalesce_same_cascading_ifs.py +2 -2
- angr/analyses/decompiler/peephole_optimizations/const_mull_a_shift.py +1 -1
- angr/analyses/decompiler/peephole_optimizations/constant_derefs.py +1 -1
- angr/analyses/decompiler/peephole_optimizations/conv_a_sub0_shr_and.py +1 -1
- angr/analyses/decompiler/peephole_optimizations/conv_shl_shr.py +1 -1
- angr/analyses/decompiler/peephole_optimizations/eager_eval.py +1 -1
- angr/analyses/decompiler/peephole_optimizations/extended_byte_and_mask.py +1 -1
- angr/analyses/decompiler/peephole_optimizations/inlined_strcpy.py +2 -2
- angr/analyses/decompiler/peephole_optimizations/inlined_strcpy_consolidation.py +2 -2
- angr/analyses/decompiler/peephole_optimizations/inlined_wstrcpy.py +2 -2
- angr/analyses/decompiler/peephole_optimizations/invert_negated_logical_conjuction_disjunction.py +1 -1
- angr/analyses/decompiler/peephole_optimizations/one_sub_bool.py +1 -1
- angr/analyses/decompiler/peephole_optimizations/remove_cascading_conversions.py +1 -1
- angr/analyses/decompiler/peephole_optimizations/remove_cxx_destructor_calls.py +2 -2
- angr/analyses/decompiler/peephole_optimizations/remove_empty_if_body.py +2 -2
- angr/analyses/decompiler/peephole_optimizations/remove_noop_conversions.py +1 -1
- angr/analyses/decompiler/peephole_optimizations/remove_redundant_bitmasks.py +1 -1
- angr/analyses/decompiler/peephole_optimizations/remove_redundant_conversions.py +1 -1
- angr/analyses/decompiler/peephole_optimizations/remove_redundant_ite_branch.py +1 -1
- angr/analyses/decompiler/peephole_optimizations/remove_redundant_ite_comparisons.py +1 -1
- angr/analyses/decompiler/peephole_optimizations/remove_redundant_nots.py +1 -1
- angr/analyses/decompiler/peephole_optimizations/remove_redundant_reinterprets.py +1 -1
- angr/analyses/decompiler/peephole_optimizations/remove_redundant_shifts.py +1 -1
- angr/analyses/decompiler/peephole_optimizations/remove_redundant_shifts_around_comparators.py +1 -1
- angr/analyses/decompiler/peephole_optimizations/rewrite_bit_extractions.py +1 -1
- angr/analyses/decompiler/peephole_optimizations/rewrite_conv_mul.py +1 -1
- angr/analyses/decompiler/peephole_optimizations/rewrite_cxx_operator_calls.py +3 -3
- angr/analyses/decompiler/peephole_optimizations/rewrite_mips_gp_loads.py +1 -1
- angr/analyses/decompiler/peephole_optimizations/rol_ror.py +2 -2
- angr/analyses/decompiler/peephole_optimizations/sar_to_signed_div.py +1 -1
- angr/analyses/decompiler/peephole_optimizations/shl_to_mul.py +1 -1
- angr/analyses/decompiler/peephole_optimizations/simplify_pc_relative_loads.py +1 -1
- angr/analyses/decompiler/peephole_optimizations/single_bit_cond_to_boolexpr.py +1 -1
- angr/analyses/decompiler/peephole_optimizations/single_bit_xor.py +1 -1
- angr/analyses/decompiler/peephole_optimizations/tidy_stack_addr.py +2 -2
- angr/analyses/decompiler/peephole_optimizations/utils.py +1 -1
- angr/analyses/decompiler/redundant_label_remover.py +1 -1
- angr/analyses/decompiler/region_identifier.py +4 -4
- angr/analyses/decompiler/region_simplifiers/cascading_cond_transformer.py +1 -1
- angr/analyses/decompiler/region_simplifiers/cascading_ifs.py +1 -1
- angr/analyses/decompiler/region_simplifiers/expr_folding.py +37 -8
- angr/analyses/decompiler/region_simplifiers/goto.py +1 -1
- angr/analyses/decompiler/region_simplifiers/if_.py +1 -1
- angr/analyses/decompiler/region_simplifiers/loop.py +1 -1
- angr/analyses/decompiler/region_simplifiers/node_address_finder.py +1 -1
- angr/analyses/decompiler/region_simplifiers/region_simplifier.py +14 -2
- angr/analyses/decompiler/region_simplifiers/switch_cluster_simplifier.py +3 -3
- angr/analyses/decompiler/region_simplifiers/switch_expr_simplifier.py +1 -1
- angr/analyses/decompiler/return_maker.py +1 -1
- angr/analyses/decompiler/seq_to_blocks.py +1 -1
- angr/analyses/decompiler/sequence_walker.py +2 -2
- angr/analyses/decompiler/ssailification/rewriting.py +4 -4
- angr/analyses/decompiler/ssailification/rewriting_engine.py +4 -4
- angr/analyses/decompiler/ssailification/rewriting_state.py +3 -3
- angr/analyses/decompiler/ssailification/ssailification.py +2 -2
- angr/analyses/decompiler/ssailification/traversal.py +1 -1
- angr/analyses/decompiler/ssailification/traversal_engine.py +11 -2
- angr/analyses/decompiler/structured_codegen/c.py +3 -3
- angr/analyses/decompiler/structuring/dream.py +1 -1
- angr/analyses/decompiler/structuring/phoenix.py +3 -3
- angr/analyses/decompiler/structuring/structurer_base.py +1 -1
- angr/analyses/decompiler/structuring/structurer_nodes.py +1 -2
- angr/analyses/decompiler/utils.py +1 -1
- angr/analyses/deobfuscator/api_obf_peephole_optimizer.py +1 -1
- angr/analyses/deobfuscator/string_obf_opt_passes.py +3 -3
- angr/analyses/deobfuscator/string_obf_peephole_optimizer.py +2 -2
- angr/analyses/propagator/propagator.py +1 -1
- angr/analyses/proximity_graph.py +2 -2
- angr/analyses/reaching_definitions/engine_ail.py +1 -1
- angr/analyses/reaching_definitions/reaching_definitions.py +1 -1
- angr/analyses/reaching_definitions/subject.py +1 -1
- angr/analyses/s_liveness.py +2 -2
- angr/analyses/s_propagator.py +3 -3
- angr/analyses/s_reaching_definitions/s_rda_model.py +1 -1
- angr/analyses/s_reaching_definitions/s_rda_view.py +3 -3
- angr/analyses/s_reaching_definitions/s_reaching_definitions.py +3 -3
- angr/analyses/typehoon/simple_solver.py +231 -29
- angr/analyses/typehoon/typehoon.py +10 -2
- angr/analyses/variable_recovery/engine_ail.py +10 -22
- angr/analyses/variable_recovery/engine_base.py +1 -1
- angr/analyses/variable_recovery/variable_recovery_base.py +1 -1
- angr/analyses/variable_recovery/variable_recovery_fast.py +2 -2
- angr/engines/light/data.py +1 -1
- angr/engines/light/engine.py +1 -1
- angr/knowledge_plugins/key_definitions/atoms.py +1 -1
- angr/knowledge_plugins/propagations/prop_value.py +1 -1
- angr/knowledge_plugins/propagations/propagation_model.py +1 -1
- angr/knowledge_plugins/propagations/states.py +1 -1
- angr/knowledge_plugins/variables/variable_manager.py +1 -1
- angr/rustylib.abi3.so +0 -0
- angr/state_plugins/unicorn_engine.py +4 -4
- angr/utils/ail.py +4 -4
- angr/utils/endness.py +1 -1
- angr/utils/ssa/__init__.py +14 -4
- angr/utils/ssa/tmp_uses_collector.py +4 -4
- angr/utils/ssa/vvar_uses_collector.py +4 -4
- {angr-9.2.158.dist-info → angr-9.2.160.dist-info}/METADATA +6 -7
- {angr-9.2.158.dist-info → angr-9.2.160.dist-info}/RECORD +195 -183
- /angr/{lib/angr_native.so → unicornlib.so} +0 -0
- {angr-9.2.158.dist-info → angr-9.2.160.dist-info}/WHEEL +0 -0
- {angr-9.2.158.dist-info → angr-9.2.160.dist-info}/entry_points.txt +0 -0
- {angr-9.2.158.dist-info → angr-9.2.160.dist-info}/licenses/LICENSE +0 -0
- {angr-9.2.158.dist-info → angr-9.2.160.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class TaggedObject:
|
|
5
|
+
"""
|
|
6
|
+
A class that takes arbitrary tags.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
__slots__ = (
|
|
10
|
+
"_hash",
|
|
11
|
+
"_tags",
|
|
12
|
+
"idx",
|
|
13
|
+
)
|
|
14
|
+
|
|
15
|
+
def __init__(self, idx: int | None, **kwargs):
|
|
16
|
+
self._tags = None
|
|
17
|
+
self.idx = idx
|
|
18
|
+
self._hash = None
|
|
19
|
+
if kwargs:
|
|
20
|
+
self.initialize_tags(kwargs)
|
|
21
|
+
|
|
22
|
+
def initialize_tags(self, tags):
|
|
23
|
+
self._tags = {}
|
|
24
|
+
for k, v in tags.items():
|
|
25
|
+
self._tags[k] = v
|
|
26
|
+
|
|
27
|
+
def __getattr__(self, item):
|
|
28
|
+
try:
|
|
29
|
+
return self.tags[item]
|
|
30
|
+
except KeyError:
|
|
31
|
+
return super().__getattribute__(item)
|
|
32
|
+
|
|
33
|
+
def __new__(cls, *args, **kwargs): # pylint:disable=unused-argument
|
|
34
|
+
"""Create a new instance and set `_tags` attribute.
|
|
35
|
+
|
|
36
|
+
Since TaggedObject override `__getattr__` method and try to access the
|
|
37
|
+
`_tags` attribute, infinite recursion could occur if `_tags` not ready
|
|
38
|
+
to exists.
|
|
39
|
+
|
|
40
|
+
This behavior causes an infinite recursion error when copying
|
|
41
|
+
`TaggedObject` with `copy.deepcopy`.
|
|
42
|
+
|
|
43
|
+
Hence, we set `_tags` attribute here to prevent this problem.
|
|
44
|
+
"""
|
|
45
|
+
self = super().__new__(cls)
|
|
46
|
+
self._tags = None
|
|
47
|
+
return self
|
|
48
|
+
|
|
49
|
+
def __hash__(self) -> int:
|
|
50
|
+
if self._hash is None:
|
|
51
|
+
self._hash = self._hash_core()
|
|
52
|
+
return self._hash
|
|
53
|
+
|
|
54
|
+
def _hash_core(self):
|
|
55
|
+
raise NotImplementedError
|
|
56
|
+
|
|
57
|
+
@property
|
|
58
|
+
def tags(self) -> dict:
|
|
59
|
+
if not self._tags:
|
|
60
|
+
self._tags = {}
|
|
61
|
+
return self._tags
|
angr/ailment/utils.py
ADDED
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
# pylint:disable=ungrouped-imports,wrong-import-position
|
|
2
|
+
from __future__ import annotations
|
|
3
|
+
from typing import TypeAlias
|
|
4
|
+
import struct
|
|
5
|
+
|
|
6
|
+
try:
|
|
7
|
+
from claripy.ast import Bits
|
|
8
|
+
except ImportError:
|
|
9
|
+
from typing_extensions import Never as Bits
|
|
10
|
+
|
|
11
|
+
try:
|
|
12
|
+
import _md5 as md5lib
|
|
13
|
+
except ImportError:
|
|
14
|
+
import hashlib as md5lib
|
|
15
|
+
|
|
16
|
+
GetBitsTypeParams: TypeAlias = "Expression"
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def get_bits(expr: GetBitsTypeParams) -> int:
|
|
20
|
+
|
|
21
|
+
if isinstance(expr, Expression):
|
|
22
|
+
return expr.bits
|
|
23
|
+
if isinstance(expr, Bits):
|
|
24
|
+
return expr.size()
|
|
25
|
+
raise TypeError(type(expr))
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
md5_unpacker = struct.Struct("4I")
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def stable_hash(t: tuple) -> int:
|
|
32
|
+
cnt = _dump_tuple(t)
|
|
33
|
+
hd = md5lib.md5(cnt).digest()
|
|
34
|
+
return md5_unpacker.unpack(hd)[0] # 32 bits
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def _dump_tuple(t: tuple) -> bytes:
|
|
38
|
+
cnt = b""
|
|
39
|
+
for item in t:
|
|
40
|
+
if item is not None:
|
|
41
|
+
type_ = type(item)
|
|
42
|
+
if type_ in _DUMP_BY_TYPE:
|
|
43
|
+
cnt += _DUMP_BY_TYPE[type_](item)
|
|
44
|
+
else:
|
|
45
|
+
# for TaggedObjects, hash(item) is stable
|
|
46
|
+
# other types of items may show up, such as pyvex.expr.CCall and Dirty. they will be removed some day.
|
|
47
|
+
cnt += struct.pack("<Q", hash(item) & 0xFFFF_FFFF_FFFF_FFFF)
|
|
48
|
+
cnt += b"\xf0"
|
|
49
|
+
return cnt
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
def _dump_str(t: str) -> bytes:
|
|
53
|
+
return t.encode("ascii")
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
def _dump_int(t: int) -> bytes:
|
|
57
|
+
prefix = b"" if t >= 0 else b"-"
|
|
58
|
+
t = abs(t)
|
|
59
|
+
if t <= 0xFFFF:
|
|
60
|
+
return prefix + struct.pack("<H", t)
|
|
61
|
+
if t <= 0xFFFF_FFFF:
|
|
62
|
+
return prefix + struct.pack("<I", t)
|
|
63
|
+
if t <= 0xFFFF_FFFF_FFFF_FFFF:
|
|
64
|
+
return prefix + struct.pack("<Q", t)
|
|
65
|
+
cnt = b""
|
|
66
|
+
while t > 0:
|
|
67
|
+
cnt += _dump_int(t & 0xFFFF_FFFF_FFFF_FFFF)
|
|
68
|
+
t >>= 64
|
|
69
|
+
return prefix + cnt
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
def _dump_type(t: type) -> bytes:
|
|
73
|
+
return t.__name__.encode("ascii")
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
_DUMP_BY_TYPE = {
|
|
77
|
+
tuple: _dump_tuple,
|
|
78
|
+
str: _dump_str,
|
|
79
|
+
int: _dump_int,
|
|
80
|
+
type: _dump_type,
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
def is_none_or_likeable(arg1, arg2, is_list=False):
|
|
85
|
+
"""
|
|
86
|
+
Returns whether two things are both None or can like each other
|
|
87
|
+
"""
|
|
88
|
+
if arg1 is None or arg2 is None:
|
|
89
|
+
return arg1 == arg2
|
|
90
|
+
|
|
91
|
+
if is_list:
|
|
92
|
+
return len(arg1) == len(arg2) and all(is_none_or_likeable(a1, a2) for a1, a2 in zip(arg1, arg2))
|
|
93
|
+
|
|
94
|
+
if isinstance(arg1, Expression):
|
|
95
|
+
return arg1.likes(arg2)
|
|
96
|
+
return arg1 == arg2
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
def is_none_or_matchable(arg1, arg2, is_list=False):
|
|
100
|
+
"""
|
|
101
|
+
Returns whether two things are both None or can match each other
|
|
102
|
+
"""
|
|
103
|
+
if arg1 is None or arg2 is None:
|
|
104
|
+
return arg1 == arg2
|
|
105
|
+
|
|
106
|
+
if is_list:
|
|
107
|
+
return len(arg1) == len(arg2) and all(is_none_or_matchable(a1, a2) for a1, a2 in zip(arg1, arg2))
|
|
108
|
+
|
|
109
|
+
if isinstance(arg1, Expression):
|
|
110
|
+
return arg1.matches(arg2)
|
|
111
|
+
return arg1 == arg2
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
from .expression import Expression
|
|
@@ -9,7 +9,7 @@ import capstone
|
|
|
9
9
|
|
|
10
10
|
from pyvex.stmt import Put
|
|
11
11
|
from pyvex.expr import RdTmp
|
|
12
|
-
import ailment
|
|
12
|
+
import angr.ailment as ailment
|
|
13
13
|
|
|
14
14
|
from angr.code_location import ExternalCodeLocation
|
|
15
15
|
|
|
@@ -988,7 +988,11 @@ class CallingConventionAnalysis(Analysis):
|
|
|
988
988
|
for ret_block in self._function.ret_sites:
|
|
989
989
|
fpretval_updated, retval_updated = False, False
|
|
990
990
|
fp_reg_size = 0
|
|
991
|
-
|
|
991
|
+
try:
|
|
992
|
+
irsb = self.project.factory.block(ret_block.addr, size=ret_block.size).vex
|
|
993
|
+
except SimTranslationError:
|
|
994
|
+
# failed to lift the block
|
|
995
|
+
continue
|
|
992
996
|
for stmt in irsb.statements:
|
|
993
997
|
if isinstance(stmt, Put) and isinstance(stmt.data, RdTmp):
|
|
994
998
|
reg_size = irsb.tyenv.sizeof(stmt.data.tmp) // self.project.arch.byte_width # type: ignore
|
|
@@ -8,10 +8,10 @@ import logging
|
|
|
8
8
|
|
|
9
9
|
import networkx
|
|
10
10
|
|
|
11
|
-
from ailment import AILBlockWalker
|
|
12
|
-
from ailment.block import Block
|
|
13
|
-
from ailment.statement import Statement, Assignment, Store, Call, ConditionalJump, DirtyStatement, WeakAssignment
|
|
14
|
-
from ailment.expression import (
|
|
11
|
+
from angr.ailment import AILBlockWalker
|
|
12
|
+
from angr.ailment.block import Block
|
|
13
|
+
from angr.ailment.statement import Statement, Assignment, Store, Call, ConditionalJump, DirtyStatement, WeakAssignment
|
|
14
|
+
from angr.ailment.expression import (
|
|
15
15
|
Register,
|
|
16
16
|
Convert,
|
|
17
17
|
Load,
|
|
@@ -51,7 +51,7 @@ from .ccall_rewriters import CCALL_REWRITERS
|
|
|
51
51
|
from .counters.expression_counters import SingleExpressionCounter
|
|
52
52
|
|
|
53
53
|
if TYPE_CHECKING:
|
|
54
|
-
from ailment.manager import Manager
|
|
54
|
+
from angr.ailment.manager import Manager
|
|
55
55
|
|
|
56
56
|
|
|
57
57
|
_l = logging.getLogger(__name__)
|
|
@@ -2,9 +2,9 @@ from __future__ import annotations
|
|
|
2
2
|
from collections import defaultdict
|
|
3
3
|
from typing import Any
|
|
4
4
|
|
|
5
|
-
from ailment import Block
|
|
6
|
-
from ailment.statement import Call, Statement, ConditionalJump, Assignment, Store, Return, Jump
|
|
7
|
-
from ailment.expression import (
|
|
5
|
+
from angr.ailment import Block
|
|
6
|
+
from angr.ailment.statement import Call, Statement, ConditionalJump, Assignment, Store, Return, Jump
|
|
7
|
+
from angr.ailment.expression import (
|
|
8
8
|
Load,
|
|
9
9
|
VirtualVariable,
|
|
10
10
|
Expression,
|
|
@@ -16,7 +16,7 @@ from ailment.expression import (
|
|
|
16
16
|
Const,
|
|
17
17
|
StackBaseOffset,
|
|
18
18
|
)
|
|
19
|
-
from ailment.block_walker import AILBlockWalkerBase
|
|
19
|
+
from angr.ailment.block_walker import AILBlockWalkerBase
|
|
20
20
|
|
|
21
21
|
|
|
22
22
|
from angr.knowledge_plugins.key_definitions.atoms import MemoryLocation, Register, SpOffset, ConstantSrc
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
import logging
|
|
3
3
|
import networkx as nx
|
|
4
|
-
from ailment.block import Block
|
|
5
|
-
from ailment.statement import Statement, ConditionalJump
|
|
4
|
+
from angr.ailment.block import Block
|
|
5
|
+
from angr.ailment.statement import Statement, ConditionalJump
|
|
6
6
|
|
|
7
7
|
from .utils import find_block_by_addr
|
|
8
8
|
|
|
@@ -4,9 +4,9 @@ import logging
|
|
|
4
4
|
from typing import TYPE_CHECKING
|
|
5
5
|
from collections.abc import Iterable, Mapping
|
|
6
6
|
|
|
7
|
-
from ailment.statement import Statement, Assignment, Call, Store, Jump
|
|
8
|
-
from ailment.expression import Tmp, Load, Const, Register, Convert, Expression
|
|
9
|
-
from ailment import AILBlockWalkerBase
|
|
7
|
+
from angr.ailment.statement import Statement, Assignment, Call, Store, Jump
|
|
8
|
+
from angr.ailment.expression import Tmp, Load, Const, Register, Convert, Expression
|
|
9
|
+
from angr.ailment import AILBlockWalkerBase
|
|
10
10
|
|
|
11
11
|
from angr.code_location import ExternalCodeLocation, CodeLocation
|
|
12
12
|
|
|
@@ -26,7 +26,7 @@ from .utils import peephole_optimize_exprs, peephole_optimize_stmts, peephole_op
|
|
|
26
26
|
|
|
27
27
|
if TYPE_CHECKING:
|
|
28
28
|
from angr.knowledge_plugins.key_definitions.live_definitions import Definition
|
|
29
|
-
from ailment.block import Block
|
|
29
|
+
from angr.ailment.block import Block
|
|
30
30
|
|
|
31
31
|
|
|
32
32
|
_l = logging.getLogger(name=__name__)
|
|
@@ -4,8 +4,8 @@ import copy
|
|
|
4
4
|
import logging
|
|
5
5
|
|
|
6
6
|
import archinfo
|
|
7
|
-
from ailment import Stmt, Expr, Const
|
|
8
|
-
from ailment.manager import Manager
|
|
7
|
+
from angr.ailment import Stmt, Expr, Const
|
|
8
|
+
from angr.ailment.manager import Manager
|
|
9
9
|
|
|
10
10
|
from angr.procedures.stubs.format_parser import FormatParser, FormatSpecifier
|
|
11
11
|
from angr.sim_type import (
|
|
@@ -11,7 +11,7 @@ from dataclasses import dataclass
|
|
|
11
11
|
import networkx
|
|
12
12
|
import capstone
|
|
13
13
|
|
|
14
|
-
import ailment
|
|
14
|
+
import angr.ailment as ailment
|
|
15
15
|
|
|
16
16
|
from angr.errors import AngrDecompilationError
|
|
17
17
|
from angr.knowledge_base import KnowledgeBase
|
|
@@ -143,7 +143,8 @@ class Clinic(Analysis):
|
|
|
143
143
|
desired_variables: set[str] | None = None,
|
|
144
144
|
force_loop_single_exit: bool = True,
|
|
145
145
|
complete_successors: bool = False,
|
|
146
|
-
max_type_constraints: int =
|
|
146
|
+
max_type_constraints: int = 100_000,
|
|
147
|
+
type_constraint_set_degradation_threshold: int = 150,
|
|
147
148
|
ail_graph: networkx.DiGraph | None = None,
|
|
148
149
|
arg_vvars: dict[int, tuple[ailment.Expr.VirtualVariable, SimVariable]] | None = None,
|
|
149
150
|
start_stage: ClinicStage | None = ClinicStage.INITIALIZATION,
|
|
@@ -185,6 +186,7 @@ class Clinic(Analysis):
|
|
|
185
186
|
self._cache = cache
|
|
186
187
|
self._mode = mode
|
|
187
188
|
self._max_type_constraints = max_type_constraints
|
|
189
|
+
self._type_constraint_set_degradation_threshold = type_constraint_set_degradation_threshold
|
|
188
190
|
self.vvar_id_start = vvar_id_start
|
|
189
191
|
self.vvar_to_vvar: dict[int, int] | None = None
|
|
190
192
|
# during SSA conversion, we create secondary stack variables because they overlap and are larger than the
|
|
@@ -1871,6 +1873,7 @@ class Clinic(Analysis):
|
|
|
1871
1873
|
must_struct=must_struct,
|
|
1872
1874
|
ground_truth=groundtruth,
|
|
1873
1875
|
stackvar_max_sizes=tv_max_sizes,
|
|
1876
|
+
constraint_set_degradation_threshold=self._type_constraint_set_degradation_threshold,
|
|
1874
1877
|
)
|
|
1875
1878
|
# tp.pp_constraints()
|
|
1876
1879
|
# tp.pp_solution()
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
import typing
|
|
3
3
|
|
|
4
|
-
from ailment import AILBlockWalkerBase
|
|
4
|
+
from angr.ailment import AILBlockWalkerBase
|
|
5
5
|
|
|
6
6
|
if typing.TYPE_CHECKING:
|
|
7
|
-
from ailment.expression import BinaryOp
|
|
8
|
-
from ailment.statement import Statement
|
|
9
|
-
from ailment.block import Block
|
|
7
|
+
from angr.ailment.expression import BinaryOp
|
|
8
|
+
from angr.ailment.statement import Statement
|
|
9
|
+
from angr.ailment.block import Block
|
|
10
10
|
|
|
11
11
|
|
|
12
12
|
class BooleanCounter(AILBlockWalkerBase):
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
from typing import TYPE_CHECKING
|
|
3
3
|
|
|
4
|
-
from ailment import Block
|
|
5
|
-
from ailment.statement import Label
|
|
6
|
-
from ailment.block_walker import AILBlockWalkerBase
|
|
4
|
+
from angr.ailment import Block
|
|
5
|
+
from angr.ailment.statement import Label
|
|
6
|
+
from angr.ailment.block_walker import AILBlockWalkerBase
|
|
7
7
|
|
|
8
8
|
from angr.analyses.decompiler.sequence_walker import SequenceWalker
|
|
9
9
|
|
|
10
10
|
if TYPE_CHECKING:
|
|
11
|
-
from ailment.statement import Call
|
|
11
|
+
from angr.ailment.statement import Call
|
|
12
12
|
|
|
13
13
|
|
|
14
14
|
class AILBlockCallCounter(AILBlockWalkerBase):
|
|
@@ -3,13 +3,13 @@ from typing import Any, TYPE_CHECKING
|
|
|
3
3
|
from collections.abc import Iterable
|
|
4
4
|
from collections import defaultdict
|
|
5
5
|
|
|
6
|
-
from ailment.expression import Expression, Register
|
|
7
|
-
from ailment.statement import Statement
|
|
8
|
-
from ailment.block_walker import AILBlockWalkerBase
|
|
9
|
-
from ailment import Block
|
|
6
|
+
from angr.ailment.expression import Expression, Register
|
|
7
|
+
from angr.ailment.statement import Statement
|
|
8
|
+
from angr.ailment.block_walker import AILBlockWalkerBase
|
|
9
|
+
from angr.ailment import Block
|
|
10
10
|
|
|
11
11
|
if TYPE_CHECKING:
|
|
12
|
-
from ailment.expression import BinaryOp, UnaryOp
|
|
12
|
+
from angr.ailment.expression import BinaryOp, UnaryOp
|
|
13
13
|
|
|
14
14
|
|
|
15
15
|
class SingleExpressionCounter(AILBlockWalkerBase):
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
from collections import defaultdict
|
|
3
3
|
|
|
4
|
-
import ailment
|
|
4
|
+
import angr.ailment as ailment
|
|
5
5
|
|
|
6
6
|
from angr.analyses.decompiler.sequence_walker import SequenceWalker
|
|
7
7
|
from angr.analyses.decompiler.structuring.structurer_nodes import LoopNode
|
|
@@ -7,7 +7,7 @@ from typing import Any, TYPE_CHECKING
|
|
|
7
7
|
|
|
8
8
|
import networkx
|
|
9
9
|
from cle import SymbolType
|
|
10
|
-
import ailment
|
|
10
|
+
import angr.ailment as ailment
|
|
11
11
|
|
|
12
12
|
from angr.analyses.cfg import CFGFast
|
|
13
13
|
from angr.knowledge_plugins.functions.function import Function
|
|
@@ -23,7 +23,7 @@ from .ailgraph_walker import AILGraphWalker
|
|
|
23
23
|
from .condition_processor import ConditionProcessor
|
|
24
24
|
from .decompilation_options import DecompilationOption
|
|
25
25
|
from .decompilation_cache import DecompilationCache
|
|
26
|
-
from .utils import
|
|
26
|
+
from .utils import remove_edges_in_ailgraph
|
|
27
27
|
from .sequence_walker import SequenceWalker
|
|
28
28
|
from .structuring.structurer_nodes import SequenceNode
|
|
29
29
|
from .presets import DECOMPILATION_PRESETS, DecompilationPreset
|
|
@@ -319,12 +319,8 @@ class Decompiler(Analysis):
|
|
|
319
319
|
# removed!
|
|
320
320
|
remove_edges_in_ailgraph(clinic.graph, clinic.edges_to_remove)
|
|
321
321
|
|
|
322
|
-
# Rewrite the graph to remove phi expressions
|
|
323
|
-
# this is probably optional if we do not pretty-print clinic.graph
|
|
324
|
-
clinic.graph = self._transform_graph_from_ssa(clinic.graph)
|
|
325
|
-
|
|
326
322
|
# save the graph before structuring happens (for AIL view)
|
|
327
|
-
clinic.cc_graph =
|
|
323
|
+
clinic.cc_graph = clinic.copy_graph()
|
|
328
324
|
|
|
329
325
|
codegen = None
|
|
330
326
|
seq_node = None
|
|
@@ -357,7 +353,7 @@ class Decompiler(Analysis):
|
|
|
357
353
|
)
|
|
358
354
|
|
|
359
355
|
# rewrite the sequence node to remove phi expressions
|
|
360
|
-
seq_node = self.
|
|
356
|
+
seq_node = self.transform_seqnode_from_ssa(seq_node)
|
|
361
357
|
|
|
362
358
|
# update memory data
|
|
363
359
|
if self._cfg is not None and self._update_memory_data:
|
|
@@ -670,15 +666,24 @@ class Decompiler(Analysis):
|
|
|
670
666
|
memory_data_addrs=added_memory_data_addrs,
|
|
671
667
|
)
|
|
672
668
|
|
|
673
|
-
def
|
|
669
|
+
def transform_graph_from_ssa(self, ail_graph: networkx.DiGraph) -> networkx.DiGraph:
|
|
670
|
+
"""
|
|
671
|
+
Translate an SSA AIL graph out of SSA form. This is useful for producing a non-SSA AIL graph for displaying in
|
|
672
|
+
angr management.
|
|
673
|
+
|
|
674
|
+
:param ail_graph: The AIL graph to transform out of SSA form.
|
|
675
|
+
:return: The translated AIL graph.
|
|
676
|
+
"""
|
|
677
|
+
variable_kb = self._variable_kb
|
|
674
678
|
dephication = self.project.analyses.GraphDephication(
|
|
675
|
-
self.func, ail_graph, rewrite=True, kb=self.kb, fail_fast=self._fail_fast
|
|
679
|
+
self.func, ail_graph, rewrite=True, variable_kb=variable_kb, kb=self.kb, fail_fast=self._fail_fast
|
|
676
680
|
)
|
|
677
681
|
return dephication.output
|
|
678
682
|
|
|
679
|
-
def
|
|
683
|
+
def transform_seqnode_from_ssa(self, seq_node: SequenceNode) -> SequenceNode:
|
|
684
|
+
variable_kb = self._variable_kb
|
|
680
685
|
dephication = self.project.analyses.SeqNodeDephication(
|
|
681
|
-
self.func, seq_node, rewrite=True, kb=self.kb, fail_fast=self._fail_fast
|
|
686
|
+
self.func, seq_node, rewrite=True, variable_kb=variable_kb, kb=self.kb, fail_fast=self._fail_fast
|
|
682
687
|
)
|
|
683
688
|
return dephication.output
|
|
684
689
|
|
|
@@ -1,10 +1,14 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
|
+
from typing import TYPE_CHECKING
|
|
2
3
|
from typing import Any
|
|
3
4
|
import logging
|
|
4
5
|
from collections import defaultdict
|
|
5
6
|
|
|
6
7
|
from angr.analyses import Analysis
|
|
7
8
|
|
|
9
|
+
if TYPE_CHECKING:
|
|
10
|
+
from angr import KnowledgeBase
|
|
11
|
+
|
|
8
12
|
l = logging.getLogger(name=__name__)
|
|
9
13
|
|
|
10
14
|
|
|
@@ -14,12 +18,19 @@ class DephicationBase(Analysis):
|
|
|
14
18
|
AIL statement containers.
|
|
15
19
|
"""
|
|
16
20
|
|
|
17
|
-
def __init__(
|
|
21
|
+
def __init__(
|
|
22
|
+
self,
|
|
23
|
+
func,
|
|
24
|
+
vvar_to_vvar_mapping: dict[int, int] | None = None,
|
|
25
|
+
rewrite: bool = False,
|
|
26
|
+
variable_kb: KnowledgeBase | None = None,
|
|
27
|
+
):
|
|
18
28
|
if isinstance(func, str):
|
|
19
29
|
self._function = self.kb.functions[func]
|
|
20
30
|
else:
|
|
21
31
|
self._function = func
|
|
22
32
|
|
|
33
|
+
self.variable_kb = variable_kb
|
|
23
34
|
self.vvar_to_vvar_mapping = vvar_to_vvar_mapping if vvar_to_vvar_mapping is not None else None
|
|
24
35
|
self.rewrite = rewrite
|
|
25
36
|
self.output = None
|
|
@@ -1,17 +1,21 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
|
+
from typing import TYPE_CHECKING
|
|
2
3
|
import logging
|
|
3
4
|
from collections import defaultdict
|
|
4
5
|
|
|
5
6
|
import networkx
|
|
6
7
|
|
|
7
|
-
from ailment.expression import Phi, VirtualVariable
|
|
8
|
-
from ailment.statement import Assignment
|
|
9
|
-
|
|
8
|
+
from angr.ailment.expression import Phi, VirtualVariable
|
|
9
|
+
from angr.ailment.statement import Assignment
|
|
10
10
|
from angr.knowledge_plugins.functions import Function
|
|
11
11
|
from angr.analyses import register_analysis
|
|
12
12
|
from .graph_rewriting import GraphRewritingAnalysis
|
|
13
13
|
from .dephication_base import DephicationBase
|
|
14
14
|
|
|
15
|
+
if TYPE_CHECKING:
|
|
16
|
+
from angr import KnowledgeBase
|
|
17
|
+
|
|
18
|
+
|
|
15
19
|
l = logging.getLogger(name=__name__)
|
|
16
20
|
|
|
17
21
|
|
|
@@ -27,6 +31,7 @@ class GraphDephication(DephicationBase): # pylint:disable=abstract-method
|
|
|
27
31
|
ail_graph,
|
|
28
32
|
vvar_to_vvar_mapping: dict[int, int] | None = None,
|
|
29
33
|
rewrite: bool = False,
|
|
34
|
+
variable_kb: KnowledgeBase | None = None,
|
|
30
35
|
):
|
|
31
36
|
"""
|
|
32
37
|
:param func: The subject of the analysis: a function, or a single basic block
|
|
@@ -35,7 +40,7 @@ class GraphDephication(DephicationBase): # pylint:disable=abstract-method
|
|
|
35
40
|
|
|
36
41
|
self._graph = ail_graph
|
|
37
42
|
|
|
38
|
-
super().__init__(func, vvar_to_vvar_mapping=vvar_to_vvar_mapping, rewrite=rewrite)
|
|
43
|
+
super().__init__(func, vvar_to_vvar_mapping=vvar_to_vvar_mapping, rewrite=rewrite, variable_kb=variable_kb)
|
|
39
44
|
|
|
40
45
|
self._analyze()
|
|
41
46
|
|
|
@@ -56,7 +61,9 @@ class GraphDephication(DephicationBase): # pylint:disable=abstract-method
|
|
|
56
61
|
|
|
57
62
|
def _rewrite_container(self) -> networkx.DiGraph:
|
|
58
63
|
# replace all vvars with phi variables in the graph
|
|
59
|
-
rewriter = GraphRewritingAnalysis(
|
|
64
|
+
rewriter = GraphRewritingAnalysis(
|
|
65
|
+
self.project, self._function, self._graph, self.vvar_to_vvar_mapping, variable_kb=self.variable_kb
|
|
66
|
+
)
|
|
60
67
|
return rewriter.out_graph
|
|
61
68
|
|
|
62
69
|
|
|
@@ -4,8 +4,7 @@ import logging
|
|
|
4
4
|
|
|
5
5
|
import networkx
|
|
6
6
|
|
|
7
|
-
import ailment
|
|
8
|
-
|
|
7
|
+
from angr import ailment
|
|
9
8
|
from angr.utils.ail import is_phi_assignment
|
|
10
9
|
from angr.analyses import ForwardAnalysis
|
|
11
10
|
from angr.analyses.forward_analysis.visitors.graph import NodeType
|
|
@@ -21,23 +20,20 @@ class GraphRewritingAnalysis(ForwardAnalysis[None, NodeType, object, object]):
|
|
|
21
20
|
This analysis traverses the AIL graph and rewrites virtual variables accordingly.
|
|
22
21
|
"""
|
|
23
22
|
|
|
24
|
-
def __init__(
|
|
25
|
-
self,
|
|
26
|
-
project,
|
|
27
|
-
func,
|
|
28
|
-
ail_graph,
|
|
29
|
-
vvar_to_vvar: dict[int, int],
|
|
30
|
-
):
|
|
23
|
+
def __init__(self, project, func, ail_graph, vvar_to_vvar: dict[int, int], variable_kb=None):
|
|
31
24
|
self.project = project
|
|
32
25
|
self._function = func
|
|
33
26
|
self._graph_visitor = FunctionGraphVisitor(self._function, ail_graph)
|
|
27
|
+
self.variable_kb = variable_kb
|
|
34
28
|
|
|
35
29
|
ForwardAnalysis.__init__(
|
|
36
30
|
self, order_jobs=False, allow_merging=False, allow_widening=False, graph_visitor=self._graph_visitor
|
|
37
31
|
)
|
|
38
32
|
self._graph = ail_graph
|
|
39
33
|
self._vvar_to_vvar = vvar_to_vvar
|
|
40
|
-
self._engine_ail = SimEngineDephiRewriting(
|
|
34
|
+
self._engine_ail = SimEngineDephiRewriting(
|
|
35
|
+
self.project, self._vvar_to_vvar, func_addr=self._function.addr, variable_kb=self.variable_kb
|
|
36
|
+
)
|
|
41
37
|
|
|
42
38
|
self._visited_blocks: set[Any] = set()
|
|
43
39
|
self.out_blocks = {}
|