From 162691723e45d6dab20b68614886a6c4a29d619e Mon Sep 17 00:00:00 2001 From: OBarronCS <55004530+OBarronCS@users.noreply.github.com> Date: Fri, 18 Apr 2025 04:14:06 -0700 Subject: [PATCH] Context display fix involving unknown syscall ABI's + MIPS Disassembly CapstoneV6 Hotfix (#2898) * Fix crash on syscalls instructions when syscall ABI is not defined * Fix crash when branch delay slot contains an invalid instruction * Hotfix to detect mips version more precisely on gdb --- pwndbg/aglib/disasm/arch.py | 6 ++++- pwndbg/aglib/disasm/disassembly.py | 40 +++++++++++++++++++++++++----- pwndbg/arguments.py | 5 +++- 3 files changed, 43 insertions(+), 8 deletions(-) diff --git a/pwndbg/aglib/disasm/arch.py b/pwndbg/aglib/disasm/arch.py index d0cac6bb5..9e2ddb3ea 100644 --- a/pwndbg/aglib/disasm/arch.py +++ b/pwndbg/aglib/disasm/arch.py @@ -605,7 +605,11 @@ class DisassemblyAssistant: Elements of the tuple will be None to indicate it's not a syscall """ - return (pwndbg.aglib.arch.name, pwndbg.lib.abi.ABI.syscall().syscall_register) + try: + abi = pwndbg.lib.abi.ABI.syscall() + except KeyError: + return (None, None) + return (pwndbg.aglib.arch.name, abi.syscall_register) def _enhance_conditional(self, instruction: PwndbgInstruction, emu: Emulator) -> None: """ diff --git a/pwndbg/aglib/disasm/disassembly.py b/pwndbg/aglib/disasm/disassembly.py index 9c59bd73e..21af1e244 100644 --- a/pwndbg/aglib/disasm/disassembly.py +++ b/pwndbg/aglib/disasm/disassembly.py @@ -181,12 +181,35 @@ def get_disassembler(address): elif pwndbg.aglib.arch.name == "i8086": extra = CS_MODE_16 - elif ( - pwndbg.aglib.arch.name == "mips" - and pwndbg.dbg.is_gdblib_available() - and "isa32r6" in gdb.newest_frame().architecture().name() - ): - extra = CS_MODE_MIPS32R6 + elif pwndbg.aglib.arch.name == "mips": + if pwndbg.dbg.is_gdblib_available(): + # Example: "mips:isa64r2" + raw_arch_name = gdb.newest_frame().architecture().name() + + if "isa32r2" in raw_arch_name: + extra = CS_MODE_MIPS32R2 + elif "isa32r3" in raw_arch_name: + extra = CS_MODE_MIPS32R3 + elif "isa32r5" in raw_arch_name: + extra = CS_MODE_MIPS32R5 + elif "isa32r6" in raw_arch_name: + extra = CS_MODE_MIPS32R6 + elif "isa64r2" in raw_arch_name: + extra = CS_MODE_MIPS64R2 + elif "isa64r3" in raw_arch_name: + extra = CS_MODE_MIPS64R3 + elif "isa64r5" in raw_arch_name: + extra = CS_MODE_MIPS64R5 + elif "isa64r6" in raw_arch_name: + extra = CS_MODE_MIPS64R6 + elif "micromips" in raw_arch_name: + extra = CS_MODE_MICRO + elif "mips5" in raw_arch_name: + extra = CS_MODE_MIPS5 + elif pwndbg.aglib.arch.ptrsize == 64: + extra = CS_MODE_MIPS64 + else: + extra = CS_MODE_MIPS32 elif pwndbg.aglib.arch.name == "rv32": extra = CS_MODE_RISCV32 | CS_MODE_RISCVC # novermin @@ -499,6 +522,11 @@ def near( emu.valid = False split_insn = one(insn.address + insn.size, None, put_cache=True) + + # There might not be a valid instruction at the branch delay slot + if split_insn is None: + break + insns.append(split_insn) # Manually make the backtracing cache correct diff --git a/pwndbg/arguments.py b/pwndbg/arguments.py index d07c39481..f4e385ba9 100644 --- a/pwndbg/arguments.py +++ b/pwndbg/arguments.py @@ -60,7 +60,10 @@ def get(instruction: PwndbgInstruction) -> List[Tuple[pwndbg.lib.functions.Argum elif CS_GRP_INT in instruction.groups: # Get the syscall number and name name = instruction.syscall_name - abi = pwndbg.lib.abi.ABI.syscall() + try: + abi = pwndbg.lib.abi.ABI.syscall() + except KeyError: + return [] target = None if name is None: