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.
- angr/__init__.py +1 -1
- angr/analyses/cfg/cfg_base.py +6 -1
- angr/analyses/cfg/cfg_fast.py +32 -10
- angr/analyses/decompiler/clinic.py +204 -4
- angr/analyses/decompiler/condition_processor.py +8 -2
- angr/analyses/decompiler/decompiler.py +19 -17
- angr/analyses/decompiler/goto_manager.py +34 -51
- angr/analyses/decompiler/optimization_passes/__init__.py +5 -5
- angr/analyses/decompiler/optimization_passes/div_simplifier.py +2 -0
- angr/analyses/decompiler/optimization_passes/lowered_switch_simplifier.py +1 -1
- angr/analyses/decompiler/optimization_passes/mod_simplifier.py +2 -0
- angr/analyses/decompiler/optimization_passes/multi_simplifier.py +2 -0
- angr/analyses/decompiler/optimization_passes/optimization_pass.py +131 -3
- angr/analyses/decompiler/optimization_passes/ret_deduplicator.py +3 -3
- angr/analyses/decompiler/optimization_passes/return_duplicator.py +519 -0
- angr/analyses/decompiler/peephole_optimizations/constant_derefs.py +14 -2
- angr/analyses/decompiler/region_identifier.py +8 -2
- angr/analyses/decompiler/region_simplifiers/goto.py +5 -4
- angr/analyses/decompiler/structured_codegen/c.py +33 -1
- angr/analyses/decompiler/structuring/phoenix.py +3 -1
- angr/analyses/decompiler/structuring/structurer_nodes.py +11 -5
- angr/analyses/decompiler/utils.py +50 -0
- angr/analyses/disassembly.py +10 -3
- angr/analyses/propagator/engine_ail.py +125 -0
- angr/analyses/reaching_definitions/engine_ail.py +36 -2
- angr/analyses/reaching_definitions/rd_initializer.py +15 -1
- angr/analyses/reaching_definitions/rd_state.py +9 -4
- angr/analyses/stack_pointer_tracker.py +10 -17
- angr/analyses/variable_recovery/engine_ail.py +27 -1
- angr/angrdb/serializers/loader.py +10 -3
- angr/calling_conventions.py +2 -0
- angr/engines/pcode/behavior.py +7 -2
- angr/engines/pcode/cc.py +1 -0
- angr/engines/pcode/emulate.py +144 -104
- angr/engines/pcode/lifter.py +135 -79
- angr/knowledge_plugins/functions/function_manager.py +5 -3
- angr/knowledge_plugins/propagations/states.py +14 -0
- angr/lib/angr_native.dll +0 -0
- angr/procedures/cgc/deallocate.py +5 -2
- angr/procedures/posix/gethostbyname.py +23 -8
- angr/project.py +4 -0
- angr/simos/__init__.py +2 -0
- angr/simos/simos.py +1 -0
- angr/simos/snimmuc_nxp.py +152 -0
- angr/state_plugins/history.py +3 -1
- angr/utils/graph.py +20 -18
- {angr-9.2.84.dist-info → angr-9.2.85.dist-info}/METADATA +9 -8
- {angr-9.2.84.dist-info → angr-9.2.85.dist-info}/RECORD +57 -55
- tests/analyses/cfg/test_cfg_rust_got_resolution.py +2 -1
- tests/analyses/cfg/test_jumptables.py +2 -1
- tests/analyses/decompiler/test_decompiler.py +130 -103
- tests/engines/pcode/test_emulate.py +607 -0
- tests/serialization/test_db.py +30 -0
- angr/analyses/decompiler/optimization_passes/eager_returns.py +0 -285
- {angr-9.2.84.dist-info → angr-9.2.85.dist-info}/LICENSE +0 -0
- {angr-9.2.84.dist-info → angr-9.2.85.dist-info}/WHEEL +0 -0
- {angr-9.2.84.dist-info → angr-9.2.85.dist-info}/entry_points.txt +0 -0
- {angr-9.2.84.dist-info → angr-9.2.85.dist-info}/top_level.txt +0 -0
angr/engines/pcode/lifter.py
CHANGED
|
@@ -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
|
|
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
|
|
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.
|
|
81
|
+
return self.insn.addr.offset
|
|
77
82
|
|
|
78
83
|
@property
|
|
79
84
|
def mnemonic(self) -> str:
|
|
80
|
-
return self.insn.
|
|
85
|
+
return self.insn.mnem
|
|
81
86
|
|
|
82
87
|
@property
|
|
83
88
|
def op_str(self) -> str:
|
|
84
|
-
return self.insn.
|
|
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
|
-
"
|
|
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
|
-
|
|
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.
|
|
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
|
-
|
|
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
|
-
|
|
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.
|
|
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
|
-
|
|
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
|
-
|
|
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,
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
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
|
-
|
|
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.
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
864
|
-
|
|
865
|
-
|
|
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
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
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
|
-
(
|
|
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
|
|
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
|
|
921
|
+
if next_block is None:
|
|
922
|
+
next_block = (None, "Ijk_Boring")
|
|
882
923
|
elif op.opcode == pypcode.OpCode.CALL:
|
|
883
|
-
next_block
|
|
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
|
|
927
|
+
if next_block is None:
|
|
928
|
+
next_block = (None, "Ijk_Call")
|
|
886
929
|
elif op.opcode == pypcode.OpCode.RETURN:
|
|
887
|
-
next_block
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
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
|
-
|
|
947
|
+
except (pypcode.BadDataError, pypcode.UnimplError):
|
|
896
948
|
next_block = (fallthru_addr, "Ijk_NoDecode")
|
|
897
|
-
|
|
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("
|
|
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,
|
|
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) ->
|
|
355
|
-
|
|
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
|
|
@@ -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
|
-
|
|
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,
|
|
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
|
-
|
|
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
|
-
|
|
16
|
-
self.state.solver.BVS("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
|
-
|
|
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
|
-
|
|
24
|
-
self.state.solver.BVS("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)
|