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.

Files changed (45) hide show
  1. angr/__init__.py +1 -1
  2. angr/analyses/cfg/cfg_base.py +20 -10
  3. angr/analyses/cfg/indirect_jump_resolvers/amd64_elf_got.py +1 -1
  4. angr/analyses/cfg/indirect_jump_resolvers/arm_elf_fast.py +89 -32
  5. angr/analyses/cfg/indirect_jump_resolvers/jumptable.py +276 -133
  6. angr/analyses/complete_calling_conventions.py +1 -1
  7. angr/analyses/decompiler/ail_simplifier.py +20 -0
  8. angr/analyses/decompiler/block_io_finder.py +293 -0
  9. angr/analyses/decompiler/block_similarity.py +190 -0
  10. angr/analyses/decompiler/callsite_maker.py +5 -0
  11. angr/analyses/decompiler/clinic.py +103 -1
  12. angr/analyses/decompiler/decompilation_cache.py +2 -0
  13. angr/analyses/decompiler/decompiler.py +21 -4
  14. angr/analyses/decompiler/optimization_passes/__init__.py +6 -0
  15. angr/analyses/decompiler/optimization_passes/code_motion.py +361 -0
  16. angr/analyses/decompiler/optimization_passes/optimization_pass.py +1 -0
  17. angr/analyses/decompiler/optimization_passes/stack_canary_simplifier.py +30 -18
  18. angr/analyses/decompiler/optimization_passes/switch_default_case_duplicator.py +110 -0
  19. angr/analyses/decompiler/peephole_optimizations/bswap.py +53 -2
  20. angr/analyses/decompiler/peephole_optimizations/eager_eval.py +20 -1
  21. angr/analyses/decompiler/structured_codegen/c.py +76 -41
  22. angr/analyses/decompiler/structuring/phoenix.py +41 -9
  23. angr/analyses/decompiler/utils.py +13 -4
  24. angr/analyses/propagator/engine_ail.py +3 -0
  25. angr/analyses/reaching_definitions/engine_ail.py +3 -0
  26. angr/analyses/reaching_definitions/reaching_definitions.py +7 -0
  27. angr/analyses/stack_pointer_tracker.py +60 -10
  28. angr/analyses/typehoon/simple_solver.py +95 -24
  29. angr/analyses/typehoon/typeconsts.py +1 -1
  30. angr/calling_conventions.py +0 -3
  31. angr/engines/pcode/cc.py +1 -1
  32. angr/engines/successors.py +6 -0
  33. angr/knowledge_plugins/propagations/states.py +2 -1
  34. angr/procedures/definitions/glibc.py +3 -1
  35. angr/procedures/definitions/parse_win32json.py +2135 -383
  36. angr/procedures/definitions/wdk_ntoskrnl.py +956 -0
  37. angr/sim_type.py +53 -13
  38. angr/utils/library.py +2 -2
  39. {angr-9.2.92.dist-info → angr-9.2.94.dist-info}/METADATA +6 -6
  40. {angr-9.2.92.dist-info → angr-9.2.94.dist-info}/RECORD +44 -41
  41. {angr-9.2.92.dist-info → angr-9.2.94.dist-info}/WHEEL +1 -1
  42. angr/procedures/definitions/wdk_ntdll.py +0 -994
  43. {angr-9.2.92.dist-info → angr-9.2.94.dist-info}/LICENSE +0 -0
  44. {angr-9.2.92.dist-info → angr-9.2.94.dist-info}/entry_points.txt +0 -0
  45. {angr-9.2.92.dist-info → angr-9.2.94.dist-info}/top_level.txt +0 -0
angr/__init__.py CHANGED
@@ -1,7 +1,7 @@
1
1
  # pylint: disable=wildcard-import
2
2
  # pylint: disable=wrong-import-position
3
3
 
4
- __version__ = "9.2.92"
4
+ __version__ = "9.2.94"
5
5
 
6
6
  if bytes is str:
