angr 9.2.133__py3-none-manylinux2014_x86_64.whl → 9.2.135__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 (25) hide show
  1. angr/__init__.py +1 -1
  2. angr/analyses/__init__.py +2 -1
  3. angr/analyses/calling_convention/__init__.py +6 -0
  4. angr/analyses/{calling_convention.py → calling_convention/calling_convention.py} +28 -61
  5. angr/analyses/calling_convention/fact_collector.py +503 -0
  6. angr/analyses/calling_convention/utils.py +57 -0
  7. angr/analyses/cfg/indirect_jump_resolvers/jumptable.py +6 -6
  8. angr/analyses/complete_calling_conventions.py +32 -3
  9. angr/analyses/decompiler/optimization_passes/register_save_area_simplifier.py +0 -6
  10. angr/analyses/decompiler/optimization_passes/stack_canary_simplifier.py +1 -6
  11. angr/analyses/decompiler/optimization_passes/switch_default_case_duplicator.py +0 -6
  12. angr/analyses/decompiler/optimization_passes/win_stack_canary_simplifier.py +0 -6
  13. angr/analyses/decompiler/structured_codegen/c.py +15 -5
  14. angr/analyses/variable_recovery/engine_vex.py +5 -0
  15. angr/calling_conventions.py +12 -4
  16. angr/knowledge_plugins/functions/function.py +4 -4
  17. angr/knowledge_plugins/functions/function_manager.py +6 -0
  18. angr/storage/memory_mixins/name_resolution_mixin.py +1 -1
  19. angr/utils/bits.py +13 -0
  20. {angr-9.2.133.dist-info → angr-9.2.135.dist-info}/METADATA +6 -6
  21. {angr-9.2.133.dist-info → angr-9.2.135.dist-info}/RECORD +25 -22
  22. {angr-9.2.133.dist-info → angr-9.2.135.dist-info}/LICENSE +0 -0
  23. {angr-9.2.133.dist-info → angr-9.2.135.dist-info}/WHEEL +0 -0
  24. {angr-9.2.133.dist-info → angr-9.2.135.dist-info}/entry_points.txt +0 -0
  25. {angr-9.2.133.dist-info → angr-9.2.135.dist-info}/top_level.txt +0 -0
angr/__init__.py CHANGED
@@ -2,7 +2,7 @@
2
2
  # pylint: disable=wrong-import-position
3
3
  from __future__ import annotations
4
4
 
5
- __version__ = "9.2.133"
5
+ __version__ = "9.2.135"
6
6
 
7
7
  if bytes is str:
