angr 9.2.84__py3-none-win_amd64.whl → 9.2.85__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 (58) hide show
  1. angr/__init__.py +1 -1
  2. angr/analyses/cfg/cfg_base.py +6 -1
  3. angr/analyses/cfg/cfg_fast.py +32 -10
  4. angr/analyses/decompiler/clinic.py +204 -4
  5. angr/analyses/decompiler/condition_processor.py +8 -2
  6. angr/analyses/decompiler/decompiler.py +19 -17
  7. angr/analyses/decompiler/goto_manager.py +34 -51
  8. angr/analyses/decompiler/optimization_passes/__init__.py +5 -5
  9. angr/analyses/decompiler/optimization_passes/div_simplifier.py +2 -0
  10. angr/analyses/decompiler/optimization_passes/lowered_switch_simplifier.py +1 -1
  11. angr/analyses/decompiler/optimization_passes/mod_simplifier.py +2 -0
  12. angr/analyses/decompiler/optimization_passes/multi_simplifier.py +2 -0
  13. angr/analyses/decompiler/optimization_passes/optimization_pass.py +131 -3
  14. angr/analyses/decompiler/optimization_passes/ret_deduplicator.py +3 -3
  15. angr/analyses/decompiler/optimization_passes/return_duplicator.py +519 -0
  16. angr/analyses/decompiler/peephole_optimizations/constant_derefs.py +14 -2
  17. angr/analyses/decompiler/region_identifier.py +8 -2
  18. angr/analyses/decompiler/region_simplifiers/goto.py +5 -4
  19. angr/analyses/decompiler/structured_codegen/c.py +33 -1
  20. angr/analyses/decompiler/structuring/phoenix.py +3 -1
  21. angr/analyses/decompiler/structuring/structurer_nodes.py +11 -5
  22. angr/analyses/decompiler/utils.py +50 -0
  23. angr/analyses/disassembly.py +10 -3
  24. angr/analyses/propagator/engine_ail.py +125 -0
  25. angr/analyses/reaching_definitions/engine_ail.py +36 -2
  26. angr/analyses/reaching_definitions/rd_initializer.py +15 -1
  27. angr/analyses/reaching_definitions/rd_state.py +9 -4
  28. angr/analyses/stack_pointer_tracker.py +10 -17
  29. angr/analyses/variable_recovery/engine_ail.py +27 -1
  30. angr/angrdb/serializers/loader.py +10 -3
  31. angr/calling_conventions.py +2 -0
  32. angr/engines/pcode/behavior.py +7 -2
  33. angr/engines/pcode/cc.py +1 -0
  34. angr/engines/pcode/emulate.py +144 -104
  35. angr/engines/pcode/lifter.py +135 -79
  36. angr/knowledge_plugins/functions/function_manager.py +5 -3
  37. angr/knowledge_plugins/propagations/states.py +14 -0
  38. angr/lib/angr_native.dll +0 -0
  39. angr/procedures/cgc/deallocate.py +5 -2
  40. angr/procedures/posix/gethostbyname.py +23 -8
  41. angr/project.py +4 -0
  42. angr/simos/__init__.py +2 -0
  43. angr/simos/simos.py +1 -0
  44. angr/simos/snimmuc_nxp.py +152 -0
  45. angr/state_plugins/history.py +3 -1
  46. angr/utils/graph.py +20 -18
  47. {angr-9.2.84.dist-info → angr-9.2.85.dist-info}/METADATA +9 -8
  48. {angr-9.2.84.dist-info → angr-9.2.85.dist-info}/RECORD +57 -55
  49. tests/analyses/cfg/test_cfg_rust_got_resolution.py +2 -1
  50. tests/analyses/cfg/test_jumptables.py +2 -1
  51. tests/analyses/decompiler/test_decompiler.py +130 -103
  52. tests/engines/pcode/test_emulate.py +607 -0
  53. tests/serialization/test_db.py +30 -0
  54. angr/analyses/decompiler/optimization_passes/eager_returns.py +0 -285
  55. {angr-9.2.84.dist-info → angr-9.2.85.dist-info}/LICENSE +0 -0
  56. {angr-9.2.84.dist-info → angr-9.2.85.dist-info}/WHEEL +0 -0
  57. {angr-9.2.84.dist-info → angr-9.2.85.dist-info}/entry_points.txt +0 -0
  58. {angr-9.2.84.dist-info → angr-9.2.85.dist-info}/top_level.txt +0 -0