7
7
  raise Exception(
@@ -8,7 +8,7 @@ from sortedcontainers import SortedDict
8
8
 
9
9
  import pyvex
10
10
  from claripy.utils.orderedset import OrderedSet
11
- from cle import ELF, PE, Blob, TLSObject, MachO, ExternObject, KernelObject, FunctionHintSource, Hex, Coff
11
+ from cle import ELF, PE, Blob, TLSObject, MachO, ExternObject, KernelObject, FunctionHintSource, Hex, Coff, SRec
12
12
  from cle.backends import NamedRegion
13
13
  import archinfo
14
14
  from archinfo.arch_soot import SootAddressDescriptor
@@ -748,19 +748,29 @@ class CFGBase(Analysis):
748
748
  for b in binaries:
749
749
  if isinstance(b, ELF):
750
750
  # If we have sections, we get result from sections
751
+ sections = []
751
752
  if not force_segment and b.sections:
752
753
  # Get all executable sections
753
754
  for section in b.sections:
754
755
  if section.is_executable:
755
756
  tpl = (section.min_addr, section.max_addr + 1)
756
- memory_regions.append(tpl)
757
-
758
- else:
759
- # Get all executable segments
760
- for segment in b.segments:
761
- if segment.is_executable:
762
- tpl = (segment.min_addr, segment.max_addr + 1)
763
- memory_regions.append(tpl)
757
+ sections.append(tpl)
758
+ memory_regions += sections
759
+
760
+ segments = []
761
+ # Get all executable segments
762
+ for segment in b.segments:
763
+ if segment.is_executable:
764
+ tpl = (segment.min_addr, segment.max_addr + 1)
765
+ segments.append(tpl)
766
+ if sections and segments:
767
+ # are there executable segments with no sections inside?
768
+ for segment in segments:
769
+ for section in sections:
770
+ if segment[0] <= section[0] < segment[1]:
771
+ break
772
+ else:
773
+ memory_regions.append(segment)
764
774
 
765
775
  elif isinstance(b, (Coff, PE)):
766
776
  for section in b.sections:
@@ -778,7 +788,7 @@ class CFGBase(Analysis):
778
788
  tpl = (section.min_addr, section.max_addr + 1)
779
789
  memory_regions.append(tpl)
780
790
 
781
- elif isinstance(b, Hex):
791
+ elif isinstance(b, (Hex, SRec)):
782
792
  if b.regions:
783
793
  for region_addr, region_size in b.regions:
784
794
  memory_regions.append((region_addr, region_addr + region_size))
@@ -18,7 +18,7 @@ class AMD64ElfGotResolver(IndirectJumpResolver):
18
18
  super().__init__(project, timeless=True)
19
19
 
20
20
  def filter(self, cfg, addr, func_addr, block, jumpkind):
21
- if jumpkind != "Ijk_Call":
21
+ if not (jumpkind == "Ijk_Call" or (jumpkind == "Ijk_Boring" and addr == func_addr)):
22
22
  return False
23
23
  return True
24
24
 
@@ -12,11 +12,7 @@ _l = logging.getLogger(name=__name__)
12
12
 
13
13
  class ArmElfFastResolver(IndirectJumpResolver):
14
14
  """
15
- Resolves the indirect jump in ARM ELF binaries where all internal function calls are performed in the following
16
- manner::
17
-
18
- ldr r3, [pc+#0x124] ; load a constant from the constant_pool
19
- blx r3
15
+ Resolves indirect jumps in ARM ELF binaries
20
16
  """
21
17
 
22
18
  def __init__(self, project):
@@ -29,6 +25,89 @@ class ArmElfFastResolver(IndirectJumpResolver):
29
25
  return False
30
26
  return True
31
27
 
28
+ def _resolve_default(self, stmt, block, source, cfg, blade):
29
+ """
30
+ Resolves the indirect jump in ARM ELF binaries where all internal function calls are performed in the following
31
+ manner::
32
+
33
+ ldr r3, [pc+#0x124] ; load a constant from the constant_pool
34
+ blx r3
35
+ """
36
+
37
+ if not isinstance(stmt.data, pyvex.IRExpr.Load):
38
+ return False, []
39
+ if not isinstance(stmt.data.addr, pyvex.IRExpr.Const):
40
+ return False, []
41
+ load_addr = stmt.data.addr.con.value
42
+ load_size = stmt.data.result_size(block.tyenv) // 8
43
+ endness = archinfo.Endness.BE if stmt.data.endness == "Iend_BE" else archinfo.Endness.LE
44
+
45
+ # the next statement should be the default exit
46
+ next_target = next(iter(blade.slice.successors(source)))
47
+
48
+ if not (next_target[0] == block.addr and next_target[1] == DEFAULT_STATEMENT):
49
+ return False, []
50
+ next_tmp = block.next
51
+ if next_tmp.tmp != stmt.tmp:
52
+ return False, []
53
+
54
+ # load the address to jump to
55
+ try:
56
+ target_addr = self.project.loader.memory.unpack_word(load_addr, size=load_size, endness=endness)
57
+ if cfg.tag == "CFGFast":
58
+ cfg._seg_list.occupy(load_addr, load_size, "pointer-array")
59
+ except KeyError:
60
+ return False, []
61
+
62
+ return True, [target_addr]
63
+
64
+ def _resolve_put(self, stmt, block, source, cfg, blade):
65
+ """
66
+ Resolves the indirect jump in ARM ELF binaries where all internal function calls are performed in the following
67
+ manner::
68
+
69
+ add ip, pc, #0x100000
70
+ add ip, ip, #0x1e000
71
+ ldr pc, [ip,#0x884]!
72
+ """
73
+
74
+ # Get the value of r12 register
75
+ if not isinstance(stmt.data, pyvex.IRExpr.Const):
76
+ return False, []
77
+ if not self.project.arch.register_names[stmt.offset] == "r12":
78
+ return False, []
79
+ load_addr = stmt.data.con.value
80
+ load_size = stmt.data.result_size(block.tyenv) // 8
81
+ endness = self.project.arch.default_endness
82
+
83
+ count = 0
84
+ for next_stmt in block.statements:
85
+ if (
86
+ isinstance(next_stmt, pyvex.IRStmt.WrTmp)
87
+ and isinstance(next_stmt.data, pyvex.IRExpr.Binop)
88
+ and "Add" in next_stmt.data.op
89
+ ):
90
+ load_addr += next_stmt.constants[0].value
91
+ count += 1
92
+
93
+ if count != 2:
94
+ return False, []
95
+
96
+ next_target = next(iter(blade.slice.successors(source)))
97
+
98
+ if not next_target[0] == block.addr:
99
+ return False, []
100
+
101
+ # load the address to jump to
102
+ try:
103
+ target_addr = self.project.loader.memory.unpack_word(load_addr, size=load_size, endness=endness)
104
+ if cfg.tag == "CFGFast":
105
+ cfg._seg_list.occupy(load_addr, load_size, "pointer-array")
106
+ except KeyError:
107
+ return False, []
108
+
109
+ return True, [target_addr]
110
+
32
111
  def resolve( # pylint:disable=unused-argument
33
112
  self, cfg, addr, func_addr, block, jumpkind, func_graph_complete: bool = True, **kwargs
34
113
  ):
@@ -64,31 +143,9 @@ class ArmElfFastResolver(IndirectJumpResolver):
64
143
  return False, []
65
144
 
66
145
  stmt = block.statements[stmt_idx]
67
- if not isinstance(stmt, pyvex.IRStmt.WrTmp):
146
+ if isinstance(stmt, pyvex.IRStmt.WrTmp):
147
+ return self._resolve_default(stmt, block, source, cfg, b)
148
+ elif isinstance(stmt, pyvex.IRStmt.Put):
149
+ return self._resolve_put(stmt, block, source, cfg, b)
150
+ else:
68
151
  return False, []
69
- if not isinstance(stmt.data, pyvex.IRExpr.Load):
70
- return False, []
71
- if not isinstance(stmt.data.addr, pyvex.IRExpr.Const):
72
- return False, []
73
- load_addr = stmt.data.addr.con.value
74
- load_size = stmt.data.result_size(block.tyenv) // 8
75
- endness = archinfo.Endness.BE if stmt.data.endness == "Iend_BE" else archinfo.Endness.LE
76
-
77
- # the next statement should be the default exit
78
- next_target = next(iter(b.slice.successors(source)))
79
-
80
- if not (next_target[0] == block.addr and next_target[1] == DEFAULT_STATEMENT):
81
- return False, []
82
- next_tmp = block.next
83
- if next_tmp.tmp != stmt.tmp:
84
- return False, []
85
-
86
- # load the address to jump to
87
- try:
88
- target_addr = self.project.loader.memory.unpack_word(load_addr, size=load_size, endness=endness)
89
- if cfg.tag == "CFGFast":
90
- cfg._seg_list.occupy(load_addr, load_size, "pointer-array")
91
- except KeyError:
92
- return False, []
93
-
94
- return True, [target_addr]