|
|
|
|
@ -14,7 +14,9 @@ from pwndbg.lib.arch import ArchDefinition
|
|
|
|
|
from pwndbg.lib.arch import Platform
|
|
|
|
|
|
|
|
|
|
# Supported architectures can be obtained using the command: `zig targets`
|
|
|
|
|
_arch_mapping: Dict[Tuple[PWNDBG_SUPPORTED_ARCHITECTURES_TYPE, Literal["little", "big"], int], str] = {
|
|
|
|
|
_arch_mapping: Dict[
|
|
|
|
|
Tuple[PWNDBG_SUPPORTED_ARCHITECTURES_TYPE, Literal["little", "big"], int], str
|
|
|
|
|
] = {
|
|
|
|
|
("x86-64", "little", 8): "x86_64",
|
|
|
|
|
("i386", "little", 4): "x86",
|
|
|
|
|
("mips", "big", 4): "mips",
|
|
|
|
|
@ -44,7 +46,6 @@ _asm_header: Dict[str, str] = {
|
|
|
|
|
# `.intel_syntax noprefix` forces the use of Intel assembly syntax instead of AT&T
|
|
|
|
|
"x86_64": _prefix_header + ".intel_syntax noprefix\n",
|
|
|
|
|
"x86": _prefix_header + ".intel_syntax noprefix\n",
|
|
|
|
|
|
|
|
|
|
# `.set noreorder` disables instruction reordering for MIPS to handle delay slots correctly
|
|
|
|
|
"mips": _prefix_header + ".set noreorder\n",
|
|
|
|
|
"mipsel": _prefix_header + ".set noreorder\n",
|
|
|
|
|
@ -52,7 +53,6 @@ _asm_header: Dict[str, str] = {
|
|
|
|
|
"mips64el": _prefix_header + ".set noreorder\n",
|
|
|
|
|
"aarch64": _prefix_header,
|
|
|
|
|
"aarch64_be": _prefix_header,
|
|
|
|
|
|
|
|
|
|
# `.syntax unified` enables the unified assembly syntax for ARM/Thumb
|
|
|
|
|
"arm": _prefix_header + ".syntax unified\n",
|
|
|
|
|
"armeb": _prefix_header + ".syntax unified\n",
|
|
|
|
|
@ -70,6 +70,7 @@ _asm_header: Dict[str, str] = {
|
|
|
|
|
"s390x": _prefix_header,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def _get_zig_target(arch: ArchDefinition) -> str | None:
|
|
|
|
|
if arch.platform == Platform.LINUX:
|
|
|
|
|
# "gnu", "gnuabin32", "gnuabi64", "gnueabi", "gnueabihf",
|
|
|
|
|
@ -96,7 +97,9 @@ def flags(arch: ArchDefinition) -> List[str]:
|
|
|
|
|
|
|
|
|
|
zig_target = _get_zig_target(arch)
|
|
|
|
|
if zig_target is None:
|
|
|
|
|
raise ValueError(f"Can't find ziglang target for ({(arch.name, arch.endian, arch.ptrsize)})")
|
|
|
|
|
raise ValueError(
|
|
|
|
|
f"Can't find ziglang target for ({(arch.name, arch.endian, arch.ptrsize)})"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
return [
|
|
|
|
|
os.path.join(os.path.dirname(ziglang.__file__), "zig"),
|
|
|
|
|
@ -106,15 +109,17 @@ def flags(arch: ArchDefinition) -> List[str]:
|
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def asm(arch: ArchDefinition, data: str, includes: List[pathlib.Path] | None=None) -> bytes:
|
|
|
|
|
def asm(arch: ArchDefinition, data: str, includes: List[pathlib.Path] | None = None) -> bytes:
|
|
|
|
|
arch_mapping = _arch_mapping.get((arch.name, arch.endian, arch.ptrsize), None)
|
|
|
|
|
if arch_mapping is None:
|
|
|
|
|
raise ValueError(f"Can't find ziglang target for ({(arch.name, arch.endian, arch.ptrsize)})")
|
|
|
|
|
raise ValueError(
|
|
|
|
|
f"Can't find ziglang target for ({(arch.name, arch.endian, arch.ptrsize)})"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
return _asm(arch_mapping, data, includes)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def _asm(arch_mapping: str, data: str, includes: List[pathlib.Path] | None=None) -> bytes:
|
|
|
|
|
def _asm(arch_mapping: str, data: str, includes: List[pathlib.Path] | None = None) -> bytes:
|
|
|
|
|
try:
|
|
|
|
|
import ziglang
|
|
|
|
|
except ImportError:
|
|
|
|
|
@ -127,8 +132,8 @@ def _asm(arch_mapping: str, data: str, includes: List[pathlib.Path] | None=None)
|
|
|
|
|
if includes is None:
|
|
|
|
|
includes = []
|
|
|
|
|
|
|
|
|
|
includes = ''.join((f'#include "{path}"\n' for path in includes))
|
|
|
|
|
target = f'{arch_mapping}-freestanding'
|
|
|
|
|
includes = "".join((f'#include "{path}"\n' for path in includes))
|
|
|
|
|
target = f"{arch_mapping}-freestanding"
|
|
|
|
|
|
|
|
|
|
with tempfile.TemporaryDirectory() as tmpdir:
|
|
|
|
|
asm_file = os.path.join(tmpdir, "input.S")
|
|
|
|
|
@ -176,7 +181,9 @@ def _asm(arch_mapping: str, data: str, includes: List[pathlib.Path] | None=None)
|
|
|
|
|
universal_newlines=True,
|
|
|
|
|
)
|
|
|
|
|
if objcopy_process.returncode != 0:
|
|
|
|
|
raise Exception("Extracting bytecode error", objcopy_process.stdout, objcopy_process.stderr)
|
|
|
|
|
raise Exception(
|
|
|
|
|
"Extracting bytecode error", objcopy_process.stdout, objcopy_process.stderr
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
with open(bytecode_file, "rb") as f:
|
|
|
|
|
return f.read()
|
|
|
|
|
|