mirror of https://github.com/pwndbg/pwndbg.git
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.
207 lines
5.3 KiB
Python
207 lines
5.3 KiB
Python
from __future__ import annotations
|
|
|
|
import pathlib
|
|
import tempfile
|
|
|
|
import pytest
|
|
import unicorn as uc
|
|
from unicorn import arm64_const
|
|
from unicorn import arm_const
|
|
from unicorn import mips_const
|
|
from unicorn import ppc_const
|
|
from unicorn import riscv_const
|
|
from unicorn import s390x_const
|
|
from unicorn import sparc_const
|
|
from unicorn import x86_const
|
|
|
|
import pwndbg.lib.zig
|
|
|
|
expected_value = 60
|
|
include_text = f"""
|
|
#define FROM_INCLUDE_VALUE {expected_value}
|
|
"""
|
|
|
|
regs_and_instr = {
|
|
"x86": (
|
|
"mov eax, FROM_INCLUDE_VALUE",
|
|
uc.UC_ARCH_X86,
|
|
uc.UC_MODE_32,
|
|
None,
|
|
x86_const.UC_X86_REG_EAX,
|
|
),
|
|
"x86_64": (
|
|
"mov rax, FROM_INCLUDE_VALUE",
|
|
uc.UC_ARCH_X86,
|
|
uc.UC_MODE_64,
|
|
None,
|
|
x86_const.UC_X86_REG_RAX,
|
|
),
|
|
"mips": (
|
|
"li $a0, FROM_INCLUDE_VALUE",
|
|
uc.UC_ARCH_MIPS,
|
|
uc.UC_MODE_MIPS32 | uc.UC_MODE_BIG_ENDIAN,
|
|
None,
|
|
mips_const.UC_MIPS_REG_A0,
|
|
),
|
|
"mipsel": (
|
|
"li $a0, FROM_INCLUDE_VALUE",
|
|
uc.UC_ARCH_MIPS,
|
|
uc.UC_MODE_MIPS32 | uc.UC_MODE_LITTLE_ENDIAN,
|
|
None,
|
|
mips_const.UC_MIPS_REG_A0,
|
|
),
|
|
"mips64": (
|
|
"li $a0, FROM_INCLUDE_VALUE",
|
|
uc.UC_ARCH_MIPS,
|
|
uc.UC_MODE_MIPS64 | uc.UC_MODE_BIG_ENDIAN,
|
|
None,
|
|
mips_const.UC_MIPS_REG_A0,
|
|
),
|
|
"mips64el": (
|
|
"li $a0, FROM_INCLUDE_VALUE",
|
|
uc.UC_ARCH_MIPS,
|
|
uc.UC_MODE_MIPS64 | uc.UC_MODE_LITTLE_ENDIAN,
|
|
None,
|
|
mips_const.UC_MIPS_REG_A0,
|
|
),
|
|
"arm": (
|
|
"mov r0, #FROM_INCLUDE_VALUE",
|
|
uc.UC_ARCH_ARM,
|
|
uc.UC_MODE_ARM,
|
|
None,
|
|
arm_const.UC_ARM_REG_R0,
|
|
),
|
|
"armeb": (
|
|
"mov r0, #FROM_INCLUDE_VALUE",
|
|
uc.UC_ARCH_ARM,
|
|
uc.UC_MODE_ARM | uc.UC_MODE_BIG_ENDIAN,
|
|
None,
|
|
arm_const.UC_ARM_REG_R0,
|
|
),
|
|
"thumb": (
|
|
"mov r0, #FROM_INCLUDE_VALUE",
|
|
uc.UC_ARCH_ARM,
|
|
uc.UC_MODE_THUMB,
|
|
None,
|
|
arm_const.UC_ARM_REG_R0,
|
|
),
|
|
"thumbeb": (
|
|
"mov r0, #FROM_INCLUDE_VALUE",
|
|
uc.UC_ARCH_ARM,
|
|
uc.UC_MODE_THUMB | uc.UC_MODE_BIG_ENDIAN,
|
|
None,
|
|
arm_const.UC_ARM_REG_R0,
|
|
),
|
|
"aarch64": (
|
|
"mov x0, #FROM_INCLUDE_VALUE",
|
|
uc.UC_ARCH_ARM64,
|
|
uc.UC_MODE_ARM,
|
|
None,
|
|
arm64_const.UC_ARM64_REG_X0,
|
|
),
|
|
"aarch64_be": (
|
|
"mov x0, #FROM_INCLUDE_VALUE",
|
|
uc.UC_ARCH_ARM64,
|
|
uc.UC_MODE_ARM | uc.UC_MODE_BIG_ENDIAN,
|
|
None,
|
|
arm64_const.UC_ARM64_REG_X0,
|
|
),
|
|
"riscv32": (
|
|
"li a0, FROM_INCLUDE_VALUE",
|
|
uc.UC_ARCH_RISCV,
|
|
uc.UC_MODE_RISCV32,
|
|
None,
|
|
riscv_const.UC_RISCV_REG_A0,
|
|
),
|
|
"riscv64": (
|
|
"li a0, FROM_INCLUDE_VALUE",
|
|
uc.UC_ARCH_RISCV,
|
|
uc.UC_MODE_RISCV64,
|
|
None,
|
|
riscv_const.UC_RISCV_REG_A0,
|
|
),
|
|
"s390x": (
|
|
"lghi %r2, FROM_INCLUDE_VALUE",
|
|
uc.UC_ARCH_S390X,
|
|
uc.UC_MODE_BIG_ENDIAN,
|
|
s390x_const.UC_CPU_S390X_Z14,
|
|
s390x_const.UC_S390X_REG_R2,
|
|
),
|
|
# FIXME: upstream bug, https://github.com/ziglang/zig/issues/23674
|
|
# 'sparc': ('mov 60,%i0', uc.UC_ARCH_SPARC, uc.UC_MODE_SPARC32 | uc.UC_MODE_BIG_ENDIAN, None, sparc_const.UC_SPARC_REG_I0),
|
|
"sparc64": (
|
|
"mov FROM_INCLUDE_VALUE,%i0",
|
|
uc.UC_ARCH_SPARC,
|
|
uc.UC_MODE_SPARC64 | uc.UC_MODE_BIG_ENDIAN,
|
|
None,
|
|
sparc_const.UC_SPARC_REG_I0,
|
|
),
|
|
"powerpc": (
|
|
"li %r1, FROM_INCLUDE_VALUE",
|
|
uc.UC_ARCH_PPC,
|
|
uc.UC_MODE_32 | uc.UC_MODE_BIG_ENDIAN,
|
|
ppc_const.UC_CPU_PPC32_7457A_V1_2,
|
|
ppc_const.UC_PPC_REG_1,
|
|
),
|
|
"powerpc64": (
|
|
"li %r1, FROM_INCLUDE_VALUE",
|
|
uc.UC_ARCH_PPC,
|
|
uc.UC_MODE_64 | uc.UC_MODE_BIG_ENDIAN,
|
|
ppc_const.UC_CPU_PPC64_970_V2_2,
|
|
ppc_const.UC_PPC_REG_1,
|
|
),
|
|
"powerpcle": (
|
|
"li %r1, FROM_INCLUDE_VALUE",
|
|
None,
|
|
None,
|
|
None,
|
|
None,
|
|
), # FIXME: UC_MODE_LITTLE_ENDIAN, Not supported by Unicorn
|
|
"powerpc64le": (
|
|
"li %r1, FROM_INCLUDE_VALUE",
|
|
None,
|
|
None,
|
|
None,
|
|
None,
|
|
), # FIXME: UC_MODE_LITTLE_ENDIAN, Not supported by Unicorn
|
|
"loongarch64": (
|
|
"addi.d $r1, $r1, FROM_INCLUDE_VALUE",
|
|
None,
|
|
None,
|
|
None,
|
|
None,
|
|
), # FIXME: Not supported by Unicorn
|
|
}
|
|
test_cases = list(regs_and_instr.keys())
|
|
|
|
|
|
@pytest.mark.parametrize("arch", test_cases)
|
|
def test_zig_asm_compiles(arch):
|
|
asm_line, uc_arch, uc_mode, uc_cpu, reg_id = regs_and_instr[arch]
|
|
|
|
with tempfile.NamedTemporaryFile(mode="wt", suffix="test.h", delete=False) as example_h:
|
|
example_h.write(include_text)
|
|
|
|
bytecode = pwndbg.lib.zig._asm(arch, asm_line, includes=[pathlib.Path(example_h.name)])
|
|
assert len(bytecode) > 0, "Bytecode too short"
|
|
|
|
if uc_arch is None:
|
|
pytest.skip("unsupported by Unicorn")
|
|
|
|
mu = uc.Uc(uc_arch, uc_mode, uc_cpu)
|
|
|
|
# Map 4KB memory at 0x20000
|
|
ADDRESS = 0x20000
|
|
mu.mem_map(ADDRESS, 0x2000)
|
|
mu.mem_write(ADDRESS, bytes(bytecode))
|
|
|
|
# Zero the register
|
|
mu.reg_write(reg_id, 0)
|
|
|
|
# Run the code
|
|
mu.emu_start(ADDRESS, ADDRESS + len(bytecode), count=1)
|
|
|
|
# Read result
|
|
value = mu.reg_read(reg_id)
|
|
assert value == expected_value, "Value mismatch"
|