@@ -5,13 +5,11 @@
5
5
  # - Fix default_exit_target
6
6
  # - Fix/remove NotImplementedError's
7
7
 
8
- import copy
9
8
  import logging
10
- from typing import Union, Optional, Iterable, Sequence, Tuple, List
9
+ from typing import Union, Optional, Iterable, Sequence, Tuple
11
10
 
12
11
  import archinfo
13
12
  from archinfo import ArchARM, ArchPcode
14
- import pypcode
15
13
  import cle
16
14
  from cachetools import LRUCache
17
15
 
@@ -28,6 +26,13 @@ from ...errors import SimEngineError, SimTranslationError, SimError
28
26
  from ... import sim_options as o
29
27
  from ...block import DisassemblerBlock, DisassemblerInsn
30
28
 
29
+
30
+ try:
31
+ import pypcode
32
+ except ImportError:
33
+ pypcode = None
34
+
35
+
31
36
  l = logging.getLogger(__name__)
32
37
 
33
38
  IRSB_MAX_SIZE = 400
@@ -54,7 +59,7 @@ class ExitStatement:
54
59
 
55
60
  class PcodeDisassemblerBlock(DisassemblerBlock):
56
61
  """
57
- Helper class to represent a block of dissassembled target architecture
62
+ Helper class to represent a block of disassembled target architecture
58
63
  instructions
59
64
  """
60
65
 
@@ -73,15 +78,15 @@ class PcodeDisassemblerInsn(DisassemblerInsn):
73
78
 
74
79
  @property
75
80
  def address(self) -> int:
76
- return self.insn.address.offset
81
+ return self.insn.addr.offset
77
82
 
78
83
  @property
79
84
  def mnemonic(self) -> str:
80
- return self.insn.asm_mnem
85
+ return self.insn.mnem
81
86
 
82
87
  @property
83
88
  def op_str(self) -> str:
84
- return self.insn.asm_body
89
+ return self.insn.body
85
90
 
86
91
 
87
92
  class IRSB:
@@ -107,7 +112,7 @@ class IRSB:
107
112
  "_direct_next",
108
113
  "_exit_statements",
109
114
  "_instruction_addresses",
110
- "_instructions",
115
+ "_ops",
111
116
  "_size",
112
117
  "_statements",
113
118
  "_disassembly",
@@ -122,8 +127,8 @@ class IRSB:
122
127
 
123
128
  _direct_next: Optional[bool]
124
129
  _exit_statements: Sequence[Tuple[int, int, ExitStatement]]
125
- _instruction_addresses: Sequence[int]
126
- _instructions: Sequence[pypcode.Translation]
130
+ _instruction_addresses: Optional[Sequence[int]]
131
+ _ops: Sequence["pypcode.PcodeOp"] # FIXME: Merge into _statements
127
132
  _size: Optional[int]
128
133
  _statements: Iterable # Note: currently unused
129
134
  _disassembly: Optional[PcodeDisassemblerBlock]
@@ -189,8 +194,8 @@ class IRSB:
189
194
 
190
195
  self._direct_next = None
191
196
  self._exit_statements = []
192
- self._instruction_addresses = ()
193
- self._instructions: List["pypcode.Translation"] = []
197
+ self._instruction_addresses = None
198
+ self._ops = []
194
199
  self._size = None
195
200
  self._statements = []
196
201
  self.addr = mem_addr
@@ -258,15 +263,7 @@ class IRSB:
258
263
  nxt=self.next,
259
264
  jumpkind=self.jumpkind,
260
265
  direct_next=self.direct_next,
261
- # deepcopy call to 'pickle' fails.
262
- # shallow copy should work since _instructions shouldn't mutate
263
- instructions=copy.copy(self._instructions),
264
- # statements = None, #unused
265
- # instruction_addresses = None # computed
266
- # tyenv = None # unused
267
- # exit_statements = None # currently unused
268
- # default_exit_target = None # currently unused
269
- # size = None # computed
266
+ ops=self._ops[:],
270
267
  )
271
268
 
272
269
  return new
@@ -277,22 +274,14 @@ class IRSB:
277
274
  The appended irsb's jumpkind and default exit are used.
