angr 9.2.92__py3-none-manylinux2014_x86_64.whl → 9.2.94__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_base.py +20 -10
- angr/analyses/cfg/indirect_jump_resolvers/amd64_elf_got.py +1 -1
- angr/analyses/cfg/indirect_jump_resolvers/arm_elf_fast.py +89 -32
- angr/analyses/cfg/indirect_jump_resolvers/jumptable.py +276 -133
- angr/analyses/complete_calling_conventions.py +1 -1
- angr/analyses/decompiler/ail_simplifier.py +20 -0
- angr/analyses/decompiler/block_io_finder.py +293 -0
- angr/analyses/decompiler/block_similarity.py +190 -0
- angr/analyses/decompiler/callsite_maker.py +5 -0
- angr/analyses/decompiler/clinic.py +103 -1
- angr/analyses/decompiler/decompilation_cache.py +2 -0
- angr/analyses/decompiler/decompiler.py +21 -4
- angr/analyses/decompiler/optimization_passes/__init__.py +6 -0
- angr/analyses/decompiler/optimization_passes/code_motion.py +361 -0
- angr/analyses/decompiler/optimization_passes/optimization_pass.py +1 -0
- angr/analyses/decompiler/optimization_passes/stack_canary_simplifier.py +30 -18
- angr/analyses/decompiler/optimization_passes/switch_default_case_duplicator.py +110 -0
- angr/analyses/decompiler/peephole_optimizations/bswap.py +53 -2
- angr/analyses/decompiler/peephole_optimizations/eager_eval.py +20 -1
- angr/analyses/decompiler/structured_codegen/c.py +76 -41
- angr/analyses/decompiler/structuring/phoenix.py +41 -9
- angr/analyses/decompiler/utils.py +13 -4
- angr/analyses/propagator/engine_ail.py +3 -0
- angr/analyses/reaching_definitions/engine_ail.py +3 -0
- angr/analyses/reaching_definitions/reaching_definitions.py +7 -0
- angr/analyses/stack_pointer_tracker.py +60 -10
- angr/analyses/typehoon/simple_solver.py +95 -24
- angr/analyses/typehoon/typeconsts.py +1 -1
- angr/calling_conventions.py +0 -3
- angr/engines/pcode/cc.py +1 -1
- angr/engines/successors.py +6 -0
- angr/knowledge_plugins/propagations/states.py +2 -1
- angr/procedures/definitions/glibc.py +3 -1
- angr/procedures/definitions/parse_win32json.py +2135 -383
- angr/procedures/definitions/wdk_ntoskrnl.py +956 -0
- angr/sim_type.py +53 -13
- angr/utils/library.py +2 -2
- {angr-9.2.92.dist-info → angr-9.2.94.dist-info}/METADATA +6 -6
- {angr-9.2.92.dist-info → angr-9.2.94.dist-info}/RECORD +44 -41
- {angr-9.2.92.dist-info → angr-9.2.94.dist-info}/WHEEL +1 -1
- angr/procedures/definitions/wdk_ntdll.py +0 -994
- {angr-9.2.92.dist-info → angr-9.2.94.dist-info}/LICENSE +0 -0
- {angr-9.2.92.dist-info → angr-9.2.94.dist-info}/entry_points.txt +0 -0
- {angr-9.2.92.dist-info → angr-9.2.94.dist-info}/top_level.txt +0 -0
|
@@ -224,7 +224,8 @@ class Sketch:
|
|
|
224
224
|
@staticmethod
|
|
225
225
|
def flatten_typevar(
|
|
226
226
|
derived_typevar: Union[TypeVariable, TypeConstant, DerivedTypeVariable]
|
|
227
|
-
) -> Union[DerivedTypeVariable, TypeVariable, TypeConstant]:
|
|
227
|
+
) -> Union[DerivedTypeVariable, TypeVariable, TypeConstant]:
|
|
228
|
+
# pylint:disable=too-many-boolean-expressions
|
|
228
229
|
if (
|
|
229
230
|
isinstance(derived_typevar, DerivedTypeVariable)
|
|
230
231
|
and isinstance(derived_typevar.type_var, Pointer)
|
|
@@ -419,15 +420,45 @@ class SimpleSolver:
|
|
|
419
420
|
for tv in typevars:
|
|
420
421
|
if tv in self._constraints:
|
|
421
422
|
constraints |= self._constraints[tv]
|
|
423
|
+
|
|
424
|
+
# collect typevars used in the constraint set
|
|
425
|
+
constrained_typevars = set()
|
|
426
|
+
for constraint in constraints:
|
|
427
|
+
if isinstance(constraint, Subtype):
|
|
428
|
+
for t in (constraint.sub_type, constraint.super_type):
|
|
429
|
+
if isinstance(t, DerivedTypeVariable):
|
|
430
|
+
if t.type_var in typevars:
|
|
431
|
+
constrained_typevars.add(t.type_var)
|
|
432
|
+
elif isinstance(t, TypeVariable):
|
|
433
|
+
if t in typevars:
|
|
434
|
+
constrained_typevars.add(t)
|
|
435
|
+
|
|
422
436
|
equivalence_classes, sketches = self.infer_shapes(typevars, constraints)
|
|
423
437
|
# TODO: Handle global variables
|
|
424
438
|
|
|
425
439
|
type_schemes = constraints
|
|
426
440
|
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
for
|
|
430
|
-
|
|
441
|
+
constraintset2tvs = defaultdict(set)
|
|
442
|
+
for idx, tv in enumerate(constrained_typevars):
|
|
443
|
+
_l.debug("Collecting constraints for type variable %r (%d/%d)", tv, idx + 1, len(constrained_typevars))
|
|
444
|
+
# build a sub constraint set for the type variable
|
|
445
|
+
constraint_subset = frozenset(self._generate_constraint_subset(constraints, {tv}))
|
|
446
|
+
constraintset2tvs[constraint_subset].add(tv)
|
|
447
|
+
|
|
448
|
+
for idx, (constraint_subset, tvs) in enumerate(constraintset2tvs.items()):
|
|
449
|
+
_l.debug(
|
|
450
|
+
"Solving %d constraints for type variables %r (%d/%d)",
|
|
451
|
+
len(constraint_subset),
|
|
452
|
+
tvs,
|
|
453
|
+
idx + 1,
|
|
454
|
+
len(constraintset2tvs),
|
|
455
|
+
)
|
|
456
|
+
base_constraint_graph = self._generate_constraint_graph(constraint_subset, tvs | PRIMITIVE_TYPES)
|
|
457
|
+
for idx_0, tv in enumerate(tvs):
|
|
458
|
+
_l.debug("Solving for type variable %r (%d/%d)", tv, idx_0 + 1, len(tvs))
|
|
459
|
+
primitive_constraints = self._generate_primitive_constraints({tv}, base_constraint_graph)
|
|
460
|
+
for primitive_constraint in primitive_constraints:
|
|
461
|
+
sketches[tv].add_constraint(primitive_constraint)
|
|
431
462
|
|
|
432
463
|
return equivalence_classes, sketches, type_schemes
|
|
433
464
|
|
|
@@ -515,10 +546,11 @@ class SimpleSolver:
|
|
|
515
546
|
return equivalence_classes, out_graph
|
|
516
547
|
|
|
517
548
|
def _generate_primitive_constraints(
|
|
518
|
-
self,
|
|
549
|
+
self,
|
|
550
|
+
non_primitive_endpoints: Set[Union[TypeVariable, DerivedTypeVariable]],
|
|
551
|
+
constraint_graph,
|
|
519
552
|
) -> Set[TypeConstraint]:
|
|
520
553
|
# FIXME: Extract interesting variables
|
|
521
|
-
constraint_graph = self._generate_constraint_graph(constraints, non_primitive_endpoints | PRIMITIVE_TYPES)
|
|
522
554
|
constraints_0 = self._solve_constraints_between(constraint_graph, non_primitive_endpoints, PRIMITIVE_TYPES)
|
|
523
555
|
constraints_1 = self._solve_constraints_between(constraint_graph, PRIMITIVE_TYPES, non_primitive_endpoints)
|
|
524
556
|
return constraints_0 | constraints_1
|
|
@@ -702,6 +734,41 @@ class SimpleSolver:
|
|
|
702
734
|
# Constraint graph
|
|
703
735
|
#
|
|
704
736
|
|
|
737
|
+
@staticmethod
|
|
738
|
+
def _generate_constraint_subset(
|
|
739
|
+
constraints: Set[TypeConstraint], typevars: Set[TypeVariable]
|
|
740
|
+
) -> Set[TypeConstraint]:
|
|
741
|
+
subset = set()
|
|
742
|
+
related_typevars = set(typevars)
|
|
743
|
+
while True:
|
|
744
|
+
new = set()
|
|
745
|
+
for constraint in constraints:
|
|
746
|
+
if constraint in subset:
|
|
747
|
+
continue
|
|
748
|
+
if isinstance(constraint, Subtype):
|
|
749
|
+
if isinstance(constraint.sub_type, DerivedTypeVariable):
|
|
750
|
+
subt = constraint.sub_type.type_var
|
|
751
|
+
elif isinstance(constraint.sub_type, TypeVariable):
|
|
752
|
+
subt = constraint.sub_type
|
|
753
|
+
else:
|
|
754
|
+
subt = None
|
|
755
|
+
if isinstance(constraint.super_type, DerivedTypeVariable):
|
|
756
|
+
supert = constraint.super_type.type_var
|
|
757
|
+
elif isinstance(constraint.super_type, TypeVariable):
|
|
758
|
+
supert = constraint.super_type
|
|
759
|
+
else:
|
|
760
|
+
supert = None
|
|
761
|
+
if subt in related_typevars or supert in related_typevars:
|
|
762
|
+
new.add(constraint)
|
|
763
|
+
if subt is not None:
|
|
764
|
+
related_typevars.add(subt)
|
|
765
|
+
if supert is not None:
|
|
766
|
+
related_typevars.add(supert)
|
|
767
|
+
if not new:
|
|
768
|
+
break
|
|
769
|
+
subset |= new
|
|
770
|
+
return subset
|
|
771
|
+
|
|
705
772
|
def _generate_constraint_graph(
|
|
706
773
|
self, constraints: Set[TypeConstraint], interesting_variables: Set[DerivedTypeVariable]
|
|
707
774
|
) -> networkx.DiGraph:
|
|
@@ -946,7 +1013,8 @@ class SimpleSolver:
|
|
|
946
1013
|
return t1
|
|
947
1014
|
return Top_
|
|
948
1015
|
|
|
949
|
-
|
|
1016
|
+
@staticmethod
|
|
1017
|
+
def abstract(t: Union[TypeConstant, TypeVariable]) -> Union[TypeConstant, TypeVariable]:
|
|
950
1018
|
if isinstance(t, Pointer32):
|
|
951
1019
|
return Pointer32()
|
|
952
1020
|
elif isinstance(t, Pointer64):
|
|
@@ -1011,6 +1079,8 @@ class SimpleSolver:
|
|
|
1011
1079
|
last_labels.append(labels[-1])
|
|
1012
1080
|
|
|
1013
1081
|
# now, what is this variable?
|
|
1082
|
+
result = None
|
|
1083
|
+
|
|
1014
1084
|
if last_labels and all(isinstance(label, (FuncIn, FuncOut)) for label in last_labels):
|
|
1015
1085
|
# create a dummy result and dump it to the cache
|
|
1016
1086
|
func_type = Function([], [])
|
|
@@ -1049,22 +1119,8 @@ class SimpleSolver:
|
|
|
1049
1119
|
for node in nodes:
|
|
1050
1120
|
solution[node.typevar] = result
|
|
1051
1121
|
|
|
1052
|
-
elif
|
|
1053
|
-
# this is a
|
|
1054
|
-
lower_bound = Bottom_
|
|
1055
|
-
upper_bound = Top_
|
|
1056
|
-
|
|
1057
|
-
for node in nodes:
|
|
1058
|
-
lower_bound = self.join(lower_bound, node.lower_bound)
|
|
1059
|
-
upper_bound = self.meet(upper_bound, node.upper_bound)
|
|
1060
|
-
# TODO: Support variables that are accessed via differently sized pointers
|
|
1061
|
-
|
|
1062
|
-
result = lower_bound if not isinstance(lower_bound, BottomType) else upper_bound
|
|
1063
|
-
for node in nodes:
|
|
1064
|
-
solution[node.typevar] = result
|
|
1065
|
-
self._solution_cache[node.typevar] = result
|
|
1066
|
-
|
|
1067
|
-
else:
|
|
1122
|
+
elif path_and_successors:
|
|
1123
|
+
# maybe this is a pointer to a struct?
|
|
1068
1124
|
if len(nodes) == 1:
|
|
1069
1125
|
the_node = next(iter(nodes))
|
|
1070
1126
|
if (
|
|
@@ -1136,6 +1192,21 @@ class SimpleSolver:
|
|
|
1136
1192
|
for node in nodes:
|
|
1137
1193
|
solution[node.typevar] = result
|
|
1138
1194
|
|
|
1195
|
+
if not path_and_successors or result in {Top_, None}:
|
|
1196
|
+
# this is probably a primitive variable
|
|
1197
|
+
lower_bound = Bottom_
|
|
1198
|
+
upper_bound = Top_
|
|
1199
|
+
|
|
1200
|
+
for node in nodes:
|
|
1201
|
+
lower_bound = self.join(lower_bound, node.lower_bound)
|
|
1202
|
+
upper_bound = self.meet(upper_bound, node.upper_bound)
|
|
1203
|
+
# TODO: Support variables that are accessed via differently sized pointers
|
|
1204
|
+
|
|
1205
|
+
result = lower_bound if not isinstance(lower_bound, BottomType) else upper_bound
|
|
1206
|
+
for node in nodes:
|
|
1207
|
+
solution[node.typevar] = result
|
|
1208
|
+
self._solution_cache[node.typevar] = result
|
|
1209
|
+
|
|
1139
1210
|
# import pprint
|
|
1140
1211
|
|
|
1141
1212
|
# print("Solution")
|
|
@@ -208,7 +208,7 @@ class Struct(TypeConstant):
|
|
|
208
208
|
|
|
209
209
|
def _hash_fields(self, visited: Set[int]):
|
|
210
210
|
keys = sorted(self.fields.keys())
|
|
211
|
-
tpl = tuple((k, self.fields[k]._hash(visited)) for k in keys)
|
|
211
|
+
tpl = tuple((k, self.fields[k]._hash(visited) if self.fields[k] is not None else None) for k in keys)
|
|
212
212
|
return hash(tpl)
|
|
213
213
|
|
|
214
214
|
@memoize
|
angr/calling_conventions.py
CHANGED
|
@@ -1774,9 +1774,6 @@ class SimCCARMHF(SimCCARM):
|
|
|
1774
1774
|
RETURN_VAL = SimRegArg("r0", 4) # TODO Return val can also include reg r1
|
|
1775
1775
|
ARCH = archinfo.ArchARMHF
|
|
1776
1776
|
|
|
1777
|
-
def next_arg(self, session, arg_type):
|
|
1778
|
-
return SimCC.next_arg(self, session, arg_type)
|
|
1779
|
-
|
|
1780
1777
|
|
|
1781
1778
|
class SimCCARMLinuxSyscall(SimCCSyscall):
|
|
1782
1779
|
# TODO: Make sure all the information is correct
|
angr/engines/pcode/cc.py
CHANGED
angr/engines/successors.py
CHANGED
|
@@ -271,6 +271,12 @@ class SimSuccessors:
|
|
|
271
271
|
self.unsat_successors.append(state)
|
|
272
272
|
elif o.NO_SYMBOLIC_JUMP_RESOLUTION in state.options and state.solver.symbolic(target):
|
|
273
273
|
self.unconstrained_successors.append(state)
|
|
274
|
+
elif o.CALLLESS in state.options and state.history.jumpkind == "Ijk_Call" and state.solver.symbolic(target):
|
|
275
|
+
# If CALLESS is set, even a symbolic call target is allowed, because we don't want to resolve the target
|
|
276
|
+
# anyway
|
|
277
|
+
# The actual state will be fixed up later during `VEXMixin.process_successors`
|
|
278
|
+
self.successors.append(state)
|
|
279
|
+
self.flat_successors.append(state)
|
|
274
280
|
elif not state.solver.symbolic(target) and not state.history.jumpkind.startswith("Ijk_Sys"):
|
|
275
281
|
# a successor with a concrete IP, and it's not a syscall
|
|
276
282
|
self.successors.append(state)
|
|
@@ -899,7 +899,8 @@ class PropagatorAILState(PropagatorState):
|
|
|
899
899
|
def_ = next(iter(defs))
|
|
900
900
|
if def_ is not None:
|
|
901
901
|
self._expr_used_locs[def_].append(codeloc)
|
|
902
|
-
|
|
902
|
+
# we must consider known future uses of this definition as well
|
|
903
|
+
prop_count = max(len(self._expr_used_locs[def_]), len(self.rda.all_uses.get_uses(def_)))
|
|
903
904
|
else:
|
|
904
905
|
# multiple definitions or no definitions - do not propagate
|
|
905
906
|
return False
|
|
@@ -43,7 +43,6 @@ libc.set_non_returning(
|
|
|
43
43
|
"__longjmp_chk",
|
|
44
44
|
"__siglongjmp_chk",
|
|
45
45
|
)
|
|
46
|
-
libc.add_alias("exit", "_exit", "_Exit")
|
|
47
46
|
|
|
48
47
|
|
|
49
48
|
#
|
|
@@ -6849,6 +6848,9 @@ libc.add_alias("getc", "_IO_getc")
|
|
|
6849
6848
|
libc.add_alias("putc", "_IO_putc")
|
|
6850
6849
|
libc.add_alias("gets", "_IO_gets")
|
|
6851
6850
|
libc.add_alias("puts", "_IO_puts")
|
|
6851
|
+
libc.add_alias("exit", "_exit", "_Exit")
|
|
6852
|
+
libc.add_alias("sprintf", "siprintf")
|
|
6853
|
+
libc.add_alias("snprintf", "sniprintf")
|
|
6852
6854
|
|
|
6853
6855
|
|
|
6854
6856
|
#
|