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