You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
pwndbg/tests/qemu-tests/conftest.py

142 lines
3.7 KiB
Python

"""
This file should consist of global test fixtures.
"""
from __future__ import annotations
import os
import subprocess
import sys
from typing import Literal
import gdb
import pytest
from pwn import context
from pwn import make_elf_from_assembly
from pwn import pwnlib
_start_binary_called = False
QEMU_PORT = os.environ.get("QEMU_PORT")
@pytest.fixture
def qemu_assembly_run():
"""
Returns function that launches given binary with 'starti' command
The `path` is returned from `make_elf_from_assembly` (provided by pwntools)
"""
qemu: subprocess.Popen = None
if QEMU_PORT is None:
print("'QEMU_PORT' environment variable not set")
sys.stdout.flush()
os._exit(1)
def _start_binary(asm: str, arch: str, *args):
nonlocal qemu
# Clear the context so setting the .arch will also set .bits
# https://github.com/Gallopsled/pwntools/issues/2498
context.clear()
context.arch = arch
binary_tmp_path = make_elf_from_assembly(asm)
qemu_suffix = pwnlib.qemu.archname()
qemu = subprocess.Popen(
[
f"qemu-{qemu_suffix}",
"-g",
f"{QEMU_PORT}",
f"{binary_tmp_path}",
]
)
os.environ["PWNDBG_IN_TEST"] = "1"
os.environ["COLUMNS"] = "80"
gdb.execute("set exception-verbose on")
gdb.execute("set context-reserve-lines never")
gdb.execute("set width 80")
gdb.execute(f"target remote :{QEMU_PORT}")
global _start_binary_called
# if _start_binary_called:
# raise Exception('Starting more than one binary is not supported in pwndbg tests.')
_start_binary_called = True
yield _start_binary
qemu.kill()
# Map of qemu_suffix to location of library files in default Ubuntu installs of cross-compilers
CROSS_ARCH_LIBC = {
"aarch64": "/usr/aarch64-linux-gnu",
"arm": "/usr/arm-linux-gnueabihf",
"mips": "/usr/mips-linux-gnu",
"mips64": "/usr/mips64-linux-gnuabi64/",
"riscv64": "/usr/riscv64-linux-gnu/",
"loongarch64": "/usr/loongarch64-linux-gnu/",
"ppc": "/usr/powerpc-linux-gnu/",
"ppc64": "/usr/powerpc64-linux-gnu/",
"sparc64": "/usr/sparc64-linux-gnu/",
}
@pytest.fixture
def qemu_start_binary():
"""
Returns function that launches given binary with 'starti' command
Argument `path` is the path to the binary
"""
qemu: subprocess.Popen = None
if QEMU_PORT is None:
print("'QEMU_PORT' environment variable not set")
sys.stdout.flush()
os._exit(1)
def _start_binary(path: str, arch: str, endian: Literal["big", "little"] | None = None):
nonlocal qemu
if endian is not None:
context.endian = endian
qemu_suffix = pwnlib.qemu.archname(arch=arch)
# qemu_libs = pwnlib.qemu.ld_prefix(arch=arch)
qemu_libs = CROSS_ARCH_LIBC.get(qemu_suffix, f"/usr/gnemul/qemu-{qemu_suffix}")
qemu = subprocess.Popen(
[
f"qemu-{qemu_suffix}",
"-L",
qemu_libs,
"-g",
f"{QEMU_PORT}",
f"{path}",
]
)
os.environ["PWNDBG_IN_TEST"] = "1"
os.environ["COLUMNS"] = "80"
gdb.execute("set exception-verbose on")
gdb.execute("set context-reserve-lines never")
gdb.execute("set width 80")
gdb.execute(f"target remote :{QEMU_PORT}")
global _start_binary_called
# if _start_binary_called:
# raise Exception('Starting more than one binary is not supported in pwndbg tests.')
_start_binary_called = True
yield _start_binary
qemu.kill()