angr 9.2.75__py3-none-win_amd64.whl → 9.2.77__py3-none-win_amd64.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 (51) hide show
  1. angr/__init__.py +1 -1
  2. angr/analyses/cfg/cfg_fast.py +37 -0
  3. angr/analyses/cfg/indirect_jump_resolvers/amd64_pe_iat.py +7 -1
  4. angr/analyses/cfg/indirect_jump_resolvers/x86_pe_iat.py +7 -1
  5. angr/analyses/decompiler/clinic.py +4 -1
  6. angr/analyses/decompiler/condition_processor.py +4 -0
  7. angr/analyses/decompiler/decompiler.py +4 -0
  8. angr/analyses/decompiler/optimization_passes/ite_region_converter.py +4 -3
  9. angr/analyses/decompiler/optimization_passes/multi_simplifier.py +1 -1
  10. angr/analyses/decompiler/structured_codegen/c.py +32 -21
  11. angr/analyses/propagator/engine_ail.py +1 -1
  12. angr/analyses/reaching_definitions/engine_ail.py +3 -6
  13. angr/analyses/reaching_definitions/engine_vex.py +32 -2
  14. angr/analyses/reaching_definitions/function_handler.py +1 -1
  15. angr/analyses/reaching_definitions/rd_initializer.py +6 -6
  16. angr/analyses/reaching_definitions/rd_state.py +9 -11
  17. angr/analyses/typehoon/typevars.py +19 -29
  18. angr/analyses/variable_recovery/irsb_scanner.py +16 -0
  19. angr/analyses/variable_recovery/variable_recovery_fast.py +33 -31
  20. angr/engines/light/engine.py +1 -1
  21. angr/keyed_region.py +19 -3
  22. angr/knowledge_plugins/cfg/cfg_model.py +25 -16
  23. angr/knowledge_plugins/cfg/memory_data.py +1 -1
  24. angr/knowledge_plugins/functions/function.py +8 -0
  25. angr/knowledge_plugins/key_definitions/live_definitions.py +53 -44
  26. angr/knowledge_plugins/key_definitions/liveness.py +102 -34
  27. angr/knowledge_plugins/key_definitions/rd_model.py +4 -4
  28. angr/knowledge_plugins/propagations/states.py +3 -1
  29. angr/knowledge_plugins/variables/variable_manager.py +51 -25
  30. angr/lib/angr_native.dll +0 -0
  31. angr/misc/bug_report.py +2 -2
  32. angr/sim_type.py +46 -0
  33. angr/storage/memory_mixins/__init__.py +3 -2
  34. angr/storage/memory_mixins/paged_memory/paged_memory_multivalue_mixin.py +63 -0
  35. angr/storage/memory_mixins/paged_memory/pages/mv_list_page.py +5 -0
  36. {angr-9.2.75.dist-info → angr-9.2.77.dist-info}/METADATA +6 -6
  37. {angr-9.2.75.dist-info → angr-9.2.77.dist-info}/RECORD +51 -50
  38. tests/analyses/cfg/test_cfgfast.py +21 -0
  39. tests/analyses/decompiler/test_decompiler.py +22 -1
  40. tests/analyses/test_flirt.py +3 -1
  41. tests/analyses/test_identifier.py +2 -0
  42. tests/engines/test_unicorn.py +4 -0
  43. tests/exploration_techniques/test_driller_core.py +4 -0
  44. tests/exploration_techniques/test_oppologist.py +2 -0
  45. tests/exploration_techniques/test_tracer.py +9 -0
  46. tests/procedures/libc/test_string.py +2 -1
  47. tests/sim/options/test_0div.py +2 -0
  48. tests/state_plugins/posix/test_files.py +2 -0
  49. {angr-9.2.75.dist-info → angr-9.2.77.dist-info}/LICENSE +0 -0
  50. {angr-9.2.75.dist-info → angr-9.2.77.dist-info}/WHEEL +0 -0
  51. {angr-9.2.75.dist-info → angr-9.2.77.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.75"
4
+ __version__ = "9.2.77"
5
5
 
6
6
  if bytes is str:
7
7
  raise Exception(
@@ -1017,6 +1017,40 @@ class CFGFast(ForwardAnalysis[CFGNode, CFGNode, CFGJob, int], CFGBase): # pylin
1017
1017
  # no string is found
1018
1018
  return 0
1019
1019
 
1020
+ def _scan_for_printable_widestrings(self, start_addr: int):
1021
+ addr = start_addr
1022
+ sz = []
1023
+ is_sz = True
1024
+
1025
+ # Get data until we meet two null bytes
1026
+ while self._inside_regions(addr):
1027
+ l.debug("Searching address %x", addr)
1028
+ val0 = self._load_a_byte_as_int(addr)
1029
+ if val0 is None:
1030
+ break
1031
+ val1 = self._load_a_byte_as_int(addr + 1)
1032
+ if val1 is None:
1033
+ break
1034
+ if val0 == 0 and val1 == 0:
1035
+ if len(sz) <= 10:
1036
+ is_sz = False
1037
+ break
1038
+ if val0 != 0 and val1 == 0 and val0 in self.PRINTABLES:
1039
+ sz += [val0, val1]
1040
+ addr += 2
1041
+ continue
1042
+
1043
+ is_sz = False
1044
+ break
1045
+
1046
+ if sz and is_sz:
1047
+ l.debug("Got a wide-string of %d wide chars", len(sz))
1048
+ string_length = len(sz) + 2
1049
+ return string_length
1050
+
1051
+ # no wide string is found
1052
+ return 0
1053
+
1020
1054
  def _scan_for_repeating_bytes(self, start_addr, repeating_byte, threshold=2):
1021
1055
  """
1022
1056
  Scan from a given address and determine the occurrences of a given byte.
@@ -1061,6 +1095,9 @@ class CFGFast(ForwardAnalysis[CFGNode, CFGNode, CFGJob, int], CFGBase): # pylin
1061
1095
 
1062
1096
  while True:
1063
1097
  string_length = self._scan_for_printable_strings(start_addr)
1098
+ if string_length == 0:
1099
+ string_length = self._scan_for_printable_widestrings(start_addr)
1100
+
1064
1101
  if string_length:
1065
1102
  self._seg_list.occupy(start_addr, string_length, "string")
1066
1103
  start_addr += string_length
@@ -22,7 +22,13 @@ class AMD64PeIatResolver(IndirectJumpResolver):
22
22
  if jumpkind not in {"Ijk_Call", "Ijk_Boring"}:
23
23
  return False
24
24
 
25
- opnd = self.project.factory.block(addr).capstone.insns[-1].insn.operands[0]
25
+ insns = self.project.factory.block(addr).capstone.insns
26
+ if not insns:
27
+ return False
28
+ if not insns[-1].insn.operands:
29
+ return False
30
+
31
+ opnd = insns[-1].insn.operands[0]
26
32
  # Must be of the form: call qword ptr [0xABCD]
27
33
  if opnd.type == X86_OP_MEM and opnd.mem.disp and opnd.mem.base == X86_REG_RIP and opnd.mem.index == 0:
28
34
  return True
@@ -22,7 +22,13 @@ class X86PeIatResolver(IndirectJumpResolver):
22
22
  if jumpkind != "Ijk_Call":
23
23
  return False
24
24
 
25
- opnd = self.project.factory.block(addr).capstone.insns[-1].insn.operands[0]
25
+ insns = self.project.factory.block(addr).capstone.insns
26
+ if not insns:
27
+ return False
28
+ if not insns[-1].insn.operands:
29
+ return False
30
+
31
+ opnd = insns[-1].insn.operands[0]
26
32
  # Must be of the form: call ds:0xABCD
27
33
  if opnd.type == X86_OP_MEM and opnd.mem.disp and not opnd.mem.base and not opnd.mem.index:
28
34
  return True
@@ -1399,7 +1399,10 @@ class Clinic(Analysis):
1399
1399
  )
1400
1400
  end_block_ail = ailment.IRSBConverter.convert(end_block.vex, self._ail_manager)
1401
1401
  else:
1402
- end_block_ail = next(iter(b for b in ail_graph if b.addr == end_block_addr))
1402
+ try:
1403
+ end_block_ail = next(iter(b for b in ail_graph if b.addr == end_block_addr))
1404
+ except StopIteration:
1405
+ return None
1403
1406
 
1404
1407
  # last check: if the first instruction of the end block has Sar, then we bail (due to the peephole optimization
1405
1408
  # SarToSignedDiv)
@@ -102,6 +102,7 @@ _ail2claripy_op_mapping = {
102
102
  "Shr": lambda expr, conv, _: _op_with_unified_size(claripy.LShR, conv, expr.operands[0], expr.operands[1]),
103
103
  "Shl": lambda expr, conv, _: _op_with_unified_size(operator.lshift, conv, expr.operands[0], expr.operands[1]),
104
104
  "Sar": lambda expr, conv, _: _op_with_unified_size(operator.rshift, conv, expr.operands[0], expr.operands[1]),
105
+ "Concat": lambda expr, conv, _: claripy.Concat(*[conv(operand) for operand in expr.operands]),
105
106
  # There are no corresponding claripy operations for the following operations
106
107
  "DivMod": lambda expr, _, m: _dummy_bvs(expr, m),
107
108
  "CmpF": lambda expr, _, m: _dummy_bvs(expr, m),
@@ -686,6 +687,9 @@ class ConditionProcessor:
686
687
  if cond_.args[0] is True
687
688
  else ailment.Expr.Const(None, None, False, 1, **tags),
688
689
  "Extract": lambda cond_, tags: self._convert_extract(*cond_.args, tags, memo=memo),
690
+ "ZeroExt": lambda cond_, tags: _binary_op_reduce(
691
+ "Concat", [claripy.BVV(0, cond_.args[0]), cond_.args[1]], tags
692
+ ),
689
693
  }
690
694
 
691
695
  if cond.op in _mapping:
@@ -90,6 +90,7 @@ class Decompiler(Analysis):
90
90
  self.cache: Optional[DecompilationCache] = None
91
91
  self.options_by_class = None
92
92
  self.seq_node = None
93
+ self.unmodified_clinic_graph = None
93
94
 
94
95
  if decompile:
95
96
  self._decompile()
@@ -183,6 +184,9 @@ class Decompiler(Analysis):
183
184
  # the function is empty
184
185
  return
185
186
 
187
+ # expose a copy of the graph before structuring optimizations happen
188
+ # use this graph if you need a reference of exact mapping of instructions to AIL statements
189
+ self.unmodified_clinic_graph = clinic.copy_graph()
186
190
  cond_proc = ConditionProcessor(self.project.arch)
187
191
 
188
192
  clinic.graph = self._run_graph_simplification_passes(
@@ -146,14 +146,15 @@ class ITERegionConverter(OptimizationPass):
146
146
  #
147
147
 
148
148
  new_region_head = region_head.copy()
149
+ addr_obj = true_stmt.src if "ins_addr" in true_stmt.src.tags else true_stmt
149
150
  ternary_expr = ITE(
150
151
  None,
151
152
  region_head.statements[-1].condition,
152
153
  true_stmt.src,
153
154
  false_stmt.src,
154
- ins_addr=true_stmt.src.ins_addr,
155
- vex_block_addr=true_stmt.src.vex_block_addr,
156
- vex_stmt_idx=true_stmt.src.vex_stmt_idx,
155
+ ins_addr=addr_obj.ins_addr,
156
+ vex_block_addr=addr_obj.vex_block_addr,
157
+ vex_stmt_idx=addr_obj.vex_stmt_idx,
157
158
  )
158
159
  new_assignment = true_stmt.copy()
159
160
  new_assignment.src = ternary_expr
@@ -21,7 +21,7 @@ class MultiSimplifierAILEngine(SimplifierAILEngine):
21
21
  if type(operand_0) in [Expr.Convert, Expr.Register]:
22
22
  if isinstance(operand_1, (Expr.Convert, Expr.Register)):
23
23
  if operand_0 == operand_1:
24
- count = Expr.Const(expr.idx, None, 2, 8)
24
+ count = Expr.Const(expr.idx, None, 2, operand_1.bits)
25
25
  return Expr.BinaryOp(expr.idx, "Mul", [operand_1, count], expr.signed, **expr.tags)
26
26
  # 2*x + x = 3*x
27
27
  if Expr.BinaryOp in [type(operand_0), type(operand_1)]:
@@ -12,6 +12,7 @@ from ....sim_type import (
12
12
  SimTypeInt,
13
13
  SimTypeShort,
14
14
  SimTypeChar,
15
+ SimTypeWideChar,
15
16
  SimTypePointer,
16
17
  SimStruct,
17
18
  SimType,
@@ -273,9 +274,6 @@ class CConstruct:
273
274
 
274
275
  last_insn_addr = None
275
276
 
276
- # track all Function Calls for highlighting
277
- used_func_calls = set()
278
-
279
277
  # track all variables so we can tell if this is a declaration or not
280
278
  used_vars = set()
281
279
 
@@ -310,15 +308,11 @@ class CConstruct:
310
308
  CBinaryOp,
311
309
  CUnaryOp,
312
310
  CAssignment,
311
+ CFunctionCall,
313
312
  ),
314
313
  ):
315
314
  if pos_to_node is not None:
316
315
  pos_to_node.add_mapping(pos, len(s), obj)
317
- elif isinstance(obj, CFunctionCall):
318
- if obj not in used_func_calls:
319
- used_func_calls.add(obj)
320
- if pos_to_node is not None:
321
- pos_to_node.add_mapping(pos, len(s), obj)
322
316
 
323
317
  # add (), {}, [], and [20] to mapping for highlighting as well as the full functions name
324
318
  elif isinstance(obj, (CClosingObject, CFunction, CArrayTypeLength, CStructFieldNameDef)):
@@ -1247,15 +1241,15 @@ class CFunctionCall(CStatement, CExpression):
1247
1241
 
1248
1242
  for i, arg in enumerate(self.args):
1249
1243
  if i:
1250
- yield ", ", self
1244
+ yield ", ", None
1251
1245
  yield from CExpression._try_c_repr_chunks(arg)
1252
1246
 
1253
1247
  yield ")", paren
1254
1248
 
1255
1249
  if not self.is_expr and not asexpr:
1256
- yield ";", self
1250
+ yield ";", None
1257
1251
  if not self.returning:
1258
- yield " /* do not return */", self
1252
+ yield " /* do not return */", None
1259
1253
  yield "\n", None
1260
1254
 
1261
1255
 
@@ -2012,14 +2006,14 @@ class CConstant(CExpression):
2012
2006
  return self._type
2013
2007
 
2014
2008
  @staticmethod
2015
- def str_to_c_str(_str):
2009
+ def str_to_c_str(_str, prefix: str = ""):
2016
2010
  repr_str = repr(_str)
2017
2011
  base_str = repr_str[1:-1]
2018
2012
  if repr_str[0] == "'":
2019
2013
  # check if there's double quotes in the body
2020
2014
  if '"' in base_str:
2021
2015
  base_str = base_str.replace('"', '\\"')
2022
- return f'"{base_str}"'
2016
+ return f'{prefix}"{base_str}"'
2023
2017
 
2024
2018
  def c_repr_chunks(self, indent=0, asexpr=False):
2025
2019
  if self.collapsed:
@@ -2045,6 +2039,9 @@ class CConstant(CExpression):
2045
2039
  elif isinstance(self._type, SimTypePointer) and isinstance(self._type.pts_to, SimTypeChar):
2046
2040
  refval = self.reference_values[self._type] # angr.knowledge_plugin.cfg.MemoryData
2047
2041
  yield CConstant.str_to_c_str(refval.content.decode("utf-8")), self
2042
+ elif isinstance(self._type, SimTypePointer) and isinstance(self._type.pts_to, SimTypeWideChar):
2043
+ refval = self.reference_values[self._type] # angr.knowledge_plugin.cfg.MemoryData
2044
+ yield CConstant.str_to_c_str(refval.content.decode("utf_16_le"), prefix="L"), self
2048
2045
  else:
2049
2046
  if isinstance(self.reference_values[self._type], int):
2050
2047
  yield self.fmt_int(self.reference_values[self._type]), self
@@ -2724,6 +2721,9 @@ class CStructuredCodeGenerator(BaseStructuredCodeGenerator, Analysis):
2724
2721
  o_constant, o_terms = extract_terms(expr)
2725
2722
 
2726
2723
  def bail_out():
2724
+ if len(o_terms) == 0:
2725
+ # probably a plain integer, return as is
2726
+ return expr
2727
2727
  result = reduce(
2728
2728
  lambda a1, a2: CBinaryOp("Add", a1, a2, codegen=self),
2729
2729
  (
@@ -3234,15 +3234,26 @@ class CStructuredCodeGenerator(BaseStructuredCodeGenerator, Analysis):
3234
3234
  and expr.bits == self.project.arch.bits
3235
3235
  and expr.value > 0x10000
3236
3236
  and expr.value in self._cfg.memory_data
3237
- and self._cfg.memory_data[expr.value].sort == MemoryDataSort.String
3238
3237
  ):
3239
- type_ = SimTypePointer(SimTypeChar()).with_arch(self.project.arch)
3240
- reference_values[type_] = self._cfg.memory_data[expr.value]
3241
- # is it a constant string?
3242
- if is_in_readonly_segment(self.project, expr.value) or is_in_readonly_section(
3243
- self.project, expr.value
3244
- ):
3245
- inline_string = True
3238
+ md = self._cfg.memory_data[expr.value]
3239
+ if md.sort == MemoryDataSort.String:
3240
+ type_ = SimTypePointer(SimTypeChar().with_arch(self.project.arch)).with_arch(self.project.arch)
3241
+ reference_values[type_] = self._cfg.memory_data[expr.value]
3242
+ # is it a constant string?
3243
+ if is_in_readonly_segment(self.project, expr.value) or is_in_readonly_section(
3244
+ self.project, expr.value
3245
+ ):
3246
+ inline_string = True
3247
+ elif md.sort == MemoryDataSort.UnicodeString:
3248
+ type_ = SimTypePointer(SimTypeWideChar().with_arch(self.project.arch)).with_arch(
3249
+ self.project.arch
3250
+ )
3251
+ reference_values[type_] = self._cfg.memory_data[expr.value]
3252
+ # is it a constant string?
3253
+ if is_in_readonly_segment(self.project, expr.value) or is_in_readonly_section(
3254
+ self.project, expr.value
3255
+ ):
3256
+ inline_string = True
3246
3257
 
3247
3258
  if type_ is None:
3248
3259
  # default to int
@@ -1204,7 +1204,7 @@ class SimEnginePropagatorAIL(
1204
1204
  o1_expr if o1_expr is not None else expr.operands[1],
1205
1205
  ],
1206
1206
  expr.signed,
1207
- bits=o0_expr.bits * 2,
1207
+ bits=expr.bits,
1208
1208
  floating_point=expr.floating_point,
1209
1209
  rounding_mode=expr.rounding_mode,
1210
1210
  **expr.tags,
@@ -118,9 +118,6 @@ class SimEngineRDAIL(
118
118
  def _process_Stmt(self, whitelist=None):
119
119
  super()._process_Stmt(whitelist=whitelist)
120
120
 
121
- if self.state.analysis:
122
- self.state.analysis.model.complete_loc()
123
-
124
121
  def _handle_Stmt(self, stmt):
125
122
  if self.state.analysis:
126
123
  self.state.analysis.stmt_observe(self.stmt_idx, stmt, self.block, self.state, OP_BEFORE)
@@ -801,7 +798,7 @@ class SimEngineRDAIL(
801
798
  elif expr0_v is None and expr1_v is not None:
802
799
  # each value in expr0 >> expr1_v
803
800
  if expr0.count() == 1 and 0 in expr0:
804
- if all(v.concrete for v in expr0[0]):
801
+ if all(v.concrete for v in expr0[0]) and expr1_v.concrete:
805
802
  vs = {
806
803
  (claripy.LShR(v, expr1_v.concrete_value) if v.concrete else self.state.top(bits))
807
804
  for v in expr0[0]
@@ -839,7 +836,7 @@ class SimEngineRDAIL(
839
836
  elif expr0_v is None and expr1_v is not None:
840
837
  # each value in expr0 >> expr1_v
841
838
  if expr0.count() == 1 and 0 in expr0:
842
- if all(v.concrete for v in expr0[0]):
839
+ if all(v.concrete for v in expr0[0]) and expr1_v.concrete:
843
840
  vs = {
844
841
  (claripy.LShR(v, expr1_v.concrete_value) if v.concrete else self.state.top(bits))
845
842
  for v in expr0[0]
@@ -877,7 +874,7 @@ class SimEngineRDAIL(
877
874
  elif expr0_v is None and expr1_v is not None:
878
875
  # each value in expr0 << expr1_v
879
876
  if expr0.count() == 1 and 0 in expr0:
880
- if all(v.concrete for v in expr0[0]):
877
+ if all(v.concrete for v in expr0[0]) and expr1_v.concrete:
881
878
  vs = {((v << expr1_v.concrete_value) if v.concrete else self.state.top(bits)) for v in expr0[0]}
882
879
  r = MultiValues(offset_to_values={0: vs})
883
880
  elif expr0_v is not None and expr1_v is None:
@@ -147,11 +147,11 @@ class SimEngineRDVEX(
147
147
  if self.state.is_heap_address(d):
148
148
  heap_offset = self.state.get_heap_offset(d)
149
149
  if heap_offset is not None:
150
- self.state.add_heap_use(heap_offset, 1, "Iend_BE")
150
+ self.state.add_heap_use(heap_offset, 1)
151
151
  elif self.state.is_stack_address(d):
152
152
  stack_offset = self.state.get_stack_offset(d)
153
153
  if stack_offset is not None:
154
- self.state.add_stack_use(stack_offset, 1, "Iend_BE")
154
+ self.state.add_stack_use(stack_offset, 1)
155
155
 
156
156
  if self.state.exit_observed and reg_offset == self.arch.sp_offset:
157
157
  return
@@ -989,6 +989,34 @@ class SimEngineRDVEX(
989
989
  return MultiValues(claripy.BVV(0, 1))
990
990
  return MultiValues(self.state.top(1))
991
991
 
992
+ def _handle_CmpGT(self, expr):
993
+ arg0, arg1 = expr.args
994
+ expr_0 = self._expr(arg0)
995
+ expr_1 = self._expr(arg1)
996
+
997
+ e0 = expr_0.one_value()
998
+ e1 = expr_1.one_value()
999
+ if e0 is not None and e1 is not None:
1000
+ if not e0.symbolic and not e1.symbolic:
1001
+ return MultiValues(claripy.BVV(1, 1) if e0.concrete_value > e1.concrete_value else claripy.BVV(0, 1))
1002
+ elif e0 is e1:
1003
+ return MultiValues(claripy.BVV(0, 1))
1004
+ return MultiValues(self.state.top(1))
1005
+
1006
+ def _handle_CmpGE(self, expr):
1007
+ arg0, arg1 = expr.args
1008
+ expr_0 = self._expr(arg0)
1009
+ expr_1 = self._expr(arg1)
1010
+
1011
+ e0 = expr_0.one_value()
1012
+ e1 = expr_1.one_value()
1013
+ if e0 is not None and e1 is not None:
1014
+ if not e0.symbolic and not e1.symbolic:
1015
+ return MultiValues(claripy.BVV(1, 1) if e0.concrete_value >= e1.concrete_value else claripy.BVV(0, 1))
1016
+ elif e0 is e1:
1017
+ return MultiValues(claripy.BVV(0, 1))
1018
+ return MultiValues(self.state.top(1))
1019
+
992
1020
  # ppc only
993
1021
  def _handle_CmpORD(self, expr):
994
1022
  arg0, arg1 = expr.args
@@ -1001,6 +1029,8 @@ class SimEngineRDVEX(
1001
1029
 
1002
1030
  if e0 is not None and e1 is not None:
1003
1031
  if not e0.symbolic and not e1.symbolic:
1032
+ e0 = e0.concrete_value
1033
+ e1 = e1.concrete_value
1004
1034
  if e0 < e1:
1005
1035
  return MultiValues(claripy.BVV(0x8, bits))
1006
1036
  elif e0 > e1:
@@ -409,7 +409,7 @@ class FunctionHandler:
409
409
  # translate all the dep atoms into dep defns
410
410
  for effect in data.effects:
411
411
  if effect.sources_defns is None and effect.sources:
412
- effect.sources_defns = set().union(*(set(state.get_definitions(atom)) for atom in effect.sources))
412
+ effect.sources_defns = set().union(*(state.get_definitions(atom) for atom in effect.sources))
413
413
  if not effect.sources_defns:
414
414
  effect.sources_defns = {Definition(atom, ExternalCodeLocation()) for atom in effect.sources}
415
415
  other_input_defns |= effect.sources_defns - all_args_defns
@@ -63,7 +63,7 @@ class RDAStateInitializer:
63
63
  self.initialize_architectural_state(state, func_addr, ex_loc, rtoc_value)
64
64
 
65
65
  if state.analysis is not None:
66
- state.analysis.model.complete_loc()
66
+ state.analysis.model.make_liveness_snapshot()
67
67
 
68
68
  def initialize_all_function_arguments(
69
69
  self,
@@ -147,7 +147,7 @@ class RDAStateInitializer:
147
147
  rtoc_def = Definition(rtoc_atom, ex_loc, tags={InitialValueTag()})
148
148
  state.all_definitions.add(rtoc_def)
149
149
  if state.analysis is not None:
150
- state.analysis.model.add_def(rtoc_def, ex_loc)
150
+ state.analysis.model.add_def(rtoc_def)
151
151
  rtoc = state.annotate_with_def(claripy.BVV(rtoc_value, self.arch.bits), rtoc_def)
152
152
  state.registers.store(offset, rtoc)
153
153
  elif self.arch.name.startswith("MIPS64"):
@@ -156,7 +156,7 @@ class RDAStateInitializer:
156
156
  t9_def = Definition(t9_atom, ex_loc, tags={InitialValueTag()})
157
157
  state.all_definitions.add(t9_def)
158
158
  if state.analysis is not None:
159
- state.analysis.model.add_def(t9_def, ex_loc)
159
+ state.analysis.model.add_def(t9_def)
160
160
  t9 = state.annotate_with_def(claripy.BVV(func_addr, self.arch.bits), t9_def)
161
161
  state.registers.store(offset, t9)
162
162
  elif self.arch.name.startswith("MIPS"):
@@ -167,7 +167,7 @@ class RDAStateInitializer:
167
167
  t9_def = Definition(t9_atom, ex_loc, tags={InitialValueTag()})
168
168
  state.all_definitions.add(t9_def)
169
169
  if state.analysis is not None:
170
- state.analysis.model.add_def(t9_def, ex_loc)
170
+ state.analysis.model.add_def(t9_def)
171
171
  t9 = state.annotate_with_def(claripy.BVV(func_addr, self.arch.bits), t9_def)
172
172
  state.registers.store(t9_offset, t9)
173
173
 
@@ -185,7 +185,7 @@ class RDAStateInitializer:
185
185
  reg_def = Definition(reg_atom, ex_loc, tags={ParameterTag(function=func_addr)})
186
186
  state.all_definitions.add(reg_def)
187
187
  if state.analysis is not None:
188
- state.analysis.model.add_def(reg_def, ex_loc)
188
+ state.analysis.model.add_def(reg_def)
189
189
  if value is None:
190
190
  value = state.top(self.arch.bits)
191
191
  reg = state.annotate_with_def(value, reg_def)
@@ -198,7 +198,7 @@ class RDAStateInitializer:
198
198
  ml_def = Definition(ml_atom, ex_loc, tags={ParameterTag(function=func_addr)})
199
199
  state.all_definitions.add(ml_def)
200
200
  if state.analysis is not None:
201
- state.analysis.model.add_def(ml_def, ex_loc)
201
+ state.analysis.model.add_def(ml_def)
202
202
  ml = state.annotate_with_def(state.top(self.arch.bits), ml_def)
203
203
  stack_address = state.get_stack_address(state.stack_address(arg.stack_offset))
204
204
  state.stack.store(stack_address, ml, endness=self.arch.memory_endness)
@@ -328,7 +328,7 @@ class ReachingDefinitionsState:
328
328
  Overwrite existing definitions w.r.t 'atom' with a dummy definition instance. A dummy definition will not be
329
329
  removed during simplification.
330
330
  """
331
- existing_defs = set(self.live_definitions.get_definitions(atom))
331
+ existing_defs = self.live_definitions.get_definitions(atom)
332
332
 
333
333
  self.live_definitions.kill_definitions(atom)
334
334
 
@@ -347,7 +347,7 @@ class ReachingDefinitionsState:
347
347
  override_codeloc: Optional[CodeLocation] = None,
348
348
  ) -> Tuple[Optional[MultiValues], Set[Definition]]:
349
349
  codeloc = override_codeloc or self.codeloc
350
- existing_defs = set(self.live_definitions.get_definitions(atom))
350
+ existing_defs = self.live_definitions.get_definitions(atom)
351
351
  mv = self.live_definitions.kill_and_add_definition(
352
352
  atom, codeloc, data, dummy=dummy, tags=tags, endness=endness, annotated=annotated
353
353
  )
@@ -417,7 +417,7 @@ class ReachingDefinitionsState:
417
417
  for def_ in existing_defs:
418
418
  self.analysis.model.kill_def(def_)
419
419
  for def_ in defs:
420
- self.analysis.model.add_def(def_, codeloc)
420
+ self.analysis.model.add_def(def_)
421
421
 
422
422
  return mv, defs
423
423
 
@@ -450,8 +450,8 @@ class ReachingDefinitionsState:
450
450
  self.codeloc_uses.add(definition)
451
451
  self.live_definitions.add_register_use_by_def(definition, self.codeloc, expr=expr)
452
452
 
453
- def add_stack_use(self, stack_offset: int, size: int, endness, expr: Optional[Any] = None) -> None:
454
- defs = self.live_definitions.get_stack_definitions(stack_offset, size, endness)
453
+ def add_stack_use(self, stack_offset: int, size: int, expr: Optional[Any] = None) -> None:
454
+ defs = self.live_definitions.get_stack_definitions(stack_offset, size)
455
455
  self.add_stack_use_by_defs(defs, expr=expr)
456
456
 
457
457
  def add_stack_use_by_defs(self, defs: Iterable[Definition], expr: Optional[Any] = None):
@@ -459,8 +459,8 @@ class ReachingDefinitionsState:
459
459
  self.codeloc_uses.add(definition)
460
460
  self.live_definitions.add_stack_use_by_def(definition, self.codeloc, expr=expr)
461
461
 
462
- def add_heap_use(self, heap_offset: int, size: int, endness, expr: Optional[Any] = None) -> None:
463
- defs = self.live_definitions.get_heap_definitions(heap_offset, size, endness)
462
+ def add_heap_use(self, heap_offset: int, size: int, expr: Optional[Any] = None) -> None:
463
+ defs = self.live_definitions.get_heap_definitions(heap_offset, size)
464
464
  self.add_heap_use_by_defs(defs, expr=expr)
465
465
 
466
466
  def add_heap_use_by_defs(self, defs: Iterable[Definition], expr: Optional[Any] = None):
@@ -477,10 +477,8 @@ class ReachingDefinitionsState:
477
477
  self.codeloc_uses.add(definition)
478
478
  self.live_definitions.add_memory_use_by_def(definition, self.codeloc, expr=expr)
479
479
 
480
- def get_definitions(
481
- self, atom: Union[Atom, Definition, Iterable[Atom], Iterable[Definition]]
482
- ) -> Iterable[Definition]:
483
- yield from self.live_definitions.get_definitions(atom)
480
+ def get_definitions(self, atom: Union[Atom, Definition, Iterable[Atom], Iterable[Definition]]) -> Set[Definition]:
481
+ return self.live_definitions.get_definitions(atom)
484
482
 
485
483
  def get_values(self, spec: Union[Atom, Definition, Iterable[Atom]]) -> Optional[MultiValues]:
486
484
  return self.live_definitions.get_values(spec)
@@ -1,9 +1,7 @@
1
1
  # pylint:disable=missing-class-docstring
2
- from typing import Dict, Any, Optional, TYPE_CHECKING
2
+ from typing import Dict, Any, Optional, Set, TYPE_CHECKING
3
3
  from itertools import count
4
4
 
5
- from ...utils.cowdict import ChainMapCOW
6
-
7
5
  if TYPE_CHECKING:
8
6
  from angr.sim_variable import SimVariable
9
7
 
@@ -340,25 +338,20 @@ class DerivedTypeVariable(TypeVariable):
340
338
 
341
339
 
342
340
  class TypeVariables:
343
- __slots__ = ("_typevars",)
341
+ __slots__ = (
342
+ "_typevars",
343
+ "_last_typevars",
344
+ )
344
345
 
345
346
  def __init__(self):
346
- self._typevars: Dict["SimVariable", TypeVariable] = ChainMapCOW(collapse_threshold=25)
347
-
348
- def merge(self, tvs):
349
- merged = TypeVariables()
350
-
351
- # TODO: Replace this with a real lattice-based merging
352
- merged._typevars = self._typevars.copy()
353
- if tvs._typevars:
354
- merged._typevars = merged._typevars.clean()
355
- merged._typevars.update(tvs._typevars)
356
-
357
- return merged
347
+ self._typevars: Dict["SimVariable", Set[TypeVariable]] = {}
348
+ self._last_typevars: Dict[SimVariable, TypeVariable] = {}
358
349
 
359
350
  def copy(self):
360
351
  copied = TypeVariables()
361
- copied._typevars = self._typevars.copy()
352
+ for var, typevars in self._typevars.items():
353
+ copied._typevars[var] = typevars.copy()
354
+ copied._last_typevars = self._last_typevars.copy()
362
355
  return copied
363
356
 
364
357
  def __repr__(self):
@@ -369,27 +362,24 @@ class TypeVariables:
369
362
  return "{TypeVars: %d items}" % len(self._typevars)
370
363
 
371
364
  def add_type_variable(self, var: "SimVariable", codeloc, typevar: TypeVariable): # pylint:disable=unused-argument
372
- # if var not in self._typevars:
373
- # self._typevars[var] = { }
374
-
375
- # assert codeloc not in self._typevars[var]
376
- # self._typevars[var][codeloc] = typevar
377
- self._typevars = self._typevars.clean()
378
- self._typevars[var] = typevar
365
+ if var not in self._typevars:
366
+ self._typevars[var] = set()
367
+ elif typevar in self._typevars[var]:
368
+ return
369
+ self._typevars[var].add(typevar)
370
+ self._last_typevars[var] = typevar
379
371
 
380
372
  def get_type_variable(self, var, codeloc): # pylint:disable=unused-argument
381
- return self._typevars[var] # [codeloc]
373
+ return self._last_typevars[var]
382
374
 
383
375
  def has_type_variable_for(self, var: "SimVariable", codeloc): # pylint:disable=unused-argument
384
- if var not in self._typevars:
385
- return False
386
- return True
376
+ return var in self._typevars
387
377
  # if codeloc not in self._typevars[var]:
388
378
  # return False
389
379
  # return True
390
380
 
391
381
  def __getitem__(self, var):
392
- return self._typevars[var]
382
+ return self._last_typevars[var]
393
383
 
394
384
  def __contains__(self, var):
395
385
  return var in self._typevars
@@ -97,6 +97,22 @@ class VEXIRSBScanner(SimEngineLightVEXMixin):
97
97
  if tmp_src in self.tmps_with_64bit_regs:
98
98
  self.tmps_converted_to_32bit.add(tmp_src)
99
99
 
100
+ def _handle_16HLto32(self, expr):
101
+ pass
102
+
103
+ def _handle_Cmp_v(self, expr, _vector_size, _vector_count):
104
+ pass
105
+
106
+ _handle_CmpEQ_v = _handle_Cmp_v
107
+ _handle_CmpNE_v = _handle_Cmp_v
108
+ _handle_CmpLE_v = _handle_Cmp_v
109
+ _handle_CmpLT_v = _handle_Cmp_v
110
+ _handle_CmpGE_v = _handle_Cmp_v
111
+ _handle_CmpGT_v = _handle_Cmp_v
112
+
113
+ def _handle_ExpCmpNE64(self, expr):
114
+ pass
115
+
100
116
  def _handle_CCall(self, expr):
101
117
  pass
102
118