278
275
  :param extendwith: The IRSB to append to this IRSB
279
276
  """
280
- # see _set_attributes call in 'copy' def for notes on other attributes
281
277
  self._set_attributes(
282
278
  nxt=extendwith.next,
283
279
  jumpkind=extendwith.jumpkind,
284
280
  direct_next=extendwith.direct_next,
285
- instructions=copy.copy(self._instructions),
281
+ ops=self._ops + extendwith._ops,
286
282
  )
287
283
 
288
- # append instructions if new
289
- addrs = self.instruction_addresses
290
- newinsns = [insn for insn in extendwith._instructions if insn.address not in addrs]
291
- self._instructions.extend(newinsns)
292
-
293
- # reset disassem. now disassem will be recomputed if irsb.disassembly is called
294
284
  self._disassembly = None
295
-
296
285
  return self
297
286
 
298
287
  def invalidate_direct_next(self) -> None:
@@ -353,21 +342,28 @@ class IRSB:
353
342
  """
354
343
  The number of instructions in this block
355
344
  """
356
- return len(self._instructions)
345
+ return len(self.instruction_addresses)
357
346
 
358
347
  @property
359
348
  def instruction_addresses(self) -> Sequence[int]:
360
349
  """
361
350
  Addresses of instructions in this block.
362
351
  """
363
- return [ins.address.offset for ins in self._instructions]
352
+ if self._instruction_addresses is None:
353
+ self._instruction_addresses = []
354
+ for op in self._ops:
355
+ if op.opcode == pypcode.OpCode.IMARK:
356
+ for vn in op.inputs:
357
+ self._instruction_addresses.append(vn.offset)
358
+ return self._instruction_addresses
364
359
 
365
360
  @property
366
361
  def size(self) -> int:
367
362
  """
368
363
  The size of this block, in bytes
369
364
  """
370
- return sum(ins.length for ins in self._instructions)
365
+ assert self._size is not None
366
+ return self._size
371
367
 
372
368
  @property
373
369
  def operations(self):
@@ -435,10 +431,12 @@ class IRSB:
435
431
  """
436
432
  sa = []
437
433
  sa.append("IRSB {")
438
- for i, ins in enumerate(self._instructions):
439
- sa.append(" %02d | ------ %08x, %d ------" % (i, ins.address.offset, ins.length))
440
- for op in ins.ops:
441
- sa.append(" +%02d | %s" % (op.seq.uniq, pypcode.PcodePrettyPrinter.fmt_op(op)))
434
+ for i, op in enumerate(self._ops):
435
+ if op.opcode == pypcode.OpCode.IMARK:
436
+ for vn in op.inputs[:]:
437
+ sa.append(f" {i:02d} | ------ {vn.offset:08x}, {vn.size} ------")
438
+ else:
439
+ sa.append(f" {i:02d} | {pypcode.PcodePrettyPrinter.fmt_op(op)}")
442
440
 
443
441
  if isinstance(self.next, int):
444
442
  next_str = "%x" % self.next
@@ -464,7 +462,7 @@ class IRSB:
464
462
  jumpkind: Optional[str] = None,
465
463
  direct_next: Optional[bool] = None,
466
464
  size: Optional[int] = None,
467
- instructions: Optional[Iterable[pypcode.Translation]] = None,
465
+ ops: Optional[Sequence["pypcode.PcodeOp"]] = None,
468
466
  instruction_addresses: Optional[Iterable[int]] = None,
469
467
  exit_statements: Sequence[Tuple[int, int, ExitStatement]] = None,
470
468
  default_exit_target: Optional = None,
@@ -475,7 +473,7 @@ class IRSB:
475
473
  self.jumpkind = jumpkind
476
474
  self._direct_next = direct_next
477
475
  self._size = size
478
- self._instructions = instructions or []
476
+ self._ops = ops or []
479
477
  self._instruction_addresses = instruction_addresses
480
478
  self._exit_statements = exit_statements or []
481
479
  self.default_exit_target = default_exit_target
@@ -488,7 +486,7 @@ class IRSB:
488
486
  irsb.jumpkind,
489
487
  irsb.direct_next,
490
488
  irsb.size,
491
- instructions=irsb._instructions,
489
+ ops=irsb._ops,
492
490
  instruction_addresses=irsb._instruction_addresses,
