angr 9.2.95__py3-none-manylinux2014_x86_64.whl → 9.2.97__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/cfg/cfg_fast.py +9 -6
- angr/analyses/cfg/indirect_jump_resolvers/const_resolver.py +6 -1
- angr/analyses/complete_calling_conventions.py +27 -11
- angr/analyses/decompiler/ail_simplifier.py +30 -8
- angr/analyses/decompiler/ccall_rewriters/amd64_ccalls.py +20 -7
- angr/analyses/decompiler/clinic.py +21 -5
- angr/analyses/decompiler/condition_processor.py +11 -0
- angr/analyses/decompiler/decompiler.py +58 -46
- angr/analyses/decompiler/optimization_passes/__init__.py +11 -5
- angr/analyses/decompiler/optimization_passes/flip_boolean_cmp.py +13 -7
- angr/analyses/decompiler/optimization_passes/optimization_pass.py +31 -11
- angr/analyses/decompiler/optimization_passes/{return_duplicator.py → return_duplicator_base.py} +54 -102
- angr/analyses/decompiler/optimization_passes/return_duplicator_high.py +57 -0
- angr/analyses/decompiler/optimization_passes/return_duplicator_low.py +121 -0
- angr/analyses/decompiler/region_identifier.py +13 -0
- angr/analyses/decompiler/seq_to_blocks.py +19 -0
- angr/analyses/decompiler/structured_codegen/c.py +21 -0
- angr/analyses/decompiler/structuring/phoenix.py +28 -4
- angr/analyses/decompiler/structuring/recursive_structurer.py +35 -1
- angr/analyses/decompiler/structuring/structurer_base.py +3 -0
- angr/analyses/decompiler/utils.py +41 -6
- angr/analyses/disassembly.py +4 -1
- angr/analyses/find_objects_static.py +15 -10
- angr/analyses/forward_analysis/forward_analysis.py +15 -1
- angr/analyses/propagator/engine_ail.py +40 -0
- angr/analyses/propagator/propagator.py +6 -3
- angr/analyses/reaching_definitions/engine_ail.py +16 -24
- angr/analyses/reaching_definitions/rd_state.py +14 -1
- angr/analyses/reaching_definitions/reaching_definitions.py +19 -2
- angr/analyses/variable_recovery/engine_ail.py +6 -6
- angr/analyses/variable_recovery/engine_base.py +22 -4
- angr/analyses/variable_recovery/variable_recovery_base.py +4 -1
- angr/engines/light/engine.py +8 -1
- angr/knowledge_plugins/key_definitions/atoms.py +4 -2
- angr/knowledge_plugins/key_definitions/environment.py +11 -0
- angr/knowledge_plugins/key_definitions/live_definitions.py +41 -8
- angr/knowledge_plugins/key_definitions/uses.py +18 -4
- angr/knowledge_plugins/propagations/states.py +22 -3
- angr/knowledge_plugins/types.py +6 -0
- angr/knowledge_plugins/variables/variable_manager.py +54 -5
- angr/simos/simos.py +2 -0
- angr/storage/memory_mixins/__init__.py +3 -0
- angr/storage/memory_mixins/multi_value_merger_mixin.py +22 -11
- angr/storage/memory_mixins/paged_memory/paged_memory_mixin.py +20 -2
- angr/storage/memory_mixins/paged_memory/pages/mv_list_page.py +81 -44
- angr/utils/cowdict.py +4 -2
- angr/utils/funcid.py +6 -0
- angr/utils/mp.py +1 -1
- {angr-9.2.95.dist-info → angr-9.2.97.dist-info}/METADATA +6 -6
- {angr-9.2.95.dist-info → angr-9.2.97.dist-info}/RECORD +55 -52
- {angr-9.2.95.dist-info → angr-9.2.97.dist-info}/LICENSE +0 -0
- {angr-9.2.95.dist-info → angr-9.2.97.dist-info}/WHEEL +0 -0
- {angr-9.2.95.dist-info → angr-9.2.97.dist-info}/entry_points.txt +0 -0
- {angr-9.2.95.dist-info → angr-9.2.97.dist-info}/top_level.txt +0 -0
|
@@ -294,6 +294,24 @@ class PagedMemoryMixin(MemoryMixin):
|
|
|
294
294
|
|
|
295
295
|
return bool(merged_bytes)
|
|
296
296
|
|
|
297
|
+
def compare(self, other: "PagedMemoryMixin") -> bool:
|
|
298
|
+
changed_pages_and_offsets: Dict[int, Optional[Set[int]]] = dict(self.changed_pages(other))
|
|
299
|
+
|
|
300
|
+
for page_no in sorted(changed_pages_and_offsets):
|
|
301
|
+
page = self._get_page(page_no, False)
|
|
302
|
+
page_addr = page_no * self.page_size
|
|
303
|
+
if page_no in other._pages:
|
|
304
|
+
r = page.compare(
|
|
305
|
+
other._pages[page_no],
|
|
306
|
+
page_addr=page_addr,
|
|
307
|
+
memory=self,
|
|
308
|
+
changed_offsets=changed_pages_and_offsets[page_no],
|
|
309
|
+
)
|
|
310
|
+
if r is False:
|
|
311
|
+
return False
|
|
312
|
+
|
|
313
|
+
return True
|
|
314
|
+
|
|
297
315
|
def permissions(self, addr, permissions=None, **kwargs):
|
|
298
316
|
if type(addr) is not int:
|
|
299
317
|
raise TypeError("addr must be an int in paged memory")
|
|
@@ -643,10 +661,10 @@ class LabeledPagesMixin(PagedMemoryMixin):
|
|
|
643
661
|
if endness is None:
|
|
644
662
|
endness = self.endness
|
|
645
663
|
|
|
646
|
-
if
|
|
664
|
+
if not isinstance(size, int):
|
|
647
665
|
raise TypeError("Need size to be resolved to an int by this point")
|
|
648
666
|
|
|
649
|
-
if
|
|
667
|
+
if not isinstance(addr, int):
|
|
650
668
|
raise TypeError("Need addr to be resolved to an int by this point")
|
|
651
669
|
|
|
652
670
|
pageno, pageoff = self._divide_addr(addr)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
# pylint:disable=abstract-method,arguments-differ
|
|
1
|
+
# pylint:disable=abstract-method,arguments-differ,assignment-from-no-return
|
|
2
2
|
import logging
|
|
3
|
-
from typing import Optional, List, Set, Tuple, Union, Callable
|
|
3
|
+
from typing import Optional, List, Set, Tuple, Union, Callable, Any, FrozenSet
|
|
4
4
|
|
|
5
5
|
from angr.utils.dynamic_dictlist import DynamicDictList
|
|
6
6
|
from .....storage.memory_object import SimMemoryObject, SimLabeledMemoryObject
|
|
@@ -166,40 +166,58 @@ class MVListPage(
|
|
|
166
166
|
continue
|
|
167
167
|
l.debug("... on byte 0x%x", b)
|
|
168
168
|
|
|
169
|
-
|
|
169
|
+
memory_object_sets: Set[Tuple[FrozenSet[SimMemoryObject], Any]] = set()
|
|
170
170
|
unconstrained_in = []
|
|
171
171
|
|
|
172
|
-
# first get a list of all memory objects at that location, and
|
|
173
|
-
|
|
172
|
+
# first get a list of all memory objects at that location, and all memories that don't have those bytes
|
|
173
|
+
self_has_memory_object_set = False
|
|
174
174
|
for sm, fv in zip(all_pages, merge_conditions):
|
|
175
175
|
if sm._contains(b, page_addr):
|
|
176
176
|
l.info("... present in %s", fv)
|
|
177
|
+
memory_objects = set()
|
|
177
178
|
for mo in sm.content_gen(b):
|
|
178
179
|
if mo.includes(page_addr + b):
|
|
179
|
-
memory_objects.
|
|
180
|
+
memory_objects.add(mo)
|
|
181
|
+
memory_object_sets.add((frozenset(memory_objects), fv))
|
|
182
|
+
if sm is self:
|
|
183
|
+
self_has_memory_object_set = True
|
|
180
184
|
else:
|
|
181
185
|
l.info("... not present in %s", fv)
|
|
182
186
|
unconstrained_in.append((sm, fv))
|
|
183
187
|
|
|
184
|
-
if not
|
|
188
|
+
if not memory_object_sets:
|
|
189
|
+
continue
|
|
190
|
+
if self_has_memory_object_set and len(memory_object_sets) == 1:
|
|
185
191
|
continue
|
|
186
192
|
|
|
187
|
-
|
|
188
|
-
mo_bases =
|
|
189
|
-
mo_lengths =
|
|
190
|
-
endnesses =
|
|
191
|
-
|
|
192
|
-
|
|
193
|
+
mo_sets = {mo_set for mo_set, _ in memory_object_sets}
|
|
194
|
+
mo_bases = set()
|
|
195
|
+
mo_lengths = set()
|
|
196
|
+
endnesses = set()
|
|
197
|
+
for mo_set in mo_sets:
|
|
198
|
+
for mo in mo_set:
|
|
199
|
+
mo_bases.add(mo.base)
|
|
200
|
+
mo_lengths.add(mo.length)
|
|
201
|
+
endnesses.add(mo.endness)
|
|
202
|
+
|
|
203
|
+
if not unconstrained_in and not (mo_sets - merged_objects): # pylint:disable=superfluous-parens
|
|
193
204
|
continue
|
|
194
205
|
|
|
195
206
|
# first, optimize the case where we are dealing with the same-sized memory objects
|
|
196
207
|
if len(mo_bases) == 1 and len(mo_lengths) == 1 and not unconstrained_in and len(endnesses) == 1:
|
|
208
|
+
if len(memory_object_sets) == 1:
|
|
209
|
+
# nothing to merge!
|
|
210
|
+
continue
|
|
211
|
+
|
|
197
212
|
the_endness = next(iter(endnesses))
|
|
198
|
-
to_merge = [
|
|
213
|
+
to_merge = []
|
|
214
|
+
for mo_set, fv in memory_object_sets:
|
|
215
|
+
for mo in mo_set:
|
|
216
|
+
to_merge.append((mo.object, fv))
|
|
199
217
|
|
|
200
218
|
# Update `merged_to`
|
|
201
219
|
mo_base = list(mo_bases)[0]
|
|
202
|
-
mo_length =
|
|
220
|
+
mo_length = next(iter(mo_lengths))
|
|
203
221
|
size = min(mo_length - (page_addr + b - mo_base), len(self.content) - b)
|
|
204
222
|
merged_to = b + size
|
|
205
223
|
|
|
@@ -212,25 +230,18 @@ class MVListPage(
|
|
|
212
230
|
# TODO: Implement in-place replacement instead of calling store()
|
|
213
231
|
# new_object = self._replace_memory_object(our_mo, merged_val, page_addr, memory.page_size)
|
|
214
232
|
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
self.store(
|
|
218
|
-
b,
|
|
219
|
-
{SimMemoryObject(v, mo_base, endness=the_endness)},
|
|
220
|
-
size=size,
|
|
221
|
-
cooperate=True,
|
|
222
|
-
weak=not first_value,
|
|
223
|
-
)
|
|
224
|
-
first_value = False
|
|
233
|
+
new_mos = {SimMemoryObject(v, mo_base, endness=the_endness) for v in merged_val}
|
|
234
|
+
self.store(b, new_mos, size=size, cooperate=True, weak=False)
|
|
225
235
|
|
|
226
236
|
merged_offsets.add(b)
|
|
227
237
|
|
|
228
238
|
else:
|
|
229
|
-
# get the size that we can merge easily. This is the minimum of
|
|
230
|
-
#
|
|
231
|
-
min_size =
|
|
232
|
-
|
|
233
|
-
|
|
239
|
+
# get the size that we can merge easily. This is the minimum of the size of all memory objects and
|
|
240
|
+
# unallocated spaces.
|
|
241
|
+
min_size = len(self.content) - b
|
|
242
|
+
for mo_set in mo_sets:
|
|
243
|
+
for mo in mo_set:
|
|
244
|
+
min_size = min(min_size, mo.length - (b + page_addr - mo.base))
|
|
234
245
|
for um, _ in unconstrained_in:
|
|
235
246
|
for i in range(0, min_size):
|
|
236
247
|
if um._contains(b + i, page_addr):
|
|
@@ -241,9 +252,11 @@ class MVListPage(
|
|
|
241
252
|
|
|
242
253
|
# Now, we have the minimum size. We'll extract/create expressions of that
|
|
243
254
|
# size and merge them
|
|
244
|
-
extracted =
|
|
245
|
-
|
|
246
|
-
|
|
255
|
+
extracted = []
|
|
256
|
+
if min_size != 0:
|
|
257
|
+
for mo_set, fv in memory_object_sets:
|
|
258
|
+
for mo in mo_set:
|
|
259
|
+
extracted.append((mo.bytes_at(page_addr + b, min_size), fv))
|
|
247
260
|
if not memory.skip_missing_values_during_merging:
|
|
248
261
|
created = [
|
|
249
262
|
(self._default_value(None, min_size, name=f"merge_uc_{uc.id}_{b:x}", memory=memory), fv)
|
|
@@ -257,22 +270,46 @@ class MVListPage(
|
|
|
257
270
|
if merged_val is None:
|
|
258
271
|
continue
|
|
259
272
|
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
self.store(
|
|
263
|
-
b,
|
|
264
|
-
{SimMemoryObject(v, page_addr + b, endness="Iend_BE")},
|
|
265
|
-
size=min_size,
|
|
266
|
-
endness="Iend_BE",
|
|
267
|
-
cooperate=True,
|
|
268
|
-
weak=not first_value,
|
|
269
|
-
) # do not convert endianness again
|
|
270
|
-
first_value = False
|
|
273
|
+
new_mos = {SimMemoryObject(v, page_addr + b, endness="Iend_BE") for v in merged_val}
|
|
274
|
+
self.store(b, new_mos, size=min_size, cooperate=True, weak=False)
|
|
271
275
|
merged_offsets.add(b)
|
|
272
276
|
|
|
273
277
|
self.stored_offset |= merged_offsets
|
|
274
278
|
return merged_offsets
|
|
275
279
|
|
|
280
|
+
def compare(
|
|
281
|
+
self, other: "MVListPage", page_addr: int = None, memory=None, changed_offsets=None
|
|
282
|
+
) -> bool: # pylint: disable=unused-argument
|
|
283
|
+
compared_to = None
|
|
284
|
+
for b in sorted(changed_offsets):
|
|
285
|
+
if compared_to is not None and not b >= compared_to:
|
|
286
|
+
continue
|
|
287
|
+
|
|
288
|
+
unconstrained_in = []
|
|
289
|
+
self_has_memory_object_set = False
|
|
290
|
+
memory_object_sets: Set[FrozenSet[SimMemoryObject]] = set()
|
|
291
|
+
for sm in [self, other]:
|
|
292
|
+
if sm._contains(b, page_addr):
|
|
293
|
+
memory_objects = set()
|
|
294
|
+
for mo in sm.content_gen(b):
|
|
295
|
+
if mo.includes(page_addr + b):
|
|
296
|
+
memory_objects.add(mo)
|
|
297
|
+
memory_object_sets.add(frozenset(memory_objects))
|
|
298
|
+
if sm is self:
|
|
299
|
+
self_has_memory_object_set = True
|
|
300
|
+
else:
|
|
301
|
+
unconstrained_in.append(sm)
|
|
302
|
+
|
|
303
|
+
if not memory_object_sets:
|
|
304
|
+
continue
|
|
305
|
+
if self_has_memory_object_set and len(memory_object_sets) == 1:
|
|
306
|
+
continue
|
|
307
|
+
|
|
308
|
+
# TODO: compare_values even more?
|
|
309
|
+
return False
|
|
310
|
+
|
|
311
|
+
return True
|
|
312
|
+
|
|
276
313
|
def changed_bytes(self, other: "MVListPage", page_addr: int = None):
|
|
277
314
|
candidates: Set[int] = super().changed_bytes(other)
|
|
278
315
|
if candidates is not None:
|
angr/utils/cowdict.py
CHANGED
|
@@ -35,7 +35,7 @@ class DefaultChainMapCOW(ChainMapCOW):
|
|
|
35
35
|
Implements a copy-on-write version of ChainMap with default values that supports auto-collapsing.
|
|
36
36
|
"""
|
|
37
37
|
|
|
38
|
-
def __init__(self,
|
|
38
|
+
def __init__(self, *args, default_factory=None, collapse_threshold=None):
|
|
39
39
|
super().__init__(*args, collapse_threshold=collapse_threshold)
|
|
40
40
|
self.default_factory = default_factory
|
|
41
41
|
|
|
@@ -53,7 +53,9 @@ class DefaultChainMapCOW(ChainMapCOW):
|
|
|
53
53
|
collapsed = {}
|
|
54
54
|
for m in reversed(self.maps):
|
|
55
55
|
collapsed.update(m)
|
|
56
|
-
return DefaultChainMapCOW(
|
|
56
|
+
return DefaultChainMapCOW(
|
|
57
|
+
collapsed, default_factory=self.default_factory, collapse_threshold=self.collapse_threshold
|
|
58
|
+
)
|
|
57
59
|
r = self.new_child()
|
|
58
60
|
r.default_factory = self.default_factory
|
|
59
61
|
r.collapse_threshold = self.collapse_threshold
|
angr/utils/funcid.py
CHANGED
|
@@ -13,6 +13,8 @@ def is_function_security_check_cookie(func, project, security_cookie_addr: int)
|
|
|
13
13
|
block = project.factory.block(func.addr)
|
|
14
14
|
if block.instructions != 2:
|
|
15
15
|
return False
|
|
16
|
+
if not block.capstone.insns or len(block.capstone.insns) != 2:
|
|
17
|
+
return False
|
|
16
18
|
ins0 = block.capstone.insns[0]
|
|
17
19
|
if (
|
|
18
20
|
ins0.mnemonic == "cmp"
|
|
@@ -57,6 +59,8 @@ def is_function_security_init_cookie(func: "Function", project, security_cookie_
|
|
|
57
59
|
block = project.factory.block(node_addr, size=node_size)
|
|
58
60
|
if not block.instructions:
|
|
59
61
|
continue
|
|
62
|
+
if not block.capstone.insns:
|
|
63
|
+
continue
|
|
60
64
|
last_insn = block.capstone.insns[-1]
|
|
61
65
|
if (
|
|
62
66
|
last_insn.mnemonic == "mov"
|
|
@@ -78,6 +82,8 @@ def is_function_security_init_cookie_win8(func: "Function", project, security_co
|
|
|
78
82
|
block = project.factory.block(func.addr)
|
|
79
83
|
if block.instructions != 3:
|
|
80
84
|
return False
|
|
85
|
+
if not block.capstone.insns or len(block.capstone.insns) != 3:
|
|
86
|
+
return False
|
|
81
87
|
ins0 = block.capstone.insns[0]
|
|
82
88
|
if (
|
|
83
89
|
ins0.mnemonic == "mov"
|
angr/utils/mp.py
CHANGED
|
@@ -43,7 +43,7 @@ class Initializer:
|
|
|
43
43
|
def initialize(self) -> None:
|
|
44
44
|
"""
|
|
45
45
|
Initialize a multiprocessing.Process
|
|
46
|
-
Set the current global
|
|
46
|
+
Set the current global initializer to the same state as this initializer, then calls each initializer
|
|
47
47
|
"""
|
|
48
48
|
self._single = self
|
|
49
49
|
for i in self.initializers:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: angr
|
|
3
|
-
Version: 9.2.
|
|
3
|
+
Version: 9.2.97
|
|
4
4
|
Summary: A multi-architecture binary analysis toolkit, with the ability to perform dynamic symbolic execution and various static analyses on binaries
|
|
5
5
|
Home-page: https://github.com/angr/angr
|
|
6
6
|
License: BSD-2-Clause
|
|
@@ -17,13 +17,13 @@ Description-Content-Type: text/markdown
|
|
|
17
17
|
License-File: LICENSE
|
|
18
18
|
Requires-Dist: CppHeaderParser
|
|
19
19
|
Requires-Dist: GitPython
|
|
20
|
-
Requires-Dist: ailment ==9.2.
|
|
21
|
-
Requires-Dist: archinfo ==9.2.
|
|
20
|
+
Requires-Dist: ailment ==9.2.97
|
|
21
|
+
Requires-Dist: archinfo ==9.2.97
|
|
22
22
|
Requires-Dist: cachetools
|
|
23
23
|
Requires-Dist: capstone ==5.0.0.post1
|
|
24
24
|
Requires-Dist: cffi >=1.14.0
|
|
25
|
-
Requires-Dist: claripy ==9.2.
|
|
26
|
-
Requires-Dist: cle ==9.2.
|
|
25
|
+
Requires-Dist: claripy ==9.2.97
|
|
26
|
+
Requires-Dist: cle ==9.2.97
|
|
27
27
|
Requires-Dist: dpkt
|
|
28
28
|
Requires-Dist: itanium-demangler
|
|
29
29
|
Requires-Dist: mulpyplexer
|
|
@@ -33,7 +33,7 @@ Requires-Dist: protobuf >=3.19.0
|
|
|
33
33
|
Requires-Dist: psutil
|
|
34
34
|
Requires-Dist: pycparser >=2.18
|
|
35
35
|
Requires-Dist: pyformlang
|
|
36
|
-
Requires-Dist: pyvex ==9.2.
|
|
36
|
+
Requires-Dist: pyvex ==9.2.97
|
|
37
37
|
Requires-Dist: rich >=13.1.0
|
|
38
38
|
Requires-Dist: rpyc
|
|
39
39
|
Requires-Dist: sortedcontainers
|