smallworld-re 1.0.3__py3-none-any.whl → 2.0.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- smallworld/analyses/__init__.py +8 -0
- smallworld/analyses/analysis.py +8 -67
- smallworld/analyses/code_coverage.py +1 -2
- smallworld/analyses/colorizer.py +301 -534
- smallworld/analyses/colorizer_def_use.py +217 -0
- smallworld/analyses/colorizer_summary.py +173 -83
- smallworld/analyses/field_detection/field_analysis.py +7 -8
- smallworld/analyses/field_detection/hints.py +1 -1
- smallworld/analyses/field_detection/malloc.py +2 -2
- smallworld/analyses/trace_execution.py +160 -0
- smallworld/analyses/trace_execution_types.py +42 -0
- smallworld/analyses/unstable/angr/divergence.py +1 -2
- smallworld/analyses/unstable/angr/model.py +5 -6
- smallworld/analyses/unstable/angr_nwbt.py +3 -4
- smallworld/analyses/unstable/code_coverage.py +2 -3
- smallworld/analyses/unstable/code_reachable.py +2 -3
- smallworld/analyses/unstable/control_flow_tracer.py +2 -3
- smallworld/analyses/unstable/pointer_finder.py +2 -3
- smallworld/analyses/unstable/utils/tui.py +71 -0
- smallworld/emulators/__init__.py +3 -1
- smallworld/emulators/angr/angr.py +30 -9
- smallworld/emulators/angr/machdefs/__init__.py +2 -0
- smallworld/emulators/angr/machdefs/aarch64.py +1 -1
- smallworld/emulators/angr/machdefs/amd64.py +0 -4
- smallworld/emulators/angr/machdefs/arm.py +0 -2
- smallworld/emulators/angr/machdefs/i386.py +0 -2
- smallworld/emulators/angr/machdefs/loongarch.py +340 -0
- smallworld/emulators/angr/machdefs/machdef.py +1 -8
- smallworld/emulators/angr/machdefs/mips.py +0 -2
- smallworld/emulators/angr/machdefs/mips64.py +0 -2
- smallworld/emulators/angr/machdefs/ppc.py +1 -2
- smallworld/emulators/angr/machdefs/riscv.py +8 -10
- smallworld/emulators/angr/machdefs/xtensa.py +7 -4
- smallworld/emulators/emulator.py +22 -0
- smallworld/emulators/ghidra/__init__.py +37 -0
- smallworld/emulators/ghidra/ghidra.py +513 -0
- smallworld/emulators/ghidra/machdefs/__init__.py +31 -0
- smallworld/emulators/ghidra/machdefs/aarch64.py +289 -0
- smallworld/emulators/ghidra/machdefs/amd64.py +185 -0
- smallworld/emulators/ghidra/machdefs/arm.py +370 -0
- smallworld/emulators/ghidra/machdefs/i386.py +109 -0
- smallworld/emulators/ghidra/machdefs/loongarch.py +162 -0
- smallworld/emulators/ghidra/machdefs/machdef.py +81 -0
- smallworld/emulators/ghidra/machdefs/mips.py +163 -0
- smallworld/emulators/ghidra/machdefs/mips64.py +186 -0
- smallworld/emulators/ghidra/machdefs/ppc.py +98 -0
- smallworld/emulators/ghidra/machdefs/riscv.py +208 -0
- smallworld/emulators/ghidra/machdefs/xtensa.py +21 -0
- smallworld/emulators/ghidra/typing.py +28 -0
- smallworld/emulators/hookable.py +18 -4
- smallworld/emulators/panda/machdefs/__init__.py +2 -2
- smallworld/emulators/panda/machdefs/aarch64.py +186 -11
- smallworld/emulators/panda/machdefs/amd64.py +103 -11
- smallworld/emulators/panda/machdefs/arm.py +216 -20
- smallworld/emulators/panda/machdefs/i386.py +30 -7
- smallworld/emulators/panda/machdefs/machdef.py +9 -16
- smallworld/emulators/panda/machdefs/mips.py +49 -5
- smallworld/emulators/panda/machdefs/mips64.py +57 -5
- smallworld/emulators/panda/machdefs/ppc.py +38 -13
- smallworld/emulators/panda/panda.py +146 -44
- smallworld/emulators/unicorn/__init__.py +2 -0
- smallworld/emulators/unicorn/machdefs/aarch64.py +253 -264
- smallworld/emulators/unicorn/machdefs/amd64.py +254 -259
- smallworld/emulators/unicorn/machdefs/arm.py +200 -212
- smallworld/emulators/unicorn/machdefs/i386.py +84 -90
- smallworld/emulators/unicorn/machdefs/machdef.py +2 -23
- smallworld/emulators/unicorn/machdefs/mips.py +127 -135
- smallworld/emulators/unicorn/unicorn.py +52 -13
- smallworld/helpers.py +4 -19
- smallworld/hinting/hinting.py +22 -192
- smallworld/hinting/hints.py +50 -18
- smallworld/instructions/bsid.py +8 -8
- smallworld/logging.py +4 -2
- smallworld/platforms/__init__.py +12 -0
- smallworld/platforms/defs/__init__.py +36 -0
- smallworld/platforms/defs/aarch64.py +450 -0
- smallworld/platforms/defs/amd64.py +463 -0
- smallworld/platforms/defs/arm.py +519 -0
- smallworld/platforms/defs/i386.py +258 -0
- smallworld/platforms/defs/loongarch.py +270 -0
- smallworld/platforms/defs/mips.py +321 -0
- smallworld/platforms/defs/mips64.py +313 -0
- smallworld/platforms/defs/platformdef.py +97 -0
- smallworld/platforms/defs/powerpc.py +259 -0
- smallworld/platforms/defs/riscv.py +257 -0
- smallworld/platforms/defs/xtensa.py +96 -0
- smallworld/{platforms.py → platforms/platforms.py} +3 -0
- smallworld/state/cpus/__init__.py +2 -0
- smallworld/state/cpus/aarch64.py +0 -9
- smallworld/state/cpus/amd64.py +6 -28
- smallworld/state/cpus/arm.py +0 -11
- smallworld/state/cpus/cpu.py +0 -11
- smallworld/state/cpus/i386.py +0 -7
- smallworld/state/cpus/loongarch.py +299 -0
- smallworld/state/cpus/mips.py +4 -47
- smallworld/state/cpus/mips64.py +18 -58
- smallworld/state/cpus/powerpc.py +2 -9
- smallworld/state/cpus/riscv.py +1 -11
- smallworld/state/cpus/xtensa.py +0 -5
- smallworld/state/memory/code.py +38 -2
- smallworld/state/memory/elf/__init__.py +5 -1
- smallworld/state/memory/elf/coredump/__init__.py +3 -0
- smallworld/state/memory/elf/coredump/coredump.py +46 -0
- smallworld/state/memory/elf/coredump/prstatus/__init__.py +27 -0
- smallworld/state/memory/elf/coredump/prstatus/aarch64.py +46 -0
- smallworld/state/memory/elf/coredump/prstatus/amd64.py +40 -0
- smallworld/state/memory/elf/coredump/prstatus/arm.py +53 -0
- smallworld/state/memory/elf/coredump/prstatus/i386.py +30 -0
- smallworld/state/memory/elf/coredump/prstatus/mips.py +55 -0
- smallworld/state/memory/elf/coredump/prstatus/mips64.py +57 -0
- smallworld/state/memory/elf/coredump/prstatus/ppc.py +82 -0
- smallworld/state/memory/elf/coredump/prstatus/prstatus.py +129 -0
- smallworld/state/memory/elf/elf.py +211 -57
- smallworld/state/memory/elf/register_state.py +36 -0
- smallworld/state/memory/elf/rela/__init__.py +2 -0
- smallworld/state/memory/elf/rela/aarch64.py +3 -1
- smallworld/state/memory/elf/rela/amd64.py +4 -2
- smallworld/state/memory/elf/rela/arm.py +4 -2
- smallworld/state/memory/elf/rela/i386.py +4 -2
- smallworld/state/memory/elf/rela/loongarch.py +32 -0
- smallworld/state/memory/elf/rela/mips.py +39 -18
- smallworld/state/memory/elf/rela/ppc.py +31 -14
- smallworld/state/memory/elf/structs.py +3 -0
- smallworld/state/memory/heap.py +2 -2
- smallworld/state/memory/memory.py +18 -0
- smallworld/state/memory/pe/__init__.py +3 -0
- smallworld/state/memory/pe/pe.py +361 -0
- smallworld/state/memory/pe/structs.py +60 -0
- smallworld/state/memory/stack/__init__.py +2 -0
- smallworld/state/memory/stack/loongarch.py +26 -0
- smallworld/state/models/__init__.py +29 -2
- smallworld/state/models/aarch64/__init__.py +1 -0
- smallworld/state/models/aarch64/systemv/__init__.py +6 -0
- smallworld/state/models/aarch64/systemv/c99/__init__.py +12 -0
- smallworld/state/models/aarch64/systemv/c99/signal.py +16 -0
- smallworld/state/models/aarch64/systemv/c99/stdio.py +265 -0
- smallworld/state/models/aarch64/systemv/c99/stdlib.py +169 -0
- smallworld/state/models/aarch64/systemv/c99/string.py +139 -0
- smallworld/state/models/aarch64/systemv/c99/time.py +61 -0
- smallworld/state/models/aarch64/systemv/posix/__init__.py +6 -0
- smallworld/state/models/aarch64/systemv/posix/libgen.py +16 -0
- smallworld/state/models/aarch64/systemv/posix/signal.py +157 -0
- smallworld/state/models/aarch64/systemv/systemv.py +80 -0
- smallworld/state/models/amd64/__init__.py +1 -0
- smallworld/state/models/amd64/systemv/__init__.py +6 -0
- smallworld/state/models/amd64/systemv/c99/__init__.py +12 -0
- smallworld/state/models/amd64/systemv/c99/signal.py +16 -0
- smallworld/state/models/amd64/systemv/c99/stdio.py +265 -0
- smallworld/state/models/amd64/systemv/c99/stdlib.py +169 -0
- smallworld/state/models/amd64/systemv/c99/string.py +139 -0
- smallworld/state/models/amd64/systemv/c99/time.py +61 -0
- smallworld/state/models/amd64/systemv/posix/__init__.py +6 -0
- smallworld/state/models/amd64/systemv/posix/libgen.py +16 -0
- smallworld/state/models/amd64/systemv/posix/signal.py +157 -0
- smallworld/state/models/amd64/systemv/systemv.py +78 -0
- smallworld/state/models/armel/__init__.py +1 -0
- smallworld/state/models/armel/systemv/__init__.py +6 -0
- smallworld/state/models/armel/systemv/c99/__init__.py +12 -0
- smallworld/state/models/armel/systemv/c99/signal.py +16 -0
- smallworld/state/models/armel/systemv/c99/stdio.py +265 -0
- smallworld/state/models/armel/systemv/c99/stdlib.py +169 -0
- smallworld/state/models/armel/systemv/c99/string.py +139 -0
- smallworld/state/models/armel/systemv/c99/time.py +61 -0
- smallworld/state/models/armel/systemv/posix/__init__.py +6 -0
- smallworld/state/models/armel/systemv/posix/libgen.py +16 -0
- smallworld/state/models/armel/systemv/posix/signal.py +157 -0
- smallworld/state/models/armel/systemv/systemv.py +82 -0
- smallworld/state/models/armhf/__init__.py +1 -0
- smallworld/state/models/armhf/systemv/__init__.py +6 -0
- smallworld/state/models/armhf/systemv/c99/__init__.py +12 -0
- smallworld/state/models/armhf/systemv/c99/signal.py +16 -0
- smallworld/state/models/armhf/systemv/c99/stdio.py +265 -0
- smallworld/state/models/armhf/systemv/c99/stdlib.py +169 -0
- smallworld/state/models/armhf/systemv/c99/string.py +139 -0
- smallworld/state/models/armhf/systemv/c99/time.py +61 -0
- smallworld/state/models/armhf/systemv/posix/__init__.py +6 -0
- smallworld/state/models/armhf/systemv/posix/libgen.py +16 -0
- smallworld/state/models/armhf/systemv/posix/signal.py +157 -0
- smallworld/state/models/armhf/systemv/systemv.py +77 -0
- smallworld/state/models/c99/__init__.py +12 -0
- smallworld/state/models/c99/fmt_print.py +915 -0
- smallworld/state/models/c99/fmt_scan.py +864 -0
- smallworld/state/models/c99/math.py +362 -0
- smallworld/state/models/c99/signal.py +71 -0
- smallworld/state/models/c99/stdio.py +1305 -0
- smallworld/state/models/c99/stdlib.py +595 -0
- smallworld/state/models/c99/string.py +674 -0
- smallworld/state/models/c99/time.py +340 -0
- smallworld/state/models/c99/utils.py +89 -0
- smallworld/state/models/cstd.py +759 -0
- smallworld/state/models/errno.py +581 -0
- smallworld/state/models/filedesc.py +515 -0
- smallworld/state/models/i386/__init__.py +1 -0
- smallworld/state/models/i386/systemv/__init__.py +6 -0
- smallworld/state/models/i386/systemv/c99/__init__.py +12 -0
- smallworld/state/models/i386/systemv/c99/signal.py +16 -0
- smallworld/state/models/i386/systemv/c99/stdio.py +265 -0
- smallworld/state/models/i386/systemv/c99/stdlib.py +169 -0
- smallworld/state/models/i386/systemv/c99/string.py +139 -0
- smallworld/state/models/i386/systemv/c99/time.py +61 -0
- smallworld/state/models/i386/systemv/posix/__init__.py +6 -0
- smallworld/state/models/i386/systemv/posix/libgen.py +16 -0
- smallworld/state/models/i386/systemv/posix/signal.py +157 -0
- smallworld/state/models/i386/systemv/systemv.py +71 -0
- smallworld/state/models/loongarch64/__init__.py +1 -0
- smallworld/state/models/loongarch64/systemv/__init__.py +6 -0
- smallworld/state/models/loongarch64/systemv/c99/__init__.py +12 -0
- smallworld/state/models/loongarch64/systemv/c99/signal.py +16 -0
- smallworld/state/models/loongarch64/systemv/c99/stdio.py +265 -0
- smallworld/state/models/loongarch64/systemv/c99/stdlib.py +169 -0
- smallworld/state/models/loongarch64/systemv/c99/string.py +139 -0
- smallworld/state/models/loongarch64/systemv/c99/time.py +61 -0
- smallworld/state/models/loongarch64/systemv/posix/__init__.py +6 -0
- smallworld/state/models/loongarch64/systemv/posix/libgen.py +16 -0
- smallworld/state/models/loongarch64/systemv/posix/signal.py +157 -0
- smallworld/state/models/loongarch64/systemv/systemv.py +83 -0
- smallworld/state/models/mips/__init__.py +1 -0
- smallworld/state/models/mips/systemv/__init__.py +6 -0
- smallworld/state/models/mips/systemv/c99/__init__.py +12 -0
- smallworld/state/models/mips/systemv/c99/signal.py +16 -0
- smallworld/state/models/mips/systemv/c99/stdio.py +265 -0
- smallworld/state/models/mips/systemv/c99/stdlib.py +169 -0
- smallworld/state/models/mips/systemv/c99/string.py +139 -0
- smallworld/state/models/mips/systemv/c99/time.py +61 -0
- smallworld/state/models/mips/systemv/posix/__init__.py +6 -0
- smallworld/state/models/mips/systemv/posix/libgen.py +16 -0
- smallworld/state/models/mips/systemv/posix/signal.py +157 -0
- smallworld/state/models/mips/systemv/systemv.py +78 -0
- smallworld/state/models/mips64/__init__.py +1 -0
- smallworld/state/models/mips64/systemv/__init__.py +6 -0
- smallworld/state/models/mips64/systemv/c99/__init__.py +12 -0
- smallworld/state/models/mips64/systemv/c99/signal.py +16 -0
- smallworld/state/models/mips64/systemv/c99/stdio.py +265 -0
- smallworld/state/models/mips64/systemv/c99/stdlib.py +169 -0
- smallworld/state/models/mips64/systemv/c99/string.py +139 -0
- smallworld/state/models/mips64/systemv/c99/time.py +61 -0
- smallworld/state/models/mips64/systemv/posix/__init__.py +6 -0
- smallworld/state/models/mips64/systemv/posix/libgen.py +16 -0
- smallworld/state/models/mips64/systemv/posix/signal.py +157 -0
- smallworld/state/models/mips64/systemv/systemv.py +98 -0
- smallworld/state/models/mips64el/__init__.py +1 -0
- smallworld/state/models/mips64el/systemv/__init__.py +6 -0
- smallworld/state/models/mips64el/systemv/c99/__init__.py +12 -0
- smallworld/state/models/mips64el/systemv/c99/signal.py +16 -0
- smallworld/state/models/mips64el/systemv/c99/stdio.py +265 -0
- smallworld/state/models/mips64el/systemv/c99/stdlib.py +169 -0
- smallworld/state/models/mips64el/systemv/c99/string.py +139 -0
- smallworld/state/models/mips64el/systemv/c99/time.py +61 -0
- smallworld/state/models/mips64el/systemv/posix/__init__.py +6 -0
- smallworld/state/models/mips64el/systemv/posix/libgen.py +16 -0
- smallworld/state/models/mips64el/systemv/posix/signal.py +157 -0
- smallworld/state/models/mips64el/systemv/systemv.py +96 -0
- smallworld/state/models/mipsel/__init__.py +1 -0
- smallworld/state/models/mipsel/systemv/__init__.py +6 -0
- smallworld/state/models/mipsel/systemv/c99/__init__.py +12 -0
- smallworld/state/models/mipsel/systemv/c99/signal.py +16 -0
- smallworld/state/models/mipsel/systemv/c99/stdio.py +265 -0
- smallworld/state/models/mipsel/systemv/c99/stdlib.py +169 -0
- smallworld/state/models/mipsel/systemv/c99/string.py +139 -0
- smallworld/state/models/mipsel/systemv/c99/time.py +61 -0
- smallworld/state/models/mipsel/systemv/posix/__init__.py +6 -0
- smallworld/state/models/mipsel/systemv/posix/libgen.py +16 -0
- smallworld/state/models/mipsel/systemv/posix/signal.py +157 -0
- smallworld/state/models/mipsel/systemv/systemv.py +78 -0
- smallworld/state/models/model.py +27 -2
- smallworld/state/models/posix/__init__.py +6 -0
- smallworld/state/models/posix/libgen.py +123 -0
- smallworld/state/models/posix/signal.py +690 -0
- smallworld/state/models/powerpc/__init__.py +1 -0
- smallworld/state/models/powerpc/systemv/__init__.py +6 -0
- smallworld/state/models/powerpc/systemv/c99/__init__.py +12 -0
- smallworld/state/models/powerpc/systemv/c99/signal.py +16 -0
- smallworld/state/models/powerpc/systemv/c99/stdio.py +265 -0
- smallworld/state/models/powerpc/systemv/c99/stdlib.py +169 -0
- smallworld/state/models/powerpc/systemv/c99/string.py +139 -0
- smallworld/state/models/powerpc/systemv/c99/time.py +61 -0
- smallworld/state/models/powerpc/systemv/posix/__init__.py +6 -0
- smallworld/state/models/powerpc/systemv/posix/libgen.py +16 -0
- smallworld/state/models/powerpc/systemv/posix/signal.py +157 -0
- smallworld/state/models/powerpc/systemv/systemv.py +93 -0
- smallworld/state/models/riscv64/__init__.py +1 -0
- smallworld/state/models/riscv64/systemv/__init__.py +6 -0
- smallworld/state/models/riscv64/systemv/c99/__init__.py +12 -0
- smallworld/state/models/riscv64/systemv/c99/signal.py +16 -0
- smallworld/state/models/riscv64/systemv/c99/stdio.py +265 -0
- smallworld/state/models/riscv64/systemv/c99/stdlib.py +169 -0
- smallworld/state/models/riscv64/systemv/c99/string.py +139 -0
- smallworld/state/models/riscv64/systemv/c99/time.py +61 -0
- smallworld/state/models/riscv64/systemv/posix/__init__.py +6 -0
- smallworld/state/models/riscv64/systemv/posix/libgen.py +16 -0
- smallworld/state/models/riscv64/systemv/posix/signal.py +157 -0
- smallworld/state/models/riscv64/systemv/systemv.py +85 -0
- smallworld/state/state.py +65 -24
- smallworld/state/unstable/elf.py +16 -31
- smallworld/utils.py +6 -1
- {smallworld_re-1.0.3.dist-info → smallworld_re-2.0.0.dist-info}/METADATA +74 -42
- smallworld_re-2.0.0.dist-info/RECORD +374 -0
- {smallworld_re-1.0.3.dist-info → smallworld_re-2.0.0.dist-info}/WHEEL +1 -1
- smallworld/state/models/x86/__init__.py +0 -2
- smallworld/state/models/x86/microsoftcdecl.py +0 -35
- smallworld/state/models/x86/systemv.py +0 -240
- smallworld_re-1.0.3.dist-info/RECORD +0 -166
- /smallworld/state/models/{posix.py → _posix.py} +0 -0
- {smallworld_re-1.0.3.dist-info → smallworld_re-2.0.0.dist-info}/entry_points.txt +0 -0
- {smallworld_re-1.0.3.dist-info → smallworld_re-2.0.0.dist-info}/licenses/LICENSE.txt +0 -0
- {smallworld_re-1.0.3.dist-info → smallworld_re-2.0.0.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,513 @@
|
|
1
|
+
import logging
|
2
|
+
import typing
|
3
|
+
|
4
|
+
import claripy
|
5
|
+
import jpype
|
6
|
+
from ghidra.pcode.emu import PcodeEmulator, PcodeThread
|
7
|
+
from ghidra.pcode.exec import PcodeExecutorStatePiece
|
8
|
+
from ghidra.program.model.address import AddressRangeImpl
|
9
|
+
from ghidra.program.model.pcode import Varnode
|
10
|
+
|
11
|
+
from ... import exceptions, platforms, utils
|
12
|
+
from ..emulator import Emulator
|
13
|
+
from .machdefs import GhidraMachineDef
|
14
|
+
from .typing import AbstractGhidraEmulator
|
15
|
+
|
16
|
+
log = logging.getLogger(__name__)
|
17
|
+
|
18
|
+
|
19
|
+
class GhidraEmulator(AbstractGhidraEmulator):
|
20
|
+
name = "pcode-emulator"
|
21
|
+
description = "Emulator based on pyghidra and pcode"
|
22
|
+
version = "0.0.1"
|
23
|
+
|
24
|
+
# Convert bytes into a JPype byte[]
|
25
|
+
# bytes and bytearray are considered variants of String by JPype
|
26
|
+
bytes_py_to_java = jpype.JByte[:]
|
27
|
+
|
28
|
+
@staticmethod
|
29
|
+
def bytes_java_to_py(val: jpype.JByte[:]):
|
30
|
+
# Convert a JPype byte[] into a bytes object
|
31
|
+
bytelist = list(
|
32
|
+
map(lambda x: x.numerator if x.numerator >= 0 else 256 + x.numerator, val)
|
33
|
+
)
|
34
|
+
return bytes(bytelist)
|
35
|
+
|
36
|
+
def __init__(self, platform: platforms.Platform):
|
37
|
+
super().__init__(platform)
|
38
|
+
self.platform: platforms.Platform = platform
|
39
|
+
self.platdef: platforms.PlatformDef = platforms.PlatformDef.for_platform(
|
40
|
+
platform
|
41
|
+
)
|
42
|
+
self.machdef: GhidraMachineDef = GhidraMachineDef.for_platform(platform)
|
43
|
+
|
44
|
+
self._emu: PcodeEmulator = PcodeEmulator(self.machdef.language)
|
45
|
+
# Set up the context configuration.
|
46
|
+
# This includes execution mode information,
|
47
|
+
# and isn't automatically propagated to the thread.
|
48
|
+
self._thread.overrideContextWithDefault()
|
49
|
+
|
50
|
+
self._memory_map = utils.RangeCollection()
|
51
|
+
|
52
|
+
# Instruction hooking callbacks
|
53
|
+
self._instructions_hook: typing.Optional[
|
54
|
+
typing.Callable[[Emulator], None]
|
55
|
+
] = None
|
56
|
+
self._instruction_hooks: typing.Dict[
|
57
|
+
int, typing.Callable[[Emulator], None]
|
58
|
+
] = dict()
|
59
|
+
|
60
|
+
# Function hooking callbacks
|
61
|
+
self._function_hooks: typing.Dict[
|
62
|
+
int, typing.Callable[[Emulator], None]
|
63
|
+
] = dict()
|
64
|
+
|
65
|
+
# Memory hooking callbacks
|
66
|
+
self._mem_reads_hook: typing.Optional[
|
67
|
+
typing.Callable[[Emulator, int, int, bytes], typing.Optional[bytes]]
|
68
|
+
] = None
|
69
|
+
self._mem_read_hooks: typing.Dict[
|
70
|
+
typing.Tuple[int, int],
|
71
|
+
typing.Callable[[Emulator, int, int, bytes], typing.Optional[bytes]],
|
72
|
+
] = dict()
|
73
|
+
self._mem_writes_hook: typing.Optional[
|
74
|
+
typing.Callable[[Emulator, int, int, bytes], None]
|
75
|
+
] = None
|
76
|
+
self._mem_write_hooks: typing.Dict[
|
77
|
+
typing.Tuple[int, int], typing.Callable[[Emulator, int, int, bytes], None]
|
78
|
+
] = dict()
|
79
|
+
|
80
|
+
@property
|
81
|
+
def _thread(self) -> PcodeThread:
|
82
|
+
return self._emu.getThread("main", True)
|
83
|
+
|
84
|
+
def read_register_content(self, name: str) -> int:
|
85
|
+
# Determine address and size of register
|
86
|
+
if name == "pc":
|
87
|
+
name = self.platdef.pc_register
|
88
|
+
reg = self.machdef.pcode_reg(name)
|
89
|
+
|
90
|
+
# Get the thread's register state
|
91
|
+
state = self._thread.getState()
|
92
|
+
|
93
|
+
# Get the register value in bytes
|
94
|
+
val = state.getVar(reg, PcodeExecutorStatePiece.Reason.INSPECT)
|
95
|
+
|
96
|
+
if self.platform.byteorder is platforms.Byteorder.LITTLE:
|
97
|
+
return int.from_bytes(val, "little")
|
98
|
+
elif self.platform.byteorder is platforms.Byteorder.BIG:
|
99
|
+
return int.from_bytes(val, "big")
|
100
|
+
else:
|
101
|
+
raise Exception("Unable to decode byteorder {self.platform.byteorder}")
|
102
|
+
|
103
|
+
def write_register_content(
|
104
|
+
self, name: str, value: typing.Union[None, int, claripy.ast.bv.BV]
|
105
|
+
) -> None:
|
106
|
+
# Determine address and size of register
|
107
|
+
if name == "pc":
|
108
|
+
name = self.platdef.pc_register
|
109
|
+
reg = self.machdef.pcode_reg(name)
|
110
|
+
|
111
|
+
if value is None:
|
112
|
+
return
|
113
|
+
if not isinstance(value, int):
|
114
|
+
raise TypeError("Pcode emulator can't support symbolic values")
|
115
|
+
|
116
|
+
state = self._thread.getState()
|
117
|
+
|
118
|
+
if self.platform.byteorder is platforms.Byteorder.BIG:
|
119
|
+
val = value.to_bytes(reg.getMinimumByteSize(), "big")
|
120
|
+
elif self.platform.byteorder is platforms.Byteorder.LITTLE:
|
121
|
+
val = value.to_bytes(reg.getMinimumByteSize(), "little")
|
122
|
+
else:
|
123
|
+
raise Exception("Unable to encode byteorder {self.platform.byteorder}")
|
124
|
+
|
125
|
+
state.setVar(reg, self.bytes_py_to_java(val))
|
126
|
+
|
127
|
+
def read_memory_content(self, address: int, size: int) -> bytes:
|
128
|
+
# Get the thread's memory state
|
129
|
+
shared = self._emu.getSharedState()
|
130
|
+
|
131
|
+
if self.platform.byteorder is platforms.Byteorder.BIG:
|
132
|
+
addr_bytes = address.to_bytes(self.platdef.address_size, "big")
|
133
|
+
elif self.platform.byteorder is platforms.Byteorder.LITTLE:
|
134
|
+
addr_bytes = address.to_bytes(self.platdef.address_size, "little")
|
135
|
+
else:
|
136
|
+
raise Exception("Unable to encode byteorder {self.platform.byteorder}")
|
137
|
+
|
138
|
+
# Get the data out of the default address space
|
139
|
+
# NOTE: Ghidra can support machines with multiple address spaces.
|
140
|
+
# SmallWorld does not.
|
141
|
+
val = shared.getVar(
|
142
|
+
self.machdef.language.getDefaultSpace(),
|
143
|
+
self.bytes_py_to_java(addr_bytes),
|
144
|
+
size,
|
145
|
+
False,
|
146
|
+
shared.Reason.INSPECT,
|
147
|
+
)
|
148
|
+
return self.bytes_java_to_py(val)
|
149
|
+
|
150
|
+
def map_memory(self, address: int, size: int) -> None:
|
151
|
+
region = (address, address + size)
|
152
|
+
self._memory_map.add_range(region)
|
153
|
+
|
154
|
+
def get_memory_map(self) -> typing.List[typing.Tuple[int, int]]:
|
155
|
+
return list(self._memory_map.ranges)
|
156
|
+
|
157
|
+
def write_memory_content(
|
158
|
+
self, address: int, content: typing.Union[bytes, claripy.ast.bv.BV]
|
159
|
+
):
|
160
|
+
if isinstance(content, claripy.ast.bv.BV):
|
161
|
+
raise TypeError("Pcode emulator can't handle symbolic expressions")
|
162
|
+
|
163
|
+
log.info(f"Writing {hex(len(content))} bytes at {hex(address)}")
|
164
|
+
|
165
|
+
# Get the thread's memory state
|
166
|
+
shared = self._emu.getSharedState()
|
167
|
+
|
168
|
+
val = self.bytes_py_to_java(content)
|
169
|
+
if self.platform.byteorder is platforms.Byteorder.BIG:
|
170
|
+
addr_bytes = address.to_bytes(self.platdef.address_size, "big")
|
171
|
+
elif self.platform.byteorder is platforms.Byteorder.LITTLE:
|
172
|
+
addr_bytes = address.to_bytes(self.platdef.address_size, "little")
|
173
|
+
else:
|
174
|
+
raise Exception("Unable to encode byteorder {self.platform.byteorder}")
|
175
|
+
|
176
|
+
# Get the data out of the default address space
|
177
|
+
# NOTE: Ghidra can support machines with multiple address spaces.
|
178
|
+
# SmallWorld does not.
|
179
|
+
shared.setVar(
|
180
|
+
self.machdef.language.getDefaultSpace(),
|
181
|
+
self.bytes_py_to_java(addr_bytes),
|
182
|
+
len(content),
|
183
|
+
False,
|
184
|
+
val,
|
185
|
+
)
|
186
|
+
|
187
|
+
def hook_instruction(
|
188
|
+
self, address: int, function: typing.Callable[[Emulator], None]
|
189
|
+
) -> None:
|
190
|
+
self._instruction_hooks[address] = function
|
191
|
+
|
192
|
+
def unhook_instruction(self, address: int) -> None:
|
193
|
+
if address in self._instruction_hooks:
|
194
|
+
del self._instruction_hooks[address]
|
195
|
+
|
196
|
+
def hook_instructions(self, function: typing.Callable[[Emulator], None]) -> None:
|
197
|
+
self._instructions_hook = function
|
198
|
+
|
199
|
+
def unhook_instructions(self) -> None:
|
200
|
+
self._instructions_hook = None
|
201
|
+
|
202
|
+
def _process_function_hook(self, address: int):
|
203
|
+
if address not in self._function_hooks:
|
204
|
+
# This really should never happen unless someone calls this manually.
|
205
|
+
raise exceptions.ConfigurationError(f"No function hook at {hex(address)}")
|
206
|
+
|
207
|
+
# Run the hook
|
208
|
+
self._function_hooks[address](self)
|
209
|
+
|
210
|
+
# Mimic a platform-specific "return" instruction.
|
211
|
+
if self.platform.architecture == platforms.Architecture.X86_32:
|
212
|
+
sp = self.read_register("esp")
|
213
|
+
if self.platform.byteorder == platforms.Byteorder.LITTLE:
|
214
|
+
ret = int.from_bytes(self.read_memory(sp, 4), "little")
|
215
|
+
elif self.platform.byteorder == platforms.Byteorder.BIG:
|
216
|
+
ret = int.from_bytes(self.read_memory(sp, 4), "big")
|
217
|
+
self.write_register("esp", sp + 4)
|
218
|
+
elif self.platform.architecture == platforms.Architecture.X86_64:
|
219
|
+
# amd64: pop an 8-byte value off the stack
|
220
|
+
sp = self.read_register("rsp")
|
221
|
+
if self.platform.byteorder == platforms.Byteorder.LITTLE:
|
222
|
+
ret = int.from_bytes(self.read_memory(sp, 8), "little")
|
223
|
+
elif self.platform.byteorder == platforms.Byteorder.BIG:
|
224
|
+
ret = int.from_bytes(self.read_memory(sp, 8), "big")
|
225
|
+
self.write_register("rsp", sp + 8)
|
226
|
+
elif (
|
227
|
+
self.platform.architecture == platforms.Architecture.AARCH64
|
228
|
+
or self.platform.architecture == platforms.Architecture.ARM_V5T
|
229
|
+
or self.platform.architecture == platforms.Architecture.ARM_V6M
|
230
|
+
or self.platform.architecture == platforms.Architecture.ARM_V6M_THUMB
|
231
|
+
or self.platform.architecture == platforms.Architecture.ARM_V7A
|
232
|
+
or self.platform.architecture == platforms.Architecture.ARM_V7M
|
233
|
+
or self.platform.architecture == platforms.Architecture.ARM_V7R
|
234
|
+
or self.platform.architecture == platforms.Architecture.POWERPC32
|
235
|
+
or self.platform.architecture == platforms.Architecture.POWERPC64
|
236
|
+
):
|
237
|
+
# aarch64, arm32, powerpc and powerpc64: branch to register 'lr'
|
238
|
+
ret = self.read_register("lr")
|
239
|
+
elif (
|
240
|
+
self.platform.architecture == platforms.Architecture.LOONGARCH64
|
241
|
+
or self.platform.architecture == platforms.Architecture.MIPS32
|
242
|
+
or self.platform.architecture == platforms.Architecture.MIPS64
|
243
|
+
or self.platform.architecture == platforms.Architecture.RISCV64
|
244
|
+
):
|
245
|
+
# mips32, mips64, and riscv64: branch to register 'ra'
|
246
|
+
ret = self.read_register("ra")
|
247
|
+
elif self.platform.architecture == platforms.Architecture.XTENSA:
|
248
|
+
# xtensa: branch to register 'a0'
|
249
|
+
ret = self.read_register("a0")
|
250
|
+
|
251
|
+
self.write_register("pc", ret)
|
252
|
+
|
253
|
+
def hook_function(
|
254
|
+
self, address: int, function: typing.Callable[[Emulator], None]
|
255
|
+
) -> None:
|
256
|
+
self._function_hooks[address] = function
|
257
|
+
|
258
|
+
def unhook_function(self, address: int) -> None:
|
259
|
+
if address in self._function_hooks:
|
260
|
+
del self._function_hooks[address]
|
261
|
+
|
262
|
+
def _update_access_breakpoints(self) -> None:
|
263
|
+
# Refresh all access breakpoints
|
264
|
+
# There's no way to clear a single access breakpoint;
|
265
|
+
# you need to clear them all and re-apply.
|
266
|
+
return
|
267
|
+
|
268
|
+
# Wipe out all access breakpoints
|
269
|
+
self._emu.clearAccessBreakpoints()
|
270
|
+
|
271
|
+
addrspace = self.machdef.language.getDefaultSpace()
|
272
|
+
|
273
|
+
# Add back the global read breakpoint
|
274
|
+
if self._mem_reads_hook is not None:
|
275
|
+
addr_range = AddressRangeImpl(
|
276
|
+
addrspace.getMinAddress(), addrspace.getMaxAddress()
|
277
|
+
)
|
278
|
+
self._emu.addAccessBreakpoint(addr_range, self._emu.AccessKind.R)
|
279
|
+
|
280
|
+
# Add back the specific read breakpoints
|
281
|
+
for start, end in self._mem_read_hooks:
|
282
|
+
start_addr = addrspace.getAddress(start)
|
283
|
+
end_addr = addrspace.getAddress(end)
|
284
|
+
addr_range = AddressRangeImpl(start_addr, end_addr)
|
285
|
+
self._emu.addAccessBreakpoint(addr_range, self._emu.AccessKind.R)
|
286
|
+
|
287
|
+
# Add back the global write breakpoint
|
288
|
+
if self._mem_writes_hook is not None:
|
289
|
+
addr_range = AddressRangeImpl(
|
290
|
+
addrspace.getMinAddress(), addrspace.getMaxAddress()
|
291
|
+
)
|
292
|
+
self._emu.addAccessBreakpoint(addr_range, self._emu.AccessKind.W)
|
293
|
+
|
294
|
+
# Add back the specific write breakpoints
|
295
|
+
for start, end in self._mem_write_hooks:
|
296
|
+
start_addr = addrspace.getAddress(start)
|
297
|
+
end_addr = addrspace.getAddress(end)
|
298
|
+
addr_range = AddressRangeImpl(start_addr, end_addr)
|
299
|
+
self._emu.addAccessBreakpoint(addr_range, self._emu.AccessKind.W)
|
300
|
+
|
301
|
+
def _process_read_breakpoint(self, addr_var: Varnode, out_var: Varnode) -> None:
|
302
|
+
state = self._thread.getState()
|
303
|
+
|
304
|
+
# Get the address out of the emulator
|
305
|
+
addr_bytes = state.getVar(addr_var, PcodeExecutorStatePiece.Reason.INSPECT)
|
306
|
+
if self.platform.byteorder is platforms.Byteorder.BIG:
|
307
|
+
addr = int.from_bytes(addr_bytes, "big")
|
308
|
+
elif self.platform.byteorder is platforms.Byteorder.LITTLE:
|
309
|
+
addr = int.from_bytes(addr_bytes, "little")
|
310
|
+
|
311
|
+
# Dereference the address to get the original data
|
312
|
+
addr_space = self.machdef.language.getDefaultSpace()
|
313
|
+
addr_addr = addr_space.getAddress(addr)
|
314
|
+
data_var = Varnode(addr_addr, out_var.getSize())
|
315
|
+
data = state.getVar(data_var, PcodeExecutorStatePiece.Reason.INSPECT)
|
316
|
+
|
317
|
+
if self._mem_reads_hook is not None:
|
318
|
+
new_data = self._mem_reads_hook(self, addr, len(data), data)
|
319
|
+
if new_data is not None:
|
320
|
+
data = new_data
|
321
|
+
|
322
|
+
end_addr = addr + len(data)
|
323
|
+
|
324
|
+
for (start, end), hook in self._mem_read_hooks.items():
|
325
|
+
rng = range(start, end)
|
326
|
+
access_rng = range(addr, end_addr)
|
327
|
+
if (
|
328
|
+
addr in rng
|
329
|
+
or end_addr - 1 in rng
|
330
|
+
or start in access_rng
|
331
|
+
or end - 1 in access_rng
|
332
|
+
):
|
333
|
+
new_data = hook(self, addr, len(data), data)
|
334
|
+
if new_data is not None:
|
335
|
+
data = new_data
|
336
|
+
|
337
|
+
# Write the data to the output
|
338
|
+
#
|
339
|
+
# CRITICAL: This must always happen, even if the op wasn't hooked!
|
340
|
+
# The main processing loop skips any LOAD opcodes,
|
341
|
+
# since their normal execution will clobber any value produced
|
342
|
+
# by this handler.
|
343
|
+
# Thus, this handler must fully replace the behavior of LOAD.
|
344
|
+
state.setVar(out_var, self.bytes_py_to_java(data))
|
345
|
+
|
346
|
+
def hook_memory_read(
|
347
|
+
self,
|
348
|
+
start: int,
|
349
|
+
end: int,
|
350
|
+
function: typing.Callable[[Emulator, int, int, bytes], typing.Optional[bytes]],
|
351
|
+
) -> None:
|
352
|
+
self._mem_read_hooks[(start, end)] = function
|
353
|
+
self._update_access_breakpoints()
|
354
|
+
|
355
|
+
def unhook_memory_read(self, start: int, end: int) -> None:
|
356
|
+
if (start, end) in self._mem_read_hooks:
|
357
|
+
del self._mem_read_hooks[(start, end)]
|
358
|
+
self._update_access_breakpoints()
|
359
|
+
|
360
|
+
def hook_memory_reads(
|
361
|
+
self,
|
362
|
+
function: typing.Callable[[Emulator, int, int, bytes], typing.Optional[bytes]],
|
363
|
+
) -> None:
|
364
|
+
self._mem_reads_hook = function
|
365
|
+
self._update_access_breakpoints()
|
366
|
+
|
367
|
+
def unhook_memory_reads(self) -> None:
|
368
|
+
if self._mem_reads_hook is not None:
|
369
|
+
self._mem_reads_hook = None
|
370
|
+
self._update_access_breakpoints()
|
371
|
+
|
372
|
+
def _process_write_breakpoint(self, addr_var: Varnode, data_var: Varnode) -> None:
|
373
|
+
state = self._thread.getState()
|
374
|
+
addr_bytes = state.getVar(addr_var, PcodeExecutorStatePiece.Reason.INSPECT)
|
375
|
+
data = state.getVar(data_var, PcodeExecutorStatePiece.Reason.INSPECT)
|
376
|
+
|
377
|
+
if self.platform.byteorder is platforms.Byteorder.BIG:
|
378
|
+
addr = int.from_bytes(addr_bytes, "big")
|
379
|
+
elif self.platform.byteorder is platforms.Byteorder.LITTLE:
|
380
|
+
addr = int.from_bytes(addr_bytes, "little")
|
381
|
+
|
382
|
+
if self._mem_writes_hook is not None:
|
383
|
+
self._mem_writes_hook(self, addr, len(data), data)
|
384
|
+
|
385
|
+
end_addr = addr + len(data)
|
386
|
+
|
387
|
+
for (start, end), hook in self._mem_write_hooks.items():
|
388
|
+
rng = range(start, end)
|
389
|
+
access_rng = range(addr, end_addr)
|
390
|
+
if (
|
391
|
+
addr in rng
|
392
|
+
or end_addr - 1 in rng
|
393
|
+
or start in access_rng
|
394
|
+
or end - 1 in access_rng
|
395
|
+
):
|
396
|
+
hook(self, addr, len(data), data)
|
397
|
+
|
398
|
+
def hook_memory_write(
|
399
|
+
self,
|
400
|
+
start: int,
|
401
|
+
end: int,
|
402
|
+
function: typing.Callable[[Emulator, int, int, bytes], None],
|
403
|
+
) -> None:
|
404
|
+
self._mem_write_hooks[(start, end)] = function
|
405
|
+
self._update_access_breakpoints()
|
406
|
+
|
407
|
+
def unhook_memory_write(self, start: int, end: int) -> None:
|
408
|
+
if (start, end) in self._mem_write_hooks:
|
409
|
+
del self._mem_write_hooks[(start, end)]
|
410
|
+
self._update_access_breakpoints()
|
411
|
+
|
412
|
+
def hook_memory_writes(
|
413
|
+
self,
|
414
|
+
function: typing.Callable[[Emulator, int, int, bytes], None],
|
415
|
+
) -> None:
|
416
|
+
self._mem_writes_hook = function
|
417
|
+
self._update_access_breakpoints()
|
418
|
+
|
419
|
+
def unhook_memory_writes(self) -> None:
|
420
|
+
if self._mem_writes_hook is not None:
|
421
|
+
self._mem_writes_hook = None
|
422
|
+
self._update_access_breakpoints()
|
423
|
+
|
424
|
+
def step_instruction(self) -> None:
|
425
|
+
if not self.machdef.supports_single_step:
|
426
|
+
raise exceptions.ConfigurationError(
|
427
|
+
f"PcodeEmulator does not support single-instruction stepping for {self.platform}"
|
428
|
+
)
|
429
|
+
|
430
|
+
# Step!
|
431
|
+
pc = self.read_register_content(self.platdef.pc_register)
|
432
|
+
pc_addr = self.machdef.language.getDefaultSpace().getAddress(pc)
|
433
|
+
self._thread.overrideCounter(pc_addr)
|
434
|
+
|
435
|
+
# Check for instruction hooks.
|
436
|
+
# TODO: Should instruction hooks override the instruction?
|
437
|
+
if self._instructions_hook is not None:
|
438
|
+
self._instructions_hook(self)
|
439
|
+
if pc in self._instruction_hooks:
|
440
|
+
self._instruction_hooks[pc](self)
|
441
|
+
|
442
|
+
# Check for function hooks
|
443
|
+
if pc in self._function_hooks:
|
444
|
+
# Function hooks bypass normal instruction processing,
|
445
|
+
# but I still want bounds/exits to work normally.
|
446
|
+
self._process_function_hook(pc)
|
447
|
+
else:
|
448
|
+
skip = False
|
449
|
+
frame = None
|
450
|
+
# We need to step individual pcode ops to capture hooks
|
451
|
+
# There is an exception-based hooking mechanism,
|
452
|
+
# but it's unworkable for SmallWorld's purpose.
|
453
|
+
while True:
|
454
|
+
if skip:
|
455
|
+
# Skip the next op; it was modeled by a hook
|
456
|
+
skip = False
|
457
|
+
self._thread.skipPcodeOp()
|
458
|
+
else:
|
459
|
+
# Execute the opcode normally
|
460
|
+
self._thread.stepPcodeOp()
|
461
|
+
|
462
|
+
frame = self._thread.getFrame()
|
463
|
+
|
464
|
+
if frame is None:
|
465
|
+
# No frame; this is the end of the instruction
|
466
|
+
break
|
467
|
+
|
468
|
+
if frame.isFinished():
|
469
|
+
# Frame is finished; this is the end of the instruction
|
470
|
+
self._thread.finishInstruction()
|
471
|
+
break
|
472
|
+
|
473
|
+
# Inspect the op to see if it's memory-hook relevant
|
474
|
+
code = frame.getCode()
|
475
|
+
op = code[frame.index()]
|
476
|
+
opcode = op.getOpcode()
|
477
|
+
if opcode == op.STORE:
|
478
|
+
# This is a STORE opcode; could trigger a "write" hook
|
479
|
+
_, addr_var, data_var = op.getInputs()
|
480
|
+
self._process_write_breakpoint(addr_var, data_var)
|
481
|
+
elif opcode == op.LOAD:
|
482
|
+
# This is a LOAD opcode; could trigger a "read" hook
|
483
|
+
_, addr_var = op.getInputs()
|
484
|
+
out_var = op.getOutput()
|
485
|
+
self._process_read_breakpoint(addr_var, out_var)
|
486
|
+
# Skip the actual LOAD opcode
|
487
|
+
# The read breakpoint handler will mimic its behavior;
|
488
|
+
# running the op normally will clobber a custom value
|
489
|
+
# produced by a hook.
|
490
|
+
skip = True
|
491
|
+
|
492
|
+
# Check exit points and bounds
|
493
|
+
pc = self.read_register_content(self.platdef.pc_register)
|
494
|
+
|
495
|
+
if pc in self._exit_points:
|
496
|
+
raise exceptions.EmulationExitpoint()
|
497
|
+
if not self._bounds.is_empty() and not self._bounds.contains_value(pc):
|
498
|
+
raise exceptions.EmulationBounds()
|
499
|
+
if not self._memory_map.is_empty() and not self._memory_map.contains_value(pc):
|
500
|
+
raise exceptions.EmulationBounds()
|
501
|
+
|
502
|
+
def step_block(self) -> None:
|
503
|
+
raise NotImplementedError("Not sure how to step by block.")
|
504
|
+
|
505
|
+
def run(self) -> None:
|
506
|
+
try:
|
507
|
+
while True:
|
508
|
+
self.step_instruction()
|
509
|
+
except exceptions.EmulationStop:
|
510
|
+
pass
|
511
|
+
|
512
|
+
def __repr__(self) -> str:
|
513
|
+
return "PcodeEmulator"
|
@@ -0,0 +1,31 @@
|
|
1
|
+
from .aarch64 import AArch64MachineDef
|
2
|
+
from .amd64 import AMD64MachineDef
|
3
|
+
from .arm import ARMv5TMachineDef, ARMv6MMachineDef, ARMv7AMachineDef, ARMv7MMachineDef
|
4
|
+
from .i386 import i386MachineDef
|
5
|
+
from .loongarch import LoongArch64MachineDef
|
6
|
+
from .machdef import GhidraMachineDef
|
7
|
+
from .mips import MIPSBEMachineDef, MIPSELMachineDef
|
8
|
+
from .mips64 import MIPS64BEMachineDef, MIPS64ELMachineDef
|
9
|
+
from .ppc import PowerPC32MachineDef, PowerPC64MachineDef
|
10
|
+
from .riscv import RISCV64MachineDef
|
11
|
+
from .xtensa import XTensaMachineDef
|
12
|
+
|
13
|
+
__all__ = [
|
14
|
+
"AArch64MachineDef",
|
15
|
+
"AMD64MachineDef",
|
16
|
+
"ARMv5TMachineDef",
|
17
|
+
"ARMv6MMachineDef",
|
18
|
+
"ARMv7MMachineDef",
|
19
|
+
"ARMv7AMachineDef",
|
20
|
+
"i386MachineDef",
|
21
|
+
"LoongArch64MachineDef",
|
22
|
+
"MIPS64BEMachineDef",
|
23
|
+
"MIPS64ELMachineDef",
|
24
|
+
"MIPSBEMachineDef",
|
25
|
+
"MIPSELMachineDef",
|
26
|
+
"GhidraMachineDef",
|
27
|
+
"PowerPC32MachineDef",
|
28
|
+
"PowerPC64MachineDef",
|
29
|
+
"RISCV64MachineDef",
|
30
|
+
"XTensaMachineDef",
|
31
|
+
]
|