smallworld-re 1.0.2__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 +44 -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 +225 -61
- 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.2.dist-info → smallworld_re-2.0.0.dist-info}/METADATA +76 -43
- smallworld_re-2.0.0.dist-info/RECORD +374 -0
- {smallworld_re-1.0.2.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.2.dist-info/RECORD +0 -166
- /smallworld/state/models/{posix.py → _posix.py} +0 -0
- {smallworld_re-1.0.2.dist-info → smallworld_re-2.0.0.dist-info}/entry_points.txt +0 -0
- {smallworld_re-1.0.2.dist-info → smallworld_re-2.0.0.dist-info/licenses}/LICENSE.txt +0 -0
- {smallworld_re-1.0.2.dist-info → smallworld_re-2.0.0.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,340 @@
|
|
1
|
+
import os
|
2
|
+
import time
|
3
|
+
import typing
|
4
|
+
|
5
|
+
from ....emulators import Emulator
|
6
|
+
from ..cstd import ArgumentType, CStdModel
|
7
|
+
from .utils import _emu_strlen
|
8
|
+
|
9
|
+
# NOTE: time_t and clock_t are longs.
|
10
|
+
# As such, all your 32-bit routers are vulnerable to the 2038 bug.
|
11
|
+
|
12
|
+
|
13
|
+
class TimeModel(CStdModel):
|
14
|
+
def time_struct_to_tuple(self, ptr: int, emulator: Emulator):
|
15
|
+
# Load the fields out of the struct
|
16
|
+
tm_sec = self.read_integer(ptr, ArgumentType.INT, emulator)
|
17
|
+
tm_min = self.read_integer(ptr + 0x4, ArgumentType.INT, emulator)
|
18
|
+
tm_hour = self.read_integer(ptr + 0x8, ArgumentType.INT, emulator)
|
19
|
+
tm_mday = self.read_integer(ptr + 0xC, ArgumentType.INT, emulator)
|
20
|
+
tm_mon = self.read_integer(ptr + 0x10, ArgumentType.INT, emulator)
|
21
|
+
tm_year = self.read_integer(ptr + 0x14, ArgumentType.INT, emulator)
|
22
|
+
tm_wday = self.read_integer(ptr + 0x18, ArgumentType.INT, emulator)
|
23
|
+
tm_yday = self.read_integer(ptr + 0x1C, ArgumentType.INT, emulator)
|
24
|
+
tm_isdst = self.read_integer(ptr + 0x20, ArgumentType.INT, emulator)
|
25
|
+
|
26
|
+
# Load data into a python struct
|
27
|
+
# A few of the fields are represented a bit differently
|
28
|
+
out = (
|
29
|
+
tm_year + 1900,
|
30
|
+
tm_mon + 1,
|
31
|
+
tm_mday,
|
32
|
+
tm_hour,
|
33
|
+
tm_min,
|
34
|
+
tm_sec,
|
35
|
+
tm_wday - 1,
|
36
|
+
tm_yday + 1,
|
37
|
+
tm_isdst,
|
38
|
+
)
|
39
|
+
|
40
|
+
return out
|
41
|
+
|
42
|
+
def tuple_to_time_struct(
|
43
|
+
self,
|
44
|
+
tp: typing.Tuple[int, int, int, int, int, int, int, int, int],
|
45
|
+
ptr: int,
|
46
|
+
emulator: Emulator,
|
47
|
+
):
|
48
|
+
(
|
49
|
+
tm_year,
|
50
|
+
tm_mon,
|
51
|
+
tm_mday,
|
52
|
+
tm_hour,
|
53
|
+
tm_min,
|
54
|
+
tm_sec,
|
55
|
+
tm_wday,
|
56
|
+
tm_yday,
|
57
|
+
tm_isdst,
|
58
|
+
) = tp
|
59
|
+
|
60
|
+
# Convert the Python representation to C's representation
|
61
|
+
tm_year -= 1900
|
62
|
+
tm_mon -= 1
|
63
|
+
tm_wday += 1
|
64
|
+
tm_yday -= 1
|
65
|
+
|
66
|
+
# Store the fields back to the struct
|
67
|
+
self.write_integer(ptr, tm_sec, ArgumentType.INT, emulator)
|
68
|
+
self.write_integer(ptr + 0x4, tm_min, ArgumentType.INT, emulator)
|
69
|
+
self.write_integer(ptr + 0x8, tm_hour, ArgumentType.INT, emulator)
|
70
|
+
self.write_integer(ptr + 0xC, tm_mday, ArgumentType.INT, emulator)
|
71
|
+
self.write_integer(ptr + 0x10, tm_mon, ArgumentType.INT, emulator)
|
72
|
+
self.write_integer(ptr + 0x14, tm_year, ArgumentType.INT, emulator)
|
73
|
+
self.write_integer(ptr + 0x18, tm_wday, ArgumentType.INT, emulator)
|
74
|
+
self.write_integer(ptr + 0x1C, tm_yday, ArgumentType.INT, emulator)
|
75
|
+
self.write_integer(ptr + 0x20, tm_isdst, ArgumentType.INT, emulator)
|
76
|
+
|
77
|
+
|
78
|
+
class Time(TimeModel):
|
79
|
+
name = "time"
|
80
|
+
|
81
|
+
# time_t time(time_t *tloc);
|
82
|
+
argument_types = [ArgumentType.POINTER]
|
83
|
+
return_type = ArgumentType.LONG
|
84
|
+
|
85
|
+
def model(self, emulator: Emulator) -> None:
|
86
|
+
super().model(emulator)
|
87
|
+
|
88
|
+
ptr = self.get_arg1(emulator)
|
89
|
+
|
90
|
+
assert isinstance(ptr, int)
|
91
|
+
|
92
|
+
intval = int(time.time())
|
93
|
+
|
94
|
+
if ptr != 0:
|
95
|
+
self.write_integer(ptr, intval, ArgumentType.LONG, emulator)
|
96
|
+
|
97
|
+
self.set_return_value(emulator, intval)
|
98
|
+
|
99
|
+
|
100
|
+
class Localtime(TimeModel):
|
101
|
+
name = "localtime"
|
102
|
+
|
103
|
+
# struct tm *localtime(const time_t *timep);
|
104
|
+
argument_types = [ArgumentType.POINTER]
|
105
|
+
return_type = ArgumentType.POINTER
|
106
|
+
|
107
|
+
# Need a static struct tm
|
108
|
+
# NOTE: This looks bigger, because GNU struct tms have extra fields.
|
109
|
+
static_space_required = 64
|
110
|
+
|
111
|
+
def model(self, emulator: Emulator) -> None:
|
112
|
+
super().model(emulator)
|
113
|
+
|
114
|
+
ptr = self.get_arg1(emulator)
|
115
|
+
|
116
|
+
assert isinstance(ptr, int)
|
117
|
+
|
118
|
+
tv = self.read_integer(ptr, ArgumentType.LONG, emulator)
|
119
|
+
|
120
|
+
timetuple = time.localtime(tv)
|
121
|
+
|
122
|
+
assert self.static_buffer_address is not None
|
123
|
+
|
124
|
+
self.tuple_to_time_struct(timetuple, self.static_buffer_address, emulator)
|
125
|
+
self.set_return_value(emulator, self.static_buffer_address)
|
126
|
+
|
127
|
+
|
128
|
+
class Gmtime(TimeModel):
|
129
|
+
name = "gmtime"
|
130
|
+
|
131
|
+
# struct tm *gmtime(const time_t *timep);
|
132
|
+
argument_types = [ArgumentType.POINTER]
|
133
|
+
return_type = ArgumentType.POINTER
|
134
|
+
|
135
|
+
# Need a static struct tm
|
136
|
+
# NOTE: This looks bigger, because GNU struct tms have extra fields.
|
137
|
+
static_space_required = 64
|
138
|
+
|
139
|
+
def model(self, emulator: Emulator) -> None:
|
140
|
+
super().model(emulator)
|
141
|
+
|
142
|
+
ptr = self.get_arg1(emulator)
|
143
|
+
|
144
|
+
assert isinstance(ptr, int)
|
145
|
+
|
146
|
+
tv = self.read_integer(ptr, ArgumentType.LONG, emulator)
|
147
|
+
|
148
|
+
timetuple = time.gmtime(tv)
|
149
|
+
|
150
|
+
assert self.static_buffer_address is not None
|
151
|
+
|
152
|
+
self.tuple_to_time_struct(timetuple, self.static_buffer_address, emulator)
|
153
|
+
self.set_return_value(emulator, self.static_buffer_address)
|
154
|
+
|
155
|
+
|
156
|
+
class Ctime(TimeModel):
|
157
|
+
name = "ctime"
|
158
|
+
|
159
|
+
# struct tm *ctime(const time_t *timep);
|
160
|
+
argument_types = [ArgumentType.POINTER]
|
161
|
+
return_type = ArgumentType.POINTER
|
162
|
+
|
163
|
+
static_space_required = 26
|
164
|
+
|
165
|
+
def model(self, emulator: Emulator) -> None:
|
166
|
+
super().model(emulator)
|
167
|
+
|
168
|
+
ptr = self.get_arg1(emulator)
|
169
|
+
|
170
|
+
assert isinstance(ptr, int)
|
171
|
+
|
172
|
+
tv = self.read_integer(ptr, ArgumentType.LONG, emulator)
|
173
|
+
|
174
|
+
timestr = time.ctime(tv)
|
175
|
+
timebytes = timestr.encode("utf-8") + b"\n\0"
|
176
|
+
|
177
|
+
assert len(timebytes) <= 26
|
178
|
+
assert self.static_buffer_address is not None
|
179
|
+
|
180
|
+
emulator.write_memory(self.static_buffer_address, timebytes)
|
181
|
+
self.set_return_value(emulator, self.static_buffer_address)
|
182
|
+
|
183
|
+
|
184
|
+
class Asctime(TimeModel):
|
185
|
+
name = "asctime"
|
186
|
+
|
187
|
+
# char *asctime(const struct tm *tp);
|
188
|
+
argument_types = [ArgumentType.POINTER]
|
189
|
+
return_type = ArgumentType.POINTER
|
190
|
+
|
191
|
+
# Need a 26-byte static buffer to store the output string
|
192
|
+
static_space_required = 26
|
193
|
+
|
194
|
+
def model(self, emulator: Emulator) -> None:
|
195
|
+
super().model(emulator)
|
196
|
+
|
197
|
+
ptr = self.get_arg1(emulator)
|
198
|
+
|
199
|
+
assert isinstance(ptr, int)
|
200
|
+
|
201
|
+
timetuple = self.time_struct_to_tuple(ptr, emulator)
|
202
|
+
|
203
|
+
# FIXME: mktime is timezone dependent
|
204
|
+
# This is actually something of a pain to handle. For now, assume UTC.
|
205
|
+
old_tz = None
|
206
|
+
if "TZ" in os.environ:
|
207
|
+
old_tz = os.environ["TZ"]
|
208
|
+
os.environ["TZ"] = "UTC"
|
209
|
+
time.tzset()
|
210
|
+
|
211
|
+
print(timetuple)
|
212
|
+
timestr = time.asctime(timetuple)
|
213
|
+
print(timestr)
|
214
|
+
|
215
|
+
if old_tz is None:
|
216
|
+
del os.environ["TZ"]
|
217
|
+
else:
|
218
|
+
os.environ["TZ"] = old_tz
|
219
|
+
time.tzset()
|
220
|
+
|
221
|
+
timebytes = timestr.encode("utf-8") + b"\n\0"
|
222
|
+
|
223
|
+
assert len(timebytes) <= 26
|
224
|
+
assert self.static_buffer_address is not None
|
225
|
+
|
226
|
+
emulator.write_memory(self.static_buffer_address, timebytes)
|
227
|
+
|
228
|
+
self.set_return_value(emulator, self.static_buffer_address)
|
229
|
+
|
230
|
+
|
231
|
+
class Strftime(TimeModel):
|
232
|
+
name = "strftime"
|
233
|
+
|
234
|
+
# size_t strftime(char *dst, size_t max, const char *fmt, const struct tm *tp);
|
235
|
+
argument_types = [
|
236
|
+
ArgumentType.POINTER,
|
237
|
+
ArgumentType.SIZE_T,
|
238
|
+
ArgumentType.POINTER,
|
239
|
+
ArgumentType.POINTER,
|
240
|
+
]
|
241
|
+
return_type = ArgumentType.SIZE_T
|
242
|
+
|
243
|
+
def model(self, emulator: Emulator) -> None:
|
244
|
+
super().model(emulator)
|
245
|
+
|
246
|
+
dst = self.get_arg1(emulator)
|
247
|
+
max = self.get_arg2(emulator)
|
248
|
+
fmt = self.get_arg3(emulator)
|
249
|
+
ptr = self.get_arg4(emulator)
|
250
|
+
|
251
|
+
assert isinstance(dst, int)
|
252
|
+
assert isinstance(max, int)
|
253
|
+
assert isinstance(fmt, int)
|
254
|
+
assert isinstance(ptr, int)
|
255
|
+
|
256
|
+
fmtlen = _emu_strlen(emulator, fmt)
|
257
|
+
fmtbytes = emulator.read_memory(fmt, fmtlen)
|
258
|
+
fmtstr = fmtbytes.decode("utf-8")
|
259
|
+
|
260
|
+
timetuple = self.time_struct_to_tuple(ptr, emulator)
|
261
|
+
timestr = time.strftime(fmtstr, timetuple)
|
262
|
+
timebytes = timestr.encode("utf-8")
|
263
|
+
timebytes += b"\0"
|
264
|
+
|
265
|
+
if len(timebytes) > max:
|
266
|
+
self.set_return_value(emulator, 0)
|
267
|
+
else:
|
268
|
+
emulator.write_memory(dst, timebytes)
|
269
|
+
self.set_return_value(emulator, len(timebytes))
|
270
|
+
|
271
|
+
|
272
|
+
class Difftime(TimeModel):
|
273
|
+
name = "difftime"
|
274
|
+
|
275
|
+
# double difftime(time_t time0, time_t time1);
|
276
|
+
argument_types = [ArgumentType.LONG, ArgumentType.LONG]
|
277
|
+
return_type = ArgumentType.DOUBLE
|
278
|
+
|
279
|
+
def model(self, emulator: Emulator) -> None:
|
280
|
+
super().model(emulator)
|
281
|
+
|
282
|
+
time0 = self.get_arg1(emulator)
|
283
|
+
time1 = self.get_arg2(emulator)
|
284
|
+
|
285
|
+
assert isinstance(time0, int)
|
286
|
+
assert isinstance(time1, int)
|
287
|
+
|
288
|
+
# Times are longs. Why does this return a double?
|
289
|
+
# The world is full of mysteries...
|
290
|
+
diff = float(time1 - time0)
|
291
|
+
|
292
|
+
self.set_return_value(emulator, diff)
|
293
|
+
|
294
|
+
|
295
|
+
class Mktime(TimeModel):
|
296
|
+
name = "mktime"
|
297
|
+
|
298
|
+
# time_t mktime(struct tm *tp);
|
299
|
+
argument_types = [ArgumentType.POINTER]
|
300
|
+
return_type = ArgumentType.LONG
|
301
|
+
|
302
|
+
def model(self, emulator: Emulator) -> None:
|
303
|
+
super().model(emulator)
|
304
|
+
|
305
|
+
ptr = self.get_arg1(emulator)
|
306
|
+
|
307
|
+
assert isinstance(ptr, int)
|
308
|
+
|
309
|
+
timetuple = self.time_struct_to_tuple(ptr, emulator)
|
310
|
+
timefloat = time.mktime(timetuple)
|
311
|
+
|
312
|
+
self.set_return_value(emulator, int(timefloat))
|
313
|
+
|
314
|
+
|
315
|
+
class Clock(TimeModel):
|
316
|
+
name = "clock"
|
317
|
+
|
318
|
+
# clock_t clock(void)
|
319
|
+
argument_types = []
|
320
|
+
return_type = ArgumentType.LONG
|
321
|
+
|
322
|
+
def model(self, emulator: Emulator) -> None:
|
323
|
+
super().model(emulator)
|
324
|
+
floatval = time.clock_gettime(time.CLOCK_PROCESS_CPUTIME_ID)
|
325
|
+
floatval /= time.clock_getres(time.CLOCK_PROCESS_CPUTIME_ID)
|
326
|
+
|
327
|
+
self.set_return_value(emulator, int(floatval))
|
328
|
+
|
329
|
+
|
330
|
+
__all__ = [
|
331
|
+
"Time",
|
332
|
+
"Localtime",
|
333
|
+
"Gmtime",
|
334
|
+
"Ctime",
|
335
|
+
"Asctime",
|
336
|
+
"Strftime",
|
337
|
+
"Difftime",
|
338
|
+
"Mktime",
|
339
|
+
"Clock",
|
340
|
+
]
|
@@ -0,0 +1,89 @@
|
|
1
|
+
import logging
|
2
|
+
|
3
|
+
from .... import emulators
|
4
|
+
|
5
|
+
logger = logging.getLogger(__name__)
|
6
|
+
|
7
|
+
# Maximum string length.
|
8
|
+
# Used to terminate unbounded string operations
|
9
|
+
MAX_STRLEN = 0x10000
|
10
|
+
|
11
|
+
# Common memory manipulation operations used by a lot of library functions.
|
12
|
+
|
13
|
+
|
14
|
+
def _emu_strnlen(emulator: emulators.Emulator, addr: int, n: int) -> int:
|
15
|
+
sl = 0
|
16
|
+
while sl <= n:
|
17
|
+
b_opt = emulator.read_memory(addr + sl, 1)
|
18
|
+
if b_opt is not None:
|
19
|
+
b = b_opt[0]
|
20
|
+
if b == 0:
|
21
|
+
break
|
22
|
+
sl += 1
|
23
|
+
else:
|
24
|
+
assert b_opt is not None
|
25
|
+
return sl
|
26
|
+
|
27
|
+
|
28
|
+
def _emu_strlen(emulator: emulators.Emulator, addr: int) -> int:
|
29
|
+
return _emu_strnlen(emulator, addr, MAX_STRLEN)
|
30
|
+
|
31
|
+
|
32
|
+
def _emu_memcpy(emulator: emulators.Emulator, dst: int, src: int, n: int) -> None:
|
33
|
+
src_bytes = emulator.read_memory(src, n)
|
34
|
+
emulator.write_memory(dst, src_bytes)
|
35
|
+
|
36
|
+
|
37
|
+
def _emu_strncpy(emulator: emulators.Emulator, dst: int, src: int, n: int) -> None:
|
38
|
+
# strncpy is slightly different from strcpy and memcpy;
|
39
|
+
# it zero-fills any unused space in the buffer.
|
40
|
+
actual = n
|
41
|
+
src_len = _emu_strlen(emulator, src) + 1
|
42
|
+
if src_len < n:
|
43
|
+
actual = src_len
|
44
|
+
|
45
|
+
data = emulator.read_memory(src, actual)
|
46
|
+
data += b"\0" * (n - actual)
|
47
|
+
|
48
|
+
print(f"Writing {n} bytes to {hex(dst)}")
|
49
|
+
emulator.write_memory(dst, data)
|
50
|
+
|
51
|
+
|
52
|
+
def _emu_memcmp(emulator: emulators.Emulator, ptr1: int, ptr2: int, n: int) -> int:
|
53
|
+
for i in range(0, n):
|
54
|
+
char1 = emulator.read_memory(ptr1 + i, 1)[0]
|
55
|
+
char2 = emulator.read_memory(ptr2 + i, 1)[0]
|
56
|
+
if char1 != char2:
|
57
|
+
return char1 - char2
|
58
|
+
return 0
|
59
|
+
|
60
|
+
|
61
|
+
def _emu_strncmp(emulator: emulators.Emulator, ptr1: int, ptr2: int, n: int) -> int:
|
62
|
+
for i in range(0, n):
|
63
|
+
char1 = emulator.read_memory(ptr1 + i, 1)[0]
|
64
|
+
char2 = emulator.read_memory(ptr2 + i, 1)[0]
|
65
|
+
if char1 == 0 or char2 == 0:
|
66
|
+
return char1 - char2
|
67
|
+
elif char1 != char2:
|
68
|
+
return char1 - char2
|
69
|
+
return 0
|
70
|
+
|
71
|
+
|
72
|
+
def _emu_strncat(emulator: emulators.Emulator, dst: int, src: int, n: int) -> None:
|
73
|
+
if n == 0:
|
74
|
+
return
|
75
|
+
if emulator.read_memory(src, 1) is None:
|
76
|
+
logger.debug("MEM not available in strncpy read @ {src:x}")
|
77
|
+
elif emulator.read_memory(dst, 1) is None:
|
78
|
+
logger.debug("MEM not available in strncpy write @ {dst:x}")
|
79
|
+
else:
|
80
|
+
# at least a byte is available at both src and dst
|
81
|
+
ld = _emu_strnlen(emulator, dst, MAX_STRLEN)
|
82
|
+
ls = _emu_strnlen(emulator, src, MAX_STRLEN)
|
83
|
+
lsn = min(ls, n)
|
84
|
+
b_opt = emulator.read_memory(src, lsn)
|
85
|
+
if b_opt is not None:
|
86
|
+
src_bytes = b_opt + b"\0"
|
87
|
+
emulator.write_memory(dst + ld, src_bytes)
|
88
|
+
else:
|
89
|
+
assert b_opt is not None
|