8
8
  raise Exception(
angr/analyses/__init__.py CHANGED
@@ -30,7 +30,7 @@ from .variable_recovery import VariableRecovery, VariableRecoveryFast
30
30
  from .identifier import Identifier
31
31
  from .callee_cleanup_finder import CalleeCleanupFinder
32
32
  from .reaching_definitions import ReachingDefinitionsAnalysis
33
- from .calling_convention import CallingConventionAnalysis
33
+ from .calling_convention import CallingConventionAnalysis, FactCollector
34
34
  from .code_tagging import CodeTagging
35
35
  from .stack_pointer_tracker import StackPointerTracker
36
36
  from .dominance_frontier import DominanceFrontier
@@ -84,6 +84,7 @@ __all__ = (
84
84
  "Decompiler",
85
85
  "Disassembly",
86
86
  "DominanceFrontier",
87
+ "FactCollector",
87
88
  "FlirtAnalysis",
88
89
  "ForwardAnalysis",
89
90
  "Identifier",
@@ -0,0 +1,6 @@
1
+ from __future__ import annotations
2
+ from .calling_convention import CallingConventionAnalysis
3
+ from .fact_collector import FactCollector
4
+
5
+
6
+ __all__ = ["CallingConventionAnalysis", "FactCollector"]
@@ -9,7 +9,6 @@ import capstone
9
9
 
10
10
  from pyvex.stmt import Put
11
11
  from pyvex.expr import RdTmp
12
- from archinfo.arch_arm import is_arm_arch, ArchARMHF
13
12
  import ailment
14
13
 
15
14
  from angr.code_location import ExternalCodeLocation
@@ -35,8 +34,9 @@ from angr.knowledge_plugins.variables.variable_access import VariableAccessSort
35
34
  from angr.knowledge_plugins.functions import Function
36
35
  from angr.utils.constants import DEFAULT_STATEMENT
37
36
  from angr import SIM_PROCEDURES
38
- from .reaching_definitions import get_all_definitions
39
- from . import Analysis, register_analysis, ReachingDefinitionsAnalysis
37
+ from angr.analyses import Analysis, register_analysis, ReachingDefinitionsAnalysis
38
+ from angr.analyses.reaching_definitions import get_all_definitions
39
+ from .utils import is_sane_register_variable
40
40
 
41
41
  if TYPE_CHECKING:
42
42
  from angr.knowledge_plugins.cfg import CFGModel
@@ -95,6 +95,8 @@ class CallingConventionAnalysis(Analysis):
95
95
  callsite_block_addr: int | None = None,
96
96
  callsite_insn_addr: int | None = None,
97
97
  func_graph: networkx.DiGraph | None = None,
98
+ input_args: list[SimRegArg | SimStackArg] | None = None,
99
+ retval_size: int | None = None,
98
100
  ):
99
101
  if func is not None and not isinstance(func, Function):
100
102
  func = self.kb.functions[func]
@@ -106,6 +108,15 @@ class CallingConventionAnalysis(Analysis):
106
108
  self.callsite_block_addr = callsite_block_addr
107
109
  self.callsite_insn_addr = callsite_insn_addr
108
110
  self._func_graph = func_graph
111
+ self._input_args = input_args
112
+ self._retval_size = retval_size
113
+
114
+ if self._retval_size is not None and self._input_args is None:
115
+ # retval size will be ignored if input_args is not specified - user error?
116
+ raise TypeError(
117
+ "input_args must be provided to use retval_size. Otherwise please set both input_args and "
118
+ "retval_size to None."
119
+ )
109
120
 
110
121
  self.cc: SimCC | None = None
111
122
  self.prototype: SimTypeFunction | None = None
@@ -308,9 +319,17 @@ class CallingConventionAnalysis(Analysis):
308
319
  # we do not analyze SimProcedures or PLT stubs
309
320
  return None
310
321
 
311
- if not self._variable_manager.has_function_manager(self._function.addr):
312
- l.warning("Please run variable recovery on %r before analyzing its calling convention.", self._function)
313
- return None
322
+ if self._input_args is None:
323
+ if not self._variable_manager.has_function_manager(self._function.addr):
324
+ l.warning("Please run variable recovery on %r before analyzing its calling convention.", self._function)
325
+ return None
326
+ vm = self._variable_manager[self._function.addr]
327
+ retval_size = vm.ret_val_size
328
+ input_variables = vm.input_variables()
329
+ input_args = self._args_from_vars(input_variables, vm)
330
+ else:
331
+ input_args = self._input_args
332
+ retval_size = self._retval_size
314
333
 
315
334
  # check if this function is a variadic function
316
335
  if self.project.arch.name == "AMD64":
@@ -319,11 +338,6 @@ class CallingConventionAnalysis(Analysis):
319
338
  is_variadic = False
320
339
  fixed_args = None
321
340
 
322
- vm = self._variable_manager[self._function.addr]
323
-
324
- input_variables = vm.input_variables()
325
- input_args = self._args_from_vars(input_variables, vm)
326
-
327
341
  # TODO: properly determine sp_delta
328
342
  sp_delta = self.project.arch.bytes if self.project.arch.call_pushes_ret else 0
329
343
 
@@ -342,7 +356,7 @@ class CallingConventionAnalysis(Analysis):
342
356
  args = args[:fixed_args]
343
357
 
344
358
  # guess the type of the return value -- it's going to be a wild guess...
345
- ret_type = self._guess_retval_type(cc, vm.ret_val_size)
359
+ ret_type = self._guess_retval_type(cc, retval_size)
346
360
  if self._function.name == "main" and self.project.arch.bits == 64 and isinstance(ret_type, SimTypeLongLong):
347
361
  # hack - main must return an int even in 64-bit binaries
348
362
  ret_type = SimTypeInt()
@@ -698,14 +712,14 @@ class CallingConventionAnalysis(Analysis):
698
712
  args.add(arg)
699
713
  elif isinstance(variable, SimRegisterVariable):
700
714
  # a register variable, convert it to a register argument
701
- if not self._is_sane_register_variable(variable, def_cc=def_cc):
715
+ if not is_sane_register_variable(self.project.arch, variable.reg, variable.size, def_cc=def_cc):
702
716
  continue
703
- reg_name = self.project.arch.translate_register_name(variable.reg, size=variable.size)
704
717
  if self.project.arch.name in {"AMD64", "X86"} and variable.size < self.project.arch.bytes:
705
718
  # use complete registers on AMD64 and X86
706
719
  reg_name = self.project.arch.translate_register_name(variable.reg, size=self.project.arch.bytes)
707
720
  arg = SimRegArg(reg_name, self.project.arch.bytes)
708
721
  else:
722
+ reg_name = self.project.arch.translate_register_name(variable.reg, size=variable.size)
709
723
  arg = SimRegArg(reg_name, variable.size)
710
724
  args.add(arg)
711
725
 
@@ -748,53 +762,6 @@ class CallingConventionAnalysis(Analysis):
748
762
 
749
763
  return args.difference(restored_reg_vars)
750
764
 
751
- def _is_sane_register_variable(self, variable: SimRegisterVariable, def_cc: SimCC | None = None) -> bool:
752
- """
753
- Filters all registers that are surly not members of function arguments.
754
- This can be seen as a workaround, since VariableRecoveryFast sometimes gives input variables of cc_ndep (which
755
- is a VEX-specific register) :-(
756
-
757
- :param variable: The variable to test.
758
- :return: True if it is an acceptable function argument, False otherwise.
759
- :rtype: bool
760
- """
761
-
762
- arch = self.project.arch
763
- arch_name = arch.name
764
- if ":" in arch_name:
765
- # for pcode architectures, we only leave registers that are known to be used as input arguments
766
- if def_cc is not None:
767
- return arch.translate_register_name(variable.reg, size=variable.size) in def_cc.ARG_REGS
768
- return True
769
-
770
- # VEX
771
- if arch_name == "AARCH64":
772
- return 16 <= variable.reg < 80 # x0-x7
773
-
774
- if arch_name == "AMD64":
775
- return 24 <= variable.reg < 40 or 64 <= variable.reg < 104 # rcx, rdx # rsi, rdi, r8, r9, r10
776
- # 224 <= variable.reg < 480) # xmm0-xmm7
777
-
778
- if is_arm_arch(arch):
779
- if isinstance(arch, ArchARMHF):
780
- return 8 <= variable.reg < 24 or 128 <= variable.reg < 160 # r0 - 32 # s0 - s7, or d0 - d4
781
- return 8 <= variable.reg < 24 # r0-r3
782
-
783
- if arch_name == "MIPS32":
784
- return 24 <= variable.reg < 40 # a0-a3
785
-
786
- if arch_name == "MIPS64":
787
- return 48 <= variable.reg < 80 or 112 <= variable.reg < 208 # a0-a3 or t4-t7
788
-
789
- if arch_name == "PPC32":
790
- return 28 <= variable.reg < 60 # r3-r10
791
-
792
- if arch_name == "X86":
793
- return 8 <= variable.reg < 24 or 160 <= variable.reg < 288 # eax, ebx, ecx, edx # xmm0-xmm7
794
-
795
- l.critical("Unsupported architecture %s.", arch.name)
796
- return True
797
-
798
765
  def _reorder_args(self, args: list[SimRegArg | SimStackArg], cc: SimCC) -> list[SimRegArg | SimStackArg]:
799
766
  """
800
767
  Reorder arguments according to the calling convention identified.