smallworld-re 1.0.3__py3-none-any.whl → 2.0.0__py3-none-any.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.
- smallworld/analyses/__init__.py +8 -0
- smallworld/analyses/analysis.py +8 -67
- smallworld/analyses/code_coverage.py +1 -2
- smallworld/analyses/colorizer.py +301 -534
- smallworld/analyses/colorizer_def_use.py +217 -0
- smallworld/analyses/colorizer_summary.py +173 -83
- smallworld/analyses/field_detection/field_analysis.py +7 -8
- smallworld/analyses/field_detection/hints.py +1 -1
- smallworld/analyses/field_detection/malloc.py +2 -2
- smallworld/analyses/trace_execution.py +160 -0
- smallworld/analyses/trace_execution_types.py +42 -0
- smallworld/analyses/unstable/angr/divergence.py +1 -2
- smallworld/analyses/unstable/angr/model.py +5 -6
- smallworld/analyses/unstable/angr_nwbt.py +3 -4
- smallworld/analyses/unstable/code_coverage.py +2 -3
- smallworld/analyses/unstable/code_reachable.py +2 -3
- smallworld/analyses/unstable/control_flow_tracer.py +2 -3
- smallworld/analyses/unstable/pointer_finder.py +2 -3
- smallworld/analyses/unstable/utils/tui.py +71 -0
- smallworld/emulators/__init__.py +3 -1
- smallworld/emulators/angr/angr.py +30 -9
- smallworld/emulators/angr/machdefs/__init__.py +2 -0
- smallworld/emulators/angr/machdefs/aarch64.py +1 -1
- smallworld/emulators/angr/machdefs/amd64.py +0 -4
- smallworld/emulators/angr/machdefs/arm.py +0 -2
- smallworld/emulators/angr/machdefs/i386.py +0 -2
- smallworld/emulators/angr/machdefs/loongarch.py +340 -0
- smallworld/emulators/angr/machdefs/machdef.py +1 -8
- smallworld/emulators/angr/machdefs/mips.py +0 -2
- smallworld/emulators/angr/machdefs/mips64.py +0 -2
- smallworld/emulators/angr/machdefs/ppc.py +1 -2
- smallworld/emulators/angr/machdefs/riscv.py +8 -10
- smallworld/emulators/angr/machdefs/xtensa.py +7 -4
- smallworld/emulators/emulator.py +22 -0
- smallworld/emulators/ghidra/__init__.py +37 -0
- smallworld/emulators/ghidra/ghidra.py +513 -0
- smallworld/emulators/ghidra/machdefs/__init__.py +31 -0
- smallworld/emulators/ghidra/machdefs/aarch64.py +289 -0
- smallworld/emulators/ghidra/machdefs/amd64.py +185 -0
- smallworld/emulators/ghidra/machdefs/arm.py +370 -0
- smallworld/emulators/ghidra/machdefs/i386.py +109 -0
- smallworld/emulators/ghidra/machdefs/loongarch.py +162 -0
- smallworld/emulators/ghidra/machdefs/machdef.py +81 -0
- smallworld/emulators/ghidra/machdefs/mips.py +163 -0
- smallworld/emulators/ghidra/machdefs/mips64.py +186 -0
- smallworld/emulators/ghidra/machdefs/ppc.py +98 -0
- smallworld/emulators/ghidra/machdefs/riscv.py +208 -0
- smallworld/emulators/ghidra/machdefs/xtensa.py +21 -0
- smallworld/emulators/ghidra/typing.py +28 -0
- smallworld/emulators/hookable.py +18 -4
- smallworld/emulators/panda/machdefs/__init__.py +2 -2
- smallworld/emulators/panda/machdefs/aarch64.py +186 -11
- smallworld/emulators/panda/machdefs/amd64.py +103 -11
- smallworld/emulators/panda/machdefs/arm.py +216 -20
- smallworld/emulators/panda/machdefs/i386.py +30 -7
- smallworld/emulators/panda/machdefs/machdef.py +9 -16
- smallworld/emulators/panda/machdefs/mips.py +49 -5
- smallworld/emulators/panda/machdefs/mips64.py +57 -5
- smallworld/emulators/panda/machdefs/ppc.py +38 -13
- smallworld/emulators/panda/panda.py +146 -44
- smallworld/emulators/unicorn/__init__.py +2 -0
- smallworld/emulators/unicorn/machdefs/aarch64.py +253 -264
- smallworld/emulators/unicorn/machdefs/amd64.py +254 -259
- smallworld/emulators/unicorn/machdefs/arm.py +200 -212
- smallworld/emulators/unicorn/machdefs/i386.py +84 -90
- smallworld/emulators/unicorn/machdefs/machdef.py +2 -23
- smallworld/emulators/unicorn/machdefs/mips.py +127 -135
- smallworld/emulators/unicorn/unicorn.py +52 -13
- smallworld/helpers.py +4 -19
- smallworld/hinting/hinting.py +22 -192
- smallworld/hinting/hints.py +50 -18
- smallworld/instructions/bsid.py +8 -8
- smallworld/logging.py +4 -2
- smallworld/platforms/__init__.py +12 -0
- smallworld/platforms/defs/__init__.py +36 -0
- smallworld/platforms/defs/aarch64.py +450 -0
- smallworld/platforms/defs/amd64.py +463 -0
- smallworld/platforms/defs/arm.py +519 -0
- smallworld/platforms/defs/i386.py +258 -0
- smallworld/platforms/defs/loongarch.py +270 -0
- smallworld/platforms/defs/mips.py +321 -0
- smallworld/platforms/defs/mips64.py +313 -0
- smallworld/platforms/defs/platformdef.py +97 -0
- smallworld/platforms/defs/powerpc.py +259 -0
- smallworld/platforms/defs/riscv.py +257 -0
- smallworld/platforms/defs/xtensa.py +96 -0
- smallworld/{platforms.py → platforms/platforms.py} +3 -0
- smallworld/state/cpus/__init__.py +2 -0
- smallworld/state/cpus/aarch64.py +0 -9
- smallworld/state/cpus/amd64.py +6 -28
- smallworld/state/cpus/arm.py +0 -11
- smallworld/state/cpus/cpu.py +0 -11
- smallworld/state/cpus/i386.py +0 -7
- smallworld/state/cpus/loongarch.py +299 -0
- smallworld/state/cpus/mips.py +4 -47
- smallworld/state/cpus/mips64.py +18 -58
- smallworld/state/cpus/powerpc.py +2 -9
- smallworld/state/cpus/riscv.py +1 -11
- smallworld/state/cpus/xtensa.py +0 -5
- smallworld/state/memory/code.py +38 -2
- smallworld/state/memory/elf/__init__.py +5 -1
- smallworld/state/memory/elf/coredump/__init__.py +3 -0
- smallworld/state/memory/elf/coredump/coredump.py +46 -0
- smallworld/state/memory/elf/coredump/prstatus/__init__.py +27 -0
- smallworld/state/memory/elf/coredump/prstatus/aarch64.py +46 -0
- smallworld/state/memory/elf/coredump/prstatus/amd64.py +40 -0
- smallworld/state/memory/elf/coredump/prstatus/arm.py +53 -0
- smallworld/state/memory/elf/coredump/prstatus/i386.py +30 -0
- smallworld/state/memory/elf/coredump/prstatus/mips.py +55 -0
- smallworld/state/memory/elf/coredump/prstatus/mips64.py +57 -0
- smallworld/state/memory/elf/coredump/prstatus/ppc.py +82 -0
- smallworld/state/memory/elf/coredump/prstatus/prstatus.py +129 -0
- smallworld/state/memory/elf/elf.py +211 -57
- smallworld/state/memory/elf/register_state.py +36 -0
- smallworld/state/memory/elf/rela/__init__.py +2 -0
- smallworld/state/memory/elf/rela/aarch64.py +3 -1
- smallworld/state/memory/elf/rela/amd64.py +4 -2
- smallworld/state/memory/elf/rela/arm.py +4 -2
- smallworld/state/memory/elf/rela/i386.py +4 -2
- smallworld/state/memory/elf/rela/loongarch.py +32 -0
- smallworld/state/memory/elf/rela/mips.py +39 -18
- smallworld/state/memory/elf/rela/ppc.py +31 -14
- smallworld/state/memory/elf/structs.py +3 -0
- smallworld/state/memory/heap.py +2 -2
- smallworld/state/memory/memory.py +18 -0
- smallworld/state/memory/pe/__init__.py +3 -0
- smallworld/state/memory/pe/pe.py +361 -0
- smallworld/state/memory/pe/structs.py +60 -0
- smallworld/state/memory/stack/__init__.py +2 -0
- smallworld/state/memory/stack/loongarch.py +26 -0
- smallworld/state/models/__init__.py +29 -2
- smallworld/state/models/aarch64/__init__.py +1 -0
- smallworld/state/models/aarch64/systemv/__init__.py +6 -0
- smallworld/state/models/aarch64/systemv/c99/__init__.py +12 -0
- smallworld/state/models/aarch64/systemv/c99/signal.py +16 -0
- smallworld/state/models/aarch64/systemv/c99/stdio.py +265 -0
- smallworld/state/models/aarch64/systemv/c99/stdlib.py +169 -0
- smallworld/state/models/aarch64/systemv/c99/string.py +139 -0
- smallworld/state/models/aarch64/systemv/c99/time.py +61 -0
- smallworld/state/models/aarch64/systemv/posix/__init__.py +6 -0
- smallworld/state/models/aarch64/systemv/posix/libgen.py +16 -0
- smallworld/state/models/aarch64/systemv/posix/signal.py +157 -0
- smallworld/state/models/aarch64/systemv/systemv.py +80 -0
- smallworld/state/models/amd64/__init__.py +1 -0
- smallworld/state/models/amd64/systemv/__init__.py +6 -0
- smallworld/state/models/amd64/systemv/c99/__init__.py +12 -0
- smallworld/state/models/amd64/systemv/c99/signal.py +16 -0
- smallworld/state/models/amd64/systemv/c99/stdio.py +265 -0
- smallworld/state/models/amd64/systemv/c99/stdlib.py +169 -0
- smallworld/state/models/amd64/systemv/c99/string.py +139 -0
- smallworld/state/models/amd64/systemv/c99/time.py +61 -0
- smallworld/state/models/amd64/systemv/posix/__init__.py +6 -0
- smallworld/state/models/amd64/systemv/posix/libgen.py +16 -0
- smallworld/state/models/amd64/systemv/posix/signal.py +157 -0
- smallworld/state/models/amd64/systemv/systemv.py +78 -0
- smallworld/state/models/armel/__init__.py +1 -0
- smallworld/state/models/armel/systemv/__init__.py +6 -0
- smallworld/state/models/armel/systemv/c99/__init__.py +12 -0
- smallworld/state/models/armel/systemv/c99/signal.py +16 -0
- smallworld/state/models/armel/systemv/c99/stdio.py +265 -0
- smallworld/state/models/armel/systemv/c99/stdlib.py +169 -0
- smallworld/state/models/armel/systemv/c99/string.py +139 -0
- smallworld/state/models/armel/systemv/c99/time.py +61 -0
- smallworld/state/models/armel/systemv/posix/__init__.py +6 -0
- smallworld/state/models/armel/systemv/posix/libgen.py +16 -0
- smallworld/state/models/armel/systemv/posix/signal.py +157 -0
- smallworld/state/models/armel/systemv/systemv.py +82 -0
- smallworld/state/models/armhf/__init__.py +1 -0
- smallworld/state/models/armhf/systemv/__init__.py +6 -0
- smallworld/state/models/armhf/systemv/c99/__init__.py +12 -0
- smallworld/state/models/armhf/systemv/c99/signal.py +16 -0
- smallworld/state/models/armhf/systemv/c99/stdio.py +265 -0
- smallworld/state/models/armhf/systemv/c99/stdlib.py +169 -0
- smallworld/state/models/armhf/systemv/c99/string.py +139 -0
- smallworld/state/models/armhf/systemv/c99/time.py +61 -0
- smallworld/state/models/armhf/systemv/posix/__init__.py +6 -0
- smallworld/state/models/armhf/systemv/posix/libgen.py +16 -0
- smallworld/state/models/armhf/systemv/posix/signal.py +157 -0
- smallworld/state/models/armhf/systemv/systemv.py +77 -0
- smallworld/state/models/c99/__init__.py +12 -0
- smallworld/state/models/c99/fmt_print.py +915 -0
- smallworld/state/models/c99/fmt_scan.py +864 -0
- smallworld/state/models/c99/math.py +362 -0
- smallworld/state/models/c99/signal.py +71 -0
- smallworld/state/models/c99/stdio.py +1305 -0
- smallworld/state/models/c99/stdlib.py +595 -0
- smallworld/state/models/c99/string.py +674 -0
- smallworld/state/models/c99/time.py +340 -0
- smallworld/state/models/c99/utils.py +89 -0
- smallworld/state/models/cstd.py +759 -0
- smallworld/state/models/errno.py +581 -0
- smallworld/state/models/filedesc.py +515 -0
- smallworld/state/models/i386/__init__.py +1 -0
- smallworld/state/models/i386/systemv/__init__.py +6 -0
- smallworld/state/models/i386/systemv/c99/__init__.py +12 -0
- smallworld/state/models/i386/systemv/c99/signal.py +16 -0
- smallworld/state/models/i386/systemv/c99/stdio.py +265 -0
- smallworld/state/models/i386/systemv/c99/stdlib.py +169 -0
- smallworld/state/models/i386/systemv/c99/string.py +139 -0
- smallworld/state/models/i386/systemv/c99/time.py +61 -0
- smallworld/state/models/i386/systemv/posix/__init__.py +6 -0
- smallworld/state/models/i386/systemv/posix/libgen.py +16 -0
- smallworld/state/models/i386/systemv/posix/signal.py +157 -0
- smallworld/state/models/i386/systemv/systemv.py +71 -0
- smallworld/state/models/loongarch64/__init__.py +1 -0
- smallworld/state/models/loongarch64/systemv/__init__.py +6 -0
- smallworld/state/models/loongarch64/systemv/c99/__init__.py +12 -0
- smallworld/state/models/loongarch64/systemv/c99/signal.py +16 -0
- smallworld/state/models/loongarch64/systemv/c99/stdio.py +265 -0
- smallworld/state/models/loongarch64/systemv/c99/stdlib.py +169 -0
- smallworld/state/models/loongarch64/systemv/c99/string.py +139 -0
- smallworld/state/models/loongarch64/systemv/c99/time.py +61 -0
- smallworld/state/models/loongarch64/systemv/posix/__init__.py +6 -0
- smallworld/state/models/loongarch64/systemv/posix/libgen.py +16 -0
- smallworld/state/models/loongarch64/systemv/posix/signal.py +157 -0
- smallworld/state/models/loongarch64/systemv/systemv.py +83 -0
- smallworld/state/models/mips/__init__.py +1 -0
- smallworld/state/models/mips/systemv/__init__.py +6 -0
- smallworld/state/models/mips/systemv/c99/__init__.py +12 -0
- smallworld/state/models/mips/systemv/c99/signal.py +16 -0
- smallworld/state/models/mips/systemv/c99/stdio.py +265 -0
- smallworld/state/models/mips/systemv/c99/stdlib.py +169 -0
- smallworld/state/models/mips/systemv/c99/string.py +139 -0
- smallworld/state/models/mips/systemv/c99/time.py +61 -0
- smallworld/state/models/mips/systemv/posix/__init__.py +6 -0
- smallworld/state/models/mips/systemv/posix/libgen.py +16 -0
- smallworld/state/models/mips/systemv/posix/signal.py +157 -0
- smallworld/state/models/mips/systemv/systemv.py +78 -0
- smallworld/state/models/mips64/__init__.py +1 -0
- smallworld/state/models/mips64/systemv/__init__.py +6 -0
- smallworld/state/models/mips64/systemv/c99/__init__.py +12 -0
- smallworld/state/models/mips64/systemv/c99/signal.py +16 -0
- smallworld/state/models/mips64/systemv/c99/stdio.py +265 -0
- smallworld/state/models/mips64/systemv/c99/stdlib.py +169 -0
- smallworld/state/models/mips64/systemv/c99/string.py +139 -0
- smallworld/state/models/mips64/systemv/c99/time.py +61 -0
- smallworld/state/models/mips64/systemv/posix/__init__.py +6 -0
- smallworld/state/models/mips64/systemv/posix/libgen.py +16 -0
- smallworld/state/models/mips64/systemv/posix/signal.py +157 -0
- smallworld/state/models/mips64/systemv/systemv.py +98 -0
- smallworld/state/models/mips64el/__init__.py +1 -0
- smallworld/state/models/mips64el/systemv/__init__.py +6 -0
- smallworld/state/models/mips64el/systemv/c99/__init__.py +12 -0
- smallworld/state/models/mips64el/systemv/c99/signal.py +16 -0
- smallworld/state/models/mips64el/systemv/c99/stdio.py +265 -0
- smallworld/state/models/mips64el/systemv/c99/stdlib.py +169 -0
- smallworld/state/models/mips64el/systemv/c99/string.py +139 -0
- smallworld/state/models/mips64el/systemv/c99/time.py +61 -0
- smallworld/state/models/mips64el/systemv/posix/__init__.py +6 -0
- smallworld/state/models/mips64el/systemv/posix/libgen.py +16 -0
- smallworld/state/models/mips64el/systemv/posix/signal.py +157 -0
- smallworld/state/models/mips64el/systemv/systemv.py +96 -0
- smallworld/state/models/mipsel/__init__.py +1 -0
- smallworld/state/models/mipsel/systemv/__init__.py +6 -0
- smallworld/state/models/mipsel/systemv/c99/__init__.py +12 -0
- smallworld/state/models/mipsel/systemv/c99/signal.py +16 -0
- smallworld/state/models/mipsel/systemv/c99/stdio.py +265 -0
- smallworld/state/models/mipsel/systemv/c99/stdlib.py +169 -0
- smallworld/state/models/mipsel/systemv/c99/string.py +139 -0
- smallworld/state/models/mipsel/systemv/c99/time.py +61 -0
- smallworld/state/models/mipsel/systemv/posix/__init__.py +6 -0
- smallworld/state/models/mipsel/systemv/posix/libgen.py +16 -0
- smallworld/state/models/mipsel/systemv/posix/signal.py +157 -0
- smallworld/state/models/mipsel/systemv/systemv.py +78 -0
- smallworld/state/models/model.py +27 -2
- smallworld/state/models/posix/__init__.py +6 -0
- smallworld/state/models/posix/libgen.py +123 -0
- smallworld/state/models/posix/signal.py +690 -0
- smallworld/state/models/powerpc/__init__.py +1 -0
- smallworld/state/models/powerpc/systemv/__init__.py +6 -0
- smallworld/state/models/powerpc/systemv/c99/__init__.py +12 -0
- smallworld/state/models/powerpc/systemv/c99/signal.py +16 -0
- smallworld/state/models/powerpc/systemv/c99/stdio.py +265 -0
- smallworld/state/models/powerpc/systemv/c99/stdlib.py +169 -0
- smallworld/state/models/powerpc/systemv/c99/string.py +139 -0
- smallworld/state/models/powerpc/systemv/c99/time.py +61 -0
- smallworld/state/models/powerpc/systemv/posix/__init__.py +6 -0
- smallworld/state/models/powerpc/systemv/posix/libgen.py +16 -0
- smallworld/state/models/powerpc/systemv/posix/signal.py +157 -0
- smallworld/state/models/powerpc/systemv/systemv.py +93 -0
- smallworld/state/models/riscv64/__init__.py +1 -0
- smallworld/state/models/riscv64/systemv/__init__.py +6 -0
- smallworld/state/models/riscv64/systemv/c99/__init__.py +12 -0
- smallworld/state/models/riscv64/systemv/c99/signal.py +16 -0
- smallworld/state/models/riscv64/systemv/c99/stdio.py +265 -0
- smallworld/state/models/riscv64/systemv/c99/stdlib.py +169 -0
- smallworld/state/models/riscv64/systemv/c99/string.py +139 -0
- smallworld/state/models/riscv64/systemv/c99/time.py +61 -0
- smallworld/state/models/riscv64/systemv/posix/__init__.py +6 -0
- smallworld/state/models/riscv64/systemv/posix/libgen.py +16 -0
- smallworld/state/models/riscv64/systemv/posix/signal.py +157 -0
- smallworld/state/models/riscv64/systemv/systemv.py +85 -0
- smallworld/state/state.py +65 -24
- smallworld/state/unstable/elf.py +16 -31
- smallworld/utils.py +6 -1
- {smallworld_re-1.0.3.dist-info → smallworld_re-2.0.0.dist-info}/METADATA +74 -42
- smallworld_re-2.0.0.dist-info/RECORD +374 -0
- {smallworld_re-1.0.3.dist-info → smallworld_re-2.0.0.dist-info}/WHEEL +1 -1
- smallworld/state/models/x86/__init__.py +0 -2
- smallworld/state/models/x86/microsoftcdecl.py +0 -35
- smallworld/state/models/x86/systemv.py +0 -240
- smallworld_re-1.0.3.dist-info/RECORD +0 -166
- /smallworld/state/models/{posix.py → _posix.py} +0 -0
- {smallworld_re-1.0.3.dist-info → smallworld_re-2.0.0.dist-info}/entry_points.txt +0 -0
- {smallworld_re-1.0.3.dist-info → smallworld_re-2.0.0.dist-info}/licenses/LICENSE.txt +0 -0
- {smallworld_re-1.0.3.dist-info → smallworld_re-2.0.0.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,595 @@
|
|
1
|
+
import logging
|
2
|
+
import random
|
3
|
+
import typing
|
4
|
+
|
5
|
+
import claripy
|
6
|
+
|
7
|
+
from .... import emulators, exceptions
|
8
|
+
from ...memory.heap import Heap
|
9
|
+
from ..cstd import ArgumentType, CStdModel
|
10
|
+
from .utils import _emu_strlen
|
11
|
+
|
12
|
+
logger = logging.getLogger("__name__")
|
13
|
+
|
14
|
+
|
15
|
+
class Abort(CStdModel):
|
16
|
+
name = "abort"
|
17
|
+
|
18
|
+
# void abort(void);
|
19
|
+
argument_types = []
|
20
|
+
return_type = ArgumentType.VOID
|
21
|
+
|
22
|
+
def model(self, emulator: emulators.Emulator) -> None:
|
23
|
+
super().model(emulator)
|
24
|
+
raise exceptions.EmulationStop("Called abort()")
|
25
|
+
|
26
|
+
|
27
|
+
class Abs(CStdModel):
|
28
|
+
name = "abs"
|
29
|
+
|
30
|
+
# int abs(int val);
|
31
|
+
argument_types = [ArgumentType.INT]
|
32
|
+
return_type = ArgumentType.INT
|
33
|
+
|
34
|
+
@property
|
35
|
+
def sign_mask(self):
|
36
|
+
return self._int_sign_mask
|
37
|
+
|
38
|
+
@property
|
39
|
+
def inv_mask(self):
|
40
|
+
return self._int_inv_mask
|
41
|
+
|
42
|
+
def model(self, emulator: emulators.Emulator) -> None:
|
43
|
+
super().model(emulator)
|
44
|
+
val = self.get_arg1(emulator)
|
45
|
+
|
46
|
+
assert isinstance(val, int)
|
47
|
+
|
48
|
+
if val & self.sign_mask:
|
49
|
+
val = ((val ^ self.inv_mask) + 1) & self.inv_mask
|
50
|
+
|
51
|
+
self.set_return_value(emulator, val)
|
52
|
+
|
53
|
+
|
54
|
+
class LAbs(Abs):
|
55
|
+
name = "labs"
|
56
|
+
|
57
|
+
# long labs(long x);
|
58
|
+
argument_types = [ArgumentType.LONG]
|
59
|
+
return_type = ArgumentType.LONG
|
60
|
+
|
61
|
+
@property
|
62
|
+
def sign_mask(self):
|
63
|
+
return self._long_sign_mask
|
64
|
+
|
65
|
+
@property
|
66
|
+
def inv_mask(self):
|
67
|
+
return self._long_inv_mask
|
68
|
+
|
69
|
+
|
70
|
+
class LLAbs(Abs):
|
71
|
+
name = "llabs"
|
72
|
+
|
73
|
+
# long long llabs(long long x);
|
74
|
+
argument_types = [ArgumentType.LONGLONG]
|
75
|
+
return_type = ArgumentType.LONGLONG
|
76
|
+
|
77
|
+
@property
|
78
|
+
def sign_mask(self):
|
79
|
+
return self._long_long_sign_mask
|
80
|
+
|
81
|
+
@property
|
82
|
+
def inv_mask(self):
|
83
|
+
return self._long_long_inv_mask
|
84
|
+
|
85
|
+
|
86
|
+
class Atexit(CStdModel):
|
87
|
+
name = "atexit"
|
88
|
+
|
89
|
+
# NOTE: In glibc binaries, relocate atexit against __cxa_atexit
|
90
|
+
# atexit is a statically-linked helper that calls __cxa_atexit
|
91
|
+
|
92
|
+
# void atexit(void);
|
93
|
+
argument_types = [ArgumentType.POINTER]
|
94
|
+
return_type = ArgumentType.INT
|
95
|
+
|
96
|
+
# This will not actually result in an exit handler getting registered.
|
97
|
+
imprecise = True
|
98
|
+
|
99
|
+
def model(self, emulator: emulators.Emulator) -> None:
|
100
|
+
super().model(emulator)
|
101
|
+
self.set_return_value(emulator, 0)
|
102
|
+
|
103
|
+
|
104
|
+
class Atof(CStdModel):
|
105
|
+
name = "atof"
|
106
|
+
|
107
|
+
# float atof(const char *str);
|
108
|
+
argument_types = [ArgumentType.POINTER]
|
109
|
+
return_type = ArgumentType.FLOAT
|
110
|
+
|
111
|
+
def model(self, emulator: emulators.Emulator) -> None:
|
112
|
+
super().model(emulator)
|
113
|
+
# TODO: Support other locales for atof
|
114
|
+
ptr = self.get_arg1(emulator)
|
115
|
+
|
116
|
+
assert isinstance(ptr, int)
|
117
|
+
|
118
|
+
n = _emu_strlen(emulator, ptr)
|
119
|
+
|
120
|
+
data = emulator.read_memory(ptr, n)
|
121
|
+
text = data.decode("utf-8")
|
122
|
+
|
123
|
+
# This is a bit tricky. Python is much less accepting than C.
|
124
|
+
text = text.strip()
|
125
|
+
found_dot = False
|
126
|
+
for i in range(0, len(text)):
|
127
|
+
if text[i].isnumeric():
|
128
|
+
continue
|
129
|
+
elif text[i] == ".":
|
130
|
+
if found_dot:
|
131
|
+
text = text[0:i]
|
132
|
+
break
|
133
|
+
else:
|
134
|
+
found_dot = True
|
135
|
+
else:
|
136
|
+
text = text[0:i]
|
137
|
+
break
|
138
|
+
if len(text) == 0:
|
139
|
+
text = "0"
|
140
|
+
|
141
|
+
self.set_return_value(emulator, float(text))
|
142
|
+
|
143
|
+
|
144
|
+
class Atoi(CStdModel):
|
145
|
+
name = "atoi"
|
146
|
+
|
147
|
+
# int atoi(const char *str);
|
148
|
+
argument_types = [ArgumentType.POINTER]
|
149
|
+
return_type = ArgumentType.INT
|
150
|
+
|
151
|
+
size_mask = 0xFFFFFFFF
|
152
|
+
|
153
|
+
def model(self, emulator: emulators.Emulator) -> None:
|
154
|
+
super().model(emulator)
|
155
|
+
# TODO: Support other locales for atoi
|
156
|
+
ptr = self.get_arg1(emulator)
|
157
|
+
|
158
|
+
assert isinstance(ptr, int)
|
159
|
+
|
160
|
+
n = _emu_strlen(emulator, ptr)
|
161
|
+
|
162
|
+
data = emulator.read_memory(ptr, n)
|
163
|
+
text = data.decode("utf-8").strip()
|
164
|
+
print(f"Converting {text} ({len(text)})")
|
165
|
+
|
166
|
+
for i in range(0, len(text)):
|
167
|
+
if not text[i].isnumeric() and text[i] != "-":
|
168
|
+
text = text[0:i]
|
169
|
+
break
|
170
|
+
|
171
|
+
if len(text) == 0:
|
172
|
+
# No valid number
|
173
|
+
self.set_return_value(emulator, 0)
|
174
|
+
return
|
175
|
+
|
176
|
+
# TODO: Not entirely sure if this is how truncation will work.
|
177
|
+
newval = int(text) & self.size_mask
|
178
|
+
self.set_return_value(emulator, newval)
|
179
|
+
|
180
|
+
|
181
|
+
class Atol(Atoi):
|
182
|
+
name = "atol"
|
183
|
+
|
184
|
+
# long atoll(const char *str);
|
185
|
+
argument_types = [ArgumentType.POINTER]
|
186
|
+
return_type = ArgumentType.LONG
|
187
|
+
|
188
|
+
size_mask = 0xFFFFFFFFFFFFFFFF
|
189
|
+
|
190
|
+
|
191
|
+
class Atoll(Atoi):
|
192
|
+
name = "atoll"
|
193
|
+
|
194
|
+
# long long atoll(const char *str);
|
195
|
+
argument_types = [ArgumentType.POINTER]
|
196
|
+
return_type = ArgumentType.LONGLONG
|
197
|
+
|
198
|
+
size_mask = 0xFFFFFFFFFFFFFFFF
|
199
|
+
|
200
|
+
|
201
|
+
class Bsearch(CStdModel):
|
202
|
+
name = "bsearch"
|
203
|
+
|
204
|
+
# void *bsearch(const void *key, const void *base,
|
205
|
+
# size_t nitems, size_t size,
|
206
|
+
# int (*compar)(const void *, const void *));
|
207
|
+
argument_types = [
|
208
|
+
ArgumentType.POINTER,
|
209
|
+
ArgumentType.POINTER,
|
210
|
+
ArgumentType.SIZE_T,
|
211
|
+
ArgumentType.SIZE_T,
|
212
|
+
ArgumentType.POINTER,
|
213
|
+
]
|
214
|
+
return_type = ArgumentType.POINTER
|
215
|
+
|
216
|
+
def model(self, emulator: emulators.Emulator) -> None:
|
217
|
+
super().model(emulator)
|
218
|
+
# Not easily possible; need to call a comparator function.
|
219
|
+
raise NotImplementedError(
|
220
|
+
"bsearch uses a function pointer; not sure how to model"
|
221
|
+
)
|
222
|
+
|
223
|
+
|
224
|
+
class Calloc(CStdModel):
|
225
|
+
name = "calloc"
|
226
|
+
|
227
|
+
# void *calloc(size_t amount, size_t size);
|
228
|
+
argument_types = [ArgumentType.SIZE_T, ArgumentType.SIZE_T]
|
229
|
+
return_type = ArgumentType.POINTER
|
230
|
+
|
231
|
+
def __init__(self, address: int):
|
232
|
+
super().__init__(address)
|
233
|
+
# Use the same heap model the harness used.
|
234
|
+
# NOTE: This will get cloned on a deep copy.
|
235
|
+
self.heap: typing.Optional[Heap] = None
|
236
|
+
|
237
|
+
def model(self, emulator: emulators.Emulator) -> None:
|
238
|
+
super().model(emulator)
|
239
|
+
if self.heap is None:
|
240
|
+
raise exceptions.ConfigurationError(
|
241
|
+
"calloc needs a heap; please assign self.heap"
|
242
|
+
)
|
243
|
+
|
244
|
+
amt = self.get_arg1(emulator)
|
245
|
+
size = self.get_arg2(emulator)
|
246
|
+
|
247
|
+
assert isinstance(amt, int)
|
248
|
+
assert isinstance(size, int)
|
249
|
+
|
250
|
+
data = b"\0" * amt * size
|
251
|
+
|
252
|
+
res = self.heap.allocate_bytes(data, None)
|
253
|
+
# This is calloc; zero out the memory
|
254
|
+
emulator.write_memory(res, data)
|
255
|
+
|
256
|
+
self.set_return_value(emulator, res)
|
257
|
+
|
258
|
+
|
259
|
+
class Div(CStdModel):
|
260
|
+
name = "div"
|
261
|
+
|
262
|
+
# div_t result(int dividend, int divisor);
|
263
|
+
argument_types = [ArgumentType.INT, ArgumentType.INT]
|
264
|
+
# FIXME: Figure out how different platforms return structs by value
|
265
|
+
|
266
|
+
def model(self, emulator: emulators.Emulator) -> None:
|
267
|
+
super().model(emulator)
|
268
|
+
# div_t result(int dividend, int divisor);
|
269
|
+
raise NotImplementedError()
|
270
|
+
|
271
|
+
|
272
|
+
class LDiv(Div):
|
273
|
+
name = "ldiv"
|
274
|
+
|
275
|
+
# ldiv_t result(long dividend, long divisor);
|
276
|
+
argument_types = [ArgumentType.LONG, ArgumentType.LONG]
|
277
|
+
# FIXME: Figure out how different platforms return structs by value
|
278
|
+
|
279
|
+
|
280
|
+
class LLDiv(Div):
|
281
|
+
name = "lldiv"
|
282
|
+
|
283
|
+
# lldiv_t result(long long dividend, long long divisor);
|
284
|
+
argument_types = [ArgumentType.LONGLONG, ArgumentType.LONGLONG]
|
285
|
+
# FIXME: Figure out how different platforms return structs by value
|
286
|
+
|
287
|
+
|
288
|
+
class Exit(CStdModel):
|
289
|
+
name = "exit"
|
290
|
+
|
291
|
+
# void exit(int code);
|
292
|
+
argument_types = [ArgumentType.INT]
|
293
|
+
return_type = ArgumentType.VOID
|
294
|
+
|
295
|
+
def model(self, emulator: emulators.Emulator) -> None:
|
296
|
+
super().model(emulator)
|
297
|
+
raise exceptions.EmulationStop("Called exit()")
|
298
|
+
|
299
|
+
|
300
|
+
class Free(CStdModel):
|
301
|
+
name = "free"
|
302
|
+
|
303
|
+
# void free(void *ptr);
|
304
|
+
argument_types = [ArgumentType.POINTER]
|
305
|
+
return_type = ArgumentType.VOID
|
306
|
+
|
307
|
+
def __init__(self, address: int):
|
308
|
+
super().__init__(address)
|
309
|
+
# Use the same heap model the harness used.
|
310
|
+
# NOTE: This will get cloned on a deep copy.
|
311
|
+
self.heap: typing.Optional[Heap] = None
|
312
|
+
|
313
|
+
def model(self, emulator: emulators.Emulator) -> None:
|
314
|
+
super().model(emulator)
|
315
|
+
if self.heap is None:
|
316
|
+
raise exceptions.ConfigurationError(
|
317
|
+
"malloc needs a heap; please assign self.heap"
|
318
|
+
)
|
319
|
+
|
320
|
+
ptr = self.get_arg1(emulator)
|
321
|
+
|
322
|
+
assert isinstance(ptr, int)
|
323
|
+
|
324
|
+
self.heap.free(ptr)
|
325
|
+
|
326
|
+
|
327
|
+
class Getenv(CStdModel):
|
328
|
+
name = "getenv"
|
329
|
+
|
330
|
+
# char *getenv(char *name);
|
331
|
+
argument_types = [ArgumentType.POINTER]
|
332
|
+
return_type = ArgumentType.POINTER
|
333
|
+
|
334
|
+
# We don't have a model of envp,
|
335
|
+
# so this will always return NULL
|
336
|
+
imprecise = True
|
337
|
+
|
338
|
+
def model(self, emulator: emulators.Emulator) -> None:
|
339
|
+
super().model(emulator)
|
340
|
+
ptr = self.get_arg1(emulator)
|
341
|
+
|
342
|
+
assert isinstance(ptr, int)
|
343
|
+
|
344
|
+
size = _emu_strlen(emulator, ptr)
|
345
|
+
data = emulator.read_memory(ptr, size)
|
346
|
+
name = data.decode("utf-8")
|
347
|
+
|
348
|
+
logger.info(f"getenv({name});")
|
349
|
+
self.set_return_value(emulator, 0)
|
350
|
+
|
351
|
+
|
352
|
+
class Malloc(CStdModel):
|
353
|
+
name = "malloc"
|
354
|
+
|
355
|
+
# void *malloc(size_t size);
|
356
|
+
argument_types = [ArgumentType.SIZE_T]
|
357
|
+
return_type = ArgumentType.POINTER
|
358
|
+
|
359
|
+
def __init__(self, address: int):
|
360
|
+
super().__init__(address)
|
361
|
+
# Use the same heap model the harness used.
|
362
|
+
# NOTE: This will get cloned on a deep copy.
|
363
|
+
self.heap: typing.Optional[Heap] = None
|
364
|
+
|
365
|
+
def model(self, emulator: emulators.Emulator) -> None:
|
366
|
+
super().model(emulator)
|
367
|
+
if self.heap is None:
|
368
|
+
raise exceptions.ConfigurationError(
|
369
|
+
"malloc needs a heap; please assign self.heap"
|
370
|
+
)
|
371
|
+
|
372
|
+
size = self.get_arg1(emulator)
|
373
|
+
|
374
|
+
assert isinstance(size, int)
|
375
|
+
|
376
|
+
res = self.heap.allocate_bytes(b"\0" * size, None)
|
377
|
+
|
378
|
+
self.set_return_value(emulator, res)
|
379
|
+
|
380
|
+
|
381
|
+
class Mblen(CStdModel):
|
382
|
+
name = "mblen"
|
383
|
+
|
384
|
+
# int mblen(char *str, size_t n);
|
385
|
+
argument_types = [ArgumentType.POINTER, ArgumentType.SIZE_T]
|
386
|
+
return_type = ArgumentType.INT
|
387
|
+
|
388
|
+
def model(self, emulator: emulators.Emulator) -> None:
|
389
|
+
super().model(emulator)
|
390
|
+
# Depends the locale.
|
391
|
+
raise NotImplementedError()
|
392
|
+
|
393
|
+
|
394
|
+
class Mbstowcs(CStdModel):
|
395
|
+
name = "mbstowcs"
|
396
|
+
|
397
|
+
# size_t mbstowcs(schar_t *pwcs, char *str, size_t n);
|
398
|
+
argument_types = [ArgumentType.POINTER, ArgumentType.POINTER, ArgumentType.SIZE_T]
|
399
|
+
return_type = ArgumentType.SIZE_T
|
400
|
+
|
401
|
+
def model(self, emulator: emulators.Emulator) -> None:
|
402
|
+
super().model(emulator)
|
403
|
+
# Depends the locale.
|
404
|
+
raise NotImplementedError()
|
405
|
+
|
406
|
+
|
407
|
+
class Mbtowc(CStdModel):
|
408
|
+
name = "mbtowc"
|
409
|
+
|
410
|
+
# size_t mbtowc(wchar_t *pwcs, char *str, size_t n);
|
411
|
+
argument_types = [ArgumentType.POINTER, ArgumentType.POINTER, ArgumentType.SIZE_T]
|
412
|
+
return_type = ArgumentType.INT
|
413
|
+
|
414
|
+
def model(self, emulator: emulators.Emulator) -> None:
|
415
|
+
super().model(emulator)
|
416
|
+
# Depends the locale.
|
417
|
+
raise NotImplementedError()
|
418
|
+
|
419
|
+
|
420
|
+
class QSort(CStdModel):
|
421
|
+
name = "qsort"
|
422
|
+
|
423
|
+
# void qsort(void *arr, size_t amount, size_t size, int (*compare)(const void *, const void *));
|
424
|
+
argument_types = [
|
425
|
+
ArgumentType.POINTER,
|
426
|
+
ArgumentType.SIZE_T,
|
427
|
+
ArgumentType.SIZE_T,
|
428
|
+
ArgumentType.POINTER,
|
429
|
+
]
|
430
|
+
return_type = ArgumentType.VOID
|
431
|
+
|
432
|
+
def model(self, emulator: emulators.Emulator) -> None:
|
433
|
+
super().model(emulator)
|
434
|
+
# Not easily possible; need to call a comparator function.
|
435
|
+
raise NotImplementedError(
|
436
|
+
"qsort uses a function pointer; not sure how to model"
|
437
|
+
)
|
438
|
+
|
439
|
+
|
440
|
+
class Rand(CStdModel):
|
441
|
+
name = "rand"
|
442
|
+
|
443
|
+
# int rand(void);
|
444
|
+
argument_types = []
|
445
|
+
return_type = ArgumentType.INT
|
446
|
+
|
447
|
+
rand = random.Random()
|
448
|
+
|
449
|
+
def model(self, emulator: emulators.Emulator) -> None:
|
450
|
+
super().model(emulator)
|
451
|
+
# TODO: Rand is easy to do simply, harder to do right.
|
452
|
+
# If someone is relying on srand/rand to produce a specific sequence,
|
453
|
+
# this won't behave correctly.
|
454
|
+
val = self.rand.randint(0, 2147483647)
|
455
|
+
self.set_return_value(emulator, val)
|
456
|
+
|
457
|
+
|
458
|
+
class Realloc(CStdModel):
|
459
|
+
name = "realloc"
|
460
|
+
|
461
|
+
# void *realloc(void *ptr, size_t size);
|
462
|
+
argument_types = [ArgumentType.POINTER, ArgumentType.SIZE_T]
|
463
|
+
return_type = ArgumentType.POINTER
|
464
|
+
|
465
|
+
def __init__(self, address: int):
|
466
|
+
super().__init__(address)
|
467
|
+
# Use the same heap model the harness used.
|
468
|
+
# NOTE: This will get cloned on a deep copy.
|
469
|
+
self.heap: typing.Optional[Heap] = None
|
470
|
+
|
471
|
+
def model(self, emulator: emulators.Emulator) -> None:
|
472
|
+
super().model(emulator)
|
473
|
+
if self.heap is None:
|
474
|
+
raise exceptions.ConfigurationError(
|
475
|
+
"realloc needs a heap; please assign self.heap"
|
476
|
+
)
|
477
|
+
|
478
|
+
ptr = self.get_arg1(emulator)
|
479
|
+
size = self.get_arg2(emulator)
|
480
|
+
|
481
|
+
assert isinstance(ptr, int)
|
482
|
+
assert isinstance(size, int)
|
483
|
+
|
484
|
+
logger.warning(f"REALLOC {hex(ptr)}, {size}")
|
485
|
+
|
486
|
+
if ptr == 0:
|
487
|
+
res = self.heap.allocate_bytes(b"\0" * size, None)
|
488
|
+
elif ptr - self.heap.address not in self.heap:
|
489
|
+
raise exceptions.EmulationError(
|
490
|
+
f"Attempted to realloc {hex(ptr)}, which was not malloc'd on this heap"
|
491
|
+
)
|
492
|
+
else:
|
493
|
+
oldsize = self.heap[ptr - self.heap.address].get_size()
|
494
|
+
data: typing.Union[bytes, claripy.ast.bv.BV]
|
495
|
+
try:
|
496
|
+
data = emulator.read_memory(ptr, oldsize)
|
497
|
+
except exceptions.SymbolicValueError:
|
498
|
+
data = emulator.read_memory_symbolic(ptr, oldsize)
|
499
|
+
|
500
|
+
self.heap.free(ptr)
|
501
|
+
|
502
|
+
res = self.heap.allocate_bytes(b"\0" * size, None)
|
503
|
+
emulator.write_memory(res, data)
|
504
|
+
|
505
|
+
self.set_return_value(emulator, res)
|
506
|
+
|
507
|
+
|
508
|
+
class Srand(CStdModel):
|
509
|
+
name = "srand"
|
510
|
+
|
511
|
+
# void srand(int seed);
|
512
|
+
argument_types = [ArgumentType.INT]
|
513
|
+
return_type = ArgumentType.VOID
|
514
|
+
|
515
|
+
def model(self, emulator: emulators.Emulator) -> None:
|
516
|
+
super().model(emulator)
|
517
|
+
seed = self.get_arg1(emulator)
|
518
|
+
Rand.rand.seed(a=seed)
|
519
|
+
|
520
|
+
|
521
|
+
class System(CStdModel):
|
522
|
+
name = "system"
|
523
|
+
|
524
|
+
argument_types = [ArgumentType.POINTER]
|
525
|
+
return_type = ArgumentType.INT
|
526
|
+
|
527
|
+
def model(self, emulator: emulators.Emulator) -> None:
|
528
|
+
super().model(emulator)
|
529
|
+
ptr = self.get_arg1(emulator)
|
530
|
+
|
531
|
+
assert isinstance(ptr, int)
|
532
|
+
|
533
|
+
size = _emu_strlen(emulator, ptr)
|
534
|
+
data = emulator.read_memory(ptr, size)
|
535
|
+
cmd = data.decode("utf-8")
|
536
|
+
|
537
|
+
logger.info(f"system({cmd});")
|
538
|
+
self.set_return_value(emulator, 0)
|
539
|
+
|
540
|
+
|
541
|
+
class Wcstombs(CStdModel):
|
542
|
+
name = "wctombs"
|
543
|
+
|
544
|
+
# size_t wctombs(char *str, wchar_t *pwcs, size_t n);
|
545
|
+
argument_types = [ArgumentType.POINTER, ArgumentType.POINTER, ArgumentType.SIZE_T]
|
546
|
+
return_type = ArgumentType.SIZE_T
|
547
|
+
|
548
|
+
def model(self, emulator: emulators.Emulator) -> None:
|
549
|
+
super().model(emulator)
|
550
|
+
# Depends the locale.
|
551
|
+
raise NotImplementedError()
|
552
|
+
|
553
|
+
|
554
|
+
class Wctomb(CStdModel):
|
555
|
+
name = "wctomb"
|
556
|
+
|
557
|
+
# int wctomb(char *str, wchar_t wchar);
|
558
|
+
argument_types = [ArgumentType.POINTER, ArgumentType.UINT]
|
559
|
+
return_type = ArgumentType.INT
|
560
|
+
|
561
|
+
def model(self, emulator: emulators.Emulator) -> None:
|
562
|
+
super().model(emulator)
|
563
|
+
# Depends the locale.
|
564
|
+
raise NotImplementedError()
|
565
|
+
|
566
|
+
|
567
|
+
__all__ = [
|
568
|
+
"Abs",
|
569
|
+
"LAbs",
|
570
|
+
"LLAbs",
|
571
|
+
"Abort",
|
572
|
+
"Atexit",
|
573
|
+
"Atof",
|
574
|
+
"Atoi",
|
575
|
+
"Atol",
|
576
|
+
"Atoll",
|
577
|
+
"Calloc",
|
578
|
+
"Div",
|
579
|
+
"LDiv",
|
580
|
+
"LLDiv",
|
581
|
+
"Exit",
|
582
|
+
"Free",
|
583
|
+
"Getenv",
|
584
|
+
"Malloc",
|
585
|
+
"Mblen",
|
586
|
+
"Mbstowcs",
|
587
|
+
"Mbtowc",
|
588
|
+
"QSort",
|
589
|
+
"Rand",
|
590
|
+
"Realloc",
|
591
|
+
"Srand",
|
592
|
+
"System",
|
593
|
+
"Wcstombs",
|
594
|
+
"Wctomb",
|
595
|
+
]
|