493
491
  exit_statements=irsb.exit_statements,
494
492
  default_exit_target=irsb.default_exit_target,
@@ -504,10 +502,6 @@ class IRSB:
504
502
 
505
503
  @property
506
504
  def disassembly(self) -> PcodeDisassemblerBlock:
507
- if self._disassembly is None:
508
- insns = [PcodeDisassemblerInsn(ins) for ins in self._instructions]
509
- thumb = False # FIXME
510
- self._disassembly = PcodeDisassemblerBlock(self.addr, insns, thumb, self.arch)
511
505
  return self._disassembly
512
506
 
513
507
 
@@ -819,7 +813,7 @@ class PcodeBasicBlockLifter:
819
813
  Lifts basic blocks to P-code
820
814
  """
821
815
 
822
- context: pypcode.Context
816
+ context: "pypcode.Context"
823
817
  behaviors: BehaviorFactory
824
818
 
825
819
  def __init__(self, arch: archinfo.Arch):
@@ -836,11 +830,7 @@ class PcodeBasicBlockLifter:
836
830
  raise NotImplementedError()
837
831
  langid = archinfo_to_lang_map[arch.name]
838
832
 
839
- langs = {l.id: l for a in pypcode.Arch.enumerate() for l in a.languages}
840
-
841
- lang = langs[langid]
842
-
843
- self.context = pypcode.Context(lang)
833
+ self.context = pypcode.Context(langid)
844
834
  self.behaviors = BehaviorFactory()
845
835
 
846
836
  def lift(
@@ -851,52 +841,121 @@ class PcodeBasicBlockLifter:
851
841
  bytes_offset: int = 0,
852
842
  max_bytes: Optional[int] = None,
853
843
  max_inst: Optional[int] = None,
844
+ branch_delay_slot: bool = False,
845
+ is_sparc32: bool = False,
854
846
  ) -> None:
847
+ assert irsb.addr == baseaddr
848
+ assert bytes_offset < len(data)
849
+
855
850
  if max_bytes is None or max_bytes > MAX_BYTES:
856
- max_bytes = min(len(data), MAX_BYTES)
851
+ max_bytes = min(len(data) - bytes_offset, MAX_BYTES)
857
852
  if max_inst is None or max_inst > MAX_INSTRUCTIONS:
858
853
  max_inst = MAX_INSTRUCTIONS
859
854
 
860
855
  irsb.behaviors = self.behaviors # FIXME
861
856
 
862
857
  # Translate
863
- addr = baseaddr + bytes_offset
864
- result = self.context.translate(data[bytes_offset : bytes_offset + max_bytes], addr, max_inst, max_bytes, True)
865
- irsb._instructions = result.instructions
858
+ sliced_data = bytes(data[bytes_offset : bytes_offset + max_bytes])
859
+
860
+ if is_sparc32:
861
+ # workaround to handle SPARC V8 decoding before having a SPARC V8 Sleigh file
862
+ # replace all jmpl xxx; rett xxx sequences with rett xxx; nop;
863
+ nop_seq = b"\x01\x00\x00\x00"
864
+ jmpl_seqs = [
865
+ b"\x81\xc4\x40\x00",
866
+ b"\x81\xc4\x80\x00",
867
+ ]
868
+ rett_seqs = [b"\x81\xcc\x80\x00", b"\x81\xcc\xa0\x04"]
869
+ for jmpl_seq in jmpl_seqs:
870
+ for rett_seq in rett_seqs:
871
+ seq = jmpl_seq + rett_seq
872
+ index = sliced_data.find(seq)
873
+ while index >= 0:
874
+ sliced_data = sliced_data[:index] + rett_seq + nop_seq + sliced_data[index + 8 :]
875
+ index = sliced_data.find(seq)
876
+
877
+ sliced_data = bytes(sliced_data)
866
878
 
867
879
  # Post-process block to mark exits and next block
868
880
  next_block = None
869
- for insn in irsb._instructions:
870
- for op in insn.ops:
871
- if op.opcode in [pypcode.OpCode.BRANCH, pypcode.OpCode.CBRANCH] and op.inputs[0].get_addr().is_constant:
872
- # P-code relative branch (op.seq.pc.offset + op.seq.uniq + op.inputs[0].offset)
881
+ irsb._instruction_addresses = []
882
+ fallthru_addr = irsb.addr
883
+
884
+ try:
885
+ translation = self.context.translate(
886
+ sliced_data,
887
+ irsb.addr,
888
+ max_instructions=max_inst,
889
+ max_bytes=max_bytes,
890
+ flags=pypcode.TranslateFlags.BB_TERMINATING,
891
+ )
892
+ irsb._ops = translation.ops
893
+
894
+ last_decode_addr = irsb.addr
895
+ last_imark_idx = 0
896
+ for op_idx, op in enumerate(irsb._ops):
897
+ # OpCode space begins with control ops ending with RETURN. Quickly filter non-control instructions.
898
+ if op.opcode > pypcode.OpCode.RETURN:
899
+ continue
900
+
901
+ if op.opcode == pypcode.OpCode.IMARK:
902
+ irsb._instruction_addresses.extend([vn.offset for vn in op.inputs])
903
+ last_decode_addr = op.inputs[0].offset
904
+ fallthru_addr = op.inputs[-1].offset + op.inputs[-1].size
905
+ last_imark_idx = op_idx
906
+ continue
907
+
908
+ if op.opcode in {pypcode.OpCode.BRANCH, pypcode.OpCode.CBRANCH} and op.inputs[0].space.name == "const":
909
+ # P-code relative branch (op_idx + op.inputs[0].offset)
910
+ # Note: We only model these in execution
873
911
  continue
912
+
874
913
  if op.opcode == pypcode.OpCode.CBRANCH:
875
914
  irsb._exit_statements.append(
876
- (op.seq.pc.offset, op.seq.uniq, ExitStatement(op.inputs[0].offset, "Ijk_Boring"))
915
+ (last_decode_addr, op_idx - last_imark_idx, ExitStatement(op.inputs[0].offset, "Ijk_Boring"))
877
916
  )
878
917
  elif op.opcode == pypcode.OpCode.BRANCH:
879
- next_block = (op.inputs[0].offset, "Ijk_Boring")
918
+ if next_block is None:
919
+ next_block = (op.inputs[0].offset, "Ijk_Boring")
880
920
  elif op.opcode == pypcode.OpCode.BRANCHIND:
881
- next_block = (None, "Ijk_Boring")
921
+ if next_block is None:
922
+ next_block = (None, "Ijk_Boring")
882
923
  elif op.opcode == pypcode.OpCode.CALL:
883
- next_block = (op.inputs[0].offset, "Ijk_Call")
924
+ if next_block is None:
925
+ next_block = (op.inputs[0].offset, "Ijk_Call")
884
926
  elif op.opcode == pypcode.OpCode.CALLIND:
885
- next_block = (None, "Ijk_Call")
927
+ if next_block is None:
928
+ next_block = (None, "Ijk_Call")
886
929
  elif op.opcode == pypcode.OpCode.RETURN:
887
- next_block = (None, "Ijk_Ret")
888
-
889
- if len(irsb._instructions) > 0:
890
- last_insn = irsb._instructions[-1]
891
- fallthru_addr = last_insn.address.offset + last_insn.length
892
- else:
893
- fallthru_addr = addr
930
+ if next_block is None:
931
+ next_block = (None, "Ijk_Ret")
932
+
933
+ # FIXME: Do this lazily
934
+ disasm = self.context.disassemble(
935
+ sliced_data,
936
+ irsb.addr,
937
+ max_instructions=max_inst,
938
+ max_bytes=fallthru_addr - irsb.addr,
939
+ )
940
+ irsb._disassembly = PcodeDisassemblerBlock(
941
+ addr=irsb.addr,
942
+ insns=[PcodeDisassemblerInsn(ins) for ins in disasm.instructions],
943
+ thumb=False,
944
+ arch=irsb.arch,
945
+ )
894
946
 
895
- if result.error:
947
+ except (pypcode.BadDataError, pypcode.UnimplError):
896
948
  next_block = (fallthru_addr, "Ijk_NoDecode")
897
- elif next_block is None:
949
+ except (pypcode.LowlevelError, IndexError):
950
+ # FIXME:
951
+ # - IndexError: Give more data
952
+ # - pypcode.LowlevelError: Sometimes a decoding failure
953
+ next_block = (irsb.addr, "Ijk_NoDecode")
954
+
955
+ if next_block is None:
898
956
  next_block = (fallthru_addr, "Ijk_Boring")
899
957
 
958
+ irsb._size = fallthru_addr - irsb.addr
900
959
  irsb.next, irsb.jumpkind = next_block
901
960
 
902
961
 
@@ -918,6 +977,8 @@ class PcodeLifter(Lifter):
918
977
  bytes_offset=self.bytes_offset,
919
978
  max_inst=self.max_inst,
920
979
  max_bytes=self.max_bytes,
980
+ branch_delay_slot=self.arch.branch_delay_slot,
981
+ is_sparc32="sparc:" in self.arch.name and self.arch.bits == 32,
921
982
  )
922
983
 
923
984
  if self.irsb.size == 0:
@@ -932,7 +993,7 @@ class PcodeLifterEngineMixin(SimEngineBase):
932
993
 
933
994
  def __init__(
934
995
  self,
935
- project,
996
+ project=None,
936
997
  use_cache: Optional[bool] = None,
937
998
  cache_size: int = 50000,
938
999
  default_opt_level: int = 1,
@@ -1231,12 +1292,7 @@ class PcodeLifterEngineMixin(SimEngineBase):
1231
1292
 
1232
1293
  # phase x: error handling
1233
1294
  except PyVEXError as e:
1234
- l.debug("VEX translation error at %#x", addr)
1235
- # FIXME
1236
- # if isinstance(buff, bytes):
1237
- # l.debug("Using bytes: %r", buff)
1238
- # else:
1239
- # l.debug("Using bytes: %r", pyvex.ffi.buffer(buff, size))
1295
+ l.debug("Translation error at %#x", addr)
1240
1296
  raise SimTranslationError("Unable to translate bytecode") from e
1241
1297
 
1242
1298
  def _load_bytes(
@@ -1,5 +1,5 @@
1
1
  # pylint:disable=raise-missing-from
2
- from typing import Dict, Set, Optional
2
+ from typing import Dict, Generator, Optional, Set
3
3
  import logging
4
4
  import collections.abc
5
5
  import re
@@ -351,8 +351,10 @@ class FunctionManager(KnowledgeBasePlugin, collections.abc.Mapping):
351
351
  def get_by_addr(self, addr) -> Function:
352
352
  return self._function_map.get(addr)
353
353
 
354
- def get_by_name(self, name: str) -> Set[Function]:
355
- return {f for f in self._function_map.values() if f.name == name}
354
+ def get_by_name(self, name: str) -> Generator[Function, None, None]:
355
+ for f in self._function_map.values():
356
+ if f.name == name:
357
+ yield f
356
358
 
357
359
  def _function_added(self, func: Function):
358
360
  """
