mirror of https://github.com/pwndbg/pwndbg.git
Replace pwnlib.asm.asm with pwndbg.lib.zig.asm (#3207)
* Replace pwnlib.asm.asm with pwndbg.lib.zig.asm * fix search * move unit-tests to ci * include pwnlib * fix test * fix docs * fix comment * fix import * fixypull/3217/head
parent
ca0b86d04c
commit
f9f90d9f02
@ -0,0 +1,26 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import pathlib
|
||||
from typing import List
|
||||
|
||||
import pwnlib.context
|
||||
import pwnlib.data
|
||||
|
||||
import pwndbg.aglib.arch
|
||||
import pwndbg.lib.zig
|
||||
|
||||
|
||||
def _get_pwntools_includes() -> List[pathlib.Path]:
|
||||
include = (
|
||||
pathlib.Path(pwnlib.data.path)
|
||||
/ "includes"
|
||||
/ str(pwnlib.context.context.os)
|
||||
/ f"{pwnlib.context.context.arch}.h"
|
||||
)
|
||||
if not include.exists():
|
||||
return []
|
||||
return [include]
|
||||
|
||||
|
||||
def asm(data: str) -> bytes:
|
||||
return pwndbg.lib.zig.asm(pwndbg.aglib.arch, data, includes=_get_pwntools_includes())
|
||||
@ -0,0 +1,206 @@
|
||||
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"
|
||||
Loading…
Reference in new issue