angr 9.2.174__cp310-abi3-win_amd64.whl → 9.2.175__cp310-abi3-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/__main__.py +32 -2
- angr/analyses/cfg/cfg_base.py +1 -1
- angr/analyses/cfg/cfg_fast.py +27 -8
- angr/analyses/decompiler/utils.py +1 -1
- angr/analyses/smc.py +1 -1
- angr/calling_conventions.py +2 -1
- angr/knowledge_plugins/functions/function.py +1 -1
- angr/misc/bug_report.py +11 -2
- angr/procedures/definitions/__init__.py +88 -20
- angr/procedures/definitions/common/glibc.json +3516 -0
- angr/procedures/definitions/parse_glibc.py +78 -0
- angr/procedures/libc/fgets.py +2 -1
- angr/rustylib.pyd +0 -0
- angr/sim_type.py +62 -5
- angr/unicornlib.dll +0 -0
- angr/utils/library.py +1 -0
- {angr-9.2.174.dist-info → angr-9.2.175.dist-info}/METADATA +5 -5
- {angr-9.2.174.dist-info → angr-9.2.175.dist-info}/RECORD +23 -22
- angr/procedures/definitions/glibc.py +0 -8372
- {angr-9.2.174.dist-info → angr-9.2.175.dist-info}/WHEEL +0 -0
- {angr-9.2.174.dist-info → angr-9.2.175.dist-info}/entry_points.txt +0 -0
- {angr-9.2.174.dist-info → angr-9.2.175.dist-info}/licenses/LICENSE +0 -0
- {angr-9.2.174.dist-info → angr-9.2.175.dist-info}/top_level.txt +0 -0
angr/__init__.py
CHANGED
angr/__main__.py
CHANGED
|
@@ -6,11 +6,14 @@ import re
|
|
|
6
6
|
from typing import TYPE_CHECKING
|
|
7
7
|
from collections.abc import Generator
|
|
8
8
|
|
|
9
|
+
from rich.syntax import Syntax
|
|
10
|
+
from rich.console import Console
|
|
11
|
+
|
|
9
12
|
import angr
|
|
10
13
|
from angr.analyses.decompiler import DECOMPILATION_PRESETS
|
|
11
14
|
from angr.analyses.decompiler.structuring import STRUCTURER_CLASSES, DEFAULT_STRUCTURER
|
|
12
15
|
from angr.analyses.decompiler.utils import decompile_functions
|
|
13
|
-
|
|
16
|
+
from angr.utils.formatting import ansi_color_enabled
|
|
14
17
|
|
|
15
18
|
if TYPE_CHECKING:
|
|
16
19
|
from angr.knowledge_plugins.functions import Function
|
|
@@ -82,11 +85,27 @@ def decompile(args):
|
|
|
82
85
|
base_address=args.base_addr,
|
|
83
86
|
preset=args.preset,
|
|
84
87
|
)
|
|
85
|
-
|
|
88
|
+
|
|
89
|
+
# Determine if we should use syntax highlighting
|
|
90
|
+
should_highlight = ansi_color_enabled and not args.no_colors
|
|
91
|
+
|
|
92
|
+
if should_highlight:
|
|
93
|
+
try:
|
|
94
|
+
console = Console()
|
|
95
|
+
syntax = Syntax(decompilation, "c", theme=args.theme, line_numbers=False)
|
|
96
|
+
console.print(syntax)
|
|
97
|
+
# pylint: disable=broad-exception-caught
|
|
98
|
+
except Exception as e:
|
|
99
|
+
log.warning("Syntax highlighting failed: %s", e)
|
|
100
|
+
# Fall back to plain text if syntax highlighting fails
|
|
101
|
+
print(decompilation)
|
|
102
|
+
else:
|
|
103
|
+
print(decompilation)
|
|
86
104
|
|
|
87
105
|
|
|
88
106
|
def main():
|
|
89
107
|
parser = argparse.ArgumentParser(description="The angr CLI allows you to decompile and analyze binaries.")
|
|
108
|
+
parser.add_argument("--version", action="version", version=angr.__version__)
|
|
90
109
|
parser.add_argument("binary", help="The path to the binary to analyze.")
|
|
91
110
|
parser.add_argument(
|
|
92
111
|
"--catch-exceptions",
|
|
@@ -133,6 +152,17 @@ def main():
|
|
|
133
152
|
symbols of the binary or as addresses like: 0x401000.""",
|
|
134
153
|
nargs="+",
|
|
135
154
|
)
|
|
155
|
+
decompile_cmd_parser.add_argument(
|
|
156
|
+
"--no-colors",
|
|
157
|
+
help="Disable syntax highlighting in the decompiled output.",
|
|
158
|
+
action="store_true",
|
|
159
|
+
default=False,
|
|
160
|
+
)
|
|
161
|
+
decompile_cmd_parser.add_argument(
|
|
162
|
+
"--theme",
|
|
163
|
+
help="The syntax highlighting theme to use (only if rich is installed and colors are enabled).",
|
|
164
|
+
default="dracula",
|
|
165
|
+
)
|
|
136
166
|
|
|
137
167
|
disassemble_cmd_parser = subparsers.add_parser("disassemble", aliases=["dis"], help=disassemble.__doc__)
|
|
138
168
|
disassemble_cmd_parser.set_defaults(func=disassemble)
|
angr/analyses/cfg/cfg_base.py
CHANGED
|
@@ -937,7 +937,7 @@ class CFGBase(Analysis):
|
|
|
937
937
|
"""
|
|
938
938
|
|
|
939
939
|
addrs = set()
|
|
940
|
-
if isinstance(self._binary, ELF) and self._binary.has_dwarf_info:
|
|
940
|
+
if (isinstance(self._binary, ELF) and self._binary.has_dwarf_info) or isinstance(self._binary, PE):
|
|
941
941
|
for function_hint in self._binary.function_hints:
|
|
942
942
|
if function_hint.source == FunctionHintSource.EH_FRAME:
|
|
943
943
|
addrs.add(function_hint.addr)
|
angr/analyses/cfg/cfg_fast.py
CHANGED
|
@@ -435,6 +435,7 @@ class CFGJobType(Enum):
|
|
|
435
435
|
COMPLETE_SCANNING = 2
|
|
436
436
|
IFUNC_HINTS = 3
|
|
437
437
|
DATAREF_HINTS = 4
|
|
438
|
+
EH_FRAME_HINTS = 5
|
|
438
439
|
|
|
439
440
|
|
|
440
441
|
class CFGJob:
|
|
@@ -612,7 +613,7 @@ class CFGFast(ForwardAnalysis[CFGNode, CFGNode, CFGJob, int], CFGBase): # pylin
|
|
|
612
613
|
low_priority=False,
|
|
613
614
|
cfb=None,
|
|
614
615
|
model=None,
|
|
615
|
-
|
|
616
|
+
eh_frame=True,
|
|
616
617
|
exceptions=True,
|
|
617
618
|
skip_unmapped_addrs=True,
|
|
618
619
|
nodecode_window_size=512,
|
|
@@ -625,6 +626,7 @@ class CFGFast(ForwardAnalysis[CFGNode, CFGNode, CFGJob, int], CFGBase): # pylin
|
|
|
625
626
|
end=None, # deprecated
|
|
626
627
|
collect_data_references=None, # deprecated
|
|
627
628
|
extra_cross_references=None, # deprecated
|
|
629
|
+
elf_eh_frame=None, # deprecated
|
|
628
630
|
**extra_arch_options,
|
|
629
631
|
):
|
|
630
632
|
"""
|
|
@@ -664,8 +666,8 @@ class CFGFast(ForwardAnalysis[CFGNode, CFGNode, CFGJob, int], CFGBase): # pylin
|
|
|
664
666
|
types will be loaded.
|
|
665
667
|
:param base_state: A state to use as a backer for all memory loads
|
|
666
668
|
:param bool detect_tail_calls: Enable aggressive tail-call optimization detection.
|
|
667
|
-
:param bool
|
|
668
|
-
binaries.
|
|
669
|
+
:param bool eh_frame: Retrieve function starts (and maybe sizes later) from the .eh_frame of ELF
|
|
670
|
+
binaries or exception records of PE binaries.
|
|
669
671
|
:param skip_unmapped_addrs: Ignore all branches into unmapped regions. True by default. You may want to set
|
|
670
672
|
it to False if you are analyzing manually patched binaries or malware samples.
|
|
671
673
|
:param indirect_calls_always_return: Should CFG assume indirect calls must return or not. Assuming indirect
|
|
@@ -778,13 +780,17 @@ class CFGFast(ForwardAnalysis[CFGNode, CFGNode, CFGJob, int], CFGBase): # pylin
|
|
|
778
780
|
)
|
|
779
781
|
force_complete_scan = False
|
|
780
782
|
|
|
783
|
+
if elf_eh_frame is not None:
|
|
784
|
+
l.warning('"elf_eh_frame" is deprecated and will be removed soon. Please use "eh_frame" instead.')
|
|
785
|
+
eh_frame = eh_frame or elf_eh_frame
|
|
786
|
+
|
|
781
787
|
self._pickle_intermediate_results = pickle_intermediate_results
|
|
782
788
|
|
|
783
789
|
self._use_symbols = symbols
|
|
784
790
|
self._use_function_prologues = function_prologues
|
|
785
791
|
self._force_smart_scan = force_smart_scan
|
|
786
792
|
self._force_complete_scan = force_complete_scan
|
|
787
|
-
self.
|
|
793
|
+
self._use_eh_frame = eh_frame
|
|
788
794
|
self._use_exceptions = exceptions
|
|
789
795
|
self._check_funcret_max_job = check_funcret_max_job
|
|
790
796
|
|
|
@@ -841,7 +847,8 @@ class CFGFast(ForwardAnalysis[CFGNode, CFGNode, CFGJob, int], CFGBase): # pylin
|
|
|
841
847
|
self._read_addr_to_run = defaultdict(list)
|
|
842
848
|
self._write_addr_to_run = defaultdict(list)
|
|
843
849
|
|
|
844
|
-
self.
|
|
850
|
+
self._remaining_eh_frame_addrs: list[int] | None = None
|
|
851
|
+
self._remaining_function_prologue_addrs: list[int] | None = None
|
|
845
852
|
|
|
846
853
|
# exception handling
|
|
847
854
|
self._exception_handling_by_endaddr = SortedDict()
|
|
@@ -1440,9 +1447,6 @@ class CFGFast(ForwardAnalysis[CFGNode, CFGNode, CFGJob, int], CFGBase): # pylin
|
|
|
1440
1447
|
if self._use_symbols:
|
|
1441
1448
|
starting_points |= self._function_addresses_from_symbols
|
|
1442
1449
|
|
|
1443
|
-
if self._use_elf_eh_frame:
|
|
1444
|
-
starting_points |= self._function_addresses_from_eh_frame
|
|
1445
|
-
|
|
1446
1450
|
if self._extra_function_starts:
|
|
1447
1451
|
starting_points |= set(self._extra_function_starts)
|
|
1448
1452
|
|
|
@@ -1467,6 +1471,9 @@ class CFGFast(ForwardAnalysis[CFGNode, CFGNode, CFGJob, int], CFGBase): # pylin
|
|
|
1467
1471
|
|
|
1468
1472
|
self._updated_nonreturning_functions = set()
|
|
1469
1473
|
|
|
1474
|
+
if self._use_eh_frame:
|
|
1475
|
+
self._remaining_eh_frame_addrs = sorted(self._function_addresses_from_eh_frame)
|
|
1476
|
+
|
|
1470
1477
|
if self._use_function_prologues and self.project.concrete_target is None:
|
|
1471
1478
|
self._remaining_function_prologue_addrs = sorted(self._func_addrs_from_prologues())
|
|
1472
1479
|
|
|
@@ -1742,6 +1749,18 @@ class CFGFast(ForwardAnalysis[CFGNode, CFGNode, CFGJob, int], CFGBase): # pylin
|
|
|
1742
1749
|
self._insert_job(job)
|
|
1743
1750
|
return
|
|
1744
1751
|
|
|
1752
|
+
if self._use_eh_frame and self._remaining_eh_frame_addrs:
|
|
1753
|
+
while self._remaining_eh_frame_addrs:
|
|
1754
|
+
eh_addr = self._remaining_eh_frame_addrs[0]
|
|
1755
|
+
self._remaining_eh_frame_addrs = self._remaining_eh_frame_addrs[1:]
|
|
1756
|
+
if self._seg_list.is_occupied(eh_addr):
|
|
1757
|
+
continue
|
|
1758
|
+
|
|
1759
|
+
job = CFGJob(eh_addr, eh_addr, "Ijk_Boring", job_type=CFGJobType.EH_FRAME_HINTS)
|
|
1760
|
+
self._insert_job(job)
|
|
1761
|
+
self._register_analysis_job(eh_addr, job)
|
|
1762
|
+
return
|
|
1763
|
+
|
|
1745
1764
|
if self._use_function_prologues and self._remaining_function_prologue_addrs:
|
|
1746
1765
|
while self._remaining_function_prologue_addrs:
|
|
1747
1766
|
prolog_addr = self._remaining_function_prologue_addrs[0]
|
angr/analyses/smc.py
CHANGED
angr/calling_conventions.py
CHANGED
|
@@ -34,6 +34,7 @@ from .sim_type import (
|
|
|
34
34
|
SimTypeBottom,
|
|
35
35
|
parse_signature,
|
|
36
36
|
SimTypeReference,
|
|
37
|
+
SimTypeRef,
|
|
37
38
|
)
|
|
38
39
|
from .state_plugins.sim_action_object import SimActionObject
|
|
39
40
|
|
|
@@ -1430,7 +1431,7 @@ class SimCCMicrosoftAMD64(SimCC):
|
|
|
1430
1431
|
return SimReferenceArgument(int_loc, referenced_loc)
|
|
1431
1432
|
|
|
1432
1433
|
def return_in_implicit_outparam(self, ty):
|
|
1433
|
-
if isinstance(ty, SimTypeBottom):
|
|
1434
|
+
if isinstance(ty, (SimTypeBottom, SimTypeRef)):
|
|
1434
1435
|
return False
|
|
1435
1436
|
return not isinstance(ty, SimTypeFloat) and ty.size > self.STRUCT_RETURN_THRESHOLD
|
|
1436
1437
|
|
|
@@ -1663,7 +1663,7 @@ class Function(Serializable):
|
|
|
1663
1663
|
|
|
1664
1664
|
@property
|
|
1665
1665
|
def demangled_name(self):
|
|
1666
|
-
ast = pydemumble.demangle(self.name)
|
|
1666
|
+
ast = pydemumble.demangle(self.name).strip()
|
|
1667
1667
|
if self.is_rust_function():
|
|
1668
1668
|
nodes = ast.split("::")[:-1]
|
|
1669
1669
|
ast = "::".join([Function._rust_fmt_node(node) for node in nodes])
|
angr/misc/bug_report.py
CHANGED
|
@@ -17,11 +17,20 @@ except ImportError:
|
|
|
17
17
|
print("If you install gitpython (`pip install gitpython`), I can give you git info too!")
|
|
18
18
|
|
|
19
19
|
|
|
20
|
-
angr_modules = [
|
|
20
|
+
angr_modules = [
|
|
21
|
+
"angr",
|
|
22
|
+
"archinfo",
|
|
23
|
+
"claripy",
|
|
24
|
+
"cle",
|
|
25
|
+
"pypcode",
|
|
26
|
+
"pyvex",
|
|
27
|
+
"unicorn",
|
|
28
|
+
"z3",
|
|
29
|
+
]
|
|
21
30
|
native_modules = {
|
|
22
31
|
"angr": lambda: angr.state_plugins.unicorn_engine._UC_NATIVE, # pylint: disable=undefined-variable
|
|
23
|
-
"unicorn": lambda: unicorn.unicorn._uc, # pylint: disable=undefined-variable
|
|
24
32
|
"pyvex": lambda: pyvex.pvc, # pylint: disable=undefined-variable
|
|
33
|
+
"unicorn": lambda: unicorn.unicorn._uc, # pylint: disable=undefined-variable
|
|
25
34
|
"z3": lambda: next(x for x in gc.get_objects() if type(x) is ctypes.CDLL and "z3" in str(x)), # YIKES FOREVER
|
|
26
35
|
}
|
|
27
36
|
python_packages = {"z3": "z3-solver"}
|
|
@@ -161,13 +161,12 @@ class SimLibrary:
|
|
|
161
161
|
for arch_name, cc_name in d["default_cc"].items():
|
|
162
162
|
cc = CC_NAMES[cc_name]
|
|
163
163
|
lib.set_default_cc(arch_name, cc)
|
|
164
|
-
if "aliases" in d:
|
|
165
|
-
for name, alt_names in d["aliases"].items():
|
|
166
|
-
lib.add_alias(name, *alt_names)
|
|
167
164
|
if "library_names" in d:
|
|
168
165
|
lib.set_library_names(*d["library_names"])
|
|
169
166
|
else:
|
|
170
167
|
raise KeyError("library_names is required")
|
|
168
|
+
if "non_returning" in d:
|
|
169
|
+
lib.set_non_returning(*d["non_returning"])
|
|
171
170
|
if "functions" in d:
|
|
172
171
|
lib.prototypes_json = {k: v["proto"] for k, v in d["functions"].items() if "proto" in v}
|
|
173
172
|
return lib
|
|
@@ -307,8 +306,8 @@ class SimLibrary:
|
|
|
307
306
|
new_procedure = copy.deepcopy(old_procedure)
|
|
308
307
|
new_procedure.display_name = alt
|
|
309
308
|
self.procedures[alt] = new_procedure
|
|
310
|
-
if
|
|
311
|
-
self.prototypes[alt] = self.
|
|
309
|
+
if self.has_prototype(name):
|
|
310
|
+
self.prototypes[alt] = self.get_prototype(name) # type:ignore
|
|
312
311
|
if name in self.non_returning:
|
|
313
312
|
self.non_returning.add(alt)
|
|
314
313
|
|
|
@@ -317,8 +316,8 @@ class SimLibrary:
|
|
|
317
316
|
proc.cc = self.default_ccs[arch.name](arch)
|
|
318
317
|
if proc.cc is None and arch.name in self.fallback_cc:
|
|
319
318
|
proc.cc = self.fallback_cc[arch.name]["Linux"](arch)
|
|
320
|
-
if proc.display_name
|
|
321
|
-
proc.prototype = self.
|
|
319
|
+
if self.has_prototype(proc.display_name):
|
|
320
|
+
proc.prototype = self.get_prototype(proc.display_name, deref=True).with_arch(arch) # type:ignore
|
|
322
321
|
proc.guessed_prototype = False
|
|
323
322
|
if proc.prototype.arg_names is None:
|
|
324
323
|
# Use inspect to extract the parameters from the run python function
|
|
@@ -361,12 +360,13 @@ class SimLibrary:
|
|
|
361
360
|
self._apply_metadata(proc, arch)
|
|
362
361
|
return proc
|
|
363
362
|
|
|
364
|
-
def get_prototype(self, name: str, arch=None) -> SimTypeFunction | None:
|
|
363
|
+
def get_prototype(self, name: str, arch=None, deref: bool = False) -> SimTypeFunction | None:
|
|
365
364
|
"""
|
|
366
365
|
Get a prototype of the given function name, optionally specialize the prototype to a given architecture.
|
|
367
366
|
|
|
368
367
|
:param name: Name of the function.
|
|
369
368
|
:param arch: The architecture to specialize to.
|
|
369
|
+
:param deref: True if any SimTypeRefs in the prototype should be dereferenced using library information.
|
|
370
370
|
:return: Prototype of the function, or None if the prototype does not exist.
|
|
371
371
|
"""
|
|
372
372
|
if name not in self.prototypes and name in self.prototypes_json:
|
|
@@ -389,6 +389,11 @@ class SimLibrary:
|
|
|
389
389
|
proto = self.prototypes.get(name, None)
|
|
390
390
|
if proto is None:
|
|
391
391
|
return None
|
|
392
|
+
if deref:
|
|
393
|
+
from angr.utils.types import dereference_simtype_by_lib # pylint:disable=import-outside-toplevel
|
|
394
|
+
|
|
395
|
+
proto = dereference_simtype_by_lib(proto, self.name)
|
|
396
|
+
assert isinstance(proto, SimTypeFunction)
|
|
392
397
|
if arch is not None:
|
|
393
398
|
return proto.with_arch(arch)
|
|
394
399
|
return proto
|
|
@@ -400,7 +405,7 @@ class SimLibrary:
|
|
|
400
405
|
:param name: The name of the function as a string
|
|
401
406
|
:return: A bool indicating if anything is known about the function
|
|
402
407
|
"""
|
|
403
|
-
return self.has_implementation(name) or name in self.non_returning or
|
|
408
|
+
return self.has_implementation(name) or name in self.non_returning or self.has_prototype(name)
|
|
404
409
|
|
|
405
410
|
def has_implementation(self, name):
|
|
406
411
|
"""
|
|
@@ -490,17 +495,18 @@ class SimCppLibrary(SimLibrary):
|
|
|
490
495
|
stub.num_args = len(stub.prototype.args)
|
|
491
496
|
return stub
|
|
492
497
|
|
|
493
|
-
def get_prototype(self, name: str, arch=None) -> SimTypeFunction | None:
|
|
498
|
+
def get_prototype(self, name: str, arch=None, deref: bool = False) -> SimTypeFunction | None:
|
|
494
499
|
"""
|
|
495
500
|
Get a prototype of the given function name, optionally specialize the prototype to a given architecture. The
|
|
496
501
|
function name will be demangled first.
|
|
497
502
|
|
|
498
503
|
:param name: Name of the function.
|
|
499
504
|
:param arch: The architecture to specialize to.
|
|
505
|
+
:param deref: True if any SimTypeRefs in the prototype should be dereferenced using library information.
|
|
500
506
|
:return: Prototype of the function, or None if the prototype does not exist.
|
|
501
507
|
"""
|
|
502
508
|
demangled_name = self._try_demangle(name)
|
|
503
|
-
return super().get_prototype(demangled_name, arch=arch)
|
|
509
|
+
return super().get_prototype(demangled_name, arch=arch, deref=deref)
|
|
504
510
|
|
|
505
511
|
def has_metadata(self, name):
|
|
506
512
|
"""
|
|
@@ -659,11 +665,39 @@ class SimSyscallLibrary(SimLibrary):
|
|
|
659
665
|
if abi in self.default_cc_mapping:
|
|
660
666
|
cc = self.default_cc_mapping[abi](arch)
|
|
661
667
|
proc.cc = cc
|
|
668
|
+
elif arch.name in self.default_ccs:
|
|
669
|
+
proc.cc = self.default_ccs[arch.name](arch)
|
|
662
670
|
# a bit of a hack.
|
|
663
671
|
name = proc.display_name
|
|
664
|
-
if self.
|
|
672
|
+
if self.has_prototype(abi, name):
|
|
665
673
|
proc.guessed_prototype = False
|
|
666
|
-
|
|
674
|
+
proto = self.get_prototype(abi, name, deref=True)
|
|
675
|
+
assert proto is not None
|
|
676
|
+
proc.prototype = proto.with_arch(arch)
|
|
677
|
+
|
|
678
|
+
def add_alias(self, name, *alt_names):
|
|
679
|
+
"""
|
|
680
|
+
Add some duplicate names for a given function. The original function's implementation must already be
|
|
681
|
+
registered.
|
|
682
|
+
|
|
683
|
+
:param name: The name of the function for which an implementation is already present
|
|
684
|
+
:param alt_names: Any number of alternate names may be passed as varargs
|
|
685
|
+
"""
|
|
686
|
+
old_procedure = self.procedures[name]
|
|
687
|
+
for alt in alt_names:
|
|
688
|
+
new_procedure = copy.deepcopy(old_procedure)
|
|
689
|
+
new_procedure.display_name = alt
|
|
690
|
+
self.procedures[alt] = new_procedure
|
|
691
|
+
for abi in self.syscall_prototypes:
|
|
692
|
+
if self.has_prototype(abi, name):
|
|
693
|
+
self.syscall_prototypes[abi][alt] = self.get_prototype(abi, name) # type:ignore
|
|
694
|
+
if name in self.non_returning:
|
|
695
|
+
self.non_returning.add(alt)
|
|
696
|
+
|
|
697
|
+
def _apply_metadata(self, proc, arch):
|
|
698
|
+
# this function is a no-op in SimSyscallLibrary; users are supposed to explicitly call
|
|
699
|
+
# _apply_numerical_metadata instead.
|
|
700
|
+
pass
|
|
667
701
|
|
|
668
702
|
# pylint: disable=arguments-differ
|
|
669
703
|
def get(self, number, arch, abi_list=()): # type:ignore
|
|
@@ -703,7 +737,9 @@ class SimSyscallLibrary(SimLibrary):
|
|
|
703
737
|
l.debug("unsupported syscall: %s", number)
|
|
704
738
|
return proc
|
|
705
739
|
|
|
706
|
-
def get_prototype(
|
|
740
|
+
def get_prototype( # type:ignore
|
|
741
|
+
self, abi: str, name: str, arch=None, deref: bool = False
|
|
742
|
+
) -> SimTypeFunction | None:
|
|
707
743
|
"""
|
|
708
744
|
Get a prototype of the given syscall name and its ABI, optionally specialize the prototype to a given
|
|
709
745
|
architecture.
|
|
@@ -711,6 +747,7 @@ class SimSyscallLibrary(SimLibrary):
|
|
|
711
747
|
:param abi: ABI of the prototype to get.
|
|
712
748
|
:param name: Name of the syscall.
|
|
713
749
|
:param arch: The architecture to specialize to.
|
|
750
|
+
:param deref: True if any SimTypeRefs in the prototype should be dereferenced using library information.
|
|
714
751
|
:return: Prototype of the syscall, or None if the prototype does not exist.
|
|
715
752
|
"""
|
|
716
753
|
if abi not in self.syscall_prototypes:
|
|
@@ -718,6 +755,11 @@ class SimSyscallLibrary(SimLibrary):
|
|
|
718
755
|
proto = self.syscall_prototypes[abi].get(name, None)
|
|
719
756
|
if proto is None:
|
|
720
757
|
return None
|
|
758
|
+
if deref:
|
|
759
|
+
from angr.utils.types import dereference_simtype_by_lib # pylint:disable=import-outside-toplevel
|
|
760
|
+
|
|
761
|
+
proto = dereference_simtype_by_lib(proto, self.name)
|
|
762
|
+
assert isinstance(proto, SimTypeFunction)
|
|
721
763
|
return proto.with_arch(arch=arch)
|
|
722
764
|
|
|
723
765
|
def has_metadata(self, number, arch, abi_list=()): # type:ignore
|
|
@@ -729,8 +771,10 @@ class SimSyscallLibrary(SimLibrary):
|
|
|
729
771
|
:param abi_list: A list of ABI names that could be used
|
|
730
772
|
:return: A bool of whether or not any implementation or metadata is known about the given syscall
|
|
731
773
|
"""
|
|
732
|
-
name, _,
|
|
733
|
-
return
|
|
774
|
+
name, _, abi = self._canonicalize(number, arch, abi_list)
|
|
775
|
+
return (
|
|
776
|
+
name in self.procedures or name in self.non_returning or (abi is not None and self.has_prototype(abi, name))
|
|
777
|
+
)
|
|
734
778
|
|
|
735
779
|
def has_implementation(self, number, arch, abi_list=()): # type:ignore
|
|
736
780
|
"""
|
|
@@ -879,7 +923,7 @@ def load_external_definitions():
|
|
|
879
923
|
|
|
880
924
|
|
|
881
925
|
def _update_libkernel32(lib: SimLibrary):
|
|
882
|
-
from angr import SIM_PROCEDURES as P # pylint:disable=import-outside-toplevel
|
|
926
|
+
from angr.procedures.procedure_dict import SIM_PROCEDURES as P # pylint:disable=import-outside-toplevel
|
|
883
927
|
|
|
884
928
|
lib.add_all_from_dict(P["win32"])
|
|
885
929
|
lib.add_alias("EncodePointer", "DecodePointer")
|
|
@@ -895,7 +939,7 @@ def _update_libkernel32(lib: SimLibrary):
|
|
|
895
939
|
|
|
896
940
|
|
|
897
941
|
def _update_libntdll(lib: SimLibrary):
|
|
898
|
-
from angr import SIM_PROCEDURES as P # pylint:disable=import-outside-toplevel
|
|
942
|
+
from angr.procedures.procedure_dict import SIM_PROCEDURES as P # pylint:disable=import-outside-toplevel
|
|
899
943
|
|
|
900
944
|
lib.add("RtlEncodePointer", P["win32"]["EncodePointer"])
|
|
901
945
|
lib.add("RtlDecodePointer", P["win32"]["EncodePointer"])
|
|
@@ -903,7 +947,7 @@ def _update_libntdll(lib: SimLibrary):
|
|
|
903
947
|
|
|
904
948
|
|
|
905
949
|
def _update_libuser32(lib: SimLibrary):
|
|
906
|
-
from angr import SIM_PROCEDURES as P # pylint:disable=import-outside-toplevel
|
|
950
|
+
from angr.procedures.procedure_dict import SIM_PROCEDURES as P # pylint:disable=import-outside-toplevel
|
|
907
951
|
from angr.calling_conventions import SimCCCdecl # pylint:disable=import-outside-toplevel
|
|
908
952
|
|
|
909
953
|
lib.add_all_from_dict(P["win_user32"])
|
|
@@ -911,11 +955,33 @@ def _update_libuser32(lib: SimLibrary):
|
|
|
911
955
|
|
|
912
956
|
|
|
913
957
|
def _update_libntoskrnl(lib: SimLibrary):
|
|
914
|
-
from angr import SIM_PROCEDURES as P # pylint:disable=import-outside-toplevel
|
|
958
|
+
from angr.procedures.procedure_dict import SIM_PROCEDURES as P # pylint:disable=import-outside-toplevel
|
|
915
959
|
|
|
916
960
|
lib.add_all_from_dict(P["win32_kernel"])
|
|
917
961
|
|
|
918
962
|
|
|
963
|
+
def _update_glibc(libc: SimLibrary):
|
|
964
|
+
from angr.procedures.procedure_dict import SIM_PROCEDURES as P # pylint:disable=import-outside-toplevel
|
|
965
|
+
|
|
966
|
+
libc.add_all_from_dict(P["libc"])
|
|
967
|
+
libc.add_all_from_dict(P["posix"])
|
|
968
|
+
libc.add_all_from_dict(P["glibc"])
|
|
969
|
+
# gotta do this since there's no distinguishing different libcs without analysis. there should be no naming
|
|
970
|
+
# conflicts in the functions.
|
|
971
|
+
libc.add_all_from_dict(P["uclibc"])
|
|
972
|
+
|
|
973
|
+
# aliases for SimProcedures
|
|
974
|
+
libc.add_alias("abort", "__assert_fail", "__stack_chk_fail")
|
|
975
|
+
libc.add_alias("memcpy", "memmove", "bcopy")
|
|
976
|
+
libc.add_alias("getc", "_IO_getc")
|
|
977
|
+
libc.add_alias("putc", "_IO_putc")
|
|
978
|
+
libc.add_alias("gets", "_IO_gets")
|
|
979
|
+
libc.add_alias("puts", "_IO_puts")
|
|
980
|
+
libc.add_alias("exit", "_exit", "_Exit")
|
|
981
|
+
libc.add_alias("sprintf", "siprintf")
|
|
982
|
+
libc.add_alias("snprintf", "sniprintf")
|
|
983
|
+
|
|
984
|
+
|
|
919
985
|
def load_win32api_definitions():
|
|
920
986
|
load_win32_type_collections()
|
|
921
987
|
if once("load_win32api_definitions"):
|
|
@@ -961,4 +1027,6 @@ load_type_collections(skip={"win32"})
|
|
|
961
1027
|
|
|
962
1028
|
|
|
963
1029
|
# Load common definitions
|
|
1030
|
+
_load_definitions(os.path.join(_DEFINITIONS_BASEDIR, "common"), only=COMMON_LIBRARIES)
|
|
964
1031
|
_load_definitions(_DEFINITIONS_BASEDIR, only=COMMON_LIBRARIES)
|
|
1032
|
+
_update_glibc(SIM_LIBRARIES["libc.so"][0])
|