@@ -692,6 +692,20 @@ class PropagatorAILState(PropagatorState):
692
692
  PropValue(claripy.BVV(0, 32), offset_and_details={0: Detail(4, reg_value, initial_codeloc)}),
693
693
  )
694
694
 
695
+ if project is not None and project.simos is not None and project.simos.function_initial_registers:
696
+ if func_addr is not None:
697
+ for reg_name, reg_value in project.simos.function_initial_registers.items():
698
+ reg_size = project.arch.registers[reg_name][1]
699
+ reg_expr = ailment.Expr.Register(None, None, project.arch.registers[reg_name][0], reg_size)
700
+ reg_value_expr = ailment.Expr.Const(None, None, reg_value, reg_size * 8)
701
+ state.store_register(
702
+ reg_expr,
703
+ PropValue(
704
+ claripy.BVV(reg_value, project.arch.bits),
705
+ offset_and_details={0: Detail(reg_size, reg_value_expr, initial_codeloc)},
706
+ ),
707
+ )
708
+
695
709
  return state
696
710
 
697
711
  def copy(self) -> "PropagatorAILState":
angr/lib/angr_native.dll CHANGED
Binary file
@@ -1,8 +1,11 @@
1
- import angr
2
-
3
1
  import logging
4
2
 
3
+ from unique_log_filter import UniqueLogFilter
4
+
5
+ import angr
6
+
5
7
  l = logging.getLogger(name=__name__)
