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
smallworld/state/unstable/elf.py
CHANGED
@@ -5,11 +5,9 @@ import lief
|
|
5
5
|
|
6
6
|
from ..emulators import Emulator
|
7
7
|
from ..exceptions import ConfigurationError
|
8
|
-
from ..hinting import Hint, get_hinter
|
9
8
|
from .state import Code, Memory
|
10
9
|
|
11
10
|
log = logging.getLogger(__name__)
|
12
|
-
hinter = get_hinter(__name__)
|
13
11
|
|
14
12
|
# Prorgam header types
|
15
13
|
PT_NULL = 0 # Empty/unused program header
|
@@ -89,10 +87,9 @@ class ELFImage(Code):
|
|
89
87
|
# Progam file does not need a specific base address
|
90
88
|
# Use a default
|
91
89
|
# FIXME: Using a fixed value will not be valid if we load multiple files
|
92
|
-
|
93
|
-
|
90
|
+
log.info(
|
91
|
+
f"No base address requested, and ELF is PIC. Using {hex(self.default_base)}"
|
94
92
|
)
|
95
|
-
hinter.info(hint)
|
96
93
|
self.base = self.default_base
|
97
94
|
else:
|
98
95
|
# Program file needs a specific base address
|
@@ -111,10 +108,9 @@ class ELFImage(Code):
|
|
111
108
|
else:
|
112
109
|
# Program file needs a specific base address
|
113
110
|
# Not possible to rebase
|
114
|
-
|
115
|
-
|
111
|
+
log.error(
|
112
|
+
f"Requested base address {hex(self.user_base)}, but program needs {hex(self.file_base)}"
|
116
113
|
)
|
117
|
-
hinter.error(hint)
|
118
114
|
raise ConfigurationError("Contradictory base addresses.")
|
119
115
|
|
120
116
|
def determine_entry(self):
|
@@ -219,8 +215,7 @@ class ELFImage(Code):
|
|
219
215
|
# Use lief to check if this is an ELF
|
220
216
|
# NOTE: for some reason, this takes list[int], not bytes
|
221
217
|
if not lief.is_elf(list(self.image)):
|
222
|
-
|
223
|
-
hinter.error(hint)
|
218
|
+
log.error("File is not an elf.")
|
224
219
|
raise ConfigurationError("Input is not an elf")
|
225
220
|
|
226
221
|
# Use lief to parse the ELF
|
@@ -245,14 +240,12 @@ class ELFImage(Code):
|
|
245
240
|
if ehdr.program_header_offset == 0:
|
246
241
|
# NULL phoff means no program headers.
|
247
242
|
# This file is not loadable; time to use another ELF loader.
|
248
|
-
|
249
|
-
hinter.error(hint)
|
243
|
+
log.error("No program headers; file is not loadable")
|
250
244
|
raise ConfigurationError("File not loadable")
|
251
245
|
if ehdr.program_header_offset >= len(self.image):
|
252
|
-
|
253
|
-
|
246
|
+
log.error(
|
247
|
+
f"Invalid program header offset: {hex(ehdr.program_header_offset)}"
|
254
248
|
)
|
255
|
-
hinter.error(hint)
|
256
249
|
raise ConfigurationError("Invalid program header offset")
|
257
250
|
|
258
251
|
# Determine the file base address,
|
@@ -272,8 +265,7 @@ class ELFImage(Code):
|
|
272
265
|
elif phdr.type == PT_DYNAMIC:
|
273
266
|
# Dynamic linking metadata.
|
274
267
|
# This ELF needs dynamic linking
|
275
|
-
|
276
|
-
hinter.info(hint)
|
268
|
+
log.info("Program includes dynamic linking metadata")
|
277
269
|
elif phdr.type == PT_INTERP:
|
278
270
|
# Program interpreter
|
279
271
|
# This completely changes how program loading works.
|
@@ -281,8 +273,7 @@ class ELFImage(Code):
|
|
281
273
|
interp = self.image[
|
282
274
|
phdr.file_offset : phdr.file_offset + phdr.physical_size
|
283
275
|
]
|
284
|
-
|
285
|
-
hinter.info(hint)
|
276
|
+
log.info(f"Program specifies interpreter {interp!r}")
|
286
277
|
elif phdr.type == PT_NOTE:
|
287
278
|
# Auxiliary information
|
288
279
|
# Possibly useful for comparing machine/OS type.
|
@@ -294,8 +285,7 @@ class ELFImage(Code):
|
|
294
285
|
elif phdr.type == PT_TLS:
|
295
286
|
# TLS Segment
|
296
287
|
# Your analysis is about to get nasty :(
|
297
|
-
|
298
|
-
hinter.info(hint)
|
288
|
+
log.info("Program includes thread-local storage")
|
299
289
|
elif phdr.type == PT_GNU_EH_FRAME:
|
300
290
|
# Exception handler frame.
|
301
291
|
# GCC puts one of these in everything. Do we care?
|
@@ -303,13 +293,11 @@ class ELFImage(Code):
|
|
303
293
|
elif phdr.type == PT_GNU_STACK:
|
304
294
|
# Stack executability
|
305
295
|
# If this is missing, assume executable stack
|
306
|
-
|
307
|
-
hinter.info(hint)
|
296
|
+
log.info("Program specifies stack permissions")
|
308
297
|
elif phdr.type == PT_GNU_RELRO:
|
309
298
|
# Read-only after relocation
|
310
299
|
# Only the dynamic linker should write this data.
|
311
|
-
|
312
|
-
hinter.info(hint)
|
300
|
+
log.info("Program specifies RELRO data")
|
313
301
|
elif phdr.type == PT_GNU_PROPERTY:
|
314
302
|
# GNU property segment
|
315
303
|
# Contains extra metadata which I'm not sure anything uses
|
@@ -318,19 +306,16 @@ class ELFImage(Code):
|
|
318
306
|
# Unknown OS-specific program header
|
319
307
|
# Either this is a weird ISA that extends the generic GNU ABI,
|
320
308
|
# or this isn't a Linux ELF.
|
321
|
-
|
322
|
-
hinter.warn(hint)
|
309
|
+
log.warn(f"Unknown OS-specific program header: {phdr.type:08x}")
|
323
310
|
elif phdr.type >= PT_LOPROC and phdr.type <= PT_HIPROC:
|
324
311
|
# Unknown machine-specific program header
|
325
312
|
# This is probably a non-Intel ISA.
|
326
313
|
# Most of these are harmless, serving to tell the RTLD
|
327
314
|
# where to find machine-specific metadata
|
328
|
-
|
329
|
-
hinter.warn(hint)
|
315
|
+
log.warn(f"Unknown machine-specific program header: {phdr.type:08x}")
|
330
316
|
else:
|
331
317
|
# Unknown program header outside the allowed custom ranges
|
332
|
-
|
333
|
-
hinter.warn(hint)
|
318
|
+
log.warn(f"Invalid program header: {phdr.type:08x}")
|
334
319
|
|
335
320
|
def map_segment(self, phdr):
|
336
321
|
"""Map a segment into a SmallWorld machine state object
|
smallworld/utils.py
CHANGED
@@ -541,12 +541,17 @@ class RBTree(Iterable):
|
|
541
541
|
return iter(self.values())
|
542
542
|
|
543
543
|
|
544
|
+
def _range_collection_key(x):
|
545
|
+
# Used to be a lambda, but can't pickle lambdas
|
546
|
+
return x[0]
|
547
|
+
|
548
|
+
|
544
549
|
class RangeCollection(Iterable):
|
545
550
|
"""A collection of non-overlapping ranges"""
|
546
551
|
|
547
552
|
def __init__(self):
|
548
553
|
# Back with an RBTree keyed off the start of the range
|
549
|
-
self._ranges = RBTree(key=
|
554
|
+
self._ranges = RBTree(key=_range_collection_key)
|
550
555
|
|
551
556
|
def is_empty(self) -> bool:
|
552
557
|
"""Check if this collection is empty
|
@@ -1,20 +1,43 @@
|
|
1
|
-
Metadata-Version: 2.
|
1
|
+
Metadata-Version: 2.4
|
2
2
|
Name: smallworld-re
|
3
|
-
Version:
|
3
|
+
Version: 2.0.0
|
4
4
|
Summary: An emulation stack tracking library
|
5
|
-
Home-page: https://github.com/smallworld-re/smallworld
|
6
5
|
Author: MIT Lincoln Laboratory
|
7
6
|
Author-email: smallworld@ll.mit.edu
|
8
|
-
License: MIT
|
7
|
+
License: MIT License
|
8
|
+
|
9
|
+
© 2023 Massachusetts Institute of Technology
|
10
|
+
|
11
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
12
|
+
this software and associated documentation files (the "Software"), to deal in
|
13
|
+
the Software without restriction, including without limitation the rights to
|
14
|
+
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
15
|
+
of the Software, and to permit persons to whom the Software is furnished to do
|
16
|
+
so, subject to the following conditions:
|
17
|
+
|
18
|
+
The above copyright notice and this permission notice shall be included in all
|
19
|
+
copies or substantial portions of the Software.
|
20
|
+
|
21
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
22
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
23
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
24
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
25
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
26
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
27
|
+
SOFTWARE.
|
28
|
+
|
29
|
+
Project-URL: Homepage, https://github.com/smallworld-re/smallworld
|
30
|
+
Project-URL: Issues, https://github.com/smallworld-re/smallworld/issues
|
9
31
|
Requires-Python: >=3.10
|
10
32
|
Description-Content-Type: text/markdown
|
11
33
|
License-File: LICENSE.txt
|
34
|
+
Requires-Dist: angr
|
35
|
+
Requires-Dist: capstone
|
36
|
+
Requires-Dist: jsons
|
37
|
+
Requires-Dist: lief
|
12
38
|
Requires-Dist: pyhidra==1.3.0
|
13
|
-
Requires-Dist:
|
14
|
-
Requires-Dist:
|
15
|
-
Requires-Dist: lief==0.14.1
|
16
|
-
Requires-Dist: pypcode==3.0
|
17
|
-
Requires-Dist: unicorn==2.0.1.post1
|
39
|
+
Requires-Dist: pypcode
|
40
|
+
Requires-Dist: unicorn
|
18
41
|
Provides-Extra: development
|
19
42
|
Requires-Dist: black; extra == "development"
|
20
43
|
Requires-Dist: isort; extra == "development"
|
@@ -24,16 +47,10 @@ Requires-Dist: pip-tools; extra == "development"
|
|
24
47
|
Requires-Dist: pre-commit; extra == "development"
|
25
48
|
Requires-Dist: sphinx; extra == "development"
|
26
49
|
Requires-Dist: sphinxcontrib-programoutput; extra == "development"
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
Dynamic:
|
31
|
-
Dynamic: home-page
|
32
|
-
Dynamic: license
|
33
|
-
Dynamic: provides-extra
|
34
|
-
Dynamic: requires-dist
|
35
|
-
Dynamic: requires-python
|
36
|
-
Dynamic: summary
|
50
|
+
Requires-Dist: jupyterlab; extra == "development"
|
51
|
+
Requires-Dist: notebook; extra == "development"
|
52
|
+
Requires-Dist: timeout-decorator; extra == "development"
|
53
|
+
Dynamic: license-file
|
37
54
|
|
38
55
|
# SmallWorld
|
39
56
|
|
@@ -56,19 +73,19 @@ There are two fundamental tenets behind SmallWorld
|
|
56
73
|
|
57
74
|
The first of these tenets we hope to support with good software APIs. As a very
|
58
75
|
simple example, consider the harnessing script
|
59
|
-
[
|
76
|
+
[square.amd64.py](https://github.com/smallworld-re/smallworld/blob/main/tests/square/square.amd64.py),
|
60
77
|
composed using SmallWorld, in which registers are initialized and a stack is
|
61
78
|
arranged for running the code in
|
62
|
-
[
|
79
|
+
[square.amd64.s](https://github.com/smallworld-re/smallworld/blob/main/tests/square/square.amd64.s).
|
63
80
|
For a more sophisticated example of SmallWorld's harnessing facitilites,
|
64
81
|
consider the code snippet
|
65
|
-
[struct.s](https://github.com/smallworld-re/smallworld/blob/main/tests/struct.s),
|
82
|
+
[struct.amd64.s](https://github.com/smallworld-re/smallworld/blob/main/tests/struct/struct.amd64.s),
|
66
83
|
which assumes a stack and input pointers to a linked list with very specific
|
67
84
|
format. The harnessing script in this case is more complicated, including
|
68
85
|
specifying type information for the linked list element structures as well as
|
69
86
|
use of a simple allocator abstraction provided by SmallWorld to instantiate
|
70
87
|
nodes and link them together appropriately:
|
71
|
-
[struct.py](https://github.com/smallworld-re/smallworld/blob/main/tests/struct.py).
|
88
|
+
[struct.amd64.py](https://github.com/smallworld-re/smallworld/blob/main/tests/struct/struct.amd64.py).
|
72
89
|
|
73
90
|
The second tenet we address with purpose-built analyses which leverage a
|
74
91
|
(possibly incomplete) harness script and that use techniques such as [Micro
|
@@ -84,33 +101,40 @@ SmallWorld directly supports yet.
|
|
84
101
|
|
85
102
|
## Installation
|
86
103
|
|
87
|
-
|
88
|
-
|
104
|
+
SmallWorld can be installed [directly from PyPi](https://pypi.org/project/smallworld-re/), just:
|
89
105
|
```bash
|
90
|
-
pip install
|
106
|
+
pip install smallworld-re
|
91
107
|
```
|
92
108
|
|
93
|
-
|
94
|
-
|
95
|
-
Print basic usage and help:
|
109
|
+
If you'd like to install the latest changes or do development, you can install directly. To install SmallWorld from this repo, [optionally set up a venv](https://docs.python.org/3/library/venv.html) and then run:
|
96
110
|
|
97
111
|
```bash
|
98
|
-
|
112
|
+
pip install .
|
99
113
|
```
|
100
114
|
|
115
|
+
The result will be a library that can be used for harnessing and analyzing. See the examples for a walkthrough.
|
116
|
+
|
101
117
|
## Contributing
|
102
118
|
|
103
119
|
Pull requests and issues more than welcome.
|
104
120
|
|
105
121
|
### Development
|
106
122
|
|
107
|
-
|
123
|
+
#### The Easy Way
|
124
|
+
To set up a development environment from this repo, the easiest method is to use
|
125
|
+
the install script `install.sh`. This has been tested on Ubuntu 22.04 and may be run
|
126
|
+
as the root user, or a non-root user with sudo permissions.
|
127
|
+
This will both install SmallWorld and build the unit and integration tests.
|
128
|
+
Note that installation will not work fully on an ARM and is not supported.
|
129
|
+
|
130
|
+
#### The Hard Way
|
131
|
+
To manually set up a development environment from this repo, install SmallWorld in
|
108
132
|
editable mode with extras for development and testing. Use the include
|
109
133
|
constraints to install frozen versions and ensure a consistent development
|
110
134
|
environment.
|
111
135
|
|
112
136
|
```bash
|
113
|
-
pip install -e .[development] -c constraints.txt
|
137
|
+
pip install -e ".[development]" -c constraints.txt
|
114
138
|
```
|
115
139
|
|
116
140
|
#### Code Style
|
@@ -123,17 +147,6 @@ installing development dependencies), run:
|
|
123
147
|
pre-commit install
|
124
148
|
```
|
125
149
|
|
126
|
-
### Documentation
|
127
|
-
|
128
|
-
To build the full SmallWorld documentation, after installing SmallWorld with
|
129
|
-
`development` extras enabled, from the `docs/` directory, run:
|
130
|
-
|
131
|
-
```bash
|
132
|
-
make html
|
133
|
-
```
|
134
|
-
|
135
|
-
Or other [supported Sphinx output formats](https://www.sphinx-doc.org/en/master/usage/builders/index.html).
|
136
|
-
|
137
150
|
### Testing
|
138
151
|
|
139
152
|
#### Prerequisites
|
@@ -149,6 +162,9 @@ You can then build the tests by running:
|
|
149
162
|
|
150
163
|
```bash
|
151
164
|
make -C tests
|
165
|
+
|
166
|
+
ulimit -c unlimited
|
167
|
+
make -C tests/elf_core
|
152
168
|
```
|
153
169
|
|
154
170
|
#### Running Tests
|
@@ -161,6 +177,23 @@ python3 tests/unit.py
|
|
161
177
|
python3 tests/integration.py
|
162
178
|
```
|
163
179
|
|
180
|
+
### Documentation
|
181
|
+
|
182
|
+
To build the full SmallWorld documentation
|
183
|
+
* verify [Sphinx](https://www.sphinx-doc.org/) has been installed
|
184
|
+
* install SmallWorld with `development` extras enabled
|
185
|
+
* make sure you have built the tests since the documentation generation requires output from those tests
|
186
|
+
* from the `docs/` directory, run:
|
187
|
+
|
188
|
+
```bash
|
189
|
+
make html
|
190
|
+
```
|
191
|
+
|
192
|
+
The resulting documentation will be in `docs/build/html/`
|
193
|
+
|
194
|
+
Other [supported Sphinx output formats](https://www.sphinx-doc.org/en/master/usage/builders/index.html) can also be generated.
|
195
|
+
|
196
|
+
|
164
197
|
## Distribution
|
165
198
|
|
166
199
|
DISTRIBUTION STATEMENT A. Approved for public release. Distribution is
|