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 enum
|
2
|
+
import typing
|
3
|
+
|
4
|
+
import angr
|
5
|
+
import archinfo
|
6
|
+
import pypcode
|
7
|
+
|
8
|
+
from ....exceptions import EmulationError
|
9
|
+
from ....platforms import Architecture, Byteorder
|
10
|
+
from .machdef import GhidraMachineDef
|
11
|
+
|
12
|
+
|
13
|
+
class UpdatedEnumMeta(enum.EnumMeta):
|
14
|
+
def __contains__(cls, obj):
|
15
|
+
if isinstance(obj, int):
|
16
|
+
return obj in cls._value2member_map_
|
17
|
+
return enum.EnumMeta.__contains__(enum.EnumMeta, obj)
|
18
|
+
|
19
|
+
|
20
|
+
def handle_nop(irsb, i):
|
21
|
+
# This op has no impact on user-facing machine state.
|
22
|
+
irsb._ops.pop(i)
|
23
|
+
return i
|
24
|
+
|
25
|
+
|
26
|
+
def handle_sigtrap(irsb, i):
|
27
|
+
# This op should terminate this block with SIGTRAP
|
28
|
+
next_addr = irsb._ops[i - 1].inputs[0].offset + 3
|
29
|
+
irsb._ops = irsb._ops[0:i]
|
30
|
+
irsb.next = next_addr
|
31
|
+
irsb._size = next_addr - irsb.addr
|
32
|
+
irsb._instruction_addresses = list(
|
33
|
+
filter(lambda x: x < next_addr, irsb._instruction_addresses)
|
34
|
+
)
|
35
|
+
irsb.jumpkind = "Ijk_SigTRAP"
|
36
|
+
return i
|
37
|
+
|
38
|
+
|
39
|
+
def handle_syscall(irsb, i):
|
40
|
+
# This op should terminate this block with a syscall
|
41
|
+
next_addr = irsb._ops[i - 1].inputs[0].offset + 3
|
42
|
+
irsb._ops = irsb._ops[0:i]
|
43
|
+
irsb.next = next_addr
|
44
|
+
irsb._size = next_addr - irsb.addr
|
45
|
+
irsb._instruction_addresses = list(
|
46
|
+
filter(lambda x: x < next_addr, irsb._instruction_addresses)
|
47
|
+
)
|
48
|
+
irsb.jumpkind = "Ijk_Sys_syscall"
|
49
|
+
|
50
|
+
return i
|
51
|
+
|
52
|
+
|
53
|
+
def handle_unimpl(irsb, i):
|
54
|
+
# I don't know what this op does yet
|
55
|
+
userop = LoongArchUserOp(irsb._ops[i].inputs[0].offset)
|
56
|
+
raise EmulationError(f"Unimplemented user op {userop!r}")
|
57
|
+
|
58
|
+
|
59
|
+
class LoongArchUserOp(enum.IntEnum, metaclass=UpdatedEnumMeta):
|
60
|
+
def __new__(
|
61
|
+
cls, val: int, name: str = "", handler: typing.Any = None, desc: str = ""
|
62
|
+
):
|
63
|
+
obj = int.__new__(cls, val)
|
64
|
+
obj._value_ = val
|
65
|
+
obj.short_name = name
|
66
|
+
obj.handler = handler
|
67
|
+
obj.description = desc
|
68
|
+
return obj
|
69
|
+
|
70
|
+
def __init__(
|
71
|
+
self, val: int, name: str = "", handler: typing.Any = None, desc: str = ""
|
72
|
+
):
|
73
|
+
self._value_: int = val
|
74
|
+
self.short_name: str = name
|
75
|
+
self.handler: typing.Any = handler
|
76
|
+
self.description: str = desc
|
77
|
+
|
78
|
+
def __repr__(self):
|
79
|
+
return f"{hex(self.value)}: {self.short_name} - {self.description}"
|
80
|
+
|
81
|
+
BREAK = 0x00, "break", handle_sigtrap, "Breakpoint instruction"
|
82
|
+
CPUCFG = 0x01, "cpucfg", handle_unimpl, "CPU config instruction"
|
83
|
+
ADDR_BOUND_EXCEPTION = 0x02, "addr_bound_exception", handle_unimpl, "Unknown"
|
84
|
+
BOUND_CHECK_EXCEPTION = 0x03, "bound_check_exception", handle_unimpl, "Unknown"
|
85
|
+
CRC_IEEE802_3 = 0x04, "crc_ieee802.3", handle_unimpl, "Unknown"
|
86
|
+
CRC_CASTAGNOLI = 0x05, "crc_castagnoli", handle_unimpl, "Unknown"
|
87
|
+
DBCL = 0x06, "dbcl", handle_unimpl, "Unknown"
|
88
|
+
DBAR = 0x07, "dbar", handle_nop, "Data Barrier"
|
89
|
+
IBAR = 0x08, "ibar", handle_nop, "Instruction Barrier"
|
90
|
+
IOCSRRD = 0x09, "iocsrrd", handle_unimpl, "Unknown"
|
91
|
+
IOCSRWR = 0x0A, "iocsrwr", handle_unimpl, "Unknown"
|
92
|
+
PRELD_LOADL1CACHE = 0x0B, "preld_loadl1cache", handle_unimpl, "Unknown"
|
93
|
+
PRELD_STOREL1CACHE = 0x0C, "preld_storel1cache", handle_unimpl, "Unknown"
|
94
|
+
PRELD_NOP = 0x0D, "preld_nop", handle_unimpl, "Unknown"
|
95
|
+
PRELDX_LOADL1CACHE = 0x0E, "preldx_loadl1cache", handle_unimpl, "Unknown"
|
96
|
+
PRELDX_STOREL1CACHE = 0x0F, "preldx_storel1cache", handle_unimpl, "Unknown"
|
97
|
+
PRELDX_NOP = 0x10, "preldx_nop", handle_unimpl, "Unknown"
|
98
|
+
RDTIME_COUNTER = 0x11, "rdtime.counter", handle_unimpl, "Unknown"
|
99
|
+
RDTIME_COUNTERID = 0x12, "rdtime.counterid", handle_unimpl, "Unknown"
|
100
|
+
SYSCALL = 0x13, "syscall", handle_syscall, "Unknown"
|
101
|
+
F_SCALEB = 0x14, "f_scaleb", handle_unimpl, "Unknown"
|
102
|
+
F_LOGB = 0x15, "f_logb", handle_unimpl, "Unknown"
|
103
|
+
F_CLASS = 0x16, "f_class", handle_unimpl, "Unknown"
|
104
|
+
ROUND_EVEN = 0x17, "round_even", handle_unimpl, "Unknown"
|
105
|
+
|
106
|
+
|
107
|
+
class LoongArchMachineDef(GhidraMachineDef):
|
108
|
+
byteorder = Byteorder.LITTLE
|
109
|
+
|
110
|
+
_registers = {
|
111
|
+
"pc": "pc",
|
112
|
+
# Zero register
|
113
|
+
"r0": "zero",
|
114
|
+
"zero": "zero",
|
115
|
+
# Return address
|
116
|
+
"r1": "ra",
|
117
|
+
"ra": "ra",
|
118
|
+
# TLS pointer
|
119
|
+
"r2": "tp",
|
120
|
+
"tp": "tp",
|
121
|
+
# Stack pointer
|
122
|
+
"r3": "sp",
|
123
|
+
"sp": "sp",
|
124
|
+
# Arguments.
|
125
|
+
# a0 and a1 are also the return registers
|
126
|
+
"r4": "a0",
|
127
|
+
"a0": "a0",
|
128
|
+
"v0": "a0",
|
129
|
+
"r5": "a1",
|
130
|
+
"a1": "a1",
|
131
|
+
"v1": "a1",
|
132
|
+
"r6": "a2",
|
133
|
+
"a2": "a2",
|
134
|
+
"r7": "a3",
|
135
|
+
"a3": "a3",
|
136
|
+
"r8": "a4",
|
137
|
+
"a4": "a4",
|
138
|
+
"r9": "a5",
|
139
|
+
"a5": "a5",
|
140
|
+
"r10": "a6",
|
141
|
+
"a6": "a6",
|
142
|
+
"r11": "a7",
|
143
|
+
"a7": "a7",
|
144
|
+
# Temporary registers
|
145
|
+
"r12": "t0",
|
146
|
+
"t0": "t0",
|
147
|
+
"r13": "t1",
|
148
|
+
"t1": "t1",
|
149
|
+
"r14": "t2",
|
150
|
+
"t2": "t2",
|
151
|
+
"r15": "t3",
|
152
|
+
"t3": "t3",
|
153
|
+
"r16": "t4",
|
154
|
+
"t4": "t4",
|
155
|
+
"r17": "t5",
|
156
|
+
"t5": "t5",
|
157
|
+
"r18": "t6",
|
158
|
+
"t6": "t6",
|
159
|
+
"r19": "t7",
|
160
|
+
"t7": "t7",
|
161
|
+
"r20": "t8",
|
162
|
+
"t8": "t8",
|
163
|
+
# Per-CPU Base Address
|
164
|
+
"r21": "r21",
|
165
|
+
"u0": "r21",
|
166
|
+
# Frame Pointer
|
167
|
+
"r22": "fp",
|
168
|
+
"fp": "fp",
|
169
|
+
# Static registers
|
170
|
+
"r23": "s0",
|
171
|
+
"s0": "s0",
|
172
|
+
"r24": "s1",
|
173
|
+
"s1": "s1",
|
174
|
+
"r25": "s2",
|
175
|
+
"s2": "s2",
|
176
|
+
"r26": "s3",
|
177
|
+
"s3": "s3",
|
178
|
+
"r27": "s4",
|
179
|
+
"s4": "s4",
|
180
|
+
"r28": "s5",
|
181
|
+
"s5": "s5",
|
182
|
+
"r29": "s6",
|
183
|
+
"s6": "s6",
|
184
|
+
"r30": "s7",
|
185
|
+
"s7": "s7",
|
186
|
+
"r31": "s8",
|
187
|
+
"s8": "s8",
|
188
|
+
# Floating-point arguments.
|
189
|
+
# fa0 and fa1 are also return values
|
190
|
+
"f0": "fa0",
|
191
|
+
"fa0": "fa0",
|
192
|
+
"f1": "fa1",
|
193
|
+
"fa1": "fa1",
|
194
|
+
"f2": "fa2",
|
195
|
+
"fa2": "fa2",
|
196
|
+
"f3": "fa3",
|
197
|
+
"fa3": "fa3",
|
198
|
+
"f4": "fa4",
|
199
|
+
"fa4": "fa4",
|
200
|
+
"f5": "fa5",
|
201
|
+
"fa5": "fa5",
|
202
|
+
"f6": "fa6",
|
203
|
+
"fa6": "fa6",
|
204
|
+
"f7": "fa7",
|
205
|
+
"fa7": "fa7",
|
206
|
+
# Floating-point temporary registers
|
207
|
+
"f8": "ft0",
|
208
|
+
"ft0": "ft0",
|
209
|
+
"f9": "ft1",
|
210
|
+
"ft1": "ft1",
|
211
|
+
"f10": "ft2",
|
212
|
+
"ft2": "ft2",
|
213
|
+
"f11": "ft3",
|
214
|
+
"ft3": "ft3",
|
215
|
+
"f12": "ft4",
|
216
|
+
"ft4": "ft4",
|
217
|
+
"f13": "ft5",
|
218
|
+
"ft5": "ft5",
|
219
|
+
"f14": "ft6",
|
220
|
+
"ft6": "ft6",
|
221
|
+
"f15": "ft7",
|
222
|
+
"ft7": "ft7",
|
223
|
+
"f16": "ft8",
|
224
|
+
"ft8": "ft8",
|
225
|
+
"f17": "ft9",
|
226
|
+
"ft9": "ft9",
|
227
|
+
"f18": "ft10",
|
228
|
+
"ft10": "ft10",
|
229
|
+
"f19": "ft11",
|
230
|
+
"ft11": "ft11",
|
231
|
+
"f20": "ft12",
|
232
|
+
"ft12": "ft12",
|
233
|
+
"f21": "ft13",
|
234
|
+
"ft13": "ft13",
|
235
|
+
"f22": "ft14",
|
236
|
+
"ft14": "ft14",
|
237
|
+
"f23": "ft15",
|
238
|
+
"ft15": "ft15",
|
239
|
+
# Floating-point static registers
|
240
|
+
"f24": "fs0",
|
241
|
+
"fs0": "fs0",
|
242
|
+
"f25": "fs1",
|
243
|
+
"fs1": "fs1",
|
244
|
+
"f26": "fs2",
|
245
|
+
"fs2": "fs2",
|
246
|
+
"f27": "fs3",
|
247
|
+
"fs3": "fs3",
|
248
|
+
"f28": "fs4",
|
249
|
+
"fs4": "fs4",
|
250
|
+
"f29": "fs5",
|
251
|
+
"fs5": "fs5",
|
252
|
+
"f30": "fs6",
|
253
|
+
"fs6": "fs6",
|
254
|
+
"f31": "fs7",
|
255
|
+
"fs7": "fs7",
|
256
|
+
}
|
257
|
+
|
258
|
+
def successors(self, state: angr.SimState, **kwargs) -> typing.Any:
|
259
|
+
# xtensa includes a _LOT_ of custom pcode operations.
|
260
|
+
|
261
|
+
# Fetch or compute the IR block for our state
|
262
|
+
if "irsb" in kwargs and kwargs["irsb"] is not None:
|
263
|
+
# Someone's already specified an IR block.
|
264
|
+
irsb = kwargs["irsb"]
|
265
|
+
else:
|
266
|
+
# Disable optimization; it doesn't work
|
267
|
+
kwargs["opt_level"] = 0
|
268
|
+
|
269
|
+
# Compute the block from the state.
|
270
|
+
# Pray to the Powers that kwargs are compatible.
|
271
|
+
irsb = state.block(**kwargs).vex
|
272
|
+
|
273
|
+
i = 0
|
274
|
+
while i < len(irsb._ops):
|
275
|
+
op = irsb._ops[i]
|
276
|
+
if op.opcode == pypcode.OpCode.CALLOTHER:
|
277
|
+
# This is a user-defined Pcode op.
|
278
|
+
# Alter irsb to mimic its behavior, if we can.
|
279
|
+
opnum = op.inputs[0].offset
|
280
|
+
|
281
|
+
if opnum not in LoongArchUserOp:
|
282
|
+
# Not a userop.
|
283
|
+
raise EmulationError(f"Undefined user op {hex(opnum)}")
|
284
|
+
# get the enum struct
|
285
|
+
userop = LoongArchUserOp(opnum)
|
286
|
+
|
287
|
+
# Invoke the handler
|
288
|
+
i = userop.handler(irsb, i)
|
289
|
+
else:
|
290
|
+
i += 1
|
291
|
+
|
292
|
+
# Force the engine to use our IR block
|
293
|
+
kwargs["irsb"] = irsb
|
294
|
+
|
295
|
+
# Turn the crank on the engine
|
296
|
+
return super().successors(state, **kwargs)
|
297
|
+
|
298
|
+
|
299
|
+
class SimCCLoongArchLinux(angr.calling_conventions.SimCC):
|
300
|
+
ARG_REGS = ["a0", "a1", "a2", "a3", "a4", "a5", "a6", "a7"]
|
301
|
+
FP_ARG_REGS = ["fa0", "fa1", "fa2", "fa3", "fa4", "fa5", "fa6", "fa7"]
|
302
|
+
RETURN_VAL = angr.calling_conventions.SimRegArg("a0", 8)
|
303
|
+
RETURN_ADDR = angr.calling_conventions.SimRegArg("ra", 8)
|
304
|
+
ARCH = archinfo.ArchPcode("Loongarch:LE:64:lp64d") # type: ignore
|
305
|
+
|
306
|
+
|
307
|
+
angr.calling_conventions.register_default_cc(
|
308
|
+
"Loongarch:LE:64:lp64d", SimCCLoongArchLinux
|
309
|
+
)
|
310
|
+
|
311
|
+
|
312
|
+
class SimCCLoongArchLinuxSyscall(angr.calling_conventions.SimCCSyscall):
|
313
|
+
ARG_REGS = ["a0", "a1", "a2", "a3", "a4", "a5"]
|
314
|
+
FP_ARG_REGS: typing.List[str] = []
|
315
|
+
RETURN_VAL = angr.calling_conventions.SimRegArg("a0", 8)
|
316
|
+
RETURN_ADDR = angr.calling_conventions.SimRegArg("ip_at_syscall", 8)
|
317
|
+
ARCH = None
|
318
|
+
|
319
|
+
@classmethod
|
320
|
+
def _match(cls, arch, args, sp_data):
|
321
|
+
# Never match; only occurs durring syscalls
|
322
|
+
return False
|
323
|
+
|
324
|
+
@staticmethod
|
325
|
+
def syscall_num(state):
|
326
|
+
# This is a massive guess from RE'ing libc
|
327
|
+
return state.regs.a7
|
328
|
+
|
329
|
+
|
330
|
+
angr.calling_conventions.register_syscall_cc(
|
331
|
+
"Loongarch:LE:64:lp64d", "default", SimCCLoongArchLinuxSyscall
|
332
|
+
)
|
333
|
+
|
334
|
+
|
335
|
+
class LoongArch64MachineDef(LoongArchMachineDef):
|
336
|
+
arch = Architecture.LOONGARCH64
|
337
|
+
pcode_language = "Loongarch:LE:64:lp64d"
|
338
|
+
|
339
|
+
|
340
|
+
__all__ = ["LoongArch64MachineDef"]
|
@@ -28,12 +28,6 @@ class AngrMachineDef:
|
|
28
28
|
"""The angr architecture to use"""
|
29
29
|
raise NotImplementedError("This is an abstract method.")
|
30
30
|
|
31
|
-
@property
|
32
|
-
@abc.abstractmethod
|
33
|
-
def pc_reg(self) -> str:
|
34
|
-
"""The program counter register name"""
|
35
|
-
return ""
|
36
|
-
|
37
31
|
# Is this thumb?
|
38
32
|
# Almost always no, but angr needs to ask.
|
39
33
|
is_thumb: bool = False
|
@@ -98,7 +92,6 @@ class AngrMachineDef:
|
|
98
92
|
|
99
93
|
Arguments:
|
100
94
|
arch: The architecture ID you want
|
101
|
-
mode: The mode ID you want
|
102
95
|
byteorder: The byteorderness you want
|
103
96
|
|
104
97
|
Returns:
|
@@ -117,7 +110,7 @@ class AngrMachineDef:
|
|
117
110
|
raise ValueError(f"No machine model for {platform}")
|
118
111
|
|
119
112
|
|
120
|
-
class
|
113
|
+
class GhidraMachineDef(AngrMachineDef):
|
121
114
|
"""Container class for pcode-dependent angr architecture-specific definitions"""
|
122
115
|
|
123
116
|
@property
|
@@ -7,8 +7,6 @@ from .machdef import AngrMachineDef
|
|
7
7
|
class PowerPCMachineDef(AngrMachineDef):
|
8
8
|
byteorder = Byteorder.BIG
|
9
9
|
|
10
|
-
pc_reg = "pc"
|
11
|
-
|
12
10
|
_registers = {
|
13
11
|
"r0": "r0",
|
14
12
|
"r1": "r1",
|
@@ -43,6 +41,7 @@ class PowerPCMachineDef(AngrMachineDef):
|
|
43
41
|
"r29": "r29",
|
44
42
|
"r30": "r30",
|
45
43
|
"r31": "r31",
|
44
|
+
"bp": "r31",
|
46
45
|
"pc": "pc",
|
47
46
|
"lr": "lr",
|
48
47
|
"ctr": "ctr",
|
@@ -58,8 +58,6 @@ class RISCV64MachineDef(AngrMachineDef):
|
|
58
58
|
|
59
59
|
angr_arch = archinfo.ArchRISCV64()
|
60
60
|
|
61
|
-
pc_reg = "pc"
|
62
|
-
|
63
61
|
_registers = {
|
64
62
|
# *** General-Purpose Registers ***
|
65
63
|
# x0 is wired to 0, and aliased as "zero"
|
@@ -194,28 +192,28 @@ class RISCV64MachineDef(AngrMachineDef):
|
|
194
192
|
"fs1": "fs1",
|
195
193
|
# f10 is argument 0
|
196
194
|
"f10": "f10",
|
197
|
-
"
|
195
|
+
"fa0": "fa0",
|
198
196
|
# f11 is argument 1
|
199
197
|
"f11": "f11",
|
200
|
-
"
|
198
|
+
"fa1": "fa1",
|
201
199
|
# f12 is argument 2
|
202
200
|
"f12": "f12",
|
203
|
-
"
|
201
|
+
"fa2": "fa2",
|
204
202
|
# f13 is argument 3
|
205
203
|
"f13": "f13",
|
206
|
-
"
|
204
|
+
"fa3": "fa3",
|
207
205
|
# f14 is argument 4
|
208
206
|
"f14": "f14",
|
209
|
-
"
|
207
|
+
"fa4": "fa4",
|
210
208
|
# f15 is argument 5
|
211
209
|
"f15": "f15",
|
212
|
-
"
|
210
|
+
"fa5": "fa5",
|
213
211
|
# f16 is argument 6
|
214
212
|
"f16": "f16",
|
215
|
-
"
|
213
|
+
"fa6": "fa6",
|
216
214
|
# f7 is argument 7
|
217
215
|
"f17": "f17",
|
218
|
-
"
|
216
|
+
"fa7": "fa7",
|
219
217
|
# f18 is a callee-saved register
|
220
218
|
"f18": "f18",
|
221
219
|
"fs2": "fs2",
|
@@ -6,7 +6,7 @@ import pypcode
|
|
6
6
|
|
7
7
|
from ....exceptions import EmulationError
|
8
8
|
from ....platforms import Architecture, Byteorder
|
9
|
-
from .machdef import
|
9
|
+
from .machdef import GhidraMachineDef
|
10
10
|
|
11
11
|
|
12
12
|
def handle_nop(irsb, i):
|
@@ -199,10 +199,13 @@ angr.calling_conventions.register_syscall_cc(
|
|
199
199
|
)
|
200
200
|
|
201
201
|
|
202
|
-
class XTensaMachineDef(
|
202
|
+
class XTensaMachineDef(GhidraMachineDef):
|
203
203
|
arch = Architecture.XTENSA
|
204
|
-
_registers = {f"a{i}": f"a{i}" for i in range(0, 16)} | {
|
205
|
-
|
204
|
+
_registers = {f"a{i}": f"a{i}" for i in range(0, 16)} | {
|
205
|
+
"pc": "pc",
|
206
|
+
"sar": "sar",
|
207
|
+
"sp": "a1",
|
208
|
+
}
|
206
209
|
|
207
210
|
def successors(self, state: angr.SimState, **kwargs) -> typing.Any:
|
208
211
|
# xtensa includes a _LOT_ of custom pcode operations.
|
smallworld/emulators/emulator.py
CHANGED
@@ -600,6 +600,13 @@ class MemoryReadHookable(metaclass=abc.ABCMeta):
|
|
600
600
|
) -> None:
|
601
601
|
"""Hook memory reads within a given range, handling concrete values
|
602
602
|
|
603
|
+
Note that this will trigger for any read that overlaps the specified range,
|
604
|
+
and will report all data read, not just the overlap.
|
605
|
+
Hooks should expect to handle partial or oddly-sized reads.
|
606
|
+
|
607
|
+
If the hook chooses to override the data being read,
|
608
|
+
it must return data of the same size as the original read.
|
609
|
+
|
603
610
|
Arguments:
|
604
611
|
start: The start address of the memory range to hook.
|
605
612
|
end: The end address of the memory range to hook.
|
@@ -633,6 +640,13 @@ class MemoryReadHookable(metaclass=abc.ABCMeta):
|
|
633
640
|
) -> None:
|
634
641
|
"""Hook memory reads within a given range, handling symbolic values
|
635
642
|
|
643
|
+
Note that this will trigger for any read that overlaps the specified range,
|
644
|
+
and will report all data read, not just the overlap.
|
645
|
+
Hooks should expect to handle partial or oddly-sized reads.
|
646
|
+
|
647
|
+
If the hook chooses to override the data being read,
|
648
|
+
it must return data of the same size as the original read.
|
649
|
+
|
636
650
|
Arguments:
|
637
651
|
start: The start address of the memory range to hook.
|
638
652
|
end: The end address of the memory range to hook.
|
@@ -739,6 +753,10 @@ class MemoryWriteHookable(metaclass=abc.ABCMeta):
|
|
739
753
|
) -> None:
|
740
754
|
"""Hook memory writes within a given range, handling concrete values.
|
741
755
|
|
756
|
+
Note that this will trigger for any write that overlaps the specified range,
|
757
|
+
and will report all data written, not just the overlap.
|
758
|
+
Hooks should expect to handle partial or oddly-sized writes.
|
759
|
+
|
742
760
|
Arguments:
|
743
761
|
start: The start address of the memory range to hook.
|
744
762
|
end: The end address of the memory range to hook.
|
@@ -763,6 +781,10 @@ class MemoryWriteHookable(metaclass=abc.ABCMeta):
|
|
763
781
|
) -> None:
|
764
782
|
"""Hook memory writes within a given range, handling symbolic values
|
765
783
|
|
784
|
+
Note that this will trigger for any write that overlaps the specified range,
|
785
|
+
and will report all data written, not just the overlap.
|
786
|
+
Hooks should expect to handle partial or oddly-sized writes.
|
787
|
+
|
766
788
|
Arguments:
|
767
789
|
start: The start address of the memory range to hook.
|
768
790
|
end: The end address of the memory range to hook.
|
@@ -0,0 +1,37 @@
|
|
1
|
+
from ... import platforms
|
2
|
+
from .typing import AbstractGhidraEmulator
|
3
|
+
|
4
|
+
|
5
|
+
def GhidraEmulator(platform: platforms.Platform) -> AbstractGhidraEmulator:
|
6
|
+
"""Factory for creating a GhidraEmulator
|
7
|
+
|
8
|
+
Importing any of the pyghidra packages requires
|
9
|
+
booting up a JVM, which takes several seconds.
|
10
|
+
It also doesn't work if Java and Ghidra are not configured.
|
11
|
+
|
12
|
+
Rather than requiring all SmallWorld users to sit through
|
13
|
+
this process, export a factory method that looks
|
14
|
+
exactly like an Emulator constructor.
|
15
|
+
Only boot pyghidra if the factory is called,
|
16
|
+
and only import GhidraEmulator if successful.
|
17
|
+
|
18
|
+
See GhidraEmulator in pcode.py for the actua emulator class.
|
19
|
+
|
20
|
+
Arguments:
|
21
|
+
platform: The platform to use when creating the emulator
|
22
|
+
|
23
|
+
Returns:
|
24
|
+
A GhidraEmulator object
|
25
|
+
"""
|
26
|
+
|
27
|
+
import pyghidra
|
28
|
+
|
29
|
+
if not pyghidra.started():
|
30
|
+
pyghidra.start()
|
31
|
+
|
32
|
+
from .ghidra import GhidraEmulator as Emu
|
33
|
+
|
34
|
+
return Emu(platform)
|
35
|
+
|
36
|
+
|
37
|
+
__all__ = ["GhidraEmulator"]
|