8
+ l.addFilter(UniqueLogFilter())
6
9
 
7
10
 
8
11
  class deallocate(angr.SimProcedure):
@@ -4,24 +4,39 @@ import angr
4
4
  class gethostbyname(angr.SimProcedure):
5
5
  def run(self, name):
6
6
  malloc = angr.SIM_PROCEDURES["libc"]["malloc"]
7
- place = self.inline_call(malloc, 32).ret_expr
7
+ int_size_bits = self.arch.sizeof["int"]
8
+ int_size = int_size_bits // 8
9
+ ptr_size_bits = self.arch.bits
10
+ ptr_size = ptr_size_bits // 8
11
+ hostent_size = (2 * int_size) + (3 * ptr_size)
12
+ place = self.inline_call(malloc, hostent_size).ret_expr
8
13
  self.state.memory.store(
9
- place, self.state.solver.BVS("h_name", 64, key=("api", "gethostbyname", "h_name")), endness="Iend_LE"
14
+ place,
15
+ self.state.solver.BVS("h_name", ptr_size_bits, key=("api", "gethostbyname", "h_name")),
16
+ endness="Iend_LE",
10
17
  )
18
+ next_addr = place + ptr_size
11
19
  self.state.memory.store(
12
- place, self.state.solver.BVS("h_aliases", 64, key=("api", "gethostbyname", "h_aliases")), endness="Iend_LE"
20
+ next_addr,
21
+ self.state.solver.BVS("h_aliases", ptr_size_bits, key=("api", "gethostbyname", "h_aliases")),
22
+ endness="Iend_LE",
13
23
  )
24
+ next_addr += ptr_size
14
25
  self.state.memory.store(
15
- place,
16
- self.state.solver.BVS("h_addrtype", 64, key=("api", "gethostbyname", "h_addrtype")),
26
+ next_addr,
27
+ self.state.solver.BVS("h_addrtype", int_size_bits, key=("api", "gethostbyname", "h_addrtype")),
17
28
  endness="Iend_LE",
18
29
  )
30
+ next_addr += int_size
19
31
  self.state.memory.store(
20
- place, self.state.solver.BVS("h_length", 64, key=("api", "gethostbyname", "h_length")), endness="Iend_LE"
32
+ next_addr,
33
+ self.state.solver.BVS("h_length", int_size_bits, key=("api", "gethostbyname", "h_length")),
34
+ endness="Iend_LE",
21
35
  )
36
+ next_addr += int_size
22
37
  self.state.memory.store(
23
- place,
24
- self.state.solver.BVS("h_addr_list", 64, key=("api", "gethostbyname", "h_addr_list")),
38
+ next_addr,
39
+ self.state.solver.BVS("h_addr_list", ptr_size_bits, key=("api", "gethostbyname", "h_addr_list")),
25
40
  endness="Iend_LE",
26
41
  )
27
42
  return place
angr/project.py CHANGED
@@ -212,6 +212,10 @@ class Project:
212
212
  self.store_function = store_function or self._store
213
213
  self.load_function = load_function or self._load
214
214
 
215
+ # FIXME: BIG HACK
216
+ if isinstance(self.filename, str) and self.filename.endswith(".xcal") and not simos:
217
+ simos = "snimmuc_nxp"
218
+
215
219
  # Step 4: determine the guest OS
216
220
  if isinstance(simos, type) and issubclass(simos, SimOS):
217
221
  self.simos = simos(self) # pylint:disable=invalid-name
angr/simos/__init__.py CHANGED
@@ -11,6 +11,7 @@ from .linux import SimLinux
11
11
  from .cgc import SimCGC
12
12
  from .windows import SimWindows
13
13
  from .javavm import SimJavaVM
14
+ from .snimmuc_nxp import SimSnimmucNxp
14
15
 
15
16
  os_mapping = defaultdict(lambda: SimOS)
16
17
 
@@ -27,3 +28,4 @@ register_simos("linux", SimLinux)
27
28
  register_simos("windows", SimWindows)
28
29
  register_simos("cgc", SimCGC)
29
30
  register_simos("javavm", SimJavaVM)
31
+ register_simos("snimmuc_nxp", SimSnimmucNxp)
angr/simos/simos.py CHANGED
@@ -35,6 +35,7 @@ class SimOS:
35
35
  self.return_deadend = None
36
36
  self.unresolvable_jump_target = None
37
37
  self.unresolvable_call_target = None
38
+ self.function_initial_registers = None
38
39
 
39
40
  def configure_project(self):
40
41
  """